From 88dc4190bb9d344766477d53909986c97eb19cc4 Mon Sep 17 00:00:00 2001 From: HaiweiZuo Date: Wed, 15 Apr 2026 17:44:33 +0800 Subject: [PATCH] fix(split): fallback when deepseek-reasoner rejects tool_choice --- .env.example | 24 - .gitattributes | 1 + .gitignore | 2 + CLAUDE.md | 295 ++- README.md | 103 +- TODO.md | 12 - WEB_APP_GUIDE.md | 443 ---- backend/.env.example | 70 + .../__init__.py | 0 backend/agents/error_correction/__init__.py | 0 .../error_correction}/agent.py | 51 +- .../error_correction}/prompts.py | 124 +- .../error_correction}/schemas.py | 4 + .../error_correction}/tools/__init__.py | 0 .../error_correction}/tools/file_tools.py | 0 .../error_correction}/tools/question_tools.py | 2 +- backend/agents/note/__init__.py | 1 + backend/agents/note/agent.py | 136 ++ backend/agents/note/prompts.py | 52 + backend/agents/note/schemas.py | 14 + .../{solve_agent => agents/solve}/__init__.py | 0 .../{solve_agent => agents/solve}/agent.py | 2 +- .../{solve_agent => agents/solve}/prompts.py | 0 .../{solve_agent => agents/solve}/schemas.py | 0 .../{teach_agent => agents/teach}/__init__.py | 0 .../{teach_agent => agents/teach}/agent.py | 52 +- .../{teach_agent => agents/teach}/prompts.py | 0 backend/benchmark/collect.py | 4 +- backend/benchmark/evaluate.py | 2 +- backend/core/__init__.py | 0 backend/{ => core}/config.py | 17 +- backend/{ => core}/llm.py | 4 +- backend/core/mail.py | 59 + backend/core/state.py | 42 + backend/db/__init__.py | 12 +- backend/db/crud.py | 1102 ---------- backend/db/crud/__init__.py | 187 ++ backend/db/crud/chat.py | 176 ++ backend/db/crud/email_verification.py | 52 + backend/db/crud/notes.py | 180 ++ backend/db/crud/providers.py | 166 ++ backend/db/crud/questions.py | 477 +++++ backend/db/crud/split_records.py | 91 + backend/db/crud/stats.py | 272 +++ backend/db/crud/tags.py | 47 + backend/db/crud/users.py | 54 + backend/db/migrate.py | 18 +- backend/db/models.py | 51 +- backend/models/blocks.py | 135 ++ backend/models/config.py | 59 - backend/models/config.yaml | 51 - backend/models/inference.py | 31 +- backend/models/model.py | 644 ++---- backend/models/test_erase.py | 5 +- backend/models/train.py | 556 ----- backend/models/weight/best.pth | 3 + backend/package-lock.json | 6 + backend/routes/__init__.py | 22 + backend/routes/auth.py | 284 +++ backend/routes/chat.py | 303 +++ backend/routes/notes.py | 250 +++ backend/routes/questions.py | 660 ++++++ backend/routes/settings.py | 310 +++ backend/routes/stats.py | 79 + backend/routes/upload.py | 648 ++++++ backend/src/paddleocr_client.py | 4 +- backend/src/utils.py | 112 +- backend/src/workflow.py | 460 +++- backend/tests/test_agent_capabilities.py | 21 + backend/tests/test_chat_routes.py | 9 +- backend/tests/test_correct_node.py | 8 +- backend/tests/test_ocr_api.py | 59 +- backend/tests/test_question_tools.py | 16 +- backend/tests/test_schemas.py | 2 +- backend/tests/test_solve_integration.py | 2 +- backend/tests/test_solve_schemas.py | 2 +- backend/tests/test_split_integration.py | 4 +- backend/tests/test_utils.py | 2 +- backend/tests/test_web_helpers.py | 3 +- backend/tests/test_web_routes.py | 45 +- backend/tests/test_workflow_helpers.py | 12 +- backend/web_app.py | 1907 ++--------------- data-processing/README.md | 104 - data-processing/preprocessing/README.md | 101 - .../preprocessing/data_preprocessing.py | 508 ----- data-processing/preprocessing/examples.py | 69 - .../preprocessing/preprocessing_mode.json | 52 - .../processing/evaluation_recognition.py | 191 -- .../processing/exam_accuracy_results.json | 92 - .../processing/jiaocai_accuracy_results.json | 92 - .../exam/exam_accuracy_results.json | 92 - ...\243\346\236\220\357\274\211_page_003.png" | Bin 354755 -> 0 bytes ...\243\346\236\220\357\274\211_page_015.png" | Bin 427389 -> 0 bytes ...\275\345\215\267\357\274\211_page_001.png" | Bin 459307 -> 0 bytes ...-archive_1997_Solutions_1997s_page_003.png | Bin 440978 -> 0 bytes ...am-archive_2006_Problems_2006_page_001.png | Bin 489730 -> 0 bytes ...am-archive_2007_Problems_2007_page_001.png | Bin 435153 -> 0 bytes ...-archive_2009_Solutions_2009s_page_002.png | Bin 658109 -> 0 bytes ...-archive_2009_Solutions_2009s_page_003.png | Bin 731814 -> 0 bytes ...am-archive_2014_Problems_2014_page_001.png | Bin 490873 -> 0 bytes ...am-archive_2015_Problems_2015_page_001.png | Bin 436464 -> 0 bytes .../jiaocai/jiaocai_accuracy_results.json | 92 - .../jiaocai/jiaocai_jiaocai_en_117.jpg | Bin 64271 -> 0 bytes ...adeb6ea4da576068201b6c6958ce93f4.pdf_8.jpg | Bin 187356 -> 0 bytes .../jiaocaineedrop_eng-45646.pdf_30.jpg | Bin 188507 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_1249.jpg | Bin 240282 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_1303.jpg | Bin 293437 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_1544.jpg | Bin 257141 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_1884.jpg | Bin 232232 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_2002.jpg | Bin 266102 -> 0 bytes ...jiaocaineedrop_jiaocai_needrop_en_3428.jpg | Bin 373593 -> 0 bytes .../jiaocaineedrop_jiaocai_needrop_en_377.jpg | Bin 381546 -> 0 bytes .../standard_doc/DATA_LABELING_STANDARDS.md | 62 - .../standard_doc/SCANNING_STANDARDS.md | 32 - docs/API.md | 571 ----- docs/HANDWRITTEN_API.md | 287 --- docs/PROJECT_STRUCTURE.md | 1359 ------------ ...7\345\215\267\347\211\210\357\274\211.pdf" | Bin ...7\345\215\267\347\211\210\357\274\211.pdf" | Bin example_uploads/{ => exams}/test2.jpg | Bin example_uploads/{ => exams}/test3.jpg | Bin example_uploads/{ => exams}/test4.pdf | Bin example_uploads/{ => exams}/test5.jpg | Bin example_uploads/{ => exams}/test6.jpg | Bin ...7\347\254\254\344\270\200\351\235\242.jpg" | Bin ...7\347\254\254\344\272\214\351\235\242.jpg" | Bin example_uploads/{ => notes}/test.jpg | Bin frontend/LINEAR_DESIGN.md | 111 + frontend/app.html | 2 +- frontend/package.json | 1 + frontend/public/favicon.svg | 28 + frontend/public/logo.svg | 9 +- frontend/src/App.vue | 26 +- frontend/src/api.js | 155 +- frontend/src/assets/vue.svg | 1 - frontend/src/components/AuthLayout.vue | 177 -- frontend/src/components/AuthView.vue | 253 --- frontend/src/components/CalendarPicker.vue | 143 -- frontend/src/components/CustomSelect.vue | 78 - frontend/src/components/DateRangePicker.vue | 223 -- frontend/src/components/FileList.vue | 70 - frontend/src/components/FileUploader.vue | 99 - frontend/src/components/GlassCard.vue | 15 - frontend/src/components/LoginView.vue | 86 - frontend/src/components/PageHeader.vue | 59 - frontend/src/components/RegisterView.vue | 125 -- frontend/src/components/SearchInput.vue | 26 - frontend/src/components/StepIndicator.vue | 84 - .../components/auth/ForgotPasswordModal.vue | 231 ++ frontend/src/components/base/BaseButton.vue | 104 + frontend/src/components/base/BaseCard.vue | 19 + .../BaseGhostButton.vue} | 6 +- .../{AppLoading.vue => base/BaseLoading.vue} | 15 +- frontend/src/components/base/BaseLogo.vue | 72 + frontend/src/components/base/BaseSelect.vue | 80 + frontend/src/components/base/EmptyState.vue | 31 + .../src/components/{ => base}/ImageModal.vue | 6 +- frontend/src/components/base/SearchInput.vue | 30 + .../components/{ => base}/ToastContainer.vue | 6 +- .../components/{ => dashboard}/StatCard.vue | 6 +- frontend/src/components/home/HomeFooter.vue | 31 + frontend/src/components/home/HomeHeader.vue | 58 + frontend/src/components/home/HomePill.vue | 29 + frontend/src/components/home/HomeSideNav.vue | 49 + .../components/landing/LandingBackToTop.vue | 22 - .../src/components/landing/LandingCta.vue | 44 - .../src/components/landing/LandingDemo.vue | 73 - .../components/landing/LandingFeatures.vue | 58 - .../src/components/landing/LandingHero.vue | 347 --- .../src/components/landing/LandingNav.vue | 90 - .../components/landing/LandingWorkflow.vue | 122 -- .../{ => question}/EditNoteDialog.vue | 8 +- .../{ => question}/QuestionCard.vue | 74 +- .../{ => question}/QuestionDetailModal.vue | 38 +- .../{ => question}/QuestionItem.vue | 26 +- .../{ => question}/QuestionItemSkeleton.vue | 6 +- .../{ => question}/QuestionList.vue | 10 +- .../{ => review}/AiAnalysisModal.vue | 6 +- .../{ => settings}/ProviderDialog.vue | 25 +- .../{ => settings}/ProviderSection.vue | 6 +- .../components/{ => workspace}/ActionBar.vue | 38 +- .../components/workspace/AnswerInputModal.vue | 48 + .../src/components/workspace/ContentPanel.vue | 77 + .../src/components/workspace/ErasePreview.vue | 98 + .../workspace/ErrorBankFilterPanel.vue | 56 + .../src/components/workspace/FileList.vue | 69 + .../src/components/workspace/FileUploader.vue | 89 + .../src/components/workspace/OcrPreview.vue | 162 ++ .../src/components/workspace/ReviewStage.vue | 73 + .../{ => workspace}/SelectionPanel.vue | 6 +- .../src/components/workspace/SidebarNav.vue | 313 +++ .../{ => workspace}/SplitLoading.vue | 57 +- .../components/{ => workspace}/StatusBar.vue | 128 +- .../components/workspace/StepIndicator.vue | 96 + .../src/components/workspace/UploadStage.vue | 179 ++ .../workspace/WorkspaceBackground.vue | 64 + frontend/src/composables/useAiChatSessions.js | 89 + frontend/src/composables/useChatSession.js | 75 + frontend/src/composables/useFileUpload.js | 175 ++ frontend/src/composables/useImageModal.js | 28 + frontend/src/composables/usePageTransition.js | 4 +- frontend/src/composables/usePaginatedList.js | 81 + frontend/src/composables/useQuestionList.js | 30 + frontend/src/composables/useSelectableList.js | 38 + .../src/composables/useSidebarIndicator.js | 76 + frontend/src/composables/useSplitPipeline.js | 179 ++ frontend/src/composables/useSystemStatus.js | 74 + frontend/src/composables/useTheme.js | 57 + frontend/src/composables/useToast.js | 16 + frontend/src/composables/useWorkspaceNav.js | 90 + frontend/src/composables/useWorkspaceToast.js | 18 + frontend/src/main.js | 6 +- frontend/src/router/index.js | 42 +- frontend/src/style.css | 38 +- frontend/src/utils.js | 11 +- .../views/{LandingView.vue => HomeView.vue} | 158 +- frontend/src/views/WorkspaceView.vue | 1119 ---------- frontend/src/views/app/AppLayout.vue | 221 ++ frontend/src/views/app/ChatPageView.vue | 286 +++ .../{components => views/app}/ChatView.vue | 54 +- .../app/DashboardView.vue} | 99 +- .../app/ErrorBankView.vue} | 261 +-- frontend/src/views/app/NoteView.vue | 340 +++ .../{components => views/app}/ReviewView.vue | 104 +- .../app}/SettingsView.vue | 38 +- .../app/SplitHistoryView.vue} | 147 +- frontend/src/views/app/WorkspaceView.vue | 242 +++ frontend/src/views/auth/AuthLayout.vue | 286 +++ frontend/src/views/auth/LoginView.vue | 81 + frontend/src/views/auth/RegisterView.vue | 255 +++ frontend/src/views/home/HomeDemo.vue | 71 + frontend/src/views/home/HomeFeatures.vue | 133 ++ frontend/src/views/home/HomeHero.vue | 236 ++ frontend/src/views/home/HomeWorkflow.vue | 126 ++ frontend/tailwind.config.js | 6 +- frontend/vite.config.js | 23 +- requirements.txt | 1 + ...00\345\217\221\350\247\204\350\214\203.md" | 289 --- 238 files changed, 12737 insertions(+), 12837 deletions(-) delete mode 100644 .env.example create mode 100644 .gitattributes delete mode 100644 TODO.md delete mode 100644 WEB_APP_GUIDE.md create mode 100644 backend/.env.example rename backend/{error_correction_agent => agents}/__init__.py (100%) create mode 100644 backend/agents/error_correction/__init__.py rename backend/{error_correction_agent => agents/error_correction}/agent.py (72%) rename backend/{error_correction_agent => agents/error_correction}/prompts.py (68%) rename backend/{error_correction_agent => agents/error_correction}/schemas.py (80%) rename backend/{error_correction_agent => agents/error_correction}/tools/__init__.py (100%) rename backend/{error_correction_agent => agents/error_correction}/tools/file_tools.py (100%) rename backend/{error_correction_agent => agents/error_correction}/tools/question_tools.py (99%) create mode 100644 backend/agents/note/__init__.py create mode 100644 backend/agents/note/agent.py create mode 100644 backend/agents/note/prompts.py create mode 100644 backend/agents/note/schemas.py rename backend/{solve_agent => agents/solve}/__init__.py (100%) rename backend/{solve_agent => agents/solve}/agent.py (98%) rename backend/{solve_agent => agents/solve}/prompts.py (100%) rename backend/{solve_agent => agents/solve}/schemas.py (100%) rename backend/{teach_agent => agents/teach}/__init__.py (100%) rename backend/{teach_agent => agents/teach}/agent.py (55%) rename backend/{teach_agent => agents/teach}/prompts.py (100%) create mode 100644 backend/core/__init__.py rename backend/{ => core}/config.py (94%) rename backend/{ => core}/llm.py (94%) create mode 100644 backend/core/mail.py create mode 100644 backend/core/state.py delete mode 100644 backend/db/crud.py create mode 100644 backend/db/crud/__init__.py create mode 100644 backend/db/crud/chat.py create mode 100644 backend/db/crud/email_verification.py create mode 100644 backend/db/crud/notes.py create mode 100644 backend/db/crud/providers.py create mode 100644 backend/db/crud/questions.py create mode 100644 backend/db/crud/split_records.py create mode 100644 backend/db/crud/stats.py create mode 100644 backend/db/crud/tags.py create mode 100644 backend/db/crud/users.py create mode 100644 backend/models/blocks.py delete mode 100644 backend/models/config.py delete mode 100644 backend/models/config.yaml delete mode 100644 backend/models/train.py create mode 100644 backend/models/weight/best.pth create mode 100644 backend/package-lock.json create mode 100644 backend/routes/__init__.py create mode 100644 backend/routes/auth.py create mode 100644 backend/routes/chat.py create mode 100644 backend/routes/notes.py create mode 100644 backend/routes/questions.py create mode 100644 backend/routes/settings.py create mode 100644 backend/routes/stats.py create mode 100644 backend/routes/upload.py create mode 100644 backend/tests/test_agent_capabilities.py delete mode 100644 data-processing/README.md delete mode 100644 data-processing/preprocessing/README.md delete mode 100644 data-processing/preprocessing/data_preprocessing.py delete mode 100644 data-processing/preprocessing/examples.py delete mode 100644 data-processing/preprocessing/preprocessing_mode.json delete mode 100644 data-processing/processing/evaluation_recognition.py delete mode 100644 data-processing/processing/exam_accuracy_results.json delete mode 100644 data-processing/processing/jiaocai_accuracy_results.json delete mode 100644 data-processing/processing/sample_image/exam/exam_accuracy_results.json delete mode 100644 "data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_003.png" delete mode 100644 "data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_015.png" delete mode 100644 "data-processing/processing/sample_image/exam/exam_paper_2018\345\271\264\345\271\277\350\245\277\345\214\227\346\265\267\343\200\201\351\222\246\345\267\236\343\200\201\345\215\227\345\256\201\343\200\201\346\235\245\345\256\276\343\200\201\345\264\207\345\267\246\343\200\201\351\230\262\345\237\216\346\270\257\343\200\201\345\214\227\351\203\250\346\271\276\347\273\217\346\265\216\345\214\272\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\347\251\272\347\231\275\345\215\267\357\274\211_page_001.png" delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_1997_Solutions_1997s_page_003.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2006_Problems_2006_page_001.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2007_Problems_2007_page_001.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_002.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_003.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2014_Problems_2014_page_001.png delete mode 100644 data-processing/processing/sample_image/exam/exam_paper_en-file-putnam-archive_2015_Problems_2015_page_001.png delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocai_accuracy_results.json delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocai_jiaocai_en_117.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_624b60c58c9d8bfb6ff1886c2fd605d2adeb6ea4da576068201b6c6958ce93f4.pdf_8.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_eng-45646.pdf_30.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_1249.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_1303.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_1544.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_1884.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_2002.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_3428.jpg delete mode 100644 data-processing/processing/sample_image/jiaocai/jiaocaineedrop_jiaocai_needrop_en_377.jpg delete mode 100644 data-processing/standard_doc/DATA_LABELING_STANDARDS.md delete mode 100644 data-processing/standard_doc/SCANNING_STANDARDS.md delete mode 100644 docs/API.md delete mode 100644 docs/HANDWRITTEN_API.md delete mode 100644 docs/PROJECT_STRUCTURE.md rename "example_uploads/2023\345\271\264\351\207\215\345\272\206\345\270\202\344\270\255\350\200\203\345\214\226\345\255\246\347\234\237\351\242\230\357\274\210B\345\215\267\357\274\211\357\274\210\345\216\237\345\215\267\347\211\210\357\274\211.pdf" => "example_uploads/exams/2023\345\271\264\351\207\215\345\272\206\345\270\202\344\270\255\350\200\203\345\214\226\345\255\246\347\234\237\351\242\230\357\274\210B\345\215\267\357\274\211\357\274\210\345\216\237\345\215\267\347\211\210\357\274\211.pdf" (100%) rename "example_uploads/2023\345\271\264\351\207\215\345\272\206\345\270\202\344\270\255\350\200\203\347\211\251\347\220\206\350\257\225\351\242\230\357\274\210A\345\215\267\357\274\211\357\274\210\345\216\237\345\215\267\347\211\210\357\274\211.pdf" => "example_uploads/exams/2023\345\271\264\351\207\215\345\272\206\345\270\202\344\270\255\350\200\203\347\211\251\347\220\206\350\257\225\351\242\230\357\274\210A\345\215\267\357\274\211\357\274\210\345\216\237\345\215\267\347\211\210\357\274\211.pdf" (100%) rename example_uploads/{ => exams}/test2.jpg (100%) rename example_uploads/{ => exams}/test3.jpg (100%) rename example_uploads/{ => exams}/test4.pdf (100%) rename example_uploads/{ => exams}/test5.jpg (100%) rename example_uploads/{ => exams}/test6.jpg (100%) rename "example_uploads/\345\260\217\345\255\246\346\225\260\345\255\246\350\257\225\345\215\267\346\211\253\346\217\217\347\254\254\344\270\200\351\235\242.jpg" => "example_uploads/exams/\345\260\217\345\255\246\346\225\260\345\255\246\350\257\225\345\215\267\346\211\253\346\217\217\347\254\254\344\270\200\351\235\242.jpg" (100%) rename "example_uploads/\345\260\217\345\255\246\346\225\260\345\255\246\350\257\225\345\215\267\346\211\253\346\217\217\347\254\254\344\272\214\351\235\242.jpg" => "example_uploads/exams/\345\260\217\345\255\246\346\225\260\345\255\246\350\257\225\345\215\267\346\211\253\346\217\217\347\254\254\344\272\214\351\235\242.jpg" (100%) rename example_uploads/{ => notes}/test.jpg (100%) create mode 100644 frontend/LINEAR_DESIGN.md create mode 100644 frontend/public/favicon.svg delete mode 100644 frontend/src/assets/vue.svg delete mode 100644 frontend/src/components/AuthLayout.vue delete mode 100644 frontend/src/components/AuthView.vue delete mode 100644 frontend/src/components/CalendarPicker.vue delete mode 100644 frontend/src/components/CustomSelect.vue delete mode 100644 frontend/src/components/DateRangePicker.vue delete mode 100644 frontend/src/components/FileList.vue delete mode 100644 frontend/src/components/FileUploader.vue delete mode 100644 frontend/src/components/GlassCard.vue delete mode 100644 frontend/src/components/LoginView.vue delete mode 100644 frontend/src/components/PageHeader.vue delete mode 100644 frontend/src/components/RegisterView.vue delete mode 100644 frontend/src/components/SearchInput.vue delete mode 100644 frontend/src/components/StepIndicator.vue create mode 100644 frontend/src/components/auth/ForgotPasswordModal.vue create mode 100644 frontend/src/components/base/BaseButton.vue create mode 100644 frontend/src/components/base/BaseCard.vue rename frontend/src/components/{GlassButton.vue => base/BaseGhostButton.vue} (60%) rename frontend/src/components/{AppLoading.vue => base/BaseLoading.vue} (70%) create mode 100644 frontend/src/components/base/BaseLogo.vue create mode 100644 frontend/src/components/base/BaseSelect.vue create mode 100644 frontend/src/components/base/EmptyState.vue rename frontend/src/components/{ => base}/ImageModal.vue (88%) create mode 100644 frontend/src/components/base/SearchInput.vue rename frontend/src/components/{ => base}/ToastContainer.vue (95%) rename frontend/src/components/{ => dashboard}/StatCard.vue (94%) create mode 100644 frontend/src/components/home/HomeFooter.vue create mode 100644 frontend/src/components/home/HomeHeader.vue create mode 100644 frontend/src/components/home/HomePill.vue create mode 100644 frontend/src/components/home/HomeSideNav.vue delete mode 100644 frontend/src/components/landing/LandingBackToTop.vue delete mode 100644 frontend/src/components/landing/LandingCta.vue delete mode 100644 frontend/src/components/landing/LandingDemo.vue delete mode 100644 frontend/src/components/landing/LandingFeatures.vue delete mode 100644 frontend/src/components/landing/LandingHero.vue delete mode 100644 frontend/src/components/landing/LandingNav.vue delete mode 100644 frontend/src/components/landing/LandingWorkflow.vue rename frontend/src/components/{ => question}/EditNoteDialog.vue (97%) rename frontend/src/components/{ => question}/QuestionCard.vue (59%) rename frontend/src/components/{ => question}/QuestionDetailModal.vue (91%) rename frontend/src/components/{ => question}/QuestionItem.vue (70%) rename frontend/src/components/{ => question}/QuestionItemSkeleton.vue (91%) rename frontend/src/components/{ => question}/QuestionList.vue (91%) rename frontend/src/components/{ => review}/AiAnalysisModal.vue (98%) rename frontend/src/components/{ => settings}/ProviderDialog.vue (95%) rename frontend/src/components/{ => settings}/ProviderSection.vue (94%) rename frontend/src/components/{ => workspace}/ActionBar.vue (54%) create mode 100644 frontend/src/components/workspace/AnswerInputModal.vue create mode 100644 frontend/src/components/workspace/ContentPanel.vue create mode 100644 frontend/src/components/workspace/ErasePreview.vue create mode 100644 frontend/src/components/workspace/ErrorBankFilterPanel.vue create mode 100644 frontend/src/components/workspace/FileList.vue create mode 100644 frontend/src/components/workspace/FileUploader.vue create mode 100644 frontend/src/components/workspace/OcrPreview.vue create mode 100644 frontend/src/components/workspace/ReviewStage.vue rename frontend/src/components/{ => workspace}/SelectionPanel.vue (95%) create mode 100644 frontend/src/components/workspace/SidebarNav.vue rename frontend/src/components/{ => workspace}/SplitLoading.vue (76%) rename frontend/src/components/{ => workspace}/StatusBar.vue (67%) create mode 100644 frontend/src/components/workspace/StepIndicator.vue create mode 100644 frontend/src/components/workspace/UploadStage.vue create mode 100644 frontend/src/components/workspace/WorkspaceBackground.vue create mode 100644 frontend/src/composables/useAiChatSessions.js create mode 100644 frontend/src/composables/useChatSession.js create mode 100644 frontend/src/composables/useFileUpload.js create mode 100644 frontend/src/composables/useImageModal.js create mode 100644 frontend/src/composables/usePaginatedList.js create mode 100644 frontend/src/composables/useQuestionList.js create mode 100644 frontend/src/composables/useSelectableList.js create mode 100644 frontend/src/composables/useSidebarIndicator.js create mode 100644 frontend/src/composables/useSplitPipeline.js create mode 100644 frontend/src/composables/useSystemStatus.js create mode 100644 frontend/src/composables/useTheme.js create mode 100644 frontend/src/composables/useToast.js create mode 100644 frontend/src/composables/useWorkspaceNav.js create mode 100644 frontend/src/composables/useWorkspaceToast.js rename frontend/src/views/{LandingView.vue => HomeView.vue} (56%) delete mode 100644 frontend/src/views/WorkspaceView.vue create mode 100644 frontend/src/views/app/AppLayout.vue create mode 100644 frontend/src/views/app/ChatPageView.vue rename frontend/src/{components => views/app}/ChatView.vue (87%) rename frontend/src/{components/Dashboard.vue => views/app/DashboardView.vue} (82%) rename frontend/src/{components/ErrorBank.vue => views/app/ErrorBankView.vue} (68%) create mode 100644 frontend/src/views/app/NoteView.vue rename frontend/src/{components => views/app}/ReviewView.vue (82%) rename frontend/src/{components => views/app}/SettingsView.vue (92%) rename frontend/src/{components/SplitHistory.vue => views/app/SplitHistoryView.vue} (60%) create mode 100644 frontend/src/views/app/WorkspaceView.vue create mode 100644 frontend/src/views/auth/AuthLayout.vue create mode 100644 frontend/src/views/auth/LoginView.vue create mode 100644 frontend/src/views/auth/RegisterView.vue create mode 100644 frontend/src/views/home/HomeDemo.vue create mode 100644 frontend/src/views/home/HomeFeatures.vue create mode 100644 frontend/src/views/home/HomeHero.vue create mode 100644 frontend/src/views/home/HomeWorkflow.vue delete mode 100644 "\345\211\215\347\253\257\345\274\200\345\217\221\350\247\204\350\214\203.md" diff --git a/.env.example b/.env.example deleted file mode 100644 index 46e07193..00000000 --- a/.env.example +++ /dev/null @@ -1,24 +0,0 @@ -# ============================================================================ -# Flask 会话密钥(必须配置) -# ============================================================================ -SECRET_KEY=your-random-secret-key-change-this - -# ============================================================================ -# LangSmith 配置(可选,用于调试追踪) -# ============================================================================ -LANGSMITH_TRACING=false -# LANGSMITH_ENDPOINT=https://api.smith.langchain.com -# LANGSMITH_API_KEY=你的_langsmith_api_key -# LANGSMITH_PROJECT="error-correction" - -# ============================================================================ -# 输出目录配置(可选) -# ============================================================================ -# 目录配置由 config.py 集中管理(默认:backend/runtime_data/) -# 如需覆盖运行时输出的根目录,请设置 APP_RUNTIME_DIR(绝对路径) -# APP_RUNTIME_DIR= - -# ============================================================================ -# 注意:API Provider 配置(OpenAI / Anthropic / PaddleOCR)已迁移到数据库, -# 每个用户在系统设置页面独立管理自己的 API Key 和供应商配置。 -# ============================================================================ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..b763b395 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +backend/models/weight/*.pth filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 513c3f4a..53d02f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ dataset/ # 环境变量 .env +backend/.env PR.md +TODO.md diff --git a/CLAUDE.md b/CLAUDE.md index fc92d1df..9f6f3310 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,10 +19,12 @@ cd frontend && npm run dev # Vite dev server, proxy /api → :5001 ### 生产构建 ```bash -cd frontend && npm run build # 输出到 backend 静态目录 -cd backend && python web_app.py # Flask 托管前端产物,访问 :5001 +cd frontend && npm run build # 构建前端产物(目前仅用于部署,Flask 不再托管) +cd backend && python web_app.py # 启动纯 API 服务,仅监听 :5001 ``` +> **注意**:`web_app.py` 已重构为纯 API 服务器,不提供前端页面。前端必须通过 Vite dev server(`:5173`)或独立部署访问,直接访问 `:5001` 只会得到 JSON 404。 + ### 测试 ```bash @@ -47,7 +49,7 @@ cd frontend && npm install # 前端(Node 18+) ### 环境配置 -复制 `.env.example` → `.env`,至少配置一组 LLM API key(DeepSeek 或 ERNIE)和 PaddleOCR token。详见 `.env.example` 注释。 +复制 `backend/.env.example` → 项目根目录 `.env`,必须配置 `SECRET_KEY`。`core/config.py` 从项目根目录读取 `.env`。LLM API Provider 配置(OpenAI / Anthropic / PaddleOCR)已迁移到数据库,用户在系统设置页面管理。SMTP 邮件配置(注册验证码、找回密码)通过 `.env` 的 `APP_SMTP_*` 变量管理。 --- @@ -60,11 +62,13 @@ cd frontend && npm install # 前端(Node 18+) ``` 用户上传文件 → prepare_input(PDF 转图片) - → PaddleOCR API(异步任务,asyncio.gather 并行) + → [可选] EnsExam 擦除手写字迹(/api/erase,独立预处理步骤) + → PaddleOCR API(/api/ocr,异步并行,返回 bbox 预览) → simplify_ocr_results()(block_label 归一化,唯一转换点) → split_batch(2 页/批滑动窗口,ThreadPoolExecutor 并行,上限 3) → LLM Agent 分割题目(invoke_split) → _dedup_questions()(跨批次去重) + → _normalize_image_paths()(修复 LLM 篡改的图片路径) → LLM Agent 纠错(invoke_correction) → 导出 / 保存数据库 ``` @@ -72,23 +76,33 @@ cd frontend && npm install # 前端(Node 18+) ### 关键模块关系 - **`backend/src/workflow.py`** — LangGraph StateGraph 主工作流,串联所有处理步骤 -- **`backend/error_correction_agent/`** — 题目分割 + OCR 纠错 Agent(`create_agent` 工厂函数) -- **`backend/solve_agent/`** — 独立的解题 Agent -- **`backend/teach_agent/`** — 教学讲解 Agent,用于 AI 分析功能 -- **`backend/web_app.py`** — Flask 主应用,路由 + 全局会话状态(`session_lock` 保护) -- **`backend/config.py`** — 所有运行时路径集中管理,`ensure_dirs()` 显式初始化 -- **`backend/llm.py`** — `init_model()` 统一 LLM 初始化,支持 deepseek / ernie -- **`backend/db/`** — SQLite + SQLAlchemy ORM,错题库持久化 -- **`frontend/src/App.vue`** — 根组件,全局状态集中于此(无 Pinia/Vuex) +- **`backend/agents/error_correction/`** — 题目分割 + OCR 纠错 Agent(`create_inner_split_agent` / `create_inner_correct_agent`) +- **`backend/agents/solve/`** — 独立的解题 Agent(`invoke_solve`) +- **`backend/agents/teach/`** — 教学讲解 Agent,流式多轮对话(`stream_teach`) +- **`backend/agents/note/`** — 笔记整理 Agent,OCR → LLM 结构化(`invoke_note_organize`) +- **`backend/web_app.py`** — Flask 应用工厂,注册 7 个 Blueprint,全局 session 状态在 `state.py` +- **`backend/routes/`** — 7 个 Blueprint 模块(upload、questions、chat、stats、auth、settings、notes) +- **`backend/core/state.py`** — 全局会话状态(`session_files`、`session_lock`) +- **`backend/core/mail.py`** — SMTP 邮件发送(注册验证码、找回密码) +- **`backend/core/config.py`** — 所有运行时路径 + LLM provider 注册集中管理,`ensure_dirs()` 显式初始化 +- **`backend/core/llm.py`** — `init_model()` 统一 LLM 初始化,支持多 provider +- **`backend/db/`** — SQLite + SQLAlchemy ORM,错题库持久化;`db/crud/providers.py` 管理用户存储的 API key ### Flask 路由 -- `GET /` → 介绍页 | `GET /app` → Vue 工作台 -- `POST /api/upload` / `/api/split` / `/api/export` / `/api/cancel_file` — 核心工作流 API -- `GET /api/status` — 系统状态(OCR 配置、可用模型列表) -- `/api/error-bank` / `/api/subjects` / `/api/question-types` / `/api/stats` — 错题库 CRUD + 统计 -- `/api/chat` / `/api/chat//messages` / `/api/chat//stream` — AI 对话(SSE 流式) -- `/api/ai-analysis` — AI 分析(teach_agent) +路由实现在 `backend/routes/` 的 7 个 Blueprint 模块中,`web_app.py` 仅做注册: + +- `POST /api/upload` / `/api/erase` / `/api/ocr` / `/api/split` / `/api/export` / `/api/cancel_file` — 核心工作流 API(upload.py) +- `GET /api/image/` — 图片资源访问(upload.py) +- `GET /api/status` — 系统状态(OCR 配置、可用模型列表)(upload.py) +- `GET /api/split-records` — 分割历史记录(upload.py) +- `/api/error-bank` / `/api/subjects` / `/api/question-types` — 错题库 CRUD(questions.py) +- `/api/stats` — 统计数据(stats.py) +- `/api/chat` / `/api/chat//messages` / `/api/chat//stream` — AI 对话(SSE 流式)(chat.py) +- `/api/ai-analysis` — AI 分析(teach_agent)(chat.py) +- `/api/auth` / `/api/auth/send-code` / `/api/auth/reset-password` — 认证 + 邮箱验证码(auth.py) +- `/api/settings` — LLM provider 配置(settings.py) +- `/api/notes` — 笔记 CRUD(notes.py) --- @@ -107,63 +121,95 @@ cd frontend && npm install # 前端(Node 18+) ### 技术栈 - Vue 3 + ` + + + + +``` + - UI 文案使用中文,API 路径前缀 `/api/` - 新功能提取为独立 `.vue` 组件放 `src/components/` +- 认证组件放 `components/auth/`,首页组件放 `components/home/` - 关键 DOM 元素添加语义类名或 `data-testid` +- Modal/Dropdown 使用 `useClickOutside` 处理外部点击关闭 + +### Vite 配置 + +- API 代理:`/api`、`/images`、`/download`、`/erased`、`/uploads` → `http://localhost:5001` +- SPA 路由:`/auth*`、`/app*` → `app.html` +- 构建产物:`dist/` --- @@ -209,7 +340,7 @@ cd frontend && npm install # 前端(Node 18+) ### 模块级副作用 - **禁止在模块顶层执行有副作用的操作**(创建目录、写文件、启动连接等) -- `config.py` 目录创建通过 `ensure_dirs()` 显式调用 +- `core/config.py` 目录创建通过 `ensure_dirs()` 显式调用 - `load_dotenv()` 仅在入口文件或需要环境变量的模块中调用 ### 数据库 @@ -220,7 +351,7 @@ cd frontend && npm install # 前端(Node 18+) ### 线程安全 -- Flask 全局状态修改必须在 `session_lock` 保护下 +- 全局会话状态集中在 `core/state.py`,修改必须在 `session_lock` 保护下 - 锁内用原地修改(`.remove()`, `.append()`),**不要用推导式重新赋值** - Agent 缓存通过 `_agent_cache_lock` 保护并发初始化 @@ -228,9 +359,9 @@ cd frontend && npm install # 前端(Node 18+) - 结构化输出优先用 `create_agent` + `ToolStrategy` - 已知问题:`ToolStrategy` 与 DeepSeek 的 `handle_errors` 重试不兼容,大数据量可能触发 400 -- ernie 用 `model.with_structured_output()`(不支持 function calling) -- 轻量任务用 `DEEPSEEK_LIGHT_MODEL_NAME` / `ERNIE_LIGHT_MODEL_NAME` 小模型 +- 不支持 function calling 的模型用 `model.with_structured_output()` - `invoke_split` / `invoke_correction` 是统一调用入口,屏蔽 provider 差异 +- API Provider 配置(key、模型名)存储在数据库中,用户通过系统设置页面管理 ### OCR 数据处理 @@ -240,14 +371,18 @@ cd frontend && npm install # 前端(Node 18+) ### 文件与路径 -- 所有运行时路径通过 `config.py` 集中管理,禁止硬编码 +- 所有运行时路径通过 `core/config.py` 集中管理,禁止硬编码 - 文件名解析用 `os.path.splitext()`,**不要用 `rsplit('.', 1)`** - 文件上传用 `uuid.uuid4().hex` 生成安全文件名 ### 环境变量 -- `.env` 不入版本控制,`.env.example` 作为模板 -- 新增配置项必须同步更新 `.env.example` +- `.env` 放项目根目录,不入版本控制;`backend/.env.example` 作为模板 +- `core/config.py` 的 `Settings` 使用 `env_prefix="APP_"`,从项目根目录 `.env` 读取 +- LLM API Provider 配置已迁移到数据库,不再通过 `.env` 管理 +- Flask 级配置(`SECRET_KEY`、`FLASK_DEBUG`、`LANGSMITH_*`)仍通过 `.env` 管理 +- SMTP 邮件配置通过 `APP_SMTP_*` 变量管理(`core/mail.py`) +- 新增 `.env` 配置项必须同步更新 `backend/.env.example` - 可选项用 `os.getenv("KEY")` + 代码中提供默认值 --- diff --git a/README.md b/README.md index 66e80ad5..e0b214e7 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,59 @@ -# 错题本生成系统 +# 智卷 — 智能错题本生成系统 -基于 PaddleOCR + LangChain Agent 的智能错题本生成系统。上传试卷 PDF 或图片,自动识别文档结构、智能分割题目、OCR 纠错,导出为 Markdown 错题本并存入错题库,支持 AI 解题与教学讲解。 +基于 PaddleOCR + LangChain Agent 的智能错题本生成系统。上传试卷 PDF 或图片,自动识别文档结构、智能分割题目、OCR 纠错,导出为 Markdown 错题本并存入错题库。支持 AI 解题与教学讲解、笔记整理、独立 AI 对话、错题复习计划与数据统计。 ## 功能 -- **智能分割**:LLM Agent 自动识别题目边界,支持批次并行处理 +- **智能分割**:LLM Agent 自动识别题目边界,支持批次并行处理,跨页去重 - **OCR 纠错**:LLM 对识别结果进行结构化纠错,还原原题格式 -- **错题库**:SQLite 持久化存储,支持按科目、题型、日期筛选和统计 +- **手写擦除**:EnsExam 模型自动擦除手写字迹,提升 OCR 精度 +- **OCR 预览**:识别结果 bbox 框标注叠加在原图上,直观预览 +- **错题库**:SQLite 持久化存储,支持按科目、题型、知识点筛选和统计 +- **笔记整理**:上传手写笔记图片,OCR + LLM 自动结构化整理为 Markdown - **AI 解题**:独立解题 Agent,逐步给出解题过程 -- **AI 分析**:教学讲解 Agent,深度分析题目知识点 -- **AI 对话**:多轮对话,支持 SSE 流式输出 -- **导出**:导出为 Markdown 文件 +- **AI 教学**:教学讲解 Agent,绑定错题上下文的一对一辅导 +- **AI 对话**:独立多轮对话,支持 SSE 流式输出和深度思考(DeepSeek Reasoner) +- **复习计划**:间隔复习,追踪错题掌握状态 +- **数据统计**:Dashboard 可视化,按科目/题型/时间维度分析 +- **导出**:导出为 Markdown 文件,按大题分组 ## 项目结构 ``` -├── backend/ # Flask 后端(API + 静态资源托管) -│ ├── config.py # 集中配置(路径、目录) -│ ├── llm.py # LLM 初始化(DeepSeek / 文心) -│ ├── web_app.py # Flask 主应用(路由 + 会话状态) +├── backend/ # Flask 后端(纯 API 服务) +│ ├── core/ # 核心模块 +│ │ ├── config.py # 集中配置(路径、Settings) +│ │ ├── llm.py # LLM 初始化(多 provider 支持) +│ │ ├── state.py # 全局会话状态(session_files、锁) +│ │ └── mail.py # SMTP 邮件发送 +│ ├── web_app.py # Flask 应用工厂 + Blueprint 注册 +│ ├── routes/ # 7 个 Blueprint(upload、questions、chat、stats、auth、settings、notes) │ ├── src/ # 核心模块(LangGraph workflow、OCR 客户端、工具函数) -│ ├── error_correction_agent/ # LangChain Agent(题目分割、OCR 纠错、科目识别) -│ ├── solve_agent/ # 解题 Agent -│ ├── teach_agent/ # 教学讲解 Agent(AI 分析功能) -│ ├── benchmark/ # 模型评测(数据采集、评测运行、指标计算) -│ ├── db/ # SQLite 数据库(ORM 模型、CRUD) -│ └── tests/ # 后端测试(19 个测试模块) -├── frontend/ # Vue 3 + Vite + Tailwind CSS 前端 -│ ├── index.html # 介绍落地页 -│ ├── app.html # Vue 工作台入口 +│ ├── agents/ # LangChain Agent +│ │ ├── error_correction/ # 题目分割 + OCR 纠错 +│ │ ├── solve/ # 解题 Agent +│ │ ├── teach/ # 教学讲解 Agent +│ │ └── note/ # 笔记整理 Agent +│ ├── db/ # SQLite + SQLAlchemy ORM +│ │ ├── models.py # 数据模型(User、Question、Note、Chat 等) +│ │ ├── crud/ # CRUD 模块化包 +│ │ └── migrate.py # 数据库自动迁移 +│ ├── benchmark/ # 模型评测 +│ └── tests/ # 后端测试 +├── frontend/ # Vue 3 + Vite + Tailwind CSS +│ ├── app.html # SPA 入口 │ └── src/ -│ ├── App.vue # 根组件(侧边栏布局 + 视图路由) -│ ├── components/ # 18 个功能组件 +│ ├── views/ # 页面级组件(HomeView、WorkspaceView) +│ ├── components/ # 55+ 功能组件 +│ │ ├── auth/ # 认证(登录、注册、找回密码) +│ │ └── home/ # 首页组件 +│ ├── composables/ # 组合式函数(useAuth、useTheme 等) +│ ├── router/ # Vue Router 路由配置 +│ ├── api.js # 集中式 API 层 +│ ├── utils.js # 工具函数(Markdown 渲染、MathJax、DOMPurify) │ └── __tests__/ # 前端测试(Vitest) -├── example_uploads/ # 示例测试文件(图片 + PDF) -├── .env.example # 环境变量模板 +├── example_uploads/ # 示例测试文件 +├── backend/.env.example # 环境变量模板 └── requirements.txt # Python 依赖 ``` @@ -55,27 +74,15 @@ cd frontend && npm install ### 2. 配置环境变量 ```bash -copy .env.example .env +# 复制模板到项目根目录 +cp backend/.env.example .env ``` -编辑 `.env`,填写以下必需项: +编辑 `.env`,必须配置 `SECRET_KEY`。 -```dotenv -# LLM API(OpenAI 兼容接口,支持 OpenAI / DeepSeek / Qwen / Moonshot 等) -OPENAI_API_KEY=your_key -# OPENAI_BASE_URL=https://api.deepseek.com # 留空则使用 OpenAI 官方;填写后可切换 DeepSeek 等供应商 -# OPENAI_MODEL_NAME=gpt-4o-mini # 默认模型(可选) +LLM API Provider(OpenAI / Anthropic / PaddleOCR)配置已迁移到数据库,启动后在系统设置页面管理。 -# Anthropic API(可选,与 OpenAI 兼容接口二选一或同时配置) -# ANTHROPIC_API_KEY=your_key - -# PaddleOCR API(文档结构解析,V2 异步任务接口) -PADDLEOCR_API_URL=https://paddleocr.aistudio-app.com/api/v2/ocr/jobs -PADDLEOCR_API_TOKEN=your_token -PADDLEOCR_MODEL=PaddleOCR-VL-1.5 -``` - -> LLM 至少配置一种(OpenAI 兼容接口或 Anthropic),前端会自动检测可用模型。轻量模型、LangSmith 追踪、PaddleOCR 特性开关等可选配置见 `.env.example`。 +SMTP 邮件配置(注册验证码、找回密码)通过 `.env` 的 `APP_SMTP_*` 变量管理,详见 `backend/.env.example`。 ### 3. 启动 @@ -89,19 +96,11 @@ cd backend && python web_app.py cd frontend && npm run dev ``` -前端开发服务器会自动将 `/api`、`/images`、`/download` 请求代理到后端 `localhost:5001`。 - -**生产模式**(Flask 托管前端静态资源): +前端开发服务器会自动将 `/api`、`/images`、`/download`、`/erased`、`/uploads` 请求代理到后端 `localhost:5001`。 -```bash -# 构建前端 -cd frontend && npm run build - -# 启动后端(自动托管构建产物) -cd backend && python web_app.py -``` +访问 **http://localhost:5173** 即可使用。 -访问 **http://localhost:5001** 即可使用。 +> **注意**:后端已重构为纯 API 服务器,不提供前端页面。直接访问 `:5001` 只会得到 JSON 404。 ## 支持的文件格式 diff --git a/TODO.md b/TODO.md deleted file mode 100644 index ca6fc76d..00000000 --- a/TODO.md +++ /dev/null @@ -1,12 +0,0 @@ -# TODO - -## 用户级 API Key 存储 - -每个用户独立配置自己的 LLM API Key(AES-256 加密存 DB),替代系统全局 .env 配置。 - -- [ ] DB:用户表新增加密 api_key 字段(per provider) -- [ ] 后端:加解密工具函数(AES-256,密钥从 .env 读取) -- [ ] 后端:设置接口(POST 保存 / DELETE 删除 / GET 状态查询,不返回明文) -- [ ] 后端:调用 LLM 时优先使用用户 key,fallback 到系统全局 key -- [ ] 前端:设置页 API Key 管理 UI(输入、保存、删除、状态显示) -- [ ] .env.example:新增 API_KEY_ENCRYPTION_SECRET 配置项 diff --git a/WEB_APP_GUIDE.md b/WEB_APP_GUIDE.md deleted file mode 100644 index ea5324fe..00000000 --- a/WEB_APP_GUIDE.md +++ /dev/null @@ -1,443 +0,0 @@ -# Web应用使用指南 - -## 📱 功能简介 - -Web应用提供了一个可视化界面,用于测试错题本生成系统的完整工作流程。 - -### 主要功能 - -1. ✅ **文件上传** - 支持拖拽或点击上传PDF/图片 -2. ✅ **自动OCR解析** - 调用PaddleOCR API进行文档结构化解析 -3. ✅ **AI题目分割** - 使用DeepSeek Agent智能分割题目 -4. ✅ **题目预览** - 可视化展示分割后的题目 -5. ✅ **选择导出** - 勾选需要的题目并导出为Markdown格式 - ---- - -## 🚀 快速启动 - -### 1. 确保环境配置完成 - -检查 `.env` 文件是否包含必要的配置: - -```bash -# 必需配置 -PADDLEOCR_API_URL=https://... -PADDLEOCR_API_TOKEN=your_token -DEEPSEEK_API_KEY=your_key - -# 可选配置 -LANGSMITH_TRACING=true -LANGSMITH_API_KEY=your_key -``` - -### 2. 启动Web服务 - -```bash -python web_app.py -``` - -### 3. 访问界面 - -打开浏览器访问:**http://localhost:5001** - ---- - -## 📋 使用流程 - -### 步骤1: 上传文件 - -- **方式1**: 点击上传区域选择文件 -- **方式2**: 拖拽文件到上传区域 - -**支持格式**: -- PDF: `.pdf` -- 图片: `.png`, `.jpg`, `.jpeg`, `.bmp`, `.tiff`, `.webp` - -**文件大小**: 最大 50MB - -### 步骤2: OCR解析 - -文件上传后,系统会自动: -1. 将PDF转换为图片(如果是PDF) -2. 调用PaddleOCR API进行文档结构化解析 -3. 保存OCR结果到 `output/struct/` 目录 - -**进度显示**: -- 图片数量 -- OCR解析完成状态 - -### 步骤3: 分割题目 - -点击 **"🤖 开始分割题目"** 按钮: - -1. 系统调用DeepSeek Agent -2. Agent分析OCR结果 -3. 智能识别题号、题型、选项 -4. 保存分割结果到 `results/questions.json` - -**预计时间**: 10-30秒/页(取决于API响应速度) - -### 步骤4: 预览和导出 - -分割完成后: - -1. **预览题目**: 查看所有识别的题目 -2. **选择题目**: 勾选需要导出的题目 -3. **导出错题本**: 点击 **"📥 导出错题本"** 按钮 -4. **下载文件**: 点击下载链接获取Markdown文件 - ---- - -## 🔧 API端点说明 - -### 1. 系统状态检查 - -```http -GET /api/status -``` - -**响应**: -```json -{ - "success": true, - "status": { - "paddleocr_configured": true, - "deepseek_configured": true, - "langsmith_enabled": false, - "output_dirs": { - "pages": "output/pages", - "struct": "output/struct", - "results": "results" - } - } -} -``` - -### 2. 文件上传和OCR解析 - -```http -POST /api/upload -Content-Type: multipart/form-data - -file: <文件> -``` - -**响应**: -```json -{ - "success": true, - "message": "文件处理成功", - "result": { - "image_count": 3, - "ocr_count": 3, - "image_paths": ["output/pages/test_page_001.png", ...] - } -} -``` - -### 3. Agent分割题目 - -```http -POST /api/split -``` - -**响应**: -```json -{ - "success": true, - "message": "成功分割 5 道题目", - "questions": [ - { - "question_id": "1", - "question_type": "选择题", - "content_blocks": [...], - "options": ["A. ...", "B. ..."], - ... - } - ] -} -``` - -### 4. 导出错题本 - -```http -POST /api/export -Content-Type: application/json - -{ - "selected_ids": ["1", "2", "3"] -} -``` - -**响应**: -```json -{ - "success": true, - "message": "错题本导出成功", - "output_path": "results/wrongbook.md" -} -``` - -### 5. 获取题目列表 - -```http -GET /api/questions -``` - -**响应**: -```json -{ - "success": true, - "questions": [...] -} -``` - -### 6. 下载文件 - -```http -GET /download/wrongbook.md -``` - -直接下载Markdown文件 - ---- - -## 🎨 界面功能说明 - -### 系统状态指示器 - -顶部显示系统配置状态: -- ✓ **PaddleOCR**: API已配置 -- ✓ **DeepSeek**: API已配置 -- ✓ **LangSmith追踪**: 调试追踪已启用 - -### 步骤指示器 - -4步流程可视化: -1. **上传文件** - 上传PDF或图片 -2. **OCR解析** - 文档结构化识别 -3. **分割题目** - AI智能分割 -4. **预览导出** - 选择和导出 - -### 题目卡片 - -每道题目显示: -- 题号(如"题目 1") -- 题型标签(选择题/填空题/解答题) -- 题目内容(文本、公式、图片引用) -- 选项(如果是选择题) -- 复选框(用于选择导出) - ---- - -## ⚙️ 配置说明 - -### 端口配置 - -默认端口: **5001** - -修改端口(在 `web_app.py` 最后一行): -```python -app.run(host='0.0.0.0', port=8080, debug=True) -``` - -### 文件大小限制 - -默认: **50MB** - -修改限制(在 `web_app.py` 配置部分): -```python -app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB -``` - -### 上传目录 - -默认: `uploads/` - -修改目录(在 `web_app.py` 配置部分): -```python -UPLOAD_FOLDER = 'my_uploads' -``` - ---- - -## 🐛 常见问题 - -### Q1: 上传文件后长时间没有响应? - -**原因**: PaddleOCR API响应较慢或网络问题 - -**解决**: -1. 检查网络连接 -2. 查看浏览器控制台的网络请求 -3. 检查 `.env` 中的API配置是否正确 - -### Q2: Agent分割失败? - -**原因**: DeepSeek API配置错误或OCR结果为空 - -**解决**: -1. 检查 `DEEPSEEK_API_KEY` 是否正确 -2. 查看 `output/struct/` 目录下是否有OCR结果 -3. 检查 `results/split_issues.jsonl` 查看Agent记录的问题 - -### Q3: 题目预览显示为空? - -**原因**: Agent未能正确识别题目或保存失败 - -**解决**: -1. 检查 `results/questions.json` 是否存在 -2. 手动查看JSON文件内容 -3. 启用LangSmith追踪查看Agent执行日志 - -### Q4: 导出的Markdown文件在哪里? - -**位置**: `results/wrongbook.md` - -**下载**: 点击页面上的下载链接,或直接访问 `/download/wrongbook.md` - ---- - -## 🔍 调试技巧 - -### 1. 查看系统日志 - -启动Web应用后,终端会显示所有请求日志: -``` -127.0.0.1 - - [27/Jan/2026 10:30:15] "POST /api/upload HTTP/1.1" 200 - -127.0.0.1 - - [27/Jan/2026 10:30:45] "POST /api/split HTTP/1.1" 200 - -``` - -### 2. 检查中间结果 - -**标准化图片**: -```bash -ls output/pages/ -# test_page_001.png, test_page_002.png, ... -``` - -**OCR结果**: -```bash -ls output/struct/ -# test_page_001_struct.json, ... -``` - -**题目JSON**: -```bash -cat results/questions.json -``` - -**问题日志**: -```bash -cat results/split_issues.jsonl -``` - -### 3. 启用LangSmith追踪 - -在 `.env` 中设置: -```bash -LANGSMITH_TRACING=true -LANGSMITH_API_KEY=your_key -LANGSMITH_PROJECT=error-correction-web -``` - -然后访问 https://smith.langchain.com 查看Agent执行轨迹。 - -### 4. 浏览器开发者工具 - -按 `F12` 打开开发者工具: -- **Console**: 查看JavaScript错误 -- **Network**: 查看API请求和响应 -- **Application**: 查看本地存储 - ---- - -## 📊 性能优化 - -### 1. 减少处理时间 - -**方法1**: 降低图片DPI -```python -# 在 src/utils.py 的 prepare_input 函数中 -images = convert_from_path(file_path, dpi=200) # 默认300 -``` - -**方法2**: 关闭部分OCR功能 -```bash -# .env -PADDLEOCR_USE_DOC_ORIENTATION=false -PADDLEOCR_USE_DOC_UNWARPING=false -PADDLEOCR_USE_CHART_RECOGNITION=false -``` - -### 2. 提高并发处理能力 - -使用 gunicorn 代替 Flask 开发服务器: -```bash -pip install gunicorn -gunicorn -w 4 -b 0.0.0.0:5001 web_app:app -``` - -### 3. 添加缓存 - -对于相同文件,可以缓存OCR结果避免重复调用API。 - ---- - -## 🔒 安全注意事项 - -### 1. 文件上传安全 - -- ✅ 已限制文件扩展名 -- ✅ 已使用 `secure_filename` 处理文件名 -- ✅ 已限制文件大小(50MB) - -### 2. API密钥保护 - -- ⚠️ 不要将 `.env` 文件提交到版本控制 -- ⚠️ 生产环境使用更安全的密钥管理方案 - -### 3. 部署建议 - -如果部署到公网: -- 添加用户认证 -- 使用HTTPS -- 限制请求频率 -- 定期清理临时文件 - ---- - -## 🎯 扩展功能建议 - -### 1. 批量处理 - -支持一次上传多个文件并批量处理 - -### 2. 历史记录 - -保存处理历史,支持查看和重新导出 - -### 3. 自定义模板 - -允许用户自定义错题本的Markdown模板 - -### 4. 在线编辑 - -在导出前支持在线编辑题目内容 - ---- - -## 📞 技术支持 - -如遇到问题: - -1. 查看本文档的"常见问题"部分 -2. 检查 `docs/PROJECT_STRUCTURE.md` 了解系统架构 -3. 查看终端日志和浏览器控制台 -4. 启用LangSmith追踪进行调试 - ---- - -**文档版本**: v1.0.0 -**最后更新**: 2026-01-27 diff --git a/backend/.env.example b/backend/.env.example new file mode 100644 index 00000000..0bf1ebb6 --- /dev/null +++ b/backend/.env.example @@ -0,0 +1,70 @@ +# ============================================================================ +# Flask API 服务配置 SECRET_KEY必须配置! +# ============================================================================ +SECRET_KEY=your-random-secret-key-change-this +# 开发模式开关(true 启用热重载和调试信息,生产环境务必设为 false) +FLASK_DEBUG=false + +# ============================================================================ +# LangSmith 配置(可选,用于调试追踪) +# ============================================================================ +LANGSMITH_TRACING=false +# LANGSMITH_ENDPOINT=https://api.smith.langchain.com +# LANGSMITH_API_KEY=你的_langsmith_api_key +# LANGSMITH_PROJECT="error-correction" + +# ============================================================================ +# 输出目录配置(可选) +# ============================================================================ +# 目录配置由 config.py 集中管理(默认:backend/runtime_data/) +# 如需覆盖运行时输出的根目录,请设置 APP_RUNTIME_DIR(绝对路径) +# APP_RUNTIME_DIR= + +# ============================================================================ +# 文字擦除模型权重(可选) +# ============================================================================ +# 默认路径:backend/models/weight/best.pth +# 如需指定其他位置,取消注释并填写绝对路径 +# APP_MODEL_PATH=/path/to/your/best.pth + +# ============================================================================ + +# ============================================================================ +# 验证码邮件 — SMTP 配置(注册验证码 + 找回密码共用) +# +# 【必填项】APP_SMTP_HOST / APP_SMTP_USER / APP_SMTP_PASSWORD / APP_SMTP_FROM +# 未填写时无法发送验证码邮件。 +# 开发调试时可设置 FLASK_DEBUG=true,验证码会打印到后端日志,无需真实 SMTP。 +# +# 【发件账号说明】 +# APP_SMTP_USER — 发件邮箱地址(同时作为 SMTP 登录用户名) +# APP_SMTP_FROM — 邮件显示的发件人地址,通常与 USER 相同 +# APP_SMTP_PASSWORD — SMTP 授权码,不是邮箱登录密码! +# · QQ 邮箱:邮箱设置 → 账户 → POP3/IMAP/SMTP → 开启服务 → 生成授权码 +# · 163 邮箱:设置 → POP3/SMTP/IMAP → 开启 → 设置客户端授权密码 +# · Gmail:需开启两步验证后生成「应用专用密码」 +# +# 【端口与加密方式】 +# APP_SMTP_PORT=587 + APP_SMTP_USE_TLS=true → STARTTLS(推荐,先明文握手再加密) +# APP_SMTP_PORT=465 + APP_SMTP_USE_TLS=false → SSL/TLS(直连加密,代码自动切换 SMTP_SSL) +# +# 常用邮件服务商: +# QQ 邮箱 smtp.qq.com 587(STARTTLS) 或 465(SSL) +# 163 邮箱 smtp.163.com 587(STARTTLS) 或 465(SSL) +# Gmail smtp.gmail.com 587(STARTTLS) 或 465(SSL) +# Outlook smtp.office365.com 587(STARTTLS) +# +# 【频率与安全控制】 +# APP_REGISTRATION_CODE_TTL_MINUTES — 验证码有效期(分钟),默认 10 +# APP_REGISTRATION_SEND_INTERVAL_SECONDS — 同一邮箱重发最短间隔(秒),默认 60 +# APP_REGISTRATION_MAX_ATTEMPTS — 验证码最大错误次数,超出后需重新获取,默认 5 +# ============================================================================ +APP_SMTP_HOST=smtp.qq.com +APP_SMTP_PORT=587 +APP_SMTP_USER=your-email@qq.com +APP_SMTP_PASSWORD=your-smtp-authorization-code +APP_SMTP_FROM=your-email@qq.com +APP_SMTP_USE_TLS=true +APP_REGISTRATION_CODE_TTL_MINUTES=10 +APP_REGISTRATION_SEND_INTERVAL_SECONDS=60 +APP_REGISTRATION_MAX_ATTEMPTS=5 diff --git a/backend/error_correction_agent/__init__.py b/backend/agents/__init__.py similarity index 100% rename from backend/error_correction_agent/__init__.py rename to backend/agents/__init__.py diff --git a/backend/agents/error_correction/__init__.py b/backend/agents/error_correction/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/error_correction_agent/agent.py b/backend/agents/error_correction/agent.py similarity index 72% rename from backend/error_correction_agent/agent.py rename to backend/agents/error_correction/agent.py index f1c60318..c1947199 100644 --- a/backend/error_correction_agent/agent.py +++ b/backend/agents/error_correction/agent.py @@ -9,8 +9,8 @@ from langchain.agents.structured_output import ToolStrategy from langchain_core.messages import SystemMessage, HumanMessage -from config import settings -from llm import init_model as _init_model +from core.config import settings +from core.llm import init_model as _init_model from .prompts import SPLIT_PROMPT, SPLIT_PROMPT_LITE, CORRECTION_PROMPT from .schemas import QuestionSplitResult, CorrectionResult @@ -21,6 +21,35 @@ _agent_cache_lock = threading.Lock() +def _should_avoid_tool_strategy(provider: str, model_name: str | None, cfg) -> bool: + """判断是否应避免 ToolStrategy(避免发送 tool_choice 到不兼容模型)""" + if provider != "openai": + return False + + effective_model = (cfg.resolve_model_name(model_name) or "").lower() + base_url = (getattr(cfg, "base_url", "") or "").lower() + + # DeepSeek 推理模型(如 deepseek-reasoner)不支持 tool_choice + if "reasoner" in effective_model and "deepseek" in (effective_model + base_url): + return True + return False + + +def _invoke_with_json_schema_fallback(*, prompt: str, provider: str, model_name: str | None, temperature: float, schema, system_prompt: str): + """不使用 ToolStrategy 的结构化调用兜底路径。""" + model = _init_model(temperature=temperature, provider=provider, model_name=model_name) + messages = [ + SystemMessage(content=system_prompt), + HumanMessage(content=prompt), + ] + try: + # 对 OpenAI-compatible(含 DeepSeek)优先使用 json_mode,避免 tool_choice。 + return model.with_structured_output(schema, method="json_mode").invoke(messages) + except TypeError: + # 部分模型/版本不支持 method 参数。 + return model.with_structured_output(schema).invoke(messages) + + def detect_subject_via_llm(ocr_text_sample: str, db_subjects: list, provider: str = "openai") -> str: """通过轻量 LLM 识别试卷科目 @@ -123,12 +152,18 @@ def _invoke_structured( """通用结构化输出调用,屏蔽 ToolStrategy vs with_structured_output 差异""" cfg = settings.get_provider(provider) - if not cfg.supports_function_calling: - model = _init_model(temperature=temperature, provider=provider, model_name=model_name) - return model.with_structured_output(schema).invoke([ - SystemMessage(content=system_prompt_fallback), - HumanMessage(content=prompt), - ]) + if (not cfg.supports_function_calling) or _should_avoid_tool_strategy(provider, model_name, cfg): + if _should_avoid_tool_strategy(provider, model_name, cfg): + effective = cfg.resolve_model_name(model_name) + logger.info("模型 %s 不兼容 tool_choice,切换为 JSON 结构化兜底路径", effective) + return _invoke_with_json_schema_fallback( + prompt=prompt, + provider=provider, + model_name=model_name, + temperature=temperature, + schema=schema, + system_prompt=system_prompt_fallback, + ) full_key = f"{cache_key}_{provider}_{model_name or 'default'}" with _agent_cache_lock: diff --git a/backend/error_correction_agent/prompts.py b/backend/agents/error_correction/prompts.py similarity index 68% rename from backend/error_correction_agent/prompts.py rename to backend/agents/error_correction/prompts.py index 5e8c5c02..c17ae3f4 100644 --- a/backend/error_correction_agent/prompts.py +++ b/backend/agents/error_correction/prompts.py @@ -13,9 +13,11 @@ ## 最重要的规则(必须遵守) 1. **子题禁止拆分**:含(1)(2)(3)的大题必须作为一道题输出,question_id 用大题号(如 "17"),不要输出 "17-1"、"17-2" -2. **跨页连续性**:一道题的内容可能跨越两页。如果某页开头的内容块没有新题号(如 1. 2. 3.),它一定属于上一页最后一道题: +2. **主处理页与上下文页**:每页带有 `is_primary` 字段。`is_primary: true` 的页必须提取其中开始的所有题目;`is_primary: false` 的页仅作跨页补全参考,不要提取只在该页开始的独立题目。 +3. **跨页连续性**:一道题的内容可能跨越两页。如果某页开头的内容块没有新题号(如 1. 2. 3.),它一定属于上一页最后一道题: - 页首出现 A/B/C/D 选项但无题号 → 是上一题的选项 - 页首出现(1)(2)小问但无大题号 → 是上一题的子问内容 + - **页首出现 image block 且其后才出现新题号 → 该图片属于上一题,加入上一题 content_blocks 末尾,不归属本页第一道题** - **绝对不要把这类无题号内容创建为新题目** 3. **content_blocks 的 block_type 只能填 text 或 image**,不能填 paragraph_title 等其他值 4. **question_type 只能填**:选择题、填空题、解答题、判断题 @@ -31,9 +33,11 @@ ## 各字段填写 - question_id:题号,如 "1"、"2"、"17" +- section_title:该题所属的大题标题,即题目之前最近出现的 `paragraph_title` block 的文字,如"四、我会计算。";若试卷无大题结构则填 null - question_type:选择题/填空题/解答题/判断题 - content_blocks:题干内容,每项 {"block_type": "text"/"image", "content": "..."} - options:选择题的选项列表,其他题型填 null +- option_images:选项对应的图片路径列表,与 options 按索引一一对应。若某个选项的内容是一张图片(如实验装置图),将图片路径填入对应位置,无图片的选项填空字符串 ""。非选择题或选项无图片时填 null - has_formula:含公式填 true - has_image:含图片填 true - knowledge_tags:1-3 个知识点标签,如 ["三角函数", "诱导公式"] @@ -46,7 +50,8 @@ ## 表格处理 -内容含表格数据时,转为 HTML 放入 text 块:`
...
...
`,单元格内公式仍用 LaTeX。 +- 输入 block 的 `block_label` 为 `table` 时:将其 `block_content`(已是完整 HTML)原样作为一个 `block_type: text` 的 content_block 输出,禁止拆散单元格;若 HTML 含 `` 标签,路径加入 `image_refs`,设 `has_image: true` +- 纯文本表格数据需转换时:使用 `
...
...
` 结构放入 text 块,单元格内公式仍用 LaTeX ## OCR 变量下标还原 @@ -63,89 +68,25 @@ 你是一个专业的试卷题目分割专家。你的任务是分析OCR识别的文档结构,智能分割出独立的题目。 -## 核心任务 - -从PaddleOCR解析的结构化数据中: -1. 识别题目边界(题号是关键标志) -2. 提取题干内容(公式用 LaTeX 标记嵌入文本中) -3. 识别并提取选项(如果是选择题) -4. 识别图片块并保留引用 -5. 按阅读顺序组织内容 - -## 题目类型识别 - -### 1. 选择题 -- 特征:包含选项标记(A. B. C. D. 或 A) B) C) D)) -- 需提取:题号、题干、选项列表、公式、图片 - -### 2. 填空题 -- 特征:包含下划线 `_____` 或 `( )` -- 需提取:题号、题干、公式、图片 - -### 3. 解答题 -- 特征:要求"解答"、"证明"、"计算"等 -- 需提取:题号、题干、公式、图片 - -### 4. 判断题 -- 特征:要求判断"正确"、"错误"或"对"、"错" -- 需提取:题号、题干 - -## 题号识别规则 +## 题目类型与题号 -常见题号格式: -- `1.` `2.` `3.` ... -- `1、` `2、` `3、` ... -- `(1)` `(2)` `(3)` ... -- `一、` `二、` `三、` ... +**题型**(只能填以下之一):选择题(含 A/B/C/D 选项)、填空题(含 `___` 或 `( )`)、解答题(计算/证明/解答)、判断题 -注意: -- 题号通常在段落开头 -- 题号后跟随题干内容 -- 大题号可能包含子题号(如 1. (1) (2)) +**题号格式**:`1.` `1、` `(1)` 等阿拉伯数字编号为小题号;`一、` `二、` 等汉字序号为大题头(见下方注意事项) ## 工作流程 -1. **分析block顺序** - - 使用 block_order 确定阅读顺序 - - 按顺序扫描所有 block - -2. **识别题目起点** - - 查找包含题号的 text 或 paragraph_title block - - 记录题号和题型 - -3. **收集题目内容** - - 从题号开始,收集后续的 block - - 遇到下一个题号时停止 - - **content_blocks 的 block_type 只允许 `text` 或 `image` 两个值**。即使 OCR 原始数据中有 `paragraph_title`、`doc_title` 等标签,输出时一律归为 `text` - - 公式不单独成块,直接用 LaTeX 标记嵌入 text 的 content 中(行内 `$...$`,独占行 `$$...$$`) - - **图片必须嵌入 content_blocks**:所有属于该题目的 image block 都必须作为 `{"block_type": "image", "content": "/images/..."}` 加入 content_blocks,即使图片与选项关联(如实验操作图)。不要只放在 image_refs 中而不嵌入 content_blocks - -4. **结构化输出** - - 将每道题目组织为结构化数据 - - 输出格式由系统自动约束,请按 schema 字段填写 +1. 按 block_order 顺序扫描所有 block +2. 遇到 `paragraph_title` block(如"四、我会计算。")时,更新当前大题标题(`section_title`);该 block **不输出为题目** +3. 遇到阿拉伯数字题号(1. 2. 3.)时,标记为新题目起点,并将当前 `section_title` 写入该题 +4. 收集题目内容直到下一个题号:`content_blocks` 只允许 `text`/`image`;公式用 LaTeX 嵌入 text;图片必须作为 image block 加入 content_blocks +5. 按 schema 字段组织结构化输出 ## 知识点标注 -为每道题目标注 1-3 个知识点标签(填写到 `knowledge_tags` 字段),要求: - -1. **粒度为二级知识点**:使用具体的知识点名称,不要过于宽泛也不要过于细碎 - - 正确:`["三角函数", "诱导公式"]` - - 过于宽泛:`["数学"]` - - 过于细碎:`["三角函数的诱导公式在特殊角求值中的应用"]` -2. **使用中文短语**,4-8 个字为宜 -3. **优先复用已有标签**:如果调用时提供了 `existing_tags`(已有知识点标签池),请优先从中选取匹配的标签,只有确实没有匹配项时才创建新标签 -4. **示例**(数学): - - 复数求共轭 → `["复数", "复数运算"]` - - 求圆锥体积 → `["立体几何", "圆锥"]` - - 等差数列求和 → `["数列", "等差数列"]` - - 三角函数图像变换 → `["三角函数", "函数图像变换"]` - - 线性规划最值 → `["不等式", "线性规划"]` -5. **示例**(物理): - - 牛顿第二定律应用 → `["力学", "牛顿第二定律"]` - - 电场强度计算 → `["电磁学", "电场强度"]` -6. **示例**(化学): - - 离子方程式判断 → `["离子反应", "离子方程式"]` - - 化学平衡移动 → `["化学平衡", "平衡移动"]` +为每道题目标注 1-3 个知识点标签(`knowledge_tags`):使用二级知识点短语(4-8 字),有 `existing_tags` 时优先复用。 + +示例:等差数列求和 → `["数列", "等差数列"]`;牛顿第二定律 → `["力学", "牛顿第二定律"]`;离子方程式 → `["离子反应", "离子方程式"]` ## OCR 错误标记 @@ -186,10 +127,20 @@ - 含子题的大题:「17. 已知函数 f(x)…(1)求…(2)证明…」是同一道题的多问 → 输出 1 道题 - 板块标题本身不输出为任何题目,其分值说明也无需保留 -4. **跨页连续性** +4. **主处理页与上下文页(重要)** + - 每页数据带有 `is_primary` 字段 + - `is_primary: true`(主处理页):**必须**提取该页中出现的所有题目(含跨页延续到 context 页的题目) + - `is_primary: false`(上下文页):**仅**用于补全主处理页题目跨页的内容,**不要**提取只在该页开始的独立题目 + - 判断"题目在哪页开始":题号(阿拉伯数字)首次出现在哪页,就算在哪页开始 + +5. **跨页连续性** - 一道题的内容可能跨越两页。如果某页开头的内容块没有新题号,它属于上一页最后一道题 - 典型情况:页首出现 A/B/C/D 选项但无题号 → 是上一题的选项;页首出现(1)(2)小问但无大题号 → 是上一题的子问 - 不要把这类无题号的跨页内容创建为新题目 + - **页首图片的归属(极其重要)**:若某页最先出现的 block 是 image,且该图片**之前没有出现任何阿拉伯数字题号**,则该图片**属于上一道题**,必须将其加入上一题的 content_blocks 末尾,而不是归入本页第一道题。 + - 判断依据:图片归属看的是"该图片出现在哪道题的题号之后"。图片在题号之前 → 归上一题;图片在题号之后 → 归该题。 + - 即使本页第一道题的题干中含"如图所示",也不能把题号之前出现的图片归给它。 + - 示例:页面顺序为 `[image: 电路图] → [text: "21. 桔槔是..."]`,该电路图在题号 21 之前出现,应归属题号 20(上一题),而非题目 21。 5. **准确性优先** - 不确定的边界,宁可保守(保留更多内容) @@ -217,14 +168,19 @@ - 对于选择题,如果你已经把选项提取到 `options` 数组中,则必须从 `content_blocks` 的文本中移除选项部分 - `content_blocks` 只保留题干(题目正文),不包含选项文本 - 例如原始文本为 "下列说法正确的是()\\nA. xxx B. yyy",则 content_blocks 中的 text 只保留 "下列说法正确的是()",选项 "A. xxx"、"B. yyy" 放入 options 数组 + - **所有选项必须完整提取**:选择题通常有 4 个选项(A/B/C/D),务必逐一检查,不要遗漏任何选项。如果某个选项的 OCR 文本与图片分散在不同 block 中,仍需完整识别并提取 9. **表格处理(重要)** - - 如果题目内容中包含表格数据(如实验数据、统计数据、对比数据),必须将其转换为 HTML 表格 - - 使用如下结构,放入 `text` 类型的 content_block: - `
列1列2
值1值2
` - - 表格单元格内的公式仍然用 LaTeX 标记(如 `$x_i$`) - - 每行数据对应一个 ``,表头行放在 `` 中,数据行放在 `` 中 - - 例如:试验序号/伸缩率数据应输出为包含 `` 的 HTML 字符串,而不是纯文本 + + **情况一:输入 block 已是 table 类型(`block_label: "table"`)** + - 其 `block_content` 已是完整 HTML,**必须将整段 HTML 原样作为一个 `block_type: text` 的 content_block 输出** + - 禁止拆散单元格,禁止把表格中的图片单独提取为独立的 image block + - 若 HTML 中含有 `` 标签,将所有 src 路径加入 `image_refs`,并设 `has_image: true` + + **情况二:纯文本表格数据需要转换** + - 如果题目含有表格数据但输入为纯文本(如实验数据、统计数据、对比数据),将其转换为 HTML 表格,放入 `text` 类型的 content_block + - 使用结构:`
列1列2
值1值2
` + - 表格单元格内的公式仍用 LaTeX 标记(如 `$x_i$`) ## 示例 diff --git a/backend/error_correction_agent/schemas.py b/backend/agents/error_correction/schemas.py similarity index 80% rename from backend/error_correction_agent/schemas.py rename to backend/agents/error_correction/schemas.py index 5bff6bb6..ae7dc6b6 100644 --- a/backend/error_correction_agent/schemas.py +++ b/backend/agents/error_correction/schemas.py @@ -16,9 +16,11 @@ class ContentBlock(BaseModel): class Question(BaseModel): """单道题目""" question_id: str = Field(description="题号,如 '1', '2', '(1)' 等") + section_title: Optional[str] = Field(default=None, description="该题所属的大题标题,即题目之前最近出现的 paragraph_title block 的文字,如'四、我会计算。';若试卷无大题结构则为 null") question_type: Literal["选择题", "填空题", "解答题", "判断题"] = Field(description="题目类型") content_blocks: List[ContentBlock] = Field(description="题干内容块列表(不含选项)") options: Optional[List[str]] = Field(default=None, description="选项列表,仅选择题需要,如 ['A. xxx', 'B. yyy']") + option_images: Optional[List[str]] = Field(default=None, description="选项对应的图片路径列表,与 options 按索引一一对应;无图片的选项填 null 或空字符串") has_formula: bool = Field(default=False, description="是否包含数学公式") has_image: bool = Field(default=False, description="是否包含图片") image_refs: Optional[List[str]] = Field(default=None, description="图片引用路径列表") @@ -35,9 +37,11 @@ class QuestionSplitResult(BaseModel): class CorrectedQuestion(BaseModel): """纠错后的单道题目""" question_id: str = Field(description="题号") + section_title: Optional[str] = Field(default=None, description="所属大题标题,透传自分割结果,不需要修改") question_type: Literal["选择题", "填空题", "解答题", "判断题"] = Field(description="题目类型") content_blocks: List[ContentBlock] = Field(description="纠错后的题干内容块列表") options: Optional[List[str]] = Field(default=None, description="纠错后的选项列表") + option_images: Optional[List[str]] = Field(default=None, description="选项对应的图片路径列表,与 options 按索引一一对应") has_formula: bool = Field(default=False, description="是否包含数学公式") has_image: bool = Field(default=False, description="是否包含图片") image_refs: Optional[List[str]] = Field(default=None, description="图片引用路径列表") diff --git a/backend/error_correction_agent/tools/__init__.py b/backend/agents/error_correction/tools/__init__.py similarity index 100% rename from backend/error_correction_agent/tools/__init__.py rename to backend/agents/error_correction/tools/__init__.py diff --git a/backend/error_correction_agent/tools/file_tools.py b/backend/agents/error_correction/tools/file_tools.py similarity index 100% rename from backend/error_correction_agent/tools/file_tools.py rename to backend/agents/error_correction/tools/file_tools.py diff --git a/backend/error_correction_agent/tools/question_tools.py b/backend/agents/error_correction/tools/question_tools.py similarity index 99% rename from backend/error_correction_agent/tools/question_tools.py rename to backend/agents/error_correction/tools/question_tools.py index aa1943d1..37b95fd4 100644 --- a/backend/error_correction_agent/tools/question_tools.py +++ b/backend/agents/error_correction/tools/question_tools.py @@ -9,7 +9,7 @@ from typing import List, Dict, Any from dotenv import load_dotenv from langchain_core.tools import tool -from config import settings +from core.config import settings from src.utils import simplify_ocr_results, run_async load_dotenv() diff --git a/backend/agents/note/__init__.py b/backend/agents/note/__init__.py new file mode 100644 index 00000000..cc59c13f --- /dev/null +++ b/backend/agents/note/__init__.py @@ -0,0 +1 @@ +from .agent import invoke_note_organize diff --git a/backend/agents/note/agent.py b/backend/agents/note/agent.py new file mode 100644 index 00000000..7ef827da --- /dev/null +++ b/backend/agents/note/agent.py @@ -0,0 +1,136 @@ +""" +笔记整理 Agent — 将 OCR 文本整理为结构化 Markdown 笔记 + +支持: + - 重试机制(指数退避,最多 3 次) + - 多页分批处理(超过阈值时分批整理再合并) +""" + +import logging +import time + +from langchain_core.messages import SystemMessage, HumanMessage + +from core.config import settings +from core.llm import init_model +from .prompts import NOTE_ORGANIZE_PROMPT +from .schemas import OrganizedNote + +logger = logging.getLogger(__name__) + +# 单次 LLM 调用的文本长度上限(字符数),超过则分批 +BATCH_CHAR_LIMIT = 6000 +MAX_RETRIES = 3 + + +def _invoke_once(model, ocr_text: str) -> OrganizedNote: + """单次 LLM 调用,返回结构化笔记""" + structured_model = model.with_structured_output(OrganizedNote, method="function_calling") + return structured_model.invoke([ + SystemMessage(content=NOTE_ORGANIZE_PROMPT), + HumanMessage(content=f"以下是 OCR 识别出的课堂笔记原始文本,请整理为结构化笔记:\n\n{ocr_text}"), + ]) + + +def _invoke_with_retry(model, ocr_text: str) -> OrganizedNote: + """带指数退避的重试调用""" + last_error = None + for attempt in range(1, MAX_RETRIES + 1): + try: + result = _invoke_once(model, ocr_text) + if result: + return result + last_error = "LLM 未返回有效结果" + except Exception as e: + last_error = str(e) + logger.warning(f"笔记整理: 第 {attempt}/{MAX_RETRIES} 次失败: {last_error}") + + if attempt < MAX_RETRIES: + wait = 2 ** attempt # 2s, 4s + logger.info(f"笔记整理: {wait}s 后重试...") + time.sleep(wait) + + raise RuntimeError(f"笔记整理失败(重试 {MAX_RETRIES} 次): {last_error}") + + +def _split_text_into_batches(text: str) -> list: + """按行将文本拆分为多个批次,每批不超过 BATCH_CHAR_LIMIT 字符""" + lines = text.split('\n') + batches = [] + current = [] + current_len = 0 + + for line in lines: + if current_len + len(line) + 1 > BATCH_CHAR_LIMIT and current: + batches.append('\n'.join(current)) + current = [] + current_len = 0 + current.append(line) + current_len += len(line) + 1 + + if current: + batches.append('\n'.join(current)) + return batches + + +def _merge_notes(notes: list) -> OrganizedNote: + """合并多批次的笔记结果""" + # 用第一批的标题和科目 + title = notes[0].title + subject = notes[0].subject + + # 合并 Markdown 内容 + all_markdown = '\n\n'.join(n.content_markdown for n in notes) + + # 合并去重标签 + all_tags = [] + seen = set() + for n in notes: + for tag in n.knowledge_tags: + if tag not in seen: + all_tags.append(tag) + seen.add(tag) + + return OrganizedNote( + title=title, + subject=subject, + content_markdown=all_markdown, + knowledge_tags=all_tags[:5], # 最多 5 个 + ) + + +def invoke_note_organize( + ocr_text: str, + provider: str = "openai", + model_name: str = None, +) -> OrganizedNote: + """调用 LLM 将 OCR 文本整理为结构化笔记 + + 文本较短时直接整理,较长时分批处理再合并。 + 每次调用带 3 次重试(指数退避)。 + + Args: + ocr_text: OCR 识别出的原始文本 + provider: 模型供应商 + model_name: 指定模型名称,None 使用默认 + + Returns: + OrganizedNote 结构化结果 + """ + model = init_model(temperature=0.3, provider=provider, model_name=model_name) + + # 短文本:直接整理 + if len(ocr_text) <= BATCH_CHAR_LIMIT: + return _invoke_with_retry(model, ocr_text) + + # 长文本:分批处理 + batches = _split_text_into_batches(ocr_text) + logger.info(f"笔记文本较长({len(ocr_text)} 字符),分 {len(batches)} 批处理") + + results = [] + for i, batch in enumerate(batches): + logger.info(f"处理第 {i + 1}/{len(batches)} 批({len(batch)} 字符)") + result = _invoke_with_retry(model, batch) + results.append(result) + + return _merge_notes(results) diff --git a/backend/agents/note/prompts.py b/backend/agents/note/prompts.py new file mode 100644 index 00000000..09a9d270 --- /dev/null +++ b/backend/agents/note/prompts.py @@ -0,0 +1,52 @@ +""" +笔记整理 Prompt +""" + +NOTE_ORGANIZE_PROMPT = """你是一位专业的学习笔记整理助手。 + +## 任务 +将 OCR 识别出的课堂笔记原始文本,整理为结构清晰、条理分明的 Markdown 格式知识点笔记。 + +## 输入 +用户会提供 OCR 识别出的原始文本,可能包含: +- 手写笔记内容 +- 板书内容 +- 课堂重点标注 +- 公式、定理、定义 +- 例题和解题步骤 + +## 整理要求 + +### 标题 +- 根据笔记内容自动生成一个简洁的标题 +- 格式:【科目】主题,如 "高中数学 - 三角函数基本性质" + +### 内容整理 +1. **识别知识结构**:提取定义、定理、公式、性质、方法等 +2. **层级组织**:用 Markdown 标题(##、###)组织层级关系 +3. **公式还原**:将 OCR 可能识别不完整的数学公式用 LaTeX 标记还原(行内 $...$,独占行 $$...$$) +4. **要点标注**:用 **加粗** 标注重点,用 > 引用块标注注意事项 +5. **列表归纳**:零散的知识点用有序/无序列表归纳 +6. **纠正错误**:修正 OCR 识别中的明显错误(如乱码、错别字、符号错误) + +### 知识点标签 +- 提取 2-5 个核心知识点作为标签 +- 标签用中文,4-8 个字,如 "三角函数"、"诱导公式" +- 优先使用通用教材中的标准术语 + +### 科目识别 +- 根据内容判断科目,格式:学段+科目(如 "高中数学"、"初中物理") +- 无法判断时输出 "未知" + +### 图片处理 +- 输入文本中的 `[图片: /images/xxx.jpg]` 表示 OCR 识别到的图片(如几何图形、示意图、图表等) +- 在 Markdown 中对应位置插入图片引用:`![图片描述](/images/xxx.jpg)` +- 根据上下文给图片添加合适的描述文字(如 "平行四边形示意图"、"函数图像" 等) +- 不要遗漏任何图片 + +## 注意 +- 保留原始笔记中有价值的内容,不要遗漏 +- 不要添加原文中没有的知识内容 +- 如果原文有例题,保留例题和解法 +- 输出纯 Markdown,不要包含 ```markdown``` 代码块标记 +""" diff --git a/backend/agents/note/schemas.py b/backend/agents/note/schemas.py new file mode 100644 index 00000000..ef036f05 --- /dev/null +++ b/backend/agents/note/schemas.py @@ -0,0 +1,14 @@ +""" +笔记整理结构化输出 Schema +""" + +from typing import List, Optional +from pydantic import BaseModel, Field + + +class OrganizedNote(BaseModel): + """LLM 整理后的笔记结构""" + title: str = Field(description="笔记标题,根据内容自动生成,简洁明确") + subject: str = Field(description="科目,如 '高中数学'、'初中物理',无法判断则输出 '未知'") + content_markdown: str = Field(description="整理后的 Markdown 格式笔记内容,包含知识点归纳、公式、要点等") + knowledge_tags: List[str] = Field(description="知识点标签列表(2-5 个),如 ['三角函数', '诱导公式']") diff --git a/backend/solve_agent/__init__.py b/backend/agents/solve/__init__.py similarity index 100% rename from backend/solve_agent/__init__.py rename to backend/agents/solve/__init__.py diff --git a/backend/solve_agent/agent.py b/backend/agents/solve/agent.py similarity index 98% rename from backend/solve_agent/agent.py rename to backend/agents/solve/agent.py index bfa233d0..478b0fcb 100644 --- a/backend/solve_agent/agent.py +++ b/backend/agents/solve/agent.py @@ -11,7 +11,7 @@ from langchain_core.messages import SystemMessage, HumanMessage -from llm import init_model +from core.llm import init_model from .prompts import SOLVE_PROMPT from .schemas import SolveBatchResult diff --git a/backend/solve_agent/prompts.py b/backend/agents/solve/prompts.py similarity index 100% rename from backend/solve_agent/prompts.py rename to backend/agents/solve/prompts.py diff --git a/backend/solve_agent/schemas.py b/backend/agents/solve/schemas.py similarity index 100% rename from backend/solve_agent/schemas.py rename to backend/agents/solve/schemas.py diff --git a/backend/teach_agent/__init__.py b/backend/agents/teach/__init__.py similarity index 100% rename from backend/teach_agent/__init__.py rename to backend/agents/teach/__init__.py diff --git a/backend/teach_agent/agent.py b/backend/agents/teach/agent.py similarity index 55% rename from backend/teach_agent/agent.py rename to backend/agents/teach/agent.py index e8765051..67aca635 100644 --- a/backend/teach_agent/agent.py +++ b/backend/agents/teach/agent.py @@ -7,7 +7,7 @@ from langchain_core.messages import SystemMessage, HumanMessage, AIMessage -from llm import init_model +from core.llm import init_model from .prompts import build_teach_prompt logger = logging.getLogger(__name__) @@ -37,9 +37,15 @@ def _build_question_text(question: Dict[str, Any]) -> str: return "\n".join(parts) +GENERAL_SYSTEM_PROMPT = """你是一位专业的学习辅导助手,擅长数学、物理、化学、英语等学科。 +请用清晰、有条理的方式回答学生的问题。 +如果涉及数学公式,使用 LaTeX 标记(行内 $...$,独占行 $$...$$)。 +回答要准确、简洁,适合中学生和大学生理解。""" + + def stream_teach( *, - question: Dict[str, Any], + question: Dict[str, Any] = None, messages: List[Dict[str, str]], provider: str = "openai", model_name: str | None = None, @@ -47,8 +53,7 @@ def stream_teach( """流式教学对话 Args: - question: 题目数据(含 content_json, options_json, answer, question_type, - subject, knowledge_tags 等字段) + question: 题目数据(可选,None 为独立对话) messages: 对话历史 [{"role": "user"|"assistant", "content": "..."}] provider: 模型供应商 model_name: 指定模型名称,为 None 时使用 provider 默认模型 @@ -56,17 +61,20 @@ def stream_teach( Yields: 逐 token 的文本片段 """ - subject = question.get("subject") or "未知科目" - knowledge_tags = question.get("knowledge_tags") or [] - answer_text = question.get("answer") or "暂无答案" - question_text = _build_question_text(question) - - system_prompt = build_teach_prompt( - subject=subject, - knowledge_tags=knowledge_tags, - question_text=question_text, - answer_text=answer_text, - ) + if question: + subject = question.get("subject") or "未知科目" + knowledge_tags = question.get("knowledge_tags") or [] + answer_text = question.get("answer") or "暂无答案" + question_text = _build_question_text(question) + + system_prompt = build_teach_prompt( + subject=subject, + knowledge_tags=knowledge_tags, + question_text=question_text, + answer_text=answer_text, + ) + else: + system_prompt = GENERAL_SYSTEM_PROMPT # 构建 LangChain 消息列表 lc_messages = [SystemMessage(content=system_prompt)] @@ -79,6 +87,16 @@ def stream_teach( model = init_model(temperature=0.4, provider=provider, model_name=model_name) for chunk in model.stream(lc_messages): + # DeepSeek reasoner 模型会在 additional_kwargs 里返回 reasoning_content + reasoning = None + if hasattr(chunk, 'additional_kwargs'): + reasoning = chunk.additional_kwargs.get('reasoning_content') + token = chunk.content - if token: - yield token + # 安全处理:确保 token 是字符串(某些模型返回 list) + if isinstance(token, list): + token = ''.join(str(t) for t in token if t) + if reasoning and isinstance(reasoning, str): + yield {"type": "reasoning", "content": reasoning} + if token and isinstance(token, str): + yield {"type": "content", "content": token} diff --git a/backend/teach_agent/prompts.py b/backend/agents/teach/prompts.py similarity index 100% rename from backend/teach_agent/prompts.py rename to backend/agents/teach/prompts.py diff --git a/backend/benchmark/collect.py b/backend/benchmark/collect.py index 7026d402..68d2334a 100644 --- a/backend/benchmark/collect.py +++ b/backend/benchmark/collect.py @@ -29,7 +29,7 @@ if str(BACKEND_ROOT) not in sys.path: sys.path.insert(0, str(BACKEND_ROOT)) -from config import settings +from core.config import settings logger = logging.getLogger(__name__) @@ -93,7 +93,7 @@ def ocr_and_split(image_paths: List[str], provider: str = "openai") -> List[Dict batches = _build_overlapping_batches(ocr_data, batch_size=2, overlap=1) # 分割 - from error_correction_agent.tools import split_batch + from agents.error_correction.tools import split_batch all_questions = [] for batch_data in batches: diff --git a/backend/benchmark/evaluate.py b/backend/benchmark/evaluate.py index b9c64023..eca4e4ae 100644 --- a/backend/benchmark/evaluate.py +++ b/backend/benchmark/evaluate.py @@ -62,7 +62,7 @@ def run_evaluation(provider: str, targets: List[Dict[str, Any]]) -> Dict[str, An Returns: 评测报告 dict """ - from solve_agent import invoke_solve + from agents.solve import invoke_solve # 提取题目数据 questions = [] diff --git a/backend/core/__init__.py b/backend/core/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/backend/config.py b/backend/core/config.py similarity index 94% rename from backend/config.py rename to backend/core/config.py index dd11c106..f6c37683 100644 --- a/backend/config.py +++ b/backend/core/config.py @@ -12,7 +12,7 @@ _CONNECTION_CACHE_TTL = 60 # 连通性检测缓存有效期(秒) _providers_lock = threading.Lock() # 保护 llm_providers 并发读写 -_BACKEND_ROOT = Path(__file__).resolve().parent +_BACKEND_ROOT = Path(__file__).resolve().parent.parent # backend/core/ → backend/ _PROJECT_ROOT = _BACKEND_ROOT.parent _ENV_FILE = _PROJECT_ROOT / ".env" @@ -180,6 +180,17 @@ class Settings(BaseSettings): max_file_size_mb: int = 50 allowed_extensions: set[str] = {"pdf", "png", "jpg", "jpeg", "bmp", "tiff", "webp"} + # 注册验证码邮件(SMTP,环境变量前缀仍为 APP_,如 APP_SMTP_HOST) + smtp_host: str = "" + smtp_port: int = 587 + smtp_user: str = "" + smtp_password: str = "" + smtp_from: str = "" + smtp_use_tls: bool = True + registration_code_ttl_minutes: int = 10 + registration_send_interval_seconds: int = 60 + registration_max_attempts: int = 5 + # LLM 供应商注册表 llm_providers: dict[str, LLMProviderConfig] | None = None @@ -198,7 +209,7 @@ def _resolve_defaults(self): if self.erased_dir is None: self.erased_dir = self.runtime_dir / "erased" if self.model_path is None: - self.model_path = self.runtime_dir / "models" / "latest.pth" + self.model_path = _BACKEND_ROOT / "models" / "weight" / "best.pth" # 初始化 LLM 供应商注册表 if self.llm_providers is None: @@ -271,7 +282,7 @@ def load_providers_from_db(self, user_id: int) -> None: def _clear_agent_cache(self): """清除 agent 缓存""" try: - from error_correction_agent.agent import _agent_cache, _agent_cache_lock + from agents.error_correction.agent import _agent_cache, _agent_cache_lock with _agent_cache_lock: _agent_cache.clear() except ImportError: diff --git a/backend/llm.py b/backend/core/llm.py similarity index 94% rename from backend/llm.py rename to backend/core/llm.py index e361ed6a..91c44865 100644 --- a/backend/llm.py +++ b/backend/core/llm.py @@ -5,7 +5,7 @@ 供应商配置和工厂方法统一在 config.py 的 LLMProviderConfig 子类中定义。 """ -from config import settings +from core.config import settings def init_model( @@ -33,7 +33,7 @@ def init_model( """ if api_key: # 用传入的凭据动态构建配置,跳过环境变量 - from config import OpenAICompatibleConfig, AnthropicCompatibleConfig + from core.config import OpenAICompatibleConfig, AnthropicCompatibleConfig if provider == "anthropic": cfg = AnthropicCompatibleConfig( api_key=api_key, diff --git a/backend/core/mail.py b/backend/core/mail.py new file mode 100644 index 00000000..8e21fbe1 --- /dev/null +++ b/backend/core/mail.py @@ -0,0 +1,59 @@ +"""SMTP 发信(注册验证码等)。""" + +import logging +import smtplib +import threading +from email.mime.text import MIMEText + +logger = logging.getLogger(__name__) + + +def _send_sync( + host, port, user, password, mail_from, use_tls, to_addr, msg, +): + if port == 465: + smtp = smtplib.SMTP_SSL(host, port, timeout=15) + else: + smtp = smtplib.SMTP(host, port, timeout=15) + if use_tls: + smtp.starttls() + + with smtp: + if user and password: + smtp.login(user, password) + smtp.sendmail(mail_from, [to_addr], msg.as_string()) + + logger.info("已发送邮件至 %s", to_addr) + + +def send_smtp_email( + *, + host: str, + port: int, + user: str, + password: str, + mail_from: str, + use_tls: bool, + to_addr: str, + subject: str, + body: str, + async_send: bool = True, +) -> None: + if not host or not mail_from: + raise ValueError("SMTP 未配置:需要 smtp_host 与 smtp_from") + + msg = MIMEText(body, "plain", "utf-8") + msg["Subject"] = subject + msg["From"] = mail_from + msg["To"] = to_addr + + if async_send: + t = threading.Thread( + target=_send_sync, + args=(host, port, user, password, mail_from, use_tls, to_addr, msg), + daemon=True, + ) + t.start() + logger.info("邮件发送任务已提交(异步): %s", to_addr) + else: + _send_sync(host, port, user, password, mail_from, use_tls, to_addr, msg) diff --git a/backend/core/state.py b/backend/core/state.py new file mode 100644 index 00000000..1e3d85ab --- /dev/null +++ b/backend/core/state.py @@ -0,0 +1,42 @@ +""" +全局会话状态 — 供各 Blueprint 模块共享 + +所有需要跨路由访问的运行时变量集中在此模块, +通过 session_lock 保护并发写操作。 + +会话状态按 user_id 隔离,每个用户拥有独立的上传/分割上下文。 +""" + +import threading + +from src.workflow import build_workflow + +# 全局工作流图(无状态,可安全共享) +workflow_graph = build_workflow() + +# 线程锁(全局共享) +session_lock = threading.Lock() + +# ── 按用户隔离的会话状态 ────────────────────────────────── + +_user_sessions: dict = {} + + +def get_user_session(user_id) -> dict: + """获取或创建指定用户的会话状态""" + key = user_id if user_id is not None else "anon" + if key not in _user_sessions: + _user_sessions[key] = { + "current_thread_id": None, + "session_files": {}, # file_key → {filename, filepath} + "session_file_order": [], # 上传顺序 + "cancelled_file_keys": set(), # 已取消的文件 key + "erased_file_paths": None, # 擦除后的文件路径列表 + } + return _user_sessions[key] + + +def clear_user_session(user_id): + """清除指定用户的会话状态""" + key = user_id if user_id is not None else "anon" + _user_sessions.pop(key, None) diff --git a/backend/db/__init__.py b/backend/db/__init__.py index e53e5ae7..1904304c 100644 --- a/backend/db/__init__.py +++ b/backend/db/__init__.py @@ -9,7 +9,7 @@ # 添加 backend 目录到路径以支持导入 config sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from config import settings +from core.config import settings # 确保数据库目录存在 db_dir = settings.db_path.parent @@ -41,6 +41,16 @@ def _migrate_schema(): if 'answer' not in columns: cursor.execute("ALTER TABLE questions ADD COLUMN answer TEXT") conn.commit() + + # chat_sessions 表:question_id 需要改为 nullable + # SQLite 不支持 ALTER COLUMN,需要重建表 + cursor.execute("PRAGMA table_info(chat_sessions)") + cs_columns = {row[1]: row for row in cursor.fetchall()} + if 'title' not in cs_columns: + # 旧表结构,需要重建 + cursor.execute("DROP TABLE IF EXISTS chat_messages") + cursor.execute("DROP TABLE IF EXISTS chat_sessions") + conn.commit() finally: conn.close() diff --git a/backend/db/crud.py b/backend/db/crud.py deleted file mode 100644 index e79a56ed..00000000 --- a/backend/db/crud.py +++ /dev/null @@ -1,1102 +0,0 @@ -""" -数据库 CRUD 操作 -""" - -import hashlib -import json -import logging -import re -from datetime import datetime -from typing import List, Dict, Any, Optional, Tuple - -from sqlalchemy.orm import Session, joinedload, selectinload -from sqlalchemy import func - -logger = logging.getLogger(__name__) - -from db.models import UploadBatch, Question, KnowledgeTag, QuestionTagMapping, ChatSession, ChatMessage, SplitRecord, User, ProviderConfig - - -def _filter_by_subject(query, subject: Optional[str]): - """如有学科筛选,为 Question 查询追加 JOIN UploadBatch 过滤""" - if subject: - return query.join(UploadBatch).filter(UploadBatch.subject == subject) - return query - - - -def _filter_by_user(query, user_id): - if user_id is not None: - query = query.filter(Question.user_id == user_id) - return query - - -# ============================================================ -# 用户认证 CRUD -# ============================================================ - -def create_user(db, email, password_hash, username, is_admin=False): - """创建用户""" - user = User(email=email, password_hash=password_hash, username=username, is_admin=is_admin) - db.add(user) - try: - db.commit() - db.refresh(user) - return user - except Exception as e: - db.rollback() - raise - - -def get_user_by_email(db, email): - """按邮箱查询用户""" - return db.query(User).filter(User.email == email).first() - - -def get_user_by_id(db, user_id): - """按 ID 查询用户""" - return db.query(User).filter(User.id == user_id).first() - - -def get_user_by_login(db, identifier): - """按邮箱或用户名查询用户(登录用,大小写不敏感邮箱)""" - identifier = identifier.strip() - return db.query(User).filter( - (func.lower(User.email) == identifier.lower()) | (User.username == identifier) - ).first() - - -def _parse_tag_list(knowledge_tag: str) -> List[str]: - """将逗号分隔的标签字符串拆分为去空白的非空列表""" - return [t.strip() for t in knowledge_tag.split(',') if t.strip()] - - -def compute_content_hash(content_blocks: List[Dict]) -> str: - """ - 基于 content_blocks 计算去重哈希 - 使用题目文本内容计算 SHA256 - """ - text_parts = [] - for block in content_blocks: - if block.get("block_type") == "text": - text_parts.append(block.get("content", "")) - - text = " ".join(text_parts).strip() - if not text: - # 如果没有文本内容,使用整个 content_blocks 的 JSON 作为哈希源 - text = json.dumps(content_blocks, ensure_ascii=False) - - return hashlib.sha256(text.encode()).hexdigest() - - -def get_existing_subjects(db, user_id=None): - """获取数据库中已有的所有科目名称(去重)""" - query = db.query(UploadBatch.subject).distinct().filter( - UploadBatch.subject.isnot(None), - UploadBatch.subject != "", - ) - if user_id is not None: - query = query.filter(UploadBatch.user_id == user_id) - return [r[0] for r in query.all()] - - -def get_existing_tag_names(db: Session, subject: Optional[str] = None) -> List[str]: - """获取数据库中已有的知识点标签名称列表(字符串)""" - query = db.query(KnowledgeTag.tag_name).distinct() - if subject: - query = query.filter(KnowledgeTag.subject == subject) - rows = query.order_by(KnowledgeTag.tag_name).all() - return [r[0] for r in rows] - - -def get_or_create_tag(db: Session, tag_name: str, subject: str) -> KnowledgeTag: - """获取或创建知识点标签""" - tag = db.query(KnowledgeTag).filter_by( - tag_name=tag_name, - subject=subject - ).first() - - if not tag: - tag = KnowledgeTag(tag_name=tag_name, subject=subject) - db.add(tag) - db.flush() - - return tag - - -def question_exists(db, content_hash, user_id=None): - """检查题目是否已存在(通过内容哈希 + 用户隔离)""" - q = db.query(Question).filter(Question.content_hash == content_hash) - if user_id is not None: - q = q.filter(Question.user_id == user_id) - return q.first() - - -def save_questions_to_db( - db: Session, - questions: List[Dict], - batch_info: Dict[str, Any], - user_id=None, -) -> Dict[str, int]: - """ - 批量入库题目 - - Args: - db: 数据库会话 - questions: 题目列表(字典格式,来自 questions.json) - batch_info: 批次信息,包含 original_filename, file_path 等 - - Returns: - dict: {"created": 新增数量, "duplicates": 重复数量} - """ - # 科目由编排智能体识别,不再使用关键词匹配 - subject = batch_info.get("subject") or "未知" - - # 创建批次记录 - batch = UploadBatch( - user_id=user_id, - original_filename=batch_info.get("original_filename", "未知"), - subject=subject, - file_path=batch_info.get("file_path", ""), - upload_time=batch_info.get("upload_time") or datetime.utcnow() - ) - db.add(batch) - db.flush() # 获取 batch.id - - created = 0 - duplicates = 0 - - for q in questions: - content_blocks = q.get("content_blocks", []) - if not content_blocks: - continue - - content_hash = compute_content_hash(content_blocks) - - # 检查是否已存在 - if question_exists(db, content_hash, user_id=user_id): - duplicates += 1 - continue - - # 创建题目记录 - question = Question( - user_id=user_id, - batch_id=batch.id, - content_hash=content_hash, - question_type=q.get("question_type"), - content_json=json.dumps(content_blocks, ensure_ascii=False), - options_json=json.dumps(q.get("options"), ensure_ascii=False) if q.get("options") else None, - has_formula=q.get("has_formula", False), - has_image=q.get("has_image", False), - image_refs_json=json.dumps(q.get("image_refs"), ensure_ascii=False) if q.get("image_refs") else None, - needs_correction=q.get("needs_correction", False), - ocr_issues_json=json.dumps(q.get("ocr_issues"), ensure_ascii=False) if q.get("ocr_issues") else None, - answer=q.get("answer") or None, - user_answer=q.get("user_answer") or None, - ) - db.add(question) - db.flush() - - # 处理知识点标签 - knowledge_tags = q.get("knowledge_tags") or [] - for tag_name in knowledge_tags: - tag = get_or_create_tag(db, tag_name, subject) - mapping = QuestionTagMapping( - question_id=question.id, - tag_id=tag.id - ) - db.add(mapping) - - created += 1 - - db.commit() - - return {"created": created, "duplicates": duplicates} - - -def get_questions_by_subject( - db: Session, - subject: str, - limit: int = 100, - offset: int = 0 -) -> List[Question]: - """按科目查询题目""" - return db.query(Question).join(UploadBatch).filter( - UploadBatch.subject == subject - ).order_by(Question.created_at.desc()).offset(offset).limit(limit).all() - - -def get_questions_by_tag( - db: Session, - tag_name: str, - limit: int = 100, - offset: int = 0 -) -> List[Question]: - """按标签查询题目""" - return db.query(Question).join(QuestionTagMapping).join(KnowledgeTag).filter( - KnowledgeTag.tag_name == tag_name - ).order_by(Question.created_at.desc()).offset(offset).limit(limit).all() - - -def get_all_tags(db: Session, subject: Optional[str] = None) -> List[KnowledgeTag]: - """获取所有标签(可按科目筛选)""" - query = db.query(KnowledgeTag) - if subject: - query = query.filter(KnowledgeTag.subject == subject) - return query.order_by(KnowledgeTag.tag_name).all() - - -def get_statistics(db: Session, subject: Optional[str] = None, user_id=None) -> Dict[str, Any]: - """获取统计信息""" - q_query = _filter_by_subject(db.query(func.count(Question.id)), subject) - if user_id is not None: - q_query = q_query.filter(Question.user_id == user_id) - total_questions = q_query.scalar() - - batch_query = db.query(func.count(UploadBatch.id)) - if user_id is not None: - batch_query = batch_query.filter(UploadBatch.user_id == user_id) - total_batches = batch_query.scalar() - - total_tags = db.query(func.count(KnowledgeTag.id)).scalar() - - # 按科目统计 - subject_q = db.query(UploadBatch.subject, func.count(Question.id)).join(Question) - if user_id is not None: - subject_q = subject_q.filter(Question.user_id == user_id) - subject_stats = subject_q.group_by(UploadBatch.subject).all() - - return { - "total_questions": total_questions or 0, - "total_batches": total_batches or 0, - "total_tags": total_tags or 0, - "by_subject": {s: c for s, c in subject_stats} - } - - -def get_history_questions( - db: Session, - start_date: Optional[datetime] = None, - end_date: Optional[datetime] = None, - page: int = 1, - page_size: int = 20 -) -> Tuple[List[Question], int]: - """ - 分页查询历史题目(全部题目) - - Args: - db: 数据库会话 - start_date: 开始日期筛选 - end_date: 结束日期筛选 - page: 页码(从1开始) - page_size: 每页数量 - - Returns: - (题目列表, 总数) - """ - query = db.query(Question).join(UploadBatch) - - if start_date: - query = query.filter(UploadBatch.upload_time >= start_date) - if end_date: - from datetime import timedelta - query = query.filter(UploadBatch.upload_time < end_date + timedelta(days=1)) - - # 获取总数 - total = query.count() - - # 分页查询 - offset = (page - 1) * page_size - questions = ( - query.options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) - .order_by(Question.created_at.desc()) - .offset(offset) - .limit(page_size) - .all() - ) - - return questions, total - - -def search_questions( - db: Session, - keyword: Optional[str] = None, - knowledge_tag: Optional[str] = None, - question_type: Optional[str] = None, - page: int = 1, - page_size: int = 20 -) -> Tuple[List[Question], int]: - """ - 搜索题目(知识点/题型/关键字) - - Args: - db: 数据库会话 - keyword: 关键字搜索(匹配题目内容 content_json) - knowledge_tag: 知识点标签筛选 - question_type: 题型筛选 - page: 页码(从1开始) - page_size: 每页数量 - - Returns: - (题目列表, 总数) - """ - query = db.query(Question) - - # 关键字搜索:匹配 content_json 中的内容 - if keyword: - escaped = re.sub(r"([%_\\])", r"\\\1", keyword) - query = query.filter(Question.content_json.ilike(f"%{escaped}%")) - - # 题型筛选 - if question_type: - query = query.filter(Question.question_type == question_type) - - # 知识点标签筛选(支持逗号分隔多选,OR 语义) - if knowledge_tag: - tag_list = _parse_tag_list(knowledge_tag) - if tag_list: - query = query.join(QuestionTagMapping).join(KnowledgeTag).filter( - KnowledgeTag.tag_name.in_(tag_list) - ) - - # 获取总数(需要先去除distinct,因为join可能产生重复) - total = query.distinct().count() - - # 分页查询 - offset = (page - 1) * page_size - questions = ( - query.distinct() - .options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) - .order_by(Question.created_at.desc()) - .offset(offset) - .limit(page_size) - .all() - ) - - return questions, total - - -def get_knowledge_stats(db: Session, subject: Optional[str] = None, limit: Optional[int] = None, user_id=None) -> List[Dict]: - """ - 获取知识点统计信息 - - Args: - subject: 可选,按学科筛选 - limit: 可选,返回前 N 条 - user_id: 可选,按用户隔离 - - Returns: - [{"tag_name": "xxx", "count": 10}, ...] - """ - query = db.query( - KnowledgeTag.tag_name, - func.count(QuestionTagMapping.question_id).label("count") - ).join( - QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id - ) - - if user_id is not None: - query = query.join(Question, Question.id == QuestionTagMapping.question_id).filter( - Question.user_id == user_id - ) - - if subject: - query = query.filter(KnowledgeTag.subject == subject) - - query = query.group_by( - KnowledgeTag.id, KnowledgeTag.tag_name - ).order_by( - func.count(QuestionTagMapping.question_id).desc() - ) - - if limit: - query = query.limit(limit) - - stats = query.all() - - return [{"tag_name": tag_name, "count": count} for tag_name, count in stats] - - -def delete_question(db: Session, question_id: int) -> bool: - """ - 删除题目 - - Args: - db: 数据库会话 - question_id: 题目ID - - Returns: - 是否删除成功 - """ - question = db.query(Question).filter(Question.id == question_id).first() - if not question: - return False - - try: - # 删除关联的标签映射 - db.query(QuestionTagMapping).filter(QuestionTagMapping.question_id == question_id).delete() - - # 删除题目 - db.delete(question) - db.commit() - except Exception as e: - db.rollback() - logger.error(f"删除题目 {question_id} 失败: {e}") - raise - - return True - - -def query_questions( - db: Session, - subject: Optional[str] = None, - knowledge_tag: Optional[str] = None, - question_type: Optional[str] = None, - keyword: Optional[str] = None, - start_date: Optional[datetime] = None, - end_date: Optional[datetime] = None, - review_status: Optional[str] = None, - page: int = 1, - page_size: int = 20, - user_id=None, -) -> Tuple[List[Question], int]: - """ - 统一查询题目(合并 get_history_questions 和 search_questions 的能力) - - 支持所有筛选条件任意组合。 - """ - query = db.query(Question).join(UploadBatch) - - if user_id is not None: - query = query.filter(Question.user_id == user_id) - - if subject: - query = query.filter(UploadBatch.subject == subject) - - if question_type: - query = query.filter(Question.question_type == question_type) - - if keyword: - escaped = re.sub(r"([%_\\])", r"\\\1", keyword) - query = query.filter(Question.content_json.ilike(f"%{escaped}%")) - - if knowledge_tag: - tag_list = _parse_tag_list(knowledge_tag) - if tag_list: - query = query.join(QuestionTagMapping).join(KnowledgeTag).filter( - KnowledgeTag.tag_name.in_(tag_list) - ) - - if start_date: - query = query.filter(Question.created_at >= start_date) - if end_date: - from datetime import timedelta - query = query.filter(Question.created_at < end_date + timedelta(days=1)) - - if review_status: - query = query.filter(Question.review_status == review_status) - - total = query.distinct().count() - - offset = (page - 1) * page_size - questions = ( - query.distinct() - .options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) - .order_by(Question.created_at.desc()) - .offset(offset) - .limit(page_size) - .all() - ) - - return questions, total - - -def update_user_answer(db: Session, question_id: int, user_answer: str) -> Optional[Question]: - """更新用户答案""" - question = db.query(Question).filter(Question.id == question_id).first() - if not question: - return None - - try: - question.user_answer = user_answer - question.updated_at = datetime.utcnow() - db.commit() - db.refresh(question) - return question - except Exception as e: - db.rollback() - logger.error(f"更新题目 {question_id} 答案失败: {e}") - raise - - -def get_existing_question_types(db: Session, user_id=None) -> List[str]: - """获取数据库中已有的所有题型(去重)""" - query = db.query(Question.question_type).distinct().filter( - Question.question_type.isnot(None), - Question.question_type != "", - ) - if user_id is not None: - query = query.filter(Question.user_id == user_id) - return [r[0] for r in query.all()] - - -def get_questions_by_ids(db: Session, question_ids: List[int]) -> List[Question]: - """按 ID 列表批量查询题目""" - if not question_ids: - return [] - return ( - db.query(Question) - .options(joinedload(Question.batch), joinedload(Question.tags).joinedload(QuestionTagMapping.tag)) - .filter(Question.id.in_(question_ids)) - .all() - ) - - -VALID_REVIEW_STATUSES = ('待复习', '复习中', '已掌握') - - -def update_review_status(db: Session, question_id: int, review_status: str) -> Optional[Question]: - """更新题目复习状态""" - if review_status not in VALID_REVIEW_STATUSES: - raise ValueError(f"无效的复习状态: {review_status},可选值: {VALID_REVIEW_STATUSES}") - - question = db.query(Question).filter(Question.id == question_id).first() - if not question: - return None - - try: - question.review_status = review_status - question.updated_at = datetime.utcnow() - db.commit() - db.refresh(question) - return question - except Exception as e: - db.rollback() - logger.error(f"更新题目 {question_id} 复习状态失败: {e}") - raise - - -def get_review_status_stats(db: Session, subject: Optional[str] = None, user_id=None) -> Dict[str, int]: - """按复习状态分组统计数量""" - query = _filter_by_subject(db.query( - Question.review_status, - func.count(Question.id) - ), subject) - if user_id is not None: - query = query.filter(Question.user_id == user_id) - - rows = query.group_by(Question.review_status).all() - - result = {s: 0 for s in VALID_REVIEW_STATUSES} - for status, count in rows: - key = status or '待复习' - if key in result: - result[key] += count - else: - result['待复习'] += count - return result - - -def get_daily_counts(db: Session, days: int = 7, subject: Optional[str] = None, user_id=None) -> List[Dict[str, Any]]: - """获取最近 N 天每日新增题目数 + 每日新增已掌握数""" - from datetime import timedelta - cutoff = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=days - 1) - - # SQLite 兼容:使用 func.date() 提取日期字符串 - date_expr = func.date(Question.created_at) - - # 新增题目数 - query = _filter_by_subject(db.query( - date_expr.label('date'), - func.count(Question.id).label('count') - ).filter(Question.created_at >= cutoff), subject) - if user_id is not None: - query = query.filter(Question.user_id == user_id) - rows = query.group_by(date_expr).order_by(date_expr).all() - date_map = {str(row.date): row.count for row in rows} - - # 每日新增已掌握数(按 updated_at 统计) - mastered_date_expr = func.date(Question.updated_at) - mq = _filter_by_subject(db.query( - mastered_date_expr.label('date'), - func.count(Question.id).label('count') - ).filter( - Question.updated_at >= cutoff, - Question.review_status == '已掌握', - ), subject) - if user_id is not None: - mq = mq.filter(Question.user_id == user_id) - mastered_rows = mq.group_by(mastered_date_expr).order_by(mastered_date_expr).all() - mastered_map = {str(row.date): row.count for row in mastered_rows} - - # 填充缺失的日期 - result = [] - for i in range(days): - d = cutoff + timedelta(days=i) - date_key = d.strftime('%Y-%m-%d') - date_str = d.strftime('%m-%d') - result.append({ - 'date': date_str, - 'count': date_map.get(date_key, 0), - 'mastered': mastered_map.get(date_key, 0), - }) - - return result - - -def get_tag_status_stats(db: Session, subject: Optional[str] = None, limit: int = 10, user_id=None) -> List[Dict]: - """ - 知识点 × 掌握状态统计(堆叠柱状图用) - - Returns: - [{"tag_name": "函数", "待复习": 3, "复习中": 2, "已掌握": 5}, ...] - """ - query = db.query( - KnowledgeTag.tag_name, - Question.review_status, - func.count(Question.id).label('count') - ).join( - QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id - ).join( - Question, Question.id == QuestionTagMapping.question_id - ) - - if user_id is not None: - query = query.filter(Question.user_id == user_id) - if subject: - query = query.filter(KnowledgeTag.subject == subject) - - rows = query.group_by( - KnowledgeTag.tag_name, Question.review_status - ).all() - - # 按 tag 聚合 - tag_data = {} - tag_totals = {} - for tag_name, status, count in rows: - if tag_name not in tag_data: - tag_data[tag_name] = {'tag_name': tag_name, **{s: 0 for s in VALID_REVIEW_STATUSES}} - tag_totals[tag_name] = 0 - key = status or '待复习' - if key in VALID_REVIEW_STATUSES: - tag_data[tag_name][key] += count - else: - tag_data[tag_name]['待复习'] += count - tag_totals[tag_name] += count - - # 按总数降序,取 top N - sorted_tags = sorted(tag_data.keys(), key=lambda t: tag_totals[t], reverse=True)[:limit] - return [tag_data[t] for t in sorted_tags] - - -def get_tag_type_stats(db: Session, subject: Optional[str] = None, tag_limit: int = 8, user_id=None) -> Dict[str, Any]: - """ - 知识点 × 题型交叉统计(热力图用) - - Returns: - {"tags": ["函数", ...], "types": ["选择题", ...], "data": [[3, 1, ...], ...]} - """ - query = db.query( - KnowledgeTag.tag_name, - Question.question_type, - func.count(Question.id).label('count') - ).join( - QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id - ).join( - Question, Question.id == QuestionTagMapping.question_id - ).filter( - Question.question_type.isnot(None), - Question.question_type != '', - ) - - if user_id is not None: - query = query.filter(Question.user_id == user_id) - if subject: - query = query.filter(KnowledgeTag.subject == subject) - - rows = query.group_by( - KnowledgeTag.tag_name, Question.question_type - ).all() - - # 收集所有 tag 和 type - tag_totals = {} - type_set = set() - cross = {} - for tag_name, q_type, count in rows: - tag_totals[tag_name] = tag_totals.get(tag_name, 0) + count - type_set.add(q_type) - cross[(tag_name, q_type)] = count - - # 按总数取 top N tag - sorted_tags = sorted(tag_totals.keys(), key=lambda t: tag_totals[t], reverse=True)[:tag_limit] - sorted_types = sorted(type_set) - - # 构建矩阵 - data = [] - for tag in sorted_tags: - row = [cross.get((tag, t), 0) for t in sorted_types] - data.append(row) - - return {"tags": sorted_tags, "types": sorted_types, "data": data} - - -# ============================================================ -# 教学辅导对话 CRUD -# ============================================================ - - -def update_question_answer(db: Session, question_id: int, answer: str) -> Optional[Question]: - """保存/更新题目答案(Markdown 格式)""" - question = db.query(Question).filter(Question.id == question_id).first() - if not question: - return None - - try: - question.answer = answer - question.updated_at = datetime.utcnow() - db.commit() - db.refresh(question) - return question - except Exception as e: - db.rollback() - logger.error(f"保存题目 {question_id} 答案失败: {e}") - raise - - -def create_chat_session(db: Session, question_id: int) -> ChatSession: - """为题目创建新的对话会话""" - session = ChatSession(question_id=question_id) - db.add(session) - try: - db.commit() - db.refresh(session) - return session - except Exception as e: - db.rollback() - logger.error(f"创建对话会话失败: {e}") - raise - - -_VALID_ROLES = ('user', 'assistant') - - -def add_chat_message(db: Session, session_id: int, role: str, content: str) -> ChatMessage: - """向对话中追加一条消息""" - if role not in _VALID_ROLES: - raise ValueError(f"无效的消息角色: {role}(可选: {', '.join(_VALID_ROLES)})") - msg = ChatMessage(session_id=session_id, role=role, content=content) - db.add(msg) - try: - # 同步更新会话的 updated_at(直接 UPDATE 避免加载整行) - db.query(ChatSession).filter(ChatSession.id == session_id).update( - {"updated_at": datetime.utcnow()}, synchronize_session=False - ) - db.commit() - db.refresh(msg) - return msg - except Exception as e: - db.rollback() - logger.error(f"添加对话消息失败: {e}") - raise - - -def get_chat_messages( - db: Session, - session_id: int, - limit: int = 30, - before_id: Optional[int] = None, -) -> Dict[str, Any]: - """ - 游标分页获取对话消息 - - Args: - session_id: 会话 ID - limit: 每次返回的消息数 - before_id: 游标,返回 ID 小于此值的消息 - - Returns: - {"messages": [...], "hasMore": bool} - """ - query = db.query(ChatMessage).filter(ChatMessage.session_id == session_id) - if before_id: - query = query.filter(ChatMessage.id < before_id) - - # 按 ID 降序取 limit+1 条,判断是否还有更早消息 - rows = query.order_by(ChatMessage.id.desc()).limit(limit + 1).all() - - has_more = len(rows) > limit - messages = rows[:limit] - messages.reverse() # 恢复正序 - - return { - "messages": [ - {"id": m.id, "role": m.role, "content": m.content, "created_at": m.created_at.isoformat() if m.created_at else None} - for m in messages - ], - "hasMore": has_more, - } - - -def get_chat_sessions_by_question(db: Session, question_id: int, limit: int = 50) -> List[ChatSession]: - """获取某道题目的对话会话(按更新时间降序,默认最多 50 条)""" - return ( - db.query(ChatSession) - .filter(ChatSession.question_id == question_id) - .order_by(ChatSession.updated_at.desc()) - .limit(limit) - .all() - ) - - -# ============================================================ -# 分割历史记录 CRUD -# ============================================================ - - -MAX_SPLIT_RECORDS = 20 - - -def save_split_record( - db: Session, - subject: Optional[str], - model_provider: str, - file_names: List[str], - questions: List[Dict], - user_id=None, -) -> SplitRecord: - """保存一次分割操作的完整结果,超过上限自动清理最旧记录""" - record = SplitRecord( - user_id=user_id, - subject=subject, - model_provider=model_provider, - file_names_json=json.dumps(file_names, ensure_ascii=False), - questions_json=json.dumps(questions, ensure_ascii=False), - question_count=len(questions), - ) - db.add(record) - try: - db.commit() - db.refresh(record) - _cleanup_old_split_records(db) - return record - except Exception as e: - db.rollback() - logger.error(f"保存分割记录失败: {e}") - raise - - -def _cleanup_old_split_records(db: Session): - """删除超出上限的最旧分割记录""" - count = db.query(func.count(SplitRecord.id)).scalar() - if count <= MAX_SPLIT_RECORDS: - return - overflow = count - MAX_SPLIT_RECORDS - old_ids = [ - row[0] for row in - db.query(SplitRecord.id) - .order_by(SplitRecord.created_at.asc()) - .limit(overflow) - .all() - ] - try: - db.query(SplitRecord).filter(SplitRecord.id.in_(old_ids)).delete(synchronize_session=False) - db.commit() - logger.info(f"已清理 {overflow} 条过期分割记录") - except Exception as e: - db.rollback() - logger.error(f"清理分割记录失败: {e}") - - -def get_recent_split_records(db, limit: int = 10, user_id=None): - """获取最近 N 条分割记录(不加载 questions_json 大字段)""" - from sqlalchemy.orm import defer - return ( - db.query(SplitRecord) - .options(defer(SplitRecord.questions_json)) - .order_by(SplitRecord.created_at.desc()) - .limit(limit) - .all() - ) - - -def get_split_record_by_id(db: Session, record_id: int) -> Optional[SplitRecord]: - """按 ID 获取单条分割记录(含完整 questions_json)""" - return db.query(SplitRecord).filter(SplitRecord.id == record_id).first() - - -def get_all_chat_sessions( - db: Session, - page: int = 1, - page_size: int = 20, -) -> Tuple[List[ChatSession], int]: - """分页获取所有对话会话""" - query = db.query(ChatSession) - total = query.count() - offset = (page - 1) * page_size - sessions = ( - query.options(selectinload(ChatSession.question)) - .order_by(ChatSession.updated_at.desc()) - .offset(offset) - .limit(page_size) - .all() - ) - return sessions, total - - -# ── Provider Config CRUD ────────────────────────────────────── - - -def _mask_secret(value: str, visible: int = 4) -> str: - """脱敏显示密钥""" - if not value: - return "" - if len(value) <= visible: - return "*" * len(value) - return "*" * 4 + value[-visible:] - - -def _serialize_provider(p: ProviderConfig) -> dict: - """序列化 ProviderConfig 为前端可用 dict(密钥脱敏)""" - d = { - "id": p.id, - "name": p.name, - "is_active": p.is_active, - "api_key_set": bool(p.api_key), - "api_key_hint": _mask_secret(p.api_key), - "base_url": p.base_url or "", - "model_name": p.model_name or "", - } - if p.category == "openai": - d["light_model_name"] = p.light_model_name or "" - d["supports_function_calling"] = p.supports_function_calling - elif p.category == "paddleocr": - d["use_doc_orientation"] = p.use_doc_orientation - d["use_doc_unwarping"] = p.use_doc_unwarping - d["use_chart_recognition"] = p.use_chart_recognition - return d - - -def get_user_providers(db: Session, user_id: int) -> dict: - """获取用户的所有 provider 配置,按类别分组返回""" - providers = db.query(ProviderConfig).filter( - ProviderConfig.user_id == user_id - ).order_by(ProviderConfig.created_at).all() - - result = { - "openai_providers": [], - "anthropic_providers": [], - "paddleocr_providers": [], - "active_openai_id": None, - "active_anthropic_id": None, - "active_paddleocr_id": None, - } - category_key = { - "openai": "openai_providers", - "anthropic": "anthropic_providers", - "paddleocr": "paddleocr_providers", - } - active_key = { - "openai": "active_openai_id", - "anthropic": "active_anthropic_id", - "paddleocr": "active_paddleocr_id", - } - - for p in providers: - key = category_key.get(p.category) - if key: - result[key].append(_serialize_provider(p)) - if p.is_active: - ak = active_key.get(p.category) - if ak: - result[ak] = p.id - - return result - - -def save_user_providers(db: Session, user_id: int, data: dict) -> None: - """保存用户的 provider 配置(全量覆盖) - - data 结构: - openai_providers: [{ id, name, api_key?, base_url, model_name, ... }] - anthropic_providers: [...] - paddleocr_providers: [...] - active_openai_id: str | None - active_anthropic_id: str | None - active_paddleocr_id: str | None - """ - active_ids = { - "openai": data.get("active_openai_id"), - "anthropic": data.get("active_anthropic_id"), - "paddleocr": data.get("active_paddleocr_id"), - } - - # 读取已有配置(用于保留未重新提交的 api_key) - existing = { - p.id: p for p in db.query(ProviderConfig).filter( - ProviderConfig.user_id == user_id - ).all() - } - - # 收集本次提交的所有 ID - submitted_ids = set() - items_to_save = [] - - category_map = { - "openai_providers": "openai", - "anthropic_providers": "anthropic", - "paddleocr_providers": "paddleocr", - } - - for list_key, category in category_map.items(): - for item in data.get(list_key, []): - pid = item.get("id") - submitted_ids.add(pid) - old = existing.get(pid) - - # API Key:前端提交了新值则更新,否则保留旧值 - new_api_key = item.get("api_key") or item.get("api_token") or "" - if not new_api_key and old: - new_api_key = old.api_key or "" - - base_url = item.get("base_url") or item.get("api_url") or "" - model_name = item.get("model_name") or item.get("model") or "" - - items_to_save.append({ - "id": pid, - "category": category, - "name": item.get("name", ""), - "is_active": pid == active_ids.get(category), - "api_key": new_api_key, - "base_url": base_url, - "model_name": model_name, - "light_model_name": item.get("light_model_name", ""), - "supports_function_calling": item.get("supports_function_calling", True), - "use_doc_orientation": item.get("use_doc_orientation", False), - "use_doc_unwarping": item.get("use_doc_unwarping", False), - "use_chart_recognition": item.get("use_chart_recognition", False), - }) - - # 删除已移除的 provider - for pid in set(existing.keys()) - submitted_ids: - db.delete(existing[pid]) - - # 更新或新增 - for item in items_to_save: - old = existing.get(item["id"]) - if old: - for k, v in item.items(): - setattr(old, k, v) - else: - p = ProviderConfig(user_id=user_id, **item) - db.add(p) - - db.commit() - - -def get_active_provider(db: Session, user_id: int, category: str) -> Optional[ProviderConfig]: - """获取用户指定类别的激活 provider(用于后端调用 LLM/OCR 时读取凭据)""" - return db.query(ProviderConfig).filter( - ProviderConfig.user_id == user_id, - ProviderConfig.category == category, - ProviderConfig.is_active == True, - ).first() diff --git a/backend/db/crud/__init__.py b/backend/db/crud/__init__.py new file mode 100644 index 00000000..bd8967e2 --- /dev/null +++ b/backend/db/crud/__init__.py @@ -0,0 +1,187 @@ +""" +数据库 CRUD 操作 + +所有公共函数从子模块汇总导出,保持 ``from db import crud; crud.xxx()`` 的使用方式不变。 +""" + +from typing import Optional + +from db.models import UploadBatch, Question + + +# ── 共享过滤辅助函数 ────────────────────────────────────────── + +def _filter_by_subject(query, subject: Optional[str]): + """如有学科筛选,为 Question 查询追加 JOIN UploadBatch 过滤""" + if subject: + return query.join(UploadBatch).filter(UploadBatch.subject == subject) + return query + + +def _filter_by_user(query, user_id): + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return query + + +# ── 子模块导出 ──────────────────────────────────────────────── + +from db.crud.users import ( + create_user, + get_user_by_email, + get_user_by_id, + get_user_by_login, + update_user_password, +) + +from db.crud.email_verification import ( + get_verification_by_email, + upsert_registration_code, + delete_verification_by_email, + increment_verification_attempts, +) + +from db.crud.tags import ( + _parse_tag_list, + get_or_create_tag, + get_existing_tag_names, + get_all_tags, +) + +from db.crud.questions import ( + compute_content_hash, + question_exists, + save_questions_to_db, + get_questions_by_subject, + get_questions_by_tag, + get_history_questions, + search_questions, + query_questions, + get_questions_by_ids, + delete_question, + update_user_answer, + update_question_answer, + update_review_status, + get_existing_subjects, + get_existing_question_types, + VALID_REVIEW_STATUSES, +) + +from db.crud.stats import ( + get_statistics, + get_knowledge_stats, + get_review_status_stats, + get_today_mastered_count, + get_daily_counts, + get_tag_status_stats, + get_tag_type_stats, +) + +from db.crud.chat import ( + create_chat_session, + add_chat_message, + get_chat_messages, + get_chat_sessions_by_question, + get_all_chat_sessions, + get_user_chat_sessions, + update_chat_session_title, + delete_chat_session, +) + +from db.crud.split_records import ( + MAX_SPLIT_RECORDS, + save_split_record, + _cleanup_old_split_records, + get_recent_split_records, + get_split_record_by_id, +) + +from db.crud.providers import ( + _mask_secret, + _serialize_provider, + get_user_providers, + save_user_providers, + get_active_provider, +) + +from db.crud.notes import ( + save_note, + get_notes, + get_note_by_id, + update_note, + delete_note, +) + +__all__ = [ + # shared helpers + "_filter_by_subject", + "_filter_by_user", + # users + "create_user", + "get_user_by_email", + "get_user_by_id", + "get_user_by_login", + "update_user_password", + # email verification + "get_verification_by_email", + "upsert_registration_code", + "delete_verification_by_email", + "increment_verification_attempts", + # tags + "_parse_tag_list", + "get_or_create_tag", + "get_existing_tag_names", + "get_all_tags", + # questions + "compute_content_hash", + "question_exists", + "save_questions_to_db", + "get_questions_by_subject", + "get_questions_by_tag", + "get_history_questions", + "search_questions", + "query_questions", + "get_questions_by_ids", + "delete_question", + "update_user_answer", + "update_question_answer", + "update_review_status", + "get_existing_subjects", + "get_existing_question_types", + "VALID_REVIEW_STATUSES", + # stats + "get_statistics", + "get_knowledge_stats", + "get_review_status_stats", + "get_today_mastered_count", + "get_daily_counts", + "get_tag_status_stats", + "get_tag_type_stats", + # chat + "create_chat_session", + "add_chat_message", + "get_chat_messages", + "get_chat_sessions_by_question", + "get_all_chat_sessions", + "get_user_chat_sessions", + "update_chat_session_title", + "delete_chat_session", + # split_records + "MAX_SPLIT_RECORDS", + "save_split_record", + "_cleanup_old_split_records", + "get_recent_split_records", + "get_split_record_by_id", + # providers + "_mask_secret", + "_serialize_provider", + "get_user_providers", + "save_user_providers", + "get_active_provider", + # notes + "save_note", + "get_notes", + "get_note_by_id", + "update_note", + "delete_note", +] diff --git a/backend/db/crud/chat.py b/backend/db/crud/chat.py new file mode 100644 index 00000000..83fc3556 --- /dev/null +++ b/backend/db/crud/chat.py @@ -0,0 +1,176 @@ +"""对话 CRUD(支持题目绑定对话和独立对话)""" + +import logging +from datetime import datetime +from typing import List, Dict, Any, Optional, Tuple + +from sqlalchemy.orm import Session, selectinload + +from db.models import ChatSession, ChatMessage + +logger = logging.getLogger(__name__) + + +def create_chat_session( + db: Session, + question_id: int = None, + user_id: int = None, + title: str = "新对话", +) -> ChatSession: + """创建对话会话 + + Args: + question_id: 绑定的题目 ID(可选,None 为独立对话) + user_id: 用户 ID + title: 对话标题 + """ + session = ChatSession(question_id=question_id, user_id=user_id, title=title) + db.add(session) + try: + db.commit() + db.refresh(session) + return session + except Exception as e: + db.rollback() + logger.error(f"创建对话会话失败: {e}") + raise + + +_VALID_ROLES = ('user', 'assistant') + + +def add_chat_message(db: Session, session_id: int, role: str, content: str, user_id=None) -> ChatMessage: + """向对话中追加一条消息""" + if role not in _VALID_ROLES: + raise ValueError(f"无效的消息角色: {role}(可选: {', '.join(_VALID_ROLES)})") + # 验证 session 归属 + if user_id is not None: + owner_check = db.query(ChatSession).filter( + ChatSession.id == session_id, ChatSession.user_id == user_id + ).first() + if not owner_check: + raise ValueError("对话不存在或无权操作") + msg = ChatMessage(session_id=session_id, role=role, content=content) + db.add(msg) + try: + db.query(ChatSession).filter(ChatSession.id == session_id).update( + {"updated_at": datetime.utcnow()}, synchronize_session=False + ) + db.commit() + db.refresh(msg) + return msg + except Exception as e: + db.rollback() + logger.error(f"添加对话消息失败: {e}") + raise + + +def get_chat_messages( + db: Session, + session_id: int, + limit: int = 30, + before_id: Optional[int] = None, + user_id=None, +) -> Dict[str, Any]: + """游标分页获取对话消息""" + # 验证 session 归属 + if user_id is not None: + owner_check = db.query(ChatSession).filter( + ChatSession.id == session_id, ChatSession.user_id == user_id + ).first() + if not owner_check: + return {"messages": [], "hasMore": False} + query = db.query(ChatMessage).filter(ChatMessage.session_id == session_id) + if before_id: + query = query.filter(ChatMessage.id < before_id) + + rows = query.order_by(ChatMessage.id.desc()).limit(limit + 1).all() + has_more = len(rows) > limit + messages = rows[:limit] + messages.reverse() + + return { + "messages": [ + {"id": m.id, "role": m.role, "content": m.content, "created_at": m.created_at.isoformat() if m.created_at else None} + for m in messages + ], + "hasMore": has_more, + } + + +def get_chat_sessions_by_question(db: Session, question_id: int, limit: int = 50, user_id=None) -> List[ChatSession]: + """获取某道题目的对话会话""" + query = db.query(ChatSession).filter(ChatSession.question_id == question_id) + if user_id is not None: + query = query.filter(ChatSession.user_id == user_id) + return query.order_by(ChatSession.updated_at.desc()).limit(limit).all() + + +def get_user_chat_sessions( + db: Session, + user_id: int, + page: int = 1, + page_size: int = 20, +) -> Tuple[List[ChatSession], int]: + """获取用户的独立对话列表(不含题目绑定的对话)""" + query = db.query(ChatSession).filter( + ChatSession.user_id == user_id, + ChatSession.question_id == None, + ) + total = query.count() + sessions = ( + query.order_by(ChatSession.updated_at.desc()) + .offset((page - 1) * page_size) + .limit(page_size) + .all() + ) + return sessions, total + + +def get_all_chat_sessions( + db: Session, + page: int = 1, + page_size: int = 20, + user_id=None, +) -> Tuple[List[ChatSession], int]: + """分页获取对话会话(user_id 非 None 时按用户过滤)""" + query = db.query(ChatSession) + if user_id is not None: + query = query.filter(ChatSession.user_id == user_id) + total = query.count() + sessions = ( + query.options(selectinload(ChatSession.question)) + .order_by(ChatSession.updated_at.desc()) + .offset((page - 1) * page_size) + .limit(page_size) + .all() + ) + return sessions, total + + +def update_chat_session_title(db: Session, session_id: int, title: str, user_id=None) -> Optional[ChatSession]: + """更新对话标题""" + query = db.query(ChatSession).filter(ChatSession.id == session_id) + if user_id is not None: + query = query.filter(ChatSession.user_id == user_id) + session = query.first() + if not session: + return None + session.title = title + db.commit() + db.refresh(session) + return session + + +def delete_chat_session(db: Session, session_id: int, user_id=None) -> bool: + """删除对话(级联删除消息)""" + query = db.query(ChatSession).filter(ChatSession.id == session_id) + if user_id is not None: + query = query.filter(ChatSession.user_id == user_id) + session = query.first() + if not session: + return False + db.query(ChatMessage).filter(ChatMessage.session_id == session_id).delete() + db.delete(session) + db.commit() + return True diff --git a/backend/db/crud/email_verification.py b/backend/db/crud/email_verification.py new file mode 100644 index 00000000..b5d845b7 --- /dev/null +++ b/backend/db/crud/email_verification.py @@ -0,0 +1,52 @@ +"""注册邮箱验证码 CRUD""" + +from datetime import datetime + +from db.models import EmailVerification + + +def get_verification_by_email(db, email: str): + return db.query(EmailVerification).filter(EmailVerification.email == email).first() + + +def upsert_registration_code( + db, + email: str, + code_hash: str, + expires_at: datetime, + last_sent_at: datetime, +) -> EmailVerification: + row = get_verification_by_email(db, email) + if row: + row.code_hash = code_hash + row.expires_at = expires_at + row.last_sent_at = last_sent_at + # 不重置 attempts:防止攻击者反复请求新验证码来绕过尝试次数限制 + else: + row = EmailVerification( + email=email, + code_hash=code_hash, + expires_at=expires_at, + last_sent_at=last_sent_at, + attempts=0, + ) + db.add(row) + db.commit() + db.refresh(row) + return row + + +def delete_verification_by_email(db, email: str) -> None: + row = get_verification_by_email(db, email) + if row: + db.delete(row) + db.commit() + + +def increment_verification_attempts(db, email: str) -> int: + row = get_verification_by_email(db, email) + if not row: + return 0 + row.attempts = (row.attempts or 0) + 1 + db.commit() + return row.attempts diff --git a/backend/db/crud/notes.py b/backend/db/crud/notes.py new file mode 100644 index 00000000..89b0bf9b --- /dev/null +++ b/backend/db/crud/notes.py @@ -0,0 +1,180 @@ +""" +笔记 CRUD 操作 +""" + +import json +import logging +from typing import List, Dict, Any, Optional + +from sqlalchemy.orm import Session, selectinload + +from db.models import Note, NoteTagMapping, KnowledgeTag + +logger = logging.getLogger(__name__) + + +def save_note( + db: Session, + title: str, + subject: str, + content_markdown: str, + source_images: List[str], + ocr_text: str, + knowledge_tags: List[str] = None, + user_id: int = None, +) -> Note: + """保存一条笔记到数据库 + + Args: + title: 笔记标题 + subject: 科目 + content_markdown: LLM 整理后的 Markdown 内容 + source_images: 原始上传图片路径列表 + ocr_text: OCR 识别的原始文本 + knowledge_tags: 知识点标签名称列表 + user_id: 用户 ID + + Returns: + 创建的 Note 对象 + """ + note = Note( + user_id=user_id, + title=title, + subject=subject, + content_markdown=content_markdown, + source_images_json=json.dumps(source_images, ensure_ascii=False), + ocr_text=ocr_text, + ) + db.add(note) + db.flush() # 获取 note.id + + # 创建知识点标签关联 + if knowledge_tags: + from db.crud.tags import get_or_create_tag + for tag_name in knowledge_tags: + tag_name = tag_name.strip() + if not tag_name: + continue + tag = get_or_create_tag(db, tag_name, subject or "") + mapping = NoteTagMapping(note_id=note.id, tag_id=tag.id) + db.add(mapping) + + db.commit() + db.refresh(note) + return note + + +def get_notes( + db: Session, + user_id: int = None, + subject: str = None, + knowledge_tag: str = None, + keyword: str = None, + page: int = 1, + page_size: int = 20, +) -> tuple: + """分页查询笔记列表 + + Returns: + (笔记列表, 总数) + """ + query = db.query(Note).options( + selectinload(Note.tags).selectinload(NoteTagMapping.tag), + ) + + if user_id is not None: + query = query.filter(Note.user_id == user_id) + if subject: + query = query.filter(Note.subject == subject) + if keyword: + query = query.filter( + Note.title.ilike(f"%{keyword}%") | + Note.content_markdown.ilike(f"%{keyword}%") + ) + if knowledge_tag: + query = query.join(NoteTagMapping).join(KnowledgeTag).filter( + KnowledgeTag.tag_name == knowledge_tag + ) + + total = query.count() + notes = ( + query.order_by(Note.updated_at.desc()) + .offset((page - 1) * page_size) + .limit(page_size) + .all() + ) + return notes, total + + +def get_note_by_id(db: Session, note_id: int, user_id=None) -> Optional[Note]: + """根据 ID 获取单条笔记""" + query = db.query(Note).options( + selectinload(Note.tags).selectinload(NoteTagMapping.tag), + ).filter(Note.id == note_id) + if user_id is not None: + query = query.filter(Note.user_id == user_id) + return query.first() + + +def update_note( + db: Session, + note_id: int, + title: str = None, + content_markdown: str = None, + subject: str = None, + knowledge_tags: List[str] = None, + user_id=None, +) -> Optional[Note]: + """更新笔记内容 + + Args: + note_id: 笔记 ID + title: 新标题(None 不更新) + content_markdown: 新 Markdown 内容(None 不更新) + subject: 新科目(None 不更新) + knowledge_tags: 新标签列表(None 不更新,空列表清空标签) + + Returns: + 更新后的 Note 对象,不存在返回 None + """ + query = db.query(Note).filter(Note.id == note_id) + if user_id is not None: + query = query.filter(Note.user_id == user_id) + note = query.first() + if not note: + return None + + if title is not None: + note.title = title + if content_markdown is not None: + note.content_markdown = content_markdown + if subject is not None: + note.subject = subject + + # 更新标签:先删后建 + if knowledge_tags is not None: + db.query(NoteTagMapping).filter(NoteTagMapping.note_id == note_id).delete() + from db.crud.tags import get_or_create_tag + for tag_name in knowledge_tags: + tag_name = tag_name.strip() + if not tag_name: + continue + tag = get_or_create_tag(db, tag_name, note.subject or "") + db.add(NoteTagMapping(note_id=note.id, tag_id=tag.id)) + + db.commit() + db.refresh(note) + return note + + +def delete_note(db: Session, note_id: int, user_id=None) -> bool: + """删除笔记(级联删除标签关联)""" + query = db.query(Note).filter(Note.id == note_id) + if user_id is not None: + query = query.filter(Note.user_id == user_id) + note = query.first() + if not note: + return False + db.delete(note) + db.commit() + return True diff --git a/backend/db/crud/providers.py b/backend/db/crud/providers.py new file mode 100644 index 00000000..49388aac --- /dev/null +++ b/backend/db/crud/providers.py @@ -0,0 +1,166 @@ +"""Provider Config CRUD""" + +import logging +from typing import Optional + +from sqlalchemy.orm import Session + +from db.models import ProviderConfig + +logger = logging.getLogger(__name__) + + +def _mask_secret(value: str, visible: int = 4) -> str: + """脱敏显示密钥""" + if not value: + return "" + if len(value) <= visible: + return "*" * len(value) + return "*" * 4 + value[-visible:] + + +def _serialize_provider(p: ProviderConfig) -> dict: + """序列化 ProviderConfig 为前端可用 dict(密钥脱敏)""" + d = { + "id": p.id, + "name": p.name, + "is_active": p.is_active, + "api_key_set": bool(p.api_key), + "api_key_hint": _mask_secret(p.api_key), + "base_url": p.base_url or "", + "model_name": p.model_name or "", + } + if p.category == "openai": + d["light_model_name"] = p.light_model_name or "" + d["supports_function_calling"] = p.supports_function_calling + elif p.category == "paddleocr": + d["use_doc_orientation"] = p.use_doc_orientation + d["use_doc_unwarping"] = p.use_doc_unwarping + d["use_chart_recognition"] = p.use_chart_recognition + return d + + +def get_user_providers(db: Session, user_id: int) -> dict: + """获取用户的所有 provider 配置,按类别分组返回""" + providers = db.query(ProviderConfig).filter( + ProviderConfig.user_id == user_id + ).order_by(ProviderConfig.created_at).all() + + result = { + "openai_providers": [], + "anthropic_providers": [], + "paddleocr_providers": [], + "active_openai_id": None, + "active_anthropic_id": None, + "active_paddleocr_id": None, + } + category_key = { + "openai": "openai_providers", + "anthropic": "anthropic_providers", + "paddleocr": "paddleocr_providers", + } + active_key = { + "openai": "active_openai_id", + "anthropic": "active_anthropic_id", + "paddleocr": "active_paddleocr_id", + } + + for p in providers: + key = category_key.get(p.category) + if key: + result[key].append(_serialize_provider(p)) + if p.is_active: + ak = active_key.get(p.category) + if ak: + result[ak] = p.id + + return result + + +def save_user_providers(db: Session, user_id: int, data: dict) -> None: + """保存用户的 provider 配置(全量覆盖) + + data 结构: + openai_providers: [{ id, name, api_key?, base_url, model_name, ... }] + anthropic_providers: [...] + paddleocr_providers: [...] + active_openai_id: str | None + active_anthropic_id: str | None + active_paddleocr_id: str | None + """ + active_ids = { + "openai": data.get("active_openai_id"), + "anthropic": data.get("active_anthropic_id"), + "paddleocr": data.get("active_paddleocr_id"), + } + + # 读取已有配置(用于保留未重新提交的 api_key) + existing = { + p.id: p for p in db.query(ProviderConfig).filter( + ProviderConfig.user_id == user_id + ).all() + } + + # 收集本次提交的所有 ID + submitted_ids = set() + items_to_save = [] + + category_map = { + "openai_providers": "openai", + "anthropic_providers": "anthropic", + "paddleocr_providers": "paddleocr", + } + + for list_key, category in category_map.items(): + for item in data.get(list_key, []): + pid = item.get("id") + submitted_ids.add(pid) + old = existing.get(pid) + + # API Key:前端提交了新值则更新,否则保留旧值 + new_api_key = item.get("api_key") or item.get("api_token") or "" + if not new_api_key and old: + new_api_key = old.api_key or "" + + base_url = item.get("base_url") or item.get("api_url") or "" + model_name = item.get("model_name") or item.get("model") or "" + + items_to_save.append({ + "id": pid, + "category": category, + "name": item.get("name", ""), + "is_active": pid == active_ids.get(category), + "api_key": new_api_key, + "base_url": base_url, + "model_name": model_name, + "light_model_name": item.get("light_model_name", ""), + "supports_function_calling": item.get("supports_function_calling", True), + "use_doc_orientation": item.get("use_doc_orientation", False), + "use_doc_unwarping": item.get("use_doc_unwarping", False), + "use_chart_recognition": item.get("use_chart_recognition", False), + }) + + # 删除已移除的 provider + for pid in set(existing.keys()) - submitted_ids: + db.delete(existing[pid]) + + # 更新或新增 + for item in items_to_save: + old = existing.get(item["id"]) + if old: + for k, v in item.items(): + setattr(old, k, v) + else: + p = ProviderConfig(user_id=user_id, **item) + db.add(p) + + db.commit() + + +def get_active_provider(db: Session, user_id: int, category: str) -> Optional[ProviderConfig]: + """获取用户指定类别的激活 provider(用于后端调用 LLM/OCR 时读取凭据)""" + return db.query(ProviderConfig).filter( + ProviderConfig.user_id == user_id, + ProviderConfig.category == category, + ProviderConfig.is_active == True, + ).first() diff --git a/backend/db/crud/questions.py b/backend/db/crud/questions.py new file mode 100644 index 00000000..69c954ae --- /dev/null +++ b/backend/db/crud/questions.py @@ -0,0 +1,477 @@ +"""题目 CRUD""" + +import hashlib +import json +import logging +import re +from datetime import datetime +from typing import List, Dict, Any, Optional, Tuple + +from sqlalchemy.orm import Session, joinedload, selectinload + +from db.models import UploadBatch, Question, KnowledgeTag, QuestionTagMapping +from db.crud.tags import _parse_tag_list, get_or_create_tag + +logger = logging.getLogger(__name__) + + +def _get_filters(): + """延迟导入共享过滤函数,避免循环导入""" + from db.crud import _filter_by_subject, _filter_by_user + return _filter_by_subject, _filter_by_user + + +def compute_content_hash(content_blocks: List[Dict]) -> str: + """ + 基于 content_blocks 计算去重哈希 + 使用题目文本内容计算 SHA256 + """ + text_parts = [] + for block in content_blocks: + if block.get("block_type") == "text": + text_parts.append(block.get("content", "")) + + text = " ".join(text_parts).strip() + if not text: + # 如果没有文本内容,使用整个 content_blocks 的 JSON 作为哈希源 + text = json.dumps(content_blocks, ensure_ascii=False) + + return hashlib.sha256(text.encode()).hexdigest() + + +def question_exists(db, content_hash, user_id=None): + """检查题目是否已存在(通过内容哈希 + 用户隔离)""" + q = db.query(Question).filter(Question.content_hash == content_hash) + if user_id is not None: + q = q.filter(Question.user_id == user_id) + return q.first() + + +def save_questions_to_db( + db: Session, + questions: List[Dict], + batch_info: Dict[str, Any], + user_id=None, +) -> Dict[str, int]: + """ + 批量入库题目 + + Args: + db: 数据库会话 + questions: 题目列表(字典格式,来自 questions.json) + batch_info: 批次信息,包含 original_filename, file_path 等 + + Returns: + dict: {"created": 新增数量, "duplicates": 重复数量} + """ + # 科目由编排智能体识别,不再使用关键词匹配 + subject = batch_info.get("subject") or "未知" + + # 创建批次记录 + batch = UploadBatch( + user_id=user_id, + original_filename=batch_info.get("original_filename", "未知"), + subject=subject, + file_path=batch_info.get("file_path", ""), + upload_time=batch_info.get("upload_time") or datetime.utcnow() + ) + db.add(batch) + db.flush() # 获取 batch.id + + created = 0 + duplicates = 0 + + for q in questions: + content_blocks = q.get("content_blocks", []) + if not content_blocks: + continue + + content_hash = compute_content_hash(content_blocks) + + # 检查是否已存在 + if question_exists(db, content_hash, user_id=user_id): + duplicates += 1 + continue + + # 创建题目记录 + question = Question( + user_id=user_id, + batch_id=batch.id, + content_hash=content_hash, + question_type=q.get("question_type"), + content_json=json.dumps(content_blocks, ensure_ascii=False), + options_json=json.dumps(q.get("options"), ensure_ascii=False) if q.get("options") else None, + has_formula=q.get("has_formula", False), + has_image=q.get("has_image", False), + image_refs_json=json.dumps(q.get("image_refs"), ensure_ascii=False) if q.get("image_refs") else None, + needs_correction=q.get("needs_correction", False), + ocr_issues_json=json.dumps(q.get("ocr_issues"), ensure_ascii=False) if q.get("ocr_issues") else None, + answer=q.get("answer") or None, + user_answer=q.get("user_answer") or None, + ) + db.add(question) + db.flush() + + # 处理知识点标签 + knowledge_tags = q.get("knowledge_tags") or [] + for tag_name in knowledge_tags: + tag = get_or_create_tag(db, tag_name, subject) + mapping = QuestionTagMapping( + question_id=question.id, + tag_id=tag.id + ) + db.add(mapping) + + created += 1 + + db.commit() + + return {"created": created, "duplicates": duplicates} + + +def get_questions_by_subject( + db: Session, + subject: str, + limit: int = 100, + offset: int = 0, + user_id=None, +) -> List[Question]: + """按科目查询题目""" + query = db.query(Question).join(UploadBatch).filter( + UploadBatch.subject == subject + ) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return query.order_by(Question.created_at.desc()).offset(offset).limit(limit).all() + + +def get_questions_by_tag( + db: Session, + tag_name: str, + limit: int = 100, + offset: int = 0, + user_id=None, +) -> List[Question]: + """按标签查询题目""" + query = db.query(Question).join(QuestionTagMapping).join(KnowledgeTag).filter( + KnowledgeTag.tag_name == tag_name + ) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return query.order_by(Question.created_at.desc()).offset(offset).limit(limit).all() + + +def get_history_questions( + db: Session, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + page: int = 1, + page_size: int = 20, + user_id=None, +) -> Tuple[List[Question], int]: + """ + 分页查询历史题目(全部题目) + + Args: + db: 数据库会话 + start_date: 开始日期筛选 + end_date: 结束日期筛选 + page: 页码(从1开始) + page_size: 每页数量 + + Returns: + (题目列表, 总数) + """ + query = db.query(Question).join(UploadBatch) + + if user_id is not None: + query = query.filter(Question.user_id == user_id) + + if start_date: + query = query.filter(UploadBatch.upload_time >= start_date) + if end_date: + from datetime import timedelta + query = query.filter(UploadBatch.upload_time < end_date + timedelta(days=1)) + + # 获取总数 + total = query.count() + + # 分页查询 + offset = (page - 1) * page_size + questions = ( + query.options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) + .order_by(Question.created_at.desc()) + .offset(offset) + .limit(page_size) + .all() + ) + + return questions, total + + +def search_questions( + db: Session, + keyword: Optional[str] = None, + knowledge_tag: Optional[str] = None, + question_type: Optional[str] = None, + page: int = 1, + page_size: int = 20, + user_id=None, +) -> Tuple[List[Question], int]: + """ + 搜索题目(知识点/题型/关键字) + + Args: + db: 数据库会话 + keyword: 关键字搜索(匹配题目内容 content_json) + knowledge_tag: 知识点标签筛选 + question_type: 题型筛选 + page: 页码(从1开始) + page_size: 每页数量 + + Returns: + (题目列表, 总数) + """ + query = db.query(Question) + + if user_id is not None: + query = query.filter(Question.user_id == user_id) + + # 关键字搜索:匹配 content_json 中的内容 + if keyword: + escaped = re.sub(r"([%_\\])", r"\\\1", keyword) + query = query.filter(Question.content_json.ilike(f"%{escaped}%")) + + # 题型筛选 + if question_type: + query = query.filter(Question.question_type == question_type) + + # 知识点标签筛选(支持逗号分隔多选,OR 语义) + if knowledge_tag: + tag_list = _parse_tag_list(knowledge_tag) + if tag_list: + query = query.join(QuestionTagMapping).join(KnowledgeTag).filter( + KnowledgeTag.tag_name.in_(tag_list) + ) + + # 获取总数(需要先去除distinct,因为join可能产生重复) + total = query.distinct().count() + + # 分页查询 + offset = (page - 1) * page_size + questions = ( + query.distinct() + .options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) + .order_by(Question.created_at.desc()) + .offset(offset) + .limit(page_size) + .all() + ) + + return questions, total + + +def query_questions( + db: Session, + subject: Optional[str] = None, + knowledge_tag: Optional[str] = None, + question_type: Optional[str] = None, + keyword: Optional[str] = None, + start_date: Optional[datetime] = None, + end_date: Optional[datetime] = None, + review_status: Optional[str] = None, + page: int = 1, + page_size: int = 20, + user_id=None, +) -> Tuple[List[Question], int]: + """ + 统一查询题目(合并 get_history_questions 和 search_questions 的能力) + + 支持所有筛选条件任意组合。 + """ + query = db.query(Question).join(UploadBatch) + + if user_id is not None: + query = query.filter(Question.user_id == user_id) + + # 未筛选的总收录数(仅按用户隔离) + grand_total = query.distinct().count() + + if subject: + query = query.filter(UploadBatch.subject == subject) + + if question_type: + query = query.filter(Question.question_type == question_type) + + if keyword: + escaped = re.sub(r"([%_\\])", r"\\\1", keyword) + query = query.filter(Question.content_json.ilike(f"%{escaped}%")) + + if knowledge_tag: + tag_list = _parse_tag_list(knowledge_tag) + if tag_list: + query = query.join(QuestionTagMapping).join(KnowledgeTag).filter( + KnowledgeTag.tag_name.in_(tag_list) + ) + + if start_date: + query = query.filter(Question.created_at >= start_date) + if end_date: + from datetime import timedelta + query = query.filter(Question.created_at < end_date + timedelta(days=1)) + + if review_status: + query = query.filter(Question.review_status == review_status) + + total = query.distinct().count() + + offset = (page - 1) * page_size + questions = ( + query.distinct() + .options(selectinload(Question.batch), selectinload(Question.tags).selectinload(QuestionTagMapping.tag)) + .order_by(Question.created_at.desc()) + .offset(offset) + .limit(page_size) + .all() + ) + + return questions, total, grand_total + + +def get_questions_by_ids(db: Session, question_ids: List[int], user_id=None) -> List[Question]: + """按 ID 列表批量查询题目""" + if not question_ids: + return [] + query = ( + db.query(Question) + .options(joinedload(Question.batch), joinedload(Question.tags).joinedload(QuestionTagMapping.tag)) + .filter(Question.id.in_(question_ids)) + ) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return query.all() + + +def delete_question(db: Session, question_id: int, user_id=None) -> bool: + """ + 删除题目 + + Args: + db: 数据库会话 + question_id: 题目ID + user_id: 用户ID(非 None 时校验归属) + + Returns: + 是否删除成功 + """ + query = db.query(Question).filter(Question.id == question_id) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + question = query.first() + if not question: + return False + + try: + # 删除关联的标签映射 + db.query(QuestionTagMapping).filter(QuestionTagMapping.question_id == question_id).delete() + + # 删除题目 + db.delete(question) + db.commit() + except Exception as e: + db.rollback() + logger.error(f"删除题目 {question_id} 失败: {e}") + raise + + return True + + +def update_user_answer(db: Session, question_id: int, user_answer: str, user_id=None) -> Optional[Question]: + """更新用户答案""" + query = db.query(Question).filter(Question.id == question_id) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + question = query.first() + if not question: + return None + + try: + question.user_answer = user_answer + question.updated_at = datetime.utcnow() + db.commit() + db.refresh(question) + return question + except Exception as e: + db.rollback() + logger.error(f"更新题目 {question_id} 答案失败: {e}") + raise + + +def update_question_answer(db: Session, question_id: int, answer: str, user_id=None) -> Optional[Question]: + """保存/更新题目答案(Markdown 格式)""" + query = db.query(Question).filter(Question.id == question_id) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + question = query.first() + if not question: + return None + + try: + question.answer = answer + question.updated_at = datetime.utcnow() + db.commit() + db.refresh(question) + return question + except Exception as e: + db.rollback() + logger.error(f"保存题目 {question_id} 答案失败: {e}") + raise + + +VALID_REVIEW_STATUSES = ('待复习', '复习中', '已掌握') + + +def update_review_status(db: Session, question_id: int, review_status: str, user_id=None) -> Optional[Question]: + """更新题目复习状态""" + if review_status not in VALID_REVIEW_STATUSES: + raise ValueError(f"无效的复习状态: {review_status},可选值: {VALID_REVIEW_STATUSES}") + + query = db.query(Question).filter(Question.id == question_id) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + question = query.first() + if not question: + return None + + try: + question.review_status = review_status + question.updated_at = datetime.utcnow() + db.commit() + db.refresh(question) + return question + except Exception as e: + db.rollback() + logger.error(f"更新题目 {question_id} 复习状态失败: {e}") + raise + + +def get_existing_subjects(db, user_id=None): + """获取数据库中已有的所有科目名称(去重)""" + query = db.query(UploadBatch.subject).distinct().filter( + UploadBatch.subject.isnot(None), + UploadBatch.subject != "", + ) + if user_id is not None: + query = query.filter(UploadBatch.user_id == user_id) + return [r[0] for r in query.all()] + + +def get_existing_question_types(db: Session, user_id=None) -> List[str]: + """获取数据库中已有的所有题型(去重)""" + query = db.query(Question.question_type).distinct().filter( + Question.question_type.isnot(None), + Question.question_type != "", + ) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return [r[0] for r in query.all()] diff --git a/backend/db/crud/split_records.py b/backend/db/crud/split_records.py new file mode 100644 index 00000000..d80e1b4d --- /dev/null +++ b/backend/db/crud/split_records.py @@ -0,0 +1,91 @@ +"""分割历史记录 CRUD""" + +import json +import logging +from typing import List, Dict, Optional + +from sqlalchemy.orm import Session +from sqlalchemy import func + +from db.models import SplitRecord + +logger = logging.getLogger(__name__) + + +MAX_SPLIT_RECORDS = 20 + + +def save_split_record( + db: Session, + subject: Optional[str], + model_provider: str, + file_names: List[str], + questions: List[Dict], + user_id=None, +) -> SplitRecord: + """保存一次分割操作的完整结果,超过上限自动清理最旧记录""" + record = SplitRecord( + user_id=user_id, + subject=subject, + model_provider=model_provider, + file_names_json=json.dumps(file_names, ensure_ascii=False), + questions_json=json.dumps(questions, ensure_ascii=False), + question_count=len(questions), + ) + db.add(record) + try: + db.commit() + db.refresh(record) + _cleanup_old_split_records(db, user_id=user_id) + return record + except Exception as e: + db.rollback() + logger.error(f"保存分割记录失败: {e}") + raise + + +def _cleanup_old_split_records(db: Session, user_id=None): + """删除超出上限的最旧分割记录(按用户隔离)""" + count_query = db.query(func.count(SplitRecord.id)) + if user_id is not None: + count_query = count_query.filter(SplitRecord.user_id == user_id) + count = count_query.scalar() + if count <= MAX_SPLIT_RECORDS: + return + overflow = count - MAX_SPLIT_RECORDS + ids_query = db.query(SplitRecord.id) + if user_id is not None: + ids_query = ids_query.filter(SplitRecord.user_id == user_id) + old_ids = [ + row[0] for row in + ids_query.order_by(SplitRecord.created_at.asc()) + .limit(overflow) + .all() + ] + try: + db.query(SplitRecord).filter(SplitRecord.id.in_(old_ids)).delete(synchronize_session=False) + db.commit() + logger.info(f"已清理 {overflow} 条过期分割记录") + except Exception as e: + db.rollback() + logger.error(f"清理分割记录失败: {e}") + + +def get_recent_split_records(db, limit: int = 10, user_id=None): + """获取最近 N 条分割记录(不加载 questions_json 大字段)""" + from sqlalchemy.orm import defer + query = ( + db.query(SplitRecord) + .options(defer(SplitRecord.questions_json)) + ) + if user_id is not None: + query = query.filter(SplitRecord.user_id == user_id) + return query.order_by(SplitRecord.created_at.desc()).limit(limit).all() + + +def get_split_record_by_id(db: Session, record_id: int, user_id=None) -> Optional[SplitRecord]: + """按 ID 获取单条分割记录(含完整 questions_json)""" + query = db.query(SplitRecord).filter(SplitRecord.id == record_id) + if user_id is not None: + query = query.filter(SplitRecord.user_id == user_id) + return query.first() diff --git a/backend/db/crud/stats.py b/backend/db/crud/stats.py new file mode 100644 index 00000000..375b7734 --- /dev/null +++ b/backend/db/crud/stats.py @@ -0,0 +1,272 @@ +"""统计信息 CRUD""" + +import logging +from datetime import datetime +from typing import List, Dict, Any, Optional + +from sqlalchemy.orm import Session +from sqlalchemy import func + +from db.models import UploadBatch, Question, KnowledgeTag, QuestionTagMapping +from db.crud.questions import VALID_REVIEW_STATUSES + +logger = logging.getLogger(__name__) + + +def _get_filters(): + """延迟导入共享过滤函数,避免循环导入""" + from db.crud import _filter_by_subject, _filter_by_user + return _filter_by_subject, _filter_by_user + + +def get_statistics(db: Session, subject: Optional[str] = None, user_id=None) -> Dict[str, Any]: + """获取统计信息""" + _filter_by_subject, _filter_by_user = _get_filters() + + q_query = _filter_by_subject(db.query(func.count(Question.id)), subject) + if user_id is not None: + q_query = q_query.filter(Question.user_id == user_id) + total_questions = q_query.scalar() + + batch_query = db.query(func.count(UploadBatch.id)) + if user_id is not None: + batch_query = batch_query.filter(UploadBatch.user_id == user_id) + total_batches = batch_query.scalar() + + total_tags = db.query(func.count(KnowledgeTag.id)).scalar() + + # 按科目统计 + subject_q = db.query(UploadBatch.subject, func.count(Question.id)).join(Question) + if user_id is not None: + subject_q = subject_q.filter(Question.user_id == user_id) + subject_stats = subject_q.group_by(UploadBatch.subject).all() + + return { + "total_questions": total_questions or 0, + "total_batches": total_batches or 0, + "total_tags": total_tags or 0, + "by_subject": {s: c for s, c in subject_stats} + } + + +def get_knowledge_stats(db: Session, subject: Optional[str] = None, limit: Optional[int] = None, user_id=None) -> List[Dict]: + """ + 获取知识点统计信息 + + Args: + subject: 可选,按学科筛选 + limit: 可选,返回前 N 条 + user_id: 可选,按用户隔离 + + Returns: + [{"tag_name": "xxx", "count": 10}, ...] + """ + query = db.query( + KnowledgeTag.tag_name, + func.count(QuestionTagMapping.question_id).label("count") + ).join( + QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id + ) + + if user_id is not None: + query = query.join(Question, Question.id == QuestionTagMapping.question_id).filter( + Question.user_id == user_id + ) + + if subject: + query = query.filter(KnowledgeTag.subject == subject) + + query = query.group_by( + KnowledgeTag.id, KnowledgeTag.tag_name + ).order_by( + func.count(QuestionTagMapping.question_id).desc() + ) + + if limit: + query = query.limit(limit) + + stats = query.all() + + return [{"tag_name": tag_name, "count": count} for tag_name, count in stats] + + +def get_review_status_stats(db: Session, subject: Optional[str] = None, user_id=None) -> Dict[str, int]: + """按复习状态分组统计数量""" + _filter_by_subject, _filter_by_user = _get_filters() + + query = _filter_by_subject(db.query( + Question.review_status, + func.count(Question.id) + ), subject) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + + rows = query.group_by(Question.review_status).all() + + result = {s: 0 for s in VALID_REVIEW_STATUSES} + for status, count in rows: + key = status or '待复习' + if key in result: + result[key] += count + else: + result['待复习'] += count + return result + + +def get_today_mastered_count(db: Session, subject: Optional[str] = None, user_id=None) -> int: + """获取今日新掌握的题目数(updated_at 在今天且状态为已掌握)""" + _filter_by_subject, _filter_by_user = _get_filters() + + today_start = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) + query = _filter_by_subject(db.query(func.count(Question.id)).filter( + Question.updated_at >= today_start, + Question.review_status == '已掌握', + ), subject) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + return query.scalar() or 0 + + +def get_daily_counts(db: Session, days: int = 7, subject: Optional[str] = None, user_id=None) -> List[Dict[str, Any]]: + """获取最近 N 天每日新增题目数 + 每日新增已掌握数""" + from datetime import timedelta + _filter_by_subject, _filter_by_user = _get_filters() + + cutoff = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=days - 1) + + # SQLite 兼容:使用 func.date() 提取日期字符串 + date_expr = func.date(Question.created_at) + + # 新增题目数 + query = _filter_by_subject(db.query( + date_expr.label('date'), + func.count(Question.id).label('count') + ).filter(Question.created_at >= cutoff), subject) + if user_id is not None: + query = query.filter(Question.user_id == user_id) + rows = query.group_by(date_expr).order_by(date_expr).all() + date_map = {str(row.date): row.count for row in rows} + + # 每日新增已掌握数(按 updated_at 统计) + mastered_date_expr = func.date(Question.updated_at) + mq = _filter_by_subject(db.query( + mastered_date_expr.label('date'), + func.count(Question.id).label('count') + ).filter( + Question.updated_at >= cutoff, + Question.review_status == '已掌握', + ), subject) + if user_id is not None: + mq = mq.filter(Question.user_id == user_id) + mastered_rows = mq.group_by(mastered_date_expr).order_by(mastered_date_expr).all() + mastered_map = {str(row.date): row.count for row in mastered_rows} + + # 填充缺失的日期 + result = [] + for i in range(days): + d = cutoff + timedelta(days=i) + date_key = d.strftime('%Y-%m-%d') + date_str = d.strftime('%m-%d') + result.append({ + 'date': date_str, + 'count': date_map.get(date_key, 0), + 'mastered': mastered_map.get(date_key, 0), + }) + + return result + + +def get_tag_status_stats(db: Session, subject: Optional[str] = None, limit: int = 10, user_id=None) -> List[Dict]: + """ + 知识点 × 掌握状态统计(堆叠柱状图用) + + Returns: + [{"tag_name": "函数", "待复习": 3, "复习中": 2, "已掌握": 5}, ...] + """ + query = db.query( + KnowledgeTag.tag_name, + Question.review_status, + func.count(Question.id).label('count') + ).join( + QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id + ).join( + Question, Question.id == QuestionTagMapping.question_id + ) + + if user_id is not None: + query = query.filter(Question.user_id == user_id) + if subject: + query = query.filter(KnowledgeTag.subject == subject) + + rows = query.group_by( + KnowledgeTag.tag_name, Question.review_status + ).all() + + # 按 tag 聚合 + tag_data = {} + tag_totals = {} + for tag_name, status, count in rows: + if tag_name not in tag_data: + tag_data[tag_name] = {'tag_name': tag_name, **{s: 0 for s in VALID_REVIEW_STATUSES}} + tag_totals[tag_name] = 0 + key = status or '待复习' + if key in VALID_REVIEW_STATUSES: + tag_data[tag_name][key] += count + else: + tag_data[tag_name]['待复习'] += count + tag_totals[tag_name] += count + + # 按总数降序,取 top N + sorted_tags = sorted(tag_data.keys(), key=lambda t: tag_totals[t], reverse=True)[:limit] + return [tag_data[t] for t in sorted_tags] + + +def get_tag_type_stats(db: Session, subject: Optional[str] = None, tag_limit: int = 8, user_id=None) -> Dict[str, Any]: + """ + 知识点 × 题型交叉统计(热力图用) + + Returns: + {"tags": ["函数", ...], "types": ["选择题", ...], "data": [[3, 1, ...], ...]} + """ + query = db.query( + KnowledgeTag.tag_name, + Question.question_type, + func.count(Question.id).label('count') + ).join( + QuestionTagMapping, QuestionTagMapping.tag_id == KnowledgeTag.id + ).join( + Question, Question.id == QuestionTagMapping.question_id + ).filter( + Question.question_type.isnot(None), + Question.question_type != '', + ) + + if user_id is not None: + query = query.filter(Question.user_id == user_id) + if subject: + query = query.filter(KnowledgeTag.subject == subject) + + rows = query.group_by( + KnowledgeTag.tag_name, Question.question_type + ).all() + + # 收集所有 tag 和 type + tag_totals = {} + type_set = set() + cross = {} + for tag_name, q_type, count in rows: + tag_totals[tag_name] = tag_totals.get(tag_name, 0) + count + type_set.add(q_type) + cross[(tag_name, q_type)] = count + + # 按总数取 top N tag + sorted_tags = sorted(tag_totals.keys(), key=lambda t: tag_totals[t], reverse=True)[:tag_limit] + sorted_types = sorted(type_set) + + # 构建矩阵 + data = [] + for tag in sorted_tags: + row = [cross.get((tag, t), 0) for t in sorted_types] + data.append(row) + + return {"tags": sorted_tags, "types": sorted_types, "data": data} diff --git a/backend/db/crud/tags.py b/backend/db/crud/tags.py new file mode 100644 index 00000000..dc16753d --- /dev/null +++ b/backend/db/crud/tags.py @@ -0,0 +1,47 @@ +"""知识点标签 CRUD""" + +import logging +from typing import List, Optional + +from sqlalchemy.orm import Session + +from db.models import KnowledgeTag + +logger = logging.getLogger(__name__) + + +def _parse_tag_list(knowledge_tag: str) -> List[str]: + """将逗号分隔的标签字符串拆分为去空白的非空列表""" + return [t.strip() for t in knowledge_tag.split(',') if t.strip()] + + +def get_or_create_tag(db: Session, tag_name: str, subject: str) -> KnowledgeTag: + """获取或创建知识点标签""" + tag = db.query(KnowledgeTag).filter_by( + tag_name=tag_name, + subject=subject + ).first() + + if not tag: + tag = KnowledgeTag(tag_name=tag_name, subject=subject) + db.add(tag) + db.flush() + + return tag + + +def get_existing_tag_names(db: Session, subject: Optional[str] = None) -> List[str]: + """获取数据库中已有的知识点标签名称列表(字符串)""" + query = db.query(KnowledgeTag.tag_name).distinct() + if subject: + query = query.filter(KnowledgeTag.subject == subject) + rows = query.order_by(KnowledgeTag.tag_name).all() + return [r[0] for r in rows] + + +def get_all_tags(db: Session, subject: Optional[str] = None) -> List[KnowledgeTag]: + """获取所有标签(可按科目筛选)""" + query = db.query(KnowledgeTag) + if subject: + query = query.filter(KnowledgeTag.subject == subject) + return query.order_by(KnowledgeTag.tag_name).all() diff --git a/backend/db/crud/users.py b/backend/db/crud/users.py new file mode 100644 index 00000000..5763677b --- /dev/null +++ b/backend/db/crud/users.py @@ -0,0 +1,54 @@ +"""用户认证 CRUD""" + +import logging +from sqlalchemy import func + +from db.models import User + +logger = logging.getLogger(__name__) + + +def create_user(db, email, password_hash, username, is_admin=False): + """创建用户""" + user = User(email=email, password_hash=password_hash, username=username, is_admin=is_admin) + db.add(user) + try: + db.commit() + db.refresh(user) + return user + except Exception as e: + db.rollback() + raise + + +def get_user_by_email(db, email): + """按邮箱查询用户""" + return db.query(User).filter(User.email == email).first() + + +def get_user_by_id(db, user_id): + """按 ID 查询用户""" + return db.query(User).filter(User.id == user_id).first() + + +def get_user_by_login(db, identifier): + """按邮箱或用户名查询用户(登录用,大小写不敏感邮箱)""" + identifier = identifier.strip() + return db.query(User).filter( + (func.lower(User.email) == identifier.lower()) | (User.username == identifier) + ).first() + + +def update_user_password(db, email: str, new_password_hash: str) -> bool: + """按邮箱更新用户密码,成功返回 True""" + user = db.query(User).filter(User.email == email).first() + if not user: + return False + user.password_hash = new_password_hash + user.session_version = (user.session_version or 0) + 1 + try: + db.commit() + return True + except Exception: + db.rollback() + raise diff --git a/backend/db/migrate.py b/backend/db/migrate.py index f613ea8c..80377d5f 100644 --- a/backend/db/migrate.py +++ b/backend/db/migrate.py @@ -12,16 +12,32 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from werkzeug.security import generate_password_hash -from config import settings +from core.config import settings from db import engine, SessionLocal from db.models import Base from db import crud +def _add_column_if_missing(conn, table: str, column: str, col_type: str, default=None): + """安全地给已有表添加列,若已存在则跳过""" + from sqlalchemy import text, inspect + inspector = inspect(conn) + existing = [c["name"] for c in inspector.get_columns(table)] + if column not in existing: + default_clause = f" DEFAULT {default}" if default is not None else "" + conn.execute(text(f"ALTER TABLE {table} ADD COLUMN {column} {col_type}{default_clause}")) + print(f"[migrate] 已添加列: {table}.{column}") + + def migrate(): """增量迁移:仅创建缺失的表,并确保 Admin 用户存在。每次启动自动调用,安全幂等。""" Base.metadata.create_all(bind=engine) # checkfirst=True by default,已存在的表不动 + # 增量列迁移(新增字段时在此追加) + with engine.connect() as conn: + _add_column_if_missing(conn, "users", "session_version", "INTEGER", 0) + conn.commit() + default_users = [ {"email": "admin@admin.com", "username": "Admin", "password": "123456", "is_admin": True}, {"email": "admin2@admin.com", "username": "Admin2", "password": "123456", "is_admin": True}, diff --git a/backend/db/models.py b/backend/db/models.py index d9ace4ad..be8d6638 100644 --- a/backend/db/models.py +++ b/backend/db/models.py @@ -19,12 +19,14 @@ class User(Base): email = Column(String(255), unique=True, nullable=False, index=True) password_hash = Column(String(255), nullable=False) is_admin = Column(Boolean, default=False) + session_version = Column(Integer, default=0, nullable=False) created_at = Column(DateTime, default=datetime.utcnow) questions = relationship("Question", back_populates="user") upload_batches = relationship("UploadBatch", back_populates="user") split_records = relationship("SplitRecord", back_populates="user") provider_configs = relationship("ProviderConfig", back_populates="user", cascade="all, delete-orphan") + notes = relationship("Note", back_populates="user") class ProviderConfig(Base): @@ -100,14 +102,17 @@ class Question(Base): class ChatSession(Base): - """教学辅导对话会话""" + """对话会话(可绑定题目,也可独立对话)""" __tablename__ = "chat_sessions" id = Column(Integer, primary_key=True) - question_id = Column(Integer, ForeignKey("questions.id"), nullable=False, index=True) + user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True) + question_id = Column(Integer, ForeignKey("questions.id"), nullable=True, index=True) + title = Column(String(255), default="新对话") created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + user = relationship("User") question = relationship("Question", back_populates="chat_sessions") messages = relationship("ChatMessage", back_populates="session", order_by="ChatMessage.id") @@ -164,3 +169,45 @@ class QuestionTagMapping(Base): question = relationship("Question", back_populates="tags") tag = relationship("KnowledgeTag") + + +class Note(Base): + """笔记表""" + __tablename__ = "notes" + + id = Column(Integer, primary_key=True) + user_id = Column(Integer, ForeignKey("users.id"), nullable=True, index=True) + title = Column(String(255), nullable=False) # 笔记标题 + subject = Column(String(50)) # 科目 + content_markdown = Column(Text, default="") # LLM 整理后的 Markdown 内容 + source_images_json = Column(Text) # 原始上传图片路径列表 JSON + ocr_text = Column(Text) # OCR 识别的原始文本(保留用于重新整理) + created_at = Column(DateTime, default=datetime.utcnow, index=True) + updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + + user = relationship("User", back_populates="notes") + tags = relationship("NoteTagMapping", back_populates="note", cascade="all, delete-orphan") + + +class NoteTagMapping(Base): + """笔记-标签关联表(与错题共享 KnowledgeTag)""" + __tablename__ = "note_tag_mapping" + + note_id = Column(Integer, ForeignKey("notes.id"), primary_key=True) + tag_id = Column(Integer, ForeignKey("knowledge_tags.id"), primary_key=True) + + note = relationship("Note", back_populates="tags") + tag = relationship("KnowledgeTag") + + +class EmailVerification(Base): + """注册邮箱验证码(仅存哈希,不存明文)""" + __tablename__ = "email_verifications" + + id = Column(Integer, primary_key=True) + email = Column(String(255), unique=True, nullable=False, index=True) + code_hash = Column(String(64), nullable=False) + expires_at = Column(DateTime, nullable=False) + last_sent_at = Column(DateTime, nullable=True) + attempts = Column(Integer, default=0) + created_at = Column(DateTime, default=datetime.utcnow) diff --git a/backend/models/blocks.py b/backend/models/blocks.py new file mode 100644 index 00000000..1684afcb --- /dev/null +++ b/backend/models/blocks.py @@ -0,0 +1,135 @@ +""" +基础网络模块:CBAM 注意力、编码/解码块,供 Generator 和 Discriminator 组合使用。 +""" +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class CBAM(nn.Module): + """Convolutional Block Attention Module:通道注意力 + 空间注意力。 + + Args: + in_channels: 输入特征图通道数 + reduction: 通道注意力 MLP 的压缩比,越大参数越少但表达力越弱 + """ + def __init__(self, in_channels: int, reduction: int = 16): + super().__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.max_pool = nn.AdaptiveMaxPool2d(1) + self.mlp = nn.Sequential( + nn.Linear(in_channels, in_channels // reduction, bias=False), + nn.ReLU(inplace=True), + nn.Linear(in_channels // reduction, in_channels, bias=False), + ) + self.sigmoid = nn.Sigmoid() + # 空间注意力:7×7 大感受野,无 BN(标准 CBAM) + self.spatial = nn.Sequential( + nn.Conv2d(2, 1, kernel_size=7, padding=3, bias=False), + nn.Sigmoid(), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + b, c, h, w = x.shape + + # 通道注意力 + avg_out = self.mlp(self.avg_pool(x).view(b, c)).view(b, c, 1, 1) + max_out = self.mlp(self.max_pool(x).view(b, c)).view(b, c, 1, 1) + x = x * self.sigmoid(avg_out + max_out) + + # 空间注意力 + avg_s = torch.mean(x, dim=1, keepdim=True) + max_s, _ = torch.max(x, dim=1, keepdim=True) + x = x * self.spatial(torch.cat([avg_s, max_s], dim=1)) + + return x + + +class DilatedConvBlock(nn.Module): + """空洞卷积块,用于 RefineNet 解码器,扩大感受野而不损失分辨率。 + + Args: + dilation: 空洞率,默认 2;padding 自动计算以保持尺寸不变 + """ + def __init__(self, in_channels: int, out_channels: int, dilation: int = 2): + super().__init__() + padding = dilation * (3 - 1) // 2 + self.block = nn.Sequential( + nn.Conv2d(in_channels, out_channels, 3, + padding=padding, dilation=dilation, bias=False), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.block(x) + + +class DownSample(nn.Module): + """U-Net 编码器下采样块:步长为 2 的卷积,分辨率减半。""" + def __init__(self, in_channels: int, out_channels: int): + super().__init__() + self.conv = nn.Sequential( + nn.Conv2d(in_channels, out_channels, 4, stride=2, padding=1, bias=False), + nn.BatchNorm2d(out_channels), + nn.LeakyReLU(0.2, inplace=True), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.conv(x) + + +class ResBlock(nn.Module): + """残差块,参照 EraseNet Residual:conv1(stride) → ReLU → conv2 + skip → BN → ReLU。 + + stride=1 时要求 in_channels == out_channels(无投影); + stride=2 时自动添加 1×1 skip 投影以匹配通道和尺寸。 + """ + def __init__(self, in_channels: int, out_channels: int, stride: int = 1): + super().__init__() + self.conv1 = nn.Conv2d(in_channels, in_channels, 3, stride=stride, padding=1) + self.conv2 = nn.Conv2d(in_channels, out_channels, 3, padding=1) + self.bn = nn.BatchNorm2d(out_channels) + self.skip = (nn.Conv2d(in_channels, out_channels, 1, stride=stride) + if (stride != 1 or in_channels != out_channels) else None) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + out = F.relu(self.conv1(x)) + out = self.conv2(out) + identity = self.skip(x) if self.skip is not None else x + return F.relu(self.bn(out + identity)) + + +class LateralConnection(nn.Module): + """跳跃连接特征精炼:1×1 → 3×3 → 3×3 → 1×1,参照 EraseNet lateral_connection。 + + 输入输出通道数相同,中间扩张为 2×channels。 + """ + def __init__(self, channels: int): + super().__init__() + inner = channels * 2 + self.net = nn.Sequential( + nn.Conv2d(channels, channels, 1), + nn.Conv2d(channels, inner, 3, padding=1), + nn.Conv2d(inner, inner, 3, padding=1), + nn.Conv2d(inner, channels, 1), + ) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.net(x) + + +class UpSample(nn.Module): + """U-Net 解码器上采样块:转置卷积,分辨率翻倍,可选 CBAM 注意力。""" + def __init__(self, in_channels: int, out_channels: int, + use_cbam: bool = False, reduction: int = 16): + super().__init__() + self.conv = nn.Sequential( + nn.ConvTranspose2d(in_channels, out_channels, 4, stride=2, padding=1, bias=False), + nn.BatchNorm2d(out_channels), + nn.ReLU(inplace=True), + ) + self.cbam = CBAM(out_channels, reduction) if use_cbam else nn.Identity() + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.cbam(self.conv(x)) diff --git a/backend/models/config.py b/backend/models/config.py deleted file mode 100644 index 07cd972d..00000000 --- a/backend/models/config.py +++ /dev/null @@ -1,59 +0,0 @@ -import os -import yaml -from pathlib import Path - - -class Config: - _instance = None - _config = None - - def __new__(cls): - if cls._instance is None: - cls._instance = super().__new__(cls) - return cls._instance - - def __init__(self): - if self._config is None: - self._load_config() - - def _load_config(self, config_path=None): - if config_path is None: - config_path = os.path.join( - os.path.dirname(__file__), - 'config.yaml' - ) - - if not os.path.exists(config_path): - raise FileNotFoundError(f"配置文件不存在: {config_path}") - - with open(config_path, 'r', encoding='utf-8') as f: - self._config = yaml.safe_load(f) - - @property - def train(self): - return self._config.get('train', {}) - - @property - def loss(self): - return self._config.get('loss', {}) - - @property - def inference(self): - return self._config.get('inference', {}) - - @property - def wandb(self): - return self._config.get('wandb', {}) - - def get(self, key, default=None): - keys = key.split('.') - value = self._config - for k in keys: - if isinstance(value, dict): - value = value.get(k, default) - else: - return default - return value - - -config = Config() diff --git a/backend/models/config.yaml b/backend/models/config.yaml deleted file mode 100644 index 164f9193..00000000 --- a/backend/models/config.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# EnsExam 配置文件 - -# ====================== 训练参数 ====================== -train: - epochs: 100 # 训练轮数 - batch_size: 4 # 批次大小 - lr: 0.0001 # 学习率 - device: "cuda" # 训练设备 ("cuda" 或 "cpu") - num_workers: 4 # 数据加载线程数 - - # 路径配置 - data_root: "D:\\PythonProject1\\LLM\\adcj\\src\\adcj\\EnsExam\\SCUT-EnsExam\\SCUT-EnsExam" - save_dir: "./ensexam_checkpoints" - resume_path: "./ensexam_checkpoints/latest.pth" - -# ====================== 损失权重 ====================== -loss: - # LR Loss 多尺度权重 [Ic4, Ic2, Ic1, Ire] - lambda_n: [5, 6, 8, 10] - beta_n: [0.8, 0.8, 0.8, 2] - - # 各损失总权重 - lambda_lr: 1.0 # LR损失权重 - lambda_p: 0.05 # 感知损失权重 - lambda_style: 120 # 风格损失权重 - lambda_sn: 1 # SN损失权重 - lambda_b: 0.4 # 块损失权重 - -# ====================== 推理参数 ====================== -inference: - model_path: "D:\\PythonProject1\\LLM\\adcj\\src\\adcj\\EnsExam\\ensexam_checkpoints\\ensexam_epoch_5.pth" - img_size: 512 # 必须和训练时一致 - - # 单张图片推理 - input_image_path: "D:\\PythonProject1\\LLM\\adcj\\src\\adcj\\EnsExam\\SCUT-EnsExam\\SCUT-EnsExam\\test\\all_images\\15.jpg" - output_image_path: "./test_output.jpg" - - # 批量目录推理 - input_dir: "D:\\PythonProject1\\LLM\\adcj\\src\\adcj\\EnsExam\\SCUT-EnsExam\\SCUT-EnsExam\\test\\all_images" - output_dir: "./output" - patch_size: 512 # 滑动窗口尺寸 - overlap: 32 # 重叠像素 - -# ====================== WandB 配置 ====================== -wandb: - enabled: true # 是否启用 wandb - project: "ensexam" # 项目名称 - name: null # 实验名称 (null 则自动生成) - entity: null # 团队/用户名 - offline: true # 离线模式 (true 使用 offline wandb) - dir: "./wandb" # wandb 日志目录 diff --git a/backend/models/inference.py b/backend/models/inference.py index e06c848e..3ad48d14 100644 --- a/backend/models/inference.py +++ b/backend/models/inference.py @@ -12,8 +12,14 @@ import threading import numpy as np +import torch from PIL import Image +from models.model import Generator + +# cuDNN v8 frontend 与 A30+PyTorch2.1 不兼容 +torch.backends.cudnn.enabled = False + logger = logging.getLogger(__name__) _PATCH_SIZE = 512 @@ -50,23 +56,18 @@ def _load_model(self): if self._model is not None: return - import torch - torch.backends.cudnn.deterministic = True - torch.backends.cudnn.benchmark = False - from models.model import Generator - from config import settings + from core.config import settings model_path = settings.model_path if not model_path.exists(): raise FileNotFoundError( - f"模型权重不存在,请将 latest.pth 放到: {model_path}" + f"模型权重不存在,请将 best.pth 放到: {model_path}" ) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") generator = Generator().to(device) ckpt = torch.load(model_path, map_location=device, weights_only=False) - # train.py 保存格式:{'G_state_dict': ..., 'D_state_dict': ..., ...} state_dict = ( ckpt.get("G_state_dict") or ckpt.get("generator_state_dict") @@ -85,7 +86,7 @@ def _load_model(self): @staticmethod def _preprocess(pil_img: Image.Image): - """PIL → float Tensor [-1, 1],并 padding 到 512 的整数倍 + """PIL → float ndarray [-1, 1],并 padding 到 512 的整数倍 Returns: arr_padded (np.ndarray): shape (H_pad, W_pad, 3),float32 in [-1,1] @@ -105,14 +106,12 @@ def _preprocess(pil_img: Image.Image): arr = np.array(img, dtype=np.float32) / 127.5 - 1.0 return arr, orig_w, orig_h - @staticmethod - def _to_tensor(arr: np.ndarray, device): + def _to_tensor(self, arr: np.ndarray) -> torch.Tensor: """(H, W, 3) ndarray → (1, 3, H, W) Tensor on device""" - import torch - return torch.from_numpy(arr).permute(2, 0, 1).unsqueeze(0).to(device) + return torch.from_numpy(arr).permute(2, 0, 1).unsqueeze(0).to(self._device) @staticmethod - def _to_numpy(tensor) -> np.ndarray: + def _to_numpy(tensor: torch.Tensor) -> np.ndarray: """(1, 3, H, W) Tensor → (H, W, 3) uint8 ndarray""" arr = tensor.squeeze(0).permute(1, 2, 0).cpu().numpy() return np.clip((arr + 1.0) * 127.5, 0, 255).astype(np.uint8) @@ -123,8 +122,6 @@ def _to_numpy(tensor) -> np.ndarray: def _infer_sliding_window(self, arr: np.ndarray) -> np.ndarray: """滑动窗口推理,patch 重叠区域做加权平均以消除接缝""" - import torch - h, w, _ = arr.shape result = np.zeros((h, w, 3), dtype=np.float32) weight = np.zeros((h, w, 1), dtype=np.float32) @@ -141,9 +138,8 @@ def _ticks(total): for y in _ticks(h): for x in _ticks(w): patch = arr[y:y + _PATCH_SIZE, x:x + _PATCH_SIZE] - tensor = self._to_tensor(patch, self._device) + tensor = self._to_tensor(patch) *_, Icomp = self._model(tensor) - # 直接从 tensor 提取 float32,避免 uint8 截断精度损失 out = (Icomp.squeeze(0).permute(1, 2, 0).cpu().numpy() + 1.0) * 127.5 result[y:y + _PATCH_SIZE, x:x + _PATCH_SIZE] += out weight[y:y + _PATCH_SIZE, x:x + _PATCH_SIZE] += 1.0 @@ -167,7 +163,6 @@ def run(self, image_bytes: bytes) -> Image.Image: pil_img = Image.open(io.BytesIO(image_bytes)) arr, orig_w, orig_h = self._preprocess(pil_img) - h, w, _ = arr.shape result_arr = self._infer_sliding_window(arr) diff --git a/backend/models/model.py b/backend/models/model.py index 436f19ad..cc931c52 100644 --- a/backend/models/model.py +++ b/backend/models/model.py @@ -1,473 +1,213 @@ -import math - -import cv2 -import numpy as np +""" +生成器网络:CoarseNet(粗擦除 + 掩码预测) + RefineNet(精细修复)。 + +结构对照 EraseNet (STRnet2),核心改动: + - 编码器:EraseNet 残差块风格(conv1/conva/convb + ResBlock×8) + - 跳跃连接:LateralConnection 特征精炼(替代简单 cat) + - 掩码分支:从 x_mask(瓶颈前 H/16 特征)出发,与 EraseNet 对齐 + - 保留:CBAM 注意力、双 sigmoid 掩码(Ms/Mb)、RefineNet 输入含 Ms + - RefineNet:EraseNet 风格多尺度空洞卷积,输入保持 cat([Iin, Ms, Ic1]) +""" import torch +import torch.nn as nn import torch.nn.functional as F -from torch import nn -from torchvision.models import vgg16 - - -class CBAM(nn.Module): - def __init__(self, in_channels, reduction=16): - super().__init__() - # 通道注意力(标准实现) - self.avg_pool = nn.AdaptiveAvgPool2d(1) - self.max_pool = nn.AdaptiveMaxPool2d(1) - self.mlp = nn.Sequential( - nn.Linear(in_channels, in_channels // reduction, bias=False), - nn.ReLU(inplace=True), - nn.Linear(in_channels // reduction, in_channels, bias=False) - ) - self.sigmoid = nn.Sigmoid() - - # 空间注意力(关键修正:7×7卷积 + 无BatchNorm) - self.spatial = nn.Sequential( - nn.Conv2d(2, 1, kernel_size=7, padding=3, bias=False), # ✅ 7×7 - nn.Sigmoid() # ✅ 无BatchNorm - ) - - def forward(self, x): - b, c, h, w = x.shape - - # ========== 通道注意力 ========== - avg_out = self.mlp(self.avg_pool(x).view(b, c)).view(b, c, 1, 1) - max_out = self.mlp(self.max_pool(x).view(b, c)).view(b, c, 1, 1) - channel_att = self.sigmoid(avg_out + max_out) - x = x * channel_att # 广播相乘 [B,C,H,W] * [B,C,1,1] - # ========== 空间注意力 ========== - avg_out = torch.mean(x, dim=1, keepdim=True) # [B,1,H,W] - max_out, _ = torch.max(x, dim=1, keepdim=True) # [B,1,H,W] - spatial_att = self.spatial(torch.cat([avg_out, max_out], dim=1)) # [B,1,H,W] - x = x * spatial_att # 广播相乘 [B,C,H,W] * [B,1,H,W] +from models.blocks import (DownSample, UpSample, DilatedConvBlock, + ResBlock, LateralConnection) - return x - - -# 空洞卷积块(Refine网络用) -class DilatedConvBlock(nn.Module): - def __init__(self, in_channels, out_channels, dilation=2): - super().__init__() - padding = dilation * (3 - 1) // 2 - self.block = nn.Sequential( - nn.Conv2d(in_channels, out_channels, 3, padding=padding, dilation=dilation, bias=False), - nn.BatchNorm2d(out_channels), - nn.ReLU(inplace=True) - ) - - def forward(self, x): - return self.block(x) - - -# U-Net下采样块(Coarse/Refine网络编码器) -class DownSample(nn.Module): - def __init__(self, in_channels, out_channels): - super().__init__() - self.conv = nn.Sequential( - nn.Conv2d(in_channels, out_channels, 4, 2, 1, bias=False), - nn.BatchNorm2d(out_channels), - nn.LeakyReLU(0.2, inplace=True) - ) - - def forward(self, x): - x = self.conv(x) - return x - - -# U-Net上采样块(Coarse网络解码器) -class UpSample(nn.Module): - def __init__(self, in_channels, out_channels, use_cbam=False): - super().__init__() - self.conv = nn.Sequential( - nn.ConvTranspose2d(in_channels, out_channels, 4, 2, 1, bias=False), - nn.BatchNorm2d(out_channels), - nn.ReLU(inplace=True) - ) - self.cbam = CBAM(out_channels) if use_cbam else nn.modules.Identity() - def forward(self, x): - x = self.conv(x) - x = self.cbam(x) - return x - - -# 带空洞卷积的上采样块(Refine网络解码器) -class DilatedUpSample(nn.Module): - def __init__(self, in_channels, out_channels, dilation=2): - super().__init__() - self.conv = nn.Sequential( - nn.ConvTranspose2d(in_channels, out_channels, 4, 2, 1, bias=False), - nn.BatchNorm2d(out_channels), - nn.ReLU(inplace=True) - ) - self.dilated = DilatedConvBlock(out_channels, out_channels, dilation) - - def forward(self, x): - x = self.conv(x) - x = self.dilated(x) - return x - - -# Coarse网络 class CoarseNet(nn.Module): - def __init__(self, in_channels=3): - super().__init__() - # 编码器:下采样+CBAM - self.down1 = DownSample(in_channels, 64) # 1/2 - self.down2 = DownSample(64, 128) # 1/4 - self.down3 = DownSample(128, 256) # 1/8 - self.down4 = DownSample(256, 512) # 1/16 - self.down5 = DownSample(512, 512) # 1/32 - # 解码器:上采样 - self.up1 = UpSample(512, 512, use_cbam=True) # 1/16 - self.up2 = UpSample(1024, 256, use_cbam=True) # 1/8 - self.up3 = UpSample(512, 128, use_cbam=True) # 1/4 → Ic4 - self.up4 = UpSample(256, 64, use_cbam=True) # 1/2 → Ic2 - self.up5 = UpSample(128, 64, use_cbam=True) # 1/1 → Ic1 - # 输出层:Ms(笔画掩码), Mb(文本块掩码), 多尺度Ic - self.up1_seg = UpSample(512, 512, use_cbam=True) - self.up2_seg = UpSample(1024, 256, use_cbam=True) - self.up3_seg = UpSample(512, 128, use_cbam=True) - self.up4_seg = UpSample(256, 64, use_cbam=True) - self.up5_seg = UpSample(128, 64, use_cbam=True) - - self.out_ms = nn.Conv2d(64, 1, 3, 1, 1, bias=True) - self.out_mb = nn.Conv2d(64, 1, 3, 1, 1, bias=True) - self.out_ic4 = nn.Conv2d(128, 3, 3, 1, 1, bias=False) - self.out_ic2 = nn.Conv2d(64, 3, 3, 1, 1, bias=False) - self.out_ic1 = nn.Conv2d(64, 3, 3, 1, 1, bias=False) - - def forward(self, x): - # 编码器(下采样) - d1 = self.down1(x) # H/2 - d2 = self.down2(d1) # H/4 - d3 = self.down3(d2) # H/8 - d4 = self.down4(d3) # H/16 - d5 = self.down5(d4) # H/32 - - # 解码器(上采样 + 跳跃连接) - u1 = self.up1(d5) - u1 = torch.cat([u1, d4], dim=1) # 拼接H/16特征 + """粗擦除网络:EraseNet 残差编码器 + 双解码器(修复 + 掩码)。 - u2 = self.up2(u1) - u2 = torch.cat([u2, d3], dim=1) # 拼接H/8特征 - - u3 = self.up3(u2) # H/4 → 输出 Ic4 - Ic4 = torch.tanh(self.out_ic4(u3)) - u3 = torch.cat([u3, d2], dim=1) # 拼接H/4特征 - - u4 = self.up4(u3) # H/2 → 输出 Ic2 - Ic2 = torch.tanh(self.out_ic2(u4)) - u4 = torch.cat([u4, d1], dim=1) # 拼接H/2特征 - - u5 = self.up5(u4) # H → 输出 Ic1, Mb, Ms - Ic1 = torch.tanh(self.out_ic1(u5)) - - u1_seg = self.up1_seg(d5) - u1_seg = torch.cat([u1_seg, d4], dim=1) - u2_seg = self.up2_seg(u1_seg) - u2_seg = torch.cat([u2_seg, d3], dim=1) - u3_seg = self.up3_seg(u2_seg) - u3_seg = torch.cat([u3_seg, d2], dim=1) - u4_seg = self.up4_seg(u3_seg) - u4_seg = torch.cat([u4_seg, d1], dim=1) - u5_seg = self.up5_seg(u4_seg) - Mb = torch.sigmoid(self.out_mb(u5_seg)) - Ms = torch.sigmoid(self.out_ms(u5_seg)) + Args: + in_channels: 输入通道数,RGB 固定为 3 + cbam_reduction: CBAM 通道压缩比 + """ + def __init__(self, in_channels: int = 3, cbam_reduction: int = 16): + super().__init__() + r = cbam_reduction + + # ── 编码器(EraseNet 风格) ────────────────────────────────────── + self.conv1 = nn.Sequential( + nn.Conv2d(in_channels, 32, 4, stride=2, padding=1, bias=False), + nn.BatchNorm2d(32), nn.LeakyReLU(0.2, inplace=True)) # H/2, 32 + self.conva = nn.Sequential( + nn.Conv2d(32, 32, 3, padding=1, bias=False), + nn.BatchNorm2d(32), nn.LeakyReLU(0.2, inplace=True)) # H/2, 32 + self.convb = nn.Sequential( + nn.Conv2d(32, 64, 4, stride=2, padding=1, bias=False), + nn.BatchNorm2d(64), nn.LeakyReLU(0.2, inplace=True)) # H/4, 64 + self.res1 = ResBlock(64, 64) + self.res2 = ResBlock(64, 64) + self.res3 = ResBlock(64, 128, stride=2) # H/8, 128 + self.res4 = ResBlock(128, 128) + self.res5 = ResBlock(128, 256, stride=2) # H/16, 256 + self.res6 = ResBlock(256, 256) + self.res7 = ResBlock(256, 512, stride=2) # H/32, 512 + self.res8 = ResBlock(512, 512) + self.conv2 = nn.Conv2d(512, 512, 1) # H/32, 512(瓶颈) + + # ── 修复解码器(LateralConnection + CBAM UpSample) ───────────── + self.lat1 = LateralConnection(256) + self.lat2 = LateralConnection(128) + self.lat3 = LateralConnection(64) + self.lat4 = LateralConnection(32) + self.up1 = UpSample(512, 256, use_cbam=True, reduction=r) + self.up2 = UpSample(512, 128, use_cbam=True, reduction=r) + self.up3 = UpSample(256, 64, use_cbam=True, reduction=r) + self.up4 = UpSample(128, 32, use_cbam=True, reduction=r) + self.up5 = UpSample(64, 32, use_cbam=True, reduction=r) + self.out_ic4 = nn.Conv2d(64, 3, 1) + self.out_ic2 = nn.Conv2d(32, 3, 1) + self.out_ic1 = nn.Conv2d(32, 3, 3, padding=1) + + # ── 掩码解码器(从瓶颈 d5 出发,保留全局上下文,双 sigmoid 头) ── + self.mask_up_0 = UpSample(512, 256, use_cbam=True, reduction=r) # H/32→H/16 + self.mask_up_a = UpSample(512, 256, use_cbam=True, reduction=r) + self.mask_conv_a = nn.Sequential( + nn.Conv2d(256, 128, 3, padding=1, bias=False), + nn.BatchNorm2d(128), nn.ReLU(inplace=True)) + self.mask_up_b = UpSample(256, 128, use_cbam=True, reduction=r) + self.mask_conv_b = nn.Sequential( + nn.Conv2d(128, 64, 3, padding=1, bias=False), + nn.BatchNorm2d(64), nn.ReLU(inplace=True)) + self.mask_up_c = UpSample(128, 64, use_cbam=True, reduction=r) + self.mask_conv_c = nn.Sequential( + nn.Conv2d(64, 32, 3, padding=1, bias=False), + nn.BatchNorm2d(32), nn.ReLU(inplace=True)) + self.mask_up_d = UpSample(64, 32, use_cbam=True, reduction=r) + self.out_ms = nn.Conv2d(32, 1, 1) # 软笔画掩码 + self.out_mb = nn.Conv2d(32, 1, 1) # 文本块掩码 + + def forward(self, x: torch.Tensor): + # 编码 + x = self.conv1(x) + x = self.conva(x) + con_x1 = x # H/2, 32 + x = self.convb(x) + x = self.res1(x) + con_x2 = x # H/4, 64 + x = self.res2(x) + x = self.res3(x) + con_x3 = x # H/8, 128 + x = self.res4(x) + x = self.res5(x) + con_x4 = x # H/16, 256 + x = self.res6(x) + x = self.res7(x) + x = self.res8(x) + d5 = self.conv2(x) # H/32, 512(瓶颈) + + # 修复解码 + u1 = torch.cat([self.lat1(con_x4), self.up1(d5)], dim=1) # H/16, 512 + u2 = torch.cat([self.lat2(con_x3), self.up2(u1)], dim=1) # H/8, 256 + xo1 = self.up3(u2) # H/4, 64 + Ic4 = torch.tanh(self.out_ic4(xo1)) + u3 = torch.cat([self.lat3(con_x2), xo1], dim=1) # H/4, 128 + xo2 = self.up4(u3) # H/2, 32 + Ic2 = torch.tanh(self.out_ic2(xo2)) + u4 = torch.cat([self.lat4(con_x1), xo2], dim=1) # H/2, 64 + Ic1 = torch.tanh(self.out_ic1(self.up5(u4))) # H, 3 + + # 掩码解码(从瓶颈 d5 出发,保留全局上下文) + mm = self.mask_up_a(torch.cat([self.mask_up_0(d5), con_x4], dim=1)) # H/8, 256 + mm = self.mask_conv_a(mm) # H/8, 128 + mm = self.mask_up_b(torch.cat([mm, con_x3], dim=1)) # H/4, 128 + mm = self.mask_conv_b(mm) # H/4, 64 + mm = self.mask_up_c(torch.cat([mm, con_x2], dim=1)) # H/2, 64 + mm = self.mask_conv_c(mm) # H/2, 32 + mm = self.mask_up_d(torch.cat([mm, con_x1], dim=1)) # H, 32 + Ms = torch.sigmoid(self.out_ms(mm)) + Mb = torch.sigmoid(self.out_mb(mm)) return Ms, Mb, Ic4, Ic2, Ic1 -# Refine网络 class RefineNet(nn.Module): - def __init__(self, in_channels=7): # 3(Iin)+1(Ms)+3(Ic1) =7 - super().__init__() - # 编码器:下采样 - self.down1 = DownSample(in_channels, 64) # 1/2 - self.down2 = DownSample(64, 128) # 1/4 - self.down3 = DownSample(128, 256) # 1/8 - self.down4 = DownSample(256, 512) # 1/16 - # 解码器:带空洞卷积的上采样 - self.up1 = DilatedUpSample(512, 256) # 1/8 - self.up2 = DilatedUpSample(512, 128) # 1/4 - self.up3 = DilatedUpSample(256, 64) # 1/2 - self.up4 = DilatedUpSample(128, 64) # 1/1 - # 输出层:精细化擦除结果Ire - self.out_ire = nn.Conv2d(64, 3, 3, 1, 1) + """精细修复网络:EraseNet 风格多尺度空洞卷积,感受野更大。 - def forward(self, x): - # 编码器 - d1 = self.down1(x) - d2 = self.down2(d1) - d3 = self.down3(d2) - d4 = self.down4(d3) - # 解码器 - u1 = self.up1(d4) - u1 = torch.cat([u1, d3], dim=1) - - u2 = self.up2(u1) - u2 = torch.cat([u2, d2], dim=1) - - u3 = self.up3(u2) - u3 = torch.cat([u3, d1], dim=1) - - u4 = self.up4(u3) - # 输出 - Ire = torch.tanh(self.out_ire(u4)) - return Ire + Args: + in_channels: 输入通道数 = Iin(3) + Ms(1) + Ic1(3) = 7 + """ + def __init__(self, in_channels: int = 7): + super().__init__() + cnum = 32 + + # 编码 + self.conva = nn.Sequential( + nn.Conv2d(in_channels, cnum, 5, padding=2, bias=False), + nn.BatchNorm2d(cnum), nn.ReLU(inplace=True)) + self.down1 = DownSample(cnum, cnum * 2) # H/2, 64 + self.convc = nn.Sequential( + nn.Conv2d(cnum * 2, cnum * 2, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 2), nn.ReLU(inplace=True)) + self.down2 = DownSample(cnum * 2, cnum * 4) # H/4, 128 + self.conve = nn.Sequential( + nn.Conv2d(cnum * 4, cnum * 4, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 4), nn.ReLU(inplace=True)) + self.convf = nn.Sequential( + nn.Conv2d(cnum * 4, cnum * 4, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 4), nn.ReLU(inplace=True)) + + # 多尺度空洞卷积(参照 EraseNet astrous_net) + self.astrous = nn.Sequential( + DilatedConvBlock(cnum * 4, cnum * 4, dilation=2), + DilatedConvBlock(cnum * 4, cnum * 4, dilation=4), + DilatedConvBlock(cnum * 4, cnum * 4, dilation=8), + DilatedConvBlock(cnum * 4, cnum * 4, dilation=16), + ) + self.convk = nn.Sequential( + nn.Conv2d(cnum * 4, cnum * 4, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 4), nn.ReLU(inplace=True)) + self.convl = nn.Sequential( + nn.Conv2d(cnum * 4, cnum * 4, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 4), nn.ReLU(inplace=True)) + + # 解码(cat 自身跳跃连接) + self.up1 = UpSample(cnum * 8, cnum * 2) # cat([x,x_c2]) H/4→H/2 + self.convm = nn.Sequential( + nn.Conv2d(cnum * 2, cnum * 2, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum * 2), nn.ReLU(inplace=True)) + self.up2 = UpSample(cnum * 4, cnum) # cat([x,x_c1]) H/2→H + self.convn = nn.Sequential( + nn.Conv2d(cnum, cnum // 2, 3, padding=1, bias=False), + nn.BatchNorm2d(cnum // 2), nn.ReLU(inplace=True), + nn.Conv2d(cnum // 2, 3, 3, padding=1)) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + x = self.conva(x) + x = self.down1(x) + x = self.convc(x) + x_c1 = x # H/2, 64 + x = self.down2(x) + x = self.conve(x) + x = self.convf(x) + x_c2 = x # H/4, 128 + x = self.astrous(x) + x = self.convk(x) + x = self.convl(x) + x = self.up1(torch.cat([x, x_c2], dim=1)) # H/2, 64 + x = self.convm(x) + x = self.up2(torch.cat([x, x_c1], dim=1)) # H, 32 + return torch.tanh(self.convn(x)) -# 生成器整体 class Generator(nn.Module): - def __init__(self): + """完整生成器:CoarseNet → RefineNet → 融合输出。 + + Args: + cfg: model 子配置字典,含 coarse_in_channels / refine_in_channels / cbam_reduction + """ + def __init__(self, cfg: dict = None): super().__init__() - self.coarse = CoarseNet() - self.refine = RefineNet() + if cfg is None: + cfg = {'coarse_in_channels': 3, 'refine_in_channels': 7, 'cbam_reduction': 16} + self.coarse = CoarseNet(in_channels=cfg['coarse_in_channels'], + cbam_reduction=cfg['cbam_reduction']) + self.refine = RefineNet(in_channels=cfg['refine_in_channels']) - def forward(self, Iin): - # Coarse网络输出 + def forward(self, Iin: torch.Tensor): Ms, Mb, Ic4, Ic2, Ic1 = self.coarse(Iin) - # 拼接输入:Iin + Ms + Ic1(通道维度) - refine_in = torch.cat([Iin, Ms, Ic1], dim=1) - # Refine网络输出 - Ire = self.refine(refine_in) - # 融合得到最终结果Icomp + Ire = self.refine(torch.cat([Iin, Ms, Ic1], dim=1)) Icomp = Ire * Mb + Iin * (1 - Mb) return Ms, Mb, Ic4, Ic2, Ic1, Ire, Icomp - - -# 基础判别器块 -class DiscBlock(nn.Module): - def __init__(self, in_channels, out_channels, stride=2): - super().__init__() - self.block = nn.Sequential( - nn.Conv2d(in_channels, out_channels, 4, stride, 1, bias=False), - nn.BatchNorm2d(out_channels), - nn.LeakyReLU(0.2, inplace=True) - ) - - def forward(self, x): - return self.block(x) - - -# Local-Global判别器 -class Discriminator(nn.Module): - def __init__(self, in_channels=3): - super().__init__() - # 全局判别器:输出标量(适配任意尺寸) - self.global_disc = nn.Sequential( - DiscBlock(in_channels, 64), - DiscBlock(64, 128), - DiscBlock(128, 256), - DiscBlock(256, 512), - nn.Conv2d(512, 1, 4, 1, 0, bias=False) # [B,1,1,1] - ) - # 局部判别器:输出特征图(用于掩码加权) - self.local_disc = nn.Sequential( - DiscBlock(in_channels, 64), - DiscBlock(64, 128), - DiscBlock(128, 256), - DiscBlock(256, 512), - nn.Conv2d(512, 1, 1, 1, 0, bias=False) # [B,1,H',W'] - ) - - def forward(self, x, local_mask=None): - """ - :param x: [B,3,H,W] 归一化到[-1,1]的图像 - :param local_mask: [B,1,H,W] 真实文本掩码(训练时必需) - :return: - global_score: [B,1,1,1] 全局判别logits - local_score: [B,1,H',W'] 掩码加权后的局部判别logits - """ - global_score = self.global_disc(x) - local_score = 0 - - if local_mask is not None: - # 1. 计算局部判别特征图 - local_feat = self.local_disc(x) # [B,1,H',W'] - # 2. 将local_mask下采样到local_feat的尺寸 - _, _, h_feat, w_feat = local_feat.shape - local_mask_scaled = F.interpolate(local_mask, size=(h_feat, w_feat), mode='nearest') - # 3. 关键修复:用掩码加权局部特征(仅关注文本区域) - local_score = local_feat * local_mask_scaled - - return global_score, local_score - - -# 加载预训练VGG16(用于感知/风格损失) -class VGG16Feature(nn.Module): - def __init__(self): - super().__init__() - vgg = vgg16(pretrained=True).features - self.feat1 = nn.Sequential(*vgg[:5]) # 第1个池化层前 - self.feat2 = nn.Sequential(*vgg[5:10]) # 第2个池化层前 - self.feat3 = nn.Sequential(*vgg[10:17]) # 第3个池化层前 - # 冻结参数 - for param in self.parameters(): - param.requires_grad = False - - # 【关键修正】ImageNet归一化参数 - # self.mean = torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1).cuda() - # self.std = torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1).cuda() - self.register_buffer('mean', torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1)) - self.register_buffer('std', torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1)) - - def forward(self, x): - # x: [B,3,H,W] 归一化到ImageNet标准 - # x: [-1,1] → [0,1] → ImageNet归一化 - x = (x + 1) / 2.0 # [-1,1] → [0,1] - x = F.interpolate(x, size=(224, 224), mode='bilinear', align_corners=False) - x = (x - self.mean) / self.std - f1 = self.feat1(x) - f2 = self.feat2(f1) - f3 = self.feat3(f2) - return [f1, f2, f3] - - -# Gram矩阵计算 -def gram_matrix(x): - b, c, h, w = x.shape - x = x.view(b, c, h * w) - return torch.bmm(x, x.transpose(1, 2)) / (c * h * w) - - -# 全量Loss计算类 -class EnsExamLoss(nn.Module): - def __init__(self, loss_config=None): - super().__init__() - if loss_config is None: - loss_config = {} - self.vgg_feat = VGG16Feature() - self.lambda_n = loss_config.get('lambda_n', [5, 6, 8, 10]) - self.beta_n = loss_config.get('beta_n', [0.8, 0.8, 0.8, 2]) - self.lambda_lr = loss_config.get('lambda_lr', 1.0) - self.lambda_p = loss_config.get('lambda_p', 0.05) - self.lambda_style = loss_config.get('lambda_style', 120) - self.lambda_sn = loss_config.get('lambda_sn', 1) - self.lambda_b = loss_config.get('lambda_b', 0.4) - - def sn_loss(self, Ms, Ms_gt): - """SN损失""" - Ms = Ms.float() - Ms_gt = Ms_gt.float() - - # 1. 计算每个样本的 GT 字迹总面积 (Batch 维度) - # shape: [B] - sum_gt = torch.sum(Ms_gt, dim=tuple(range(1, Ms.dim()))) - - # 2. 创建掩码:只选择 GT 中有字迹的样本 (阈值设为 1,避免浮点误差) - # 如果 sum_gt > 0,则 valid_mask 为 1,否则为 0 - valid_mask = (sum_gt > 1.0).float() - - # 如果整个 Batch 都没有字迹,直接返回 0,避免除零或无效计算 - if valid_mask.sum() == 0: - # 返回与输入无关的零梯度,但保持可训练 - return Ms.sum() * 0 # 利用输入创建,保持计算图连接 - - # 3. 计算 L1 误差总和 [B] - l1_sum = torch.sum(torch.abs(Ms - Ms_gt), dim=tuple(range(1, Ms.dim()))) - - # 4. 计算归一化分母 [B] - sum_pred = torch.sum(Ms, dim=tuple(range(1, Ms.dim()))) - normalization = torch.min(sum_pred, sum_gt) - - # 5. 计算单样本 Loss - # 注意:这里 epsilon 可以改回 1e-6,因为 valid_mask 已经保证了 sum_gt 不为 0 - loss_batch = l1_sum / (normalization + 1e-6) - - # 6. 只对有字迹的样本求平均 - # 乘以 valid_mask 将无字样本 loss 置零,除以 valid_mask.sum() 保证梯度尺度稳定 - L_sn = (loss_batch * valid_mask).sum() / (valid_mask.sum() + 1e-6) - - return L_sn - - def block_loss(self, Mb, Mb_gt): - # 逐样本计算 - intersection = (Mb * Mb_gt).sum(dim=[1, 2, 3]) # [B] - mb_sq = (Mb ** 2).sum(dim=[1, 2, 3]) # [B] - mbgt_sq = (Mb_gt ** 2).sum(dim=[1, 2, 3]) # [B] - - dice = (2 * intersection) / (mb_sq + mbgt_sq + 1e-8) # [B] - return (1 - dice).mean() # 平均所有样本 - - def lr_loss(self, Iouts, Igt_list, Mb_gt): - """LR损失(修复多尺度掩码维度匹配问题)""" - lr_loss = 0.0 - for i, (Iout, Igt) in enumerate(zip(Iouts, Igt_list)): - # 关键修复:将Mb_gt下采样到当前Iout/Igt的尺度 - # 获取当前Iout的高/宽 - _, _, h, w = Iout.shape - # 下采样Mb_gt到(h, w),保持通道数不变 - Mb_gt_scaled = F.interpolate(Mb_gt, size=(h, w), mode='nearest') - - # 文本区域损失(使用下采样后的掩码) - loss_text = F.l1_loss(Iout * Mb_gt_scaled, Igt * Mb_gt_scaled, reduction='mean') - # 非文本区域损失(使用下采样后的掩码) - loss_nontext = F.l1_loss(Iout * (1 - Mb_gt_scaled), Igt * (1 - Mb_gt_scaled), reduction='mean') - # 加权求和 - lr_loss += self.lambda_n[i] * loss_text + self.beta_n[i] * loss_nontext - return lr_loss - - def perceptual_loss(self, I_list, Igt): - """感知损失""" - per_loss = 0.0 - gt_feats = self.vgg_feat(Igt) - for I in I_list: - I_feats = self.vgg_feat(I) - for f1, f2 in zip(I_feats, gt_feats): - per_loss += F.l1_loss(f1, f2, reduction='mean') - return per_loss - - def style_loss(self, I_list, Igt): - style_loss = 0.0 - gt_feats = self.vgg_feat(Igt) - for I in I_list: - I_feats = self.vgg_feat(I) - for f1, f2 in zip(I_feats, gt_feats): - b, c, h, w = f1.shape - gram1 = gram_matrix(f1) # [B, C, C] - gram2 = gram_matrix(f2) # [B, C, C] - # 关键:除以 H*W*C 归一化 - norm = h * w * c - style_loss += F.l1_loss(gram1, gram2, reduction='mean') / norm - return style_loss - - # 判别器损失(训练D时用) - @staticmethod - def hinge_loss_D(real_score, fake_score): - loss_real = torch.mean(F.relu(1.0 - real_score)) - loss_fake = torch.mean(F.relu(1.0 + fake_score)) - return loss_real + loss_fake - - # 生成器损失(训练G时用) - @staticmethod - def hinge_loss_G(fake_score): - return -torch.mean(F.relu(1.0 + fake_score)) # 注意:ReLU(1+score) - - def forward(self, gen_out, gt, disc_score): - """ - 总损失计算 - :param gen_out: 生成器输出 (Ms, Mb, Ic4, Ic2, Ic1, Ire, Icomp) - :param gt: 标签 (Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt) - :param disc_score: 判别器分数 (global_score, local_score) - :return: 总损失,各分项损失 - """ - Ms, Mb, Ic4, Ic2, Ic1, Ire, Icomp = gen_out - Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt = gt - global_score, local_score = disc_score - - # 各分项损失 - L_sn = self.sn_loss(Ms, Ms_gt) * self.lambda_sn - L_block = self.block_loss(Mb, Mb_gt) * self.lambda_b - L_lr = self.lr_loss([Ic4, Ic2, Ic1, Ire], [Igt4, Igt2, Igt1, Igt], Mb_gt) * self.lambda_lr - L_per = self.perceptual_loss([Ire, Icomp], Igt) * self.lambda_p - L_style = self.style_loss([Ire, Icomp], Igt) * self.lambda_style - - L_adv_global = self.hinge_loss_G(global_score) - L_adv_local = self.hinge_loss_G(local_score) - L_adv = (L_adv_global + L_adv_local) / 2 - - # 总损失 - L_total = L_adv + L_lr + L_per + L_style + L_sn + L_block - return L_total, [L_adv, L_lr, L_per, L_style, L_sn, L_block] \ No newline at end of file diff --git a/backend/models/test_erase.py b/backend/models/test_erase.py index 59c13aa4..e0eee131 100644 --- a/backend/models/test_erase.py +++ b/backend/models/test_erase.py @@ -9,8 +9,7 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) import torch -torch.backends.cudnn.deterministic = True -torch.backends.cudnn.benchmark = False +torch.backends.cudnn.enabled = False # cuDNN v8 frontend 与 A30+PyTorch2.1 不兼容 from pathlib import Path from PIL import Image import numpy as np @@ -27,7 +26,7 @@ sys.exit(1) # ── 路径配置 ────────────────────────────────────────── -MODEL_PATH = Path(__file__).parent.parent / "runtime_data" / "models" / "latest.pth" +MODEL_PATH = Path(__file__).parent / "weight" / "best.pth" OUTPUT_DIR = Path(__file__).parent.parent / "runtime_data" / "erased" OUTPUT_DIR.mkdir(parents=True, exist_ok=True) diff --git a/backend/models/train.py b/backend/models/train.py deleted file mode 100644 index 9baa621a..00000000 --- a/backend/models/train.py +++ /dev/null @@ -1,556 +0,0 @@ -# 设备 -import math -import os -import argparse - -import numpy as np -import torch -from torch import optim -from torch.utils.data import Dataset, DataLoader -from torchvision.transforms import transforms -import torch.nn.functional as F -from tqdm import tqdm - -from src.adcj.EnsExam.model import Generator, Discriminator, EnsExamLoss -from src.adcj.EnsExam.config import config - -import os -import torch -import numpy as np -import cv2 -from torch.utils.data import Dataset -from torchvision import transforms -import torch.nn.functional as F - - -def generate_mask_from_pair(Iin, Igt, threshold=20, debug=False): - """ - 单块(512x512)软笔画掩码生成 - 修正版本 - :param Iin: 单块图像 (H,W,3) RGB 0-255 - :param Igt: 单块GT图 (H,W,3) RGB 0-255 - :param threshold: 差异阈值,默认20 - :param debug: 是否返回中间结果用于调试 - :return: Ms_gt(软掩码), Mb_gt(基础掩码), [debug_dict] - """ - H, W = Iin.shape[:2] - - # ========== 1. 生成粗笔画掩码 ========== - # 使用int16避免溢出,计算RGB三通道的平均差异 - diff = np.abs(Iin.astype(np.int16) - Igt.astype(np.int16)).mean(axis=-1) - # print(f"Diff统计: min={diff.min()}, max={diff.max()}, 90%={np.percentile(diff, 90)}") - coarse_mask = (diff > threshold).astype(np.uint8) - - # ========== 2. 形态学去噪 ========== - kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) - # 开运算去除散点噪声 + 闭运算连接断裂笔画 - denoised_mask = cv2.morphologyEx(coarse_mask, cv2.MORPH_OPEN, kernel) - denoised_mask = cv2.morphologyEx(denoised_mask, cv2.MORPH_CLOSE, kernel) - - # ========== 3. 生成 Mb_gt(基础文本块掩码) ========== - # 对去噪后的掩码适度膨胀,作为文本区域指导 - Mb_gt = cv2.dilate(denoised_mask, kernel, iterations=2).astype(np.float32) - - # ========== 4. 生成软笔画掩码 Ms_gt ========== - # 4.1 骨架:笔画收缩1像素(论文明确要求) - skeleton = cv2.erode(denoised_mask, kernel, iterations=1) - - # 4.2 外边界区域:原始笔画扩张5像素 - kernel_large = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) - outer_region = cv2.dilate(denoised_mask, kernel_large, iterations=5) - - # 4.3 距离变换:计算outer_region内每个像素到边缘的最短距离 - # 输入要求:uint8, 0=背景, >0=前景;输出:float32,单位像素 - dist_map = cv2.distanceTransform(outer_region, cv2.DIST_L2, cv2.DIST_MASK_PRECISE) - - # 4.4 SAF 参数 (论文明确值) - alpha = 3.0 - L = 5.0 - exp_neg_alpha = np.exp(-alpha) - C = (1 + exp_neg_alpha) / (1 - exp_neg_alpha + 1e-8) # +eps防除零 - - # 4.5 向量化计算软掩码(避免循环,提速100x) - Ms_gt = np.zeros((H, W), dtype=np.float32) - - # 区域划分mask - mask_skeleton = skeleton > 0 # 骨架区域 → 值=1 - mask_outer = outer_region > 0 # 扩张区域(含骨架) - mask_middle = mask_outer & (~mask_skeleton) # 中间环形区域 → 用SAF - - # (a) 骨架区域强制=1 - Ms_gt[mask_skeleton] = 1.0 - - # (b) 中间区域应用SAF衰减 - if np.any(mask_middle): - D = np.clip(dist_map[mask_middle], 0, L) # 距离截断到[0, L] - # SAF公式: C * (2/(1+exp(-α*D/L)) - 1) - exp_term = np.exp(-alpha * D / L) - saf_vals = C * (2.0 / (1.0 + exp_term + 1e-8) - 1.0) - Ms_gt[mask_middle] = np.clip(saf_vals, 0.0, 1.0) - - # (c) 外边界及以外区域保持=0(已初始化为0) - - # ========== 5. 调试信息(可选) ========== - if debug: - debug_info = { - 'coarse_mask': coarse_mask, - 'denoised_mask': denoised_mask, - 'skeleton': skeleton, - 'outer_region': outer_region, - 'dist_map': dist_map, - 'mask_middle': mask_middle.astype(np.uint8) * 255 - } - return Ms_gt, Mb_gt, debug_info - - return Ms_gt, Mb_gt - - -# -------------------------- 真实数据集加载类(核心修复:统一图像尺寸) -------------------------- -# class EnsExamRealDataset(Dataset): -# """ -# 适配“仅含原始图+擦除GT图”的数据集加载类 -# ✅ 修复:所有图像读取后先resize到img_size,保证批量尺寸一致 -# """ -# -# def __init__(self, data_root, img_size=512, is_train=True): -# self.data_root = data_root -# self.img_size = img_size # 统一目标尺寸(512×512) -# self.is_train = is_train -# -# # 1. 定义图像预处理:归一化到[-1,1](匹配GAN训练) -# self.img_transform = transforms.Compose([ -# transforms.ToTensor(), # HWC→CHW,0-255→0-1 -# transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # 0-1→[-1,1] -# ]) -# -# # 2. 加载文件列表(保证images和gt目录下文件同名) -# split = "train" if is_train else "test" -# self.img_dir = os.path.join(data_root, split, "all_images") -# self.gt_dir = os.path.join(data_root, split, "all_labels") -# -# # 过滤有效文件(仅保留png/jpg/jpeg) -# self.file_names = [ -# f for f in os.listdir(self.img_dir) -# if f.endswith((".png", ".jpg", ".jpeg")) and os.path.exists(os.path.join(self.gt_dir, f)) -# ] -# assert len(self.file_names) > 0, f"未找到匹配的图像文件!检查{self.img_dir}和{self.gt_dir}目录" -# -# def __len__(self): -# return len(self.file_names) -# -# def __getitem__(self, idx): -# # 1. 加载原始图和擦除GT图 -# file_name = self.file_names[idx] -# img_path = os.path.join(self.img_dir, file_name) -# gt_path = os.path.join(self.gt_dir, file_name) -# -# # 读取图像(BGR→RGB,避免OpenCV默认BGR格式问题) -# Iin = cv2.imread(img_path)[:, :, ::-1] # (H,W,3),0-255,RGB -# Igt = cv2.imread(gt_path)[:, :, ::-1] # (H,W,3),0-255,RGB -# -# # ✅ 核心修复1:先统一resize到img_size×img_size(所有样本尺寸一致) -# Iin = cv2.resize(Iin, (self.img_size, self.img_size), interpolation=cv2.INTER_LINEAR) -# Igt = cv2.resize(Igt, (self.img_size, self.img_size), interpolation=cv2.INTER_LINEAR) -# -# # 2. 自动生成Ms_gt(软笔画掩码)、Mb_gt(文本块掩码) -# # ✅ 核心修复2:传入已resize的图像,函数内不再重复resize -# Ms_gt_np, Mb_gt_np = generate_mask_from_pair(Iin, Igt, threshold=20) -# -# # 3. 图像预处理(归一化到[-1,1]) -# Iin = self.img_transform(Iin) # (3,512,512),[-1,1] -# Igt = self.img_transform(Igt) # (3,512,512),[-1,1] -# -# # 4. 掩码预处理(归一化到[0,1],扩展通道维度) -# Ms_gt = torch.from_numpy(Ms_gt_np).unsqueeze(0).float() # (1,512,512),[0,1] -# Mb_gt = torch.from_numpy(Mb_gt_np).unsqueeze(0).float() # (1,512,512),[0,1] -# -# # 5. 生成多尺度擦除GT(1/4, 1/2, 1/1) -# # Igt4:512→128,Igt2:512→256,Igt1:原尺寸 -# Igt4 = F.interpolate(Igt.unsqueeze(0), size=(self.img_size // 4, self.img_size // 4), mode='bilinear', -# align_corners=False).squeeze(0) -# Igt2 = F.interpolate(Igt.unsqueeze(0), size=(self.img_size // 2, self.img_size // 2), mode='bilinear', -# align_corners=False).squeeze(0) -# Igt1 = Igt # 1:1尺度 -# -# # 返回顺序:Iin, Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt -# return Iin, Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt - -class EnsExamRealDataset(Dataset): - """ - 适配“仅含原始图 + 擦除 GT 图”的数据集加载类 - ✅ 修改:不再 resize 原图,而是将大图裁剪为多个 512x512 的样本块 - """ - - def __init__(self, data_root, img_size=512, is_train=True, overlap=0): - """ - :param data_root: 数据集根目录 - :param img_size: 裁剪块尺寸 (默认 512) - :param is_train: 是否训练模式 - :param overlap: 裁剪重叠像素 (默认 0,即不重叠;训练时可设为 128 增加数据量) - """ - self.data_root = data_root - self.img_size = img_size - self.is_train = is_train - self.overlap = overlap - - # 1. 定义图像预处理:归一化到 [-1,1] - self.img_transform = transforms.Compose([ - transforms.ToTensor(), # HWC→CHW, 0-255→0-1 - transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) - ]) - - # 2. 获取文件路径 - split = "train" if is_train else "test" - self.img_dir = os.path.join(data_root, split, "all_images") - self.gt_dir = os.path.join(data_root, split, "all_labels") - - # 3. ✅ 核心修改:构建“样本索引列表” - # 不再是一对一 (1 图=1 样本),而是一对多 (1 图=N 个样本块) - self.patch_index_map = [] - - valid_extensions = (".png", ".jpg", ".jpeg") - all_files = [f for f in os.listdir(self.img_dir) if f.endswith(valid_extensions)] - - print(f"🔍 正在扫描数据集并构建裁剪索引 (Overlap={overlap})...") - for fname in all_files: - if not os.path.exists(os.path.join(self.gt_dir, fname)): - continue - - img_path = os.path.join(self.img_dir, fname) - gt_path = os.path.join(self.gt_dir, fname) - - # 读取尺寸 (仅读取头信息,不加载像素,速度快) - # 如果 cv2.imread 太慢,可用 imageio 或 PIL 获取 size,这里为了兼容直接用 cv2 - # 注意:这里必须加载一次获取 H,W,或者用 cv2.imread + IMREAD_UNCHANGED - img_temp = cv2.imread(img_path) - if img_temp is None: continue - H, W = img_temp.shape[:2] - del img_temp # 释放内存 - - # 计算步长 - step = self.img_size - self.overlap - if step <= 0: step = 1 # 防止 overlap 过大导致步长为 0 - - # 计算该图能切多少块 (覆盖全图,边缘不足补黑) - # 使用 math.ceil 确保覆盖整张图 - num_h = math.ceil((H - self.overlap) / step) if H > self.img_size else 1 - num_w = math.ceil((W - self.overlap) / step) if W > self.img_size else 1 - - # 如果原图小于 512,也作为一个样本 (后续会 padding) - if H <= self.img_size and W <= self.img_size: - num_h, num_w = 1, 1 - - for i in range(num_h): - for j in range(num_w): - # 计算裁剪坐标 - y1 = i * step - x1 = j * step - - # 如果是最后一块,确保覆盖到边缘 - y2 = min(y1 + self.img_size, H) - x2 = min(x1 + self.img_size, W) - - # 如果是第一块且图很小,直接取全图 - if H <= self.img_size: y1, y2 = 0, H - if W <= self.img_size: x1, x2 = 0, W - - # 记录样本信息:(图路径,GT 路径,裁剪坐标,是否需要 padding) - need_pad_h = (y2 - y1) < self.img_size - need_pad_w = (x2 - x1) < self.img_size - - self.patch_index_map.append({ - 'img_path': img_path, - 'gt_path': gt_path, - 'y1': y1, 'y2': y2, - 'x1': x1, 'x2': x2, - 'pad_h': need_pad_h, - 'pad_w': need_pad_w - }) - - print(f"✅ 索引构建完成:共 {len(self.patch_index_map)} 个样本块 (来自 {len(all_files)} 张图)") - assert len(self.patch_index_map) > 0, "未找到有效样本!" - - def __len__(self): - return len(self.patch_index_map) - - def __getitem__(self, idx): - # 1. 获取当前样本的裁剪信息 - info = self.patch_index_map[idx] - - # print(f"🔎 Loading: {info['img_path']}") - # print(f" Exists: {os.path.exists(info['img_path'])}") - - # 2. 加载完整原图 (RGB) - Iin_full = cv2.imread(info['img_path'])[:, :, ::-1] - Igt_full = cv2.imread(info['gt_path'])[:, :, ::-1] - - # 3. ✅ 核心修改:根据坐标裁剪 - Iin = Iin_full[info['y1']:info['y2'], info['x1']:info['x2']] - Igt = Igt_full[info['y1']:info['y2'], info['x1']:info['x2']] - - Iin = np.ascontiguousarray(Iin) - Igt = np.ascontiguousarray(Igt) - - # 4. ✅ 边缘填充 (确保输入模型的都是 512x512) - if info['pad_h'] or info['pad_w']: - pad_h = self.img_size - Iin.shape[0] - pad_w = self.img_size - Iin.shape[1] - # 使用 REPLICATE 填充比 CONSTANT(黑边) 更好,减少边界伪影 - Iin = cv2.copyMakeBorder(Iin, 0, pad_h, 0, pad_w, cv2.BORDER_REPLICATE) - Igt = cv2.copyMakeBorder(Igt, 0, pad_h, 0, pad_w, cv2.BORDER_REPLICATE) - - # 5. 生成掩码 (输入已经是 512x512) - # 注意:这里调用的是单块生成函数,不是滑动拼接函数 - Ms_gt_np, Mb_gt_np = generate_mask_from_pair(Iin, Igt, threshold=20) - - # 6. 图像预处理 (归一化) - Iin = self.img_transform(Iin) # (3, 512, 512) - Igt = self.img_transform(Igt) # (3, 512, 512) - - # 7. 掩码转 Tensor - Ms_gt = torch.from_numpy(Ms_gt_np).unsqueeze(0).float() - Mb_gt = torch.from_numpy(Mb_gt_np).unsqueeze(0).float() - - # 8. 生成多尺度 GT (1/4, 1/2, 1/1) - Igt_unsqueeze = Igt.unsqueeze(0) - Igt4 = F.interpolate(Igt_unsqueeze, size=(self.img_size // 4, self.img_size // 4), - mode='bilinear', align_corners=False).squeeze(0) - Igt2 = F.interpolate(Igt_unsqueeze, size=(self.img_size // 2, self.img_size // 2), - mode='bilinear', align_corners=False).squeeze(0) - Igt1 = Igt - - # 返回:Iin, Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt - return Iin, Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt - - -# ====================== 3. 核心训练函数 ====================== -def train_ensexam( - epochs=None, - batch_size=None, - lr=None, - data_root=None, - img_size=512, - save_dir=None, - resume_path=None, - resume=False, - num_workers=None, - device=None, - use_wandb=None): - train_cfg = config.train - loss_cfg = config.loss - wandb_cfg = config.wandb - - epochs = epochs if epochs is not None else train_cfg.get('epochs', 100) - batch_size = batch_size if batch_size is not None else train_cfg.get('batch_size', 4) - lr = lr if lr is not None else train_cfg.get('lr', 0.0001) - data_root = data_root if data_root is not None else train_cfg.get('data_root', './data') - save_dir = save_dir if save_dir is not None else train_cfg.get('save_dir', './ensexam_checkpoints') - resume_path = resume_path if resume_path is not None else train_cfg.get('resume_path', - './ensexam_checkpoints/latest.pth') - num_workers = num_workers if num_workers is not None else train_cfg.get('num_workers', 4) - device = device if device is not None else train_cfg.get('device', 'cuda' if torch.cuda.is_available() else 'cpu') - use_wandb = use_wandb if use_wandb is not None else wandb_cfg.get('enabled', True) - # 0. 初始化目录 - os.makedirs(save_dir, exist_ok=True) - - wandb_run = None - if use_wandb: - try: - import wandb - wandb_cfg = config.wandb - if wandb_cfg.get('offline', True): - os.environ['WANDB_MODE'] = 'offline' - wandb_dir = wandb_cfg.get('dir', './wandb') - os.makedirs(wandb_dir, exist_ok=True) - - wandb_run = wandb.init( - project=wandb_cfg.get('project', 'ensexam'), - name=wandb_cfg.get('name'), - entity=wandb_cfg.get('entity'), - dir=wandb_cfg.get('dir', './wandb'), - config={ - 'train': train_cfg, - 'loss': loss_cfg - } - ) - print(f"WandB 初始化成功 (离线模式: {wandb_cfg.get('offline', True)})") - except ImportError: - print("Warning: wandb 未安装,跳过 wandb 记录") - except Exception as e: - print(f"Warning: wandb 初始化失败: {e}") - - # 1. 数据加载 - train_dataset = EnsExamRealDataset(data_root=data_root) - train_loader = DataLoader( - train_dataset, - batch_size=batch_size, - shuffle=True, - num_workers=0, # Windows下建议设为0,避免多进程问题 - drop_last=True - ) - - # 2. 模型初始化 - G = Generator().to(device) - D = Discriminator().to(device) - criterion = EnsExamLoss(loss_cfg).to(device) - - # 3. 优化器 - optimizer_G = optim.Adam(G.parameters(), lr=lr, betas=(0.5, 0.9)) - optimizer_D = optim.Adam(D.parameters(), lr=lr, betas=(0.5, 0.9)) - - # 4. 断点续训 - start_epoch = 0 - if resume and os.path.exists(resume_path): - checkpoint = torch.load(resume_path, map_location=device) - G.load_state_dict(checkpoint['G_state_dict']) - D.load_state_dict(checkpoint['D_state_dict']) - optimizer_G.load_state_dict(checkpoint['optimizer_G']) - optimizer_D.load_state_dict(checkpoint['optimizer_D']) - start_epoch = checkpoint['epoch'] - print(f"断点续训:从第{start_epoch}Epoch恢复") - - # 5. 训练循环 - G.train() - D.train() - for epoch in range(start_epoch, epochs): - epoch_loss_G = 0.0 # 生成器总损失 - epoch_loss_D = 0.0 # 判别器总损失 - epoch_loss_parts = { - 'adv': 0.0, - 'lr': 0.0, - 'per': 0.0, - 'style': 0.0, - 'sn': 0.0, - 'block': 0.0 - } - pbar = tqdm(train_loader, desc=f"Epoch {epoch + 1}/{epochs}") - - for batch_idx, (Iin, Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt) in enumerate(pbar): - # 数据移到设备 - Iin = Iin.to(device) - Ms_gt = Ms_gt.to(device) - Mb_gt = Mb_gt.to(device) - Igt4 = Igt4.to(device) - Igt2 = Igt2.to(device) - Igt1 = Igt1.to(device) - Igt = Igt.to(device) - gt = (Ms_gt, Mb_gt, Igt4, Igt2, Igt1, Igt) - - # ---------------------- 步骤1:训练判别器D ---------------------- - optimizer_D.zero_grad() - - # 1.1 真实图像判别 - real_global, real_local = D(Igt, Mb_gt) - # 1.2 生成图像判别 - gen_out = G(Iin) - Icomp = gen_out[-1] # 取最后一个输出Icomp - fake_global, fake_local = D(Icomp.detach(), Mb_gt) - # 1.3 计算D损失(使用Model中的hinge_loss_D) - loss_D_global = EnsExamLoss.hinge_loss_D(real_global, fake_global) - loss_D_local = EnsExamLoss.hinge_loss_D(real_local, fake_local) - loss_D = (loss_D_global + loss_D_local) / 2 - - loss_D.backward() - optimizer_D.step() - - # ---------------------- 步骤2:训练生成器G ---------------------- - optimizer_G.zero_grad() - - # 2.1 重新计算生成图像的判别分数 - fake_global, fake_local = D(Icomp, Mb_gt) - disc_score = (fake_global, fake_local) - # 2.2 计算G的全量损失(Model中的EnsExamLoss.forward) - loss_G, loss_parts = criterion(gen_out, gt, disc_score) - - loss_G.backward() - optimizer_G.step() - - # ---------------------- 步骤3:日志记录 ---------------------- - epoch_loss_G += loss_G.item() - epoch_loss_D += loss_D.item() - epoch_loss_parts['adv'] += loss_parts[0].item() - epoch_loss_parts['lr'] += loss_parts[1].item() - epoch_loss_parts['per'] += loss_parts[2].item() - epoch_loss_parts['style'] += loss_parts[3].item() - epoch_loss_parts['sn'] += loss_parts[4].item() - epoch_loss_parts['block'] += loss_parts[5].item() - - # 进度条显示 - pbar.set_postfix({ - 'Loss_D': f"{loss_D.item():.4f}", - 'Loss_G': f"{loss_G.item():.4f}", - 'Loss_G_adv': f"{loss_parts[0].item():.4f}", - 'Loss_G_lr': f"{loss_parts[1].item():.4f}" - }) - if wandb_run is not None: - wandb.log({ - 'batch_loss_G': loss_G.item(), - 'batch_loss_D': loss_D.item(), - 'batch_loss_G_adv': loss_parts[0].item(), - 'batch_loss_G_lr': loss_parts[1].item(), - 'batch_loss_G_per': loss_parts[2].item(), - 'batch_loss_G_style': loss_parts[3].item(), - 'batch_loss_G_sn': loss_parts[4].item(), - 'batch_loss_G_block': loss_parts[5].item() - }) - - # ---------------------- 步骤4:Epoch结束处理 ---------------------- - # 计算Epoch平均损失 - avg_loss_G = epoch_loss_G / len(train_loader) - avg_loss_D = epoch_loss_D / len(train_loader) - avg_loss_parts = {k: v / len(train_loader) for k, v in epoch_loss_parts.items()} - print(f"Epoch {epoch + 1} 平均损失:Loss_G={avg_loss_G:.4f}, Loss_D={avg_loss_D:.4f}") - if wandb_run is not None: - wandb.log({ - 'epoch': epoch + 1, - 'avg_loss_G': avg_loss_G, - 'avg_loss_D': avg_loss_D - }) - - # 保存模型(每5个Epoch保存一次,同时保存最新模型) - if (epoch + 1) % 5 == 0 or epoch == epochs - 1: - checkpoint = { - 'epoch': epoch + 1, - 'G_state_dict': G.state_dict(), - 'D_state_dict': D.state_dict(), - 'optimizer_G': optimizer_G.state_dict(), - 'optimizer_D': optimizer_D.state_dict(), - 'avg_loss_G': avg_loss_G, - 'avg_loss_D': avg_loss_D - } - # 保存最新模型(用于断点续训) - torch.save(checkpoint, os.path.join(save_dir, 'latest.pth')) - # 保存Epoch模型 - torch.save(checkpoint, os.path.join(save_dir, f'ensexam_epoch_{epoch + 1}.pth')) - print(f"模型已保存:{os.path.join(save_dir, f'ensexam_epoch_{epoch + 1}.pth')}") - - if wandb_run is not None: - wandb.finish() - print("训练完成!") - - -# ====================== 4. 启动训练 ====================== -if __name__ == "__main__": - parser = argparse.ArgumentParser(description='EnsExam 训练') - parser.add_argument('--epochs', type=int, default=None, help='训练轮数') - parser.add_argument('--batch_size', type=int, default=None, help='批次大小') - parser.add_argument('--lr', type=float, default=None, help='学习率') - parser.add_argument('--device', type=str, default=None, help='设备 (cuda/cpu)') - parser.add_argument('--data_root', type=str, default=None, help='数据集路径') - parser.add_argument('--save_dir', type=str, default=None, help='模型保存目录') - parser.add_argument('--resume', action='store_true', help='断点续训') - parser.add_argument('--no_wandb', action='store_true', help='禁用 wandb') - args = parser.parse_args() - - use_wandb = not args.no_wandb - device = args.device - - train_ensexam( - epochs=args.epochs, - batch_size=args.batch_size, - lr=args.lr, - device=device, - data_root=args.data_root, - save_dir=args.save_dir, - resume=args.resume, - use_wandb=use_wandb - ) \ No newline at end of file diff --git a/backend/models/weight/best.pth b/backend/models/weight/best.pth new file mode 100644 index 00000000..61723552 --- /dev/null +++ b/backend/models/weight/best.pth @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ce399f0447fdc016bbe3957559264735a5b9e5de30725ca2ed4d66699fd3f47 +size 362841171 diff --git a/backend/package-lock.json b/backend/package-lock.json new file mode 100644 index 00000000..dfb18f11 --- /dev/null +++ b/backend/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "backend", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/backend/routes/__init__.py b/backend/routes/__init__.py new file mode 100644 index 00000000..1a9f7b33 --- /dev/null +++ b/backend/routes/__init__.py @@ -0,0 +1,22 @@ +""" +路由注册模块 — 将所有 Blueprint 注册到 Flask app +""" + +from .auth import bp as auth_bp +from .upload import bp as upload_bp +from .questions import bp as questions_bp +from .chat import bp as chat_bp +from .stats import bp as stats_bp +from .settings import bp as settings_bp +from .notes import bp as notes_bp + + +def register_routes(app): + """注册所有 Blueprint 到 Flask app""" + app.register_blueprint(auth_bp, url_prefix='/api/auth') + app.register_blueprint(upload_bp, url_prefix='/api') + app.register_blueprint(questions_bp, url_prefix='/api') + app.register_blueprint(chat_bp, url_prefix='/api') + app.register_blueprint(stats_bp, url_prefix='/api') + app.register_blueprint(settings_bp, url_prefix='/api') + app.register_blueprint(notes_bp, url_prefix='/api/notes') diff --git a/backend/routes/auth.py b/backend/routes/auth.py new file mode 100644 index 00000000..01efeeb1 --- /dev/null +++ b/backend/routes/auth.py @@ -0,0 +1,284 @@ +import hmac +import hashlib +import logging +import secrets +from datetime import datetime, timedelta + +from flask import Blueprint, request, jsonify, session, current_app +from werkzeug.security import generate_password_hash, check_password_hash + +from core.config import settings +from core.mail import send_smtp_email +from db import SessionLocal +from db import crud + +logger = logging.getLogger(__name__) + +bp = Blueprint("auth", __name__) + + +def _hash_registration_code(email: str, code: str, pepper: str) -> str: + raw = f"{email.lower().strip()}:{code}".encode("utf-8") + return hmac.new(pepper.encode("utf-8"), raw, hashlib.sha256).hexdigest() + + +def _generate_six_digit_code() -> str: + return f"{secrets.randbelow(900000) + 100000}" + + +@bp.route("/register", methods=["POST"]) +def auth_register(): + """用户注册(需先调用 /send-code?type=register 并填写正确验证码)。""" + data = request.get_json() or {} + email = (data.get("email") or "").strip().lower() + username = (data.get("username") or "").strip() + password = data.get("password") or "" + code = (data.get("code") or "").strip() + + if not email or "@" not in email: + return jsonify({"success": False, "error": "邮箱格式不正确"}), 400 + if not username: + return jsonify({"success": False, "error": "用户名不能为空"}), 400 + if len(password) < 6: + return jsonify({"success": False, "error": "密码至少 6 位"}), 400 + if not code or not code.isdigit() or len(code) != 6: + return jsonify({"success": False, "error": "请输入 6 位邮箱验证码"}), 400 + + pepper = (current_app.secret_key or "dev-secret-change-in-production")[:64] + submitted_hash = _hash_registration_code(email, code, pepper) + now = datetime.utcnow() + + user_id = None + username_out = None + email_out = None + is_admin_out = None + + with SessionLocal() as db: + if crud.get_user_by_email(db, email): + return jsonify({"success": False, "error": "该邮箱已注册"}), 409 + + row = crud.get_verification_by_email(db, email) + if not row: + return jsonify({"success": False, "error": "请先获取邮箱验证码"}), 400 + if row.expires_at < now: + crud.delete_verification_by_email(db, email) + return jsonify({"success": False, "error": "验证码已过期,请重新获取"}), 400 + if (row.attempts or 0) >= settings.registration_max_attempts: + crud.delete_verification_by_email(db, email) + return jsonify({"success": False, "error": "验证失败次数过多,请重新获取验证码"}), 400 + + if not hmac.compare_digest(row.code_hash, submitted_hash): + crud.increment_verification_attempts(db, email) + return jsonify({"success": False, "error": "验证码错误"}), 400 + + pwd_hash = generate_password_hash(password) + user = crud.create_user(db, email=email, password_hash=pwd_hash, username=username) + crud.delete_verification_by_email(db, email) + # 将需要的字段提前取出为纯 Python 变量,避免脱离 Session 后访问 ORM 对象触发 DetachedInstanceError + user_id = user.id + username_out = user.username + email_out = user.email + is_admin_out = user.is_admin + session_version_out = user.session_version or 0 + + session["user_id"] = user_id + session["username"] = username_out + session["is_admin"] = bool(is_admin_out) + session["session_version"] = session_version_out + return jsonify( + { + "success": True, + "user": { + "id": user_id, + "email": email_out, + "username": username_out, + "is_admin": is_admin_out, + }, + } + ), 201 + + +@bp.route("/send-code", methods=["POST"]) +def send_code(): + """发送验证码(支持注册和找回密码两种场景)。 + + 请求体:{ email, type: 'register' | 'reset' } + """ + data = request.get_json() or {} + email = (data.get("email") or "").strip().lower() + code_type = (data.get("type") or "register").strip().lower() + + if not email or "@" not in email: + return jsonify({"success": False, "error": "邮箱格式不正确"}), 400 + + now = datetime.utcnow() + # 提前生成验证码,保证频率检查与写入在同一个 DB 事务中(消除 TOCTOU 竞态) + code = _generate_six_digit_code() + pepper = (current_app.secret_key or "dev-secret-change-in-production")[:64] + code_hash = _hash_registration_code(email, code, pepper) + expires_at = now + timedelta(minutes=settings.registration_code_ttl_minutes) + + with SessionLocal() as db: + # 频率限制与写入在同一 session,防止并发请求绕过限制 + row = crud.get_verification_by_email(db, email) + if row and row.last_sent_at: + delta = (now - row.last_sent_at).total_seconds() + if delta < settings.registration_send_interval_seconds: + wait = int(settings.registration_send_interval_seconds - delta) + return jsonify( + {"success": False, "error": f"发送过于频繁,请 {wait} 秒后再试"} + ), 429 + + user = crud.get_user_by_email(db, email) + # 防邮箱枚举:注册时邮箱已存在、重置时邮箱不存在,均返回相同成功响应但不实际发送 + # 同时写入记录以保证频率限制行为一致,防止通过 429 差异探测邮箱 + if (code_type == "register" and user) or (code_type == "reset" and not user): + crud.upsert_registration_code(db, email, "anti-enum-dummy", now + timedelta(minutes=1), now) + return jsonify({"success": True, "message": "验证码已发送"}) + + crud.upsert_registration_code(db, email, code_hash, expires_at, now) + + subject_text = "找回密码" if code_type == "reset" else "注册" + smtp_ok = bool(settings.smtp_host and settings.smtp_from) + if smtp_ok: + try: + send_smtp_email( + host=settings.smtp_host, + port=settings.smtp_port, + user=settings.smtp_user, + password=settings.smtp_password, + mail_from=settings.smtp_from, + use_tls=settings.smtp_use_tls, + to_addr=email, + subject=f"【智卷系统】{subject_text}验证码", + body=f"您的{subject_text}验证码为:{code},{settings.registration_code_ttl_minutes} 分钟内有效。请勿泄露给他人。", + async_send=True, + ) + except Exception: + logger.exception("发送验证码邮件失败") + return jsonify({"success": False, "error": "邮件发送失败,请稍后重试"}), 502 + else: + if current_app.debug: + logger.warning( + "[开发模式] 未配置 SMTP,验证码(仅调试用) email=%s code=%s", + email, + code, + ) + else: + return jsonify( + {"success": False, "error": "服务器未配置发信,无法发送验证码"} + ), 503 + + return jsonify({"success": True, "message": "验证码已发送"}) + + +@bp.route("/reset-password", methods=["POST"]) +def reset_password(): + """通过邮箱验证码重置密码。 + + 请求体:{ email, code, password } + """ + data = request.get_json() or {} + email = (data.get("email") or "").strip().lower() + code = (data.get("code") or "").strip() + password = data.get("password") or "" + + if not email or "@" not in email: + return jsonify({"success": False, "error": "邮箱格式不正确"}), 400 + if not code or not code.isdigit() or len(code) != 6: + return jsonify({"success": False, "error": "请输入 6 位验证码"}), 400 + if len(password) < 6: + return jsonify({"success": False, "error": "密码至少 6 位"}), 400 + + pepper = (current_app.secret_key or "dev-secret-change-in-production")[:64] + submitted_hash = _hash_registration_code(email, code, pepper) + now = datetime.utcnow() + + with SessionLocal() as db: + user = crud.get_user_by_email(db, email) + if not user: + # 防枚举:与验证码错误返回相同提示 + return jsonify({"success": False, "error": "验证码错误"}), 400 + + row = crud.get_verification_by_email(db, email) + if not row: + return jsonify({"success": False, "error": "请先获取验证码"}), 400 + if row.expires_at < now: + crud.delete_verification_by_email(db, email) + return jsonify({"success": False, "error": "验证码已过期,请重新获取"}), 400 + if (row.attempts or 0) >= settings.registration_max_attempts: + crud.delete_verification_by_email(db, email) + return jsonify({"success": False, "error": "验证失败次数过多,请重新获取验证码"}), 400 + + if not hmac.compare_digest(row.code_hash, submitted_hash): + crud.increment_verification_attempts(db, email) + return jsonify({"success": False, "error": "验证码错误"}), 400 + + if check_password_hash(user.password_hash, password): + return jsonify({"success": False, "error": "新密码不能与原密码相同"}), 400 + + new_hash = generate_password_hash(password) + crud.update_user_password(db, email, new_hash) + crud.delete_verification_by_email(db, email) + + return jsonify({"success": True, "message": "密码重置成功"}) + + +@bp.route("/login", methods=["POST"]) +def auth_login(): + """用户登录(支持邮箱或用户名)""" + data = request.get_json() or {} + identifier = (data.get("email") or data.get("identifier") or "").strip() + password = data.get("password") or "" + + if not identifier: + return jsonify({"error": "请输入邮箱或用户名"}), 400 + + with SessionLocal() as db: + user = crud.get_user_by_login(db, identifier) + if not user or not check_password_hash(user.password_hash, password): + return jsonify({"error": "账号或密码错误"}), 401 + session["user_id"] = user.id + session["username"] = user.username + session["is_admin"] = bool(user.is_admin) + session["session_version"] = user.session_version or 0 + return jsonify( + { + "user": { + "id": user.id, + "email": user.email, + "username": user.username, + "is_admin": user.is_admin, + } + } + ) + + +@bp.route("/logout", methods=["POST"]) +def auth_logout(): + """退出登录""" + session.clear() + return jsonify({"ok": True}) + + +@bp.route("/me", methods=["GET"]) +def auth_me(): + """获取当前登录用户""" + user_id = session.get("user_id") + if not user_id: + return jsonify({"error": "未登录", "code": "UNAUTHORIZED"}), 401 + with SessionLocal() as db: + user = crud.get_user_by_id(db, user_id) + if not user: + session.clear() + return jsonify({"error": "用户不存在", "code": "UNAUTHORIZED"}), 401 + return jsonify( + { + "user": { + "id": user.id, + "email": user.email, + "username": user.username, + "is_admin": user.is_admin, + } + } + ) diff --git a/backend/routes/chat.py b/backend/routes/chat.py new file mode 100644 index 00000000..d7b636c7 --- /dev/null +++ b/backend/routes/chat.py @@ -0,0 +1,303 @@ +"""Chat-related routes (AI conversation with questions).""" + +import json +import logging + +from flask import Blueprint, request, jsonify, session, Response + +from db import SessionLocal +from db import crud +from db.models import Question, ChatSession as ChatSessionModel, QuestionTagMapping +from core.config import settings + +logger = logging.getLogger(__name__) + +bp = Blueprint('chat', __name__) + + +def _effective_user_id(): + """管理员返回 None(不过滤),普通用户返回 user_id""" + if session.get('is_admin'): + return None + return session.get('user_id') + + +def _serialize_chat_session(s) -> dict: + """将 ChatSession ORM 对象序列化为前端 JSON""" + return { + 'id': s.id, + 'title': s.title or '新对话', + 'question_id': s.question_id, + 'created_at': s.created_at.isoformat() if s.created_at else None, + 'updated_at': s.updated_at.isoformat() if s.updated_at else None, + } + + +def _serialize_question(q: Question) -> dict: + """将 Question ORM 对象序列化为前端 JSON 格式""" + subject = None + if q.batch: + subject = q.batch.subject + knowledge_tags = [] + if q.tags: + for mapping in q.tags: + if mapping.tag: + knowledge_tags.append(mapping.tag.tag_name) + + return { + 'id': q.id, + 'question_type': q.question_type, + 'content_json': json.loads(q.content_json) if q.content_json else [], + 'options_json': json.loads(q.options_json) if q.options_json else None, + 'has_formula': q.has_formula, + 'has_image': q.has_image, + 'needs_correction': q.needs_correction, + 'answer': q.answer, + 'subject': subject, + 'knowledge_tags': knowledge_tags, + 'created_at': q.created_at.isoformat() if q.created_at else None, + } + + +@bp.route('/question//chats', methods=['GET']) +def get_question_chats(question_id): + """获取某道题目的所有对话会话""" + try: + with SessionLocal() as db: + sessions = crud.get_chat_sessions_by_question(db, question_id, user_id=_effective_user_id()) + return jsonify({ + 'success': True, + 'sessions': [_serialize_chat_session(s) for s in sessions], + }) + except Exception as e: + logger.exception("获取对话列表失败") + return jsonify({'success': False, 'error': '获取对话列表失败'}), 500 + + +@bp.route('/chat', methods=['POST']) +def create_chat(): + """创建新对话(支持绑定题目或独立对话)""" + try: + data = request.get_json(silent=True) or {} + question_id = data.get('question_id') # 可选 + title = data.get('title', '新对话') + user_id = session.get('user_id') + + if question_id: + with SessionLocal() as db: + uid = _effective_user_id() + q_query = db.query(Question).filter(Question.id == question_id) + if uid is not None: + q_query = q_query.filter(Question.user_id == uid) + question = q_query.first() + if not question: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + chat_session = crud.create_chat_session(db, question_id=question_id, user_id=user_id, title=title) + return jsonify({'success': True, 'session': _serialize_chat_session(chat_session)}) + else: + # 独立对话 + with SessionLocal() as db: + chat_session = crud.create_chat_session(db, user_id=user_id, title=title) + return jsonify({'success': True, 'session': _serialize_chat_session(chat_session)}) + + except Exception as e: + logger.exception("创建对话失败") + return jsonify({'success': False, 'error': '创建对话失败'}), 500 + + +@bp.route('/chat/my-sessions', methods=['GET']) +def get_my_chat_sessions(): + """获取当前用户的独立对话列表""" + try: + user_id = session.get('user_id') + page = max(1, request.args.get('page', 1, type=int)) + page_size = min(50, max(1, request.args.get('limit', 20, type=int))) + + with SessionLocal() as db: + sessions_list, total = crud.get_user_chat_sessions(db, user_id, page=page, page_size=page_size) + return jsonify({ + 'success': True, + 'sessions': [_serialize_chat_session(s) for s in sessions_list], + 'total': total, + }) + except Exception as e: + logger.exception("获取对话列表失败") + return jsonify({'success': False, 'error': '获取对话列表失败'}), 500 + + +@bp.route('/chat/', methods=['PATCH']) +def update_chat_title(session_id): + """更新对话标题""" + try: + data = request.get_json(silent=True) or {} + title = data.get('title', '').strip() + if not title: + return jsonify({'success': False, 'error': '标题不能为空'}), 400 + + with SessionLocal() as db: + s = crud.update_chat_session_title(db, session_id, title, user_id=_effective_user_id()) + if not s: + return jsonify({'success': False, 'error': '对话不存在'}), 404 + return jsonify({'success': True, 'session': _serialize_chat_session(s)}) + except Exception as e: + logger.exception("更新对话标题失败") + return jsonify({'success': False, 'error': '更新失败'}), 500 + + +@bp.route('/chat/', methods=['DELETE']) +def delete_chat(session_id): + """删除对话""" + try: + with SessionLocal() as db: + if not crud.delete_chat_session(db, session_id, user_id=_effective_user_id()): + return jsonify({'success': False, 'error': '对话不存在'}), 404 + return jsonify({'success': True}) + except Exception as e: + logger.exception("删除对话失败") + return jsonify({'success': False, 'error': '删除失败'}), 500 + + +@bp.route('/chat/sessions', methods=['GET']) +def get_chat_sessions(): + """分页获取所有对话会话""" + try: + page = max(1, request.args.get('page', 1, type=int)) + page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) + + with SessionLocal() as db: + sessions, total = crud.get_all_chat_sessions(db, page=page, page_size=page_size, user_id=_effective_user_id()) + total_pages = (total + page_size - 1) // page_size + + return jsonify({ + 'success': True, + 'sessions': [_serialize_chat_session(s) for s in sessions], + 'total': total, + 'page': page, + 'total_pages': total_pages, + }) + + except Exception as e: + logger.exception("获取对话会话列表失败") + return jsonify({'success': False, 'error': '获取对话会话列表失败'}), 500 + + +@bp.route('/chat//messages', methods=['GET']) +def get_chat_messages(session_id): + """游标分页获取对话消息""" + try: + limit = min(100, max(1, request.args.get('limit', 30, type=int))) + before_id = request.args.get('before_id', type=int) + + with SessionLocal() as db: + result = crud.get_chat_messages(db, session_id, limit=limit, before_id=before_id, user_id=_effective_user_id()) + return jsonify({ + 'success': True, + 'messages': result['messages'], + 'hasMore': result['hasMore'], + }) + + except Exception as e: + logger.exception("获取对话消息失败") + return jsonify({'success': False, 'error': '获取对话消息失败'}), 500 + + +@bp.route('/chat//stream', methods=['POST']) +def stream_chat(session_id): + """SSE 流式对话""" + from agents.teach import stream_teach + from sqlalchemy.orm import selectinload + + try: + data = request.get_json(silent=True) or {} + message = data.get('message', '').strip() + model_provider = data.get('model_provider', 'openai') + model_name = data.get('model_name') or None + deep_think = data.get('deep_think', False) + + # 深度思考模式:切换到 reasoner 模型 + if deep_think and model_provider == 'openai': + model_name = 'deepseek-reasoner' + + if not message: + return jsonify({'success': False, 'error': '消息不能为空'}), 400 + + if not settings.is_valid_provider(model_provider): + return jsonify({'success': False, 'error': f'不支持的模型供应商: {model_provider}'}), 400 + + # 从数据库加载用户的 LLM 凭据 + user_id = session.get('user_id') + if user_id: + settings.load_providers_from_db(user_id) + + with SessionLocal() as db: + uid = _effective_user_id() + cs_query = db.query(ChatSessionModel).options( + selectinload(ChatSessionModel.question) + .selectinload(Question.batch), + selectinload(ChatSessionModel.question) + .selectinload(Question.tags) + .selectinload(QuestionTagMapping.tag), + ).filter(ChatSessionModel.id == session_id) + if uid is not None: + cs_query = cs_query.filter(ChatSessionModel.user_id == uid) + chat_session = cs_query.first() + if not chat_session: + return jsonify({'success': False, 'error': '对话不存在'}), 404 + + # 独立对话或题目绑定对话 + question = chat_session.question + q_data = _serialize_question(question) if question else None + + # 加载历史消息(最近 20 条) + history_result = crud.get_chat_messages(db, session_id, limit=20) + history = [{"role": m["role"], "content": m["content"]} for m in history_result["messages"]] + + # 追加用户消息 + history.append({"role": "user", "content": message}) + crud.add_chat_message(db, session_id, "user", message) + + def generate(): + full_response = [] + full_reasoning = [] + try: + for chunk in stream_teach( + question=q_data, + messages=history, + provider=model_provider, + model_name=model_name, + ): + # stream_teach 现在 yield dict: {"type": "reasoning"|"content", "content": "..."} + if isinstance(chunk, dict): + if chunk["type"] == "reasoning": + full_reasoning.append(chunk["content"]) + yield f"data: {json.dumps({'reasoning': chunk['content']}, ensure_ascii=False)}\n\n" + else: + full_response.append(chunk["content"]) + yield f"data: {json.dumps({'token': chunk['content']}, ensure_ascii=False)}\n\n" + else: + # 兼容旧格式(纯字符串) + full_response.append(chunk) + yield f"data: {json.dumps({'token': chunk}, ensure_ascii=False)}\n\n" + except Exception as e: + logger.exception("流式对话错误") + yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n" + + # 保存完整的 assistant 回复(思考过程不保存到消息历史) + assistant_content = "".join(full_response) + if assistant_content: + try: + with SessionLocal() as db: + crud.add_chat_message(db, session_id, "assistant", assistant_content) + except Exception as e: + logger.error(f"保存 assistant 回复失败: {e}") + + yield f"data: {json.dumps({'done': True})}\n\n" + + resp = Response(generate(), mimetype='text/event-stream') + resp.headers['Cache-Control'] = 'no-cache' + resp.headers['X-Accel-Buffering'] = 'no' + return resp + + except Exception as e: + logger.exception("流式对话失败") + return jsonify({'success': False, 'error': '对话失败,请稍后重试'}), 500 diff --git a/backend/routes/notes.py b/backend/routes/notes.py new file mode 100644 index 00000000..cb16d88d --- /dev/null +++ b/backend/routes/notes.py @@ -0,0 +1,250 @@ +""" +笔记模块 API 路由 + +流程:上传笔记图片 → PaddleOCR 识别 → LLM 整理 → 保存到数据库 +""" + +import os +import uuid +import json +import logging +from pathlib import PurePath + +from flask import Blueprint, request, jsonify, session + +from core.config import settings +from db import SessionLocal +from db import crud + +logger = logging.getLogger(__name__) + +bp = Blueprint('notes', __name__) + + +def _effective_user_id(): + """管理员返回 None(不过滤),普通用户返回 user_id""" + if session.get('is_admin'): + return None + return session.get('user_id') + + +def _allowed_image(filename): + """检查是否为允许的图片格式""" + return PurePath(filename).suffix.lower().lstrip('.') in {'png', 'jpg', 'jpeg', 'bmp', 'tiff', 'webp'} + + +def _serialize_note(note) -> dict: + """将 Note ORM 对象序列化为前端 JSON""" + knowledge_tags = [] + if note.tags: + for mapping in note.tags: + if mapping.tag: + knowledge_tags.append(mapping.tag.tag_name) + + return { + 'id': note.id, + 'title': note.title, + 'subject': note.subject, + 'content_markdown': note.content_markdown, + 'source_images': json.loads(note.source_images_json) if note.source_images_json else [], + 'knowledge_tags': knowledge_tags, + 'created_at': note.created_at.isoformat() if note.created_at else None, + 'updated_at': note.updated_at.isoformat() if note.updated_at else None, + } + + +@bp.route('/', methods=['POST']) +def create_note(): + """上传笔记图片 → OCR → LLM 整理 → 保存 + + 请求:multipart/form-data + - files: 一张或多张图片 + - model_provider: 模型供应商(可选,默认 openai) + - model_name: 模型名称(可选) + """ + files = request.files.getlist('files') + if not files or all(f.filename == '' for f in files): + return jsonify({'success': False, 'error': '请上传笔记图片'}), 400 + + # 校验文件格式 + for f in files: + if f.filename and not _allowed_image(f.filename): + return jsonify({'success': False, 'error': f'不支持的图片格式: {f.filename}'}), 400 + + user_id = session.get('user_id') + model_provider = request.form.get('model_provider', 'openai') + model_name = request.form.get('model_name') or None + + try: + # 1. 保存上传图片 + saved_paths = [] + for f in files: + if not f.filename: + continue + ext = os.path.splitext(f.filename)[1].lower() + filename = f"{uuid.uuid4().hex}{ext}" + filepath = os.path.join(str(settings.upload_dir), filename) + f.save(filepath) + saved_paths.append(filepath) + + if not saved_paths: + return jsonify({'success': False, 'error': '没有有效的图片文件'}), 400 + + # 2. OCR 识别 + from src.paddleocr_client import PaddleOCRClient + from src.utils import simplify_ocr_results, run_async + + # 从数据库加载用户 OCR 凭据 + ocr_kwargs = {} + if user_id: + with SessionLocal() as db: + ocr_provider = crud.get_active_provider(db, user_id, 'paddleocr') + if ocr_provider: + ocr_kwargs = { + "api_url": ocr_provider.base_url, + "token": ocr_provider.api_key, + "model": ocr_provider.model_name, + } + + client = PaddleOCRClient(**ocr_kwargs) + raw_results = run_async(client.parse_images_async(saved_paths)) + simplified = simplify_ocr_results(raw_results) + + # 拼接 OCR 文本 + 图片引用 + ocr_text_parts = [] + image_refs = [] + for page in simplified: + for block in page.get('blocks', []): + label = block.get('block_label', '') + content = block.get('block_content', '').strip() + if label in ('image', 'chart') and content: + # 图片块:记录路径,在文本中插入占位符 + image_refs.append(content) + ocr_text_parts.append(f'[图片: {content}]') + elif content: + ocr_text_parts.append(content) + ocr_text = '\n'.join(ocr_text_parts) + + if not ocr_text.strip(): + return jsonify({'success': False, 'error': 'OCR 未识别到任何文字,请检查图片'}), 400 + + # 3. LLM 整理 + if user_id: + settings.load_providers_from_db(user_id) + + from agents.note import invoke_note_organize + result = invoke_note_organize(ocr_text, provider=model_provider, model_name=model_name) + + # 4. 保存到数据库 + with SessionLocal() as db: + note = crud.save_note( + db, + title=result.title, + subject=result.subject, + content_markdown=result.content_markdown, + source_images=saved_paths, + ocr_text=ocr_text, + knowledge_tags=result.knowledge_tags, + user_id=user_id, + ) + return jsonify({ + 'success': True, + 'note': _serialize_note(note), + }), 201 + + except Exception as e: + logger.exception("笔记创建失败") + return jsonify({'success': False, 'error': f'笔记创建失败: {str(e)}'}), 500 + + +@bp.route('/', methods=['GET']) +def list_notes(): + """分页查询笔记列表 + + 查询参数:page, limit, subject, knowledge_tag, keyword + """ + try: + page = max(1, request.args.get('page', 1, type=int)) + limit = min(100, max(1, request.args.get('limit', 20, type=int))) + subject = request.args.get('subject') or None + knowledge_tag = request.args.get('knowledge_tag') or None + keyword = request.args.get('keyword') or None + user_id = session.get('user_id') + + with SessionLocal() as db: + notes, total = crud.get_notes( + db, + user_id=user_id, + subject=subject, + knowledge_tag=knowledge_tag, + keyword=keyword, + page=page, + page_size=limit, + ) + return jsonify({ + 'success': True, + 'items': [_serialize_note(n) for n in notes], + 'total': total, + 'page': page, + 'total_pages': (total + limit - 1) // limit, + }) + + except Exception as e: + logger.exception("获取笔记列表失败") + return jsonify({'success': False, 'error': '获取笔记列表失败'}), 500 + + +@bp.route('/', methods=['GET']) +def get_note(note_id): + """获取单条笔记详情""" + try: + with SessionLocal() as db: + note = crud.get_note_by_id(db, note_id, user_id=_effective_user_id()) + if not note: + return jsonify({'success': False, 'error': '笔记不存在'}), 404 + return jsonify({ + 'success': True, + 'note': _serialize_note(note), + }) + except Exception as e: + logger.exception("获取笔记详情失败") + return jsonify({'success': False, 'error': '获取笔记详情失败'}), 500 + + +@bp.route('/', methods=['PATCH']) +def update_note_route(note_id): + """更新笔记(标题、内容、科目、标签)""" + try: + data = request.get_json(silent=True) or {} + with SessionLocal() as db: + note = crud.update_note( + db, + note_id=note_id, + title=data.get('title'), + content_markdown=data.get('content_markdown'), + subject=data.get('subject'), + knowledge_tags=data.get('knowledge_tags'), + user_id=_effective_user_id(), + ) + if not note: + return jsonify({'success': False, 'error': '笔记不存在'}), 404 + return jsonify({ + 'success': True, + 'note': _serialize_note(note), + }) + except Exception as e: + logger.exception("更新笔记失败") + return jsonify({'success': False, 'error': '更新笔记失败'}), 500 + + +@bp.route('/', methods=['DELETE']) +def delete_note_route(note_id): + """删除笔记""" + try: + with SessionLocal() as db: + if not crud.delete_note(db, note_id, user_id=_effective_user_id()): + return jsonify({'success': False, 'error': '笔记不存在'}), 404 + return jsonify({'success': True}) + except Exception as e: + logger.exception("删除笔记失败") + return jsonify({'success': False, 'error': '删除笔记失败'}), 500 diff --git a/backend/routes/questions.py b/backend/routes/questions.py new file mode 100644 index 00000000..2f0e8ece --- /dev/null +++ b/backend/routes/questions.py @@ -0,0 +1,660 @@ +import os +import json +import logging +from datetime import datetime + +from flask import Blueprint, request, jsonify, session + +from db import SessionLocal +from db import crud +from db.models import Question, UploadBatch, KnowledgeTag +from core.config import settings +from src.utils import export_wrongbook as export_wrongbook_md + +logger = logging.getLogger(__name__) + +bp = Blueprint('questions', __name__) + + +def _effective_user_id(): + """管理员返回 None(不过滤),普通用户返回 user_id""" + if session.get('is_admin'): + return None + return session.get('user_id') + + +def _serialize_question(q: Question) -> dict: + """将 Question ORM 对象序列化为前端 JSON 格式""" + subject = None + if q.batch: + subject = q.batch.subject + knowledge_tags = [] + if q.tags: + for mapping in q.tags: + if mapping.tag: + knowledge_tags.append(mapping.tag.tag_name) + + return { + 'id': q.id, + 'question_type': q.question_type, + 'content_json': json.loads(q.content_json) if q.content_json else [], + 'options_json': json.loads(q.options_json) if q.options_json else None, + 'has_formula': q.has_formula, + 'has_image': q.has_image, + 'needs_correction': q.needs_correction, + 'answer': q.answer, + 'subject': subject, + 'knowledge_tags': knowledge_tags, + 'created_at': q.created_at.isoformat() if q.created_at else None, + } + + +def _serialize_question_detail(q: Question) -> dict: + """将 Question ORM 对象序列化为详情 JSON(含科目、标签、答案等)""" + base = _serialize_question(q) + # subject / knowledge_tags already set by _serialize_question + base['original_filename'] = q.batch.original_filename if q.batch else None + base['user_answer'] = q.user_answer + base['updated_at'] = q.updated_at.isoformat() if q.updated_at else None + base['review_status'] = q.review_status or '待复习' + base['image_refs_json'] = json.loads(q.image_refs_json) if q.image_refs_json else None + return base + + +def _read_split_subject(): + """从 split_metadata.json 读取学科信息""" + meta_path = os.path.join(str(settings.results_dir), "split_metadata.json") + if os.path.exists(meta_path): + with open(meta_path, 'r', encoding='utf-8') as f: + return json.load(f).get("subject") + return None + + +@bp.route('/questions', methods=['GET']) +def get_questions(): + """ + 获取已分割的题目列表 + + Returns: + JSON响应,包含题目列表 + """ + try: + results_dir = settings.results_dir + questions_file = os.path.join(results_dir, "questions.json") + + if not os.path.exists(questions_file): + return jsonify({ + 'success': True, + 'questions': [], + 'message': '暂无题目数据' + }) + + with open(questions_file, 'r', encoding='utf-8') as f: + questions = json.load(f) + + return jsonify({ + 'success': True, + 'questions': questions + }) + + except json.JSONDecodeError: + return jsonify({ + 'success': False, + 'error': '题目数据文件格式错误,请重新分割题目' + }), 500 + except Exception as e: + logger.exception("获取题目列表失败") + return jsonify({ + 'success': False, + 'error': '获取题目列表失败,请稍后重试' + }), 500 + + +@bp.route('/history', methods=['GET']) +def get_history(): + """ + 分页查询历史题目(全部题目,非仅错题) + + Query参数: + page: 页码(默认1) + page_size: 每页数量(默认20) + start_date: 开始日期(可选,格式:YYYY-MM-DD) + end_date: 结束日期(可选,格式:YYYY-MM-DD) + """ + try: + page = max(1, request.args.get('page', 1, type=int)) + page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) + start_date_str = request.args.get('start_date') + end_date_str = request.args.get('end_date') + + # 解析日期 + start_date = None + end_date = None + if start_date_str: + start_date = datetime.strptime(start_date_str, '%Y-%m-%d') + if end_date_str: + end_date = datetime.strptime(end_date_str, '%Y-%m-%d') + + with SessionLocal() as db: + questions, total = crud.get_history_questions( + db, + start_date=start_date, + end_date=end_date, + page=page, + page_size=page_size, + user_id=_effective_user_id(), + ) + + total_pages = (total + page_size - 1) // page_size + items = [_serialize_question(q) for q in questions] + + return jsonify({ + 'success': True, + 'items': items, + 'total': total, + 'page': page, + 'page_size': page_size, + 'total_pages': total_pages + }) + + except ValueError: + return jsonify({'success': False, 'error': '日期格式错误,请使用 YYYY-MM-DD 格式'}), 400 + except Exception as e: + logger.exception("查询历史题目失败") + return jsonify({'success': False, 'error': '查询失败,请稍后重试'}), 500 + + +@bp.route('/search', methods=['GET']) +def search_questions(): + """ + 搜索题目(知识点/题型/关键字) + + Query参数: + keyword: 关键字搜索(匹配题目内容) + knowledge_tag: 知识点标签筛选 + question_type: 题型筛选 + page: 页码(默认1) + page_size: 每页数量(默认20) + """ + try: + page = max(1, request.args.get('page', 1, type=int)) + page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) + keyword = request.args.get('keyword', type=str) + knowledge_tag = request.args.get('knowledge_tag', type=str) + question_type = request.args.get('question_type', type=str) + + # 至少需要一个搜索条件 + if not any([keyword, knowledge_tag, question_type]): + return jsonify({ + 'success': False, + 'error': '至少需要提供一个搜索条件(keyword/knowledge_tag/question_type)' + }), 400 + + with SessionLocal() as db: + questions, total = crud.search_questions( + db, + keyword=keyword if keyword else None, + knowledge_tag=knowledge_tag if knowledge_tag else None, + question_type=question_type if question_type else None, + page=page, + page_size=page_size, + user_id=_effective_user_id(), + ) + + total_pages = (total + page_size - 1) // page_size + items = [_serialize_question(q) for q in questions] + + return jsonify({ + 'success': True, + 'items': items, + 'total': total, + 'page': page, + 'page_size': page_size, + 'total_pages': total_pages + }) + + except Exception as e: + logger.exception("搜索题目失败") + return jsonify({'success': False, 'error': '搜索失败,请稍后重试'}), 500 + + +@bp.route('/question/', methods=['DELETE']) +def delete_question(question_id): + """ + 删除题目 + + Path参数: + question_id: 题目ID + """ + try: + with SessionLocal() as db: + success = crud.delete_question(db, question_id, user_id=_effective_user_id()) + if success: + return jsonify({ + 'success': True, + 'message': '题目已删除' + }) + else: + return jsonify({ + 'success': False, + 'error': '题目不存在' + }), 404 + + except Exception as e: + logger.exception("删除题目失败") + return jsonify({'success': False, 'error': '删除失败,请稍后重试'}), 500 + + +@bp.route('/error-bank', methods=['GET']) +def get_error_bank(): + """ + 错题库统一查询 + + Query参数: + subject: 科目筛选 + knowledge_tag: 知识点标签筛选 + question_type: 题型筛选 + keyword: 关键字搜索 + start_date: 开始日期(YYYY-MM-DD) + end_date: 结束日期(YYYY-MM-DD) + page: 页码(默认1) + page_size: 每页数量(默认20) + """ + try: + page = max(1, request.args.get('page', 1, type=int)) + page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) + subject = request.args.get('subject', type=str) or None + knowledge_tag = request.args.get('knowledge_tag', type=str) or None + question_type = request.args.get('question_type', type=str) or None + keyword = request.args.get('keyword', type=str) or None + review_status = request.args.get('review_status', type=str) or None + start_date_str = request.args.get('start_date') + end_date_str = request.args.get('end_date') + + start_date = None + end_date = None + if start_date_str: + start_date = datetime.strptime(start_date_str, '%Y-%m-%d') + if end_date_str: + end_date = datetime.strptime(end_date_str, '%Y-%m-%d') + + with SessionLocal() as db: + questions, total, grand_total = crud.query_questions( + db, + user_id=_effective_user_id(), + subject=subject, + knowledge_tag=knowledge_tag, + question_type=question_type, + keyword=keyword, + start_date=start_date, + end_date=end_date, + review_status=review_status, + page=page, + page_size=page_size, + ) + + total_pages = (total + page_size - 1) // page_size + items = [_serialize_question_detail(q) for q in questions] + + return jsonify({ + 'success': True, + 'items': items, + 'total': total, + 'grand_total': grand_total, + 'page': page, + 'page_size': page_size, + 'total_pages': total_pages, + }) + + except ValueError: + return jsonify({'success': False, 'error': '日期格式错误,请使用 YYYY-MM-DD 格式'}), 400 + except Exception as e: + logger.exception("查询错题库失败") + return jsonify({'success': False, 'error': '查询失败,请稍后重试'}), 500 + + +@bp.route('/subjects', methods=['GET']) +def get_subjects(): + """获取所有科目列表""" + try: + with SessionLocal() as db: + subjects = crud.get_existing_subjects(db, user_id=_effective_user_id()) + return jsonify({'success': True, 'subjects': subjects}) + except Exception as e: + logger.exception("获取科目列表失败") + return jsonify({'success': False, 'error': '获取科目列表失败'}), 500 + + +@bp.route('/question-types', methods=['GET']) +def get_question_types(): + """获取所有题型列表""" + try: + with SessionLocal() as db: + types = crud.get_existing_question_types(db, user_id=_effective_user_id()) + return jsonify({'success': True, 'question_types': types}) + except Exception as e: + logger.exception("获取题型列表失败") + return jsonify({'success': False, 'error': '获取题型列表失败'}), 500 + + +@bp.route('/question/', methods=['PATCH']) +def update_question(question_id): + """编辑题目内容和/或答案""" + try: + data = request.get_json(silent=True) or {} + with SessionLocal() as db: + question = db.get(Question, question_id) + if not question: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + uid = _effective_user_id() + if uid is not None and question.user_id != uid: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + try: + if 'content' in data: + text = str(data['content'])[:20000] + blocks = [{'block_type': 'text', 'content': text}] + question.content_json = json.dumps(blocks, ensure_ascii=False) + question.content_hash = crud.compute_content_hash(blocks) + if 'answer' in data: + question.answer = str(data['answer'])[:10000] if data['answer'] else None + question.updated_at = datetime.utcnow() + db.commit() + return jsonify({'success': True}) + except Exception: + db.rollback() + raise + except Exception: + logger.exception("编辑题目失败") + return jsonify({'success': False, 'error': '保存失败,请稍后重试'}), 500 + + +@bp.route('/question//answer', methods=['PATCH']) +def update_question_answer(question_id): + """保存用户答案""" + try: + data = request.get_json(silent=True) or {} + user_answer = data.get('user_answer') + if user_answer is None: + return jsonify({'success': False, 'error': '缺少 user_answer 字段'}), 400 + if len(user_answer) > 10000: + return jsonify({'success': False, 'error': '答案内容过长(最多 10000 字符)'}), 400 + + with SessionLocal() as db: + question = crud.update_user_answer(db, question_id, user_answer, user_id=_effective_user_id()) + if not question: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + + return jsonify({ + 'success': True, + 'message': '答案已保存', + 'user_answer': question.user_answer, + 'updated_at': question.updated_at.isoformat() if question.updated_at else None, + }) + + except Exception as e: + logger.exception("保存答案失败") + return jsonify({'success': False, 'error': '保存答案失败,请稍后重试'}), 500 + + +@bp.route('/question//review-status', methods=['PATCH']) +def update_question_review_status(question_id): + """更新题目复习状态""" + try: + data = request.get_json(silent=True) or {} + review_status = data.get('review_status') + if not review_status: + return jsonify({'success': False, 'error': '缺少 review_status 字段'}), 400 + + with SessionLocal() as db: + question = crud.update_review_status(db, question_id, review_status, user_id=_effective_user_id()) + if not question: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + + return jsonify({ + 'success': True, + 'message': '复习状态已更新', + 'review_status': question.review_status, + 'updated_at': question.updated_at.isoformat() if question.updated_at else None, + }) + + except ValueError: + return jsonify({'success': False, 'error': f'无效的复习状态,可选值: {", ".join(crud.VALID_REVIEW_STATUSES)}'}), 400 + except Exception as e: + logger.exception("更新复习状态失败") + return jsonify({'success': False, 'error': '更新复习状态失败,请稍后重试'}), 500 + + +@bp.route('/save-to-db', methods=['POST']) +def save_to_db(): + """ + 将分割好的题目导入错题库(仅入库,不导出 Markdown) + + Request Body: + { + "selected_ids": ["q_0", "q_1", ...] # 选中的题目 ID 列表 + } + """ + try: + data = request.get_json(silent=True) or {} + selected_uids = data.get('selected_ids', []) + + if not isinstance(selected_uids, list) or not selected_uids: + return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 + + results_dir = settings.results_dir + questions_file = os.path.join(results_dir, "questions.json") + if not os.path.exists(questions_file): + return jsonify({'success': False, 'error': '请先分割题目'}), 400 + + with open(questions_file, 'r', encoding='utf-8') as f: + questions = json.load(f) + + uid_set = set(selected_uids) + selected_questions = [q for q in questions if q.get('uid') in uid_set] + if not selected_questions: + return jsonify({'success': False, 'error': '未找到选中的题目'}), 400 + + # 合并前端传来的 answer/user_answer(按 uid 匹配) + answers_map = {a['uid']: a for a in data.get('answers', []) if 'uid' in a} + for sq in selected_questions: + uid = sq.get('uid') + if uid and uid in answers_map: + if 'answer' in answers_map[uid]: + sq['answer'] = answers_map[uid]['answer'] + if 'user_answer' in answers_map[uid]: + sq['user_answer'] = answers_map[uid]['user_answer'] + + # 读取科目信息 + subject = _read_split_subject() + + from core.state import session_lock, get_user_session + uid = session.get('user_id') + with session_lock: + us = get_user_session(uid) + batch_info = { + "original_filename": ", ".join( + us["session_files"].get(k, {}).get("filename", "未知") + for k in us["session_file_order"] + ), + "subject": subject, + "file_path": "", + } + + with SessionLocal() as db: + result = crud.save_questions_to_db(db, selected_questions, batch_info, user_id=session.get('user_id')) + + return jsonify({ + 'success': True, + 'message': f'已导入 {result["created"]} 道题目(跳过 {result["duplicates"]} 道重复)', + 'created': result['created'], + 'duplicates': result['duplicates'], + }) + + except Exception as e: + logger.exception("导入错题库失败") + return jsonify({'success': False, 'error': '导入错题库失败,请稍后重试'}), 500 + + +@bp.route('/ai-analysis', methods=['POST']) +def ai_analysis(): + """ + AI 错题分析(骨架路由) + + 接收一组题目 ID,调用 AI 对这些错题进行综合分析,返回: + - 薄弱知识点诊断 + - 错因归纳 + - 针对性复习建议 + + Request Body: + { + "question_ids": [1, 2, 3] # 必填,至少 1 道,最多 20 道 + } + + Response: + { + "success": true, + "analysis": { + "summary": "综合诊断摘要", + "weak_points": ["知识点A", "知识点B"], + "error_patterns": [ + {"pattern": "错因类型", "description": "详细描述", "question_ids": [1, 2]} + ], + "suggestions": ["建议1", "建议2"], + "per_question": [ + {"question_id": 1, "diagnosis": "该题错因分析", "hint": "解题提示"} + ] + } + } + + TODO(后端开发者): + 1. 从数据库查询题目详情(content_json, options_json, user_answer, knowledge_tags) + 2. 构建 prompt,将题目内容 + 用户答案 + 知识点标签传给 LLM + 3. 调用 LLM(建议使用 llm.py 中的 init_model,支持 openai/anthropic) + 4. 解析 LLM 返回的结构化结果,填充 analysis 字段 + 5. 可选:将分析结果缓存到数据库,避免重复分析 + """ + try: + data = request.get_json(silent=True) or {} + question_ids = data.get('question_ids', []) + + if not isinstance(question_ids, list) or not question_ids: + return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 + + if len(question_ids) > 20: + return jsonify({'success': False, 'error': '单次最多分析 20 道题目'}), 400 + + with SessionLocal() as db: + questions = crud.get_questions_by_ids(db, question_ids, user_id=_effective_user_id()) + if not questions: + return jsonify({'success': False, 'error': '未找到对应题目'}), 404 + + # ── TODO: 替换为真实 AI 分析逻辑 ────────────────── + # 当前返回占位数据,供前端联调使用 + knowledge_tags = set() + per_question = [] + for q in questions: + tags = [m.tag.tag_name for m in (q.tags or []) if m.tag] + knowledge_tags.update(tags) + per_question.append({ + 'question_id': q.id, + 'diagnosis': f'题目 #{q.id} 的错因分析(待 AI 生成)', + 'hint': f'题目 #{q.id} 的解题提示(待 AI 生成)', + }) + + analysis = { + 'summary': f'已选择 {len(questions)} 道题目进行分析(AI 分析功能待接入)', + 'weak_points': list(knowledge_tags) or ['暂无知识点数据'], + 'error_patterns': [ + { + 'pattern': '待 AI 识别', + 'description': '错因模式将由 AI 自动归纳', + 'question_ids': [q.id for q in questions], + } + ], + 'suggestions': [ + '建议回顾相关知识点章节', + '建议针对薄弱环节进行专项练习', + ], + 'per_question': per_question, + } + # ── END TODO ────────────────────────────────────── + + return jsonify({ + 'success': True, + 'analysis': analysis, + }) + + except Exception as e: + logger.exception("AI 分析失败") + return jsonify({'success': False, 'error': 'AI 分析失败,请稍后重试'}), 500 + + +@bp.route('/export-from-db', methods=['POST']) +def export_from_db(): + """从数据库按 ID 列表导出 Markdown 错题本""" + try: + data = request.get_json(silent=True) or {} + selected_ids = data.get('selected_ids', []) + + if not isinstance(selected_ids, list) or not selected_ids: + return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 + + with SessionLocal() as db: + questions_orm = crud.get_questions_by_ids(db, selected_ids, user_id=_effective_user_id()) + if not questions_orm: + return jsonify({'success': False, 'error': '未找到对应题目'}), 404 + + # 转换为 export_wrongbook_md 所需的 dict 格式 + questions = [] + for q in questions_orm: + questions.append({ + 'question_id': str(q.id), + 'question_type': q.question_type, + 'content_blocks': json.loads(q.content_json) if q.content_json else [], + 'options': json.loads(q.options_json) if q.options_json else None, + 'has_formula': q.has_formula, + 'has_image': q.has_image, + 'knowledge_tags': [m.tag.tag_name for m in (q.tags or []) if m.tag], + }) + + # DB 导出的题目已按 selected_ids 过滤完毕,赋顺序 uid 后全部导出 + for i, q in enumerate(questions): + q['uid'] = str(i) + output_path = export_wrongbook_md(questions, [str(i) for i in range(len(questions))]) + + return jsonify({ + 'success': True, + 'message': '错题本导出成功', + 'output_path': output_path, + }) + + except Exception as e: + logger.exception("从数据库导出失败") + return jsonify({'success': False, 'error': '导出失败,请稍后重试'}), 500 + + +@bp.route('/question//answer', methods=['PUT']) +def save_question_answer(question_id): + """保存题目答案(Markdown 格式,用于 AI 辅导)""" + try: + data = request.get_json(silent=True) or {} + answer = data.get('answer') + if answer is None: + return jsonify({'success': False, 'error': '缺少 answer 字段'}), 400 + if len(answer) > 50000: + return jsonify({'success': False, 'error': '答案内容过长(最多 50000 字符)'}), 400 + + with SessionLocal() as db: + question = crud.update_question_answer(db, question_id, answer, user_id=_effective_user_id()) + if not question: + return jsonify({'success': False, 'error': '题目不存在'}), 404 + + return jsonify({ + 'success': True, + 'message': '答案已保存', + 'answer': question.answer, + }) + + except Exception as e: + logger.exception("保存答案失败") + return jsonify({'success': False, 'error': '保存答案失败,请稍后重试'}), 500 diff --git a/backend/routes/settings.py b/backend/routes/settings.py new file mode 100644 index 00000000..163a9efd --- /dev/null +++ b/backend/routes/settings.py @@ -0,0 +1,310 @@ +import os +import json +import uuid +import logging + +import requests as http_requests +from flask import Blueprint, request, jsonify, session + +from core.config import settings +from db import SessionLocal +from db import crud +from db.models import ProviderConfig + +logger = logging.getLogger(__name__) + +bp = Blueprint('settings', __name__) + + +@bp.route('/models/erase', methods=['POST']) +def erase_text(): + """文字擦除接口 + + 使用 GAN 模型将试卷图片中的手写笔迹擦除,还原干净的题目底图。 + + Request: + multipart/form-data,字段 file:图片文件(JPEG/PNG/BMP 等) + + Response: + {"success": true, "result_url": "/erased/"} + """ + if 'file' not in request.files: + return jsonify({'success': False, 'error': '缺少 file 字段'}), 400 + + file = request.files['file'] + if not file or not file.filename: + return jsonify({'success': False, 'error': '文件为空'}), 400 + + ext = os.path.splitext(file.filename)[1].lower() or '.png' + allowed = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'} + if ext not in allowed: + return jsonify({'success': False, 'error': f'不支持的图片格式: {ext}'}), 400 + + try: + image_bytes = file.read() + except Exception: + return jsonify({'success': False, 'error': '读取文件失败'}), 400 + + try: + from models.inference import InferenceEngine + + result_img = InferenceEngine().run(image_bytes) + + filename = uuid.uuid4().hex + '.png' + save_path = settings.erased_dir / filename + result_img.save(save_path, format='PNG') + + return jsonify({'success': True, 'result_url': f'/erased/{filename}'}) + + except FileNotFoundError as e: + logger.error("模型权重缺失: %s", e) + return jsonify({'success': False, 'error': str(e)}), 503 + except Exception: + logger.exception("文字擦除失败") + return jsonify({'success': False, 'error': '擦除处理失败,请稍后重试'}), 500 + + +@bp.route('/status', methods=['GET']) +def get_status(): + """ + 获取系统状态 + + Returns: + JSON响应,包含系统配置和状态 + """ + try: + user_id = session.get('user_id') + + # 检查 EnsExam 模型权重是否存在 + ensexam_configured = settings.model_path.exists() + + if user_id: + # 已登录:从数据库读取用户配置 + with SessionLocal() as db: + paddle_provider = crud.get_active_provider(db, user_id, 'paddleocr') + paddleocr_configured = bool(paddle_provider and paddle_provider.api_key and paddle_provider.base_url) + + # 构建用户级可用模型列表 + available_models = [] + for category, label in [('openai', 'OpenAI'), ('anthropic', 'Anthropic')]: + provider = crud.get_active_provider(db, user_id, category) + if provider and provider.api_key: + available_models.append({ + 'value': category, + 'label': provider.name or label, + 'configured': True, + 'status': '配置成功', + 'default_model': provider.model_name or '', + 'models': [provider.model_name] if provider.model_name else [], + }) + else: + available_models.append({ + 'value': category, + 'label': label, + 'configured': False, + 'status': '未配置', + 'default_model': '', + 'models': [], + }) + else: + # 未登录:返回空状态 + paddleocr_configured = False + available_models = [] + + status = { + 'paddleocr_configured': paddleocr_configured, + 'ensexam_configured': ensexam_configured, + 'available_models': available_models, + 'langsmith_enabled': os.getenv('LANGSMITH_TRACING', 'false').lower() == 'true', + 'output_dirs': { + 'pages': str(settings.pages_dir), + 'struct': str(settings.struct_dir), + 'results': str(settings.results_dir), + } + } + + return jsonify({ + 'success': True, + 'status': status + }) + + except Exception as e: + logger.exception("获取系统状态失败") + return jsonify({ + 'success': False, + 'error': '获取系统状态失败,请稍后重试' + }), 500 + + +@bp.route('/config', methods=['GET']) +def get_config(): + """获取当前用户的 provider 配置""" + try: + user_id = session.get('user_id') + if not user_id: + return jsonify({'success': False, 'error': '请先登录'}), 401 + with SessionLocal() as db: + config = crud.get_user_providers(db, user_id) + return jsonify({'success': True, 'config': config}) + except Exception as e: + logger.exception("获取配置失败") + return jsonify({'success': False, 'error': '获取配置失败'}), 500 + + +@bp.route('/config', methods=['PUT']) +def update_config(): + """保存当前用户的 provider 配置到数据库""" + try: + data = request.get_json(force=True) or {} + user_id = session.get('user_id') + + if not user_id: + return jsonify({'success': False, 'error': '请先登录'}), 401 + + with SessionLocal() as db: + try: + crud.save_user_providers(db, user_id, data) + except Exception: + db.rollback() + raise + return jsonify({'success': True}) + + except Exception as e: + logger.exception("更新配置失败") + return jsonify({'success': False, 'error': '更新配置失败,请检查日志'}), 500 + + +@bp.route('/models/list', methods=['POST']) +def list_models(): + """代理请求目标 API 的模型列表,绕过浏览器 CORS 限制。 + + 请求体: + type: 'openai' | 'anthropic' + api_key: API Key(可选,留空则使用系统已配置的 key) + base_url: Base URL(可选) + provider_id: 已有 provider 的 id(可选,用于回退读取已存 key) + """ + try: + data = request.get_json(force=True) or {} + provider_type = data.get('type', 'openai') + api_key = data.get('api_key') or '' + base_url = data.get('base_url') or '' + + # 如果前端没传 key,从数据库读取已保存的配置 + if not api_key: + user_id = session.get('user_id') + provider_id = data.get('provider_id') + if user_id: + with SessionLocal() as db: + if provider_id: + provider = db.query(ProviderConfig).filter_by( + id=provider_id, user_id=user_id + ).first() + else: + provider = crud.get_active_provider(db, user_id, provider_type) + if provider: + if not api_key: + api_key = provider.api_key or '' + if not base_url: + base_url = provider.base_url or '' + + if not api_key: + return jsonify({'error': '未提供 API Key,请先在设置中配置'}), 400 + + if provider_type == 'openai': + url = (base_url.rstrip('/') if base_url else 'https://api.openai.com') + '/v1/models' + headers = {'Authorization': f'Bearer {api_key}'} + resp = http_requests.get(url, headers=headers, timeout=15) + + # 部分 OpenAI 兼容 API 的路径可能不带 /v1 + if resp.status_code == 404: + url_alt = (base_url.rstrip('/') if base_url else 'https://api.openai.com') + '/models' + resp = http_requests.get(url_alt, headers=headers, timeout=15) + + if resp.status_code != 200: + return jsonify({'error': f'API 返回 {resp.status_code}: {resp.text[:200]}'}), 502 + + body = resp.json() + models = sorted([m['id'] for m in body.get('data', [])]) if 'data' in body else [] + return jsonify({'models': models}) + + elif provider_type == 'anthropic': + # Anthropic 没有官方 list models 接口,返回常用模型列表 + models = [ + 'claude-opus-4-20250514', + 'claude-sonnet-4-20250514', + 'claude-haiku-4-20250506', + 'claude-3-5-sonnet-20241022', + 'claude-3-5-haiku-20241022', + 'claude-3-opus-20240229', + ] + return jsonify({'models': models}) + + else: + return jsonify({'error': f'不支持的 provider 类型: {provider_type}'}), 400 + + except http_requests.Timeout: + return jsonify({'error': '请求超时,请检查 Base URL 是否正确'}), 504 + except http_requests.ConnectionError: + return jsonify({'error': '无法连接目标 API,请检查 Base URL'}), 502 + except Exception as e: + logger.exception("获取模型列表失败") + return jsonify({'error': str(e)}), 500 + + +@bp.route('/paddleocr/test', methods=['POST']) +def test_paddleocr(): + """测试 PaddleOCR API Token 是否可用。 + + 请求体: + api_token: API Token(可选,留空则从数据库读取) + api_url: API URL(可选,留空则从数据库读取) + provider_id: 已有 provider 的 id(可选,用于回退读取已存 token) + """ + try: + data = request.get_json(force=True) or {} + api_token = data.get('api_token') or '' + api_url = data.get('api_url') or '' + + # 前端未提供凭据时,从数据库读取已保存的配置 + if not api_token or not api_url: + user_id = session.get('user_id') + provider_id = data.get('provider_id') + if user_id: + with SessionLocal() as db: + if provider_id: + provider = db.query(ProviderConfig).filter_by( + id=provider_id, user_id=user_id + ).first() + else: + provider = crud.get_active_provider(db, user_id, 'paddleocr') + if provider: + if not api_token: + api_token = provider.api_key or '' + if not api_url: + api_url = provider.base_url or '' + + if not api_token or not api_url: + return jsonify({'error': '未提供 API Token 或 API URL'}), 400 + + # 用 GET 请求 API URL,带 token 验证认证是否有效 + headers = {'Authorization': f'bearer {api_token}'} + resp = http_requests.get(api_url, headers=headers, timeout=10) + + # 401/403 表示 token 无效 + if resp.status_code in (401, 403): + return jsonify({'success': False, 'error': '认证失败,请检查 API Token 是否正确'}) + + # 其他非 5xx 状态码都认为 token 有效(包括 404/405 等,因为 GET 可能不被支持但认证通过了) + if resp.status_code >= 500: + return jsonify({'success': False, 'error': f'服务端错误 ({resp.status_code}),请检查 API URL'}) + + return jsonify({'success': True, 'message': 'API Token 验证通过'}) + + except http_requests.Timeout: + return jsonify({'success': False, 'error': '请求超时,请检查 API URL 是否正确'}), 504 + except http_requests.ConnectionError: + return jsonify({'success': False, 'error': '无法连接,请检查 API URL'}), 502 + except Exception as e: + logger.exception("测试 PaddleOCR 连接失败") + return jsonify({'success': False, 'error': str(e)}), 500 diff --git a/backend/routes/stats.py b/backend/routes/stats.py new file mode 100644 index 00000000..b74f5f7c --- /dev/null +++ b/backend/routes/stats.py @@ -0,0 +1,79 @@ +import logging + +from flask import Blueprint, request, jsonify, session + +from db import SessionLocal +from db import crud + +logger = logging.getLogger(__name__) + +bp = Blueprint('stats', __name__) + + +@bp.route('/stats', methods=['GET']) +def get_stats(): + """ + 获取知识点统计信息 + """ + try: + subject = request.args.get('subject', type=str) or None + with SessionLocal() as db: + stats = crud.get_knowledge_stats(db, subject=subject, user_id=session.get('user_id')) + return jsonify({ + 'success': True, + 'stats': stats, + 'total_tags': len(stats) + }) + + except Exception as e: + logger.exception("获取统计失败") + return jsonify({'success': False, 'error': '获取统计失败,请稍后重试'}), 500 + + +@bp.route('/dashboard-stats', methods=['GET']) +def get_dashboard_stats(): + """获取 Dashboard 所需的完整统计数据,支持 ?subject= 学科筛选""" + try: + subject = request.args.get('subject') or None + uid = session.get('user_id') + with SessionLocal() as db: + # 可用学科列表(按当前用户隔离) + subjects = crud.get_existing_subjects(db, user_id=uid) + + # 复习状态统计 + review_stats = crud.get_review_status_stats(db, subject=subject, user_id=uid) + + # 总体统计 + statistics = crud.get_statistics(db, subject=subject, user_id=uid) + + # 知识点标签统计 top 10(横向条形图) + tag_stats = crud.get_knowledge_stats(db, subject=subject, limit=10, user_id=uid) + + # 知识点 × 掌握状态(堆叠柱状图) + tag_status_stats = crud.get_tag_status_stats(db, subject=subject, limit=10, user_id=uid) + + # 知识点 × 题型(热力图) + tag_type_stats = crud.get_tag_type_stats(db, subject=subject, tag_limit=8, user_id=uid) + + # 今日掌握数 + today_mastered = crud.get_today_mastered_count(db, subject=subject, user_id=uid) + + # 最近30天每日新增 + 已掌握趋势 + daily_counts = crud.get_daily_counts(db, days=30, subject=subject, user_id=uid) + + return jsonify({ + 'success': True, + 'subjects': subjects, + 'review_stats': review_stats, + 'today_mastered': today_mastered, + 'total_questions': statistics['total_questions'], + 'by_subject': statistics['by_subject'], + 'tag_stats': tag_stats, + 'tag_status_stats': tag_status_stats, + 'tag_type_stats': tag_type_stats, + 'daily_counts': daily_counts, + }) + + except Exception as e: + logger.exception("获取 Dashboard 统计失败") + return jsonify({'success': False, 'error': '获取统计失败,请稍后重试'}), 500 diff --git a/backend/routes/upload.py b/backend/routes/upload.py new file mode 100644 index 00000000..357a94d5 --- /dev/null +++ b/backend/routes/upload.py @@ -0,0 +1,648 @@ +import os +import json +import uuid +import logging +from pathlib import PurePath +from typing import Optional + +from flask import Blueprint, request, jsonify, session + +import core.state as state +from core.state import ( + workflow_graph, + session_lock, + get_user_session, +) +from db import SessionLocal +from db import crud +from core.config import settings +from src.utils import export_wrongbook as export_wrongbook_md + +logger = logging.getLogger(__name__) + +bp = Blueprint('upload', __name__) + + +# --------------------------------------------------------------------------- +# Helper functions +# --------------------------------------------------------------------------- + +def allowed_file(filename): + """检查文件扩展名是否允许""" + return PurePath(filename).suffix.lower().lstrip('.') in settings.allowed_extensions + + +def _read_split_subject() -> Optional[str]: + """从 split_metadata.json 读取学科信息""" + meta_path = os.path.join(str(settings.results_dir), "split_metadata.json") + if os.path.exists(meta_path): + with open(meta_path, 'r', encoding='utf-8') as f: + return json.load(f).get("subject") + return None + + +def _serialize_split_record(r) -> dict: + """将 SplitRecord ORM 对象序列化为前端 JSON 格式""" + return { + "id": r.id, + "subject": r.subject, + "model_provider": r.model_provider, + "file_names": json.loads(r.file_names_json) if r.file_names_json else [], + "question_count": r.question_count, + "created_at": r.created_at.isoformat() if r.created_at else None, + } + + +# --------------------------------------------------------------------------- +# Routes +# --------------------------------------------------------------------------- + +@bp.route('/upload', methods=['POST']) +def upload_file(): + """处理文件上传(支持多文件)。 + + 这里只负责把原始文件保存到 uploads 并登记到会话中; + 标准化(PDF/图片 → 图片列表) + OCR + 分割,会在 /api/split 里由用户点击"开始分割"后统一触发。 + + Returns: + JSON响应,包含上传结果 + """ + # 支持多文件:前端用 'files' 字段发送,兼容单文件 'file' 字段 + files = request.files.getlist('files') + if not files: + files = request.files.getlist('file') + if not files or all(f.filename == '' for f in files): + return jsonify({'error': '没有上传文件'}), 400 + + # 校验每个文件 + for file in files: + if file.filename == '': + continue + + if not allowed_file(file.filename): + return jsonify({ + 'error': f'不支持的文件格式: {file.filename}。支持: {", ".join(settings.allowed_extensions)}' + }), 400 + + file.seek(0, 2) + file_size = file.tell() + file.seek(0) + file_size_mb = file_size / (1024 * 1024) + + if file_size_mb > settings.max_file_size_mb: + return jsonify({ + 'error': f'{file.filename} 大小为 {file_size_mb:.1f}MB,超出最大限制 {settings.max_file_size_mb}MB' + }), 400 + + if file_size == 0: + return jsonify({ + 'error': f'{file.filename} 为空文件,请重新选择' + }), 400 + + try: + file_keys = request.form.getlist('file_key') + if not file_keys: + file_keys = request.form.getlist('file_keys') + + prepared = [] + for i, file in enumerate(files): + if file.filename == '': + continue + fk = file_keys[i] if i < len(file_keys) and file_keys[i] else None + prepared.append((fk, file)) + + if not prepared: + return jsonify({'error': '没有上传文件'}), 400 + + results_out = [] + uid = session.get('user_id') + for fk, file in prepared: + file_key = fk or f"{uuid.uuid4().hex}" + + original_ext = os.path.splitext(file.filename)[1].lower().lstrip('.') + filename = f"{uuid.uuid4().hex}.{original_ext}" + filepath = os.path.join(str(settings.upload_dir), filename) + file.save(filepath) + + with session_lock: + us = get_user_session(uid) + cancelled = file_key in us["cancelled_file_keys"] + if cancelled: + us["cancelled_file_keys"].discard(file_key) + + if cancelled: + try: + os.remove(filepath) + except FileNotFoundError: + pass + continue + + with session_lock: + us = get_user_session(uid) + if us["current_thread_id"] is not None: + us["current_thread_id"] = None + us["session_files"].clear() + us["session_file_order"].clear() + + us["session_files"][file_key] = { + "filename": file.filename, + "filepath": filepath, + } + if file_key not in us["session_file_order"]: + us["session_file_order"].append(file_key) + + results_out.append({ + "file_key": file_key, + "filename": file.filename, + }) + + return jsonify({ + 'success': True, + 'message': '上传成功', + 'result': { + 'file_count': len(results_out), + 'files': results_out, + } + }) + + except FileNotFoundError: + return jsonify({ + 'success': False, + 'error': '文件保存失败,请重新上传' + }), 500 + except Exception as e: + logger.exception("文件处理失败") + return jsonify({ + 'success': False, + 'error': '文件处理失败,请稍后重试' + }), 500 + + +@bp.route('/cancel_file', methods=['POST']) +def cancel_file(): + try: + data = request.get_json(silent=True) or {} + file_key = data.get('file_key') + if not file_key: + return jsonify({ + 'success': False, + 'error': '缺少 file_key' + }), 400 + + uid = session.get('user_id') + with session_lock: + us = get_user_session(uid) + if us["current_thread_id"] is not None: + return jsonify({ + 'success': False, + 'error': '已开始分割,无法撤销单个文件;请重置后重新上传' + }), 400 + + filepath = None + existed = False + with session_lock: + us = get_user_session(uid) + us["cancelled_file_keys"].add(file_key) + + existed = file_key in us["session_files"] + v = us["session_files"].pop(file_key, None) or {} + filepath = v.get('filepath') + if file_key in us["session_file_order"]: + us["session_file_order"].remove(file_key) + + us["cancelled_file_keys"].discard(file_key) + + if filepath: + try: + os.remove(filepath) + except FileNotFoundError: + pass + + return jsonify({ + 'success': True, + 'message': '已撤销该文件' if existed else '已标记撤销该文件', + }) + + except Exception as e: + logger.exception("撤销文件失败") + return jsonify({ + 'success': False, + 'error': '撤销失败,请稍后重试' + }), 500 + + +@bp.route('/erase', methods=['POST']) +def run_erase(): + """擦除手写笔迹,返回擦除后的图片 URL。 + + 擦除后的文件路径保存在会话状态中,供后续 /api/ocr 使用。 + """ + try: + uid = session.get('user_id') + with session_lock: + us = get_user_session(uid) + keys = list(us["session_file_order"]) + file_paths = [] + for k in keys: + v = us["session_files"].get(k) or {} + fp = v.get('filepath') + if fp: + file_paths.append(fp) + + if not file_paths: + return jsonify({'success': False, 'error': '请先上传文件'}), 400 + + ensexam_configured = settings.model_path.exists() + if not ensexam_configured: + return jsonify({'success': False, 'error': 'EnsExam 模型未配置'}), 400 + + from models.inference import InferenceEngine + engine = InferenceEngine() + erased_paths = [] + for fp in file_paths: + with open(fp, 'rb') as f: + img_bytes = f.read() + result_img = engine.run(img_bytes) + erased_name = f"auto_{uuid.uuid4().hex[:8]}_{os.path.splitext(os.path.basename(fp))[0]}.png" + erased_path = settings.erased_dir / erased_name + result_img.save(str(erased_path), format='PNG') + erased_paths.append(str(erased_path)) + + # 保存擦除后的路径到会话,供 /api/ocr 复用 + with session_lock: + us = get_user_session(uid) + us["erased_file_paths"] = erased_paths + + preview = [] + for i, (orig, erased) in enumerate(zip(file_paths, erased_paths)): + preview.append({ + "index": i, + "original_url": f"/api/image/{os.path.basename(orig)}", + "erased_url": f"/api/image/{os.path.basename(erased)}", + }) + + return jsonify({ + 'success': True, + 'message': f'擦除完成,共 {len(erased_paths)} 张图片', + 'images': preview, + }) + + except Exception: + logger.exception("擦除手写笔迹失败") + return jsonify({'success': False, 'error': '擦除失败,请稍后重试'}), 500 + + +@bp.route('/ocr', methods=['POST']) +def run_ocr(): + """只执行 OCR,返回识别结果供用户预览。 + + 流程:标准化输入 → OCR 解析 → 返回结构化文本 + 不触发 Agent 分割。 + 如果之前调用过 /api/erase,则使用擦除后的图片。 + """ + try: + # 加载 OCR 凭据 + user_id = session.get('user_id') + ocr_credentials = {} + if user_id: + with SessionLocal() as db: + ocr_provider = crud.get_active_provider(db, user_id, 'paddleocr') + if ocr_provider: + ocr_credentials = { + "api_url": ocr_provider.base_url, + "token": ocr_provider.api_key, + "model": ocr_provider.model_name, + "use_doc_orientation": ocr_provider.use_doc_orientation, + "use_doc_unwarping": ocr_provider.use_doc_unwarping, + "use_chart_recognition": ocr_provider.use_chart_recognition, + } + + # 优先使用擦除后的路径 + file_paths = None + with session_lock: + us = get_user_session(user_id) + if us["erased_file_paths"]: + file_paths = list(us["erased_file_paths"]) + us["erased_file_paths"] = None # 用完即清 + + if not file_paths: + with session_lock: + us = get_user_session(user_id) + keys = list(us["session_file_order"]) + file_paths = [] + for k in keys: + v = us["session_files"].get(k) or {} + fp = v.get('filepath') + if fp: + file_paths.append(fp) + + if not file_paths: + return jsonify({'success': False, 'error': '请先上传文件'}), 400 + + # 标准化输入(PDF → 图片) + from src.utils import prepare_input + all_image_paths = [] + for fp in file_paths: + all_image_paths.extend(prepare_input(fp)) + + # 执行 OCR(获取原始结果用于预览 bbox,简化结果用于后续分割) + from src.paddleocr_client import PaddleOCRClient + from src.utils import simplify_ocr_results + from src.workflow import run_async + + creds = ocr_credentials or {} + client = PaddleOCRClient( + api_url=creds.get("api_url"), + token=creds.get("token"), + model=creds.get("model"), + use_doc_orientation=creds.get("use_doc_orientation"), + use_doc_unwarping=creds.get("use_doc_unwarping"), + use_chart_recognition=creds.get("use_chart_recognition"), + ) + + # 按文件类型分组 + pdf_paths = [p for p in all_image_paths if p.lower().endswith(".pdf")] + image_only = [p for p in all_image_paths if not p.lower().endswith(".pdf")] + + raw_ocr_results = [] + for pdf_path in pdf_paths: + try: + raw_ocr_results.append(client.parse_pdf(pdf_path, save_output=True)) + except Exception: + logger.exception(f"OCR PDF 失败: {pdf_path}") + if image_only: + try: + img_results = run_async(client.parse_images_async(image_only, save_output=True)) + if img_results: + raw_ocr_results.extend(img_results) + except Exception: + logger.exception("OCR 图片失败") + + if not raw_ocr_results: + return jsonify({'success': False, 'error': 'OCR 解析失败,请检查 PaddleOCR 配置'}), 500 + + # 简化结果用于后续分割 + ocr_data = simplify_ocr_results(raw_ocr_results) + + # 保存 OCR 结果到会话,供后续 /api/split 复用 + import json + results_dir = str(settings.results_dir) + os.makedirs(results_dir, exist_ok=True) + ocr_cache_path = os.path.join(results_dir, "ocr_cache.json") + with open(ocr_cache_path, 'w', encoding='utf-8') as f: + json.dump(ocr_data, f, ensure_ascii=False, indent=2) + + # 构建前端预览数据:每页的图片 + bbox 标注 + preview_pages = [] + page_idx = 0 + for result in raw_ocr_results: + for layout_page in result.get("layoutParsingResults", []): + pruned = layout_page.get("prunedResult", {}) + page_w = pruned.get("width", 1) + page_h = pruned.get("height", 1) + parsing_list = pruned.get("parsing_res_list", []) + + blocks = [] + for b in parsing_list: + bbox = b.get("block_bbox") + if not bbox: + continue + blocks.append({ + "label": b.get("block_label", ""), + "content": (b.get("block_content", "") or "")[:80], + "bbox": bbox, + }) + + image_path = all_image_paths[page_idx] if page_idx < len(all_image_paths) else None + image_url = f"/api/image/{os.path.basename(image_path)}" if image_path else None + + preview_pages.append({ + "page_index": page_idx, + "image_url": image_url, + "page_width": page_w, + "page_height": page_h, + "blocks": blocks, + }) + page_idx += 1 + + return jsonify({ + 'success': True, + 'message': f'OCR 完成,共 {len(preview_pages)} 页', + 'pages': preview_pages, + 'total_blocks': sum(len(p["blocks"]) for p in preview_pages), + }) + + except Exception: + logger.exception("OCR 执行失败") + return jsonify({'success': False, 'error': 'OCR 执行失败,请稍后重试'}), 500 + + +@bp.route('/split', methods=['POST']) +def split_questions(): + """开始执行标准化 + OCR + 分割。 + + 用户点击前端"开始分割题目"后调用该接口: + - 标准化输入(PDF/图片 → 图片列表) + - 触发 Agent/OCR 并分割题目 + + Returns: + JSON响应,包含分割后的题目 + """ + try: + # 读取请求体参数(模型供应商 + 模型名称) + data = request.get_json(silent=True) or {} + model_provider = data.get("model_provider", "openai") + model_name = data.get("model_name") # 可选,None 时使用 provider 默认模型 + if not settings.is_valid_provider(model_provider): + return jsonify({ + 'success': False, + 'error': f'不支持的模型供应商: {model_provider}' + }), 400 + + # 从数据库加载用户的 LLM + OCR 凭据 + user_id = session.get('user_id') + ocr_credentials = {} + if user_id: + settings.load_providers_from_db(user_id) + with SessionLocal() as db: + ocr_provider = crud.get_active_provider(db, user_id, 'paddleocr') + if ocr_provider: + ocr_credentials = { + "api_url": ocr_provider.base_url, + "token": ocr_provider.api_key, + "model": ocr_provider.model_name, + "use_doc_orientation": ocr_provider.use_doc_orientation, + "use_doc_unwarping": ocr_provider.use_doc_unwarping, + "use_chart_recognition": ocr_provider.use_chart_recognition, + } + + with session_lock: + us = get_user_session(user_id) + keys = list(us["session_file_order"]) + file_paths = [] + for k in keys: + v = us["session_files"].get(k) or {} + fp = v.get('filepath') + if fp: + file_paths.append(fp) + + if not file_paths: + return jsonify({ + 'success': False, + 'error': '请先上传文件' + }), 400 + + with session_lock: + us = get_user_session(user_id) + us["current_thread_id"] = str(uuid.uuid4()) + thread_id = us["current_thread_id"] + config = {"configurable": {"thread_id": thread_id}} + + initial_state = { + "file_paths": file_paths, + "model_provider": model_provider, + "model_name": model_name, + "ocr_credentials": ocr_credentials, + } + workflow_graph.invoke(initial_state, config=config) + result_state = workflow_graph.invoke(None, config=config) + + questions = result_state.get('questions', []) + warnings = result_state.get('warnings', []) + + # 自动保存分割记录 + try: + subject = _read_split_subject() + + with session_lock: + us = get_user_session(user_id) + file_names = [ + us["session_files"].get(k, {}).get("filename", "未知") + for k in us["session_file_order"] + ] + + with SessionLocal() as db: + crud.save_split_record(db, subject, model_provider, file_names, questions, user_id=user_id) + except Exception: + logger.warning("保存分割记录失败,不影响主流程", exc_info=True) + + return jsonify({ + 'success': True, + 'message': f'成功分割 {len(questions)} 道题目', + 'questions': questions, + 'warnings': warnings, + }) + + except Exception as e: + logger.exception("题目分割失败") + return jsonify({ + 'success': False, + 'error': '题目分割失败,请稍后重试' + }), 500 + + +@bp.route('/split-records', methods=['GET']) +def get_split_records(): + """获取最近 N 次分割历史记录,limit 由前端通过查询参数指定""" + try: + limit = request.args.get('limit', 10, type=int) + limit = max(1, min(limit, crud.MAX_SPLIT_RECORDS)) # 上限与保留条数一致 + + with SessionLocal() as db: + records = crud.get_recent_split_records(db, limit, user_id=session.get('user_id')) + result = [_serialize_split_record(r) for r in records] + + return jsonify({"success": True, "records": result}) + + except Exception as e: + logger.exception("获取分割记录失败") + return jsonify({"success": False, "error": "获取分割记录失败"}), 500 + + +@bp.route('/split-records/', methods=['GET']) +def get_split_record_detail(record_id): + """获取单条分割记录的完整数据(含 questions)""" + try: + with SessionLocal() as db: + uid = None if session.get('is_admin') else session.get('user_id') + record = crud.get_split_record_by_id(db, record_id, user_id=uid) + if not record: + return jsonify({"success": False, "error": "记录不存在"}), 404 + + result = _serialize_split_record(record) + result["questions"] = json.loads(record.questions_json) if record.questions_json else [] + + return jsonify({"success": True, "record": result}) + + except Exception as e: + logger.exception("获取分割记录详情失败") + return jsonify({"success": False, "error": "获取分割记录详情失败"}), 500 + + +@bp.route('/export', methods=['POST']) +def export_wrongbook(): + """ + 注入选中题目 ID 并恢复图执行导出 + + 图执行: export → END + + Returns: + JSON响应,包含导出文件路径 + """ + try: + data = request.get_json(silent=True) or {} + selected_uids = data.get('selected_ids', []) + + if not isinstance(selected_uids, list): + return jsonify({ + 'success': False, + 'error': 'selected_ids 必须为列表' + }), 400 + + if not selected_uids: + return jsonify({ + 'success': False, + 'error': '未选择任何题目' + }), 400 + + # 检查是否已分割(通过 questions.json 存在性判断,不依赖内存中的 current_thread_id) + results_dir = settings.results_dir + questions_file = os.path.join(results_dir, "questions.json") + if not os.path.exists(questions_file): + return jsonify({ + 'success': False, + 'error': '请先分割题目' + }), 400 + + with open(questions_file, 'r', encoding='utf-8') as f: + questions = json.load(f) + + output_path = export_wrongbook_md( + questions, + selected_uids, + ) + + return jsonify({ + 'success': True, + 'message': '错题本导出成功', + 'output_path': output_path + }) + + except Exception as e: + logger.exception("导出失败") + return jsonify({ + 'success': False, + 'error': '导出失败,请稍后重试' + }), 500 + + +@bp.route('/image/') +def serve_image(filename): + """提供上传/处理后的图片文件访问(OCR 预览用)""" + from flask import send_from_directory + # 在多个目录中查找 + for d in [settings.upload_dir, settings.erased_dir, settings.results_dir, settings.pages_dir]: + path = os.path.join(str(d), filename) + if os.path.exists(path): + return send_from_directory(str(d), filename) + return jsonify({'error': 'File not found'}), 404 diff --git a/backend/src/paddleocr_client.py b/backend/src/paddleocr_client.py index af16130f..79b13db3 100644 --- a/backend/src/paddleocr_client.py +++ b/backend/src/paddleocr_client.py @@ -120,7 +120,7 @@ def _parse_file( ) -> Dict[str, Any]: """解析文件并返回结构化结果(同步,任务轮询模式)""" if output_dir is None: - from config import settings + from core.config import settings output_dir = settings.struct_dir console.print(f"[cyan]正在解析: {file_path}[/cyan]") @@ -270,7 +270,7 @@ async def async_parse_image( ) -> Dict[str, Any]: """异步解析单张图片(提交任务 → 轮询 → 下载结果)""" if output_dir is None: - from config import settings + from core.config import settings output_dir = settings.struct_dir console.print(f"[cyan]正在解析图片: {image_path}[/cyan]") diff --git a/backend/src/utils.py b/backend/src/utils.py index 6d5f07bd..db8ad164 100644 --- a/backend/src/utils.py +++ b/backend/src/utils.py @@ -4,6 +4,7 @@ """ import os +import re import shutil import asyncio from concurrent.futures import ThreadPoolExecutor @@ -12,9 +13,9 @@ from dotenv import load_dotenv from rich.console import Console -from config import settings +from core.config import settings -load_dotenv() +load_dotenv(os.path.join(os.path.dirname(__file__), "..", ".env")) console = Console() @@ -62,7 +63,7 @@ def prepare_input(file_path: str) -> List[str]: def export_wrongbook( questions: List[Dict[str, Any]], - selected_ids: List[str], + selected_uids: List[str], output_path: str = None, batch_info: Dict[str, Any] = None ) -> str: @@ -73,7 +74,7 @@ def export_wrongbook( Args: questions: 题目列表 - selected_ids: 用户选择的题目ID列表 + selected_uids: 用户选择的题目 uid 列表 output_path: 输出Markdown文件路径(可选) batch_info: 批次信息(用于入库),包含 original_filename, subject 等 @@ -84,59 +85,107 @@ def export_wrongbook( os.makedirs(settings.results_dir, exist_ok=True) output_path = os.path.join(settings.results_dir, "wrongbook.md") - # 过滤选中的题目 - selected_questions = [q for q in questions if q.get('question_id') in selected_ids] + # 用 uid 过滤选中的题目,保持原始顺序 + uid_set = set(selected_uids) + selected_questions = [q for q in questions if q.get('uid') in uid_set] # 构建Markdown内容 md_content = "# 错题本\n\n" md_content += f"> 共收录 {len(selected_questions)} 道题目\n\n" md_content += "---\n\n" - for i, q in enumerate(selected_questions, start=1): - md_content += f"## {i}. 题目 {q.get('question_id', '')} ({q.get('question_type', '未知')})\n\n" + rel_struct_dir = os.path.relpath(settings.struct_dir, settings.results_dir) + _img_src_re = re.compile(r'src="((?:/images/|imgs/)[^"]+)"') + + def _resolve_image_path(p: str) -> str: + """将 Agent 输出的图片路径统一转为 Markdown 可用的相对路径。 + + Agent 有时输出 '/images/xxx.jpg'(Flask 路由),有时输出 'imgs/xxx.jpg' + (LLM 对路径的自由变形),统一映射到 struct_dir/imgs/ 下的相对路径。 + """ + p = p.strip() + if p.startswith("/images/"): + return f"{rel_struct_dir}/imgs/{p[len('/images/'):]}" + if p.startswith("imgs/"): + return f"{rel_struct_dir}/imgs/{p[len('imgs/'):]}" + return p + + def _fix_html_image_src(html: str) -> str: + """修正 HTML 内 中的图片路径,与独立 image block 保持一致。""" + return _img_src_re.sub( + lambda m: f'src="{_resolve_image_path(m.group(1))}"', html + ) + + _INIT = object() # 初始哨兵,确保第一个有 section_title 的题一定触发标题输出 + current_section = _INIT + unsorted_started = False + serial = 0 # 全局序号 + + for q in selected_questions: + section = q.get('section_title') + + if section: + # 有 section_title:正常输出大题分组标题 + if section != current_section: + current_section = section + md_content += f"## {section}\n\n" + else: + # section=None:首次遇到时输出"(未分类)"节标题 + if not unsorted_started: + unsorted_started = True + md_content += "## (未分类)\n\n" + + serial += 1 + md_content += f"### {serial}. 题目 {q.get('question_id', '')} ({q.get('question_type', '未知')})\n\n" # 获取图片引用列表,用于填充空的 image block image_refs = q.get('image_refs') or [] - rendered_images = set() # 记录已渲染的图片路径 + rendered_images = set() # 记录已渲染的图片路径(原始路径,供 image_refs 兜底比对) + + # 预扫描:收集已内嵌在 HTML 文本块(如 table)中的图片路径,避免重复渲染 + html_embedded = set() + for block in q.get('content_blocks', []): + if block.get('block_type') == 'text': + for m in _img_src_re.finditer(block.get('content', '')): + html_embedded.add(m.group(1).strip()) # 添加内容块(只有 text 和 image,公式以 LaTeX 标记嵌入 text 中) for block in q.get('content_blocks', []): if block['block_type'] == 'text': - md_content += f"{block['content']}\n\n" + content = block['content'].replace('\n', ' \n') + # 修正 HTML 内嵌图片路径(table 中的 ) + content = _fix_html_image_src(content) + md_content += f"{content}\n\n" elif block['block_type'] == 'image': image_path = block.get('content', '').strip() - if image_path: - rendered_images.add(image_path) - - # 将 Flask 路由路径转为 Markdown 相对路径 - if image_path.startswith("/images/"): - rel_struct_dir = os.path.relpath(settings.struct_dir, settings.results_dir) - image_path = f"{rel_struct_dir}/imgs/{image_path[len('/images/') :]}" - - if image_path: - md_content += f"![图片]({image_path})\n\n" + if not image_path or image_path in html_embedded: + # 已在 HTML 表格中渲染过,跳过独立 image block 避免重复 + continue + rendered_images.add(image_path) + resolved = _resolve_image_path(image_path) + if resolved: + md_content += f"![图片]({resolved})\n\n" # 添加选项 if q.get('options'): for option in q['options']: - md_content += f"{option}\n\n" + md_content += f"{option} \n" + md_content += "\n" - # 兜底:渲染 image_refs 中未被 content_blocks 覆盖的图片 - remaining_images = [p for p in image_refs if p not in rendered_images] + # 兜底:渲染 image_refs 中未被 content_blocks 覆盖、也未在 HTML 中出现的图片 + remaining_images = [p for p in image_refs if p not in rendered_images and p not in html_embedded] if remaining_images: for image_path in remaining_images: - if image_path.startswith("/images/"): - rel_struct_dir = os.path.relpath(settings.struct_dir, settings.results_dir) - image_path = f"{rel_struct_dir}/imgs/{image_path[len('/images/') :]}" - md_content += f"![图片]({image_path})\n\n" + md_content += f"![图片]({_resolve_image_path(image_path)})\n\n" - md_content += "### 我的答案\n\n" + answer_prefix = "####" if section else "###" + md_content += f"{answer_prefix} 我的答案\n\n" md_content += "_(请在此处填写你的答案)_\n\n" - md_content += "### 正确答案\n\n" + md_content += f"{answer_prefix} 正确答案\n\n" md_content += "_(请在此处填写正确答案)_\n\n" - md_content += "### 解析\n\n" + md_content += f"{answer_prefix} 解析\n\n" md_content += "_(请在此处填写解题思路和知识点)_\n\n" md_content += "---\n\n" @@ -185,6 +234,9 @@ def simplify_ocr_results(ocr_results: list) -> List[Dict[str, Any]]: if bbox: prefix = "img_in_chart_box" if label == "chart" else "img_in_image_box" content = f"/images/{prefix}_{int(bbox[0])}_{int(bbox[1])}_{int(bbox[2])}_{int(bbox[3])}.jpg" + # 统一 OCR 原始输出中的图片路径:imgs/ → /images/ + if 'src="imgs/' in content: + content = content.replace('src="imgs/', 'src="/images/') slim_blocks.append({ "block_label": label, "block_content": content, diff --git a/backend/src/workflow.py b/backend/src/workflow.py index ce0c8f7d..4ed8c1e7 100644 --- a/backend/src/workflow.py +++ b/backend/src/workflow.py @@ -4,16 +4,21 @@ """ import os +import re as _re import json import logging import time +import traceback +import difflib as _difflib from typing import List, Dict, Any, TypedDict from concurrent.futures import ThreadPoolExecutor, as_completed from rich.console import Console from langgraph.graph import StateGraph, START, END from langgraph.checkpoint.memory import MemorySaver -from config import settings +from core.config import settings from .utils import prepare_input, export_wrongbook, simplify_ocr_results, run_async + +_HTML_TAG_RE = _re.compile(r"<[^>]+>") console = Console() # 配置日志 @@ -106,14 +111,15 @@ def _run_ocr_and_simplify(file_paths: List[str], ocr_credentials: Dict[str, Any] break except Exception as e: last_error = e + tb = traceback.format_exc() if attempt < max_retries: delay = retry_delays[attempt - 1] - logger.warning(f"OCR PDF 第 {attempt} 次失败 ({e}),{delay}s 后重试...") - console.print(f"[yellow]OCR PDF 第 {attempt} 次失败,{delay}s 后重试...[/yellow]") + logger.warning(f"OCR PDF 第 {attempt} 次失败 ({type(e).__name__}: {e}),{delay}s 后重试...\n{tb}") + console.print(f"[yellow]OCR PDF 第 {attempt} 次失败 ({type(e).__name__}: {e}),{delay}s 后重试...[/yellow]") time.sleep(delay) else: - logger.error(f"OCR PDF 全部 {max_retries} 次重试失败: {last_error}") - console.print(f"[red]OCR PDF 解析失败(已重试 {max_retries} 次): {last_error}[/red]") + logger.error(f"OCR PDF 全部 {max_retries} 次重试失败 ({type(last_error).__name__}: {last_error})\n{tb}") + console.print(f"[red]OCR PDF 解析失败(已重试 {max_retries} 次): {type(last_error).__name__}: {last_error}[/red]") if result is not None: ocr_results.append(result) @@ -128,14 +134,15 @@ def _run_ocr_and_simplify(file_paths: List[str], ocr_credentials: Dict[str, Any] break except Exception as e: last_error = e + tb = traceback.format_exc() if attempt < max_retries: delay = retry_delays[attempt - 1] - logger.warning(f"OCR 图片第 {attempt} 次失败 ({e}),{delay}s 后重试...") - console.print(f"[yellow]OCR 图片第 {attempt} 次失败,{delay}s 后重试...[/yellow]") + logger.warning(f"OCR 图片第 {attempt} 次失败 ({type(e).__name__}: {e}),{delay}s 后重试...\n{tb}") + console.print(f"[yellow]OCR 图片第 {attempt} 次失败 ({type(e).__name__}: {e}),{delay}s 后重试...[/yellow]") time.sleep(delay) else: - logger.error(f"OCR 图片全部 {max_retries} 次重试失败: {last_error}") - console.print(f"[red]OCR 图片解析失败(已重试 {max_retries} 次): {last_error}[/red]") + logger.error(f"OCR 图片全部 {max_retries} 次重试失败 ({type(last_error).__name__}: {last_error})\n{tb}") + console.print(f"[red]OCR 图片解析失败(已重试 {max_retries} 次): {type(last_error).__name__}: {last_error}[/red]") if img_results: ocr_results.extend(img_results) @@ -150,28 +157,40 @@ def _build_overlapping_batches( batch_size: int = 2, overlap: int = 1, ) -> List[List[Dict[str, Any]]]: - """构建重叠批次 + """构建重叠批次,并为每页打上 is_primary 标记。 每批 batch_size 页,相邻批次重叠 overlap 页。 例如 5 页, batch_size=2, overlap=1: - 批次0: [page0, page1] - 批次1: [page1, page2] - 批次2: [page2, page3] - 批次3: [page3, page4] + 批次0: [page0(primary), page1(context)] + 批次1: [page1(primary), page2(context)] + 批次2: [page2(primary), page3(context)] + 批次3: [page3(primary), page4(primary←最后一批)] + + is_primary=True → Agent 必须提取该页开始的所有题目 + is_primary=False → 仅作跨页上下文,Agent 不提取该页独立开始的题目 + + 最后一批次的所有页均为 primary(最后一页没有后续批次来处理它)。 """ if not ocr_data: return [] n_pages = len(ocr_data) if n_pages <= batch_size: - return [ocr_data] + # 只有一批:全部页都是 primary + return [[dict(page, is_primary=True) for page in ocr_data]] step = batch_size - overlap batches = [] for start in range(0, n_pages, step): end = min(start + batch_size, n_pages) - batches.append(ocr_data[start:end]) - if end >= n_pages: + is_last = (end >= n_pages) + batch = [] + for page_idx, page in enumerate(ocr_data[start:end]): + # 第一页始终 primary;最后批次的所有页都 primary + primary = (page_idx == 0) or is_last + batch.append(dict(page, is_primary=primary)) + batches.append(batch) + if is_last: break return batches @@ -240,7 +259,7 @@ def _identify_subject( # ── 第 1 层:LLM 预检 ── try: - from error_correction_agent.agent import detect_subject_via_llm + from agents.error_correction.agent import detect_subject_via_llm llm_result = detect_subject_via_llm(text_sample, db_subjects, provider=model_provider) if llm_result: @@ -299,18 +318,218 @@ def _content_fingerprint(q: Dict[str, Any]) -> str: return "" +def _question_text(q: Dict[str, Any], chars: int = 400) -> str: + """提取题目纯文本,用于相似度计算。 + + 包含:content_blocks 中的 text 块(去除 HTML 标签)+ options 选项列表。 + image 块不参与计算。 + + chars 上限设为 400:覆盖大多数题目的完整内容,同时避免超长题目的 O(n²) 开销。 + + 去除 HTML 标签的原因:表格题目在不同批次的 table 结构可能不同(th/td 排列差异), + 但纯文本内容相同。去标签后两个版本的实验描述文字完全一致,相似度可正确判断。 + + 纳入 options 的原因:跨页截断时题干可能不同,但选项往往相同,是最稳定的指纹。 + """ + parts = [] + for block in q.get("content_blocks", []): + if block.get("block_type") == "text": + content = block.get("content", "") + content = _HTML_TAG_RE.sub("", content) # 去除 HTML 标签,保留文本 + parts.append(content) + for opt in q.get("options") or []: + if isinstance(opt, str): + parts.append(opt) + return "".join(parts)[:chars] + + +def _image_paths(q: Dict[str, Any]) -> set: + """提取题目所有 image block 的路径集合,用于图片指纹比对。""" + paths = set() + for block in q.get("content_blocks", []): + if block.get("block_type") == "image": + p = block.get("content", "").strip() + if p: + paths.add(p) + return paths + + +def _text_similarity(q1: Dict[str, Any], q2: Dict[str, Any]) -> float: + """计算两道题目内容相似度,返回 0~1。 + + 优先用文本相似度(difflib);若两题文本均过短(图片题), + 则用图片路径 Jaccard 系数兜底,避免纯图片题的重复无法被检测到。 + """ + t1 = _question_text(q1) + t2 = _question_text(q2) + + # 文本足够长时直接用 difflib + if len(t1) >= 10 and len(t2) >= 10: + return _difflib.SequenceMatcher(None, t1, t2).ratio() + + # 文本过短(图片题):用图片路径 Jaccard 系数兜底 + imgs1 = _image_paths(q1) + imgs2 = _image_paths(q2) + if imgs1 or imgs2: + intersection = len(imgs1 & imgs2) + union = len(imgs1 | imgs2) + return intersection / union if union else 0.0 + + # 文本和图片都为空:不认为是重复 + return 0.0 + + +def _fix_leading_images(questions: List[Dict[str, Any]]) -> None: + """后处理:将题目 content_blocks 中排在所有文本之前的图片移到前一道题末尾。 + + 产生原因:试卷某题的插图印在下一页顶部,OCR 按页面顺序扫描时,该图片 + 出现在下一题文字之前。Agent 在该批次里将其归入下一题的 content_blocks 首位, + 实际上属于上一题。 + + 判断规则:若一道题的 content_blocks 中第一个出现的 text block 之前存在 + image block,则这些 leading image 属于上一道题,移至上一题末尾。 + """ + for i in range(1, len(questions)): + q = questions[i] + blocks = q.get("content_blocks") or [] + if not blocks: + continue + + # 分离开头的连续 image 块(在第一个 text 块之前) + leading_images: List[Dict[str, Any]] = [] + rest: List[Dict[str, Any]] = [] + found_text = False + for block in blocks: + if not found_text and block.get("block_type") == "image": + leading_images.append(block) + else: + if block.get("block_type") == "text": + found_text = True + rest.append(block) + + if not leading_images: + continue + + # 若去掉 leading images 后该题没有任何文本,说明它本身是纯图片题,不搬移 + if not any(b.get("block_type") == "text" for b in rest): + continue + + # 移到前一道题末尾 + prev_q = questions[i - 1] + prev_blocks = prev_q.get("content_blocks") or [] + prev_q["content_blocks"] = prev_blocks + leading_images + q["content_blocks"] = rest + logger.info( + f"修复 leading image: {len(leading_images)} 张图片 " + f"从题目 {q.get('question_id')} 移至题目 {prev_q.get('question_id')}" + ) + + +def _normalize_image_paths(questions: List[Dict[str, Any]]) -> None: + """修复 LLM 可能篡改的图片路径,原地修改。 + + LLM 有时会把输入中的 '/images/xxx.jpg' 改写为 'imgs/xxx.jpg', + 导致前端通过 Vite proxy 请求时路径不匹配。统一规范为 '/images/xxx'。 + """ + def _fix(path: str) -> str: + p = path.strip() + if p.startswith("imgs/"): + return "/images/" + p[len("imgs/"):] + return p + + for q in questions: + for block in q.get("content_blocks") or []: + content = block.get("content", "") + if block.get("block_type") == "image": + block["content"] = _fix(content) + elif block.get("block_type") == "text" and "imgs/" in content: + # 修复 text block 中嵌入的 HTML 图片路径(如 table 中的 ) + block["content"] = content.replace('src="imgs/', 'src="/images/') + if q.get("image_refs"): + q["image_refs"] = [_fix(ref) for ref in q["image_refs"]] + if q.get("option_images"): + q["option_images"] = [_fix(ref) if ref else ref for ref in q["option_images"]] + + +def _propagate_section_between_batches(batch_results: List[List[Dict[str, Any]]]) -> None: + """跨批次传播 section_title,原地修改 batch_results。 + + 并行批次处理完成后调用。若批次 i 开头若干题的 section_title=None, + 说明大题标题在前一批次的页面里,当前批次窗口看不到。 + 从批次 i-1 的末尾向前找最后一个有 section_title 的题,将其 section_title + 赋给批次 i 中连续的 section=None 开头题,遇到批次 i 自己识别出 section_title + 的题时停止传播。 + + 防误传:若待传播 section 是在批次 i-1 中由题号较大的题建立的,则不向题号 + 更小的题传播(说明该 None 题属于更早的大题,而非当前 last_section)。 + """ + def _to_int_id(q) -> int | None: + try: + return int(str(q.get("question_id", "")).strip()) + except (ValueError, TypeError): + return None + + for i in range(1, len(batch_results)): + # 单次遍历上一批次:同时找 last_section 和该节首次出现的最小题号 + last_section = None + first_section_id: int | None = None + for q in batch_results[i - 1]: + s = q.get("section_title") + if s: + if s != last_section: + # 进入新节,重置首题号 + last_section = s + first_section_id = None + qid = _to_int_id(q) + if qid is not None: + if first_section_id is None or qid < first_section_id: + first_section_id = qid + + if not last_section: + continue + + # 将 last_section 赋给本批次开头连续的 section=None 题 + # 防误传:若待传播题的题号 < first_section_id,说明它属于更早的大题,跳过 + propagated = 0 + for q in batch_results[i]: + if not q.get("section_title"): + qid = _to_int_id(q) + if first_section_id is not None and qid is not None and qid < first_section_id: + # 该题题号比 last_section 第一题还小,不应继承该 section + continue + q["section_title"] = last_section + propagated += 1 + else: + break # 本批次已有自己识别出的 section,停止传播 + + if propagated: + logger.info( + f"跨批次 section 传播: 批次 {i} 前 {propagated} 道题 " + f"继承 section_title={repr(last_section)}" + ) + + def _dedup_questions(questions: List[Dict[str, Any]]) -> List[Dict[str, Any]]: - """按「题号 + 内容指纹」去重。 + """按「(大题, 题号)」去重,再用内容相似度消除跨批次重复。 - - 同题号 + 相同指纹 → 重叠页产生的真重复,保留内容更丰富的版本 - - 同题号 + 不同指纹 → 不同板块的同号题(如小学试卷各大题下均有第1题),全部保留 + 第一轮:同一 (section_title, question_id) 内保留最丰富版本。 + 第二轮:同一 question_id 下若有多份,两两计算前 120 字相似度; + 相似度 ≥ 0.75 视为重复,优先保留有 section_title 的版本, + 相似度 < 0.75 视为不同大题下的同号题,全部保留。 """ if not questions: return [] from collections import defaultdict - groups: Dict[str, List[Dict[str, Any]]] = defaultdict(list) + # ── 预处理:将 question_id 统一归一化为 str,防止 int/str 类型不一致导致去重失效 ── + for q in questions: + qid = q.get("question_id") + if qid is not None: + q["question_id"] = str(qid).strip() + + # ── 第一轮:按 (section, qid) 复合键去重 ────────────────── + groups: Dict[tuple, List[Dict[str, Any]]] = defaultdict(list) no_id: List[Dict[str, Any]] = [] for q in questions: @@ -318,26 +537,91 @@ def _dedup_questions(questions: List[Dict[str, Any]]) -> List[Dict[str, Any]]: if not qid: no_id.append(q) else: - groups[qid].append(q) - - result: List[Dict[str, Any]] = list(no_id) + section = q.get("section_title") or "" + groups[(section, qid)].append(q) + after_round1: List[Dict[str, Any]] = list(no_id) for qs in groups.values(): - if len(qs) == 1: - result.append(qs[0]) + after_round1.append(max(qs, key=_question_richness)) + + # ── 第二轮:结构优先 + 内容相似度去重 ─────────────────────── + # 策略: + # 1. 同一 qid 下同时存在有 section 和无 section 版本 → 直接丢弃所有 section=None 版本 + # (section=None 说明该批次只捕获到选项/部分内容,有 section 的是完整版本) + # 2. 同一 qid 下均有 section(不同 section)→ difflib 相似度 ≥ 0.75 视为重复,保留最优 + # 3. 同一 qid 下均无 section → 保留内容最丰富的一份 + by_qid: Dict[str, List[Dict[str, Any]]] = defaultdict(list) + for q in after_round1: + by_qid[q.get("question_id", "")].append(q) + + SIMILARITY_THRESHOLD = 0.75 + final: List[Dict[str, Any]] = list(no_id) + round2_removed = 0 + + for qid, entries in by_qid.items(): + if not qid: continue + if len(entries) == 1: + final.extend(entries) + continue + + sectioned = [q for q in entries if q.get("section_title")] + unsectioned = [q for q in entries if not q.get("section_title")] - # 按内容指纹二次分组 - fp_groups: Dict[str, List[Dict[str, Any]]] = defaultdict(list) - for q in qs: - fp_groups[_content_fingerprint(q)].append(q) + # 策略1:有 section 版本存在时,丢弃全部 section=None 版本 + if sectioned and unsectioned: + round2_removed += len(unsectioned) + for q in unsectioned: + logger.debug( + f"二次去重剔除(结构): qid={qid} " + f"section=None,保留有大题标题的版本,richness={_question_richness(q)}" + ) + entries = sectioned + + if len(entries) == 1: + final.extend(entries) + continue - # 每个指纹组只保留最丰富的版本 - for fp_qs in fp_groups.values(): - result.append(max(fp_qs, key=_question_richness)) + # 策略2/3:全部有 section 或全部无 section → difflib 去重 + entries.sort(key=lambda q: ( + 0 if q.get("section_title") else 1, + -_question_richness(q) + )) + + kept: List[Dict[str, Any]] = [] + for candidate in entries: + sim = max( + (_text_similarity(candidate, k) for k in kept), + default=0.0, + ) + if sim >= SIMILARITY_THRESHOLD: + round2_removed += 1 + logger.debug( + f"二次去重剔除(相似度): qid={qid} " + f"section={repr(candidate.get('section_title'))} " + f"相似度={sim:.2f}" + ) + else: + kept.append(candidate) + final.extend(kept) + + if round2_removed: + logger.info(f"二次去重: 剔除 {round2_removed} 道重复题目(结构优先 + 相似度阈值={SIMILARITY_THRESHOLD})") + console.print(f"[yellow]二次去重: 剔除 {round2_removed} 道重复题目[/yellow]") + + # ── 排序:有 section 的题按首次出现顺序 + 题号,section=None 的题排最后 ── + section_order: Dict[str, int] = {} + for q in questions: + s = q.get("section_title") + if s and s not in section_order: + section_order[s] = len(section_order) - result.sort(key=lambda q: _sort_key(q.get("question_id", ""))) - return result + final.sort(key=lambda q: ( + 0 if q.get("section_title") else 1, # 有 section 的排前,None 排后 + section_order.get(q.get("section_title") or "", 999), + _sort_key(q.get("question_id", "")) + )) + return final def _question_richness(q: Dict[str, Any]) -> int: @@ -388,30 +672,43 @@ def split_questions_node(state: WorkflowState) -> dict: if os.path.exists(meta_path): os.remove(meta_path) - # ── Step 1: OCR 解析 ── - console.print(f"[cyan]OCR 解析 {len(file_paths)} 个文件...[/cyan]") - ocr_start = time.time() - - ocr_data = _run_ocr_and_simplify(file_paths, ocr_credentials=ocr_credentials) + # ── Step 1: OCR 解析(优先使用缓存) ── + ocr_cache_path = os.path.join(results_dir, "ocr_cache.json") + ocr_data = None + if os.path.exists(ocr_cache_path): + try: + with open(ocr_cache_path, 'r', encoding='utf-8') as f: + ocr_data = json.load(f) + console.print(f"[green]✓ 使用 OCR 缓存: {len(ocr_data)} 页[/green]") + logger.info(f"使用 OCR 缓存: {len(ocr_data)} 页") + os.remove(ocr_cache_path) # 用完即删,避免下次误用 + except Exception as e: + logger.warning(f"读取 OCR 缓存失败: {e},将重新执行 OCR") + ocr_data = None if not ocr_data: - logger.error("OCR 解析失败,无数据返回") - console.print("[red]⚠ OCR 解析失败[/red]") - return { - "questions": [], - "warnings": ["步骤 2(OCR 解析)失败:无法解析图片内容,请检查 PaddleOCR API Token 配置"], - } + console.print(f"[cyan]OCR 解析 {len(file_paths)} 个文件...[/cyan]") + ocr_start = time.time() + ocr_data = _run_ocr_and_simplify(file_paths, ocr_credentials=ocr_credentials) + + if not ocr_data: + logger.error("OCR 解析失败,无数据返回") + console.print("[red]⚠ OCR 解析失败[/red]") + return { + "questions": [], + "warnings": ["步骤 2(OCR 解析)失败:无法解析图片内容,请检查 PaddleOCR API Token 配置"], + } + + total_blocks = sum(len(p.get("blocks", [])) for p in ocr_data) + ocr_elapsed = time.time() - ocr_start + logger.info(f"OCR 完成: {len(ocr_data)} 页, {total_blocks} 个 block, 耗时 {ocr_elapsed:.2f}s") + console.print(f"[green]✓ OCR 完成: {len(ocr_data)} 页, {total_blocks} 个 block ({ocr_elapsed:.1f}s)[/green]") # 保存 agent_input.json(供纠错节点使用) agent_input_path = os.path.join(results_dir, "agent_input.json") with open(agent_input_path, 'w', encoding='utf-8') as f: json.dump(ocr_data, f, ensure_ascii=False, indent=2) - total_blocks = sum(len(p.get("blocks", [])) for p in ocr_data) - ocr_elapsed = time.time() - ocr_start - logger.info(f"OCR 完成: {len(ocr_data)} 页, {total_blocks} 个 block, 耗时 {ocr_elapsed:.2f}s") - console.print(f"[green]✓ OCR 完成: {len(ocr_data)} 页, {total_blocks} 个 block ({ocr_elapsed:.1f}s)[/green]") - # ── Step 2: 加载 DB 上下文 ── db_subjects, db_tags = _load_db_context() @@ -435,13 +732,18 @@ def split_questions_node(state: WorkflowState) -> dict: # ── Step 4: 构建重叠批次 ── batches = _build_overlapping_batches(ocr_data, batch_size=2, overlap=1) - console.print(f"[cyan]构建 {len(batches)} 个批次(2页/批, 1页重叠)[/cyan]") + console.print(f"[cyan]构建 {len(batches)} 个批次(每批1主页+1上下文页)[/cyan]") + + # 保存完整批次数据到 agent_input.json(含 is_primary 标记,供调试和纠错节点使用) + agent_input_path = os.path.join(results_dir, "agent_input.json") + with open(agent_input_path, 'w', encoding='utf-8') as f: + json.dump(batches, f, ensure_ascii=False, indent=2) # ── Step 5: 并行分割 ── split_start = time.time() console.print(f"[cyan]并行分割 {len(batches)} 个批次...[/cyan]") - from error_correction_agent.tools import split_batch + from agents.error_correction.tools import split_batch existing_tags_str = ",".join(db_tags) if db_tags else "" max_workers = min(len(batches), 3) @@ -497,7 +799,9 @@ def _invoke_split(batch_idx: int, batch_data: list) -> None: split_elapsed = time.time() - split_start logger.info(f"并行分割完成, 耗时 {split_elapsed:.2f}s") - # ── Step 6: 合并 + 去重 ── + # ── Step 6: 跨批次 section 传播 + 合并 + 去重 ── + _propagate_section_between_batches(batch_results) + all_questions = [] for questions in batch_results: all_questions.extend(questions) @@ -510,6 +814,16 @@ def _invoke_split(batch_idx: int, batch_data: list) -> None: logger.info(f"去重: {before_dedup} → {after_dedup} 道题目(移除 {before_dedup - after_dedup} 道重复)") console.print(f"[yellow]去重: 移除 {before_dedup - after_dedup} 道重复题目[/yellow]") + # 修复 leading image(页面顶部图属于上一题) + _fix_leading_images(deduped) + + # 修复 LLM 可能篡改的图片路径(如 imgs/xxx → /images/xxx) + _normalize_image_paths(deduped) + + # 为每道题赋全局唯一 uid(顺序字符串),供前端选择和导出时使用 + for i, q in enumerate(deduped): + q["uid"] = str(i) + # ── Step 7: 保存结果 ── with open(questions_file, 'w', encoding='utf-8') as f: json.dump(deduped, f, ensure_ascii=False, indent=2) @@ -567,15 +881,29 @@ def correct_questions_node(state: WorkflowState) -> dict: console.print(f"[cyan]发现 {len(flagged)} 道题目需要纠错(共 {len(questions)} 道)[/cyan]") logger.info(f"开始纠错: {len(flagged)}/{len(questions)} 道题目") - # 加载原始 OCR 数据作为纠错上下文 + # 加载 OCR 数据作为纠错上下文 + # agent_input.json 现在保存的是批次数据([[page, ...], ...]),需要还原为扁平页面列表 ocr_context = "{}" agent_input_path = os.path.join(settings.results_dir, "agent_input.json") if os.path.exists(agent_input_path): with open(agent_input_path, 'r', encoding='utf-8') as f: - ocr_context = f.read() + raw = json.load(f) + # 兼容新格式(批次列表)和旧格式(扁平页面列表) + if raw and isinstance(raw[0], list): + # 新格式:按 page_index 去重,还原为扁平页面列表 + seen = {} + for batch in raw: + for page in batch: + idx = page.get("page_index", id(page)) + if idx not in seen: + seen[idx] = page + flat_pages = [seen[k] for k in sorted(seen)] + ocr_context = json.dumps(flat_pages, ensure_ascii=False) + else: + ocr_context = json.dumps(raw, ensure_ascii=False) # 调用纠错工具 - from error_correction_agent.tools import correct_batch + from agents.error_correction.tools import correct_batch model_provider = state.get("model_provider", "openai") model_name = state.get("model_name") @@ -597,19 +925,25 @@ def correct_questions_node(state: WorkflowState) -> dict: console.print("[red]⚠ 纠错结果解析失败,保留原始题目[/red]") return {"questions": questions} - # 按 question_id 合并纠错结果 - corrected_map = {q["question_id"]: q for q in corrected} + # 按 (section_title, question_id) 复合键合并纠错结果,避免不同大题同号题互相覆盖 + corrected_map = { + (q.get("section_title") or "", q["question_id"]): q + for q in corrected + } merged = [] for q in questions: qid = q.get("question_id") - if qid in corrected_map: - cq = corrected_map[qid] + section = q.get("section_title") or "" + key = (section, qid) + if key in corrected_map: + cq = corrected_map[key] corrections = cq.pop("corrections_applied", []) cq["needs_correction"] = False cq["ocr_issues"] = None + cq["uid"] = q.get("uid") # 纠错对象来自 LLM 输出,不含 uid,从原题还原 merged.append(cq) - logger.info(f"题目 {qid} 已纠错: {corrections}") + logger.info(f"题目 {section}-{qid} 已纠错: {corrections}") else: merged.append(q) diff --git a/backend/tests/test_agent_capabilities.py b/backend/tests/test_agent_capabilities.py new file mode 100644 index 00000000..1a051b3f --- /dev/null +++ b/backend/tests/test_agent_capabilities.py @@ -0,0 +1,21 @@ +from agents.error_correction.agent import _should_avoid_tool_strategy + + +class _DummyCfg: + def __init__(self, model_name: str, base_url: str = ""): + self._model_name = model_name + self.base_url = base_url + + def resolve_model_name(self, model_name=None, *, use_light=False): + return model_name or self._model_name + + +def test_should_avoid_tool_strategy_for_deepseek_reasoner(): + cfg = _DummyCfg(model_name="deepseek-reasoner", base_url="https://api.deepseek.com") + assert _should_avoid_tool_strategy("openai", None, cfg) is True + + +def test_should_not_avoid_tool_strategy_for_deepseek_chat(): + cfg = _DummyCfg(model_name="deepseek-chat", base_url="https://api.deepseek.com") + assert _should_avoid_tool_strategy("openai", None, cfg) is False + diff --git a/backend/tests/test_chat_routes.py b/backend/tests/test_chat_routes.py index 4b856bcc..76e16ba0 100644 --- a/backend/tests/test_chat_routes.py +++ b/backend/tests/test_chat_routes.py @@ -52,10 +52,17 @@ def __enter__(self): def __exit__(self, *args): pass - with patch("web_app.SessionLocal", FakeSessionLocal()): + fake = FakeSessionLocal() + with patch("routes.chat.SessionLocal", fake), \ + patch("routes.questions.SessionLocal", fake), \ + patch("routes.settings.SessionLocal", fake), \ + patch("routes.auth.SessionLocal", fake): from web_app import app app.config["TESTING"] = True with app.test_client() as c: + with c.session_transaction() as sess: + sess['user_id'] = 1 + sess['username'] = 'test' yield c diff --git a/backend/tests/test_correct_node.py b/backend/tests/test_correct_node.py index 5aa58c1c..3a6c63c6 100644 --- a/backend/tests/test_correct_node.py +++ b/backend/tests/test_correct_node.py @@ -40,7 +40,7 @@ def test_skip_when_no_flagged(self): result = correct_questions_node(state) assert result["questions"] == qs - @patch("error_correction_agent.tools.correct_batch") + @patch("agents.error_correction.tools.correct_batch") def test_merge_corrected(self, mock_correct_batch, tmp_path): """纠错结果应按 question_id 合并回原列表""" q1 = _q("1") @@ -62,7 +62,7 @@ def test_merge_corrected(self, mock_correct_batch, tmp_path): with open(os.path.join(results_dir, "agent_input.json"), "w") as f: f.write(agent_input) - with patch("config.settings.results_dir", Path(results_dir)): + with patch("core.config.settings.results_dir", Path(results_dir)): state = {"questions": [q1, q2, q3]} result = correct_questions_node(state) @@ -79,7 +79,7 @@ def test_merge_corrected(self, mock_correct_batch, tmp_path): merged_q1 = next(q for q in merged if q["question_id"] == "1") assert merged_q1["content_blocks"][0]["content"] == "内容" - @patch("error_correction_agent.tools.correct_batch") + @patch("agents.error_correction.tools.correct_batch") def test_invalid_json_keeps_original(self, mock_correct_batch, tmp_path): """纠错返回无效 JSON 时应保留原始题目""" q1 = _q("1", needs_correction=True) @@ -89,7 +89,7 @@ def test_invalid_json_keeps_original(self, mock_correct_batch, tmp_path): with open(os.path.join(results_dir, "agent_input.json"), "w") as f: f.write("{}") - with patch("config.settings.results_dir", Path(results_dir)): + with patch("core.config.settings.results_dir", Path(results_dir)): state = {"questions": [q1]} result = correct_questions_node(state) diff --git a/backend/tests/test_ocr_api.py b/backend/tests/test_ocr_api.py index 14cf78e6..57474a30 100644 --- a/backend/tests/test_ocr_api.py +++ b/backend/tests/test_ocr_api.py @@ -5,7 +5,7 @@ pytest tests/test_ocr_api.py -v -s 需要配置环境变量:PADDLEOCR_API_URL、PADDLEOCR_API_TOKEN。 -测试图片使用 example_uploads/ 目录下的文件(test.jpg + test4.pdf)。 +测试图片使用 example_uploads/notes/test.jpg,测试 PDF 使用 example_uploads/exams/test4.pdf。 """ import os @@ -19,15 +19,46 @@ # ── 配置 ──────────────────────────────────────────────── -API_URL = os.getenv("PADDLEOCR_API_URL", "") -TOKEN = os.getenv("PADDLEOCR_API_TOKEN", "") -MODEL = os.getenv("PADDLEOCR_MODEL", "PaddleOCR-VL-1.5") + +def _load_ocr_creds_from_db() -> dict: + """从数据库读取激活的 PaddleOCR provider 凭据(作为环境变量的 fallback)""" + try: + import sys + _backend = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + if _backend not in sys.path: + sys.path.insert(0, _backend) + from db import SessionLocal + from db.models import ProviderConfig + with SessionLocal() as db: + p = db.query(ProviderConfig).filter( + ProviderConfig.category == "paddleocr", + ProviderConfig.is_active == True, + ).first() + if p: + return { + "api_url": p.base_url or "", + "token": p.api_key or "", + "model": p.model_name or "PaddleOCR-VL-1.5", + "use_doc_orientation": p.use_doc_orientation, + "use_doc_unwarping": p.use_doc_unwarping, + "use_chart_recognition": p.use_chart_recognition, + } + except Exception: + pass + return {} + + +_DB_CREDS = _load_ocr_creds_from_db() + +API_URL = os.getenv("PADDLEOCR_API_URL") or _DB_CREDS.get("api_url", "") +TOKEN = os.getenv("PADDLEOCR_API_TOKEN") or _DB_CREDS.get("token", "") +MODEL = os.getenv("PADDLEOCR_MODEL") or _DB_CREDS.get("model", "PaddleOCR-VL-1.5") EXAMPLE_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "..", "example_uploads") ) -TEST_IMAGE = os.path.join(EXAMPLE_DIR, "test.jpg") -TEST_PDF = os.path.join(EXAMPLE_DIR, "test4.pdf") +TEST_IMAGE = os.path.join(EXAMPLE_DIR, "notes", "test.jpg") +TEST_PDF = os.path.join(EXAMPLE_DIR, "exams", "test4.pdf") POLL_INTERVAL = 3 POLL_TIMEOUT = 120 # 最长等待秒数 @@ -144,7 +175,7 @@ class TestImageApiConnection: def test_submit_returns_job_id(self, image_job_result): """提交图片任务应返回非空 jobId""" job_id, _ = image_job_result - assert job_id and job_id.startswith("ocrjob-") + assert job_id def test_job_completes_successfully(self, image_job_result): """图片任务应在超时前完成""" @@ -242,7 +273,7 @@ class TestPdfApiConnection: def test_submit_returns_job_id(self, pdf_job_result): """提交 PDF 任务应返回非空 jobId""" job_id, _ = pdf_job_result - assert job_id and job_id.startswith("ocrjob-") + assert job_id def test_job_completes_successfully(self, pdf_job_result): """PDF 任务应在超时前完成""" @@ -295,7 +326,7 @@ def test_parse_image_returns_result(self, tmp_path): """parse_image 应返回包含 layoutParsingResults 的结果""" from src.paddleocr_client import PaddleOCRClient - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) result = client.parse_image(TEST_IMAGE, save_output=True, output_dir=str(tmp_path)) assert "layoutParsingResults" in result @@ -306,7 +337,7 @@ def test_saves_struct_json(self, tmp_path): from src.paddleocr_client import PaddleOCRClient from pathlib import Path - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) client.parse_image(TEST_IMAGE, save_output=True, output_dir=str(tmp_path)) stem = Path(TEST_IMAGE).stem @@ -322,7 +353,7 @@ def test_simplify_ocr_results_compatible(self): from src.paddleocr_client import PaddleOCRClient from src.utils import simplify_ocr_results - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) result = client.parse_image(TEST_IMAGE, save_output=False) simplified = simplify_ocr_results([result]) @@ -342,7 +373,7 @@ def test_parse_pdf_returns_result(self, tmp_path): """parse_pdf 应返回包含 layoutParsingResults 的结果""" from src.paddleocr_client import PaddleOCRClient - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) result = client.parse_pdf(TEST_PDF, save_output=True, output_dir=str(tmp_path)) assert "layoutParsingResults" in result @@ -353,7 +384,7 @@ def test_pdf_simplify_compatible(self): from src.paddleocr_client import PaddleOCRClient from src.utils import simplify_ocr_results - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) result = client.parse_pdf(TEST_PDF, save_output=False) simplified = simplify_ocr_results([result]) @@ -367,7 +398,7 @@ def test_pdf_multipage_index_continuity(self): from src.paddleocr_client import PaddleOCRClient from src.utils import simplify_ocr_results - client = PaddleOCRClient() + client = PaddleOCRClient(**_DB_CREDS) result = client.parse_pdf(TEST_PDF, save_output=False) simplified = simplify_ocr_results([result]) diff --git a/backend/tests/test_question_tools.py b/backend/tests/test_question_tools.py index ff262cc1..f1af1cf5 100644 --- a/backend/tests/test_question_tools.py +++ b/backend/tests/test_question_tools.py @@ -10,7 +10,7 @@ import json import pytest from unittest.mock import patch -from error_correction_agent.tools.question_tools import save_questions, log_issue +from agents.error_correction.tools.question_tools import save_questions, log_issue # ═══════════════════════════════════════════════════════════ @@ -25,7 +25,7 @@ def test_save_new_file(self, tmp_path): out = str(tmp_path / "questions.json") questions = [{"question_id": "1", "content_blocks": []}] - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): result = save_questions.invoke({ "questions": questions, "output_path": out, @@ -41,7 +41,7 @@ def test_append_to_existing(self, tmp_path): q1 = [{"question_id": "1", "content_blocks": []}] q2 = [{"question_id": "2", "content_blocks": []}] - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): save_questions.invoke({"questions": q1, "output_path": out}) save_questions.invoke({"questions": q2, "output_path": out}) @@ -53,7 +53,7 @@ def test_subject_metadata(self, tmp_path): out = str(tmp_path / "questions.json") questions = [{"question_id": "1", "content_blocks": []}] - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): save_questions.invoke({ "questions": questions, "subject": "高中数学", @@ -70,7 +70,7 @@ def test_empty_subject_no_metadata(self, tmp_path): out = str(tmp_path / "questions.json") questions = [{"question_id": "1", "content_blocks": []}] - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): save_questions.invoke({ "questions": questions, "subject": "", @@ -90,7 +90,7 @@ class TestLogIssue: """log_issue 工具测试""" def test_basic_log(self, tmp_path): - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): result = log_issue.invoke({ "issue_type": "unclear_boundary", "description": "第3题和第4题边界不清", @@ -105,7 +105,7 @@ def test_basic_log(self, tmp_path): assert "第3题" in line["description"] def test_with_block_info(self, tmp_path): - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): log_issue.invoke({ "issue_type": "missing_question_number", "description": "缺少题号", @@ -119,7 +119,7 @@ def test_with_block_info(self, tmp_path): def test_append_multiple(self, tmp_path): """多次调用应追加(JSONL 格式)""" - with patch("config.settings.results_dir", tmp_path): + with patch("core.config.settings.results_dir", tmp_path): log_issue.invoke({"issue_type": "a", "description": "issue 1"}) log_issue.invoke({"issue_type": "b", "description": "issue 2"}) diff --git a/backend/tests/test_schemas.py b/backend/tests/test_schemas.py index 178e1d7a..f89b2f27 100644 --- a/backend/tests/test_schemas.py +++ b/backend/tests/test_schemas.py @@ -11,7 +11,7 @@ import pytest from pydantic import ValidationError -from error_correction_agent.schemas import ( +from agents.error_correction.schemas import ( ContentBlock, Question, QuestionSplitResult, diff --git a/backend/tests/test_solve_integration.py b/backend/tests/test_solve_integration.py index 8b533a79..00ab1643 100644 --- a/backend/tests/test_solve_integration.py +++ b/backend/tests/test_solve_integration.py @@ -55,7 +55,7 @@ @pytest.fixture(scope="session") def solve_results(model_provider): """session 级 fixture:只调用一次 API,所有测试共享结果""" - from solve_agent import invoke_solve + from agents.solve import invoke_solve return invoke_solve(SAMPLE_QUESTIONS, provider=model_provider) diff --git a/backend/tests/test_solve_schemas.py b/backend/tests/test_solve_schemas.py index e887dcf8..b843049b 100644 --- a/backend/tests/test_solve_schemas.py +++ b/backend/tests/test_solve_schemas.py @@ -8,7 +8,7 @@ import pytest from pydantic import ValidationError -from solve_agent.schemas import SolveResult, SolveBatchResult +from agents.solve.schemas import SolveResult, SolveBatchResult # ═══════════════════════════════════════════════════════════ diff --git a/backend/tests/test_split_integration.py b/backend/tests/test_split_integration.py index 0e07b037..0c314ca4 100644 --- a/backend/tests/test_split_integration.py +++ b/backend/tests/test_split_integration.py @@ -48,7 +48,7 @@ def ocr_data(): @pytest.fixture(scope="session") def split_result(ocr_data, model_provider): """调用 split_batch 一次,所有测试共享结果(节省 API 调用)""" - from error_correction_agent.tools import split_batch + from agents.error_correction.tools import split_batch result = split_batch.invoke({ "ocr_data": json.dumps(ocr_data, ensure_ascii=False), @@ -79,7 +79,7 @@ def test_returns_non_empty(self, split_result): def test_question_schema(self, split_result): """每道题目应符合 Question schema""" - from error_correction_agent.schemas import Question + from agents.error_correction.schemas import Question for q_data in split_result: q = Question(**q_data) diff --git a/backend/tests/test_utils.py b/backend/tests/test_utils.py index 3c8bd52f..e73a408a 100644 --- a/backend/tests/test_utils.py +++ b/backend/tests/test_utils.py @@ -14,7 +14,7 @@ def mock_env(monkeypatch, tmp_path): """使用临时目录作为 settings.pages_dir""" pages_dir = tmp_path / "pages" - monkeypatch.setattr("config.settings.pages_dir", pages_dir) + monkeypatch.setattr("core.config.settings.pages_dir", pages_dir) return pages_dir diff --git a/backend/tests/test_web_helpers.py b/backend/tests/test_web_helpers.py index 9bdad5fe..1c9ced04 100644 --- a/backend/tests/test_web_helpers.py +++ b/backend/tests/test_web_helpers.py @@ -8,7 +8,8 @@ import os import pytest -from web_app import allowed_file, _safe_join +from routes.upload import allowed_file +from web_app import _safe_join # ═══════════════════════════════════════════════════════════ diff --git a/backend/tests/test_web_routes.py b/backend/tests/test_web_routes.py index b7f1bac4..9e7e775f 100644 --- a/backend/tests/test_web_routes.py +++ b/backend/tests/test_web_routes.py @@ -18,13 +18,16 @@ from sqlalchemy import create_engine, event from sqlalchemy.orm import sessionmaker -from db.models import Base +from db.models import Base, User from db import crud +# 测试用户 ID,与 client fixture 中的 session['user_id'] 一致 +TEST_USER_ID = 1 + @pytest.fixture def test_db(): - """内存数据库 + 建表""" + """内存数据库 + 建表 + 创建测试用户""" engine = create_engine("sqlite:///:memory:", echo=False) @event.listens_for(engine, "connect") @@ -36,6 +39,10 @@ def set_sqlite_pragma(dbapi_connection, connection_record): Base.metadata.create_all(bind=engine) Session = sessionmaker(bind=engine) session = Session() + # 创建测试用户(与 client session 中的 user_id 匹配) + user = User(id=TEST_USER_ID, username="test", email="test@test.com", password_hash="x") + session.add(user) + session.commit() yield session session.close() @@ -54,10 +61,20 @@ def __enter__(self): def __exit__(self, *args): pass - with patch("web_app.SessionLocal", FakeSessionLocal()): + fake = FakeSessionLocal() + with patch("routes.settings.SessionLocal", fake), \ + patch("routes.questions.SessionLocal", fake), \ + patch("routes.stats.SessionLocal", fake), \ + patch("routes.upload.SessionLocal", fake), \ + patch("routes.chat.SessionLocal", fake), \ + patch("routes.auth.SessionLocal", fake): from web_app import app app.config["TESTING"] = True with app.test_client() as c: + with c.session_transaction() as sess: + sess['user_id'] = TEST_USER_ID + sess['username'] = 'test' + sess['session_version'] = 0 yield c @@ -176,7 +193,7 @@ def test_delete_existing(self, client, test_db): save_questions_to_db(test_db, qs, { "original_filename": "test.pdf", "subject": "数学", - }) + }, user_id=TEST_USER_ID) # 查询刚插入的题目 ID from db.models import Question @@ -230,7 +247,7 @@ def test_with_data(self, client, test_db): save_questions_to_db(test_db, qs, { "original_filename": "test.pdf", "subject": "数学", - }) + }, user_id=TEST_USER_ID) resp = client.get("/api/error-bank") data = resp.get_json() assert data["total"] == 1 @@ -260,7 +277,7 @@ def test_with_data(self, client, test_db): "question_type": "选择题", "content_blocks": [{"block_type": "text", "content": "t"}], "has_formula": False, "has_image": False, - }], {"original_filename": "a.pdf", "subject": "高中数学"}) + }], {"original_filename": "a.pdf", "subject": "高中数学"}, user_id=TEST_USER_ID) resp = client.get("/api/subjects") assert "高中数学" in resp.get_json()["subjects"] @@ -300,7 +317,7 @@ def test_save_answer(self, client, test_db): "question_type": "选择题", "content_blocks": [{"block_type": "text", "content": "答案测试"}], "has_formula": False, "has_image": False, - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) from db.models import Question q = test_db.query(Question).first() resp = client.patch(f"/api/question/{q.id}/answer", json={"user_answer": "选B"}) @@ -342,7 +359,7 @@ def test_invalid_status(self, client, test_db): "question_type": "选择题", "content_blocks": [{"block_type": "text", "content": "状态测试"}], "has_formula": False, "has_image": False, - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) from db.models import Question q = test_db.query(Question).first() resp = client.patch(f"/api/question/{q.id}/review-status", json={"review_status": "无效"}) @@ -359,7 +376,7 @@ def test_update_status(self, client, test_db): "question_type": "选择题", "content_blocks": [{"block_type": "text", "content": "复习状态测试"}], "has_formula": False, "has_image": False, - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) from db.models import Question q = test_db.query(Question).first() resp = client.patch(f"/api/question/{q.id}/review-status", json={"review_status": "已掌握"}) @@ -396,7 +413,7 @@ def test_with_data(self, client, test_db): "content_blocks": [{"block_type": "text", "content": "统计测试"}], "has_formula": False, "has_image": False, "knowledge_tags": ["导数"], - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) resp = client.get("/api/dashboard-stats") data = resp.get_json() assert data["total_questions"] == 1 @@ -413,14 +430,14 @@ def test_subject_filter(self, client, test_db): "content_blocks": [{"block_type": "text", "content": "数学题"}], "has_formula": False, "has_image": False, "knowledge_tags": ["函数"], - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) save_questions_to_db(test_db, [{ "question_id": "2", "question_type": "选择题", "content_blocks": [{"block_type": "text", "content": "英语题"}], "has_formula": False, "has_image": False, "knowledge_tags": ["语法"], - }], {"original_filename": "b.pdf", "subject": "英语"}) + }], {"original_filename": "b.pdf", "subject": "英语"}, user_id=TEST_USER_ID) resp = client.get("/api/dashboard-stats") data = resp.get_json() assert data["total_questions"] == 2 @@ -451,7 +468,7 @@ def test_filter_by_review_status(self, client, test_db): "content_blocks": [{"block_type": "text", "content": "已掌握题"}], "has_formula": False, "has_image": False, }, - ], {"original_filename": "a.pdf", "subject": "数学"}) + ], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) from db.models import Question qs = test_db.query(Question).all() update_review_status(test_db, qs[1].id, "已掌握") @@ -492,7 +509,7 @@ def test_success(self, client, test_db): "content_blocks": [{"block_type": "text", "content": "AI分析测试"}], "has_formula": False, "has_image": False, "knowledge_tags": ["导数"], - }], {"original_filename": "a.pdf", "subject": "数学"}) + }], {"original_filename": "a.pdf", "subject": "数学"}, user_id=TEST_USER_ID) from db.models import Question q = test_db.query(Question).first() resp = client.post("/api/ai-analysis", json={"question_ids": [q.id]}) diff --git a/backend/tests/test_workflow_helpers.py b/backend/tests/test_workflow_helpers.py index 57b648f1..27b948ed 100644 --- a/backend/tests/test_workflow_helpers.py +++ b/backend/tests/test_workflow_helpers.py @@ -519,7 +519,7 @@ class TestIdentifySubject: @pytest.fixture(autouse=True) def _mock_llm(self): with patch( - "error_correction_agent.agent.detect_subject_via_llm", + "agents.error_correction.agent.detect_subject_via_llm", return_value="", ) as mock: self.mock_llm = mock @@ -655,7 +655,7 @@ def _make_ocr(self, text: str) -> list: }] }] - @patch("error_correction_agent.agent.detect_subject_via_llm", return_value="高中数学") + @patch("agents.error_correction.agent.detect_subject_via_llm", return_value="高中数学") def test_llm_success(self, mock_llm): """LLM 返回有效科目时直接采用""" ocr = self._make_ocr("普通内容无关键词") @@ -663,14 +663,14 @@ def test_llm_success(self, mock_llm): assert result == "高中数学" mock_llm.assert_called_once() - @patch("error_correction_agent.agent.detect_subject_via_llm", return_value="初中地理") + @patch("agents.error_correction.agent.detect_subject_via_llm", return_value="初中地理") def test_llm_returns_new_subject(self, mock_llm): """LLM 返回不在 db_subjects 中的新科目也应采用""" ocr = self._make_ocr("普通内容") result = _identify_subject(ocr, ["高中数学"]) assert result == "初中地理" - @patch("error_correction_agent.agent.detect_subject_via_llm", return_value="") + @patch("agents.error_correction.agent.detect_subject_via_llm", return_value="") def test_llm_empty_fallback_to_keyword(self, mock_llm): """LLM 返回空时应 fallback 到关键词匹配""" ocr = self._make_ocr("数学试卷") @@ -678,7 +678,7 @@ def test_llm_empty_fallback_to_keyword(self, mock_llm): assert result == "高中数学" @patch( - "error_correction_agent.agent.detect_subject_via_llm", + "agents.error_correction.agent.detect_subject_via_llm", side_effect=Exception("API error"), ) def test_llm_exception_fallback(self, mock_llm): @@ -687,7 +687,7 @@ def test_llm_exception_fallback(self, mock_llm): result = _identify_subject(ocr, []) assert result == "高中物理" - @patch("error_correction_agent.agent.detect_subject_via_llm", return_value="高中物理") + @patch("agents.error_correction.agent.detect_subject_via_llm", return_value="高中物理") def test_llm_receives_provider(self, mock_llm): """model_provider 应正确传递到 LLM 函数""" ocr = self._make_ocr("普通内容") diff --git a/backend/web_app.py b/backend/web_app.py index 8411ea0c..6e576aba 100644 --- a/backend/web_app.py +++ b/backend/web_app.py @@ -1,56 +1,66 @@ """ -错题本生成系统 - Web应用 -提供前端界面用于执行工作流 +错题本生成系统 - Web应用(纯 API 服务) + +职责: + - 创建 Flask 应用实例,配置全局参数 + - 注册所有 Blueprint 路由(routes/ 目录) + - 提供全局错误处理和登录鉴权中间件 + - 提供 OCR 图片、下载文件、擦除结果等静态资源接口 + +前端由 Vite dev server 独立运行(localhost:5173), +通过代理将 /api 等请求转发到本服务(localhost:5001)。 """ import os -import json -import uuid +import sys import logging -import threading -import mimetypes -from datetime import datetime -from pathlib import PurePath -from typing import Optional -import requests as http_requests +# 无论从项目根目录执行 `python backend/web_app.py` 还是在 `backend` 下执行 `python web_app.py`, +# 都把 backend 目录加入 sys.path,保证 `core`、`routes`、`db` 等包解析一致。 +_BACKEND_ROOT = os.path.dirname(os.path.abspath(__file__)) +if _BACKEND_ROOT not in sys.path: + sys.path.insert(0, _BACKEND_ROOT) -# Windows 注册表可能将 .js 映射为 text/plain,导致浏览器拒绝加载 ES module -mimetypes.add_type('application/javascript', '.js') -from flask import Flask, request, jsonify, send_file, send_from_directory, redirect, session +from flask import Flask, request, jsonify, send_file, session +from flask_cors import CORS from dotenv import load_dotenv -from werkzeug.security import generate_password_hash, check_password_hash -from src.workflow import build_workflow -from src.utils import export_wrongbook as export_wrongbook_md -from config import settings +from core.config import settings from db import init_db, SessionLocal from db import crud -from db.models import Question, UploadBatch, KnowledgeTag +from routes import register_routes -# 加载环境变量 -load_dotenv() +# 加载 backend/.env(无论从哪个目录启动都指向同一文件) +load_dotenv(os.path.join(_BACKEND_ROOT, ".env")) +# 模块级日志记录器,日志名称为 'web_app' logger = logging.getLogger(__name__) +# ============================================================ +# Flask 应用初始化 +# ============================================================ + app = Flask(__name__) + +# 会话密钥:用于加密 Flask session cookie,生产环境必须修改 app.secret_key = os.getenv('SECRET_KEY', 'dev-secret-change-in-production') -# 配置(统一从 config.py 导入) +# 跨域支持:前端 dev server (5173) 和后端 (5001) 端口不同,需要 CORS +# supports_credentials=True 允许携带 cookie(登录态依赖 session cookie) +CORS(app, supports_credentials=True) + +# 文件上传配置 app.config['UPLOAD_FOLDER'] = settings.upload_dir -app.config['MAX_CONTENT_LENGTH'] = settings.max_file_size_mb * 1024 * 1024 +app.config['MAX_CONTENT_LENGTH'] = settings.max_file_size_mb * 1024 * 1024 # MB → 字节 -def _safe_join(base_dir: str, rel_path: str) -> str | None: - base = os.path.abspath(base_dir) - target = os.path.abspath(os.path.join(base, rel_path)) - if os.path.normcase(target).startswith(os.path.normcase(base + os.sep)): - return target - return None +# ============================================================ +# 全局错误处理 +# ============================================================ @app.errorhandler(413) def request_entity_too_large(error): - """文件大小超出Flask限制""" + """上传文件超出 MAX_CONTENT_LENGTH 限制时触发""" return jsonify({ 'success': False, 'error': f'文件大小超出限制,最大允许 {settings.max_file_size_mb}MB' @@ -59,7 +69,7 @@ def request_entity_too_large(error): @app.errorhandler(404) def not_found(error): - """页面未找到""" + """请求的路由不存在""" return jsonify({ 'success': False, 'error': '请求的资源不存在' @@ -68,714 +78,112 @@ def not_found(error): @app.errorhandler(500) def internal_error(error): - """服务器内部错误""" + """未捕获的服务端异常""" return jsonify({ 'success': False, 'error': '服务器内部错误,请稍后重试' }), 500 -# 全局工作流图(带 MemorySaver,通过 thread_id 管理会话状态) -workflow_graph = build_workflow() -current_thread_id = None -session_files = {} -session_file_order = [] -cancelled_file_keys = set() -session_lock = threading.Lock() - - -def allowed_file(filename): - """检查文件扩展名是否允许""" - return PurePath(filename).suffix.lower().lstrip('.') in settings.allowed_extensions - - -def _read_split_subject() -> Optional[str]: - """从 split_metadata.json 读取学科信息""" - meta_path = os.path.join(str(settings.results_dir), "split_metadata.json") - if os.path.exists(meta_path): - with open(meta_path, 'r', encoding='utf-8') as f: - return json.load(f).get("subject") - return None - - -def _serialize_split_record(r) -> dict: - """将 SplitRecord ORM 对象序列化为前端 JSON 格式""" - return { - "id": r.id, - "subject": r.subject, - "model_provider": r.model_provider, - "file_names": json.loads(r.file_names_json) if r.file_names_json else [], - "question_count": r.question_count, - "created_at": r.created_at.isoformat() if r.created_at else None, - } - - -def _serialize_question(q: Question) -> dict: - """将 Question ORM 对象序列化为前端 JSON 格式""" - subject = None - if q.batch: - subject = q.batch.subject - knowledge_tags = [] - if q.tags: - for mapping in q.tags: - if mapping.tag: - knowledge_tags.append(mapping.tag.tag_name) - - return { - 'id': q.id, - 'question_type': q.question_type, - 'content_json': json.loads(q.content_json) if q.content_json else [], - 'options_json': json.loads(q.options_json) if q.options_json else None, - 'has_formula': q.has_formula, - 'has_image': q.has_image, - 'needs_correction': q.needs_correction, - 'answer': q.answer, - 'subject': subject, - 'knowledge_tags': knowledge_tags, - 'created_at': q.created_at.isoformat() if q.created_at else None, - } - - -def _serialize_chat_session(session) -> dict: - """将 ChatSession ORM 对象序列化为前端 JSON""" - return { - 'id': session.id, - 'question_id': session.question_id, - 'created_at': session.created_at.isoformat() if session.created_at else None, - 'updated_at': session.updated_at.isoformat() if session.updated_at else None, - } - - -def _serialize_question_detail(q: Question) -> dict: - """将 Question ORM 对象序列化为详情 JSON(含科目、标签、答案等)""" - base = _serialize_question(q) - # subject / knowledge_tags already set by _serialize_question - base['original_filename'] = q.batch.original_filename if q.batch else None - base['user_answer'] = q.user_answer - base['updated_at'] = q.updated_at.isoformat() if q.updated_at else None - base['review_status'] = q.review_status or '待复习' - base['image_refs_json'] = json.loads(q.image_refs_json) if q.image_refs_json else None - return base - - # ============================================================ -# 前端托管(生产模式:直接返回 Vite 构建产物) -# ============================================================ -FRONTEND_DIST = os.path.join(settings.project_root, 'frontend', 'dist') - - - - -# ============================================================ -# 认证工具 +# 全局中间件 # ============================================================ @app.before_request def require_login(): - """所有 /api/ 路由(除 /api/auth/ 和 /api/status)要求登录""" + """登录鉴权:所有 /api/ 路由默认要求登录 + + 豁免列表: + - /api/auth/* — 登录、注册、获取当前用户等认证接口 + - /api/status — 系统状态查询(前端初始化时需要) + """ if request.path.startswith('/api/'): if request.path.startswith('/api/auth/') or request.path == '/api/status': return None if 'user_id' not in session: return jsonify({'error': '请先登录', 'code': 'UNAUTHORIZED'}), 401 + # 密码重置后失效旧 session:仅在写操作时查 DB 比对 session_version, + # GET 请求无需每次查库,降低高频只读接口的数据库压力 + if request.method != 'GET': + user_id = session['user_id'] + sess_ver = session.get('session_version') + with SessionLocal() as db: + user = crud.get_user_by_id(db, user_id) + if not user: + session.clear() + return jsonify({'error': '用户不存在', 'code': 'UNAUTHORIZED'}), 401 + db_ver = user.session_version or 0 + if sess_ver != db_ver: + session.clear() + return jsonify({'error': '登录已失效,请重新登录', 'code': 'SESSION_EXPIRED'}), 401 return None -@app.route('/api/auth/register', methods=['POST']) -def auth_register(): - """用户注册""" - data = request.get_json() or {} - email = (data.get('email') or '').strip().lower() - username = (data.get('username') or '').strip() - password = data.get('password') or '' - - if not email or '@' not in email: - return jsonify({'error': '邮箱格式不正确'}), 400 - if not username: - return jsonify({'error': '用户名不能为空'}), 400 - if len(password) < 6: - return jsonify({'error': '密码至少 6 位'}), 400 - - with SessionLocal() as db: - if crud.get_user_by_email(db, email): - return jsonify({'error': '该邮箱已注册'}), 409 - pwd_hash = generate_password_hash(password) - user = crud.create_user(db, email=email, password_hash=pwd_hash, username=username) - session['user_id'] = user.id - session['username'] = user.username - return jsonify({'user': {'id': user.id, 'email': user.email, 'username': user.username, 'is_admin': user.is_admin}}), 201 - - -@app.route('/api/auth/login', methods=['POST']) -def auth_login(): - """用户登录(支持邮箱或用户名)""" - data = request.get_json() or {} - identifier = (data.get('email') or data.get('identifier') or '').strip() - password = data.get('password') or '' - - if not identifier: - return jsonify({'error': '请输入邮箱或用户名'}), 400 - - with SessionLocal() as db: - user = crud.get_user_by_login(db, identifier) - if not user or not check_password_hash(user.password_hash, password): - return jsonify({'error': '账号或密码错误'}), 401 - session['user_id'] = user.id - session['username'] = user.username - return jsonify({'user': {'id': user.id, 'email': user.email, 'username': user.username, 'is_admin': user.is_admin}}) - - -@app.route('/api/auth/logout', methods=['POST']) -def auth_logout(): - """退出登录""" - session.clear() - return jsonify({'ok': True}) - - -@app.route('/api/auth/me', methods=['GET']) -def auth_me(): - """获取当前登录用户""" - user_id = session.get('user_id') - if not user_id: - return jsonify({'error': '未登录', 'code': 'UNAUTHORIZED'}), 401 - with SessionLocal() as db: - user = crud.get_user_by_id(db, user_id) - if not user: - session.clear() - return jsonify({'error': '用户不存在', 'code': 'UNAUTHORIZED'}), 401 - return jsonify({'user': {'id': user.id, 'email': user.email, 'username': user.username, 'is_admin': user.is_admin}}) - - -@app.route('/') -def index(): - """主页 - 返回 Vue SPA(落地页由前端路由 / 渲染)""" - return send_from_directory(FRONTEND_DIST, 'app.html') - - -@app.route('/app.html') -def app_page_redirect(): - """旧路径重定向到规范 URL""" - return redirect('/app', code=301) - - -@app.route('/app') -@app.route('/app/') -def app_page(subpath=''): - """工作台及子路由 - 返回 Vue SPA""" - return send_from_directory(FRONTEND_DIST, 'app.html') - - -@app.route('/auth') -def auth_page(): - """登录/注册页 - 返回 Vue SPA""" - return send_from_directory(FRONTEND_DIST, 'app.html') - - -@app.route('/static/vue/') -def serve_vue_dist(filename): - """提供 Vue 前端构建产物""" - return send_from_directory(FRONTEND_DIST, filename) - - # ============================================================ -# 遗留独立页面 +# 注册 Blueprint 路由 # ============================================================ +# 各 Blueprint 定义在 routes/ 目录下: +# - auth.py → /api/auth/* 用户认证 +# - upload.py → /api/* 文件上传、分割、导出 +# - questions.py → /api/* 题目 CRUD、错题库、搜索 +# - chat.py → /api/* AI 对话 +# - stats.py → /api/* 统计分析 +# - settings.py → /api/* 系统配置、模型管理 - -@app.route('/record') -def record_page(): - """错题本记录页面""" - record_file = os.path.join(settings.project_root, 'record.html') - if os.path.exists(record_file): - return send_from_directory(settings.project_root, 'record.html') - return "记录页文件不存在", 404 +register_routes(app) # ============================================================ -# API 接口 +# 静态资源服务 # ============================================================ +# 以下路由提供后端生成的文件资源,前端通过 Vite 代理访问: +# /download/* — 导出的 Markdown 错题本文件 +# /images/* — PaddleOCR 解析出的图片(存储在 struct_dir/imgs/) +# /erased/* — EnsExam 擦除手写字迹后的图片 +def _safe_join(base_dir: str, rel_path: str) -> str | None: + """安全路径拼接,防止目录遍历攻击(如 ../../etc/passwd) -@app.route('/api/upload', methods=['POST']) -def upload_file(): - """处理文件上传(支持多文件)。 - - 这里只负责把原始文件保存到 uploads 并登记到会话中; - 标准化(PDF/图片 → 图片列表) + OCR + 分割,会在 /api/split 里由用户点击“开始分割”后统一触发。 - - Returns: - JSON响应,包含上传结果 - """ - # 支持多文件:前端用 'files' 字段发送,兼容单文件 'file' 字段 - files = request.files.getlist('files') - if not files: - files = request.files.getlist('file') - if not files or all(f.filename == '' for f in files): - return jsonify({'error': '没有上传文件'}), 400 - - # 校验每个文件 - for file in files: - if file.filename == '': - continue - - if not allowed_file(file.filename): - return jsonify({ - 'error': f'不支持的文件格式: {file.filename}。支持: {", ".join(settings.allowed_extensions)}' - }), 400 - - file.seek(0, 2) - file_size = file.tell() - file.seek(0) - file_size_mb = file_size / (1024 * 1024) - - if file_size_mb > settings.max_file_size_mb: - return jsonify({ - 'error': f'{file.filename} 大小为 {file_size_mb:.1f}MB,超出最大限制 {settings.max_file_size_mb}MB' - }), 400 - - if file_size == 0: - return jsonify({ - 'error': f'{file.filename} 为空文件,请重新选择' - }), 400 - - try: - global current_thread_id, session_files, session_file_order - - file_keys = request.form.getlist('file_key') - if not file_keys: - file_keys = request.form.getlist('file_keys') - - prepared = [] - for i, file in enumerate(files): - if file.filename == '': - continue - fk = file_keys[i] if i < len(file_keys) and file_keys[i] else None - prepared.append((fk, file)) - - if not prepared: - return jsonify({'error': '没有上传文件'}), 400 - - results_out = [] - for fk, file in prepared: - file_key = fk or f"{uuid.uuid4().hex}" - - original_ext = os.path.splitext(file.filename)[1].lower().lstrip('.') - filename = f"{uuid.uuid4().hex}.{original_ext}" - filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) - file.save(filepath) - - with session_lock: - cancelled = file_key in cancelled_file_keys - if cancelled: - cancelled_file_keys.discard(file_key) - - if cancelled: - try: - os.remove(filepath) - except FileNotFoundError: - pass - continue - - with session_lock: - if current_thread_id is not None: - current_thread_id = None - session_files = {} - session_file_order = [] - - session_files[file_key] = { - "filename": file.filename, - "filepath": filepath, - } - if file_key not in session_file_order: - session_file_order.append(file_key) - - results_out.append({ - "file_key": file_key, - "filename": file.filename, - }) - - return jsonify({ - 'success': True, - 'message': '上传成功', - 'result': { - 'file_count': len(results_out), - 'files': results_out, - } - }) - - except FileNotFoundError: - return jsonify({ - 'success': False, - 'error': '文件保存失败,请重新上传' - }), 500 - except Exception as e: - logger.exception("文件处理失败") - return jsonify({ - 'success': False, - 'error': '文件处理失败,请稍后重试' - }), 500 - - -@app.route('/api/cancel_file', methods=['POST']) -def cancel_file(): - try: - global current_thread_id, session_files, session_file_order - - data = request.get_json(silent=True) or {} - file_key = data.get('file_key') - if not file_key: - return jsonify({ - 'success': False, - 'error': '缺少 file_key' - }), 400 - - if current_thread_id is not None: - return jsonify({ - 'success': False, - 'error': '已开始分割,无法撤销单个文件;请重置后重新上传' - }), 400 - - filepath = None - existed = False - with session_lock: - cancelled_file_keys.add(file_key) - - existed = file_key in session_files - v = session_files.pop(file_key, None) or {} - filepath = v.get('filepath') - if file_key in session_file_order: - session_file_order.remove(file_key) - - cancelled_file_keys.discard(file_key) - - if filepath: - try: - os.remove(filepath) - except FileNotFoundError: - pass - - return jsonify({ - 'success': True, - 'message': '已撤销该文件' if existed else '已标记撤销该文件', - }) - - except Exception as e: - logger.exception("撤销文件失败") - return jsonify({ - 'success': False, - 'error': '撤销失败,请稍后重试' - }), 500 - - -@app.route('/api/split', methods=['POST']) -def split_questions(): - """开始执行标准化 + OCR + 分割。 - - 用户点击前端“开始分割题目”后调用该接口: - - 标准化输入(PDF/图片 → 图片列表) - - 触发 Agent/OCR 并分割题目 - - Returns: - JSON响应,包含分割后的题目 - """ - try: - global workflow_graph, current_thread_id, session_files, session_file_order - - # 读取请求体参数(模型供应商 + 模型名称) - data = request.get_json(silent=True) or {} - model_provider = data.get("model_provider", "openai") - model_name = data.get("model_name") # 可选,None 时使用 provider 默认模型 - if not settings.is_valid_provider(model_provider): - return jsonify({ - 'success': False, - 'error': f'不支持的模型供应商: {model_provider}' - }), 400 - - # 从数据库加载用户的 LLM + OCR 凭据 - user_id = session.get('user_id') - ocr_credentials = {} - if user_id: - settings.load_providers_from_db(user_id) - with SessionLocal() as db: - ocr_provider = crud.get_active_provider(db, user_id, 'paddleocr') - if ocr_provider: - ocr_credentials = { - "api_url": ocr_provider.base_url, - "token": ocr_provider.api_key, - "model": ocr_provider.model_name, - "use_doc_orientation": ocr_provider.use_doc_orientation, - "use_doc_unwarping": ocr_provider.use_doc_unwarping, - "use_chart_recognition": ocr_provider.use_chart_recognition, - } - - with session_lock: - keys = list(session_file_order) - file_paths = [] - for k in keys: - v = session_files.get(k) or {} - fp = v.get('filepath') - if fp: - file_paths.append(fp) - - if not file_paths: - return jsonify({ - 'success': False, - 'error': '请先上传文件' - }), 400 - - # 擦除手写字迹(EnsExam 已接入且前端未关闭擦除开关时执行) - erase = data.get("erase", True) - ensexam_configured = settings.model_path.exists() - if ensexam_configured and erase: - try: - from models.inference import InferenceEngine - engine = InferenceEngine() - erased_paths = [] - for fp in file_paths: - # 如果是 PDF 转换为图片的临时路径,或者是直接上传的图片 - with open(fp, 'rb') as f: - img_bytes = f.read() - result_img = engine.run(img_bytes) - - # 生成擦除后的文件名,保存在 erased_dir - erased_name = f"auto_{uuid.uuid4().hex[:8]}_{os.path.basename(fp)}" - if not erased_name.lower().endswith(('.png', '.jpg', '.jpeg')): - erased_name += '.png' - - erased_path = settings.erased_dir / erased_name - result_img.save(str(erased_path), format='PNG') - erased_paths.append(str(erased_path)) - - file_paths = erased_paths - logger.info("EnsExam 已接入,自动擦除 %d 张图片的手写字迹", len(erased_paths)) - except Exception: - logger.exception("自动擦除手写字迹失败,使用原图继续流程") - - current_thread_id = str(uuid.uuid4()) - config = {"configurable": {"thread_id": current_thread_id}} - - initial_state = { - "file_paths": file_paths, - "model_provider": model_provider, - "model_name": model_name, - "ocr_credentials": ocr_credentials, - } - workflow_graph.invoke(initial_state, config=config) - state = workflow_graph.invoke(None, config=config) - - questions = state.get('questions', []) - warnings = state.get('warnings', []) - - # 自动保存分割记录 - try: - subject = _read_split_subject() - - with session_lock: - file_names = [ - session_files.get(k, {}).get("filename", "未知") - for k in session_file_order - ] - - with SessionLocal() as db: - crud.save_split_record(db, subject, model_provider, file_names, questions, user_id=session.get('user_id')) - except Exception: - logger.warning("保存分割记录失败,不影响主流程", exc_info=True) - - return jsonify({ - 'success': True, - 'message': f'成功分割 {len(questions)} 道题目', - 'questions': questions, - 'warnings': warnings, - }) - - except Exception as e: - logger.exception("题目分割失败") - return jsonify({ - 'success': False, - 'error': '题目分割失败,请稍后重试' - }), 500 - - -@app.route('/api/split-records', methods=['GET']) -def get_split_records(): - """获取最近 N 次分割历史记录,limit 由前端通过查询参数指定""" - try: - limit = request.args.get('limit', 10, type=int) - limit = max(1, min(limit, crud.MAX_SPLIT_RECORDS)) # 上限与保留条数一致 - - with SessionLocal() as db: - records = crud.get_recent_split_records(db, limit, user_id=session.get('user_id')) - result = [_serialize_split_record(r) for r in records] - - return jsonify({"success": True, "records": result}) - - except Exception as e: - logger.exception("获取分割记录失败") - return jsonify({"success": False, "error": "获取分割记录失败"}), 500 - - -@app.route('/api/split-records/', methods=['GET']) -def get_split_record_detail(record_id): - """获取单条分割记录的完整数据(含 questions)""" - try: - with SessionLocal() as db: - record = crud.get_split_record_by_id(db, record_id) - if not record: - return jsonify({"success": False, "error": "记录不存在"}), 404 - - result = _serialize_split_record(record) - result["questions"] = json.loads(record.questions_json) if record.questions_json else [] - - return jsonify({"success": True, "record": result}) - - except Exception as e: - logger.exception("获取分割记录详情失败") - return jsonify({"success": False, "error": "获取分割记录详情失败"}), 500 - - -@app.route('/api/export', methods=['POST']) -def export_wrongbook(): - """ - 注入选中题目 ID 并恢复图执行导出 - - 图执行: export → END - - Returns: - JSON响应,包含导出文件路径 - """ - try: - global current_thread_id, session_files, session_file_order - - data = request.get_json(silent=True) or {} - selected_ids = data.get('selected_ids', []) - - if not isinstance(selected_ids, list): - return jsonify({ - 'success': False, - 'error': 'selected_ids 必须为列表' - }), 400 - - if not selected_ids: - return jsonify({ - 'success': False, - 'error': '未选择任何题目' - }), 400 - - # 检查是否已分割(通过 questions.json 存在性判断,不依赖内存中的 current_thread_id) - results_dir = settings.results_dir - questions_file = os.path.join(results_dir, "questions.json") - if not os.path.exists(questions_file): - return jsonify({ - 'success': False, - 'error': '请先分割题目' - }), 400 - - with open(questions_file, 'r', encoding='utf-8') as f: - questions = json.load(f) - - output_path = export_wrongbook_md( - questions, - selected_ids, - ) - - return jsonify({ - 'success': True, - 'message': '错题本导出成功', - 'output_path': output_path - }) - - except Exception as e: - logger.exception("导出失败") - return jsonify({ - 'success': False, - 'error': '导出失败,请稍后重试' - }), 500 - - -@app.route('/api/questions', methods=['GET']) -def get_questions(): - """ - 获取已分割的题目列表 - - Returns: - JSON响应,包含题目列表 + 将 rel_path 拼接到 base_dir 后,检查结果路径是否仍在 base_dir 内。 + 如果路径跳出了 base_dir,返回 None。 """ - try: - results_dir = settings.results_dir - questions_file = os.path.join(results_dir, "questions.json") - - if not os.path.exists(questions_file): - return jsonify({ - 'success': True, - 'questions': [], - 'message': '暂无题目数据' - }) - - with open(questions_file, 'r', encoding='utf-8') as f: - questions = json.load(f) - - return jsonify({ - 'success': True, - 'questions': questions - }) - - except json.JSONDecodeError: - return jsonify({ - 'success': False, - 'error': '题目数据文件格式错误,请重新分割题目' - }), 500 - except Exception as e: - logger.exception("获取题目列表失败") - return jsonify({ - 'success': False, - 'error': '获取题目列表失败,请稍后重试' - }), 500 - - -@app.route('/preview') -def preview(): - """显示预览页面""" - results_dir = settings.results_dir - preview_file = os.path.join(results_dir, "preview.html") - - if os.path.exists(preview_file): - with open(preview_file, 'r', encoding='utf-8') as f: - content = f.read() - return content - else: - return "预览文件不存在,请先分割题目", 404 + base = os.path.abspath(base_dir) + target = os.path.abspath(os.path.join(base, rel_path)) + if os.path.normcase(target).startswith(os.path.normcase(base + os.sep)): + return target + return None -# ============================================================ -# 资源服务 -# ============================================================ +@app.route('/uploads/') +def serve_upload(filename): + """提供用户上传的原始文件(笔记图片等)""" + file_path = _safe_join(str(settings.upload_dir), filename) + if not file_path or not os.path.exists(file_path): + return jsonify({'success': False, 'error': '文件不存在'}), 404 + return send_file(file_path) @app.route('/download/') def download_file(filename): - """下载结果文件""" - results_dir = settings.results_dir - file_path = _safe_join(results_dir, filename) - if not file_path: - return jsonify({ - 'success': False, - 'error': '非法文件路径' - }), 400 + """下载结果文件(如导出的 Markdown 错题本) + 禁用浏览器缓存,确保每次下载都是最新版本。 + """ + file_path = _safe_join(settings.results_dir, filename) + if not file_path: + return jsonify({'success': False, 'error': '非法文件路径'}), 400 if not os.path.exists(file_path): - return jsonify({ - 'success': False, - 'error': '文件不存在' - }), 404 + return jsonify({'success': False, 'error': '文件不存在'}), 404 resp = send_file( file_path, - as_attachment=True, - download_name=os.path.basename(filename), + as_attachment=True, # 触发浏览器下载而非预览 + download_name=os.path.basename(filename), # 下载时显示的文件名 conditional=False, etag=False, max_age=0, ) + # 强制禁用缓存,避免浏览器返回旧文件 resp.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0' resp.headers['Pragma'] = 'no-cache' resp.headers['Expires'] = '0' @@ -784,7 +192,11 @@ def download_file(filename): @app.route('/images/') def serve_image(filename): - """提供 OCR 解析出的图片资源""" + """提供 PaddleOCR 解析出的图片资源 + + OCR 处理后的结构化图片存储在 struct_dir/imgs/ 目录下, + 前端题目卡片中的图片通过此接口加载。 + """ base = os.path.join(settings.struct_dir, "imgs") file_path = _safe_join(base, filename) if not file_path or not os.path.exists(file_path): @@ -794,1108 +206,39 @@ def serve_image(filename): @app.route('/erased/') def serve_erased_image(filename): - """提供擦除结果图片""" + """提供 EnsExam 擦除手写字迹后的图片 + + 用户上传试卷后,EnsExam 模型会擦除手写笔迹, + 还原干净的题目底图,结果保存在 erased_dir。 + """ file_path = _safe_join(str(settings.erased_dir), filename) if not file_path or not os.path.exists(file_path): return jsonify({'success': False, 'error': '图片不存在'}), 404 return send_file(file_path) -@app.route('/api/models/erase', methods=['POST']) -def erase_text(): - """文字擦除接口 - - 使用 GAN 模型将试卷图片中的手写笔迹擦除,还原干净的题目底图。 - - Request: - multipart/form-data,字段 file:图片文件(JPEG/PNG/BMP 等) - - Response: - {"success": true, "result_url": "/erased/"} - """ - if 'file' not in request.files: - return jsonify({'success': False, 'error': '缺少 file 字段'}), 400 - - file = request.files['file'] - if not file or not file.filename: - return jsonify({'success': False, 'error': '文件为空'}), 400 - - ext = os.path.splitext(file.filename)[1].lower() or '.png' - allowed = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.webp'} - if ext not in allowed: - return jsonify({'success': False, 'error': f'不支持的图片格式: {ext}'}), 400 - - try: - image_bytes = file.read() - except Exception: - return jsonify({'success': False, 'error': '读取文件失败'}), 400 - - try: - from models.inference import InferenceEngine - - result_img = InferenceEngine().run(image_bytes) - - filename = uuid.uuid4().hex + '.png' - save_path = settings.erased_dir / filename - result_img.save(save_path, format='PNG') - - return jsonify({'success': True, 'result_url': f'/erased/{filename}'}) - - except FileNotFoundError as e: - logger.error("模型权重缺失: %s", e) - return jsonify({'success': False, 'error': str(e)}), 503 - except Exception: - logger.exception("文字擦除失败") - return jsonify({'success': False, 'error': '擦除处理失败,请稍后重试'}), 500 - - -@app.route('/api/status', methods=['GET']) -def get_status(): - """ - 获取系统状态 - - Returns: - JSON响应,包含系统配置和状态 - """ - try: - user_id = session.get('user_id') - - # 检查 EnsExam 模型权重是否存在 - ensexam_configured = settings.model_path.exists() - - if user_id: - # 已登录:从数据库读取用户配置 - with SessionLocal() as db: - paddle_provider = crud.get_active_provider(db, user_id, 'paddleocr') - paddleocr_configured = bool(paddle_provider and paddle_provider.api_key and paddle_provider.base_url) - - # 构建用户级可用模型列表 - available_models = [] - for category, label in [('openai', 'OpenAI'), ('anthropic', 'Anthropic')]: - provider = crud.get_active_provider(db, user_id, category) - if provider and provider.api_key: - available_models.append({ - 'value': category, - 'label': provider.name or label, - 'configured': True, - 'status': '配置成功', - 'default_model': provider.model_name or '', - 'models': [provider.model_name] if provider.model_name else [], - }) - else: - available_models.append({ - 'value': category, - 'label': label, - 'configured': False, - 'status': '未配置', - 'default_model': '', - 'models': [], - }) - else: - # 未登录:返回空状态 - paddleocr_configured = False - available_models = [] - - status = { - 'paddleocr_configured': paddleocr_configured, - 'ensexam_configured': ensexam_configured, - 'available_models': available_models, - 'langsmith_enabled': os.getenv('LANGSMITH_TRACING', 'false').lower() == 'true', - 'output_dirs': { - 'pages': str(settings.pages_dir), - 'struct': str(settings.struct_dir), - 'results': str(settings.results_dir), - } - } - - return jsonify({ - 'success': True, - 'status': status - }) - - except Exception as e: - logger.exception("获取系统状态失败") - return jsonify({ - 'success': False, - 'error': '获取系统状态失败,请稍后重试' - }), 500 - - -@app.route('/api/config', methods=['GET']) -def get_config(): - """获取当前用户的 provider 配置""" - try: - user_id = session.get('user_id') - if not user_id: - return jsonify({'success': False, 'error': '请先登录'}), 401 - with SessionLocal() as db: - config = crud.get_user_providers(db, user_id) - return jsonify({'success': True, 'config': config}) - except Exception as e: - logger.exception("获取配置失败") - return jsonify({'success': False, 'error': '获取配置失败'}), 500 - - -@app.route('/api/config', methods=['PUT']) -def update_config(): - """保存当前用户的 provider 配置到数据库""" - try: - data = request.get_json(force=True) or {} - user_id = session.get('user_id') - - if not user_id: - return jsonify({'success': False, 'error': '请先登录'}), 401 - - with SessionLocal() as db: - try: - crud.save_user_providers(db, user_id, data) - except Exception: - db.rollback() - raise - return jsonify({'success': True}) - - except Exception as e: - logger.exception("更新配置失败") - return jsonify({'success': False, 'error': '更新配置失败,请检查日志'}), 500 - - -@app.route('/api/models/list', methods=['POST']) -def list_models(): - """代理请求目标 API 的模型列表,绕过浏览器 CORS 限制。 - - 请求体: - type: 'openai' | 'anthropic' - api_key: API Key(可选,留空则使用系统已配置的 key) - base_url: Base URL(可选) - provider_id: 已有 provider 的 id(可选,用于回退读取已存 key) - """ - try: - data = request.get_json(force=True) or {} - provider_type = data.get('type', 'openai') - api_key = data.get('api_key') or '' - base_url = data.get('base_url') or '' - - # 如果前端没传 key,从数据库读取已保存的配置 - if not api_key: - user_id = session.get('user_id') - provider_id = data.get('provider_id') - if user_id: - with SessionLocal() as db: - if provider_id: - provider = db.query(crud.ProviderConfig).filter_by( - id=provider_id, user_id=user_id - ).first() - else: - provider = crud.get_active_provider(db, user_id, provider_type) - if provider: - if not api_key: - api_key = provider.api_key or '' - if not base_url: - base_url = provider.base_url or '' - - if not api_key: - return jsonify({'error': '未提供 API Key,请先在设置中配置'}), 400 - - if provider_type == 'openai': - url = (base_url.rstrip('/') if base_url else 'https://api.openai.com') + '/v1/models' - headers = {'Authorization': f'Bearer {api_key}'} - resp = http_requests.get(url, headers=headers, timeout=15) - - # 部分 OpenAI 兼容 API 的路径可能不带 /v1 - if resp.status_code == 404: - url_alt = (base_url.rstrip('/') if base_url else 'https://api.openai.com') + '/models' - resp = http_requests.get(url_alt, headers=headers, timeout=15) - - if resp.status_code != 200: - return jsonify({'error': f'API 返回 {resp.status_code}: {resp.text[:200]}'}), 502 - - body = resp.json() - models = sorted([m['id'] for m in body.get('data', [])]) if 'data' in body else [] - return jsonify({'models': models}) - - elif provider_type == 'anthropic': - # Anthropic 没有官方 list models 接口,返回常用模型列表 - models = [ - 'claude-opus-4-20250514', - 'claude-sonnet-4-20250514', - 'claude-haiku-4-20250506', - 'claude-3-5-sonnet-20241022', - 'claude-3-5-haiku-20241022', - 'claude-3-opus-20240229', - ] - return jsonify({'models': models}) - - else: - return jsonify({'error': f'不支持的 provider 类型: {provider_type}'}), 400 - - except http_requests.Timeout: - return jsonify({'error': '请求超时,请检查 Base URL 是否正确'}), 504 - except http_requests.ConnectionError: - return jsonify({'error': '无法连接目标 API,请检查 Base URL'}), 502 - except Exception as e: - logger.exception("获取模型列表失败") - return jsonify({'error': str(e)}), 500 - - -@app.route('/api/paddleocr/test', methods=['POST']) -def test_paddleocr(): - """测试 PaddleOCR API Token 是否可用。 - - 请求体: - api_token: API Token(可选,留空则从数据库读取) - api_url: API URL(可选,留空则从数据库读取) - provider_id: 已有 provider 的 id(可选,用于回退读取已存 token) - """ - try: - data = request.get_json(force=True) or {} - api_token = data.get('api_token') or '' - api_url = data.get('api_url') or '' - - # 前端未提供凭据时,从数据库读取已保存的配置 - if not api_token or not api_url: - user_id = session.get('user_id') - provider_id = data.get('provider_id') - if user_id: - with SessionLocal() as db: - if provider_id: - provider = db.query(crud.ProviderConfig).filter_by( - id=provider_id, user_id=user_id - ).first() - else: - provider = crud.get_active_provider(db, user_id, 'paddleocr') - if provider: - if not api_token: - api_token = provider.api_key or '' - if not api_url: - api_url = provider.base_url or '' - - if not api_token or not api_url: - return jsonify({'error': '未提供 API Token 或 API URL'}), 400 - - # 用 GET 请求 API URL,带 token 验证认证是否有效 - headers = {'Authorization': f'bearer {api_token}'} - resp = http_requests.get(api_url, headers=headers, timeout=10) - - # 401/403 表示 token 无效 - if resp.status_code in (401, 403): - return jsonify({'success': False, 'error': '认证失败,请检查 API Token 是否正确'}) - - # 其他非 5xx 状态码都认为 token 有效(包括 404/405 等,因为 GET 可能不被支持但认证通过了) - if resp.status_code >= 500: - return jsonify({'success': False, 'error': f'服务端错误 ({resp.status_code}),请检查 API URL'}) - - return jsonify({'success': True, 'message': 'API Token 验证通过'}) - - except http_requests.Timeout: - return jsonify({'success': False, 'error': '请求超时,请检查 API URL 是否正确'}), 504 - except http_requests.ConnectionError: - return jsonify({'success': False, 'error': '无法连接,请检查 API URL'}), 502 - except Exception as e: - logger.exception("测试 PaddleOCR 连接失败") - return jsonify({'success': False, 'error': str(e)}), 500 - - -@app.route('/api/history', methods=['GET']) -def get_history(): - """ - 分页查询历史题目(全部题目,非仅错题) - - Query参数: - page: 页码(默认1) - page_size: 每页数量(默认20) - start_date: 开始日期(可选,格式:YYYY-MM-DD) - end_date: 结束日期(可选,格式:YYYY-MM-DD) - """ - try: - page = max(1, request.args.get('page', 1, type=int)) - page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) - start_date_str = request.args.get('start_date') - end_date_str = request.args.get('end_date') - - # 解析日期 - start_date = None - end_date = None - if start_date_str: - start_date = datetime.strptime(start_date_str, '%Y-%m-%d') - if end_date_str: - end_date = datetime.strptime(end_date_str, '%Y-%m-%d') - - with SessionLocal() as db: - questions, total = crud.get_history_questions( - db, - start_date=start_date, - end_date=end_date, - page=page, - page_size=page_size - ) - - total_pages = (total + page_size - 1) // page_size - items = [_serialize_question(q) for q in questions] - - return jsonify({ - 'success': True, - 'items': items, - 'total': total, - 'page': page, - 'page_size': page_size, - 'total_pages': total_pages - }) - - except ValueError: - return jsonify({'success': False, 'error': '日期格式错误,请使用 YYYY-MM-DD 格式'}), 400 - except Exception as e: - logger.exception("查询历史题目失败") - return jsonify({'success': False, 'error': '查询失败,请稍后重试'}), 500 - - -@app.route('/api/search', methods=['GET']) -def search_questions(): - """ - 搜索题目(知识点/题型/关键字) - - Query参数: - keyword: 关键字搜索(匹配题目内容) - knowledge_tag: 知识点标签筛选 - question_type: 题型筛选 - page: 页码(默认1) - page_size: 每页数量(默认20) - """ - try: - page = max(1, request.args.get('page', 1, type=int)) - page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) - keyword = request.args.get('keyword', type=str) - knowledge_tag = request.args.get('knowledge_tag', type=str) - question_type = request.args.get('question_type', type=str) - - # 至少需要一个搜索条件 - if not any([keyword, knowledge_tag, question_type]): - return jsonify({ - 'success': False, - 'error': '至少需要提供一个搜索条件(keyword/knowledge_tag/question_type)' - }), 400 - - with SessionLocal() as db: - questions, total = crud.search_questions( - db, - keyword=keyword if keyword else None, - knowledge_tag=knowledge_tag if knowledge_tag else None, - question_type=question_type if question_type else None, - page=page, - page_size=page_size - ) - - total_pages = (total + page_size - 1) // page_size - items = [_serialize_question(q) for q in questions] - - return jsonify({ - 'success': True, - 'items': items, - 'total': total, - 'page': page, - 'page_size': page_size, - 'total_pages': total_pages - }) - - except Exception as e: - logger.exception("搜索题目失败") - return jsonify({'success': False, 'error': '搜索失败,请稍后重试'}), 500 - - -@app.route('/api/stats', methods=['GET']) -def get_stats(): - """ - 获取知识点统计信息 - """ - try: - subject = request.args.get('subject', type=str) or None - with SessionLocal() as db: - stats = crud.get_knowledge_stats(db, subject=subject, user_id=session.get('user_id')) - return jsonify({ - 'success': True, - 'stats': stats, - 'total_tags': len(stats) - }) - - except Exception as e: - logger.exception("获取统计失败") - return jsonify({'success': False, 'error': '获取统计失败,请稍后重试'}), 500 - - -@app.route('/api/question/', methods=['DELETE']) -def delete_question(question_id): - """ - 删除题目 - - Path参数: - question_id: 题目ID - """ - try: - with SessionLocal() as db: - success = crud.delete_question(db, question_id) - if success: - return jsonify({ - 'success': True, - 'message': '题目已删除' - }) - else: - return jsonify({ - 'success': False, - 'error': '题目不存在' - }), 404 - - except Exception as e: - logger.exception("删除题目失败") - return jsonify({'success': False, 'error': '删除失败,请稍后重试'}), 500 - - # ============================================================ -# 错题库 API +# 启动入口 # ============================================================ - -@app.route('/api/error-bank', methods=['GET']) -def get_error_bank(): - """ - 错题库统一查询 - - Query参数: - subject: 科目筛选 - knowledge_tag: 知识点标签筛选 - question_type: 题型筛选 - keyword: 关键字搜索 - start_date: 开始日期(YYYY-MM-DD) - end_date: 结束日期(YYYY-MM-DD) - page: 页码(默认1) - page_size: 每页数量(默认20) - """ - try: - page = max(1, request.args.get('page', 1, type=int)) - page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) - subject = request.args.get('subject', type=str) or None - knowledge_tag = request.args.get('knowledge_tag', type=str) or None - question_type = request.args.get('question_type', type=str) or None - keyword = request.args.get('keyword', type=str) or None - review_status = request.args.get('review_status', type=str) or None - start_date_str = request.args.get('start_date') - end_date_str = request.args.get('end_date') - - start_date = None - end_date = None - if start_date_str: - start_date = datetime.strptime(start_date_str, '%Y-%m-%d') - if end_date_str: - end_date = datetime.strptime(end_date_str, '%Y-%m-%d') - - with SessionLocal() as db: - questions, total = crud.query_questions( - db, - user_id=session.get('user_id'), - subject=subject, - knowledge_tag=knowledge_tag, - question_type=question_type, - keyword=keyword, - start_date=start_date, - end_date=end_date, - review_status=review_status, - page=page, - page_size=page_size, - ) - - total_pages = (total + page_size - 1) // page_size - items = [_serialize_question_detail(q) for q in questions] - - return jsonify({ - 'success': True, - 'items': items, - 'total': total, - 'page': page, - 'page_size': page_size, - 'total_pages': total_pages, - }) - - except ValueError: - return jsonify({'success': False, 'error': '日期格式错误,请使用 YYYY-MM-DD 格式'}), 400 - except Exception as e: - logger.exception("查询错题库失败") - return jsonify({'success': False, 'error': '查询失败,请稍后重试'}), 500 - - -@app.route('/api/subjects', methods=['GET']) -def get_subjects(): - """获取所有科目列表""" - try: - with SessionLocal() as db: - subjects = crud.get_existing_subjects(db, user_id=session.get('user_id')) - return jsonify({'success': True, 'subjects': subjects}) - except Exception as e: - logger.exception("获取科目列表失败") - return jsonify({'success': False, 'error': '获取科目列表失败'}), 500 - - -@app.route('/api/question-types', methods=['GET']) -def get_question_types(): - """获取所有题型列表""" - try: - with SessionLocal() as db: - types = crud.get_existing_question_types(db, user_id=session.get('user_id')) - return jsonify({'success': True, 'question_types': types}) - except Exception as e: - logger.exception("获取题型列表失败") - return jsonify({'success': False, 'error': '获取题型列表失败'}), 500 - - -@app.route('/api/question/', methods=['PATCH']) -def update_question(question_id): - """编辑题目内容和/或答案""" - try: - data = request.get_json(silent=True) or {} - with SessionLocal() as db: - question = db.get(Question, question_id) - if not question: - return jsonify({'success': False, 'error': '题目不存在'}), 404 - try: - if 'content' in data: - text = str(data['content'])[:20000] - blocks = [{'block_type': 'text', 'content': text}] - question.content_json = json.dumps(blocks, ensure_ascii=False) - question.content_hash = crud.compute_content_hash(blocks) - if 'answer' in data: - question.answer = str(data['answer'])[:10000] if data['answer'] else None - question.updated_at = datetime.utcnow() - db.commit() - return jsonify({'success': True}) - except Exception: - db.rollback() - raise - except Exception: - logger.exception("编辑题目失败") - return jsonify({'success': False, 'error': '保存失败,请稍后重试'}), 500 - - -@app.route('/api/question//answer', methods=['PATCH']) -def update_question_answer(question_id): - """保存用户答案""" - try: - data = request.get_json(silent=True) or {} - user_answer = data.get('user_answer') - if user_answer is None: - return jsonify({'success': False, 'error': '缺少 user_answer 字段'}), 400 - if len(user_answer) > 10000: - return jsonify({'success': False, 'error': '答案内容过长(最多 10000 字符)'}), 400 - - with SessionLocal() as db: - question = crud.update_user_answer(db, question_id, user_answer) - if not question: - return jsonify({'success': False, 'error': '题目不存在'}), 404 - - return jsonify({ - 'success': True, - 'message': '答案已保存', - 'user_answer': question.user_answer, - 'updated_at': question.updated_at.isoformat() if question.updated_at else None, - }) - - except Exception as e: - logger.exception("保存答案失败") - return jsonify({'success': False, 'error': '保存答案失败,请稍后重试'}), 500 - - -@app.route('/api/question//review-status', methods=['PATCH']) -def update_question_review_status(question_id): - """更新题目复习状态""" - try: - data = request.get_json(silent=True) or {} - review_status = data.get('review_status') - if not review_status: - return jsonify({'success': False, 'error': '缺少 review_status 字段'}), 400 - - with SessionLocal() as db: - question = crud.update_review_status(db, question_id, review_status) - if not question: - return jsonify({'success': False, 'error': '题目不存在'}), 404 - - return jsonify({ - 'success': True, - 'message': '复习状态已更新', - 'review_status': question.review_status, - 'updated_at': question.updated_at.isoformat() if question.updated_at else None, - }) - - except ValueError: - return jsonify({'success': False, 'error': f'无效的复习状态,可选值: {", ".join(crud.VALID_REVIEW_STATUSES)}'}), 400 - except Exception as e: - logger.exception("更新复习状态失败") - return jsonify({'success': False, 'error': '更新复习状态失败,请稍后重试'}), 500 - - -@app.route('/api/dashboard-stats', methods=['GET']) -def get_dashboard_stats(): - """获取 Dashboard 所需的完整统计数据,支持 ?subject= 学科筛选""" - try: - subject = request.args.get('subject') or None - uid = session.get('user_id') - with SessionLocal() as db: - # 可用学科列表(按当前用户隔离) - subjects = crud.get_existing_subjects(db, user_id=uid) - - # 复习状态统计 - review_stats = crud.get_review_status_stats(db, subject=subject, user_id=uid) - - # 总体统计 - statistics = crud.get_statistics(db, subject=subject, user_id=uid) - - # 知识点标签统计 top 10(横向条形图) - tag_stats = crud.get_knowledge_stats(db, subject=subject, limit=10, user_id=uid) - - # 知识点 × 掌握状态(堆叠柱状图) - tag_status_stats = crud.get_tag_status_stats(db, subject=subject, limit=10, user_id=uid) - - # 知识点 × 题型(热力图) - tag_type_stats = crud.get_tag_type_stats(db, subject=subject, tag_limit=8, user_id=uid) - - # 最近30天每日新增 + 已掌握趋势 - daily_counts = crud.get_daily_counts(db, days=30, subject=subject, user_id=uid) - - return jsonify({ - 'success': True, - 'subjects': subjects, - 'review_stats': review_stats, - 'total_questions': statistics['total_questions'], - 'by_subject': statistics['by_subject'], - 'tag_stats': tag_stats, - 'tag_status_stats': tag_status_stats, - 'tag_type_stats': tag_type_stats, - 'daily_counts': daily_counts, - }) - - except Exception as e: - logger.exception("获取 Dashboard 统计失败") - return jsonify({'success': False, 'error': '获取统计失败,请稍后重试'}), 500 - - -@app.route('/api/save-to-db', methods=['POST']) -def save_to_db(): - """ - 将分割好的题目导入错题库(仅入库,不导出 Markdown) - - Request Body: - { - "selected_ids": ["q_0", "q_1", ...] # 选中的题目 ID 列表 - } - """ - try: - data = request.get_json(silent=True) or {} - selected_ids = data.get('selected_ids', []) - - if not isinstance(selected_ids, list) or not selected_ids: - return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 - - results_dir = settings.results_dir - questions_file = os.path.join(results_dir, "questions.json") - if not os.path.exists(questions_file): - return jsonify({'success': False, 'error': '请先分割题目'}), 400 - - with open(questions_file, 'r', encoding='utf-8') as f: - questions = json.load(f) - - selected_questions = [q for q in questions if q.get('question_id') in selected_ids] - if not selected_questions: - return jsonify({'success': False, 'error': '未找到选中的题目'}), 400 - - # 合并前端传来的 answer/user_answer(按 question_id 匹配) - answers_map = {a['question_id']: a for a in data.get('answers', []) if 'question_id' in a} - for sq in selected_questions: - qid = sq.get('question_id') - if qid and qid in answers_map: - if 'answer' in answers_map[qid]: - sq['answer'] = answers_map[qid]['answer'] - if 'user_answer' in answers_map[qid]: - sq['user_answer'] = answers_map[qid]['user_answer'] - - # 读取科目信息 - subject = _read_split_subject() - - with session_lock: - batch_info = { - "original_filename": ", ".join( - session_files.get(k, {}).get("filename", "未知") - for k in session_file_order - ), - "subject": subject, - "file_path": "", - } - - with SessionLocal() as db: - result = crud.save_questions_to_db(db, selected_questions, batch_info, user_id=session.get('user_id')) - - return jsonify({ - 'success': True, - 'message': f'已导入 {result["created"]} 道题目(跳过 {result["duplicates"]} 道重复)', - 'created': result['created'], - 'duplicates': result['duplicates'], - }) - - except Exception as e: - logger.exception("导入错题库失败") - return jsonify({'success': False, 'error': '导入错题库失败,请稍后重试'}), 500 - - -@app.route('/api/ai-analysis', methods=['POST']) -def ai_analysis(): - """ - AI 错题分析(骨架路由) - - 接收一组题目 ID,调用 AI 对这些错题进行综合分析,返回: - - 薄弱知识点诊断 - - 错因归纳 - - 针对性复习建议 - - Request Body: - { - "question_ids": [1, 2, 3] # 必填,至少 1 道,最多 20 道 - } - - Response: - { - "success": true, - "analysis": { - "summary": "综合诊断摘要", - "weak_points": ["知识点A", "知识点B"], - "error_patterns": [ - {"pattern": "错因类型", "description": "详细描述", "question_ids": [1, 2]} - ], - "suggestions": ["建议1", "建议2"], - "per_question": [ - {"question_id": 1, "diagnosis": "该题错因分析", "hint": "解题提示"} - ] - } - } - - TODO(后端开发者): - 1. 从数据库查询题目详情(content_json, options_json, user_answer, knowledge_tags) - 2. 构建 prompt,将题目内容 + 用户答案 + 知识点标签传给 LLM - 3. 调用 LLM(建议使用 llm.py 中的 init_model,支持 openai/anthropic) - 4. 解析 LLM 返回的结构化结果,填充 analysis 字段 - 5. 可选:将分析结果缓存到数据库,避免重复分析 - """ - try: - data = request.get_json(silent=True) or {} - question_ids = data.get('question_ids', []) - - if not isinstance(question_ids, list) or not question_ids: - return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 - - if len(question_ids) > 20: - return jsonify({'success': False, 'error': '单次最多分析 20 道题目'}), 400 - - with SessionLocal() as db: - questions = crud.get_questions_by_ids(db, question_ids) - if not questions: - return jsonify({'success': False, 'error': '未找到对应题目'}), 404 - - # ── TODO: 替换为真实 AI 分析逻辑 ────────────────── - # 当前返回占位数据,供前端联调使用 - knowledge_tags = set() - per_question = [] - for q in questions: - tags = [m.tag.tag_name for m in (q.tags or []) if m.tag] - knowledge_tags.update(tags) - per_question.append({ - 'question_id': q.id, - 'diagnosis': f'题目 #{q.id} 的错因分析(待 AI 生成)', - 'hint': f'题目 #{q.id} 的解题提示(待 AI 生成)', - }) - - analysis = { - 'summary': f'已选择 {len(questions)} 道题目进行分析(AI 分析功能待接入)', - 'weak_points': list(knowledge_tags) or ['暂无知识点数据'], - 'error_patterns': [ - { - 'pattern': '待 AI 识别', - 'description': '错因模式将由 AI 自动归纳', - 'question_ids': [q.id for q in questions], - } - ], - 'suggestions': [ - '建议回顾相关知识点章节', - '建议针对薄弱环节进行专项练习', - ], - 'per_question': per_question, - } - # ── END TODO ────────────────────────────────────── - - return jsonify({ - 'success': True, - 'analysis': analysis, - }) - - except Exception as e: - logger.exception("AI 分析失败") - return jsonify({'success': False, 'error': 'AI 分析失败,请稍后重试'}), 500 - - -@app.route('/api/export-from-db', methods=['POST']) -def export_from_db(): - """从数据库按 ID 列表导出 Markdown 错题本""" - try: - data = request.get_json(silent=True) or {} - selected_ids = data.get('selected_ids', []) - - if not isinstance(selected_ids, list) or not selected_ids: - return jsonify({'success': False, 'error': '请选择至少一道题目'}), 400 - - with SessionLocal() as db: - questions_orm = crud.get_questions_by_ids(db, selected_ids) - if not questions_orm: - return jsonify({'success': False, 'error': '未找到对应题目'}), 404 - - # 转换为 export_wrongbook_md 所需的 dict 格式 - questions = [] - for q in questions_orm: - questions.append({ - 'question_id': str(q.id), - 'question_type': q.question_type, - 'content_blocks': json.loads(q.content_json) if q.content_json else [], - 'options': json.loads(q.options_json) if q.options_json else None, - 'has_formula': q.has_formula, - 'has_image': q.has_image, - 'knowledge_tags': [m.tag.tag_name for m in (q.tags or []) if m.tag], - }) - - str_ids = [str(qid) for qid in selected_ids] - output_path = export_wrongbook_md(questions, str_ids) - - return jsonify({ - 'success': True, - 'message': '错题本导出成功', - 'output_path': output_path, - }) - - except Exception as e: - logger.exception("从数据库导出失败") - return jsonify({'success': False, 'error': '导出失败,请稍后重试'}), 500 - - -# ============================================================ -# 教学辅导对话 API -# ============================================================ - - -@app.route('/api/question//answer', methods=['PUT']) -def save_question_answer(question_id): - """保存题目答案(Markdown 格式,用于 AI 辅导)""" - try: - data = request.get_json(silent=True) or {} - answer = data.get('answer') - if answer is None: - return jsonify({'success': False, 'error': '缺少 answer 字段'}), 400 - if len(answer) > 50000: - return jsonify({'success': False, 'error': '答案内容过长(最多 50000 字符)'}), 400 - - with SessionLocal() as db: - question = crud.update_question_answer(db, question_id, answer) - if not question: - return jsonify({'success': False, 'error': '题目不存在'}), 404 - - return jsonify({ - 'success': True, - 'message': '答案已保存', - 'answer': question.answer, - }) - - except Exception as e: - logger.exception("保存答案失败") - return jsonify({'success': False, 'error': '保存答案失败,请稍后重试'}), 500 - - -@app.route('/api/question//chats', methods=['GET']) -def get_question_chats(question_id): - """获取某道题目的所有对话会话""" - try: - with SessionLocal() as db: - sessions = crud.get_chat_sessions_by_question(db, question_id) - return jsonify({ - 'success': True, - 'sessions': [_serialize_chat_session(s) for s in sessions], - }) - except Exception as e: - logger.exception("获取对话列表失败") - return jsonify({'success': False, 'error': '获取对话列表失败'}), 500 - - -@app.route('/api/chat', methods=['POST']) -def create_chat(): - """创建新对话""" - try: - data = request.get_json(silent=True) or {} - question_id = data.get('question_id') - if not question_id: - return jsonify({'success': False, 'error': '缺少 question_id'}), 400 - - with SessionLocal() as db: - question = db.query(Question).filter(Question.id == question_id).first() - if not question: - return jsonify({'success': False, 'error': '题目不存在'}), 404 - - session = crud.create_chat_session(db, question_id) - return jsonify({ - 'success': True, - 'session': _serialize_chat_session(session), - }) - - except Exception as e: - logger.exception("创建对话失败") - return jsonify({'success': False, 'error': '创建对话失败'}), 500 - - -@app.route('/api/chat/sessions', methods=['GET']) -def get_chat_sessions(): - """分页获取所有对话会话""" - try: - page = max(1, request.args.get('page', 1, type=int)) - page_size = min(100, max(1, request.args.get('page_size', 20, type=int))) - - with SessionLocal() as db: - sessions, total = crud.get_all_chat_sessions(db, page=page, page_size=page_size) - total_pages = (total + page_size - 1) // page_size - - return jsonify({ - 'success': True, - 'sessions': [_serialize_chat_session(s) for s in sessions], - 'total': total, - 'page': page, - 'total_pages': total_pages, - }) - - except Exception as e: - logger.exception("获取对话会话列表失败") - return jsonify({'success': False, 'error': '获取对话会话列表失败'}), 500 - - -@app.route('/api/chat//messages', methods=['GET']) -def get_chat_messages(session_id): - """游标分页获取对话消息""" - try: - limit = min(100, max(1, request.args.get('limit', 30, type=int))) - before_id = request.args.get('before_id', type=int) - - with SessionLocal() as db: - result = crud.get_chat_messages(db, session_id, limit=limit, before_id=before_id) - return jsonify({ - 'success': True, - 'messages': result['messages'], - 'hasMore': result['hasMore'], - }) - - except Exception as e: - logger.exception("获取对话消息失败") - return jsonify({'success': False, 'error': '获取对话消息失败'}), 500 - - -@app.route('/api/chat//stream', methods=['POST']) -def stream_chat(session_id): - """SSE 流式对话""" - from flask import Response - from teach_agent import stream_teach - - try: - data = request.get_json(silent=True) or {} - message = data.get('message', '').strip() - model_provider = data.get('model_provider', 'openai') - model_name = data.get('model_name') or None - - if not message: - return jsonify({'success': False, 'error': '消息不能为空'}), 400 - - if not settings.is_valid_provider(model_provider): - return jsonify({'success': False, 'error': f'不支持的模型供应商: {model_provider}'}), 400 - - # 从数据库加载用户的 LLM 凭据 - user_id = session.get('user_id') - if user_id: - settings.load_providers_from_db(user_id) - - with SessionLocal() as db: - from db.models import ChatSession as ChatSessionModel, QuestionTagMapping - from sqlalchemy.orm import selectinload - chat_session = db.query(ChatSessionModel).options( - selectinload(ChatSessionModel.question) - .selectinload(Question.batch), - selectinload(ChatSessionModel.question) - .selectinload(Question.tags) - .selectinload(QuestionTagMapping.tag), - ).filter(ChatSessionModel.id == session_id).first() - if not chat_session: - return jsonify({'success': False, 'error': '对话不存在'}), 404 - - question = chat_session.question - if not question: - return jsonify({'success': False, 'error': '关联题目不存在'}), 404 - - # 序列化题目数据 - q_data = _serialize_question(question) - - # 加载历史消息(最近 20 条) - history_result = crud.get_chat_messages(db, session_id, limit=20) - history = [{"role": m["role"], "content": m["content"]} for m in history_result["messages"]] - - # 追加用户消息 - history.append({"role": "user", "content": message}) - crud.add_chat_message(db, session_id, "user", message) - - def generate(): - full_response = [] - try: - for token in stream_teach( - question=q_data, - messages=history, - provider=model_provider, - model_name=model_name, - ): - full_response.append(token) - yield f"data: {json.dumps({'token': token}, ensure_ascii=False)}\n\n" - except Exception as e: - logger.exception("流式对话错误") - yield f"data: {json.dumps({'error': str(e)}, ensure_ascii=False)}\n\n" - - # 保存完整的 assistant 回复 - assistant_content = "".join(full_response) - if assistant_content: - try: - with SessionLocal() as db: - crud.add_chat_message(db, session_id, "assistant", assistant_content) - except Exception as e: - logger.error(f"保存 assistant 回复失败: {e}") - - yield f"data: {json.dumps({'done': True})}\n\n" - - resp = Response(generate(), mimetype='text/event-stream') - resp.headers['Cache-Control'] = 'no-cache' - resp.headers['X-Accel-Buffering'] = 'no' - return resp - - except Exception as e: - logger.exception("流式对话失败") - return jsonify({'success': False, 'error': '对话失败,请稍后重试'}), 500 - - if __name__ == '__main__': - # 确保运行时目录存在 + # 创建运行时目录(uploads、pages、results 等) settings.ensure_dirs() - # 初始化数据库 + + # 初始化数据库(建表 + 自动迁移) init_db() - # 自动迁移(添加新列等) from db.migrate import migrate migrate() - print("[数据库] 初始化完成") - print("=" * 60) - print("错题本生成系统 - Web应用") - print("=" * 60) - print("访问地址: http://localhost:5001") - print("=" * 60) + logger.info("错题本生成系统 - API 服务") + logger.info("API 地址: http://localhost:5001") + logger.info("=" * 50) + # 从环境变量读取调试模式开关(默认关闭) + # 开启后 Flask 会自动重载代码变更,并在浏览器显示详细错误信息 + debug = os.getenv('FLASK_DEBUG', 'false').lower() == 'true' app.run( - host='0.0.0.0', port=5001, debug=True, - exclude_patterns=["*site-packages*"], + host='0.0.0.0', port=5001, debug=debug, + threaded=True, # 多线程处理并发请求 + exclude_patterns=["*site-packages*"], # 排除第三方库文件变更触发的重载 ) diff --git a/data-processing/README.md b/data-processing/README.md deleted file mode 100644 index 31434c33..00000000 --- a/data-processing/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# Data Processing - -OCR 图像预处理与识别准确率评估系统。 - -## 目录结构 - -``` -data-processing/ -├── preprocessing/ # 图像预处理模块 -│ ├── data_preprocessing.py # 预处理核心 -│ ├── preprocessing_mode.json # 预处理几种方案 -│ └── README.md -│ -│ -├── processing/ # 基于OmniDocBench的识别评估模块 -│ ├── evaluation_recognition.py # 记录识别结果 -│ ├── exam_accuracy_results.json # 试卷样例识别结果 -│ ├── jiaocai_accuracy_results.json #教程样例识别结果 -│ ├── OmniDocBench.json # OmniDocBench数据集答案 -│ └── sample_image # 优秀样例图片 -│ ├──exam/ # 试卷 -│ └──jiaocai # 教材 -│ -├── standard_doc/ # 图像扫描规范文档、数据标注规范 -│ ├── DATA_LABELING_STANDARDS.md # 数据标注 -│ └── SCANNING_STANDARDS.md # 扫描规范 -└── README.md -``` - -## 快速开始 - -### 1. 原始图片识别评估 - -```bash -cd processing -python evaluation_recognition.py -``` - -评估原始图片的 OCR 识别准确率,与 OmniDocBench 标注对比,生成 `exam_accuracy_results.json`。 - -### 2. 图像预处理 - -```python -from preprocessing.data_preprocessing import run_pipeline - -# 单张图片 -run_pipeline(file_path="test.png", mode="auto", save_log=True) - -# 批量处理 -import glob -for img in glob.glob("sample_image/exam/*.png"): - run_pipeline(file_path=img, mode="auto", save_log=True) -``` - -**预处理模式**: - -| 模式 | 适用场景 | -|------|---------| -| `auto` | 自动选择最佳策略(推荐) | -| `standard` | 一般文档 | -| `lightweight` | 高质量文档、数学公式密集 | -| `illumination_rescue` | 光照不均、阴影、反光 | -| `screen_photography` | 屏幕翻拍、摩尔纹 | -| `aggressive_compression` | 文件压缩 | - - -``` - -## 实验结果 - -基于 OmniDocBench 数据集: - -- **原始平均准确率**: 83.97% -- **预处理后平均准确率**: 85.50% -- **平均提升**: 1.5-2% -- **中文试卷**: illumination_rescue 模式提升 2-7% -- **英文数学试卷**: lightweight 模式保持原有准确率 - -## 配置 - -### 环境变量 - -创建 `.env` 文件: - -```env -PADDLEOCR_API_URL=https://your-api-endpoint -PADDLEOCR_API_TOKEN=your-token-here -``` - -### 自定义预处理参数 - -编辑 `preprocessing/preprocessing_mode.json` 添加自定义模式。 - -## 注意事项 - -1. **API 限流**: 建议 `MAX_WORKERS` 不超过 5 -2. **文件命名**: 图片文件名需与 `OmniDocBench.json` 中的 `image_path` 匹配 -3. **预处理策略**: 数学公式密集文档避免使用 `illumination_rescue` - -## 相关文档 - -- [预处理模块详细说明](preprocessing/README.md) -- [数据标注规范](standard_doc/DATA_LABELING_STANDARDS.md) -- [扫描规范](standard_doc/SCANNING_STANDARDS.md) diff --git a/data-processing/preprocessing/README.md b/data-processing/preprocessing/README.md deleted file mode 100644 index 69702fb6..00000000 --- a/data-processing/preprocessing/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# 图像预处理模块 - -智能图像预处理系统,用于优化 OCR 识别效果。 - -## 核心文件 - -- `data_preprocessing.py` - 主预处理程序 -- `preprocessing_mode.json` - 预处理策略配置 - - -## 快速开始 - -### 1. 单张图片预处理 - -```python -from data_preprocessing import run_pipeline - -# 自动模式(推荐) -run_pipeline( - file_path="your_image.png", - mode="auto", # 自动选择最佳策略 - save_log=True -) - -# 手动指定模式 -run_pipeline( - file_path="your_image.png", - mode="lightweight", # 可选: standard, lightweight, illumination_rescue, screen_photography, aggressive_compression - save_log=True -) -``` - -### 2. 批量处理 - -```python -import glob -from data_preprocessing import run_pipeline - -image_files = glob.glob("your_folder/*.png") -for img_path in image_files: - run_pipeline(file_path=img_path, mode="auto", save_log=True) -``` - - - -## 预处理模式说明 - -| 模式 | 适用场景 | 特点 | -|------|---------|------| -| `auto` | 所有场景(推荐) | 自动诊断并选择最佳策略 | -| `standard` | 一般文档 | 平衡速度与精度 | -| `lightweight` | 高质量文档、数学公式密集 | 仅做基础优化,保护细节 | -| `illumination_rescue` | 光照不均、阴影、反光 | 对比度增强,光照修复 | -| `screen_photography` | 屏幕翻拍、摩尔纹 | 去除摩尔纹 | -| `aggressive_compression` | 网络差、文件大 | 极限压缩 | - -## Auto 模式智能路由 - -系统会自动分析图像特征并选择最佳策略: - -- **数学公式密集 / 高质量文档** → `lightweight` -- **光照问题明显** → `illumination_rescue` -- **屏幕翻拍特征** → `screen_photography` -- **大文件低文本密度** → `aggressive_compression` -- **其他** → `standard` - -## 输出结构 - -``` -output/ -├── image_name_processed_strategy/ -│ └── api_analysis.log # API 识别结果 -processed_exam_images/ -└── image_name.png # 预处理后的图片 -``` - -## 配置自定义 - -编辑 `preprocessing_mode.json` 可自定义预处理参数: - -```json -{ - "modes": { - "your_custom_mode": { - "description": "自定义模式说明", - "target_dpi": 150, - "max_side_len": 1920, - "jpeg_quality": 95, - "enable_deskew": true, - "enable_contrast_enhance": false, - "enable_moire_removal": false - } - } -} -``` - -## 性能优化建议 - -1. **中文试卷**:auto 模式会自动选择 `illumination_rescue`,提升 2-7% -2. **英文数学试卷**:auto 模式会自动选择 `lightweight`,避免符号识别下降 -3. **批量处理**:建议使用 auto 模式,系统会为每张图片选择最优策略 diff --git a/data-processing/preprocessing/data_preprocessing.py b/data-processing/preprocessing/data_preprocessing.py deleted file mode 100644 index 4d72dc6e..00000000 --- a/data-processing/preprocessing/data_preprocessing.py +++ /dev/null @@ -1,508 +0,0 @@ -import base64 -import os -import requests -import time -import json -import math -import cv2 -import numpy as np -from typing import Dict, Any -from dotenv import load_dotenv -from PIL import Image - -# ========================================== -# 全局配置参数 -# ========================================== -load_dotenv() # 从 .env 文件加载环境变量 -API_URL = os.getenv("PADDLEOCR_API_URL") -TOKEN = os.getenv("PADDLEOCR_API_TOKEN") - -OUTPUT_DIR = "output" # API 识别结果、标记图片和日志保存目录 -PROCESSED_DIR = "processed_exam_images" # 预处理后的中间图片保存目录 -CONFIG_FILE = "preprocessing_mode.json" # 预处理配置文件路径 - -# ========================================== -# 模块一:配置加载 -# ========================================== -def load_preprocessing_config(mode_name=None): - """加载预处理策略配置""" - if not os.path.exists(CONFIG_FILE): - raise FileNotFoundError(f"配置文件 {CONFIG_FILE} 不存在!请先创建。") - - with open(CONFIG_FILE, 'r', encoding='utf-8') as f: - config_data = json.load(f) - - if mode_name is None: - mode_name = config_data.get("default_mode", "standard") - - if mode_name not in config_data["modes"]: - raise ValueError(f"未找到预处理模式 '{mode_name}',请检查配置文件。") - - print(f"[Config] 已加载预处理模式: '{mode_name}'") - print(f"[Config] 策略描述: {config_data['modes'][mode_name].get('description', '')}") - return config_data["modes"][mode_name] - -# ========================================== -# 模块1.5:图像特征分析 (自适应诊断) -# ========================================== -def get_file_size_kb(path: str) -> float: - return round(os.path.getsize(path) / 1024.0, 2) - -def get_dpi(path: str, default: int = 72) -> int: - try: - with Image.open(path) as im: - dpi = im.info.get('dpi') - if dpi and isinstance(dpi, tuple): - return int(dpi[0]) - except Exception: - pass - return default - -def to_gray(img: np.ndarray) -> np.ndarray: - if len(img.shape) == 3: - return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - return img - -def estimate_brightness_and_contrast(gray: np.ndarray) -> Dict[str, float]: - arr = gray.astype(np.float32) - mean = float(np.mean(arr)) - std = float(np.std(arr)) - return {"brightness": round(mean, 2), "contrast": round(std, 2)} - -def estimate_sharpness(gray: np.ndarray) -> float: - # Variance of Laplacian (常用的清晰度测量) - var_lap = cv2.Laplacian(gray, cv2.CV_64F).var() - return float(var_lap) - -def estimate_noise(img: np.ndarray) -> float: - # 通过原图与高斯模糊图之差估计高频噪声 - blur = cv2.GaussianBlur(img, (3, 3), 0) - if img.ndim == 3: - diff = cv2.cvtColor(cv2.absdiff(img, blur), cv2.COLOR_BGR2GRAY) - else: - diff = cv2.absdiff(img, blur) - return float(np.std(diff)) - -def estimate_edge_density(gray: np.ndarray) -> float: - edges = cv2.Canny(gray, 100, 200) - edge_ratio = float(np.count_nonzero(edges)) / (gray.shape[0] * gray.shape[1]) - return round(edge_ratio, 4) - -def estimate_text_density(gray: np.ndarray) -> float: - # 自适应二值化后计算黑色像素比例,作为文本/线条密度的近似 - th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, - cv2.THRESH_BINARY_INV, 25, 15) - density = float(np.count_nonzero(th)) / (gray.shape[0] * gray.shape[1]) - return round(density, 4) - -def detect_color_mode(img: np.ndarray) -> str: - if len(img.shape) == 2: - return "grayscale" - # 如果三通道间差异很小,认为是灰度图 - channel_diff = np.max(img.astype(np.int32) - img[..., 0:1].astype(np.int32)) - if channel_diff < 5: - return "grayscale" - return "color" - -def estimate_skew_angle(gray: np.ndarray) -> float: - # 使用 Hough 直线检测(在边缘图上)来估计主方向角度 - h, w = gray.shape[:2] - # Resize reduce cost - scale = 600.0 / max(h, w) if max(h, w) > 600 else 1.0 - small = cv2.resize(gray, (int(w * scale), int(h * scale)), interpolation=cv2.INTER_AREA) - edges = cv2.Canny(small, 50, 150) - lines = cv2.HoughLinesP(edges, 1, np.pi / 180, threshold=50, minLineLength=30, maxLineGap=10) - angles = [] - if lines is None: - return 0.0 - for l in lines: - x1, y1, x2, y2 = l[0] - angle = math.degrees(math.atan2(y2 - y1, x2 - x1)) - # 只考虑接近水平的直线,过滤垂直线 - if abs(angle) < 45: - angles.append(angle) - if not angles: - return 0.0 - # 取中位数以减少离群点影响 - med = float(np.median(np.array(angles))) - # 返回图片坐标系下的倾斜角(度),正值表示逆时针旋转 - return round(med / scale if scale != 1.0 else med, 2) - -def analyze_image(path: str) -> Dict[str, Any]: - if not os.path.exists(path): - raise FileNotFoundError(path) - - pil_img = Image.open(path) - w, h = pil_img.size - file_size_kb = get_file_size_kb(path) - dpi = get_dpi(path) - - # Load as OpenCV image - img_cv = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED) - if img_cv is None: - # fallback via PIL - img_cv = cv2.cvtColor(np.array(pil_img.convert('RGB')), cv2.COLOR_RGB2BGR) - - gray = to_gray(img_cv) - - bc = estimate_brightness_and_contrast(gray) - sharpness = estimate_sharpness(gray) - noise = estimate_noise(img_cv) - edge_density = estimate_edge_density(gray) - text_density = estimate_text_density(gray) - color_mode = detect_color_mode(img_cv) - skew = estimate_skew_angle(gray) - - aspect_ratio = round(w / h, 4) if h != 0 else None - - return { - "file": os.path.basename(path), - "path": path, - "file_size_kb": file_size_kb, - "dpi": dpi, - "resolution": f"{w}x{h}", - "aspect_ratio": aspect_ratio, - "color_mode": color_mode, - "brightness": bc["brightness"], - "contrast": bc["contrast"], - "sharpness_variance_laplacian": round(sharpness, 2), - "noise_stddev": round(noise, 2), - "edge_density": edge_density, - "text_density": text_density, - "skew_angle_degrees": skew, - "is_blurry": sharpness < 100.0 - } - -# ========================================== -# 模块二:图像 DPI 读取与真实重采样 -# ========================================== -def get_image_dpi(file_path): - """读取图像文件的 DPI 元数据标签""" - try: - with Image.open(file_path) as img: - dpi = img.info.get('dpi') - if dpi: - return f"{int(dpi[0])} x {int(dpi[1])}" - else: - return "Not Set (System Default)" - except Exception as e: - return f"Read Failed: {e}" - -def resample_image_by_dpi(image_path, target_dpi=150, default_original_dpi=72): - """真正的 DPI 转换器:不仅修改标签,还会物理缩放像素矩阵。""" - with Image.open(image_path) as img: - orig_dpi_tuple = img.info.get('dpi') - original_dpi = orig_dpi_tuple[0] if orig_dpi_tuple else default_original_dpi - - scale_factor = target_dpi / original_dpi - - if scale_factor == 1.0: - return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) - - new_width = int(img.width * scale_factor) - new_height = int(img.height * scale_factor) - - print(f"[Preprocess] DPI Resampling: {original_dpi} -> {target_dpi} DPI") - - # 执行高质量重采样 (Lanczos) - resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) - return cv2.cvtColor(np.array(resized_img), cv2.COLOR_RGB2BGR) - -# ========================================== -# 模块三:核心 CV 预处理算法 -# ========================================== -def resize_image_for_paddle(image, max_side_len=1920): - """限制图像的最大边长""" - h, w = image.shape[:2] - if max(h, w) > max_side_len: - if h > w: - new_h = max_side_len - new_w = int(w * (max_side_len / h)) - else: - new_w = max_side_len - new_h = int(h * (max_side_len / w)) - image = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_AREA) - print(f"[Preprocess] Size Truncation: ({w}x{h}) -> ({new_w}x{new_h})") - return image - -def deskew_image(image): - """倾斜校正""" - gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - edges = cv2.Canny(gray, 50, 150, apertureSize=3) - lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=100, maxLineGap=10) - - if lines is not None: - angles = [] - for line in lines: - x1, y1, x2, y2 = line[0] - angle = np.degrees(np.arctan2(y2 - y1, x2 - x1)) - if -45 < angle < 45: - angles.append(angle) - - if angles: - median_angle = np.median(angles) - if abs(median_angle) > 0.5: - h, w = image.shape[:2] - center = (w // 2, h // 2) - M = cv2.getRotationMatrix2D(center, median_angle, 1.0) - rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255)) - print(f"[Preprocess] Deskew applied: {median_angle:.2f} degrees") - return rotated - return image - -def enhance_contrast_clahe(image, clip_limit=2.0, tile_size=8): - """CLAHE 增强图像局部对比度""" - lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB) - l, a, b = cv2.split(lab) - clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(tile_size, tile_size)) - cl = clahe.apply(l) - limg = cv2.merge((cl, a, b)) - final = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR) - print(f"[Preprocess] Contrast enhanced (CLAHE: clip={clip_limit}, tile={tile_size})") - return final - -def remove_moire_pattern(image): - """高斯滤波弱化摩尔纹""" - blurred = cv2.GaussianBlur(image, (3, 3), 0) - print("[Preprocess] Moire pattern removed (Gaussian Blur)") - return blurred - -# ========================================== -# 模块四:基于配置的预处理调度器 -# ========================================== -def preprocess_image(input_path, config): - """根据传入的配置字典执行预处理流水线""" - os.makedirs(PROCESSED_DIR, exist_ok=True) - base_name = os.path.basename(input_path) - file_name_without_ext = os.path.splitext(base_name)[0] - file_ext = os.path.splitext(base_name)[1] - - # 保存为原始文件名(保持原扩展名或使用 jpg) - if file_ext.lower() in ['.jpg', '.jpeg', '.png', '.bmp', '.webp']: - output_path = os.path.join(PROCESSED_DIR, base_name) - else: - output_path = os.path.join(PROCESSED_DIR, f"{file_name_without_ext}.jpg") - - print(f"\n[Step 1/3] Local Preprocessing: {input_path}") - - try: - image = resample_image_by_dpi(input_path, target_dpi=config.get('target_dpi', 150)) - except Exception as e: - raise ValueError(f"Image read/resample failed: {e}") - - # 根据配置执行流水线 - image = resize_image_for_paddle(image, max_side_len=config.get('max_side_len', 1920)) - - if config.get('enable_deskew', False): - image = deskew_image(image) - - if config.get('enable_moire_removal', False): - image = remove_moire_pattern(image) - - if config.get('enable_contrast_enhance', False): - clip_limit = config.get('clahe_clip_limit', 2.0) - tile_size = config.get('clahe_tile_size', 8) - image = enhance_contrast_clahe(image, clip_limit=clip_limit, tile_size=tile_size) - - # 统一转换色彩空间并使用 PIL 保存,应用 jpeg_quality 压缩参数 - image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) - pil_img = Image.fromarray(image_rgb) - - target_dpi = config.get('target_dpi', 150) - jpeg_quality = config.get('jpeg_quality', 95) - - pil_img.save(output_path, format="JPEG", quality=jpeg_quality, dpi=(target_dpi, target_dpi)) - - file_size_kb = os.path.getsize(output_path) / 1024 - print(f"[Preprocess] Completed! Saved to: {output_path} (Size: {file_size_kb:.2f} KB, Quality: {jpeg_quality})") - return output_path - -# ========================================== -# 模块五:云端 API 调用与结果解析 -# ========================================== -def get_file_type(file_path): - ext = os.path.splitext(file_path)[-1].lower() - if ext == ".pdf": return 0 - elif ext in [".jpg", ".jpeg", ".png", ".bmp", ".webp"]: return 1 - else: raise ValueError(f"Unsupported file format: {ext}") - -def call_paddleocr_api(file_path): - print(f"\n[Step 2/3] Calling Cloud API...") - file_type = get_file_type(file_path) - with open(file_path, "rb") as file: - file_bytes = file.read() - file_data = base64.b64encode(file_bytes).decode("ascii") - - headers = {"Authorization": f"token {TOKEN}", "Content-Type": "application/json"} - payload = { - "file": file_data, - "fileType": file_type, - "useDocOrientationClassify": False, - "useDocUnwarping": False, - "useChartRecognition": False, - } - - start_time = time.perf_counter() - response = requests.post(API_URL, json=payload, headers=headers) - response.raise_for_status() - api_latency = time.perf_counter() - start_time - - return response.json(), api_latency, response.json() - -def analyze_and_save(original_file_path, api_target_file, light_data, api_latency, raw_data, suffix="", save_log=False): - print(f"\n[Step 3/3] Parsing response...") - base_name = os.path.splitext(os.path.basename(original_file_path))[0] - test_output_dir = os.path.join(OUTPUT_DIR, f"{base_name}_{suffix}" if suffix else base_name) - os.makedirs(test_output_dir, exist_ok=True) - - if save_log: - log_file_path = os.path.join(test_output_dir, "api_analysis.log") - with open(log_file_path, "w", encoding="utf-8") as log_file: - json.dump(light_data, log_file, ensure_ascii=False, indent=2) - print(f"[Preprocess] API info logged to {log_file_path}") - - try: - res = light_data.get('result', {}) - layout_results = res.get('layoutParsingResults', [{}])[0] - width, height = res.get('dataInfo', {}).get('width', 0), res.get('dataInfo', {}).get('height', 0) - num_blocks = len(layout_results.get('prunedResult', {}).get('parsing_res_list', [])) - - text_content = layout_results.get('markdown', {}).get('text', '') - text_length = len(text_content) - actual_dpi = get_image_dpi(api_target_file) if get_file_type(api_target_file) == 1 else "PDF" - - print("-" * 50) - print(f"[{suffix.upper()}] API Data Metrics") - print("-" * 50) - print(f"Latency : {api_latency:.2f} s") - print(f"DPI Tag : {actual_dpi}") - print(f"Resolution : {width} x {height}") - print(f"Blocks : {num_blocks}") - print(f"Text Length : {text_length} chars") - print("-" * 50) - except Exception: - pass - -# ========================================== -# 最终运行入口 -# ========================================== -def run_pipeline(file_path, mode="auto", save_log=False): - """ - 端到端总控调度 - :param file_path: 目标文件路径 - :param mode: "auto" 会触发自动图像诊断路由,也可直接指定配置文件里的模式 - """ - print(f"\n{'='*60}") - print(f"Task Started: {file_path} | Requested Mode: {mode}") - print(f"{'='*60}") - - if not os.path.exists(file_path): - print(f"[Error] File not found: {file_path}") - return - - is_image = (get_file_type(file_path) == 1) - diagnosis_info = None - - # Step 0: 如果是图片,我们先进行物理体检(改动最小的解耦融合方案) - if is_image: - print("\n[Step 0/3] Image Auto-Diagnosis...") - try: - diagnosis_info = analyze_image(file_path) - print(f" -> Features: Brightness={diagnosis_info['brightness']}, Blur={diagnosis_info['is_blurry']}, Skew={diagnosis_info['skew_angle_degrees']}") - - # 核心融合点:如果开启了 Auto 模式,则利用诊断结果决定该用哪套 JSON 预设 - if mode == "auto": - # 判断是否为数学公式密集文档(高文本密度 + 高边缘密度 + 较高清晰度) - is_math_heavy = ( - diagnosis_info['text_density'] > 0.08 and - diagnosis_info['edge_density'] > 0.05 and - diagnosis_info['sharpness_variance_laplacian'] > 150 - ) - - # 判断是否为质量已经较好的文档 - is_good_quality = ( - diagnosis_info['brightness'] >= 120 and - diagnosis_info['brightness'] <= 200 and - diagnosis_info['contrast'] >= 50 and - not diagnosis_info['is_blurry'] and - abs(diagnosis_info['skew_angle_degrees']) < 2.0 - ) - - # 智能路由逻辑 - if is_math_heavy or is_good_quality: - # 数学公式密集或质量已经很好的文档,使用轻量级模式 - mode = "lightweight" - print(f" -> [Auto-Routing] Detected high-quality or math-heavy document, using lightweight mode") - elif diagnosis_info['brightness'] < 100 or diagnosis_info['brightness'] > 220 or diagnosis_info['contrast'] < 40: - # 光照问题明显,使用光照拯救模式 - mode = "illumination_rescue" - print(f" -> [Auto-Routing] Detected illumination issues, using illumination_rescue mode") - elif diagnosis_info['noise_stddev'] > 3.0 and not diagnosis_info['is_blurry']: - # 噪声明显但不模糊,可能是屏幕翻拍 - mode = "screen_photography" - print(f" -> [Auto-Routing] Detected screen photography patterns, using screen_photography mode") - elif diagnosis_info['file_size_kb'] > 3000 and diagnosis_info['text_density'] < 0.03: - # 文件大但文本少,需要压缩 - mode = "aggressive_compression" - print(f" -> [Auto-Routing] Large file with low text density, using aggressive_compression mode") - else: - # 默认使用标准模式 - mode = "standard" - print(f" -> [Auto-Routing] Using standard mode for general document") - except Exception as e: - print(f" -> [Warning] Diagnosis failed: {e}") - if mode == "auto": mode = "standard" - - if is_image and mode != "raw": - # 读取配置并预处理 - config = load_preprocessing_config(mode_name=mode) - api_target_file = preprocess_image(file_path, config) - suffix = f"processed_{mode}" - else: - print(f"\n[Step 1/3] Skipping preprocessing, using raw file...") - api_target_file = file_path - suffix = "raw" - - try: - light_log, latency, raw_json = call_paddleocr_api(api_target_file) - except Exception as e: - print(f"[Error] API call failed: {e}") - return - - # 把物理特征的诊断记录随同 API 结果一并写入 log 文件,辅助后期深度分析 - if diagnosis_info and isinstance(light_log, dict): - light_log["image_diagnosis"] = diagnosis_info - - analyze_and_save(file_path, api_target_file, light_log, latency, raw_json, suffix=suffix, save_log=save_log) - print("\n[Done] Pipeline execution completed successfully.") - -if __name__ == "__main__": - # ========================================== - # 1. 单张图片测试示例 - # ========================================== - # test_file = r"test_image/raw_image/raw_test_1_copy.png" - - # # 使用自适应模式 "auto",系统将自己进行体检并匹配预处理 - # run_pipeline( - # file_path=test_file, - # mode="standard", # 可选: auto, standard, aggressive_compression, illumination_rescue, screen_photography, raw - # save_log=True # 开启 Log 可以将诊断特征一并写入结果中 - # ) - - # ========================================== - # 2. 文件夹批处理测试示例 (若需使用,请取消下方注释) - # ========================================== - import glob - test_dir = r"D:\my_data\code\error_correction\data-processing\processing\sample_image\exam" - # 获取目录下所有的文件 - image_files = glob.glob(os.path.join(test_dir, "*.*")) - - print(f"\n📁 启动文件夹批处理模式: {test_dir} (共找到 {len(image_files)} 个文件)") - for img_path in image_files: - # 仅处理常见图像格式 - if img_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.webp')): - run_pipeline( - file_path=img_path, - mode="auto", # 批处理强烈建议用 auto 模式 - save_log=True # 批处理时建议开启日志以便后续分析 - ) \ No newline at end of file diff --git a/data-processing/preprocessing/examples.py b/data-processing/preprocessing/examples.py deleted file mode 100644 index d7d44f34..00000000 --- a/data-processing/preprocessing/examples.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -预处理模块使用示例 -""" -from data_preprocessing import run_pipeline -import glob -import os - -# ========================================== -# 示例 1: 单张图片预处理(自动模式) -# ========================================== -def example_single_image_auto(): - """单张图片自动预处理""" - test_file = r"test_image/sample.png" - - if os.path.exists(test_file): - run_pipeline( - file_path=test_file, - mode="auto", # 自动选择最佳策略 - save_log=True - ) - - -# ========================================== -# 示例 2: 单张图片预处理(指定模式) -# ========================================== -def example_single_image_manual(): - """单张图片手动指定模式""" - test_file = r"test_image/sample.png" - - if os.path.exists(test_file): - run_pipeline( - file_path=test_file, - mode="lightweight", # 手动指定轻量级模式 - save_log=True - ) - - -# ========================================== -# 示例 3: 批量处理文件夹 -# ========================================== -def example_batch_processing(): - """批量处理文件夹中的所有图片""" - test_dir = r"test_image/batch" - - # 获取所有图片文件 - image_files = glob.glob(os.path.join(test_dir, "*.*")) - - print(f"\n启动批处理: {test_dir} (共 {len(image_files)} 个文件)") - - for img_path in image_files: - # 仅处理常见图像格式 - if img_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.webp')): - print(f"\n处理: {os.path.basename(img_path)}") - run_pipeline( - file_path=img_path, - mode="auto", # 批处理推荐使用 auto 模式 - save_log=True - ) - - - -if __name__ == "__main__": - # 取消注释以运行相应示例 - - # example_single_image_auto() - # example_single_image_manual() - # example_batch_processing() - - print("请取消注释相应的示例函数以运行") diff --git a/data-processing/preprocessing/preprocessing_mode.json b/data-processing/preprocessing/preprocessing_mode.json deleted file mode 100644 index 23ff8765..00000000 --- a/data-processing/preprocessing/preprocessing_mode.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "default_mode": "standard", - "modes": { - "standard": { - "description": "标准通用模式:平衡了速度与精度,适合大部分正常文档", - "target_dpi": 100, - "max_side_len": 1920, - "jpeg_quality": 95, - "enable_deskew": true, - "enable_contrast_enhance": false, - "enable_moire_removal": false - }, - "lightweight": { - "description": "轻量级模式:适合质量已经较好的文档,仅做基础优化(数学公式密集文档推荐)", - "target_dpi": 150, - "max_side_len": 1920, - "jpeg_quality": 95, - "enable_deskew": true, - "enable_contrast_enhance": false, - "enable_moire_removal": false - }, - "aggressive_compression": { - "description": "极限压缩模式:网络极差或对时间要求极高时的备选方案", - "target_dpi": 72, - "max_side_len": 1600, - "jpeg_quality": 85, - "enable_deskew": false, - "enable_contrast_enhance": false, - "enable_moire_removal": false - }, - "illumination_rescue": { - "description": "光照拯救模式:针对阴影、反光、过曝等光照不均场景特调", - "target_dpi": 150, - "max_side_len": 1920, - "jpeg_quality": 92, - "enable_deskew": true, - "enable_contrast_enhance": true, - "enable_moire_removal": false, - "clahe_clip_limit": 1.5, - "clahe_tile_size": 8 - }, - "screen_photography": { - "description": "屏幕翻拍模式:专门处理电脑屏幕、投影仪翻拍产生的摩尔纹", - "target_dpi": 150, - "max_side_len": 2048, - "jpeg_quality": 95, - "enable_deskew": true, - "enable_contrast_enhance": false, - "enable_moire_removal": true - } - } -} \ No newline at end of file diff --git a/data-processing/processing/evaluation_recognition.py b/data-processing/processing/evaluation_recognition.py deleted file mode 100644 index f8dcecca..00000000 --- a/data-processing/processing/evaluation_recognition.py +++ /dev/null @@ -1,191 +0,0 @@ -import os -import json -import base64 -import requests -import time -import glob -from concurrent.futures import ThreadPoolExecutor, as_completed -import difflib -from dotenv import load_dotenv - -load_dotenv() - -# ========================================== -# 全局配置参数 -# ========================================== - -API_URL = os.getenv("PADDLEOCR_API_URL") -TOKEN = os.getenv("PADDLEOCR_API_TOKEN") - -# 文件夹与文件配置 -GT_JSON_FILE = "OmniDocBench.json" # 官方下载的标注文件 -RAW_DIR = "sample_image/jiaocai" # 存放样例原图的目录 -OUTPUT_LOG_FILE = "jiaocai_accuracy_results.json" # 样例原图识别结果 - -# 并发线程数 (不建议过高,避免触发 API 限流) -MAX_WORKERS = 5 - -# ========================================== -# 模块一:解析 OmniDocBench 官方真值 (Ground Truth) -# ========================================== -def load_omnidocbench_gt(json_path): - print(f"正在加载官方标准答案库: {json_path}...") - if not os.path.exists(json_path): - raise FileNotFoundError(f"找不到文件 {json_path},请确保已下载并放置在同级目录。") - - with open(json_path, 'r', encoding='utf-8') as f: - data = json.load(f) - - gt_dict = {} - for page in data: - img_name = os.path.basename(page['page_info']['image_path']) - - page_texts = [] - for det in page.get('layout_dets', []): - if det.get('ignore', False): - continue - - if 'text' in det and det['text'].strip(): - page_texts.append(det['text'].strip()) - elif 'latex' in det and det['latex'].strip(): - page_texts.append(det['latex'].strip()) - - gt_dict[img_name] = "\n".join(page_texts) - - print(f"成功加载 {len(gt_dict)} 张图片的标准答案!\n") - return gt_dict - -def calculate_accuracy(gt_text, pred_text): - gt_clean = gt_text.strip().lower() - pred_clean = pred_text.strip().lower() - - if not gt_clean and not pred_clean: return 100.0 - if not gt_clean or not pred_clean: return 0.0 - - matcher = difflib.SequenceMatcher(None, gt_clean, pred_clean) - return round(matcher.ratio() * 100, 2) - -# ========================================== -# 模块二:云端 API 调用 -# ========================================== -def call_api(file_path): - with open(file_path, "rb") as f: - file_data = base64.b64encode(f.read()).decode("ascii") - - payload = { - "file": file_data, - "fileType": 1, - "useDocOrientationClassify": False, - "useDocUnwarping": False - } - headers = {"Authorization": f"token {TOKEN}", "Content-Type": "application/json"} - - for i in range(3): - try: - start = time.perf_counter() - response = requests.post(API_URL, json=payload, headers=headers, timeout=60) - response.raise_for_status() - latency = time.perf_counter() - start - return latency, response.json() - except Exception as e: - time.sleep(2 ** i) - return None, {"error": "API 请求失败"} - -# ========================================== -# 模块三:多线程任务单元 -# ========================================== -def process_single_task(img_path, gt_dict): - filename = os.path.basename(img_path) - file_size_kb = round(os.path.getsize(img_path) / 1024, 2) - - # Raw 文件名就是标准答案的 Key - if filename not in gt_dict: - return filename, {"error": f"未在官方 JSON 中找到对应的标准答案: {filename}"} - - gt_text = gt_dict[filename] - strategy = "raw" - - latency, res = call_api(img_path) - if not latency: - return filename, {"error": "API 调用失败"} - - try: - data = res.get('result', {}) - layout = data.get('layoutParsingResults', [{}])[0] - pred_text = layout.get('markdown', {}).get('text', '') - blocks_count = len(layout.get('prunedResult', {}).get('parsing_res_list', [])) - except Exception: - pred_text = "" - blocks_count = 0 - - accuracy = calculate_accuracy(gt_text, pred_text) - - return filename, { - "original_img": filename, - "strategy": strategy, - "latency_s": round(latency, 2), - "size_kb": file_size_kb, - "text_len": len(pred_text), - "true_accuracy_pct": accuracy, - "blocks": blocks_count - } - -# ========================================== -# 模块四:主控引擎 (多线程并发) -# ========================================== -def run_raw_evaluation(): - try: - gt_dict = load_omnidocbench_gt(GT_JSON_FILE) - except Exception as e: - print(e) - return - - final_results = {} - if os.path.exists(OUTPUT_LOG_FILE): - with open(OUTPUT_LOG_FILE, "r", encoding="utf-8") as f: - try: - final_results = json.load(f) - print(f"发现已有成绩单,已加载 {len(final_results)} 条记录。") - except: - pass - - if not os.path.exists(RAW_DIR): - print(f"错误: 找不到文件夹 {RAW_DIR},请检查路径。") - return - - files = glob.glob(os.path.join(RAW_DIR, "*.*")) - image_files = [f for f in files if f.lower().endswith(('.jpg', '.jpeg', '.png'))] - - # 剔除已完成 - pending_files = [f for f in image_files if os.path.basename(f) not in final_results] - - if not pending_files: - print("所有 RAW 图片均已测试完毕!") - return - - total_files = len(pending_files) - print(f"开始测试 RAW 图片,共 {total_files} 个样本...") - - completed = 0 - start_time = time.time() - - with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor: - future_to_img = {executor.submit(process_single_task, img_path, gt_dict): img_path for img_path in pending_files} - - for future in as_completed(future_to_img): - filename, metrics = future.result() - final_results[filename] = metrics - - completed += 1 - acc = metrics.get('true_accuracy_pct', 'N/A') - lat = metrics.get('latency_s', 'N/A') - print(f"[{completed}/{total_files}] RAW 处理完成: {filename[:30]}... | 准确率: {acc}% | 耗时: {lat}s") - - with open(OUTPUT_LOG_FILE, "w", encoding="utf-8") as f: - json.dump(final_results, f, ensure_ascii=False, indent=4) - - total_time = round(time.time() - start_time, 2) - print(f"\nRAW 图片测试全部完成!总耗时: {total_time} 秒") - -if __name__ == "__main__": - run_raw_evaluation() \ No newline at end of file diff --git a/data-processing/processing/exam_accuracy_results.json b/data-processing/processing/exam_accuracy_results.json deleted file mode 100644 index ea1b1d64..00000000 --- a/data-processing/processing/exam_accuracy_results.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "exam_paper_en-file-putnam-archive_1997_Solutions_1997s_page_003.png": { - "original_img": "exam_paper_en-file-putnam-archive_1997_Solutions_1997s_page_003.png", - "strategy": "raw", - "latency_s": 1.48, - "size_kb": 430.64, - "text_len": 3214, - "true_accuracy_pct": 78.42, - "blocks": 16 - }, - "exam_paper_2018年广西北海、钦州、南宁、来宾、崇左、防城港、北部湾经济区中考英语试题(空白卷)_page_001.png": { - "original_img": "exam_paper_2018年广西北海、钦州、南宁、来宾、崇左、防城港、北部湾经济区中考英语试题(空白卷)_page_001.png", - "strategy": "raw", - "latency_s": 1.62, - "size_kb": 448.54, - "text_len": 1178, - "true_accuracy_pct": 85.9, - "blocks": 16 - }, - "exam_paper_2016年安徽省中考英语试题(解析)_page_003.png": { - "original_img": "exam_paper_2016年安徽省中考英语试题(解析)_page_003.png", - "strategy": "raw", - "latency_s": 1.95, - "size_kb": 346.44, - "text_len": 899, - "true_accuracy_pct": 91.58, - "blocks": 13 - }, - "exam_paper_en-file-putnam-archive_2006_Problems_2006_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2006_Problems_2006_page_001.png", - "strategy": "raw", - "latency_s": 2.24, - "size_kb": 478.25, - "text_len": 3861, - "true_accuracy_pct": 78.96, - "blocks": 24 - }, - "exam_paper_en-file-putnam-archive_2007_Problems_2007_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2007_Problems_2007_page_001.png", - "strategy": "raw", - "latency_s": 1.48, - "size_kb": 424.95, - "text_len": 3441, - "true_accuracy_pct": 79.24, - "blocks": 20 - }, - "exam_paper_2016年安徽省中考英语试题(解析)_page_015.png": { - "original_img": "exam_paper_2016年安徽省中考英语试题(解析)_page_015.png", - "strategy": "raw", - "latency_s": 3.12, - "size_kb": 417.37, - "text_len": 2060, - "true_accuracy_pct": 96.34, - "blocks": 12 - }, - "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_002.png": { - "original_img": "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_002.png", - "strategy": "raw", - "latency_s": 1.63, - "size_kb": 642.68, - "text_len": 5019, - "true_accuracy_pct": 77.01, - "blocks": 29 - }, - "exam_paper_en-file-putnam-archive_2014_Problems_2014_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2014_Problems_2014_page_001.png", - "strategy": "raw", - "latency_s": 1.63, - "size_kb": 479.37, - "text_len": 3534, - "true_accuracy_pct": 84.34, - "blocks": 29 - }, - "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_003.png": { - "original_img": "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_003.png", - "strategy": "raw", - "latency_s": 1.98, - "size_kb": 714.66, - "text_len": 5844, - "true_accuracy_pct": 85.32, - "blocks": 24 - }, - "exam_paper_en-file-putnam-archive_2015_Problems_2015_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2015_Problems_2015_page_001.png", - "strategy": "raw", - "latency_s": 1.35, - "size_kb": 426.23, - "text_len": 3329, - "true_accuracy_pct": 82.49, - "blocks": 27 - } -} \ No newline at end of file diff --git a/data-processing/processing/jiaocai_accuracy_results.json b/data-processing/processing/jiaocai_accuracy_results.json deleted file mode 100644 index a4c0807f..00000000 --- a/data-processing/processing/jiaocai_accuracy_results.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "jiaocaineedrop_624b60c58c9d8bfb6ff1886c2fd605d2adeb6ea4da576068201b6c6958ce93f4.pdf_8.jpg": { - "original_img": "jiaocaineedrop_624b60c58c9d8bfb6ff1886c2fd605d2adeb6ea4da576068201b6c6958ce93f4.pdf_8.jpg", - "strategy": "raw", - "latency_s": 1.1, - "size_kb": 182.96, - "text_len": 1440, - "true_accuracy_pct": 91.17, - "blocks": 9 - }, - "jiaocaineedrop_eng-45646.pdf_30.jpg": { - "original_img": "jiaocaineedrop_eng-45646.pdf_30.jpg", - "strategy": "raw", - "latency_s": 1.18, - "size_kb": 184.09, - "text_len": 2348, - "true_accuracy_pct": 93.59, - "blocks": 21 - }, - "jiaocaineedrop_jiaocai_needrop_en_1249.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_1249.jpg", - "strategy": "raw", - "latency_s": 1.24, - "size_kb": 234.65, - "text_len": 2859, - "true_accuracy_pct": 95.9, - "blocks": 10 - }, - "jiaocaineedrop_jiaocai_needrop_en_1303.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_1303.jpg", - "strategy": "raw", - "latency_s": 1.28, - "size_kb": 286.56, - "text_len": 1264, - "true_accuracy_pct": 91.93, - "blocks": 13 - }, - "jiaocaineedrop_jiaocai_needrop_en_1544.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_1544.jpg", - "strategy": "raw", - "latency_s": 1.29, - "size_kb": 251.11, - "text_len": 1191, - "true_accuracy_pct": 91.86, - "blocks": 31 - }, - "jiaocaineedrop_jiaocai_needrop_en_1884.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_1884.jpg", - "strategy": "raw", - "latency_s": 0.89, - "size_kb": 226.79, - "text_len": 980, - "true_accuracy_pct": 95.21, - "blocks": 38 - }, - "jiaocai_jiaocai_en_117.jpg": { - "original_img": "jiaocai_jiaocai_en_117.jpg", - "strategy": "raw", - "latency_s": 0.7, - "size_kb": 62.76, - "text_len": 188, - "true_accuracy_pct": 94.51, - "blocks": 7 - }, - "jiaocaineedrop_jiaocai_needrop_en_2002.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_2002.jpg", - "strategy": "raw", - "latency_s": 0.97, - "size_kb": 259.87, - "text_len": 916, - "true_accuracy_pct": 96.73, - "blocks": 12 - }, - "jiaocaineedrop_jiaocai_needrop_en_3428.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_3428.jpg", - "strategy": "raw", - "latency_s": 1.11, - "size_kb": 364.84, - "text_len": 1422, - "true_accuracy_pct": 96.99, - "blocks": 13 - }, - "jiaocaineedrop_jiaocai_needrop_en_377.jpg": { - "original_img": "jiaocaineedrop_jiaocai_needrop_en_377.jpg", - "strategy": "raw", - "latency_s": 1.44, - "size_kb": 372.6, - "text_len": 5329, - "true_accuracy_pct": 96.81, - "blocks": 78 - } -} \ No newline at end of file diff --git a/data-processing/processing/sample_image/exam/exam_accuracy_results.json b/data-processing/processing/sample_image/exam/exam_accuracy_results.json deleted file mode 100644 index fdadd52a..00000000 --- a/data-processing/processing/sample_image/exam/exam_accuracy_results.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "exam_paper_en-file-putnam-archive_1997_Solutions_1997s_page_003.png": { - "original_img": "exam_paper_en-file-putnam-archive_1997_Solutions_1997s_page_003.png", - "strategy": "raw", - "latency_s": 1.95, - "size_kb": 430.64, - "text_len": 3214, - "true_accuracy_pct": 78.42, - "blocks": 16 - }, - "exam_paper_2016年安徽省中考英语试题(解析)_page_015.png": { - "original_img": "exam_paper_2016年安徽省中考英语试题(解析)_page_015.png", - "strategy": "raw", - "latency_s": 1.97, - "size_kb": 417.37, - "text_len": 2060, - "true_accuracy_pct": 96.34, - "blocks": 12 - }, - "exam_paper_2016年安徽省中考英语试题(解析)_page_003.png": { - "original_img": "exam_paper_2016年安徽省中考英语试题(解析)_page_003.png", - "strategy": "raw", - "latency_s": 2.02, - "size_kb": 346.44, - "text_len": 899, - "true_accuracy_pct": 91.58, - "blocks": 13 - }, - "exam_paper_2018年广西北海、钦州、南宁、来宾、崇左、防城港、北部湾经济区中考英语试题(空白卷)_page_001.png": { - "original_img": "exam_paper_2018年广西北海、钦州、南宁、来宾、崇左、防城港、北部湾经济区中考英语试题(空白卷)_page_001.png", - "strategy": "raw", - "latency_s": 2.23, - "size_kb": 448.54, - "text_len": 1178, - "true_accuracy_pct": 85.9, - "blocks": 16 - }, - "exam_paper_en-file-putnam-archive_2006_Problems_2006_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2006_Problems_2006_page_001.png", - "strategy": "raw", - "latency_s": 2.26, - "size_kb": 478.25, - "text_len": 3861, - "true_accuracy_pct": 78.96, - "blocks": 24 - }, - "exam_paper_en-file-putnam-archive_2007_Problems_2007_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2007_Problems_2007_page_001.png", - "strategy": "raw", - "latency_s": 1.75, - "size_kb": 424.95, - "text_len": 3441, - "true_accuracy_pct": 79.24, - "blocks": 20 - }, - "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_002.png": { - "original_img": "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_002.png", - "strategy": "raw", - "latency_s": 1.98, - "size_kb": 642.68, - "text_len": 5019, - "true_accuracy_pct": 77.01, - "blocks": 29 - }, - "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_003.png": { - "original_img": "exam_paper_en-file-putnam-archive_2009_Solutions_2009s_page_003.png", - "strategy": "raw", - "latency_s": 2.09, - "size_kb": 714.66, - "text_len": 5844, - "true_accuracy_pct": 85.32, - "blocks": 24 - }, - "exam_paper_en-file-putnam-archive_2014_Problems_2014_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2014_Problems_2014_page_001.png", - "strategy": "raw", - "latency_s": 1.95, - "size_kb": 479.37, - "text_len": 3534, - "true_accuracy_pct": 84.34, - "blocks": 29 - }, - "exam_paper_en-file-putnam-archive_2015_Problems_2015_page_001.png": { - "original_img": "exam_paper_en-file-putnam-archive_2015_Problems_2015_page_001.png", - "strategy": "raw", - "latency_s": 2.04, - "size_kb": 426.23, - "text_len": 3329, - "true_accuracy_pct": 82.49, - "blocks": 27 - } -} \ No newline at end of file diff --git "a/data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_003.png" "b/data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_003.png" deleted file mode 100644 index f6097dc7b24df08341fe96dadbd84d7551e24a09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 354755 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%0D1I67Vfr{8ORchyg%|K}zDVm1>m>?<%)AF@rZ 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

D2+75yAg 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껏{=PSFz}0ov)3R8 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 diff --git "a/data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_015.png" "b/data-processing/processing/sample_image/exam/exam_paper_2016\345\271\264\345\256\211\345\276\275\347\234\201\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\350\247\243\346\236\220\357\274\211_page_015.png" deleted file mode 100644 index c6beb4ef7f55ee35448fab501150a80f2842b42b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 427389 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

y`oT@f+xyrkoi5cBY6ff-!fXNjV zd7pomiURIhBkUFMuoZUDlEb52C_x}YQMZ{|Az*UES~#QR=rCz5chRL?gWnZeXHaAR z^Mo8EAf?(y4E9*?BjRPG9S@Q7OI6IPSZSV6AP^ARW&(z+xb=pV!EJNbGb^?hoT6+W zPGx~v!`k6h&E^N+1t2?zG6^w<$Y$J}?qew&YiCGe>4}2W<8e8u$fe*ZmVmrlk9 zTmY<>#rO6Hz)tlGwaV2j0eR*<%Hnm7d$Oc^HJ^rjEV*~^=@8@;H=ftKmfwz=@_=&{ z=w(r*>0$MqoE+-x#6&H3+3Gn6OH{68WzbMmhd4IXoprDCIyQo0j^ypH!v@Dzlb^yk zcwHrvn)HfRJf})%TM-H(Q^0NLG=hLb|NZ^>@tJqT;3X5obti*chG>+^*xE~sS$kVM zn)}gx0KA+f5si{Yf*xVQ@ZsjrSeVhlbVOSEeU+89?m&(z<%cbxrF{L3KB_zNU0jlL zdnqbD`6fN~3ec@;l+`;}CR_ko0vwj(Pn zXT*;@81wiMe490@PNUpveAUS~)$+sZ^QY3eYuKUzr>YxbH{e7Nh^I0~b!Pn}w>|>l z+Vd#$*tSJxrcU5|=`=YZT;mm@jIA#Cv`mfC2JQ%;CSwPJwVDq>)wI5RnoEdsb0`yFQQhrk)rIN*I`)QdpQkUP4CWp@ za6R8+1q#S+llzz$NeE)IS_cxQfwLjSsU|8+Ye}y$m{h9}t3$5wCy{y0Fg>yOsQ;V1}tGBXMJ4)%?Xsq*5buGr^I&sxv77?GRo zwcz|~FS@?L23A@AMLD+QB!zub@Vs(u=A5nEnHfc2MJ^8F?5No!KV! zP`J>@{s}+zqLSN`0T<1kp2VI%CwZcG_%Z&n^YDA^x(>#Y1h=946oI|V={JlhPwyz* zWpq7hqg?7-24bz37>Y4qCwzQUewRn5dTIdJj2+W&c`j*p^bX*tk$V(m@oTGw_D{eC zlGA6eqw}1yX-Q6?e2v{P1)|^b)HTo}SLev@!Weg$C3tn?5>RsU z!vQ`a%cwO7T@7C{2xr4#XA;%V+}Xoh^RZ=^yjdwIP@l5J_Dm|A1&_ZEN~8KUwY~gJ)U*7Ff{&sB&P9$oy~;0QzAYe+RcU?i znKOyw9KhW_YHdZE1(QY7Oc+n^#S(&e%tKTJpkR;vno8qjU1na@9ON!S?4)++>8qm} zTJSIg1ydp z2KSA-Pf==orZE;ry1r(8@<;tHECuy8=;~h$T=%Xd*&q7Y7yacz%)qhMCMI2%=pB?? zr^P+HnZ}OfFWVIty~{tE955

`Kv-rY>2B{%nV{qG@LOayCWGq~rPay_F3{k3aaK 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 KXCFL!^?v{(Pl2ES diff --git "a/data-processing/processing/sample_image/exam/exam_paper_2018\345\271\264\345\271\277\350\245\277\345\214\227\346\265\267\343\200\201\351\222\246\345\267\236\343\200\201\345\215\227\345\256\201\343\200\201\346\235\245\345\256\276\343\200\201\345\264\207\345\267\246\343\200\201\351\230\262\345\237\216\346\270\257\343\200\201\345\214\227\351\203\250\346\271\276\347\273\217\346\265\216\345\214\272\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\347\251\272\347\231\275\345\215\267\357\274\211_page_001.png" "b/data-processing/processing/sample_image/exam/exam_paper_2018\345\271\264\345\271\277\350\245\277\345\214\227\346\265\267\343\200\201\351\222\246\345\267\236\343\200\201\345\215\227\345\256\201\343\200\201\346\235\245\345\256\276\343\200\201\345\264\207\345\267\246\343\200\201\351\230\262\345\237\216\346\270\257\343\200\201\345\214\227\351\203\250\346\271\276\347\273\217\346\265\216\345\214\272\344\270\255\350\200\203\350\213\261\350\257\255\350\257\225\351\242\230\357\274\210\347\251\272\347\231\275\345\215\267\357\274\211_page_001.png" deleted file mode 100644 index 97183707fadd65df1d4ee5e902249fe8651d014a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 459307 zcmd?Rg%FrPt4FUoZf`EX4bcaYucbBvv-5?<)B@!bNLwAUD z*SXp6bN4&vUpRAl?X~XCyzev5bH^|4cl;IQC2wGnVO_d(>BdtjG385_uBBhPgcgi( z1^$ciD@&3~moHsxUwHWUFIvq1KmCiA&>n7G+Hj>@5s~<^ zOU}*iQbO^jb_3Ri|J@~aob5$l!-?$@^EM_K?GZ2uSU*ltsZG@p$k7Hjabppsx7Zh5y?tO>vU+@ z>fil8nY;Lafde@m)fu)QrERhvX+X_Ic@Xtt4!TvxyUnv z1f#MMvkJ|G?A$z4Qi+UyMb*JI`!8DOjYjl_9sjQ82ri!7fy?_+Bc^b*UPl1~ALH6a z2x@Kb(AA>q#To0pt$zcd&PaVh03CzB1}o6Am6G3uHMVXH3Y(WQstp?$&Cts;b@z_BGTfQUAVXAIU=JfADG@@pm(YlrFBm z#8oc)u}`jrT^6aLI=H@{u@HdQJa2v7OQd@1lOV%ctE&3{#;ot5(#!aLW%U@t1bXiz z)Y>nu9xl1i_F3ziuxN%@6VJJ4s?pJuf3IFd72`DNul2r-9mjFo8>!L6)nkdk5lXSF zWg8|C`tyVHe>ZVE(#LSZL9`35rLoYI^O{rwL9V7+fm*8_x7Zp_`$m7f`S1Np;QqH$KDoI_r1e7cRJP?k~k7sw*O!6BmZHXhA?#BN`$lcQF=N2Y_MvlqO124Q=wkbXMbO1p+l zwiKVeZ2zTRXFc?b-`_xBpS<2(w|;p#At75M#*ow(?|lN}-ve){^DO@Ef~)d4Qo8t> zmx%Vz{pf&nM#sp1m(k-*)V(b-LZm%pr(MPJ&k0YMJ$@uN%X|Ot_3Jv}5`vZHFJcB) zcmFx4dF!;j?CyE}toHxC&-X+eSVC(li}sKY-lxy7L^r`y6vW>+D+zb{%fEH!hR=ML zjiRdR(5^)l_GB_%GdoV>xIu1fv|JRgG3&-k!67_RzS6 z12vxT56Xn)|MSk1xjLsx^Zoj(^S}193s=|d`N(mxX-3y7^YV0xhSuzLPw4)}#P>UG z3O^G4q?!NO*aZ6ew+Y!M36{uy?2BA{Q-x|?F1-}rE|U1~_b$1(`V8NgL#g$XJGMnb zsAbzv!`bPKJGcMK!a8`9K}ud;rFo?M-FnI7zUe>DR3G7C{9LtbVORX%Q=8uH{NJI= z%`%XbV;aN{Esm72beFQoA?tMBmW}+j|FZP)>p;l=o=RNR`_%OB&&XSy;?adt3ReTt z!;a;VT&ca1a)cXf&qodZ?q~2kT<&T5pL7S@WCB}l$$gs^_A!g9p;d7gTW{yQye_i8 zw~phEPfg-3Dq2lWGL{ra_~7~KaghbTWGBV)fe(c3(CqiT`g>Km1qOy~?+hgMAS2l` zcO-j|d=Ap=alKAa@8T`_W=ih=-r2L5!??{VN_I0m-dAs_)*=CdLiEyWDy`H<$Bo-`3K zb?EB&fK`g`|GV42+gGp3^H=YxsAlOnxltJf{}+be733E#&rR)OK1Nl#)az8Ch(sOv zDQn8JPn=j=A>956hVO~r6;u{-^8)rTMKP+^`6*$SVhnThu%1(jn{oVm{Nix3lvstr z3p7*;Lw2aj{{69w6NCL~pH2JN6DZ#p`1Zed(_F-Xp@!uQCIeZdJ_pSdSa3 zYw#kP7YEYWX=A65CHfcS{fI3YVPFN|xV?LqO% zzo!~JpR?5CCB-RMHnd7}zn48oA|s74pncZ!+uyhNI>{V%J|$~Q8(OWT4Tu%{=MSD zjRocF=6hKK0?&gqVzO3iQEQLoo(tb`Ogdw@R3>scE_?Z(lG7l1gXnM7)|-%Et>IqRuS{V%{PdQx z8PWJz>AypG(Rwe|i9}?cD74+n7Yho@>Mj<|)Y7dGjyXKJzjb;-nbpZwUzaooues7( zdkFHSa5X0>8#W2!|WYs|P zqQ!Di>g+fRTqL1r5kHbES3AWVm2G00@U8jZic%HTt!45o#eHJ3#Abh#_i-U|`I=YLOZE>pKjkqqEC5)tpZ{CVxA&|^ z-alr0FOLaOV|Ej^N2h4f{tKJ0VQKll5oK+eTj#X5%`W#0BP}nld;b0RZRdK6syp$H z*7vWgIse@ltt+h2->-hEq$MBp!@8fBmwpgnr~yZTD_|v98EN?M(Z;@$Vcfo?s*{%D z$XE<*>(pI{Ve0RKY&2@TYn=MtE=9fjgK+`EbUqIP2opDp`2MQ?-@`PV8F1dlD>O-< z$9lWxT<=`}$NtMz&v)JP5r!!*|Lc(VW(d0YGv_YSz`1Cs%pAoY1c9_{>y7u5&-357 zR=(H*CD*pneEA$NgSvl0t#=@vIn{P}!l z$fN&u)VEvB*h z%@eaR?OrE9i-y{}X8$H3n-Pw^(%gpZzvU%X$u896%vEn6pTdpT>_6w3{)02VjFZ>@ zz5n<51@l3E>(@5ZJKT~!M1api{^>?}c{44R^Hw|b|L$92mFhz0FoCfz?plrsnXAK& zZiMUK7-Wx)?xx=M&fM|F>uB0`jwZ)P4uI!z8vY9UzpiiQGZ z`TxN~8w@*L7hmU1!XBAJ{NFFTP_gy6lmB4#D2g&`PNW%=K@B;(X`JwD2nFQqYFM;#SbKacx(Hg;=h9~U-r`_*PlCw~k3 zQNq-;6I%RhQlK5IvDktFhf01$mZwAu_riCt-o}S~szYQL-gm?K%$qM}LK9N-WTMad z_KPqQiSp~yEM3PjjWc!X5jp$fb__{GIVK4)hV`=g%nin*Xqpj@^*V%HTaNsbyW+J+ z-jT=B9xE@px)ZZPrzzx+w%W0=jR*HxUpvXkt~ws!9A&>WU=6uyAC!6hOj>Bvfx6oB zBm27e>8lIg1uHwwxJV$<+X+`mO{I{5G*>724i4wT{ za&bCEe&aC?n5h6Ri&wQ>h3n>~bO{-HlVwWXGa9>;1B~*kUn)`$j^=n;vGhi}dXNq0 z>yc)j%&*SZpdUPOUz$nW^3b@z+9w|_a!ggV3iaRzihe%l?i-#3qATl{7l;b9ZnRLp zxk7vzpl;Lpj6!L3gu-PJZrY<|i>ko>Z_}i{{brA^dJ0cI zSiL^QS^6BS$fX`y7-cAW`+bG0%8xRAq|BCTLyBh2B5Ln0lCBXXYeZ1h7T%rFj-hQX zi5&^qRzwVRukOxlSOxfS9-7REX!m*JM=Y<^Y=>pvCdhl3nr1Q||7&%ZeZiXkv3BLm z`{n5`)r`+sQ`npw*-R4~LIs|m_tktnXI`YpiQ5)BIlR95-6k~o`xB4%z1y_5n#&Gt z*L!Ik*rDkk;yWc;G+DC;oiw;jTow)V7iDbpH^xaxY-wyRGBe(RV4v(C&-2qgls;clQJz zC>)C_ER!7Xb=mWaA}p=jI#Q!3B z-{iuz?78mgyrh1XRV_X6fKHUKlTsug+(4+4|FDt;{l2Jo-|w|;GvsOm63bk{&n)%k zkKf02YX>FK+u4yMIA_>r_k~1`Z~|ve4DZu1*iTY+wXk9<&DT+_s|utj4P>q^VCO?MNd5|ps0f{Q!k zIB!mU&XX36!i{MbGw(DOpNZ60v+4l!h+KX-oJM34W@W^d^62Q6xtJ1R(a`-&e%2E_ z9+_pFQF&6%5KSo(pD@t`s}KWizeDO(y!pDEz^`l(5^Y@c_&#Zs_X06#GFgzZw@(6d z{Lunzv9+DIm{yV2rF-8}4F(x9*)_#Wv6w>IkE8k1mVUhA>0j9DSqUu_tRp@A$+);i zJ>yCY;snli#s)MVtEN!NZ?Dupl>DB`!QRe$H}G*jHovKMoHgbRhNPGogLr>Te*do6NN?=0uR%VoAN9L5^{sud^WvD_2Lqc0<7loS-Z&h zv5M`w@-uXbN;!28FN&F-b@w3fiqX=ya#w z3hb*~ut_1_x2fMFZ)7z;R9B`W@*(nHFHHT$&W7n~(QI{DPw9S=IHyl-|CJ%Z^>e2` z1W5ZNl`RHOmR>W=Hh$S4b)qo>keL;(7a%dZa6zy1*s9&Pf|jn zP^X^EU#x@X2}&smD}IZ3=~XFxlc=s;KrEwj6tzUYItwKwB`7ydO-=s({%L76Qha7q zd6&)yiX&V4cy$HmW|*iwKK@?ueEhLjJ!Wv(HgC|BjsO$QD~whBUZi8jG?6G&UyCZ4 ztO(Q^u8(NA)HUl4_8`rIh5ci%rjKD_Kldk`EV~qSy-n+f0iDLz};nUDX zq~AC1%#vVwvFGG)i^pK;Qs*K|CWdf;@fylJ;jL{km(V7z{H>agPp@hew>QS^ zxaB)G6fk$ot5?JBz4n7#*HtQ+NmUbFOVWUC2`XVhE)KmZtmvB>f~I7quG)_oPw*HQ zG#ap(B8qe>hfeT1h^gt=vMfU|9OSo7FZRDE6#(Mp7g$*75u`J&0gYjlgZY2rgl?di zZZfiUzhlmdoTlLU_*ntFe-!tvGK+rdJ<$olLm!rIYoPk`qTzKurBuSd-08M|FW&1H zAYr)%Rb+E>v)*MNr)A^N)z8mwc6PSkSOw9L-;kV1QaM*kCqmoJKTx%E`AEBk9Tyij zCN>tiTwb`kY@0CCMD0$!VW1&;REb=kqNn~58&22u231M^8hc(igb!7DCs?9vBwy__ z5KT@_PEX-?g!t)HR>a2N(=ba~+#5ag^=S$Gg;PLg2NQpRmP8ZQiNU zEKts!+dqDihIiuG<#c0``**Xy;m5qh%xnXm2Qs);6CZ_N2y5N1)62~0@DaZqL^vvK z^MaTiXvdoU-Msf9Au8$fKMj`?BTEe;iXI)&5!F=OYkw4vV|m*&0S?me!A~sp``ycX5hTmq)Pc%0<6LtsPVqd4^&JjER%tK1esdWC z=Wr*S;E0zD)ytp2L1*chbAGdPNM)iB-~BFW&WPs`=fkV;-77Q;hF1HHLCW%N(PR1W z)U%^oaBEy|P3E>-Ts@trLFnZIUnZ7#=G$GX;v>3#LLwyLjLoB`hOT57qx}5*V_8?NHeuG;5$d*dpU)d1ZYAVzI3Y`;m>si&aS(=yYXzd=&I*eNh&uk9v%~veXh#r*w{%6 z)md2gJfy7i>5&~>C{6ZeTh2SK=^sCSKtR23nrd!t{`r&87rR}Y8N=`a{&*h3(}R#S zh)PDmEnI`-8h>wS`n{*Hp>QoQnw&On;v z(xJ`kZT#~}&6j2{@7-bQnA^mnQXRf0cDQ%lakd&3c>jEKLHGp{TWq@p1Di zlzZdk>TX0TUdt6p>Cb~u-Qa+trQ7DM$LpLp<7M?RrLcESPfyFrIJ-+FBqd9_e%ta^ zTWhnDG!xeAyv^tz9vyYwS?Z6z|NLVUDBB?xE-o)H!lkpmefu`Ei6DGip*cQ03~zdG ztw;ze81)XmziWY-%#htyaq9$wxA=`2gMT;3lJ{Ul=Ji)YHoU!RYdiF{!oe_+bjRN}V~z7pneG{4jOcl z-o=(E>Q&jvSF7j)4uS8)uV#3kM&0uFz;IJ55WIbIg=LM@?*>%oAV)}?mN=nXKkFW=sJq{!zHCQhiG(A2(?oAQ6PlyHe zbKGLJHl@c1{FA)APJ@BP?M|iS%4gnSy2SwTs?jP?gMS6$h31tPm3+^;&ki8mkZFZ} zNp*ca1;#aRyp2el8#hF7>s<*#OcHvGY#bc+r>5SWuF4Bb`Nn{MM%#*bI4~45xyaLhI z=6>BZM_N>chKAn6#qFBsaIHZikx_^FtIidg;!+PXvFG)t#kk0B$nNSCar5&hNoN80 zE?h;SU_Xdfu24RxqrT(WyC_2+36)^lGHxNrTF|p>&{V)>59crpa(~&D>@a=q7HHg> z1%ggnnImS!uH$zT?HKS~-^-;20GZgwjo+6H7BQ z*~kQ|SJN)e&b3ulRSgXd6%}@tmK&32C=Zz|MgO@(IJ2sss%$6~U>pNaZAq3zS-1e4E0(#I{^<<6r#Bx#f_W1;kE#GFbzgnBe!9H!e#igmzS5P z=jHEJy@JPpmki5Bnwms{f_fME1O&ucRwqx#C*>3rUXiP)-ne!pP4SZoGX*8(pS3l& zjVAQKz`!R@o*?)#hvCp@!=x zRZWf4`b51j_0+C2{&V1{07a!F8rbxD_~?;N@g6>8rSRV)xcP^J`gjgyCto8xoK zdSux)MbNDlcFLlPgqRqjmXD9`1q<={hM!P=VWInG8_5TDF}Zx8;t zy6gO9TrCMlAmFsc@8->$7x8p{b}E_%yCZbEgFHNRszTK_HlFV+BlSxTMqZ~Lo}P`2 zjHodCWHChBw2Fpt_xiQz#|_d#f=%0 z7(Uc%sjExT5zKMD)BnBe+z}oqM%!sXfGZ$vnO=UMreM@0by`~V1W3|tDk@1ToBYOC zC8RT_1peO3Tw|O#cM1H*zBnkT4m$F?@BbNBVOC`%Oc8KFOC9d$=xA*fhhtOzDi*g>lD2;H(y&@v*V>Wu!AD| z(fg6yXBFng3e23Dlb)` z+}1`bOe;(^)N)mh_E2y2@EK#f6&<4ZhK#v3w7W~U4o^;x_rqs=;-Ts7@9)#Bd+e2^ z%E`+spE1xY18$v|05KBw2OAq3avjml{dOWqj22_ud;JGwHxBqNJQg z@5ih!Ribs5HcxK=JcW;sk85jaU|zd&KK&W;MkWp4UXDtro4o^fXt25sU9=+jN*o>4zcD>QReE`k{C zxmaox87XPC)$F&<&Q3V?AzhCGlhJ|~RT2^s9qW=-c?bM%Ls86KT~r^dwML{2_*B)y z>HRcrlquyPN5;k=SU;Q+EB~NLnhtwCSD)F9$6b}90JuH{e45YCi)MaI*?)PirZ#2d z$AcMOpO=@Coa}aXxOnHzoxD6^ET0!u7WX2ba>&PLKb;w=Rm>ydvvhQf>s^FO0Qv?U zL0+C3bF^rhrKKf1;Gs@~DVKHZP1R(5egq@gWwP6~(_!D%uh`L=S?3fT|DnV|-Q%boR@XVT6ZxQ2B&f!OCH!=L> z;N!;v2xGhs<8%b(V$q0V$km^jYTQw`MHu9z+FX_>a40Axs;3pls!zmu``PT(K<7n0 z{zF5muDY_(+4SwZ;f!3k6Wd2Nj9W|!F+cZ6=+)bDJNL%A6R%Tlw~O8+=+1RcXOw=N zNI^y>O-E3m_F0kfYxL!P+%4pk6254;X2JOQcyMsAe#wWVbT|iK$S>KeOH1`N)JoK~ zUc9(NN=iybM)2bn>T<7*6g7P9-Zz_QjwF})@VV- zRd8YXG#?!SdwIX^L#(=k_bA!=Fd&@}%Lh7PRu%v#?uQRI|9n|LI(28HZDA)1mJm#p zw9sQGt%GP79*!GY1<0*(1;50n()>xA-WX#*L|z$PWT%hMb@HvilB|J1jEGiZJR7M; zGEiY*Xrw~388fWq>K*GV(@`5=KRTn=;7#*;D-aOrcf{W%w__;6CCWV!IO+$VGqnAQ zj44ZIF)dvYu2w7q14G|Hu8Oogk=M70$w>fJmC1iRC_@kk$6z%UUKU?yk^Z7Pw z6;#%{7$}heJjcDU5pa#$QF*_yFmi_7glGOAOahVuq7o?=Tv{?KaE(z{n_yZ0orp)q6m=$9<*AGd$|_EL*6TDrDSK|ukg6_%cK zFgSi=AN0Wkq6K#Zs<3KAM*br2$BcE2k&zKJ5J1i$At5m_F_zz~YOSz7-XRhf`MC;p zyhaO#$P%&vD!}xaF&AV*YisMl0fNQrfQInEgo`X!g&8boyU>x<{o`;3rd8Jyu^KH9 zh&Fg;6HK|t!X8$tOrSjj>kih!_TYgkb2NbGl9Gpz2Ho?7;v(O33ReM+DscZMs-@QF zg`$0W>ej+e;4j9TETKnfCD?pjNbIwRv*&|n>P5_|A!{xy0|UBe_i-Ehjj0bR)jmI9 zWyQUD^M1hl4?Ct6E8BFuW>X;dHpcH;5XtkD- z>7?Eb(^+ds#4E4r?Wtd4qXYKM9X=UEZi2e(q^)mIO{MupWlt;Xrl!lfLZ@kH`6>~@JWM9_X3WU;I^99r+k@<0U0fh36}Vw{h!M=n@sX~{xfr9 z&(bj3mJ@f5_Ty{v6-Dg73qy8ra?b7_w@h0i$O{KeA;olx9PI3fx;0wZ^9ENsJN;qM z!@0i4Xd5Wsp=$$b?VEmyr>CbPqXFN86r~EG)ZTRfumG42h~$u^Bl-W#g+Qdk%hE=K zzwa*IO*2Bfk5Y}fxlH+15VmQiW+;gMM(5qUu_*Egv=xjPC6?9Lm>9w1-(}D`LWRx_ zT5bx}0WqypT{`#unZee0qKtu$>qkODf^ThvvM*3;F(ne%>&) zn<%htDg~foxD*{sdf+nGp(F4C7pd#Z%gSoiSR0y|eXj%zVBW%RF;*QeOApG#g5H;L zL0(>F;=qm_PB|MZEBtLwvV_QQzWbyPOCZnZt({CvmgnXS+}zw=zeZ=q7gYUe>n}!& zHxVsu280Qihoqz}FNM(bD(gy!ZC^WwHncp3xAN znC%|Ab_A=aJ|Yf0?QT4gDI2MCKRsedb$#D?RX~AJ{t01(sdWIgDME?-5s`iKUWo|d z8<8yH=_qEO>vV}dAhE#GJ`PMchZv`2HhE-BJBY#c9-M&D-D zI^En_t=9}h=|au>{TtZSYmWHv@Nh?d)*sxBo~q&q=6-8wR+v1yRttj}W7!}GbVf*L zy?^TCVniS5*#<)qDg>40E^ppo+Y8gQdK@X7o7mbCqWjz@`GtpJr>Yw6d<3QcKt`M3jh2sRXA?ErNEeqL4Q@e z^3$WtU6?`3*NN5IQ;g+jL?<0x5*{rn4v=Sg1%;ygd}@7QA*Al4-a?=sh^A2|W#J6| zYVqjbBf}M5x{+TwyNTeiZ=SZS(9Ehs5Ed$C{(1f3l{e-gXc&`cYm1 zcE1WEZ)AI9pZlc_-vZ$>@wQh--+GxWMpJVOBtc`^z@eY#ReWbOZX?x)mdLM zKIY~I#$!nd?lZp~*u{@sP|L4BtvY8Z160(|)&_DMcjtMb)@@44>}sS6^CKP}Cs)_H zni}A;uZ@iUjMZFSM@~#k0C#Y=wjKbGQa_QC>JC6oI%}Zu6xFEb(Xn;CBDK??Q2Prc z5q>~?@8UzHS0x|`lA_s|m|$v8UG==w6+BSesGJMRor0_^OhO&+ufGa+wzhu10%Kdy zh>c85nIk))=I9imuK_WEzSelSkO;*`if#*(LN*o_NB$HjQwylKjp8aRU)CEyxDc(e z`TWmo(DYHbR2}f*j#sTT!}1KyvTwUf;kc=3xa98KzI}Kwd!bdlAl$04U(=+<`?>{Q z0oZV)_*`;)JUmTDFEH=}+kE}}IOB1?0awRkc<)ZQT{B`vTSUMyQE4v5huul@&Pkm$ zcKeW@b>byEf|r-~(IX$BexJME2p%3#`glP`y8b3%p|kVp7m#33q90uL|D-9ea!OL-^4KkG$JdJ+tL%5sAQ=#yH z>4@xYtybYnc8qRuX3%Gqn_d?88^8Rx;iP`U7-!xk${b~BE$DtiI?|>dJgm(3>{`pL zu;uo?BfkN;Nfin{F|-QZlR+VcF@UyxvpF(|^to(KQRA7jg9Ax!8jvM15-JpC&yxKY z&>>K37c4hRd3m8H@p+L>o8R$~>C}eqqO*SxE|=}DvzwEX6MQbTG4=dpQR*3Y67DCM z#k|XjKuFOvAV^4W@f*Ip-_P}c6i448Qs9TJ>6K}+=c&-s!Qz{!w8kJ5EF z&uC&VisY7G(6;TnWxL;c^v#+BJ!)G?6=z#oF*CcjoF4DTRieY^AC9~Vey;9H(Bfw{ z3}1|=Y`)8x$JQ9r>l3dR`Gl{+mbr^X6q~bjSKPEnHib5SO%|CyXc|f-N=zk+6 zE1F9no<|}bNNL;;8WH^a0$_zvhK-$0A#PrGxd4YQ7wYoHg|e+e$iFDTG^>Nl1N zoUpYB)XH>5DJpAy%+4~Bpt`kIX_Li3q(H-&m-;^GQ@wQbm6l|FRigz4fVPg# z1PawcOVs(cJo8-~`JFp_yu6wk8USDcJnTACFg@Mi%F83e^#kx+s8z$k&K}mgSmH-2 z@c}sLEsSe;`PU;aYf`IyRt;^B>@)yO#~S;2(3DXfP%Okt*+?siNevaQpP#RO0%**p6<9;%Nd!Ou0bf^ERXyk?qo7DmO2Y9Gg?oom3II12H@^R85FrN~ zNJd5mBLisr}GXsPu2lho(ku$Vg63uaAhluTM>rj56}gK~6D4rNqU(OTEk)P{>!! zI&CaoIlZ*Rn1o6|-bx=@g(wCKBsrPF*ktL6EKPSQtaf^1^Y|1hP<0IS^Q0sYy%-~r z%eKH7)Sf@ze41~en(HEx(XXzn+pdx`cV7!|RXPEiJgfeVmlaLc@%nhwRyH+SwBaA) z{Ye;~_;A&fl$7-J^uQHm=`-?7=_5r<7{~f}lVKK*nGg#Q5BQr#MhgJN0qzN=_Ewr3 zGn_EiJi{xX{;_`rUv$b8p1S}BLsVdCTAYw$6cO-K_oqGi`qp?NEeA_ZyBDo0m-vTk zg<6DDX*B_%N@g^V9?|rF=)8nqT3KmtZ4J*K028lJ4~o+xZPPCSE@i2BPEUv>p3x7z z1|%TmTyIBtDP!rmTOl{qtOk7XEwmX4N7o*YH4h7p_gNnF8(*lI|Cs5*)a)D_SDwRo zl+<0xG^Q2HgVFLEa?fk6G-B+aeKa({Xer2SjOE^i$&#UzO{*b67S`1x@+g`Q=RG}g zG-7lFO-Y%#;x_Nd>#|KCK>Th}DSu?E%LkqYWkG!K&6?;bov#zhY1SY`Hr4&^BHze~ zx9#zP(tcEpx7PR8ckCdGg`sot;D5dq+8!R`+x86j>*K@^s$QaBuUrY`Wqjhgzq3Oq zVs$Vsh~o6&?)XW~$T7_z#cQ>Y=h%1Sv;l-SVsc%qT zyW$C0+fiIa)khNd;mh)mRY^GaQ2q^fskC#DA{#gJo7F?^Uc>J%mNFEh34<6i<^pF4 zZ&~{6GVgf2ESggycovXOq7|~$iSV$9Ny3QPUPh=OfC6C8OZ&ol!BWrRi4gb_7-WPY z%o6zL5*gw0IUte-QnP+vf!5l)NHYbn=gI`0BKq<5>=?WmP_`>H&F$=VfB(h_+yX*z z%}bBtV{s4QhOb|R!5O9m7y{V|r4E)OOFwP@X=oK*3Mu@6E5z%6X%_hI@X&Yz*D#>_ z@B~#EuB*u$4J4s&iY8een}(mV7p?;u5q;$F`Rwegasjau_QFYF>aZRophJ-FAb~5n zsUW65l#el-`by9Tr1L`?VzL=Avw!*Woxa4>r3=q{Yz+KfC>*tgKr+92VHE|=9DK$9 z^I=MOL|Y~?q>?>U&3$G{5)8U>WcyY=LS0r)dZY=^*2ZDfyiE>E=wOt<+>q)AooT3i{8H< z-33UBBR;52A94s}F^CB8dlKPkF0Yj@ma`dzaxk1uh?T3d0;$byF(w?tlu7YuLac~z z49#l3Yl3IG`Zq^B&b>G$`JhYEtkaJySO{-_mb&d9pz^LYhQr$DR`AW1TLZZ8EX3fg z=7#Cv<)V(^R^laMI`0o+w4gLU*-UY+cc1Ty23##g_kK1{h505Wzi=pVXuA#kSJ0vi zIBo|^qzbs$!-+$#OVM%g^9LEPDKgS^lLjyqvtUmr!^9C;@Q?4`$LgGr>-%@d340#k z*O~GSIzvK0z5wv~jQ~6N%^R=}(*|&o$JQ&V>j?~kC9AB&mDt1a?&G$6x|mZ&$Hd=X zpJXErtmalGyYgp(uwc}pDmFG2RxkZNOPPtMLOGhZbZSM|{jR`Mu+BhXsI07nQSMW{ zm9%E|SYK|-ihk#Bu7EqcDz3_CsotKFN!)^GiM)32V51j<&S`Px!%Pfj8~7 zyu9X~>vn!$+4IwUp4pSfykfC^*?PT$vLtE7-SO5NY{JF9r2HdAMsScI^t_Q<7Qp{J zJcPifMl;jbp8*(>s}c}Xsm|5+coPZs1O!G>QWCVuyQ_kfe(E*$U$n&%^zc3nSoj8`V0 z_w<>rvz>3TJxS|3I};o&`kcqh!*e*~aXJLO0IHFj+v#?%kPtsV`R&^@otKMb7zvMn zE_S1;-rnWImVsG})5OUWv~Ia>GtkrH9b*+pg_kE} z`?O5MloMPRa3O$fkE7+BV2M}e<~OkWWa+{7exRy)KN>6H)=W?a17+z?(1__781%xv z8NnnKNMV4P!{*|9jO218`I%pXAONruG=YMmA|c0(OGiNW%I~i4I+v)M>FHgzS)M#U zom3J&k8M0Lglvd_(l9bHAz_hMxcd6_YvW>fN5^5)3NE?CxVVE0jR4Chplt?BL6F-W z?Cq(86*IPU&*pV~eSKjOi;IgHuwVFA#8*7OR=gSNt2qNM1>YnN#2cc^o_&{~Kbo4F zy1Sn>d7(F+pRRY$mzpF%-vqxCPI7Mz1-alAd$sIC%3bvpnw|*R#~Y6D6~M{rJwNF^ z;H_KDHfbK$WFfXn2h|ns*Iy$dWq5U(^$v*mWMs}@MopTijRJh$5YOD2wpn>7vItvx#pT zN?2BxmN4|;p+ZoMVC;aDuUSJl2mMBZ_mHLEyx2fqec^;UCfME}aIJ&4Oj$yB% zmv9A|KIWe?zoHh@h-OhR(eHXlCpWXCEW@Jyu8xKuqm&3cNOJR^QJu(}JeHFXK# z1F<~*^3ZHevlF4Rq$E6xBlh4&KlticanRT(sHi3zJ>b=-Q{=**0(XQNki-b>5%!#m zg{`kcemP9Kfwd@#HKWHsMQx@IjJV%eR$l(>_iG`L*?K{L2@MHx-%gyQmLo&UZdd{# z;Iq@LQQ3og6H^q@9S@U5F{}@~&8`^4J^ygxO}!toLKhxcm8qNyZP=FAZT4F*7_0op zdQ9yB*KS`go_}>no0$$45O$@dm7uD&)O<%Vqi0(9jE!~87^tXNK3DSSv1s~SD5eu? zwEn=>z#I>a0s`x|P*%;|mdo@u*Ny@64$D8P1Z4$8k3R;0A3#a~5sIC%x2K1OpJW_;fw8?pjNJ}^nn#H} zDM?Af11Nc%wSR_G)Iggwo!r}dY=5($1ivy?It%!LnwlCk0^mf70X9ZPXhe^|`h?yJ z-3vrV5KTaR@96ljtRe~RcWF_+LIPhP5ynnx$eYvfT^|VvdDz?UU6e^?GDCJ?7e!h% zSG=g@TwY-PXq^v|e45dZC;BlP7pr8f(c^p>nbUC%gaMF$VXEhW!pbi1QHWN(Gpv*r zD=PawE3Md4zgr8J96~DX7s%?=zaO>}_+K+nC>sIiFYL8?UIZ0p^h=+NYsOi)McN4R z2B&R$GjdYaI7-N5tE`rxfU>74pCm(PK~f##zQenjzm;MV|zAs^ZgK|}wr>ysKrdBi?0x{dMr;k&et zD2!m!&x4wpnxZTg;16Y?`DdszPw9uhi5#sAUTJr4OjSOG?m9gtfpCLy1F7kO0cF9| zAv=L+>EO^%5cwk8t6%|m20I^~4cbK94@3hZi>d})9fb(im71>Frzy3%r!yebe zB5#nH1>gAB`-~^ybfj#cxI?wG3fMk$&FBaHM49j&EF~nQxzo2LlkQ29R%kn?pdjE- z=nT&FI?T~q$ES`d5o9C-SKI8Jx2emXD@9%CKd@DBy7SiYTSq#*#q8f#r*A|%ZFw;1 zV{v2fi2E5*ZZAHu8sMC>^ibAFmS2Qv19NjQpukaT*#2=btFbgM6=;(8NR;MjxnN~h zLP^t0MY}w0?3|&IR)T;cugtOGVc{|C=%}wV3arz?HxiWV`KB2kp78Rre$|!C z`@J#<#;A@@hY9HL=EG)>LG5x`uZJ-16TDA~(;P??ERkz_IXI1p=;`yM1fx-z%(MMv zokQJ#!(|sLPo3d&_-z8#SenNhKXaN|rKQ|&^B+1i{^OkcQBpoVS!rEi2Kwf9BL^?96BQUZ4~l*C<* z>M1-EUqzT$nKA}Znu3({gG7dUj=tY5|7*X50Vx}6$iHcKt`AZ6gxaaa`edl-sv-+< zxF4nmZbJXspFd!Afr;aN!X*Fx7IWQ;7?`pG)enjR2>8TZFggN8ID`%u9=dM3gJ6|q zDT5IZmyl3vzc%{wrwaJ;c=3^zN-)EEZ5@UcL)+g@HUzs<#xHYLFCR5#A`cz_Dm6rf`vGcHTFK-XcK2qC2|zgG{KjzrR;StUKrp6 z>`)|(l%#^g$3mXmVaD4L~PREkICp5Y(xfvWR9MqcnCo_*Wd)kY;sD9jnbaY_k6Dd~4 zWf8u{MxnQb{OIi^32cKQgG$tzbq$Wpt#1B>h|O=E{4ZsCl#55HU$7Lu(6oN|Jr&cM z8hJ$#W*cYc0BM{}$CIw;`@p^~|GHQCES=)1vHFd#G{P@#$un7AyQ>s!<5a@< zr7Wx|w1V)Ldhuq4kO&Xg zqz=frTbbHpq%=bHW(oQ~jd!+5zp<@>!L?3rsb{V4pC%0%artsZu;(kE*9z^~s>{n= z;h0ypjij%TX>N!9@e4XK`SN>9-;ZRMB_d?SNwJJoJ}DxZYTpq`54=@h3wO9akT3uP z3zCx?8yh`|+>=g=6nWuZL`3m1B{ODKC`czDPJTr#_PiP+mGz~i@0ngBUKjacYV3b8!2U&P+Bb^S7XzMn3A$s!7I!IJYObtT(5q!5*}4DFDP$+-;1e3*%7T7h;zw+G?sqZ9nfi9|+)Cj630>r+|@3KNrP>G_R~Vwl!8 zeKe;#-QZnXMVRWZJ`d^^G-(K@`1spP++7CWtipw)m7+i(Lm)`~#Vj$QjsVbxu|`|l zC{Rflyv4k|EWn+FEoH2r3T=OsL({XhRhrHS;1Q;tFMdMgW;~20>6Z+ztgOITJSD$l zpV?y|k0&Q5$LozSJ|0}=UoFzr;{DXn)^_J&Jkie&2u+U>XKHWDv7cxz>Af+b8!hib z!Dr$k4s_e;mjo5w8}U3zU9nC=SywPs7xdr9iJ+qx8D)=KytS|p1a?=?J+pam!N-7H zX0&!gw+0-IXV3TO(Z#HGXi(6U1^he>05s~XDt5t}@I&ziov&-3!wV zJW*=Ktb|_(0;xk?TN@5b==`wv?N~LwzZm0y0wUKKVd1w5z z630v&>ktwVqUJ2Tai2;+%+haF zU+pdm*_Z?2K8Sfy?NX%NR^>)j%h?u<5caW?1NPtB-!Bjjipp{|<=6V}_mFu{JUzi$ z9)ik(7ZAZp%7yZWpq1@yM^HyYw<3>z#pGz6rG>~NkLZ|(2M30Ec$#6Z9wgZL`P0_H z;VO6lhizznw-?FNd%iD&gTxr$!0ZwkSxfuHKQYfO>Wrh6a{zj1Q`Sz){txP zWf&N9dwY8i4-c65pNhJNz27+5ocO4x_h%P-6}u!V6k%h<9}alZ+2PB7hjFSF?(WB+ zd$X|MPDgXil9>#^tO-ry@USjvXf{%U63PScqcHpIxXCb+pL)qQ&%~&T=&e(cZ^)M1 z*bU+0{uyvdR!i?-y3rG3Q)Bc&SXg+v$=lP%hn1r@cbc{!{=<4AJ`HM?6V<#0CqA4+ z@*o#?vf@ApVaGvwBqO6pcaBEf*Blm;$N_PABqG<=sipNr6cfpTa=`sad-~cKFt=tr zv;{!6UIJu-QpE4yN~fcXFsPaj*+_UW3uo}S{3kYp_cDIPI?jVMd_;>D1^hA4xbTal zV3W`VgBniG&QzWRoxAW_!u5t43S1vRYZPO?Q#rWY#k#6sHC)#UVGAlkjXe+a=8T}a z_s(u2Psavsyi^wh#Pnq0NMb#=Q+9T-@@+oN;qW$jya$K9H}@@9z-i< z2HFja#r;T9<&LeoL%C4P#NKxK*Dx>=(4mNC^z$Zk!%$3rOI44LF=LK*ZkOqDc!cB-Jo}NeNNol-*atUqLqjCeO zbO1b{h=Xo9PlxCS_Ot6rdNS5hk>%g=&1Q&H3AKD)XAJ*w#^-bsdfD@~fP?gzq?@kA zw9U_h!olu(v1={PjBZsEo6v580%W2F4o#@x?z}13IZfcz zM9vZYScYBm!FqgQX`==M`tjx-4`qqFW{EzOItc3d)iOuL-e3?LSXCMd(!mh0{Xi8L zpDezQLx{N0npL<2Zf9WitNgm=X3dyUqYpKem3R*VMXf`>=Z3!o8Rj|mJ@TJ=pE;r< zaB(K!BXLK&=@9MJ8S0Z@CDnINK81xUl9HQeL(LSzLL-um{>G9LjOqAuJQU~xp=tH+= z+UP+`hts}_Vuf=SMsIk7K>BVi25Kz?HG`EPzYYxZ&`X12Y@!BwGXP$oHUl-KMM`(@ zW6rWe-fS?8yA66Q^G$-FiwQV<+koUj2aTkO#Xe585@UoW4cf>M&pHf09Kuy%43{sr z=rG;G4=RI)9F$o%tVLhvGFYYN4O;I5Zf(sSZ$qi zihzuPuco1aiS#0n{hY7iF$3_v+v<|SMYOO`bkrh%~gf+2GuA{ zB~5G84}G&P3&0_0?O}K>s<(poFso0I^BNp$zHl-(r@!Y761cKC&$H6xuIl+FSb)`Y6%YkZO{oM$n;T$1BP<_6SnMXo!Ka0qFv~_xAR`0ED)_5a3@gT=0>D zym@%-=dWMcplfpVdtsY>a_iymd}wh!D`Nwz=(*krB|i-(tN)Me;y+4E!jf zuN7aLs(VU`?RR`MK1Er7>F}&r!raWGM}>kI!B$*5GeS0|3$bf3WRFC5-4aHUS^<1? z#iVvw5F4(@3I3B;v8dwc;GV~T7F$@fSG+g+;OgQMsH6U>(2=Q?DrE8=w!*O=KndtJ z;WzF71&U`?+Che8s_pzPnajt&v!s@iv~Ms_uDgAm4R#)!?iVS=-`&)DV`L<7Hh1ae z!1F&Kd3kyG;-yND1_DZ_&If%cGU0`94FvUtQz+jk1`~NG#@)pq-CI@Jxz;{AcWfbv zSo@)mqye^7I=v6hQV@Ndo*y!x0^WygVs@9^ZvSHyup`rLn6NEG1_X&42E9$viaF z&(qPSv9z{E(3+Z9o!N8@ywF*_@gev51C=dl=JB;Pz7sVrNjqEH$o=bmm_`$o6h{t4 z_*(;_mZWSbdn&kAb`ddkqnJ8Kc=394#|(VJ-@i>ZsX?fg zC1(I%p#aGr5pjU4YckRinuLcJpghnV)~pJ-?a$(`6{zdO@CA9RWfbu=!3I%!U;FfRwRrZg~^R zaHqVdQD3RM8g%t&I~>4u{Ir@eD1YHaxh0081;Jid4l?6}Ov!eT#sl3(PyrAgHBXY- zhxhN#X~oT(6!dDEFDo?X_6GR76oBO_TL#*!N*I%7g2=Z)0~Vp70a8Wii4NNS{{6eV zy9-MDDQhtp#y}8tviWhQq_i~WKqj|nV$;Of_!Epy@ZJ($ya>Q`<5gWZjJ>omGA> zskqX*Eo6^o0|f4sz*WJFoIwi)$V>>E&(XB!7BpI*F+Nv@=jA~!O-4rcpuu&s^zV9U z;PCSYs##cXV`HuEi!YAxiZMTF=*cA?22p@e64b84Fh9)%ZdQ2FSWo<4dB}MGOuP3jNXQ_TY zt?21kiTp{nrW9vvR{d3SlD1EcAkd46jN9jK6M7>!Sry2saJ8w6F~+?biB>Ix30g<* zxr4*jV2%oq$MQ>GpsS&>p-o3W27-BbEmM>@{Qg6huweYEC-P;~Hh79-TJsdimSUqC z!%(9U_^mI?KS4$9dfOU)*;-U5>&HFkou5Afj`c%WiUuYWos% zfP=dZW8njg^Bbkj$~Tob@Wb)v@5iYIt}C!7!==-Er#CVW zR*x^z7!>s$p)67`^A>CWw{Q9%^Z^`~mv+PagaL~|3|j%t=Yat&P|nGLa>PI|xWky8 z0sz0(adLWGzBC}6JF4c}@fOy>#C7XGUG6J>VC%h4Kw9Mk;L9~BJ^k|+_!M{zN}Ep9hQ%hU zIIe@(wBGtNb?5}w7YGLI5r8_P`lnd`T{v}cJe)!813v(7xCjJJ3&_0n?@M>G0&_ z1ZH&L&nd)6bXmq7+#08Wtb`{7OnX0nRHCxB=R(*_>YRgEZ))ixk}C4}4HH|C+yz$} z6>chs3JVGe0iX79!tN-~EF2^Qn2b9THF%1+haR_Fnlsh9S{_nxim=8!s;s>`8w@tr z^8V0PPhw!huX`iVkh~CqqW}9p!?7Yf;vY(dEmaKlwxLm;_M`NbcP*DMxE=Y^RJIpJ8 zD9X~V-;a!p%oL!U52B-^1A1sSE+CyX0?18x*1?WtRXIYYsmi0%b2sa;NaL3$@%*#8 z{YV#;TGvg+Cprn#{mJtK?Z?*4m``#v%&trV50$j}lZY!8x#B|27*rARi(h~K6!f7a zF|L?@G-aF0W5F8@h-=Fd_(Gs6Y(&;XietlIn(eY zI7jBeX9?ORc4@uyUMF2mh=IDDtNWMePpbL%U2BgeZx{tpsP4>6 zO&z$&{O7bb%e(s+A8QF>E#;hn{$4BUsUb={(zrX}t*$+i7jgYyz(2yfdGjXpeDU46 z6xqXTVsA7A#emLv{vabYmH1*ntCQ&Lna)=s!Hw`?Yb>M@leIcCvW}w#uUsVbMr;8h z^qjSolG2cudoJ*mKnj+ifU|g8B}Y54M@x@(oD1OiuPv`W%YvXC3^uVIfw`UPJkT8^ z_gaCtKK$`)q#V0h|FteZx!EsKOh~*49_(xNU}p(FN!_I4wRn=TnoW=wzyk|*r=q75 zu8;sQJ`N1@=>^N^s++rOX0>2k%29~{U=Rzn!9NW!8hCUNiTPt0DvWNRR{iOR~P z(BS6D^5OfU=Cf|r2r0cguR-SeIZggzJ}AryoT`nyw`XyNaBUWnEtmG(C)+bEtTkfx zWMKsQXqGbwek#-C)RpnCWrqY_NGX}JR5p`F3rpNzR$$zc__G3rT zu)sI&rCp62xYIIqksi#$iZK+JFDm`<`tS0jyvbJ?;~u?&<|#{S;JG(gm7xI~JdpSd zu`!U0AjW|RLe;9S@jsLF9(7XIqFMtiPzwo4k2kN5Of*u9yD58Y2}mU1bwFF))6FEJoA`Gq_Id6Q5`dd&pZy z)SHK>HfQ`W{8U|oEpuO-wlm4kQb$0j!qE-o=URI9gxgmJ^gB~-_BriqA|l&><6_?F zDF$fWu@C3Vwx%w2k5Z8ild@RK;{Q0$UHFh>oBv^DYxj3Q0u~~XV%?8&PHH7@&|HKN zbwPURl0wS($}leFja&)Ct@GxdRp#hqqf}3?cgeZ=sN?E@z*pCva87N)ZX3s-xK7Z< z13?20#f}Bwjd$)@3gj^na8r1hLwi~h25reX7K*$WP@M>_u2Pwd{t(uuKmbR*efej@ z^by}9X^n(GKDV7|2AMSxSxB`;lXGZo1`J?xd&k5<{+k$m8niL97tKJ3Sh3^p>^}TD zJ-q_^;!T>+({t z+XpjKOecUSaoG^6BAWr)X9iOET3ef&W}-P04EqcQX8D|MHq~plDz71UjV_i4np(g1T29RPOk{XSune1&l{y7%1N$NOdsXu%Jjce12WY{WIO8sRs#$P^EKE@q81!aNZUaCmWU+aL%$G$ zrn)}o*vrS;8)8q|y3D1o+*!3~X$x@dZEU7e!s&uCdajg79^XvV)Piz7-S~3H!N3*pCu_5q5sHy&_*9uY?P_Nsr zs4A}mY9!{@{uT~Te33R!O>HWQ>{x-&=ZaCWU>&0W1N2&^s~{HC(bna@f%mx^P_0>+ z*yUxOU2aP4p(oX>w>$!)pSjR;UcLENEA%uE>B8|mftUBTMXnhGaGiZtm58CfC1)6b zKrZOpi^~-@5izy_R*lf>x22^O9(I6*Xt#xsZL-PxjkDUI@8aU3qTVPF^wE)#wR!Vx zAO!`5H#D2TdnI$dQgt+Ibyiuvd(;NiUW+j4Nd`YU$U-eEcZBr(#Wobxbi&2EKp;Q2 z~{s>hoi5EWW!0@YYt^f+^s5 zEge%h5OMygm1QI)=4=@o^(|gXD)x3UWJ5JT(F9Z?bX2iiF+2ps&+c2UM&&j-!*u{O z)qyob955!BK-G>P+@{bgF7~J4`Wf86atiuAhv`p}03Br|gm=027R63+6HO7DZ>47e?T0`IXS#H7-`N<_-6?&e4JX@pk-!OT-QEu8j5_=uVm z|A-FGK)*Hbntj$>oI0Vq_A-SI1x0&G^3Q)Zi)m$K2buqoL1iO8g!4K{T;ay5}|-7udNLY zP^x~BX!q&)#y6NAyTbwvLH%K-;OB9Eh0nDmE+E1LwOfLw?73x!yi3BsIMSLXI8SK4 zC38lVH+DUk%JoiqCvA~3W&SECXJAeR?+);Qoop|?V93-$x_}=g^%j7eV0#SDhCG!O zKxUxuQr}f}=E+2VNtb>xv?hjTZeM}H(#_Gatg5Q2vQk$#;^h6%-$%94I~@Xp?`t4kPzNdSAbb;|p+5z;pvO z_fD}}tB%W+V0tMWA66+HiB7<1wjsMfeh4Ic%|{WqFgUUU!^O#ol$s%!1~YH5STNk^RA4XR%=-oOTW1Vg zPQNE`>#3+s8Dcr19~#u@Zu^1sSn5`zcYRcU3{%_lmSLLj|2V(r?ril z)R4Q1XqlRs`3F~@z4edJzn4ds{^9gKaAXSk{iUu@|6P}jq63v$2Cy3UO-%lte-{1D zF$gw~b{3vg*Eco!czM|}TqNoOxkZ^pd*0JjaS4f6s@&?sioOD^IfV*e;e7!SW-RHQ z7`)Lt0v)}>&OM4GMcovJ`4mUK|A7B+lOZR;l?|)Xo18DSxCa?44<0~YBrls0f#r{*7c+#0cH4Q*M(sU-QK zGl-_3HH0{)K;%`v*VrB=h{&(J*s6fIiD)Yd3@*m2ps{#$o3IAs&UQ&0&`VWrtvw1( zLTai6>VHayW`Z#fOH2$5e3|emrGa!hIM3mb1p^wiuJ5%~7a$a-MJp;&@TmNJJYfuX zyUw8~aUT2vIxxk?mUCFz$=Biys5PAHfOG`Dh(Adu&FWk3QsQ119qNgl3JIf}Yzdfo zf^O)0x^#(|hbO2$lK!FL201H$AiGcimsQ%MA0DOqoS0N%k|aEveMbG6M>Qd?A6&1O zDHAp;7YM+xFUFYnTdhh;k>WwQ!Q}WjKmrOmk4FN*=m?QQQqt1H%&IaEyv) zlQ*?}!L8Yv6ha`p8M%q6kUwyTM0lr?v5mMzxo}4Qtp%P)g zF+utz`=&z-7R@R-LP!ehQ$Xe*8wWb))q04W*@I(&T~3Swadx(HyZOZytN9mz)*;r5 zgVB!nhx#+(Ms*DhNQ(i2547wW!-ZJp);dsa2_LKTa0MFNzYj}XsHv%edXkWvC?Y0# z?U$*$%lc@gT082k7ckaq%4qKX=mbYEi3<(syc0vcC__v#+<=ebZuj9*cd zf%OUl4y1&zrVIxr^vPOG!$b{&1?beH52vTW#4;onMfwshi1qh#i4^mBq6s+N;87m0 zX{@aU*qD^#rkGe_ua#53HcbblbG!?CrpCkSq0==Oi7M_uiN<6z2=bB$C#lJorlQF# zI&31ci=TYZhu?7$z5zUs{L;dD*ouK*A9wfH%zeOPWB559f}yR=EifIng}7B|Pm4yg zxazfuP^j6ZS^?5L;LM-I$jl6OU}QCM0#0fRF(lk=+*;l}*U(G~#*+CjI#1#|DV&vr zYIG2_uiQ;^*L#H)au)0>6u*}<=zAf7m-Vv;`nPz_I&2K_^z;PNf=MZ4m!Hf3;W&Wc zn{b+NzCgJkU$6w#QyOHlWB<+0vL|%2E5O2wT!?ZLQqqRL06u{3F+y?4*+U*5%uGP? zl$Oh95NgVrOmx?zWVk1$;7-Vx3@E7yH47FvlN>@tD69=;bG=Ma{` z1_oH*xeH%&*jP>agEzT&*#Mod3+_VK28q+}kLQk3VsY{Dz_o#6ae?t~>qPK^zi0Tj zRTyxH*^(|nR806Ukje^H22uc?4v}SsnlNLil89+gAC9_6MQw|SS}lAFfA(0qw@G7I zafGcSCq6hN1)NzUx_$+!2tS{v)@9({2UmqaU}j$zq->D3naH8>BE#ls{K^CY{AmQW zwsm=9WhFJ~ML?`MPizZV?-XJD8)u-5fvx(-JT9fqNQP}p=GtRvj?P#e*e+BdsMvdM zB?f35ZqC-HJ+R`uSYBCyRWvC_fa!2*Q+P`-MqO0$F@KY&L-Mg;UUAdh`AI5Wlrqd8 zfItzygY*o*^?v>QSy&9IDsU=i-B&NzN1$(^uUzJG)XLJb2IUBRS&HwgoB2{KSF-}= z#{CmiO6>4Dx#AOD9I|D&g~756;-ZD+vgnD;OqCQ>o6#T_?zz95VTC|j+^3?V$ZItdIW z@tOMqwc?bg#6PZ!h=@RsM_eUA0KsYdm(XNCur$29y;t;>Zo!*1KHhpJZ}$d5P56_} z*HK8tcP~O73I%6IKM2qngU=He=;&teLA=qqeNRs-$VC z?NOr^oq<&iBB}(kg@S6|PjOZOYMhG{@O@>OSv66e3+`}$gR`q-VPqt6c`9=%od=bc~wXbMeuCtZqCkL=y#LJ zrV48Z4H}5Kfu{u-#8M#=t%76p&rnCe^}Qqz-EAiU`qx8$uRZ$~*Oa$ujqas-9|bxs z2w?<~WGPs^u}dE4+dFJNt`-Gku2gg28g_&ciZZ6vDcB&H;Ige`(CGjJz1qUjQ7wqf z>xt?Kjz7bE2!c8?exOX?18Vape~7rtw{-g~g4q7ee)IvXrC7_zVo0u>nNf*K09X~A zk#JfywY8MZK&TgtvNd*{=GQF9TDqbVuj{Q>TT9y!0qq@I3w`*|+CCwhm#msR1qYvqz8GYBs^M zzBR0QJE%dy2{l66#sL1<*RTCDiotuXsNvKj6wmPaIJ*JI`8aR^3ugm3^$iUSK<^|( zLk!(D2$4ay!|7b!tDFOzDtw4aOGjL=ox``|{5-nk3<)u<+xTPDLi2+WUmYpp-`thJ zN$AQ5Y#^GujwlK6tx7|wV5%-MwSR7{j`*@8Ch-cr*r<5$pw5?gKCt^cekYtX{+G>N zUFlZ*=f66!@pMvp)qn=C#hbw5 zZq*7=cxHy*KrjU38WMA0&P{3W5k3;n`k1YibSYJ<{^G}BS$e6de?mn*mwuHn;D4N8 ziBjG>{?xzH04XUbWoY$b=69@wmj+5Rf-X}GhXxVk)U$O6t)A)GJbl@0Av%Ogbn$=% zlX0wRygfU3-JdzWY%F#v*XYCi3vfwoK-y4wMa3>8;(*=@?q0hQWF5N z`6Edo3wIIT1ZYYq^&(zJmKpT&tv{0JNTzIum=P(kv`no^vY12uh~IcF0Jfu+S>fdx z^;u4@HQ?0c>5-ZIT#6%h4+$WGzz$p^NP{h1~j&dp;_7cLf^;Dy7O<~)1bu|m5T7h)LM%XMwCRCEW%Rm z-L0W<;Oa~HO4oNiMmAH*=CH;NB2-71@1_58L>b8?TqPO1n*0V1aqu|$`1rWEKz?u& z>N;62c{)9}mAbk*-~{)hRdY$%-j9@%f2p9gW1XGy=dR4_(wlq+5XkN0Md~hY7e57> zE3Ff7Ndjrk!eY_*Nk3|$jJOK_R>13kZUK#BqbFUhG4nc9G$v!a(`S)f2qFywF=lwNsQKer64VLuhp32qY&$_qFiy)3SQ}jF zi!qO>nv5m*y=6g2>j*VXT{+>R1jkx@+~ah9CBa8=#ACw{P;+t$bpwnpFaj%bauEJB ztA!2|G74N7XqWc2Lx8mw{L+f71Idrav(bz zh%>H7`#W!TVM7FPg-zQF<~#xeEAvjWAqC2`<3qrEkub&i#=~i@YCh>E>q9trX_bCV zP2JFV21yOjNp+2Ppy$aiumqW^7zw81GP5r^nlyUoX(z%D78OM{TJ#3>kw=|LF$4xz zXucjlc|zRX?UJIKW`E7aN>2~?wDWXbfFVn};DH^2j0qmEkuJLcNe3sV9Vq6z(2?Vj zu@27mCF>A7(d^$JD5=4ObuR6v$$b$${<^kTLvt%jV&JLzE1;@^f`atl-2lrRnEbmf z#5CHxdFUbr12T1r2He35gDej8B+(IrqwPuKz>k8vnOpYi(TW^GB^H!-9eU6r9YkB5 zPt_p`>vNPs>I!JB1!b zb)Fe!5v0W~#xB!n)98rZj^%Q+EkcE5BPk?BJ`aajRua_V-*GTNCz$ulXfazNnR6T< zZ8f9~O5(Shi>#DG&iE-*n+0b)AI5_$sz>`CubS0GI;R8w`L-hbkt4@UCMRudJ0}+n z@q=a`mb`ZzdvtWS&zOlgykyz3lVtxMJ*vMQ8^!#V3|j&4mm)ju1;v0s$Ox!Cwe|~L zEdnI}(@VjHvfzBAXy8_T+Oiukqbb;|2p7P7pXfc48dfnXtKF1)<(2BdQL!cOK( zmSS8KRi>x~I|Zn;{H(ZE6bgpj!7%_~UeKTwH-E1o>wpQ}@wcAd6!HGX}us5H3vv=mK81x;k(WK4Q3dV@AO)%c?T0tzA}_ZWzOCJp_wk{o8EIR$c~$_(@2hMlQ>tTacaWG z-PVaEM;IYs#Sr;|#fw-6O8@|VJ~K0$1MTSNv!BvPcR3Lnm@=U#A{><4tJkY*_2Qt=A{ki!YZ8glT4BMf@=Uyg%-xU|b z><6=v77~)Ez{_zT9aw3T3dclY8>uISRJ&YX3*8-@ynIae7w2$`p20Aey=LU|)kpyy zk>;~&N)^5XBsA)%!6MLOz@30#8<6mcipFD??597yR_6i3D3En3Oez@3-S19DaD;+i zADk)Lx+f2M?@Z_1M^0_(>478z;V5?@da@N~m_eUgNn2|joD(`n7k(X=_E2<-I3OI7 zzqZ*SVwlD3Ij>)u3cb91z^)=>-Vr>?Z~GZxSHa>CIgk04|DAQTJGLdG@Xv(~jVygu zNmsD~lh9AbTFj@yL32b!zJ!gBq@Ao${PING*PJDXsCs2g?UYoN=|+jj+uwFwwht}N zZoOVupwgD7I<>eX0B^BjmZPJMAV-Oq0wjVVx}`tO3i>@YA3GQ)5VNBscbV1?j5A5U{2 zG_K6dkd@X0LQ%c%Tpf_5D8g_~-9uxLElfFHRbTG`De#g?5@yA`+F8gR2p1K91Br)o zjtp03%kRFbhdHk|(@8~XAg8z({^e6+(&*(}HCeBt?Q_311m7uqU)cl06DK_a=beSF ziWnoa1|nO5FbKFKTXB%hL0;@X7{$SC^AmfuS@A{(1V-pw14MRs?d;c!X3w*uYnX(5 z8xUduqp&GFP=cotWh!syg0y=-0e~a`uYgse7bxlButQ zg!Av=zrQoU=~#aQLC~4cOBiH9X3&JXZ9S5l$(TE0mGDcZcGCI~>6)spRP%_x!*7_x zsLu#3Nf*d8@IfxY+1m0pYZLCr51k8O12}pxT*M$aBW^}qo|mRBF*^ABLR;R(2{i85 zrEIF&GPT%jxifb_@l#}qCBmmNsRKuGFNd0iLGldTSL989Dwb_mbN`lnuC)6Z|0N>> zD_;E`ID0T6K^ih3oN!-hcwO&F9GcZn9Makybg@aGHWeg$aF0Nw&wExql@#A2{E@jUG1 zo?dvhGM9dRWt>1YhF?fX2wu{!eSOn)&j_=~kTH=g!L$&%o;U`3C0E1zMI2H_)&tCh z2}|!t#B~t-^Y&}Rf8jM51knk}l&h@6^fFw+inbMG!R|rU=sAZauh59%VvLoBs%2-8 zSozw_R%&55HQ|-qsx5jih7>&6Qnhkd3$whuq*(JI;c=es5pSm%i>KZ*<+W44Y{gIC znf@V;%QhhIX;xB^p9yNMb6N=Y;Mmwo%9PlVtg$N?UIW1xehoZos|*|+OY*+dkWajg z14?Jx5YDzGC-zIM`|hP<_YDkyyGDhAKjp{({DEuD|G;%m(#|`A@a0y%z@Y!YMF6rv zATi{e>ksf#o(}y(64C~ak@pyW5dVTW6;kA$QU<=3&qs}AJ-n1|JU4=ShnotNCIIDE z@j8yhI?4aWz}$ZA8f>Y86_`nC$h(LFoS_G^?z#ucjyJl zVJ^~WiV)&B)f|m8zw|?}9>$Q4cZ|^xw11=T4T@dHoUA)rTOiZsL zNT;Bum->1)t4N2T*egpO^&QQ03sKPI_283Sv;62<8d@A7Q)@ZK9DEny1ZsOhI&DOF zam>KyA(9Cq(|hUd59`Q_H{D3=c-qwK`SnsQGg|+ug$lC zh?#RuJR}=IbSoqTo};O+v7NYjL;{zN#S^+0!N>zsY;$=zPDcEHTR7op14BNjh~^v( zBsh~VQmd#P$`OyZGyB$SG2bijidN<9IlP&h47v%Iak;7SoE)xKC6IU~!ORM>iI89z z7hPSyJ*fsOH(=G)2c8=x>6^dP0;WyE{Vpz?? zj)erw0Tql>noqLj=FguG{h{Q7o1Y`X0i2ClWkD!2OG{wF&URCp7x&MtfJT2F{SNXa z^!Ol=&!xbxc{MOITEIE7<;92Kf0L*EXD+LrREM{c*5U*s1a`a=wj0EEMNMD+S~+b( zmilaG_p|qKql(pdz$xkcyYX0yV$SlC-H%`YqINM!d!xZ1{%i)fvbH^F?6i<#& zpARTyJE9&dR z_l*`Sz|9WgB=b)Y+MDkOK==DGMF_*^7A(@nuhIW+jR^G1T33z!ZaiBFkhvz@_pa%M zYVA-JRG5X14y8q=wi`le3|1WYXTK2zDw+rbVo0&!zP?ThLaVBiOi2gn8le-LNhD~v zK{5Mr0$Ow6fWa2fMUwJ(3j!Uo;CH)z2m|;(WjEZW+qG(%$(YR&o8KBo!fJqr&;(N0$ZJSqWQ1z zaHwMt988tlXmnmB z=i30CqpPb6;O#XGFz>5}K~&_S2mY)e?1O(a7*L3fb>L1?`?ERo_k&>6;!K`izBfk` zo|7@4yBB5gbzolvEZ0)fhFnNsW{r|#qN1i6J;BXSx8UpD#>q+;6pW=HN=}gAXOe~O z#`g{Zr-b^vdLN^woyN%EViXq=R$o-Ja2AM?n=>B4DTajShZLtdQcAzGl=+jwu}kYN zQpkNO1U|rrP$2=ph3YlSuz&gozFFrpHJ}1!VysN{=Kc89i$Rh3N{fk*?IGd(>CYw2bT0qL1;z{Nu2`0JN&_T#}% zV4`z?%t=5jq3Y9vRtYdL$k@@Mx;V9|%?|mK=7D^|;BBVk8qhAI9C=a=Dl-fBBp?Oz z;8&y=VP_NlpgGI!BB{X=tBK^j*+g1j0zmG$THRwG(Q8DR=mSe^fK+sm0>ljVFEvax z0o~VL13QHAs|87%$ZDB^5$Wj$(SZxpH97@J#=R>q)*51UudU^B9o(cqWCl}TW<(Cr zM&WDM8A*(eI6Z~E9WdK;-B5*Sc-v&g8SDb-B^jl{C#e?|e6x`d3~5q&+he~FLT6`Y zLGcwt;U~wQj-L7CUO8xe-Vnon3b;@pJZ@-cKt$PB8?`))4G@2gZGU>O{NPj8{?x(t zPsQx(CT+}jud)8OoJ`hFFyN`ZI8u^Ym1;L-yilkNAG0@v&_ELQ#Z z_Y^crfa`jC!Y*X!-v(9Kpl$8`gE6@vl+Qt;9VYu)J$pQGexJ#0$4H-U&cb8+^bZ(| z`ts~Qf-HIi05Gie+8q+_Vk_?4c-fk#|!ffTJ1Z0}-h;TqA>)2jm64XFR| zE5J4gTJY}@+qA0|8pGxsx}|$4nL>@ht?Ym+f5(q2NW~-bK~h zoXM>!V(A;!#pYtU0_}O69}I9 z^~)Y?a7k*QFX4UR<>dvCCRF!?Zg716`SS;UL5NtWk_@7Z!d1MyJhXk{yw`rWU2hz{ ze3R}wUD&MWu z@sI+Cb-5-J{ludajzUc;M6xFxkRsT@!?45#~wl@rS zHoUHR$LClh3B6HlnYyH}U%*xhP)TtF+N1(oaEo88AX->5in0NcM2m}ovj@fc5UJO3 zUftLRMC3tUh^B+En6e>1z zmto!i=i7aekyb^6GAY@TAVA*beYqV|Fm09cXZtQgS8w|2WtX8G+_&4;nikjEaL7qX z*$s?_tDvO@0YO~o%+^iP9Q}7NN4aW%b?=2E3m4em#pbz03rte1K z6hPXRj-79;2^dIujdvA~h4KMczOF`U@#?{AhgG!me=ZqV$!WwhTb14Fn5W~%9l(`X zB0c0uqf{zYS6izMk-;Dq?grm2^s(^471sq$F=)uFf+*%8%T1AL7C`CjFQf%q^8%OY zg54F|yr*R#6o`iYea*h|{?*Q~gDMCG z2sIgNY`s>6fb zYWw!EAhWf#+~6m0@qjzS>p$bQM@GB|jj3aN-XFHnaLm7YdwBu!3(+L=jVpBgoIr03Pc9HgtUFcMztMNhfu(I z)Y=j3YXJ!n=nAK&Vc#(X`aq`VGS$((kA#b$7_PGwPr9y~Xc79oO)8jE?dr+EZ30Ic{QpMK=MT5M?_VDMc+Y!-HG2z~+^n|`W}f?2WpFEM6uk-k zDXdEqq}GSvSTxD+pE~MzQ{&7Lpk4CH{{_WjzG{-pHt$a&cS^qC1Sl?x_cIS}xmIiu zagsbAzr5uBLwA?Fq3tb!W{5g<~0nH&SPm&du$q(XMwD@r~P5gR= zX0Q~u88iFH=~wFAHzT%M5;YGsim3yB%5oU0FZyLW>C$v;9iE2=n1;Uq;*9bF>6EIh z)cCDX;W>3xDX~=4$S9fT-MyZT19&#hr)%Mqrw||@tI+e-8%Khfm^jZ2HZFnb>s&dW zAq$Wis9oW7-P_xP0~VfYXL??5u-uHQz*dveF$f$k6ot@n==dm3Peh;1T4pk-np*gs zwZgo_`Oa}Yhtm%hdBSERI3GaoH!NvaZ3Ji#gav}Q@l_*(nKOw1+ECCIh8W^pti!p+*O{K6KazJi3v}u$3d&Bh9v4v!9pMT*UPvxJY_z!#qS&)N>BO5X~LL~H9p1S zk>4mnl30?3k*s5;@1V$E{5%D<(kV)^cg6m9-BtoV49t(!C1Yf0#H_bhz(n)j`&3r5 zdFb$GCM8|`*UGD6^lQ>nyU6aWvZ?{@7w?$&?u76NT#?G+=CEFIVs|mxF?-*!xo0(OpjH7@#|IvOBZk9 zmKyg=+)q6E=zmfE;o7$lJroC+#d)#X%*BZGzjt}>-ZITgCMR~_#HW|91k@ol|9s(( zp4V2HzzWxcAnxEeBAW^Eo;Dt;Fk@jAOY{ykxE-!UL#G9|E@x0g1C~rO2E)QgcpPsq zX_+b!B{!Wik;Qo#nzcTB9pd!m8r+eI8mQc$$OSRu2@a?5pM{v)pf8kb4zIOCbW0*3(;CP#YA5F zNQX4iR?6G`IyWq`6OjLHL$OHfzQYoxFIj=g>1g~EOdb8KKRNT#aLkZew9mMU(Zk_4 z`NLm~Oiob`9!6c+px_X?5>z#tzeGb&pnb$F) zd~Z|M?_}gw`ab7Pih1e&TBTI`@@V{cX!Bx1l>>iIQ+tH&-L#a)qGC&quPTOP#65TR zBwUr8^JHIS*c@8CR+*sGv0>}+QDm?H&Uh%@i=Z11sfkx-AO7i`%lguuy)+puh0SHs zi)-zTXI&&V^M+KAxxp9(*aZPjY^avfRgF)0@(fYR5G@1HIq1J!q);HLmzOou<7Ym2 zQr`ck=xIJA3E2h$BKEKF(RDcvr?$;9H7I zuJZ$C_uz*EWgyl>bP{p(VPzhS6N6!QjODqTVQ=^%#SM#peoy(2aSJqlto-Tzeg$(;Tq8lsDy!)V z=?PdFV3+2EU7FK=75hf8jOOas9^P?R&WR;#c&_XhKdSB7fgJ4Rn_pqPg=ArvvB2^w zI;wSf*>3Jew~W8APdyQ89G0?8KAG68u`~qKgqd8o_O>Wn`|-CgFxS1*x2EJ0z^~{z z{BuA+!eeMT_)%Dxcx_sBgIninA`SObB_pyI4G#)aBcArsM`*fRDu?d1>Y3alDyqF= zdAa*kbM5}F_^FS!69jnJE58$PantRS{}8Nz}@zqy6>LS4|Bck=O)9T}MST&dDt472IWdj!sBf*bm*>GlItMBd@HwJ)L`$ zaPHG^8kWlhi^ruBHqTMvf3Ei*Iu>Yj51YL8tjLbNSt5lKzKf36R&Gk}*lXW>rpfl8 zD_qx-{(cVM*bB)4-fn*RUoXbtjUGUHZ;2h5EWU$uz3*g!*<1a?A9v^{qv|dF?Zv#XkFt-@R<4I^CPr2AIRj4olT=K!lEhFnT4Sbb zn4`->Q*~oJlzf%pCY7(c^wvK zu4Fu(8PUs~)Hb9yn^9f=UL({mc9JdO@JgSVkkWneq^eQoa-ho`R%+1_EuWF6FpWbs zJy70C)SBy!m+QQ?Z-{2=lVcya`Nsz_^PF`}5s79HZ`35eb5u2_*%p#DS0r;O_-@nZ zr46Gd`flp{t!bqNIXvWy|LP;q2aK{j<8#-T{uJSKl_pAyKdG?H06GxyH!zRlthUzm zEqS&-{eC~#jKL|3F~sX5rq9#I#EQ$C?QhA4gPln>j~(yR`EN~kmm3!^p3454ywrT= z)AW#w{@;mzoO=tp$>2%TR|oGcjp01m?U-~o@0mu4 z#(#^He@nKSz795?#mK%`H3?>OuJ+loKhyTyHUC@XcalJ8dUh@4`0iift5;v&?cTul zCPdj;u#AXpf=FFE6@^f2%<%vMm39SauqMdweS;NXH{t>lTqp0{OGskjjsJe{y@hDNKPL6FIz2&u>Y+P z$47kcTb|he`&EDMo>;J%W0*O!0+dZGq6J)7GnA{|fWH3j$n_a`)KN*QBhASy_+ zNyR8t>ch6&AZ2$HLQn79HCut;Kz8Xmdi=j%8oQHf!K%o3Lzy0h4A0&;fsJEh8)QMK zBVT9M6s(f4Z1K?lUF^0`zGFrhj$E#ra47_XC)Ge)^$` zDCF&b+o+SoyPXclT?792$}BrWv9fE;;tebl#ENO?>4D(*WTCtu`u{#5Y1^oSHj&lK z1KCa$rF=sJ{J1TzOP@XdzppQRrBrV@4%@e|vs!PTY9&Y)u(&Xw@&Df-vsd?8W0?7Y z&z3L-dFB87+hy8$kM!HhOJZbgauG6+^8e;g>c#*2k*M~#5+8yxUW7CSyR_q`6{<8W zw)nI0ZTkQI|G{=k9GTpjSC4~B#Db8q>LmaNwT64LR4gA70O5yk}V@LGm}jyN`;IN z8L1@6UCKxjl9iD49G|QETle#N{{Ovx*B^C{x_rht-skZ?hK~LbdYH1Wtz$@R>`TIk ze7>pWeCkH}HE?~5vj!VhM<^>_#MK@g3e<<~QV|Goa}&DmBkx0^uCz6bTcBQ9H;!{6 zDBsFye36m26Wu<}eBwX*i5Qkkw=0h(3I@EAVv0E6le_tYN0Iws{O5#Hu9o7HVk!#? ztSd-$Hd0*h*cx+@ZMK?3uQc+!&@VU}p!>}qMQG!slRI2L5`o%K5wVv?RwK zt&#S6FM+!(qP3z`%>8Zmfj%q(9MlAG3&C)vAAS3eg*moJK#|f?IXhf_ z?S0!TFVM_Qi^j&r!1@I63fZg-6(_Ff%dQ&92;#!F0oVZigM@jmshUf$x#>77z35fl zH7YMBhsF`6)W|d=9}XnEELaOr0O<%pm0b1>RDn4Kq*{TjM_5qq(%OGKr*i~{M|4=x zmW3PUug@`u;cvEH6%6rTX3Hbqt`#N`jq8|$pa{4n_+;;TRhZx26)i9pg9aCFDU>jc z<$mvl2+G2d&`H-qJi9M<5ZdHDKU#`@U3uY|Bs#uhcaDPp1KqDmC$#byFknCT04K;M zqVbpv43Kd!IqCe+XnKC}w-pLr)zznNa*xq9)W}}&s?J9@{3njLu#|&&90)3;pgJIa zh68w#28g6}r37~MX_IKF5w-czVgH2&3yG{jTtBV5Br#P+e65MqYU(Ip=FL%Ray$p` zupvc-Oc(t_$MHz#G|EJW()Fr9d*xG$I!AVKF;RSJkl-s?@X=v4A0RhaaEp`SUK> zsC~7uA8!&CfH2)H83kRt!Q!5cln2U3&$JFZc!Z&ShkFQ70p}F`)W|HjW>%Uy63*Nz znYyX1Gn*qgh|4+R_wQxFRS?cdF#a%j54RGE0V#A5$dE#>2|6&06|v5L{y8q4ybqK{ zS=r%f4>)|m9M%_t#Kr4Yl5iW+Y)8PYe$mqs`_$HWIU;3`(6&@EoQ<2--3fC5C^3G&I9c<=M&i1zr?D|cPk@I3=8Y5=no9unqtr-D zOz1m+k$@BD)Lie07Ar|~O|FD*D&j&yd-;zC2j`zCz zC;A?C53zQDku>E3IyW;T_RO4jHc~Doa5{up%Db}|ADb>cAeQP>_TRIxl=YS*zQWch zTW@aE(fca%7pwsgY1H*WJO?Teo00^{5_AL;mhoS^tLL=jc$Rzp*TBehk*|~Fb06m>QY{20}fGG`Euj<87N2E~8rYsdy|0ww|kMBq0R z)I>D;ZVjK`(=OoO@tuLhC{zXsIhbZx3g8L}QApnltc4y`%z`(~$*#>?xoTs6vdLI5}X9`JpUKCeU<5BLS8H9d?)pUmrR_i*GE(K~HNehLkw4ZEni8 zOTmK|h7$l~0*EYJa4x`DV^&0yriAey^ZdFzTP}m?df$bAHb29gGv@i73rJ6|_BOfa4ZM11ms9Zr$-QhKHm5?vOR{qx_Vmsh|oY)0 zdC_ZNNB?_$y->kaXH(k66VX_F+o80;HmP$2EfN*804JHVT_ySX(1XXfXo0G)t^K|v zMI$@u#TR71V+PYwV;?LQ)oRBJRaOM&9Y~D~w}TWH8s61Q(?#}ONF0VyHC((1sr7~{ zc+{X((3(P^_BE#T!L2&r9)_C$WZky!lx^vK5k zHdm8QM1HP=0WX^*DHC1dvO}OOlgV(_0TPH>r(`E<2$+60(gKrc?oPNN>sXu&5!OFd zu%Z~(l{$X$(b96z4hxmQBfC(EfaUP#t*c4$0ixPPqR|>bNKzU39%w>3tt4hW33H5hd39KaU1Z>8N86*~WeqVOJ&g zSj1qGVYd9MGf}gl_%`M)jGITMkqi6K$mGNcY)gKpy1KhTi|e0&{Uwp%3A`JN50Gvm zujVM5GB4MaLS^q{J*IisN4sI{}pp^3n=l>y!QwJS49P?O_XPQ_uj`L;RO&L zti(8K^)@43Z^%Wn9p)u)F9ACieq_qQAi6Ydmw9)#>&nHKCHAqez_y@li`O*>`)wx~ zW0C9QbI@sbGoZYtM@}{#;mOn2_?|>{nD?4r-7ZvW(31Zy?d9KA%r^Fvq@28wa@!<_(hc&m zZd0T>A5jz@x0)YSRLmn|wzNxY;6wmR?6=M#7i6Fnj$r- zr5!UujEDmI-+jCp{)#f(Z;4<>0;oVseIUMtLK|ch>H=Mug zF+eMjo6(Oc3S8XoVWgtarBRlZ8qE9nIxL9Mo^Xu%f3+fb0scx-75+P!^e`&1gkq0! zIh2}^0BQ#8_~H9za2$OsqV-Z0l5_+08Eg`U(A+<8UAsxVQaAv9OEAk(!;6|%%( zxZ#7w${0PLi^-1b8W@F()yp%>uw_N|=lWGaJko0W-ridqI!G+He=nteYz8jPWn;Ih zWL{69Oz@M2YZ3TaaG(!hp(KKx0e{KMOFpJKjhE44>-HALpgI;K8@tn8cnNN+Qemx5 zup8ke3C-YG)r`$<)Q#95`n1`U6PK;&!pj5P|{cU{RB7~lH%>F=^W@a}Ws z@Y}7y+YrEVE1Y5Q1Uz}VyO%y)-2rkI+JYFY6xz3efvbZ9q{X+3ikACPh~etca)yQM zMiO26ngJG#CsJDZr6^WFuosKpuxV3jN(wA`LCK`Aj-5|V&cXk}p$yA1C#M7{v%^m5 zi7r#C{PAAOX^Z>c!NS1L!`G_AF!l8-n4>5cAoFA*k*w~&Bf?Sc8)B9UJ^S#1+bCue z5*pkmvtTOE7zo*i=GJwLfw$r}irh}4T|F=l)P}(Q5zTFaw>VtCQ0>>?knmF!rE`!bLF$A<}Nx>8JV*{Yi{TtV0zr@IfA?Jk>$i z!voZRxExV6;}zZCR2X>Q_|n)V&4}GKRAj0{)B^Fww#T+TmESPYT|JlOmhQIgsm6P^ z*IcqJ*Qgri6K_hlcV9f_YH(TMMv;TSDMi-T-$i@;+`SZ~Jn{>Qi;E?vK3w`-m$ou7oYL{SJK?6iH~=jBK-#h?Na;%VMQ$`FE6dNGp5-S4Px+% zFpljs-4>*@P&|&`P0Ya>P=Q57jq7in_Nv5*AJn6-$ z<>8_w5w7rO#UI9I4raEw$su-Ypd}uwMG{d*=I2vN6KwcKcdi}S%u+peKbe;Jctx^E z9ahArx0RK`bacCPX?|hBxN{oc{P-~r;D|qh4FL5$6vqYzFOj^OLS^Aj*EUD8^ekUB{brze5q0=Sot+$t!f+%3|4v{VcWvS2qsW! zYiU^-Iim5S!^}x>#W?LcahQsw>ySxwHm_&iY5l$ewf|kgAR|g~{cY%_g6nZIES-(# zo}|cww0wk1=0r1~b_B1qwG|IsO#rMeL}$UBM2c(R%)4*`kqIkbJ-eOTKh7FIx23rF z-8Z<^z~>5qvEc_G?KyV{gtV?Ml$-c0}H7bS95s6&JO$mJK)f?Rtj#Mgjy7EWrgwj#_9v3}O zZK1sq`Q-R{@~PlPVkhGY_j3FwKzY3W0e^>OC>xtH)&1A5De*^H_tU8R`!lN>&Mr^Z zuSwNi6|uwY+Wp#1!H2>QY;GX`!@CfalvCRo)RLGJGVDIP35ELg17%z}mj3F| zsLyg(#&B?tW!O-8;fO3_p0{Jl7Rq(f_>X`2{r!f1(Wi&Y9Sr00^T+#j<#;UNDj=@- z>E!2k_w7&UveCY`O@h&g(&t-pvI1#IIZ^MAL<_Lh*2SxAY~yj#esg>`iN-scyLW2l zt>Nz%El%%v(+8iL)Gdm)##byb$}w*Gy7N4li(%IU(~kE68dJlzLvjlYA=ADRtS{;& zW_K_g4C!BNE>|VyjG_<2@4rrb1wJ)<>CDZ3zc$LdV{yynwV{0f@BfcKuu^G?@`nHY zrCa#lkw)AoKI7U-ujE$z{rFyF^!t79#Ph|c^2opQmGbj3ZBzXIeTkGCqNW~WqkXaN z_fMz%>Xw`4)x+f0Xx{a+Ym=~gw1E1;nu&pI%kg)`qOvy&orikCc4?1~FI zJ)s``cxbBYhVj2Y0KfGrkd&qhH(oJUi_Xf=Hz)tbEhDz5KRMk}Ot$=yont$D-M%Zw z)=w!f->wU-vpDO%Vt+>9MKGQQl}QfyAnv6XB<(P|kc z7Jfh^)UTj@Ce6ua%~wwCGhNaTVTMWp&AsuKVQVq=7^K!zuVknc zNY*#Nhvm>+$?n~1Om&ByM7Wz}%=j;v2#21EyvRJLviaPOZ=ne>=WaxjbN(GG#CV!k za>M<7X0#0RJtNV;rh2a8V+m+$D;}>3U1={j4r+Q$oYgjBi}JnLi{vh(w; z4Q0~1M!yWiK2LWF%^+V-`@IhN;al^ zop4L&uie}yG)G?fcZe=ou~dwYP>-G1uehAA@My8Q%`5Whj;iSE$|9Q*I#9PifNjpz%2%oGpQ-oYXC)VdQ zi&#RZyu=(NXrVyQZBK+3R#FoGwOm^+>d$Apc$kBlN;B{WJ}WtoDX1!(b!My zh|+M9IHfvdFg~T73op0+iL%zg{k)rEv->9!TKg@MzSv0dhazoP=2y-4S8$CL=Vs=# z#Ia;#I=W?TY1jwxEb8@tXIa@%`lO2{y;BB~jfZkZe&M`8OO1mH{E6R6ZD$QR9tYb( z@aGX~^6?|C0ftQ#muAGcaVXlx#s~*)w0YX4fP~zCXBDr$FNaaoUas&o`oOWZDK+s||K1HtnLKejRHeQ%Bwr_9 zg*a>AlQwXzZnLpT`dQJl2wQ6GZ#WT-UcffzBm-v>9316S9p!i+p~cml6i1pU)cn;w zgdx?weTx$j-j#RnMyd&jWxqq=4kQi&0XZJH-d6X(#sZ9Q;RfqB59}+B7F4-S0Q~p_ z&1`%Nh?~IJ9ZI2ZU}X+E2bVnfdR~U@g_E2yH8))F;Ps2arN~S8agwj-7Inh63d9e% z;HG{E4BcHRasAeRrqia4eqT&D(%iC)+-DC&XL(fQ0Gou^0KjGIHA^9i z8qx7Ufgc&e^c=p$a3Eu$_mL6_WhK#Jw+9R+K+sO|^RG2pf=hqe1V@I_t}EtgH&NVN zn)sxO9OzT`^E6&A+rXz!8C|20 z%Yy}t7RIjin(c2~p*)dEZ9RSeU7Jk+qZeR!7-(cf*zknN1@5L)ZInsUdzglpAmja< zSNf(s*8ZepvdY#&VF6Vkx;OaV%n zo?n#ziUFs#H3kW#jL%JrF5=XtpfEP!2Ha~vo|8EURtBh7AvECOdF(k?3=uBBqYcrq*Qn>O{Jn))3dxZ zgY&ALod_J#b~kaqI}Ni)*w({|0itpO$%crk;W#86R+2F0L^3mLhz`GwNoSN_V1D*$ z%1%!C#dsU-i;4q2Y~hWT4GCSN=qBM!xx%g^CrAK>a=qbymdQT4{ln@74IBr4| z>GUp8IURIoID{#01z{1!0Yh@C8(01*RD2aUaU)_noaLx`^S{zR-(MAg(MDjbbg|*H zI3u9@1sR>E31m<%vi`MH(+n;qXfHyTfhI~P3`}<6R2$LAR7YkGiWYFM>PCzLccKZ{ z`JHdy!X|2$R*V3H!MX#PYb}v*4NcLiT`$&30uF{M20$+Sjip|QliH=wNr0~u_>S0- z&Px`lML&S(WnpegFYiaZ_gp+MdEUe(iJiN5msV7)cI+nXf&>LI7OYLzYW_b{%E>Cd z`y=)`5*;$AmD3S*EOH&mO$Rb{McLb3KZ=t?PNQD~#~e4gw^Cr~x&y)3qy53*VxIml z1auHeD`oheBeEK5PG&lqSl)Q+xvyX0uxJpf9+C{WJu{1iY>R9Vh)eX0exjDci$hgYS$H7Ry!7>c( zkqI|A_*MTJE`Y0Oc{v=~ksO)+kCirS(%3}$-@&)Q!fVs*>U+_=c1@1Zv*BT!5uXiC z!584&S%kc#w!-f~HszXVOL^gbXB0=kCBS_P-&_9(d3k#;ey_KjAhJB5K9z&kJ zW5?9WPyea73O5j&)Rj6unGGM#ITgd;f}0tBVep27T&!>e$nTtZloWwkXSQM6)M_Vu zn$V=3_NYR0@`^HFmM(Utq#X3-(F8&uwy{{Q?fYe-$%`n8E9P>Zvv)h}U@V31y~uU+ zfN_Mx%nYAI5;xizQ1;KvH79Z)U(e$Ai@5o)d#DOrWbfD_NtI1`KJx5=vdRAx znY1iYW97XUD$+aZtBXZ3fY5{_x*TW) zwt91OJ{Eek#1(m2n1k9#`H5n`k8i}UPIri#q1v?ZO>~%qemJlZtZ@kDcyKVz+G)Fh zp?Me_h=xBGi=LKD1WxTxIs)}$zRZ&@iq;7=8G0Z{ugD zX=w>=?ojc4U3bGWS^!TOEfW$QmcCD)EQHuFmeMp!>`zN_X6f=h?i{@UHKz!yGBmM1? z-a3@lZsEw)wQ-;rvrFiuKW9H~nD*)J_i@VCP2c4`5Y*M!aMCgntXx z4obchSPUym_yWH?eY(<)4=>=ev63uGLln+etwfd=T9=V1^ZNB`XdpQ)Z&f4f7X=Zh z-i$jDon>HfBrjF~0o}Ls@;sO32JvDMRd`$!JvHTXp#e8WFPt#wfIb@TX7KeV(RokC zqzbSye6~USvJKCNgtE2y$%6l)DU_S><|0a=w9j!(;tboZ`J=Gs;O(lslzO2ipjXgA zwuD~t>5tx|80$xXd6Kmnj#u~0%rAaEaKr$U9aaJ?cP~_o&dfv3)H-;=*chb=P6UaX z5UW5fio1r3k2Fwe@)i3oq$PGvE2p1KI(6?j?WU2L`77qM)GJInF}rfxVbzw9oJ@1X zI*iZSrsAXgo;~ghv-c>HlXK_Ras%9hlO|MTSD)6XZBgeR5OFa352oR(u!2%4EK+&; zjERv+zZSimc<3boZ;GF%kh7h7G~5y4P%N2P>Ak#!G_8R6Fo{?$B#U9ZkIl5VPQ<{D z4|cZCTU!NL8R)mx@|cLl=i{3r%Tb)6*M@gVPpi|U6gL1ex`M)T|E6U(JG*D27cR=C zKubcop7&!jQBngC-(vagpCFqa4A$PFj+L6%4IXLel{P9Y!G{*r5Of3BbWmX!-9da) z(e2wc6T$PU5;Z8!V*Xow?j~MErEVI1F1vhP3y3SgC_(DL3Z&Hz1ii`CwyUId5czjF z0P{pt7>l_rTNz$^YJqj~@L|-!2pbj|)Tc|iacaor7t~WIzCAq9Ojo9dyW9k%q8}^W z*S&t`RozNP_YYsfeigJS0t!7VnFw-P7@HK%j2NY$J8EP@1`*wCC7rBFMivVGJa}J- z)83__XYgy!dFR*kAOAulHLm;l?bB;g$!gXNjh%4dAkop6BO$AKyY2%Y32aP?af&fD zu`r~*`yuyC3#gcON@I)9Gtnd2` z^Z%Z&)bvR+Rkczt+H5d3gi0CPq-me@iI4M-?-q&B{tN`YSUNQ#DcBJ@_rEn!QKv%PeW_QqXHp7pg_})VXJFHdGx39N)D6GjHhn zUd(q>m6D@`BKf;Yc4_qoCOH);(S&Sz93`on6m!VX^lMOEU!+~}&W475i64ocmxT6h zO`)y4###qeIF4&(QAK0PTn8Q>yqOf5#Q1lm?_`Ryow`J$+&QbZhgH*Wl23|x)w)&t zA8gPwdvYcyHlbJdGbzhcP)6`a+;emPS9X$(=|T6Ki^D9x4)dl~`opk{@8W8Pjo^FPSv?n2ei?ZVbY7pGeNY4IL?hNa^tldM+S{h5xU zt9Zj@$YE<&z1qXcVbN$h!>xRgk*=ximhxkPx`(b=|G^{9pi;O*Bf&546Mn-nOycw2 z+S8wn(>L)SV`Tm^a;N|9Ax>j5$13`3K`J|L9n*fI`%~63%W8X5cF1x@uwRaCXh!d` ztkE~F`&j731s{@B877$?FKPehl3DJ#_iUQ2c~rn7H_q?YRg)x;t4Qt5YAVpo?YQCG z(?j3oo0~h-MKmT$+9qx#QEeCMH@-I8DIQkfew0*Kb6Q-ze24t%)z7F*HOQ1k*6$+6 zX(LN_<=DDowyoI@66NeS$8TJ`o^>-;ZYo@0`1Kz5n+>U{l8?t@qdBfhHuO?u_3-nu zDDZ%;}j(S_aVf1Q^0><3<{V{AJ6*d@Xzx9GyFW;Q9%7yj>6@=_-$tC zbI&E|2cr>g*Gq%!yWZ?PR$I!RI?>}e*IasISmA@(-)c%>H8$?iUc+^*5@5xMt~PsC z>^Xh%=T>ctq^;yA(U$msaK_4P3zh&uqiBhCl{kj|J>=zO{DWmmR^H4`JcYA5TA;aD zw5w#jYMUz{U^w9scqEFm?e|1ipNLM=1bJ0+Y+2*`TleQ$gtbk`?DTfE zFnrz@^MiAFW!LAu^-@~pyHs_9M_7YPCUPHw_bfUL|G}ECHRQRUmG>N1&iujF-3EyZ zSfL;KmGklEDywLkrDO3+SNpZvY1h?NAM;iYvQ0YGRboyaPw@RH(dc^Mn}ZzB&Y)dw zfr{l$HCvAH-P>CyuGmb*v$;y<(9W>sD&vce?|W@t^t3Sy6sN-;4bHXA->OGJ%?WeWMz5z@N5DyGxy0!y8LqaUa2xL!YWL(+Mo2@ZR}5f zsmr#KS(e|ntR7%3aS{$h9lS}8BmJA*t$;1qB$P-KT(NOfhGW*j6FQJ&)c&7?`bY!P|$yXj0+0%Iby zFXq=NIg5N8D(@yJQ$K!U!QgkU$;R2cDV(Kcvz4Eg7(6J^x2L|rtb&d6cY0tf*Ed%Hf#aZLk?n9j9 z=mi*eqV-@E^_3 z$EyOU>BnN11Y0R2dru!;{&Bd<^l+SYbx%ZD1&aM$yB0Ii9@#u4_2 zd3<*(+8oWQeIzLo0xwU)Y%*4rHPv~3M zUdS(86STkSsH+KVIrQ>COVF_v?>Ke;(Zh!;%hAhd=2YXU9P#e`TN*AGDZZ*aL%VkU zmn_yO>vy9UP+{tes7{YinYyY=?MTrE`_M^-^nSl9_1RpqY*w<*{~{!=m}A-%btY@) z0?)wVp49}nD>_F{In2I&`vwdYXogBsn1p&XE>JqT>inQKmi_A*Pc6>b+S-B+1A^rD z@A9xK0-sEr{CR2)tC*M9-)!sAhNtm2Tj$;*0_~0v|}nj@BKart2wp-9{!o zQ342rUZnRP^=N#RYzo{8wI3Qi6dma$A~)cn0)h%|)zkAv>!2>Hi9rYE4&j&mYiHqoFjCQ4BVR!m2aq<=IM33{1K(jOcWOPPZ+1vTyO8EQbUO7iicFkq;YslPxuzV?Y3=tL zBF!zDoLDDQg#TceR~bEgyaE`4 z;3Z>1Bx_ks2iyfdrJcKzn>lI?>VyXb4PPJ1w(tYhJr^GtL+i7`VlAg7(C=nBY=?P^ zan=|d*lN&RLChIlGAP3yK;}YR9~r})8><&9!w(vVm^XL6jT-0uy(#Z&#GF2PUh(V3 ze%4>@<~_|bVg|-(pKr)j)Xk+Q>a%TOzpACJ9bJD;hWkpLxylGr(EeCW#Xjfg9T^rp zc8h#FR_hs41435>)*LW6R4&iW44#kT-i8E%VNgvpTm#{ZhrZaIw*X0PWiU(;6NssN z{~b(Gk;c~Bo7QF{-hlO=sjkUN65gi>))HWUvH#Ne*w9d(ZPK`229peF;0v1Vx$OX@ zF&n_Pi?dF@L361}W<9- zWG(H2(~j--+OJS3J%1i1+Jd4BMMtNrTMe{m@L9L_Tg&&ZEh4X+jLC*B0a?Xy`$R_>@3(j7TcEbdsXAIcn zfHV38CY{a4u(JU9Mn36+8+Zg1fh731Ft4laMN`X74!99IkR5jGHP?8lIw^=~2Wz)W zg=_z9AB<}&f4f+;n!YA;A<^m6#LcSG+wEG0yE!chUP>fGMwP+?`k|Ll7VfG`kmZZR5Xj|?bzujR6 z4@Vmo?Tl}MDv-a$S&9pGlsGz|A{w01{TWXI26u>wk?PW@eR%bY zMG=PZW&l+^nsFFqv(Nw{))X6X(||KfY&)l2WG|0(?^BOPa}b;&TI%4U{kD(sXq+E~ zz5hxn1~C!wFI*$~foq0N=xjS2HvoNxc5c**z&%EW9_*SP2M+;&NE+POpnps5(9a6eknT0kEMZg-E) z3nprU8sRCwCI_?zz@jKJogdxE&!?~3zr6xo7mC_)XX10<)YOAIVay(C>d~wrv_DeO zq3N*WyyELj?_Znt(cvKfTH5NB{z^rit81;m=*9ujZWlN6VJ$7)4rkhF954{at|oxK zNHAt7YR)J%B#k^PMhZHiHv(Y@#wMqLzcJneFR9rI!lF8H3UvjAxXK;(H6oAM?)^nS zi88!G%sBhJKuK2q*B-;FJ5b&k-GL>bc5dGnNi7IfKTo;q@5BxkEda)k#rgA7(DLbv zs7JdX0V26)0jd+C!R>Ww>!no^WGRg^3KbUEQhy3y>Tm za1MtO0P&hz{ky3QJ6tbIaiQnzg_BOA<|#Wn4TFw{4|k!o)w@)^FtB5FpdU;vbK9Y1 zv$I1GVRNx@p1#*~ff-0TY66p2%@+7s=>IACI5OQ^F2J!xV=l_#=zoYUZlx5IgWJE; z9`lcKuwiLE;C|%s0MS~*%Ndy_`q3|6!hQ%%A`A-TyddOqdFgU2^(rlkFf=}VWkA3c z+Qs&DC&^zVEb{?Xk`$Q);abJVD?8y8ck=xC_G0v}5rF`w;@3kDL|cMm@$Md?S}edq z4=zD{HFdjF8d}QqYAiVaBZd=U*7!9&QN`NNQGr3D6_3)Zx=2Vvhz*Jr9KF#S(#mZ| z?*n;CC8J3FKvqTQg;$!tJReWEd4gm`$nN-9b@Q2jEy@pvV5_|=+>lT>vgl>jIZbdd zZr_HeL0=@$pVJam2)xwXMWO4U^GA72dj?@I=ylLk;Kb`+TQhnAs$`1XPUQMCY*amC z%i#BbT!Q4$`LSwry)gp1MjJk+q^73cxIt<7)qZd?^Hr=Vz72|`V;{H~gml&}sewG@ zQH9;IYm`DvM>BPKsb?8)eX|Q1@t|v*l}3jRrNQ~vk)J}+x~ki+i~KFcP7@SYj`}T; zN=Rb_y?@AseC()ik(bv{GH6|)!IC{fN54*1o+GX7ZHpOGt5%wEyK0O3!9+EorsUgrpKZ($X?^qtFPP2M) zm19S5wiJnGg%`$+z6hpjhK|s!d_*V*h6#hiXKz0WmVc-Ue^VlwaBmz+@di)a0U!zc zim{oQ`OC8d2}dO0XSSKk2@~bisRp7mw}GA(Dh?0_VIIsJgpjSvmp9J%Q9S{dDa+Q} z*!|+O6Py3j`y3M|RudNU&4sKHjV5Bpgc4m5AlA#CUN21IrLxwRg{&T3 zOUr(6kGR6StG$<@wvQHodKtyR$h7?YxBC|N%I@EX`=s5&_n<}IJ8o=bl$4r!Sb!B= zDNyh*7fbBpHL}48NeiXX*sB;8x(pqMz_5xtonai%n=fA=p~e;*nt?|RFIIfXgLhKI z!JaU#7=~K|%J}PJbuW|)L+Z0~Y%^YVZ&>~IFSJ;Bh;kS;c;vnaKvyTP;GX-jrvaV= zyV1rry{cjL&e{+q3;^ zWT~(j-`|PM3{Y#~qiDAf0_w^rA}oPB#w~?rB)BDQKI4=DewC zob?{|tLZOS>e(*LQ4mp4ZRq8pvWaL!`WQBBPYbo{@cfov7~gL~ zn2YDwf?#!BVu3RN4NN*4 z`z3}INkRM7^lGY+4WEnMkNkidplzZ2#qJCcJ{OC}b%2c5|b2pRPZIZX&a`;k~5My+O zB29>8ll#iS4aN6;7Fd`n-mo&BYL~Jnk{{}Hgz8gSG+O~eyoW`@7QQVXZx@c7%ng$W zUH^IGxq8*18@zGgiUou8DtXWm@~E_70YM&j$*7}jwx@2j)}Gw)NVAr-MVIf7u%Xu^ zh+wm^GD!wiPxKgPc*jfHzYaQ7d2PW>pV{}~vx!6_wMYiB(@8mnBWg{}1)L$wzVj0y zyYX1mIHKcUbxiEnQTpOWomjV1*jMmjfW(z{WqpQY8_s{-W_xhrn97DvkJTbVcewA~ zn8X-&$zay*{FdG!<>%?{{Azyz#FQWwds7avxt`$7_qHjy^h{0_2;6vCcYklFZ2!B> zt=oqJ+NYTWWtOu9J_SltMni8Tem$?5tKdK5-e}BFCka<*x@J348sTW zpVf@Wxxd`+lgxZJJa?bUl+!8M?OrdZc7JgjzBK_$beOzk>Wat|3NdQ0tlreGwzVj+ z(ql}2uW$7cH;%+3%^NlJ%f`sL7OMAmJo=(`E?*|CyF!Iom682_O*-F;>y;n4oAlDu z%|2n^-B4*6y1Z`eyCw7Lj5kp%=E^(O^HsTd_vG!^;r{ciSe2kRUwtQE0i&?MIg-V2 zhLKS#LnM?wyO^w+=-=n2bLf*=gRp|TMFSbNnZ{n0a20>`s^GgYZu>5JczUkt+)Gnx8R<) zTCV%h0$bgI_)Hna$1Bu6x~nU@hdh(i=6$vtukAH`;Ff*;df_g{{#l;G9kZv}-Q6NS zZJ3`5XEylXt*-FBNcSX}qObdRZGz^gY}cQv4FB-|g(&I290Ni)_5bLiZuMNG>9+o- zBz#S@fXS~f;gJGEuMdlDT#g%@yI?Fkbn&iY0uZ%eU&Iw4-N0!0rJg`J>D z*0mDtnCsev^M%mtx_&ikE~g=}@g2L+wnf8L_2%Y@#)O=ZRvS7l&!K>?tA1$`|9Yg4 z)$v_dS>vIZErcLSX1#aFgxlGqtxGMtNu8>zCz@WB7B4JcdV-0aLc4e}DJRGF$BS%J zJ%j5;e(f2Do%p!uJUiPQC$@3#Xpy9AHt3}rQtHoed}sTofEc5y|1wtYlOlWRV;=QS z=b^(t_Q|i?l2$jKZJX2^6z@eXd9q8|jm;#9{)%l9=;y{_3k(k;wH=bS-r~JX=bJv| z&uqe<=(5*EZduS%{Ts8wY34SIYq_h91FO$`xqDD{!!KWjJ!S7oXXJWzF5EA3*}kOg zBJM%rPEgoByCH=oKCS)Jh4DGPRet6DadWBdhx0vS+J#*1T( z$^Ywi)>JU9O@@?aP8z~tQ--GXVetM>)lU0sQ&iuunMpP-sy2!@D5gq* zOpccM16qZEOQEx28A4^Nor@>F{peB>^zDolta`KN2d|U1VcagQOs`k2Dc_^^(BhAO zaqFu|>)oF9z1aRlyA*^|j=>IuT@#&U*o?uXCePA|a#@~z)1>J&Jq!zGc`++w1lnBV zzy496)T~+Y1oy^kr^2YH!}0COy_JopojuoXqT%DyP<#ODbz5ycm3!+NiT&I@gr(@h z`sEI(J3V9DLg8dIVOGwvbm+07M{X1m+2R$(Ti8m8lB1f5W(# zFgHUS^-YlCTy*aqd{r{`&2!Sn_jL4$=sn%47H?!oUaG7qB7{!`*^;-zX6KGK0#(}_ zhNER;CFn}RVuV6r1~4@D$z8YfpKIRHwB?^k^(*4PbJWpkMqfO{nr?mVZp@WUj#_`( zs^_2S1i!XkTHi}-3u09vKA!~28DSy!CY@}J{uf24-=&I|`6xiJnjl8zc`MOo! zsDESZ5glu#jmm8Ctuw1yo3R*gG54)A`|jTfLO~T-IxUWsh1(NHaicq+|ADOxH(0IZ zlj4M8_P}QLt58%p&yK(3Wc?ELT2Gg4oJFf0=$iG4bhYgZaLWKddW+xv9Ix)mPnIf# zKwBUscGb$kp!-*YX>CP0EkR8dCq*>UXj8wnGGh>_Gjs3RI4c;n<#A*1>sP6dQ||R% zNYh#w*w4Uv{`iM2JsjsN?JMP2FH<`lFwrX9*$^UbFUI}SYu_@H$nz>Mtz$rT@2y_pYJ{gW?yoKl|2RsMO1=gtlsKYH)eF zdZ`l(ep-K}t`d~%=np}N^!Dvr)R1++PZroE)h6HcoyB>2mLcOwrD;)qKKO>$_R4Dw zz}iKM%c1lHf&Zw9@k5 z0f-;q3{U{FT(F$51=EK$#!<%#KOKJMr!ZB1}oz2ih|t)Cd2EMfR?uCddrO zo(6@jz6F{qPP=V3k;{yxnH29fSP=AvJ&C(4PA>cCkae<6>dtXdo=uzDUv>jHoWI;I zRm<6X9*wGh77Oxa$s|B5nQg$Q(9T0_r+^>2bfSUem9GmC_@I}E6HtA9Jx*WBonRWb z#P5LePdXXBU{$tFa|kT$hTb0TJLQC59Ho18h+FXp)O6`Ok=7unqFOhNRM$+PrdGOv z0~-FYn;cxPfKt|;9Phg1Mfh_JK#*lf_yTnT<}>M}oSD&C=!N4P$D3OOkK!Zv9usbg zI_p*Wu4!-{1uD_j)`kO6Vj=>_@P4uDcD7C8L`VVmZKRSC5@3d$<}_~VH;w*M%oMeL zOECf+$d(~0eq#p5VavqfzIjM+(JNK*-9N@2>w~?{u`U(GhcW-(Q|&Sq9U&h^KYhhbHsk|&`tN&sX68Ig9eb{+@Y|TfQ%pt%UE{Udq$l!F+7N{8W@BY~092JD*y2L!;rRUSacmH~vzMS%6c!DwU^rCC^hZv9luj=#N zL=7ClbX&?jYaC!GxX-tZOj$->u=g;3iE{YzDdNdqzcv)aRv*@+ytkcDdoe1>az8z?HuAcC- z4s|in4EHbzaY82qd%yDXXN6WbD;ev=Z|=KPQdPy2cN(@fQlpi!9EcV5YW9lkKL47M({3(dR#p^%0SsYgRq1JxRM6~aV-_+w}^IyyQi!Lj>4zbe<8)A_UP zP-q&fqa92q3viw_=~N0(n+)pR_AD$yK{!-d$w5&p9%6{#U>XkU6@cuQe-$kcPt6hQ zw2LegyDy!OlwA@WN9g>0b8HcX0ARNLfnJ`Ahe!FNM+{2+kizvIlqAvI{&ul?-h{&4 zS5)Lux#{$&uNr+6Z|`MfhC+si@gn66!SFC{3JL6<@=kp9Oz@ji6QCB}JbAU|{K_DK zjF-Lq8zLHkRbAJ3SF&&S?#3gZ93g?fa}fG&ih449=# z|7;cZvD#Y!RDf^r7nxu5q5x=+1;pp{%F-*L-w`lMz}1Mx7!4R6_BhGF?`zJ} zR5uod4*okt)KtW}AAg(!(q)nSYjKzHpel`?XD9 zX0H3RuyM-y!jjL!6ASw*Wq*oIi!6uT>X|L|QMjqFv%-Qm=gk@E(xjaZughFYc6W0W zt^ed0b2I)$_WhES>uVcN#--h9%C7#jp+&f*ex|D<&ba(*2j9h^wd0w;^p?l>9oY0Z z&wk;I_USTNhq9TyqV{9{qRPyyyIy<8xO2Jm~jyfGRi2r)A1o9s`PXII zch&Xje3_h|y6>}?v+;SyT+@YTMYXC|T%tUg*95!<$>zsRurj%scQ&9Ne&0^O^ie%y z)ljfPv|2aV)L)()aUkH4vjIf=dsa}bnm0_sjtL*?4ZhrF6;BOZzt^o(KA=A~o3 z=Z>lXNFCTR2yn35MYN~Ta=ESn`EyzO5WIJm76uhiJj5Pahpzp=09qy|&CPw~ZiQyZ zc`cM-UisG|me%UjsViI!JDeB#_sYq=alK68B(Xb`qGUGd1jQ5dFp=t!@+EM?d^BI* z&#?>0v4!guT8lu+AXnXO&G0~5_ z@9W5!_mmvJcKz5cuVbrHnGj18cdlz~SF@^$_oo^D950KSj3;;NbM%RFkbe`NlELmiMY+}Rt2}0@7&eNoy-dLRRr`AQ?8&}Wul9P?lgd4J?@I+lqA0d07&D*HvAD)m?fSuDUGHwgp!AOI=2c0)P#v>4EAPtOF~IYnhB|xuKcmNM>lEEZq~RVx zVv6HAIyb3g6Lbz1vbAOe1zwVNNL!RO;cUB`5*)ukh=Ve~YdZ&h2Vzcs7()ohiV;gmls`8r^E zDDBUi!Iv^P-MNeEk+e2%B)D?N5xo;t0stC&1xReH(% z43swV@+gzd{Oj4uB}E^^?7fNd;hUSDGM94rad>a}H&Je@qyVCrdxoWiVRf=&a zGf|Wwm&}VB7wqmnUkH2;M~V8SUB%kv^do0RvNbWKAVE@CpM*00Il#4!65A^X)P}9rfFDtktB*_HfZU4J@}kd&XO2v* zbz4JqaJB;vVV(>H)^6@?uOoUi;APU%t^*&t`&0I>j61%e%qh z%=TL*kNxa@_$<-EmLq$v+^*Z@W7e+&Q6ioea@WF#!sNr57`FI4er%j9O7J`X)9Wc! zGFPc$^NUDwh}y6!Rvr+z`r*`=_xFv=KSX7xrfdCue8RfJ!FZz%ca)ZdxDnD0DJCjd ztAzyxA=d3Gu5y{Jb!8&S{At~SCI2q8ydQE0&_EI&_W8t*L>ZbMn7eP7J|#rD=e1z! zOAdoJiB6j1WOMtPfbV>0@^;~G(`KOguR9aje~g;OXt|?qQ#6;)f4(JHVH`m`to+f! z(~?p4KyIVx8s~+P1G5AqqH65ciEW1y^rEg^pjD}FRu;1PDt;}}>%4{8Oi8Y$n^}=# zj9A-8P0C|3v>k=KT0vR~3tIP^MBkl$$9m=H1nY3~2uDXlTEj{AN;q{w{?=T{-23{@ zC-K;%q1fI#)mdYDJc*I#n(XqD-&fX1h!)?V6}IsxyfMwUdW`FFvhfTliG2D`7Y)B= zloypT$NAr{s;OjoTs=Z3+q!NiB6lT#O+v7whO$-5SM-_h@ctNMiQ;L^+HRfC6;^-s zZf!Kbd+;*pLiO@{JsU~&v}4~>tC{TDi#5Dh+E#+dD88*1J>Ge#=zYzh?N!8q@RRL{ zLiao*7L1xbF(VHk&^P0`&92VDSF*dFQ>-I6YpYfmr&luMR;W6tOAZg$f zg=#oL#hAeXgnIBgV5tXoaC*Akvw4p_$waq844@aQ5QhE({$zpo(8e8g9t%KRIu|S~ zu%vZYu>F*?9XL!kbj{>-Q>(rYMY`QFK*r-0TBke{&K-zmX5>li1iT00Yg&<6mD;C;y(QBy#>W8 zbaBuW0QiY-Xy+8TB$!CyG=b>y%Zj0Ncwr&%s?fr|umr=tK8x#5&#omqC`PLGDK{Op z5TBd0tCN9^nX8){!sO-T?%b7qmfBm{G>~&wdhX?%3q4=m*k8n%Vk4h#DI7eBx76U* z#mWvQ9UgidV3-4^>28-7-L$BNC=KtxsZ&s>puV*fw$mwjbh&b{SzQueE?r%;V3%dx z!u&crwKDrAfc-i1IPf`_YqDVed(FP88KF{M>8Iau{MFT6;AfyUj+#?KE5$^05uW{@ zM;R!f`l64lZ|=MN95~4beGM;rGF@mz_U)NR$&VQXI<8I7ZW6mgFT@SbGA>~< zz^Ti!*?)R|xJlaXN#Bg$*6+_4w0K_g7cBq$*w*NH!RJCpJXrv;Cv~89^c`C~#^v8^ zy4EfHTl#91>qqZ_pEiVgiJlpl4&1!pmEUnsllLI+iF>RZRTKRW=B0WT*BKMDqdZP& zX5^Rp(G2P9i--z~n;340$i30onIe_^M(rGQeOvKsm_kOQ>B)Pg?RwXZ8l?V`-5k#H z{{5Wm5lQ;r)}m$k{oCYLwGulL*OMrEMjRc@OHX|gK7W^=zwT_VTg2Ywg`CNOD@<+2 zXMSuFHA+>pjWkW(8)x6wVfIvhP>1h<#?_es9femP>EDn}J8*Jo^e`}-^`tLosHm?i zNaVI_ND=>WekWhhok)gn&{nwDWFzX+>WBH24PBN@FZwC%)$V>0QCF+HgNq+Db2R*% zPV+B@|I;2QWH0ZhaD;f_3IM|v)ZSc;=M`nkCIX)%yi@NK(qpZ%yU^?mdVA+oIg;Jel<&RrUC%y0PzXlbFNR+@6S8QA%*~S_<$m-CLx?PWD6i}+ zl)9`qXu+(vZ)%mlDZ$b|3s$$Gecs3dq>X`vFdp1^y*=5HN@VhC!c#L<%WZ=tf}|XjiF(oyoNtkNiKTDufil(B0nxW(`HW?Db`PDOOu{ z0A3Qz4x9i{#3lpm@D$7G>dMOeSs7jOKi3k7 zEJj`09QIbDprD?kV~VFZD5cGv#GW)_-^IO{ap1di>f&S17k=;;k+MX$;FtC)net?w zQ%fxHmEC4vWPL+t<~%C2{@-kAw!&=)%x$GWVazW*^Emzl9Qjw$(O)n<7`tnAQ2rL* z`^QXA;U9omNAxd8Lmb3vO%@gwLD_=~f9tv{3EKx?*MjPrpP}~F#-F!uwJQfVks$yy z4`RRZ!nDz9Qq9^R&OWVe%cz5Si)rte|Bz8Lj<&6C7Uq?hB9|7n$qAKm!-YZ#XP z`!>rNCPTfsW6A^1C#Jr@mNYbU6HmqXIM437#Jnt~elMzd zp6-=uOK?1X{aV@ti^JDv9k;)S@BMwea2t~)#Gm*usO0yORXd+5Ocmq{qN^ZiF+8;r z5+!|;iA6HTZsBZ4KsWhf#Lj@eCCTuS`Ag0kE?(Xy#yaiSqJ|?{j$Z8ear!EQdhA>T z<=UBqv;g+_Iq%~#JNmEbHZ{MmGfnTmT0}X`;aC_D2TgkWL+5u+r&%*zN6u~sDk>Oo z1JjykvDVpZsVeWDG4y6xMR|NqBxb*qB2VMhk2)d@CjxFuNJzgIOCegn?Nz(c1h(ww z2%S=jt3}RaWMbv=H~;7+PleO4pLuNB-tRp03&aQga1TkE=p>27A!3Mq=z-Z^eCjBH zLkCVU_?61dHo?$>xEe}TWWXPlSjdRDZzbBRR|Fd-VHzY#nC2a86(ftQ3M(%V>g1I0qB1%|_`+z-yOK*J9L! zrl>nxurtgCI#7tFREw+~-mhlp|Ht@b1dfMm3*Vp`-yPjX4TY3a-69Y}$<0?j;yS>EvI4{=^82d*N77G5QqWVVK`}U!{3qHJE+zMp41P)^avvZ zxKutoZ_hRF_2)BqI)UR3#|vr~pwB>2@%DypS-cg)68uf>6Mr+WHU47rs@qhTkCeQw z=e;)yN@y*?2`^ZL8ZU%zXL0fU!e7_{H>WieK-qBYI!AEGbr*#9&R!g|A*^q3ZJ>XH z$q{&LbT$7cY9?qRg&X)QYf-X;?0?Rs8aZn$hgY9AHC26o3rPe}St219Cb^yP+iRp! z>7PD-ZumMd%lWWb0^mAVIKNO70^^3h66|p0T#i!}Fbn1LYv=a{M4U~YLSl2$?;n$s z_7EgryLRyCT_(HqqJ8*V?Ltu4WqsYDxm4v^qS;xbfi@0M&hC*-J+1`&{f1p(hwnOG z@U-AH%XJY$Uy>%8qxnE6&eI7!2-tU3^5j}S@8ds1gewR9UKIDdc>Ox7bIKpOe`{`E zsNUmt*5aUzwMp`?%MQ6MvDtoKZStqlS2}~o{pidgy+mgw!P3IU5KULgT;=kz|FVm# zD*`W_A7a19&!9|T^J>nlN>sz^4u){n4;7eKw&)s4(}ZQ}{P z;p(dI*|_4!PQH@eHqr2rvs0X607Y5dh=>-wuA3^=z&%;sfO(=LVy$K0we?*FurzzQ ztEo=79nF((uWFqc9n+QcFK}Amp0YJ3yEf@i_HwOMl0Na3h^MnP#(pZf zUdj6{V(yPE#NNIXX}yx+OeOh>g>3l2AIrq_mB&;g*-UvUs_d#QGm-mw^ABd*#&j%7 zuu}K#k%;v8W4T@1HRzFMS@w8x&21)d`Pm&wixe|PZ{owcA}ohhemZnSie8FoaD=P^ zlt2cf)bkD1Vhl5fdHy&^i+@*;6%DjH7sJ|BzG=WW^mM9bl~>-@HN6*&z*-;Z~U>q87L@lHQ z3Ku-|Biny=YoVH~7cZnuih~VhvwM!WBBrZt0;k0ECPq5D>+Vl@(n>!=q8wk0T`90Y zmnq6z#luNDV`Bkq2mW03veIR@p{lkC@=)cdysx$17|#AbSqxaoCnY5ygQ;@u-QlcK z6;65FHxs~v?L*g`*$@oe6K!z`%>??X=uV#_e**nlO=4LV0)YCDF4E?90)|n=o$B!d z{)?#Z+Rf^=h3oIKrg>iq{?wAaz0G<|71&>}&cd-y%uc=>X>9-c^;mZ;eV&k3;?TUh z>5WW{K8d;!_UM+y_r2T5=-^vCbj^BaZ~cY8%Tt|AO)8V}=TSA?+Iv6h-^ScgtVuZP zZpbTwA48mV!W7Ch9Jd8Cd$15m=|r8(9JcqMd46v_&+Zw4v2aX$^b$#UDo)gUui8ImX<5QEld17&3emBqt(xZv%P1vt;yJ zF;sw9>AoCBN9uy@Pogg%c-2;}yO%XJ%%`wAuO6IsG-?waTEBhTdh}@BT%% zE{kb?A`hEunsML8o1I69GFJ8+=X*uE;r|t3Q-MG4i-B{D1LWO1eL=>iH;^L(KcSqv zN10$|Z(V0IeSFUkgy`~U;p8rM)V?S_a8xu)xeY=G96&j$iVE0n!_<^dB72sJ=cC%> zW$qr%xx@%6Jgr!BC5-(8M$1;L}f8PK-unr##D7Eku`>_<4^`xrbEmj8#QntdN} z7=OJfoa8ZMLwjF!<$$ha&wV*O!|1w!Vc_eFX)e^y)q6ErBPe>nKpRX#L?jjWX$qV^ zW&OcaKwmd-a*c#@H*5np1AtRsBz*gtIq-jX!k@0C6B!Lf9`N|3%Imc&E=xBbP+ zhf+3MoA(Di2^yS8aytl=Y@wrozyusH#%Sg+52W=WZI3UAV8Q6+u)Mtd)BejGJQy$| z!LYd%gW;S%C&@@In!fTZ8*Qw&GiMwCo%XSb0Gu2K*$`r-h+IIeXI09lWyH_$!TZ+D zn};@z`(CuBYko&HyPuIMWYD_M(#oo}h?J72Dz3_fFG&k#KwSSn`yZoJ1nlqchEp4M zPth%0yx}M%V#NNL`IVl5WhlD`E)Ff*yxwViRl(LG36@w9N78fsgi6zUrqn#KK^S@Q zX+06(sD;!+VS6c#^BG~v?p8!H{ql2)a%M?W@HpkL14TpUxP(nT^!aRYyWlDh?0VGm zYsNvKyQ5AUZF}2TI7O`Ka=N6P-0;F*okDt}QR{EbwFG?i=bkb@v&GaKKLJT`RB(OY za(4$ILOd;IJmi{fQ0qmt>&6kChXSXPzI(9LKl8QQFY4o29W-LgohNgYb(>#;h7hS8 zFL$H75;b{nh{tn;3|thr2Ykvvaf3#~p^}nnO3oT>pxM>q`JU28w}7V$+xiK;V50v< zM@PrU31)oYv*Ty@@7+)XueD`>eT4KwGC{si*<$ zb5uPCV+H5v#%|ijU>^_b&tBBjuHRnGtgPQxxDB}ohV69rWOSpwy$Md~xVU&wa;Zc| zZ^+2XB8td>xanl!?0?(a*qW1tD)(RZzH((2T9CVEu}p;IBhilfN43VM*#^y#?Et3g zE6po;gNlg-_)wUrkjePmLQOI2^K47T^gx>~s4t_9g)Y1k<29qB0x6xozaRmtdWBYD-UsoH@P^^+g#T%9aPK~R zBap)cqD;*}a7WEA&G9TXXvTo|(VC;KBNh#kho(CWGpm>m%56iUo z@nIC!_&yyE@Gf=%iy=%2GpbercaFD0R)!cQG~lJ5gS!tJhiuiVzMrhvZ+HrM4F6KF z@JufGX3o+1?q=&j+SjTf>(xm|vp=Kau$v180T?g35eriyFj(HhH}!=u^noT`t~p3!k5MDErH;f8u+^MEn@NIPIX;nJ%gE zx53qy4Qrq1#4H(I>(yFY*S;aweMIg=bo7NOjkQDBq4n34ci{$lGF=_~HLqW9jWz@W zRSVG~VmpC~UR$yoa6@l}E{a{j|JC#7zrl!yc@X0yu}deNJUI7CNt=INx?uJIVkUkD zAl>o3#U@2dI3;*roO5`U3uaCT1H%hBGh{?jEnJDEm_(p?vlI^B-*~(}QV>_^(6Wjrxo+T4_9J-U9iHoe4C@87PKp zJP0#lz+>uuND)9xbD3h!>$)^4>y_H4$aS*6awS>}Vkp7RDE0hy<-kOyf%OKyNadeZ zNpC~Nd@zhtHQV~{b6u+d<;|;ri7YnJK-~4vMETM<4@dy#s(T%=kdx5E@fdiHo>%~2 z093tn{gDz(xDs#yF8OX^E7g;&04yeY;ybEb?)y73?WbM#FyBL@E$#*r0rw4SB{?an z-Bmxxs;0>fSO1%=u4A0=VktOSm=Gh>f)cu>mPZTaEdE6LvkeO)-X)JgTtc#~W(e|Y z#}@Y{J%GbHEd67J;MyS<{ZxuR!Q@3Z(u8yWiKu!^K5Ds-90lNBfd1gAQ~EDklLsHv znq-P-RzVQdA}n`6LV&N%!=r&!kM4!Wd#rT;K!{*c zn)uCRvE&YW&G(_Jb&IxvTehA_4ud~dww6=s{I)lx2`+duO7X=9p$&0$H8A8AF>m4*g zDmY%>?Ls(3t7mEvjIQv1PP3U{)tfhLk*cFV8`PQglHeb>@vP1;nh!yHYjq#%AxV+(wTIMDm3TXz}l~*rpe8 zx_qz}%~=X-A%pD1(b>%napq{PQNnU3pZ2WK;%-dxR5nrw)@n?7EX5pV_4)?!b3ahC zX!vYTl$XD`z5^{PYs)CKl<*@`ifIG|NQpc22>;$7-@jVU;+rwEymu zi5HGS{J-DZ)xmZKDXSm+bw4nVY5yE$V$@(Ae=Q>>E2N2507{b0U)SpJK1|bo_x*t= zOFY~dDq&dKi2H@L^-sXpd!sbdP3rkevln(Sw#pB2#!CB(kcamWz}Pk)eL>tun3ki{ zk@1i>2*m)dq~CjMB2M9cR#xa?I7d;8Z+6ygcH-#4*yR?|xM^Bw3rE0jLO8Yg86NtE zJx$=}yY@-o=VJaV&qTEg^xyd7GAA?r+W!zGwH(9pb#Xo~a2?L=Mvefdf@{R`jE5~Z zgg8Z8SnXi8KUUV|Ft>57Z9-Y7TA_UqX(HH=>#iqhxQ5U8p%^=$2+Iu#qUeMXdL^i zNE-`ue#>sEYrFbo$Ap*49N*#m~cmku!AdNMxmbLcVUYB?Cf zV%-b}nppK?`C^~^LXGk=9{I-I7nM3MyzwI^<^Cf9Z7?>}>aiz|fC^Zk?oGM_YmyxD;G>f8kLBjKWcpMX~&@8~5r1A!^oCJSg8Fk(%VGhY1ztRIJ@x zGMxQi<^DP)5=gUY5$j4S9p3DC_3Cl_pt-sFv{BC&co#+u18*hE zuNjA2CZ<(Rd47F&Iw9$w_hby+i2iiPbpGO(K0sDB$4N#Ze8SW;mql&)%9>c2n}0@O z>=&B-1#1j;06%xM&bkL3^9M)rbRfF9KhH;SEqPX|>_jhudLH;t7n+S_DWNBq;r!9~Q=QCcp6;Zi40 zrszMgVN|mEik}L1sf7BJ5hD^(ESh~^m0Lf9Qa84TRLsI47w7_QrPeHNk{YkR1MHOT%oIDvWS$E_2PmEM^x+@5` z6UGRCArM!o_=(ItsM)g!57C^v>q3{@a;~8QN^pXT8 zgcvAF&QMm|et)*zi*5sseDCvdEw(6*CvQD}F()3O7G4?qszRc$$tqs|L3xp;KHK?L zCXpW3=N6g-pbdpT5B`|g{_E4iUtZzPlgZZdriWNAG9f-rKg zmqHuh3U(v5gI{C)c=h8v`VaE(@kVyv6aPN)5dGe-xj6<3VqIH?z$cF`^D}@)z_0SV zfs|cPSU4|5mo#esz-IWKQd#KNh&7n6Dcyrc8zP*>D$@rXLaiiQnPIfIP)OiZTE`yE z-ya+?#^{9aBmQ!CBySF{MeCh?Ijk;DCcejJ57N=4&Mw7T-q=gLZTHV{?sjVHbJe_Z zZoo;v3Xo}ZG%6AD73iU}Q+SSM>5tTSaMMQyNbO$Hs+L$cn!fO}tjMQ4nPt)#b9_=K zR*d8-k)Qe53}QKJo{7q~TBDCSvL&JU0%D9MAa*p{3T_xhAd)6JQ6e|{QXK|b z;Rpu7fxp(3A7+1Zyx5%$&5);u-+6Asg!L>wyhX;KuBL5@Z1MrJKW&Six_WvDsleI* zr|tBJ{exe!Y`=!gczZSNOB6qa18wl73Kc7a@OD(DykO5zxxG5m_uXD?$Rd;>=6&z=EmNE;ZV2MUBmMDPI;)-FNRhAC5MBlMave{rlY zYpz*g;e>>b|I#2p&F(q-(1e!b@8XyWEzS3M`=P2{$-L{n!kExvxq?Vdh!oJyrA0~T zVUrHf19CU@#XaU6F@~37-3F5^WSSd{+V<(c8_+gjWfSbfVx9t8-JueuKeLx>7l_ie zGc=d?Hwtwzq0z&t%YYw2HE-Uy4oUvvXQ1G;HBT&PuvQ#A*s-d(;cZ5vbuKo5J(Tiy zLME;8<*KQ>hudPr@I$ATk;zaoD9GwKAclqZzlfhvlkjpHf4lMXRowJRng5Nh(N}}v z149BXr|Y;L(MueT$z@bXikT(;kCi&884VK!a1Fn8 zRK1Q1vj9%>+HW0snvuqkHNo35yx_bo8(h zvdjCSWXq9B{BSy)`8>9aH~`BL#3y|!v&iMwoqUkp{Eb|Kbi zmDyXMKq&p^XnqEXKPH@1I*UBkKMWuDqmra*TEn;LSyfe-@g>g=cE*r!nA_nC0d?!sK-&b z<4a@p#_#BfCU(+stFSO4bHjT<+xar}@Ibcpsp z_0`Myy^4=o(XhK#Pn-ZwYRm!&K$v>q zK;TI$Y*haNd60bSa`g~S+Pa;s1$cJssJ2=A zwT66wzZ&dd3QSOxp%gs%>|lxmb6{+QL=zb%!1psVcV#HDvYYEYxAnhknwpBKG}4m_ z*H%`pASZfd%|jQS_VpQu@c6Bbg@fAn`^FYJ8UC4F7GCSblKz90>0a)T988>F&EOI_8f}me zDqT6!(9nR56;=iDKS*LvwVLG`1kkW2aas-F&zd|28zp?9kBrY{LLjUTK;qvGWWwNk z^6ni%aeQUpTwAb`$+{TBsoXI7sK4(@sObiT)C)V?3!L-~K80r<+nlUGo>!zQP^YxC zHs+u3<6yqoO~Jte9#%!A{vgBfj(ybUSZO+QelbvxG%5A;jjAdi{!)%j57CEfFVCwP z;xTeCSNF{M=WWG_h$U=8KPW82!{_Tpc95mWubS=? z-*byln*Di)x>jDbejE2pF8ds9W=$F@c*B5MGZ7OYoOBoka3{21*lf8VC?o{WKE542 z@*7l{KcOY4F#dQMU#P&?E_2&&MtsZ30UFqwL;di1$(Pmk;-sAa@?_-GSqO`{!Uf!z z3$#@HE3)S6;tg_=&2aU zSKQ|iZ zT~q7Y{uhca@A{pj9o!ea-UpzEDrWO_b_QR#^TMs)rqx53;NWamTvZ53z+??eL^6ps zV>r#KB6 z&kLsZkYVDQdl4FX>B0)30glNc% z>4AUcj;|B*~5-7T%swoA2{Uv3PvsXU6; zJ(6G?$i^F%IT_*4sc3DvCL!rl_KLQ;?cD)&R@$3s`%?qM>k5rio+zY#E&ChVS79Om z2)UXeuEfPxz?zoc-nzn?^GG176D^EcH*`O^0W{ceg%FU(tVn~>_&!XP%f_5h`y&Sh z*}9sk>F~%1nABCqj06)QnT0Tc|E#bV$7+>q-wqxTd|}TM4~O>JN-JMm{~fP3&};HQ zkkraZ&2V>_^z|Ngy)r>>X!k~w-*LWwEU*R#LPD72l^Bg*=S4O3W8BB6^w4?#=+f-Or*N_tt;AdmaYydp!S~N%!x!{)|f~eI#(eN}Ot9 zdYWvmbC*HyvE0tth|O;fKktWIV_BFdiM|TDWJ?9bkFsNll;QRE{9rxhk~3KI;xB?K zmtQGF<0_DbP%}O>;ZVSPQa^b4IZGZt%4F*!cCr05$$GEE`S~J5#6sTlOy4kQ36b7r zzhR$ByUT?=zuU#*h2do=6~X%!l$x3{v%h8LGROuM53^8lc58jnjon@FqjpVUphk^? z`8QG_P^+-cxov-U6W-@!G1y^YFKtTN@D@`;To-eUeGIyWG35{^IZHm4GMzzL+)TW? zxI85%r>Cas=)Sy{E@10M2dTeU-Yt%f^l4&y>Z=Ho$Fkl1Foa@2D=X)^L$c{CiBZQo zhi=AW76KuX!j0DRCwEOeD&h}u2^YxLFRg(oejYC~vw*Zz>7$ntET~R3omSZL!k%@O zI`4T#_mQ7%n?KLiHA+%Bokvg2X}|VP`poD*yl1=`QE8hs(l!=g-mp1{?Hz{G27_}D z^uuqb{*_M3Oo|nA-0$E^82s2%LHbJc)q%83r^)Y)+Zo@Fr0FbaSov;VmSROAh+S>Y z7n(d*jsp94pI9x#)eOPdL+Gq~&_x+>M?iMwB!S=M)e9V}GT`TU!7KO{^$?UN$;2fr z-o4GuMEzBbCo%VEKp^$Y&$GGD4wmkmF+K2*EWUt}lzX^xWC5sn1O9k9e{XMZD0mgn zVFx+S;l#u)<(VKNT6bVlLGnRnCWonn9Tl^9`AgGGCLw-BmOHIqzI;Ig?U!N3p(W4b z@sq$jd17e|1$F{oE9QL9gH&CxIG`o_3T0kW2S+R9xD8Jt=&6g04@P` z2ZnFRmCFlzMF#hND3qeRlE|ZU6{q4ArdBxL3%szv{%%xZ$q=ok>dieGa?-7CUztN7 z`G{x?IB&@-dQ-PVx(0Q*N1Xlz3}_0t9~BS$)$4!$BcF5w+vfP4`R837xslC@E3~cA z3tns=Ld&$2jYuaa6?wI&sOFpjziem#)eM7FwKq!RnFFqQl6G7P9Hf*JCgYRq%`t(i zaRzC&1Hp`3a|XNk+&jHYacy|$a6kU|fj;@sqo*Y$V|1f;0(KB8qbvBVh12r{%N^Qx ze4U;!8Jscoq*tr8e7ZZtOO_&+JM2fuJ_^<1W_X35-OA-5N!BYhZJ<$#q zw9)C*Z%KdWjQxZY8Tda{&<>2(4FAI2ZLfeI7_W(=LWLGb1(ca4d&-WD@l@oq27BjN zmAW}Q=V zf?SDLOT4KCZ4>6^=1TJ?WQj%ZfK+#0MvpR)r$ID9_sAGMJ|?C^98B+D8hulX^8A=- z8|NF8Z2TjB^SI+7l0C~;0V0Vw02;u+Y=TF<}o>4U1eDL1`y)7G=}6~ zzJN~4_m}!VWKwcAB~KCsEd9U&kf4c2PIi1xuQOFA+9=Lr+|3Nn5R6qj{HwJ!?9roQ zFLAcGCH3RsxN9-pyvJ9@mXH_zUB={`5?MVal~@568kM`eG!qQ!0!M8u-}^0YSz=hiTX)aye5g)Xu&v%xx`e_tpg%#~idrzLLv zTf`fb`b-p|*gJ%Nc!I$ah%X}xn5r~Y;d{653XAS}(df$0E?4KgH$s0OAw|X`3>pt} zks?|-2+|^M4x1QG0)qAagn@^BGo$^jHOfzB3Q29=+!wifLCKM~qGpZQU##UX!(;N_ zg3D3dn$ThLu-t)p2D4a(hs%iaygN{U7{~bX3E&D1_!WP|Rg*{_VLFV07{rtrd)j+E zK{+qajTzK1FLuS z%EZfd*1u0s<@e19iiq4^?bV>=MH=At@W@tH+r$eTWPI6vLBG2s^gb>iZ+>=mw)lxV zq8#9RQFe)coIuW;qen>9^X&ZhlSQI4N;bsYw$ClLHdlJ8tE$j2^!WdIlQ$5t_k zWs(c+4IFxA<`_kn1@mPG2zDYw58-}APFy2m_6J6(Zf{iIM$?34w6842vq%#a13$c& zF@SmBl2g|p3Fk;Pk5+syQW=41cv;jnbvSI6-b%Z`eD{2KZZYF!k?cUU$uT-G<;iKe z0a4lLD91hRTgx508PX3;v<>fG*c?B2d*|=%Y@9qjDu0zr#pUGiIhGqZrQ=Er`x=9` z2NSHdL{~jeKT0pz4?~-idbFiBi1L85O7G+B>g(wi*3o^PZdwlV9t2KDT$-gh9f&Ql|Q8utG9vDdRK~vhhBvy zJB;ZxiNcLM{PG&!6nDcI-M*v7N<%CiS`Qj(Xz7}V0`3}3MmnVzr^P;?A(RzQ1-E&Z zU9S1f9YZz<6l(~cK5ZBwf}Ag|4IR~}U?^{p&%7k5ps&Oz*u4-(gR3(dt3G^u#+&ZM zRmqX$iROuG7Z=~#YAA15v+P*gPIEoUDsEkxmxybpqNhQG%VgN_*RRi94yEfZR%3eA zw0{o4%3;qeq(S{GH;P7F90bB+JgK=Ql8^ zNQYpCk^NxkA!k@H_!36B%D>-cUT^h^VqM+1HB`04S9UGK_#@#!A!m2kF5#E-Xay>^ zG9|v9`$drA3jh*4k+2ZF^ zg+3VA>pxS*mif6wA`gr9kq6)$YXGw+awFxYN zM1+LKexqu{>Wp>*QV0ORNe^5DCR#Y9>8I8=dj4eZ2aHwYJglu!8nl5fL!t#in=35R ztad{_K)w$SzPPm^`9UAk@nW@{#mtP1n@i)w75kwiYcRFiB@uc*;h(VFoD5j7txyZoVf2f!yFq`wH~W{^CtFIgv$_CWncGr5o~usb;9Mj z_mDvK&=wftc~+%$ATFPI42TM_#04}CF%4xp$C)nLeYro^ahxLb{RCg>$@yZO$~YD=us~i66lLK}Xb51~7=4zi;W$w!lU5N=zKDff z@mzQfwLM$DQ;KpmXH>oVBHE3HX3Q9JJEyS753RSevm>OI(7irg`!9qjl)28LL^4CK zz+B@^GL*dlK){KDd2qZoxM3KuRUoT+{9v8gxpTojtQ+0~dPjvr;ora@7sswaz#$q+ zG2a1q4oQ~CP8$zWyMq0R32YlW5m&+3@=O9s(SqToQ~D8QV*97BGP-%`*N(JTysE2< z6Q9PEhUE@i)(DJ;v&~vGq93Gm*y;JNI}f#fo5fxkqC{9Wki&&z!Gt07Rjhb_vpO57OQZSS-`BU89~tX6@$s|C`$dc~P?5NOd!?0UIVU^1 z8W!3(`N*@Q^q897g91)FDn?#KPkYLgRs}J+)>N0FVy3;vVmhbLG3?F@g*xBbi|6cj z=S^^%KZ{rzi0BRV<5!azqJLvx=SwiQg1Rcm8;m%BipV;}1~lz;beT$84%;jQ%^wlx zIY1G5u~Ms)rj&^9_o zOXzc)?P=Y)-ljhZHxuE}_;xzydE}35-xP?5?4As}qHNXu_p0xKRfg^`N@C#$GR%%n zvN?kLsCL%qXM-T5|9t~4cp9=_luWFVIf@bT#HvsqE@P<6AE`fKh&k<6pS%%|;jGs8aiC=kWw5WA+5h6RZfWY&k zm2BvVBjK(g+)r#+_kEISz5)N2B+EXY2Z5jIDupl3xl19( zUUXh@24U^E^wF}oONAI`-L7k&QT=7>bz-6CfuiciP`;!2MNasBqok?Zns-Z36wc^= z10EutRwzijUOqFZwJQDM*>6E%e57PM=2$`->q$a}bC^rSk;}NmVo6zllcCXL{z^m%QifH)f|DYNtE5iKBDL1OKD zC`=60C_^LQmIepcw-#<^>py@Fx0me|H4gZsq5N4xzSuOH&Vh7J#iP_rN!GuhnO>`uB~)XRMgkm)B)gEyKgZ(M@S5f?Gdl zA<6=c*QoV%1XbZ#!Kh*UoHL*O)KHpGObwP&KzrxyInlgGFSZ+3oQ#yhTL`khF(b=% zT9yst1X;As4#!g!W~QEJebIQO6yhwAoTPJ@lXa7X!L7NsmyYWz)Sei=11!>c;GK^^ zM!p}bQ9HQ&>>X3(M*qxo*B!%0KPuOg^tVo(_U+$)McVLWMg9qg%!3iq8Jur#x}G9V zFW*wmjBy!)M{aS^{pQV6DV?0O?Dpin+7Xm6xPn~Qt`j4h8868(K|J@iIYDtx{B?Hj zC@$0YH|fLi+{wv-vhdJ|x9Y{f31RrXdqkwurfpQ4WVOycMgI*T+dT>jO~vcKh2lu` z_lT0FQ7+n1AAr-u{c?xC{&|oQvBs`KcU#B zq6O_6;^n5y%N8*!e=w9S{QO?M zc)=XkX85!FyX9tsp zq)dn6HyULy1;twK>y_eZ#ZvloqWb|&VX&}jY3f{o6K9q4DH*!WXa*YW@tAtZz960r9uLeZ@ku9j;DiO;^rq~6 zRj#qW8yNeQx8<9+R0uj-lnLu3qN!$3Gq1G;akthMIVUSLuSY3!bF>=xau%^j=72@>A)$)9a;K{0^yndu-9XmK^tG4*_X=(o zZ65kX)lU5*2cp{fjPLA1Er}@PTCXclmrDG0Oec{J|7m}vK;fajeabvpkK&5rsRS1- zLk9brJa08mF6bw5#Hh2*qscE=*Ock$6WSKoeDvhePfYK8Wm|pzfaHPNZlF27FZklI z%@EBN)Z=9fuWD*wT<@_L_u~BE+N(F_jN~P}u-nnov-yygnp)5J2L_2T8DE+9lP=OW zYG$q20N|yR9DfO^gw%(l3%4dGi4JhXGp{Lk<&^X+?YX$$^h37>1Z|E(3!Rpgg%Kmf zPw=r|M1_VoDsQ?L((!te-thQW`=uXTXEh`Oalon+1}yE#Zc@EmSGRv&8To&4XpkMh z{JFqG9&c(bujatBoUR@Fp~uIT4NstC2L5P?tY!g3#U0hnb+5c|TJMO*87;rj>Z1m! zigLv7+z=YEE^QU{52;i+IET_VVRFB-v1vd036LPtcS*CONrqW|0kWO{9kJGWdGoI@ z!x4Ps|ECzd7jHOy)7`zSu1ud;@@D6UKu0*ZrHFW*XD(}Gg-r~PJRtP{Ts`8Y0Cu1n9sAJ1gs0b zFD$q5aL32diO`ABMpHUZgmX!XRV5W=#}-IOeRJJZy(W+{y58spf@}5j=Wu|aYRB}) z!JJ=m-@@Ky3NQ%j6@#M$(N3rFM-b!D95@;kkuSim?d8QKQkx z+`w?7vt`T}0H6SCP5t$egO~36t{$YPhjT>HmVEn8)r*RjPxl%LyR>M7e!;VYxezi| zu($st(Y2fZ+kaUpn!0ND9MQ-zHct+H!SGP3!LW_Gy%ghxVus80$_JwcwS1P@a!uo( zqSXLV3AI1!DEJWr-7z^s?oj}X*i(w$!hXh!^8ADdYYoi{;(4Lk%>9uWQ|XS{`u;TI zc*gpC-0l2V!rb0VBNoRes&srkNHCDzuC=uRzYwl%Yh$ufY-2t z1i2w0#!*7lX=0BNK}He&@qIauI?P%kRhk~Rul);#yx|F)j!nvB#Lw87GG+@u+;LTHr7&{mH=bPt;Keiu6 zQ;xHg$CrFaZvC;sIYL!Lrx{&Njw4S(qoG(^6uP9`R_IY#a7TFnn&vBwvv@&ti33f=)(QNDHKRmN zor->Jop9u_WOs1R$wWKF&=#?z4v+&RZa_PSnAA;{v&?bRAzf2+XH0)XWUkJ!o0BG< z)-2{bKW39}oGWJVwIQ3(1yg9RBS{UO5vyKRE-KtaM}ie?OidFkA2kEZjEr}}^Ye`Fkc&#WV4hmM)-am?(H zwlCkwVK=0`LT=@F0s~1jfKy+2{oul;x0sTX1;Yo#y~6fw zX$MriBb?Vs>-kub1t3qz|DI-_8D6#U{(ayE-rJ~+$qk2i8(^ed=jXR5J%@7%$l|%L zGtxAD|3NAoGWIsK`Vv1s6o^1G`AZANTUjN+20PSAA?sN<|3|r1{ZFMIbs;fB>#)bctP+M<;I%<#$EgvoS1;`WU3huoJQ(~ zH`V~-v>C8++;o-oFv!5>4v}|o;{*gSj)k8emC~C= zD6PRy1pxzSqIN^~s~jKl*{ZKBXGdWbE}^84}`!2la$WBa{X7((10# z$v&5^JcuPcfsLKO0FG#I+*2o%e|y{4BKgJOf<-j4v88}JeUUy*W%=da`nr|f^#s{a z;m|-rIC4FG3YtT(yIiCf(hcU6mVgL=~$HomQPMM(`;~&yt$HOD3 zP_LHJ3110fdO6gfEeLHja8EpWLSuAiybP`lx;)Zn1=f`!c9=$hd0Zy<+r{J<1|H@e zo&h^-=qo_))e$H+=4apd2H%)(w)5HV6+^&V3`Y$zdG!{L#QXWANkEUbqm{t+D=_%W zs5;EZH>~~yr!k&;xJpVtJs?qku@*#(6U|qPuNQ{b&DHy&*yvMoE{JfEWRDdkm`a54 zZq)P-FtR0*Q}X^}rbB;sAKnfqEF1}3eaY<&YAjx*C;JDd8fndFWU~Al{4`XO|IJ#(N4417 zDjo;i7MQ^f6&2?9TnFxfk_654Rx1`wVI`vJl9rdgh+S$RFfr?)%4~BLP}Z%ZNS2g; zU;KyjcXoe-pR2Tp=9<$`5m)EerBxoz$NUe_WS3elN1MBsrs}sdHxm4$ccTr;og9zi z$r27ds7mCRO6GXv%*t_3sTZhD1Y@@v3NSGcPx(DY?()csdsQ%N^8y}8(g?@n{*xpB zA&7g6{}dpJk^xs;m*0KEId`ef)>bqbT|RYqx&I%!S55$e*(v50Ev(=j1*N3qtfbOs zMZ#ikb+Ihi)Q9beRSvT`uqu5aQ9VQf9n5yKfatJ$e4Kb~U+xNbVkC+YkHn`SlSX`?FAWNsX9zc+=htTX zaxR%OA70DVBW9%ha!#?UT%x~I1JQpF(dQ^e5$W_|23Hb;}+LT-(2O zDhWN@f3yZ-<$;mfv%MCpn-1(aN5X?Ezb=qd``*1j)IJa`%UD70o0x}h`>UsUSXP4s z$(7Fh(~f>7d^Tq)eVlQ=@J8j-dkE%)D-fIM05T*O$o2>s=yns{InufsrN(JV#jpuR z2=z%Tv63p!mvnEXYh#={8W9c!hIoT+MR)!4VxN+(aKQ56N?%bCc}M`GPDDKfH#PB! zToc_;z3O!tO6_VRt7teCK#({r&g@4d*xERszkK^P!(S>nf@V9AmXwrtyrJN|(%MZG z%ul}bTr+4PC(tuY0m)BjM@do&W-pM>4=#+35-QIDSRL%3ppEqLsp2Mdptr;>5;cHX zU3G{;KCDX{K?Bq=nPsUqNIhl`{KG^jl7A6@!)<5mO3W^xwj+4g{5P)iw?pF9k%pjK z?9J~QnrOMVoQX|i7B*w|^j=R!qt>bZeqdxxRVfsZd^yGtyO5D%pEo6U8JAjpw_?^* z*;>Vi>~oYx?YM%dw{68M{O4~kSH&~*_Vrzzj>~=aR+K+T*qicM=SPsa!PykU8&v6E zn+RUKlf%6i^20s%yh?ly-_MxmIas@GW;M0pu`=1h| zivVkfaPg{}3p@$9Gb=3thLV zdb{pSx-Wi!NFnJ1NgxE2f~BEuPq~d0hY#~XHQ{t5>|^JOZLg(1^^yOZ{)eNrET!mjs_5kLin;=Jd5u^E@UaW_=r8VsGpd;MMGmCAm60 zt9&dt;6@6ebg;u*)UC8po;Uu2Nf7AJ;P{1SF+@RLmm25ry`xz01mLJZ=SQg6JsXZ4 znXc%))VoHM_*@f9(xA#inlV1odeGO2~y*2BSr2OlF{(x z;Kxas@Aij8k9|QASC&Qb9M=*%6{3lb+0Y7z)-a0QzSN3jb)_F-$Nq;c-on!N%wDin z80}=wRG|6z;|Py8i`5AN6hxwXdvD+{^$9Tp=mLeG8*afq7_N zC1b{cuymumSO*#@5Q;-z5#7N44*AyKhMj}#N>%>a(da-lzQpwM@I>!Sct0ygQ<&)%Ujz<%-6)RO?W^d%$X_G>gE%=cI9Tm zp+y0@XQ)fJ)V|4Oa<02j$4sI~7O&q~&eq7qHZ+9BHjIXT{r-)d1*@51rC~6HP(0wE zoI;ThxRvGL3lK4Mq>E1Xg7DQ#=r%C zu$gxMweK0Dc`dx+K{4jk;T-tcih~j?3>#$7>zxxfXr@TzOq9MY%Kw{(kwz?wB$U>J zXN=m#z>@aI{O`7nAS~{Y)2Q!fm}^K9)|!FS zT}kZ6f-TVHS=BEE=B@mDS%QlC&?P zDvVLqm3wHzh37@p5{f`>&2W#DF5mA{Utl=lDQ(H%#Z6@EZZH#EpZ61@2TOUda9@@d zBA{TS#2&P%P<#(Zb7$56(|~{f5wMvKvLH;kAc%(2uv{)Dn<&_xLkDcsk&Os1rLWFo z#Z>|#W+IhgqI(DwPR~vdQVN+HaLPjv#5A-lxT%5N0KEnlT4*!nY}`M-IZXd={V`I} znhBPWGr>d_=;+l}J)C-RnWzSGoId{u(3q^f?%Srtr|2L03S$^fYxG(|ppUqjkU{4= zWBwL@X3{EM)Th^O)FdULVwDAHdj;Pb?Uhs4ZLZ<}LLh~H(56ywo;i*h` z2;Pwe7V99t0AnxV!LPgwb{}~jotSst`x=)Fsm5v+5_+9^PL1o$zLfI?D<2FflOesz z(v6x;G8N@w*@TS@4O`XYaiw+HO#KZ6@umT7clFh!<}drL6mO}G=I&@pgnEoyiwJ#Y zV`RJDz^#Xedyl_{q9-gphmvoQ0e)A%;%Q|Cud;$UNuP)p@O?dAox!XSUOPR``hg~C z1D%)kW`cc&9gB{!JGloziZi5rLh;sdmw1tFHf2VW%{~GiuWluvVQx+)drD3f3zCFC z%YS`gRk_gVyp@H7-uO=|&HmK#{11ZrR-rhLi6JS%2hINYcQ!q*&X3TMa}<-O7ZVeM zIY-AA*e^kAgGv4ks`QBot?(P5@=Z-b1?$zL!+{t$;YZ9HY_^Oca8RO-_Cg ztV&?i_b;PJ{v!@g@0BHtVI<53q20XYvmms#0`qf(tK56ul0<|-i9CDN=L924U6xx} z6L5}zL5OUICcBm$w8ch}u3gOTK$;7e4Z3-d7@@yWdY1P0;67+%Kia}L2Ab~Zrku=7 zQxlWp&Fg+`uU;)Vw_Hs?=j(JU(auKs>Ili`c0GLZBt_F(D*Fx8g}d{$u#bQ$0NTMT zI?CV5jQM|o&I3vE2PWkGZi7&A`zG5r2BfIv8{6RRL8Co@xCO=v z!4x^UU<^R5s0oFB-!9gREQn_ek`L7U1ijNlNwLaNR`dBInm)3mI^PG6?2lG~1AwlQ zlLbCO6}8+0ko$%j(maODo?DtOEKCfa7Ct!7gBmrT!xE>EcSz^4Q!NK^>&^v@*smF8cu=%RmM!R_p{O?Aa4~#L*$JWTK4+Xlpy( z7@=C&c+VgA4*YLp_s>Nj>;gLgIutfa9JkmVB_JwdZyN@t1Ya^CaPA_~338Mi#b&k- zfo)%XXrGB!$~u1S&zVd`2IQTcny*vBZ3RhY>_x!@>;fQQcbbR&IE5K3Vfbjj!ux z85CsJq?I%p9~Ta;u&lakm)q9I|7U48z}%^nq_MUjk!e4YWe|Zd?Am@q+1Y=m!mxg} zZf!ESxelM~(!jLAW{Ei=?nt-=p=o1oA)*y{w5}V3h(1514bI zz(VmxW3{g8_B@1xF^8js7QWBLJHK|6= zo;%;805o9%p=~;y!bC{~zkv?M-V&N3FrT$~)v);G&PTR_i3&pu6CTIpFHrryu!kYR zs_Ng{e-Cd9iMK2|!sf;ox`kE509+Etgo=Ntalv)(G!y&_3LJki8e%*cD&z-1RRy|a zzzT;c04KGjv(qVQO~TF#JMM;C`-Va?THxzXZ#3iKu@AJxblzx{Ylffl!#WJ@8=#ay zwi3+3kOC0Qo%dBNv1S>@_HdAccnn~q-+G4k!2&eDpM0UK10F3PgE-u0BR|?Ij05`& z$Q8hU_{A762y1j{{;u zix1Agx$B<#490M0XF-;@tDiEQv2OiAb*hN(7~NAs+W(16sS>PWrIto`HcSrZf2O`Y z*?n+V<%fl>%G;6&+pP5Ty1QJoE7Bl7(}X|`xqisR@zj>@=4Mj#)m`F$W_TJs-5$z= zd#cKw0JS0XO-;R&Y?w89%d(GtDz#h{Fq%Or>7=Q1dfp3kf$O)p_Y0ql1u*nqlpiB8 z0=yU=EItZw%>niO$q$`?zHRr^F&qB(KrBTnH7*7>LC7qvCdegoY;drkLOg-h9cCY} z8$!xPf%uh^#yJO!Pj7^3eQL+{{gaqH+JZuGnWL<^_sSkzK8IjJP;~VY!bT>rz4jn; z!)~V=AXNWUg3P4&*hl5A)Y+!7N_q0(L;=z=;^L*;gywb-j_%^}`yvNJOi~hrm_WT0 zqF4G!q%_Ws%|JE)c|b$!JZWRFk>mnO7PtbLVZqoOV(SxtIXgc2xeN6d$H@BAp1Sdk z{NNVTY7nhJ7hwIJg)Ux5!gn@M6q!8(+(Vp9pjZewJbHKvi;k(Zv<&x&{tjs@FwLsM*g;(4!+O6N@4h)Jy(@3)O)E z2g*}RxgYJ^RjuC%2)aowg*z+W)VnsbEYheaAb_~CGFPi!J~vzM&R2fd&hnO00X5Ip z{pp(4g2%4rGbmx*?r-F8G(P#dKT*(|E(=jqRiPVUmO$+!M=3DfVy3oJT?#rKeo8n- za^T<5M50LFDH>}1`notVvqGAj>PxkKw*^geLz-!U)HtpxJ0{ccgzI6>#q1f`uSvEP z;+au0GTJB7PD1WuXtWXq+JGWnoP}93vLHGx?rJ>QSp8+5(loKl*ReCqjE%e9Bxtc= z-(u2-Z5F2I@np6!WmMp-pUMS+hX|0x3S02EgVCpav{7KnZ@vu&P>@w8+*924fkz4E zX%=;BYj-u8-wg+ET2d0@QK$=$5saH|D6`KHmeXIk5`?)#$k%n2UGOJo#2OZq_wN~v z$wjtwc$t%gOwEL#hvf*&T)IzCGO+!iDqC`FS;}9@r+(6G`o#E?p#-9{ z+t5(?MUHgz{!;#~cfE12^3MLgu+kG#K?d(j|5Ja0wz6b9eI2^Ey>YNtFL(L*IXRIe zZG(8hvc9#e3uM?7A!Xczwz*}Ek-Jiw0d zGC*D`Rf+!&QoG(>>`w_I>jga*4Au)vGlLy8dx4m|=xFqn{UqRq0P;<=i=p<& z&B_Ww#Qi1+b#Gk!@52XW8rJ0J`qd5@D8=~Yf>yx!n0NVhHa0%?_KxI2USvM@-lqJ9 zZ*WDA8uzsp`HY3WcwJRKR1lr!e&7fNu0~Q+or?EsJfk{p64~Qxkk^ggucH*=XT_pV zf+`T=YUA&w^D;9t=R0pe3zqi!cWjUpg|p0~1jrF=R;=6!s#8Z>#TB9 zM}a-#8pv{i{y?M9E%3rX9_PDa(Ev74Wlj`|59sNz0 z%?XtjhQynpv63edKE}tD8n3+Vt`PR5h+nx?cwo4VQFJmA94s_{gz`d=G;5t_v7gQI zJ&~3=pR}Xai>`02y1aRNgR66!ly`cxjJSP=4=+@Nvg&5jt#>!E=F}Ct7z+iCM`PO$ zb9k>R7hoMLo_fcy1iwKqn+vmbH8`O<2W!je+f zH}{xR5hf`fV?s@AAu7=-#{N~;^l;QfJ+~?y(KMVsAbkn24M5RaTMcQZ1wiWsLfX`L zSH6h&CcmGBsTjPT#049Z_-@qlA7#|0Fjn+(H&kF3g59skC+4v#@Px<*@=|$3Xu?5Th`T(a1*vl)P{F8{b zK}!KP4d6V&_!4>`HMJKI?ofq%&;gju!(Y7+5^8e$0sfnxpFfXF;$B0%+xjC_;y(Yk z{jhQfGGSTK-=lU7r$>*!>DeF7L{Jw)xJqtrA0?j2Og~KsjkkW~obQjU<+2L!W$Wg< zv!#&q>%g(9jF7G9%Vi9~*ns6e>-j3HP#k3Laj8?E1H8}o*Ox``>;Rp2c^MxcT9?D` z>5aWoO6)D!V}rqF>;s?Ochzt*gNjX3{3lrglM>6Ce4~l(SD+!t$3d+yiX1fnL^wyZ ze;*VE-klKlWShygQ(IuQ*&LcbPZYZO=UZ2td`-oUi{GE6+`p%vp$15T_&g|h$XTM( zuF4cqt8J_*mXSN0%wR|a`>w7M%FQcP!z=I@Uv8NIGSYoggl-;1?trHHq=Q&B)x`^ z@@rlTlyvg$7a+PcG7>6qeG(r<(N<`>?bFNql!t#OR+%B*I9g@ny(CjC+&E}E_X!b( z^nwNu>`;)-3?*4kPRYLiD;PQ`=1&5pP4_1g(o0H1caXtF~Pfe zel#Sj;^ZB96*olADn9!s)J9+|jT^cFwK?FnfBQHJiHdRt3u*lT4K@w$Je0=pDnSX} zCj`9$_+VDARwaL#;#4S|$v|@eZXWu@D zKc2JxUH6kC3TeXansk-uXm7vB^KcZ?s6T66k52$|fJ#FhyOLufF44{<#?@+dU6%}Tu_3##+J-xwIdNjwv9b8wEJQ4*^rwAi47~i|Kw|7sKLy3F}wpY z#O(=iMnT{k$b;bNP1puPo=!G4=PjhRR28p!s6k(hoot{q=2gtYo;&c^|6P?m4FkEU zrzhgBfpsl23k!&a04>#LUdJWFZW`LPg!>*z2Vg>zTl&c zq}zGliN?sW25fC=@i7CJuPRYRWS89_)=JmY4sI?Wym4(oZGj^f_ux3|#fzd#I802o z+6Y{6;>!=QhGUdsh0#31evyK0-rFyP2}``-A?`VPmxs=X=dd63(QLCTu15E`p?mYk z-@Z0Djfo91$s_i$Q5WviA;R3YY}6Db;oJRmCC50g1MI)hF_K&DPyZ~>q+-Of?NU+E zD?H$Q+@tqjGNyPR{$)?;*h_EV;nU=Lgo7aveHn$PuvSo3$xV2`0daYRg^(MksYk+N zlq)u92GW=AD*AV)LcPd+dE>_?AZ`E>J6x2)CLPAZwcEr_#D{C*_Z)Zhw+Vj z!FTX`=PvGKe35mdw1(@G;Wk{|uq6_$H68={r{pQRIuQY8wZY`@>iPNkfePz`GmO1! zp+kKAx+*(`u|A|C!)YS93x+B%5H_l;uC3L-vXT@)%bqhM6s^P_;3o6WR?H?E>(&TH z?1uFfZ>V2kxH+l9A&}%z8WAINQ5M;`ZtxG&@3^Z={|DMc) zP6j3-W#Zg)x3M8F`{T!tz`rpl_h3?g)U>n*#OYZ-MLWx4y|yR25Eu{r-C#%6Wscif{`u!Nw;h66Ps_C0tkJ*yLgx4yZ`#Ew53!pg9kIX5 zfNl;11L*YWD~yX8-;F~#p&fu>QEvAqpLij0t*f)46`g$pWwCcHUS zW2}yZ$))gm)mgB+bPvPY46ipFBS+C%+75H`zPY~NdQfo?-9f*M3O(|V|Kc%#D8KR{ zE%nsqy-MXd>W)}3_O+(P;ys4|5poFzk%o~}B@VC*Tx#NzE+C?fNyA9DxG zIVZmTd>Ow_t=#PrbE=336DfYdHrvVS7w&Fm!Vu7mlFKs0sKBNH-hU2Cn0}}|EJ;x# zBGIqcV+yejB=k_Hr9dV9@{|TgZdOl(`V7i|3inSzJ$@pAJ+=XeZonN99TTH#EYgqz z3pH_HD+oAgY$#G?6g7yymxC}1LfNymsl=gwflzt@n^$qNSnrlc)ARXX+GkAnL! z+_~I#IqJm*h5~70Ain(KE(HR_MMt3c;a~@V=IVk^e38HD`)6tSq5{zd1)$3^kghH& zD=Dc#$^veRTa~6fl%SDF8v{H(RAo#M(f5OvOYQqvSdbrti$LXd(Vdk(hDbn%W^WjT z`ThO&H{@1y-)i`PW!Y$W?<0ERaP@%?Eq8x;iZoK{A@~L*DVH?Ip3T6T`xKt@uiw7G z-Up1UKGt(rNJ`K!h-10+9*AGy!ial@FHhO>dih%)-xCAgYo8Rgt#nd&R5Mu~w0?Mz zoqe&;8@I7FIuAs;=Oz0p9(3wgkGtx~yXA@y7aCPUHqZJLNH{>nzB&UH7i4=Q%h3Yb zTuD&<_PfzkuT9g8KtCM}Gb$w0OGF!DFP9%1gt4_So#drCyKv^qtA^&`+6)ED_f1 z>HyHQH9YW92(w_<7ztB!%4@5Nw|uxM7QdEnyy{oDVN##?x*u_;Ma^bnna%$&4PbtWI`Z=a}wu-pPbiP?LPg?JrPIk~iq4M(VqU(>F&6he&vma%*tbh94$ zpEF-+mOFxjlrs!HTi*#Pin#S+>zDQ}!egYbR6QkU4Ij%V3~TLzc76i7=!5gs3i795 zYkU3o{7?9bay<@4c_#lc7&s`$q45PrOm}*_l|7HFPiLfI(4o&e*#fiY!UDZENIO@( zBlENj4SU=`(&xwl!eilofLWk3&+jVF7WA!lSKafd0&J{5#T%IO!DnsF62*A75<~`_ z_R?Hm-e5FWk`SqGG5bO5I(l(HSomkyWb%mh$(c-wxW9Ge1e_UWXFHs@JehTEotx^WOpf?PVTLD8M6endH+E4YH*+*1!%_@YW0t4vp0g(*; zzRIIEXad57m(2S;z-xg|EA|H-H67j*koz48h+OP3&;)>M-2d2nL90?dr_Np0TdMBk zs=L&PW5?2-Gc@@in!<1n+^w>JnmOqz;O1t->eQ{Ty1Dt~5k_(-k=rTLwph>WCE}OZu*JM;lfYd3YvTp*ZLxhsT{F7)OA*rm1ciZk4V3Gz_1q3yghXfP6 z@SvKW*_QKVr94%;$-L(?NMn%+2oL&b7ZMRgdYb)@9Iq+3S01~sBPkpaO=)gZX7Xq% zqV;M4hrj$n#qCiCVT#F$ZFVt*##~`dwOQR9% zK^#{9XWw6Iox{Vy5RAI@e$bZ25=oI58H6#{P~bc7_U@|VkRR7#Hkwd8Djc@zww-&P zZ%aJTF>*zJoFzfc#4O|z_D37_5d5;o;o>f1O0l)r=*#cfiNYxHZ@NX2yxg~MpwAJy-? zQY54?9+ilj-oWXF!-XGM;$fAfj9_~YvSJV|D*foSX2osh(W0J*pfZRoS?Rx=s~2X- zYm~6ow22Rebl-KTm#aYKRyHC;+$7CJT1XP2&;#Cl?#!!ZwBWHxx$p2u=LcqE)^-t1GP6VFT+OMFZE3v}F@O=BoSH-}F7{D|n&0_|BY zvaMd*M>pIw@kn~Gl*X%kbh+!S!kYYAky@SQ+`-AH7>=y1zq8alnF2l6t|^8RtBq2}8W1V%WxV zzND~rFfAcpZG`1bC!-HU?KbW{B2SfN{bl{{l^J2kOgx)RQUW$2u?-UMHdnlXG^%te z_7d&+C#^YwLjI>$jBL4H_Asa_V!=)g+Rw`}A=A1!MVL7rWzLlPdf_!wrDt2-$Ue*K zaYL7Hs6l+BsbX`57F)|>OG`_Oxlf`3tZauV^SfZRfToZ|9Q8Xpv`6eluX;;FD8u5y zw8AB8HR>!~YJjt)jM)$?^yB7nax=qwt(&K3-WG3#n9`0G_m*NC13mUk%f6)03GD90f7@A2fTI29&_WVM@??K z1Jh`>&Ac|OO1mtN!yf`T!=DWY&t62btt*%b-sv>ILk-w)eGGAX)|!CP8GWJWy85+? z$AW$y$LkYHJwUM7t1xRS`3@Jyk$UI2!Q!~=S$taeoG(q zYs;3PGMe0u#pD*jc8UURc2gwM4?$>9ZM52`u)~B~Fs5;>Bt=@2?5Y^_N`+V(?urUQ z3D{-^0(giD1oy?~A3d}PhprES7<$-+z_I#xkgz3sDdGqaN(6Ij-10H5xn_LOA* ztKD>YV}E zV+j+dE0LEu62fBf*sr~f-w;ep5zizfigL5qu{SqUEuGk~Mz&>_P%GG?@$w^acN{Wr zDK6xz@j7v_8li1A_mN+dt9W#~5;Ac1ZqAx!$df4Bj>g}$jJ2jDePofLuY17ZB*)AB zM1m(*p~6c3hof+TFfX0e0(v8#K~jRUVqxq<)Lpfvcgbr>!VnNFGcnI2Y-ngWNk3zX z9q)ouhO1kvTOn=j`_S|Y#asUDgkky-{{!RV+nNLw$t?E93SV`WN6)TzvCGLI^Dtkg z?zkV%QXa1s2uF*P%{9=a`jL$cw|aPgrM904!Q<%k+InwDbkL|~b(_8?&JX^#mE9mGiu9(F{Y&X9hdC&Na_#j zR~dA(5z8UL2;o#b$x{mqjRvk{nega<=aa!D{~$4ji$+j&kI&_vD<@`c++T+MsQPV= zJwM&$x8XJNEajh_G#l+0Zml76rzvzQ8A%;~wPmRlwM2h4AOUrjLZ+Oi`1oeVn4IS-(S(nVl5nvo zOY47>drh$=?xPXPv@kD3Y#qDE&xdX+S1?tjfA0DnIh;-&sNR%-A2)7`JRc?toUpyh zer-8W*IX4D+l2K-gGfBGUzaC9pT)MMe}hCLN5RVOUJzJ7x26OeWGha;AT-tr>o5au zm)OsF?zduij@@xGWJbu?LX4(82kD7$un~Vaw4;RXd36BiM2DNB^ng^}mlMVc0~K%B zm)Y8hT5*n3L=JIyA_1+<#yr!i?7%mm5A9-!SB!LuhMSvYptP*~U+1Dk7?p$<+WMly zU#pSx5d%%~gBryj`T2{3TS@^+`T0g8)V&^4w40f1RAeXCcIFyd1sWxqVpX*>sO*hb zQ>6I}6DSa<<4BYn;&`CkhHMXabbbgHG;e#+vDjj>lwNwQazA@M@Jjv!|?7y(wb ziYs{Cen_*B#XRnan(Uj^Xnk016s3+J9Gu6x(7&E}>l)(OLr3{; zMne|wkgFK~Hd_0>n@*Sy`RHGjhuipfjVnbA-iP~=sockhVc%U{Y6EtQL@UtldA2sSNlaT0%E-l^C46Ir5m5F1)VIC|O5o%l-P zpv3#ircUI@id~$~X+B1}sWyIaZ}QR&jyMLd_~E#P$v%x_w=I?7Y)Mq_@}YFBd8^NO z{#XL5u>L`MF|lG><$m-f#Tl~WoN2960b!?4;S;jhOif;U@yquQZYHw`dEw4?Y*7iQ zxLwwadNTY?rfMcU%7yA!Kr#AFvg7M50T@DfCa_miOcy>xKU`J3-Fh1IAU2-$MP?$- z*1fA;vv`U389b8D`op9g%47#@Zjil~^UV*B;ydZ@-qc6fCuGUc(N#9n>uC}(d$D=F zCOPBlG7j_A=pQ&9os?kc4ihb`tL``T_}8SNR4>@dA|IKEjYjYJL{uVSvr-w z&wl!;%KBunT*=&th>H7hm*u+_$+@Wj1>J)eE>d5XP=>x`DG7m8cUnxm6no#&q`BJv z2px^R_oz%G?t6;(Q^cLyUe})w#Q1vhL?qt)F>Rjmo3Zn1n)&(GS?6I}lK86=f#*N_ z6oy#etC-Iu|D|{OF~^Kv>as72Vfm${`20}G?aux7`C_etRn?^~tp~3su6&xdGT-ke zRO@7I$7xF_ynGb-kVz!e=AuP$k1jMvPv11ID33IAdF+N2_aBi*jHV(;Jmqhr=C$|{ z_r+2Q9#8$3&5m#PJ|+mZGmlq$;98AdvO@)vLrz|l;)Wxapv<_47Q0F?_RRxzUdLvg zdIPj=|KwwoR^NWPKiNywN$GuB{ZVO(`#&x9s6+HBZAvA)zYQDNHbwcUy2`m>mAt^G z+$H9@vXtCQV=z*8C8iWFd~B^JPb3EKMRbj6h7olb4<`Zf2Wn$aT`@5yN3cDUFrf)GGB`GtbDZ z%gEsd61jZ!(IT1TzfzcZ@F|Ywj~XKCKVb~l0=FDfBZL%~$vLmTjSE2yl)hbM)|}BI zG`u!uJJ6s#{UqCV2lc1rUKNva<70IkaV;uk`%poQfemB!6zo8J<%>;pmR0*L>;s;| zsGwmyK~;1DO*eV7XI4Zrzeh$YjmUevr&amITUDy| z#hGOP7W*9~=7E6~LQ9HSN$OUz2Hs_aW0iUIPny)X&6td_d-dMe9xEe5HuD~o2`k>T z6b{6e$4?EodGG3@5BYfhf3u7be5Tqj9oc*&d^jGzfEH=+(Y++x zsp0ZfC#-{H&(u*`w&+T3q>cUwEZZOux4Q`lLuvIdMqIzSShicG!kjWJp z06GEZ7C!#P7;c6HIiy!H0!iElj+pPFfyvgU5q=ywI^{Zxh$!1`2?_38485zG9{=(K z$@_1b*q8eUqVEpyN``o9tdU)+p}Qw+?aKd~Mi@)39)&XDN$jGTZp!lhSm!g>uUtug zZyw_OAgEQ)A?`pvIjT7)+$%6GktesJ0=%#{@e=Aoz8`P%LoT0O(H%O-=9E&} zuW^&$#64U?6y|3s{=W12&%rgts~Ch^(npqtt!s@l`87wTLy)R-ao<~=g&=Ss9?8!z z?2zf%p8VKu*qs zmW!)!*IO_Rri0-11Tq9hB!gN3NX2!9`K>+3bR(&Zx{hj?a+p1Yr1_L=8ae?@YyWOG zK4MM02kvcVnI&_(PuxR>))TBmA0ZK|RCI=;&Mglc7el9=5?({r)pZiV;)nTNh9msR zuLth=2cxa^QdKq;6a30ChP_xc`4KV>-jKzltc%hLIwE*xH!ToCElfl!P~<4w)*UNs z>CdHDAL)&pq>yG(4GNIhzqRpcO2NO1Y4nVZBUE!L%TOXaNb?~r z$|BrLueD)pQ?DvmvnjZN7SkR?u9Fp_;j(YnGW<7%4k0%_oTc%LwP1X_mT#BBVB~H5 zzlRKO{S`rp*F2GaMblk=S`Y|=3^qZ%IG8+JyVOkZkI!r90DwMkg6mT`c#`OeA7{@;8T z2n;iv^jD2K4jf@HV^nF#O%0wzt|Yb68S+DjMED1#f@~rf`xGstrg3=FlFuzqDs_IsD`5&wS|ophK+MqRonBPXKeFQK&HCxBx8{7d6o7?DV`#MSJA zj^Xh3{7;}V_l?8231&%gLo~`fv{5p-w`WlI=0{#zqBEekz31@roI|XHNLZD6dgK9#hl33&2=H)-P&@J84MOmo z)KA%goYcD$()|)gfMA<1QUZ^c0WS?9u9+ztIXN9JX9i<}DmP=O2E38bbpUo8Ju#{1 zU35l333UbG9K>+T9Vtj(`+yjBE-`F0oM}R?ai|`TQlzhJwAbKcV`UkRrgDqN;xWJF zqIuQVlYo!-NwYK=K@8g1cxthB;}g1GuC_M%tLMVA0*7J3mKj$+u4HQk<~!czEn>fu zCewv;Ot~>Y`svyK-&)50Z7m|>dEBooggjwv3(^a%8Bl~pnF+$8LKzWUz};R0;!Pi! zZ|+i77g=o(cLDr$FE2^T2m}&->%eS+DLa4EfQ8V)?oSvNEbXcI-v<(xwDdoVA#Va& zM`Oc-QE&B|c4=d0XLZF6;AIQG1SeN=ef+Y#;Lr?xk_&Aaa82+a!}Z|!6gqX_EbUtb zDo{ZlB;Ra`$$Q zG{coEki{4N==scsxp6bOD?uI!fSQhfe74(xi9dLXdF}=EFkA2SX zpKsm=833TBfnWnhrb{oYc29uT-uU1x#N+}|`0K~cS1(_3@#kF4iqh*YwWlE?SFp=8 z;-{7U^X0}23MLM+r=UsGqD=E=QWvXMC^($31y&u*g+b_{T}o2gI}kGYQOKEF+>U7{M)o;+B0RFSAJ67G`3OTg_`PCJ7mudI-o` zSpM+gf@k&QtoH9oEwIss*5zH~x;Qa9pLVu7dn_(k#m&u6yuGDlWpe?ALys}kqNWws zuht`XFN1WF*7rK8Y&@w8CG)$YSz50?us~$tek=L#Gwnu zX}oKk6W6M1hIJs(edXaM*YcOxc3Q^gJHXg8?rL>GD`O2RJFJK1ApeGP8_j@ z^y9Vy3_WZ{FaX}$1NA=?D9Jma#=#7Jo#rss0|7V_>H3kYV1U*b%+x@Y1P=o&#DZxM z%c~G=SvXa<=oq824vIOLo&7n3Z2}DF3N&Z`T?C4+f&TBz*AJ*lzyC~%)oT<^EdW|} zaZ&z`1>L=Qu!q7>6S9#Z1^ju5{ih$tkU`^quW}BetbHIg8U8nqSAZY_!3KOk$Cr>( z1pZ zF%@3aagd;32Mk@Mv;uLSVf_TTZ4dZmAX?Gk_Fo4XsXTVYSCm*k2f(cN=gNK=5-E zgJ78HX-ew{QW7=5jAb{VSJW`3Cbi1bE8l8oiBSpaVe_%uZX>6&(nlT_^zjU)zfnF5 z>KgGh>P%tbdp9$^3RiToS?-fJ5Z5Pt#QfWieSKzW4&EGJHEXX>5CnaaYKM@`vz7r_2Rsba+Cq_5G8Z!D=W!v zc^(sflTcsjJf~(CrfBW#_oDcB6Lc<{?}Mx9;Nr5^&QrbH0G$Ka30$0=A;AD@U<6LV zRN33l&wlP0HZG#HAay<{Yjp+n`{%I_gug&$r85eaeYoK|+(&2U7v5D1@(3kZ%;8zV z7+l0}`9U5ALMOOr+pP_xhal7ekJP)}pV$H2P-q?dR8#%+=TcWXNxpu6A)cY&lip0+0s94S(JP*(yN!OIH*w;*mX;L>oSedgbj`+px6 z*%2b+m$p4#?Sf>(9F&oRoZYKnM+5#Yq8HXsiRKb}H`y_cd`N|M5EWuj3S;kn0(BHQ z0>)h#84T@zxW5FfDmDKsiyr#*OU&+ZvEKflGnP20Py&8J_EoBXD+r`62I{u54eHUa zOn6fuvuRD1q6bRmDP@$l`#n(b0iEXW&#rTTKd8-NOQevmfiU+XEU6stdCL+B4mMZ> zCb~y8noR-0`K$VFOYlIpTuWV|o2O@MOUs?wd0EI!gApJmsRd9n z1KzpiD_5unYSb82mOa8A<7~&FRPMP96U0{^#EAR$JoK>z-e@EgD@|qmlWqj{cxwDR zBRxZMWrt##Osio{t2P?jY{1Y%MuSLHMMd}paVlSD3ld)e(G0UiTiZ{Ehspi7T#?2* z`tKk!SArrKl3pPBEz+w9gY_N~5*sqXliVZSA}U zR}yG{VpRG-uEP{-EfT@~&f^s`F%J>rWN#d zht~5Rz}O^d1mw=}k@h~^T3LZ6H#`p@w}qi7+=#AaGOeFSN1m|qfDx(>Bhl*F`SG6w zJ9>%4k8z%PwcC~*Q8}^N`-9% zj|Zedh9R$2q3<1DtkiEm-;|QNkbC^v20De(ES!o!&_~P?KAxN(_E7~%NN(Rm{vQ5? zKHK=(kQ5={B3_A6shk4}MTw2HqO&j%E^KW>DJ52AgV*7uxe!E&amXS~`UjH&sfVCI zfE#t;!|(9YM_>tqAPQ;}Gr`{*Baj7>G-9ne5}X>SixF`L3DnvEk-I&L5m&7+lPaF` zkq4~Nb|{7XNf5$7p4YZUByRkO&@~*9e;cspvx}$GqDDn5C7fP~01M|+c?BZ^2Y}MH zed!hKlnvmudcyicVM{l&1ojx%aMFF`^aE)hd3qXG8HOs-u@mGrEy0$P-wP+xz! z5W0aB1uUux2(20QV#*yXZ7nU(A3uP+ns2|Uo{DNU&TMl>CaM?zKjz*%8teUiA2s)o z%t_`)5|SjDWuAwOC7DwjAtb4gc~-_uDRU@OWt++@N&`tq5>g~($VQ>x^=R+!cb)U! zS!bQKj(%N9dk8ZY&!Ke6yo!tfbY?!V?tpgTtM7{x1VfpyBXmWFL zQJ%>EP_t=J3LXa!LnrqC+qYH?Bagq{(%El90Wp5+@v@`vBO^J{Lx=0KbSVH%LC$Lu}1lB>^?Ouvx`GzOZV$ftpvx_U*Bn zNLp`LZUPmu6Y*pqjN!ji`M|kv;X=REws$9Z-*eE~*Kr&xvN%R5$QP>3 z9_D^D9LfgP=yoInpwXdCXM$Kht9&L(_h^|Y^8@3ME#!6n7(C-@I^qmx2jiJHZ`gf4 z!Nb^^*)@{MCWY^}M-A*B5hjK}VCLu;Y98}m)DY;NM;OATvyC9&!RW1`!&u{+%v_`6 zCR#Lqm2@u$fBMV#J->gQb-A1L*5@s!?<3b+*ox^Lb}d|A{1KdtcR#O`qJ@xd+(t*> z+*d20wvZzMMF!08;VgwUnAUyX+k1TZ7kWK_Vn^?!{|V#ho=kdVsdFXhaK5nK?LOT5 z0F}VsNq!=g^&J1oW*~PEIWQ*!<7yl5#40Q2hW@(M(n>YtBb_yS7QSuphJX<_3O+;! zBU#|6Fq>=jTd1h;lpv)FnaY_^)r4_d#lQ^u+|U-&5+8s6wS~!Ui0~1s|yEV z2+Dp9Xycm;LJK}Mz^Blw&$a3=YONYg0 zblC80k>4>-7b;IRMqKgyuRab!@`YMp?n2FQhgwki3~Xp>ul#PT)Z4GN5iSVNG?Vo_ zYw@h2y2eHrhI)>n7B($`dc$TwA^U3E7^u6&Qc)ct_#mF1#$xQuH)wgb%TNe#O`SsJ zq@V!jetK#As?}DgVRRPT-fH9;<2>=GK`se|y;fy^H#Pmn;bdA;;9`XwT-3T=n>zm| zhkygA*M7othX1JP3a`?o2M-_mgHU=45hAUkpH#?g@a_ONc<0&@NP`#K6K$;(lnyzUD9sUIu00)(Sxxf;fV zw}JW>mrma_NnSs{H^vl+Lv6;P!xQs_y(hJ+zOp_!≦}o`CZUE_!@$K4}z^sBfp2 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 z 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