From b7a4e30cf630e3084bec2e3370b1be476d9e3e04 Mon Sep 17 00:00:00 2001
From: cxf <839989072@qq.com>
Date: Sat, 12 Jul 2025 17:05:25 +0800
Subject: [PATCH] =?UTF-8?q?=E9=98=BF=E6=9D=BE=E5=A4=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/README.md | 1 +
.../README_声源定位系统.md | 216 +
.../2025-06-10_08-55-17/details.md | 69 +
.../2025-06-10_08-55-17/diff-details.md | 15 +
.../2025-06-10_08-55-17/diff.csv | 2 +
.../2025-06-10_08-55-17/diff.md | 19 +
.../2025-06-10_08-55-17/diff.txt | 22 +
.../2025-06-10_08-55-17/results.csv | 56 +
.../2025-06-10_08-55-17/results.json | 1 +
.../2025-06-10_08-55-17/results.md | 50 +
.../2025-06-10_08-55-17/results.txt | 107 +
.../audio-classification/.gitignore | 296 +
.../audio-classification/LICENSE | 201 +
.../audio-classification/README.md | 373 +
.../audio-classification/README_en.md | 275 +
.../audio-classification-platform/README.md | 136 +
.../backend/app.py | 350 +
.../backend/config.py | 39 +
.../backend/requirements.txt | 7 +
.../frontend/index.html | 26 +
.../frontend/package.json | 24 +
.../frontend/src/App.vue | 106 +
.../frontend/src/components/AudioRecorder.vue | 690 +
.../src/components/AudioRecorder_new.vue | 1020 +
.../frontend/src/components/AudioUpload.vue | 714 +
.../frontend/src/components/HistoryList.vue | 616 +
.../src/components/PredictionResult.vue | 941 +
.../frontend/src/main.js | 18 +
.../frontend/src/router/index.js | 17 +
.../frontend/src/utils/api.js | 213 +
.../frontend/src/views/HomePage.vue | 841 +
.../frontend/vite.config.js | 33 +
.../frontend/yarn.lock | 1092 +
.../audio-classification-platform/start.bat | 24 +
.../audio-classification-platform/start.sh | 36 +
.../configs/augmentation.yml | 46 +
.../audio-classification/configs/cam++.yml | 80 +
.../configs/ecapa_tdnn.yml | 80 +
.../audio-classification/configs/eres2net.yml | 80 +
.../audio-classification/configs/panns.yml | 80 +
.../audio-classification/configs/res2net.yml | 80 +
.../configs/resnet_se.yml | 80 +
.../audio-classification/configs/tdnn.yml | 80 +
.../audio-classification/create_data.py | 99 +
.../docs/images/image1.png | Bin 0 -> 69600 bytes
.../audio-classification/docs/images/log.jpg | Bin 0 -> 117637 bytes
.../audio-classification/eval.py | 26 +
.../audio-classification/extract_features.py | 19 +
.../audio-classification/infer.py | 23 +
.../audio-classification/infer_record.py | 58 +
.../audio-classification/macls/__init__.py | 1 +
.../macls/data_utils/__init__.py | 0
.../macls/data_utils/collate_fn.py | 23 +
.../macls/data_utils/featurizer.py | 132 +
.../macls/data_utils/reader.py | 157 +
.../macls/metric/__init__.py | 0
.../macls/metric/metrics.py | 12 +
.../macls/optimizer/__init__.py | 32 +
.../macls/optimizer/scheduler.py | 48 +
.../audio-classification/macls/predict.py | 177 +
.../audio-classification/macls/trainer.py | 456 +
.../macls/utils/__init__.py | 0
.../macls/utils/checkpoint.py | 162 +
.../macls/utils/record.py | 31 +
.../audio-classification/macls/utils/utils.py | 131 +
.../audio-classification/record_audio.py | 14 +
.../audio-classification/requirements.txt | 17 +
.../audio-classification/setup.py | 54 +
.../tools/download_language_data.sh | 29 +
.../audio-classification/train.py | 30 +
src/声源定位代码/back-code/README.md | 421 +
.../back-code/development_board.py | 3309 +++
src/声源定位代码/back-code/pc_server.py | 2078 ++
src/声源定位代码/config.ini | 35 +
.../front-code/sound-vue-frontend/.gitignore | 52 +
.../front-code/sound-vue-frontend/README.md | 38 +
.../front-code/sound-vue-frontend/index.html | 13 +
.../sound-vue-frontend/package-lock.json | 19934 ++++++++++++++++
.../sound-vue-frontend/package.json | 38 +
.../front-code/sound-vue-frontend/src/App.vue | 344 +
.../sound-vue-frontend/src/assets/main.css | 19 +
.../src/components/SourceDataService.js | 11 +
.../front-code/sound-vue-frontend/src/main.js | 8 +
.../sound-vue-frontend/vue.config.js | 13 +
.../mic-code/Maix/Maix_config.c | 423 +
.../mic-code/Maix/Maix_fft.c | 195 +
.../mic-code/Maix/Maix_fpioa.c | 395 +
.../mic-code/Maix/Maix_gpio.c | 587 +
.../mic-code/Maix/Maix_i2s.c | 371 +
.../mic-code/Maix/Maix_kpu.c | 1840 ++
.../mic-code/Maix/Maix_kpu_classifier.c | 290 +
.../mic-code/Maix/Maix_mic_array.c | 286 +
.../mic-code/Maix/Maix_utils.c | 86 +
.../mic-code/Maix/include/Maix_config.h | 5 +
.../mic-code/Maix/include/Maix_i2s.h | 23 +
.../mic-code/Maix/include/Maix_kpu.h | 25 +
.../mic-code/Maix/include/modMaix.h | 31 +
.../mic-code/Maix/include/py_cpufreq.h | 11 +
.../mic-code/Maix/modMaix.c | 46 +
.../mic-code/Maix/py_cpufreq.c | 136 +
.../mic-code/init-code/main.py | 259 +
.../mic-code/init-code/main_raw.py | 38 +
.../mic-code/init-code/tcp_listen.py | 27 +
.../mic-code/init-code/test_send.py | 89 +
.../mic-code/init-code/wifi_connection.py | 110 +
src/声源定位代码/mic-code/sound_map.py | 113 +
.../mic-code/sound_map_wifi.py | 114 +
.../Linux_SDK/.vscode/settings.json | 3 +
.../Linux_SDK/demo/.idea/.gitignore | 8 +
.../Linux_SDK/demo/.idea/demo.iml | 9 +
.../inspectionProfiles/Project_Default.xml | 6 +
.../Linux_SDK/demo/.idea/misc.xml | 6 +
.../Linux_SDK/demo/.idea/modules.xml | 8 +
.../Linux_SDK/demo/.idea/vcs.xml | 6 +
.../2025-06-10_08-55-17/details.md | 69 +
.../2025-06-10_08-55-17/diff-details.md | 15 +
.../2025-06-10_08-55-17/diff.csv | 2 +
.../2025-06-10_08-55-17/diff.md | 19 +
.../2025-06-10_08-55-17/diff.txt | 22 +
.../2025-06-10_08-55-17/results.csv | 56 +
.../2025-06-10_08-55-17/results.json | 1 +
.../2025-06-10_08-55-17/results.md | 50 +
.../2025-06-10_08-55-17/results.txt | 107 +
.../demo/audio-classification/.gitignore | 296 +
.../demo/audio-classification/LICENSE | 201 +
.../demo/audio-classification/README.md | 373 +
.../demo/audio-classification/README_en.md | 275 +
.../audio-classification-platform/README.md | 136 +
.../backend/app.py | 350 +
.../backend/config.py | 39 +
.../backend/requirements.txt | 7 +
.../frontend/index.html | 26 +
.../frontend/package.json | 24 +
.../frontend/src/App.vue | 106 +
.../frontend/src/components/AudioRecorder.vue | 743 +
.../src/components/AudioRecorder_new.vue | 1076 +
.../frontend/src/components/AudioUpload.vue | 741 +
.../frontend/src/components/HistoryList.vue | 635 +
.../src/components/PredictionResult.vue | 995 +
.../frontend/src/main.js | 18 +
.../frontend/src/router/index.js | 17 +
.../frontend/src/utils/api.js | 213 +
.../frontend/src/views/HomePage.vue | 841 +
.../frontend/vite.config.js | 33 +
.../frontend/yarn.lock | 1092 +
.../audio-classification-platform/start.bat | 24 +
.../audio-classification-platform/start.sh | 36 +
.../configs/augmentation.yml | 46 +
.../audio-classification/configs/cam++.yml | 80 +
.../configs/ecapa_tdnn.yml | 80 +
.../audio-classification/configs/eres2net.yml | 80 +
.../audio-classification/configs/panns.yml | 80 +
.../audio-classification/configs/res2net.yml | 80 +
.../configs/resnet_se.yml | 80 +
.../audio-classification/configs/tdnn.yml | 80 +
.../demo/audio-classification/create_data.py | 99 +
.../docs/images/image1.png | Bin 0 -> 69600 bytes
.../audio-classification/docs/images/log.jpg | Bin 0 -> 117637 bytes
.../demo/audio-classification/eval.py | 26 +
.../audio-classification/extract_features.py | 19 +
.../demo/audio-classification/infer.py | 23 +
.../demo/audio-classification/infer_record.py | 58 +
.../audio-classification/macls/__init__.py | 1 +
.../macls/data_utils/__init__.py | 0
.../macls/data_utils/collate_fn.py | 23 +
.../macls/data_utils/featurizer.py | 132 +
.../macls/data_utils/reader.py | 157 +
.../macls/metric/__init__.py | 0
.../macls/metric/metrics.py | 12 +
.../macls/optimizer/__init__.py | 32 +
.../macls/optimizer/scheduler.py | 48 +
.../audio-classification/macls/predict.py | 177 +
.../audio-classification/macls/trainer.py | 456 +
.../macls/utils/__init__.py | 0
.../macls/utils/checkpoint.py | 162 +
.../macls/utils/record.py | 31 +
.../audio-classification/macls/utils/utils.py | 131 +
.../demo/audio-classification/record_audio.py | 14 +
.../audio-classification/requirements.txt | 17 +
.../demo/audio-classification/setup.py | 54 +
.../tools/download_language_data.sh | 29 +
.../demo/audio-classification/train.py | 30 +
.../Linux_SDK/demo/database/README.md | 298 +
.../Linux_SDK/demo/database/config.py | 432 +
.../demo/database/create_tables_simple.sql | 102 +
.../database/create_tables_simple_mysql.sql | 99 +
.../Linux_SDK/demo/database/db_utils.py | 553 +
.../Linux_SDK/demo/database/init_database.py | 317 +
.../Linux_SDK/demo/database/requirements.txt | 34 +
.../Linux_SDK/demo/database/setup_database.py | 226 +
.../demo/demo_for_qt/FFVideoFormatConvert.cpp | 165 +
.../demo/demo_for_qt/FFVideoFormatConvert.h | 40 +
.../Linux_SDK/demo/demo_for_qt/MapWidget.cpp | 305 +
.../Linux_SDK/demo/demo_for_qt/MapWidget.h | 62 +
.../demo/demo_for_qt/QtCameraCapture.cpp | 99 +
.../demo/demo_for_qt/QtCameraCapture.h | 116 +
.../Linux_SDK/demo/demo_for_qt/README.md | 128 +
.../demo/demo_for_qt/RecordingFlash_32x32.png | Bin 0 -> 526 bytes
.../demo/demo_for_qt/ShaderSourceCode.h | 86 +
.../demo/demo_for_qt/VLKVideoWidget.cpp | 826 +
.../demo/demo_for_qt/VLKVideoWidget.h | 137 +
.../demo/demo_for_qt/VideoObjNetwork.cpp | 519 +
.../demo/demo_for_qt/VideoObjNetwork.h | 318 +
.../demo/demo_for_qt/VideoObjUSBCamera.cpp | 294 +
.../demo/demo_for_qt/VideoObjUSBCamera.h | 48 +
.../demo/demo_for_qt/circle_empty_48x48.png | Bin 0 -> 1164 bytes
.../demo_for_qt/circle_selected_32x32.png | Bin 0 -> 939 bytes
.../demo/demo_for_qt/demo_for_qt.pro | 142 +
.../demo/demo_for_qt/demo_for_qt.pro.user | 189 +
.../image/RecordingFlash_32x32.png | Bin 0 -> 1755 bytes
.../demo_for_qt/image/circle_empty_48x48.png | Bin 0 -> 870 bytes
.../image/circle_selected_32x32.png | Bin 0 -> 1144 bytes
.../demo/demo_for_qt/imagepreviewdialog.cpp | 71 +
.../demo/demo_for_qt/imagepreviewdialog.h | 38 +
.../Linux_SDK/demo/demo_for_qt/main.cpp | 39 +
.../Linux_SDK/demo/demo_for_qt/qml/Map.qml | 330 +
.../demo/demo_for_qt/qml/TargetMarker.qml | 94 +
.../Linux_SDK/demo/demo_for_qt/res.qrc | 9 +
.../Linux_SDK/demo/demo_for_qt/widget.cpp | 2009 ++
.../Linux_SDK/demo/demo_for_qt/widget.cpp.new | 1268 +
.../Linux_SDK/demo/demo_for_qt/widget.h | 756 +
.../Linux_SDK/demo/demo_for_qt/widget.ui | 1511 ++
.../demo/demo_for_qt/widget_new.ui.h | 1259 +
.../Linux_SDK/demo/gold_eyes/.gitignore | 71 +
.../Linux_SDK/demo/gold_eyes/src/flask_app.py | 101 +
.../Linux_SDK/demo/gold_eyes/src/main.py | 259 +
.../src/sound-vue-frontend/.gitignore | 52 +
.../src/sound-vue-frontend/README.md | 38 +
.../src/sound-vue-frontend/index.html | 13 +
.../src/sound-vue-frontend/package-lock.json | 19934 ++++++++++++++++
.../src/sound-vue-frontend/package.json | 38 +
.../src/sound-vue-frontend/src/App.vue | 393 +
.../sound-vue-frontend/src/assets/main.css | 19 +
.../src/components/SourceDataService.js | 11 +
.../src/sound-vue-frontend/src/main.js | 8 +
.../src/sound-vue-frontend/vue.config.js | 13 +
.../demo/identification system/CMakeLists.txt | 38 +
.../demo/identification system/README.md | 164 +
.../src/image_processor.cpp | 286 +
.../src/image_processor.h | 54 +
.../demo/identification system/src/main.cpp | 216 +
.../identification system/src/zhipu_api.cpp | 288 +
.../identification system/src/zhipu_api.h | 48 +
.../demo/move_control_tcp/CMakeLists.txt | 12 +
.../Linux_SDK/demo/move_control_tcp/README.md | 87 +
.../demo/move_control_tcp/compile.sh | 13 +
.../demo/move_control_tcp/tcp_client.cpp | 94 +
.../Linux_SDK/demo/workproject/CMakeLists.txt | 28 +
.../Linux_SDK/demo/workproject/README.md | 93 +
.../Linux_SDK/demo/workproject/build.sh | 48 +
.../demo/workproject/include/mavlink_client.h | 84 +
.../Linux_SDK/demo/workproject/run.sh | 60 +
.../Linux_SDK/demo/workproject/src/main.cpp | 137 +
.../demo/workproject/src/mavlink_client.cpp | 361 +
.../demo/workproject/使用说明.md | 138 +
.../Linux_SDK/doc/ViewLinkSDK.chm | Bin 0 -> 655818 bytes
.../Linux_SDK/inc/ViewLink.h | 840 +
257 files changed, 90775 insertions(+)
create mode 100644 src/README.md
create mode 100644 src/声源定位代码/README_声源定位系统.md
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/details.md
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff-details.md
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.csv
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.md
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.txt
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.csv
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.json
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.md
create mode 100644 src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.txt
create mode 100644 src/声源定位代码/audio-classification/.gitignore
create mode 100644 src/声源定位代码/audio-classification/LICENSE
create mode 100644 src/声源定位代码/audio-classification/README.md
create mode 100644 src/声源定位代码/audio-classification/README_en.md
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/README.md
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/backend/app.py
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/backend/config.py
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/backend/requirements.txt
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/index.html
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/package.json
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/App.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioUpload.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/HistoryList.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/PredictionResult.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/main.js
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/router/index.js
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/utils/api.js
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/views/HomePage.vue
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/vite.config.js
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/frontend/yarn.lock
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/start.bat
create mode 100644 src/声源定位代码/audio-classification/audio-classification-platform/start.sh
create mode 100644 src/声源定位代码/audio-classification/configs/augmentation.yml
create mode 100644 src/声源定位代码/audio-classification/configs/cam++.yml
create mode 100644 src/声源定位代码/audio-classification/configs/ecapa_tdnn.yml
create mode 100644 src/声源定位代码/audio-classification/configs/eres2net.yml
create mode 100644 src/声源定位代码/audio-classification/configs/panns.yml
create mode 100644 src/声源定位代码/audio-classification/configs/res2net.yml
create mode 100644 src/声源定位代码/audio-classification/configs/resnet_se.yml
create mode 100644 src/声源定位代码/audio-classification/configs/tdnn.yml
create mode 100644 src/声源定位代码/audio-classification/create_data.py
create mode 100644 src/声源定位代码/audio-classification/docs/images/image1.png
create mode 100644 src/声源定位代码/audio-classification/docs/images/log.jpg
create mode 100644 src/声源定位代码/audio-classification/eval.py
create mode 100644 src/声源定位代码/audio-classification/extract_features.py
create mode 100644 src/声源定位代码/audio-classification/infer.py
create mode 100644 src/声源定位代码/audio-classification/infer_record.py
create mode 100644 src/声源定位代码/audio-classification/macls/__init__.py
create mode 100644 src/声源定位代码/audio-classification/macls/data_utils/__init__.py
create mode 100644 src/声源定位代码/audio-classification/macls/data_utils/collate_fn.py
create mode 100644 src/声源定位代码/audio-classification/macls/data_utils/featurizer.py
create mode 100644 src/声源定位代码/audio-classification/macls/data_utils/reader.py
create mode 100644 src/声源定位代码/audio-classification/macls/metric/__init__.py
create mode 100644 src/声源定位代码/audio-classification/macls/metric/metrics.py
create mode 100644 src/声源定位代码/audio-classification/macls/optimizer/__init__.py
create mode 100644 src/声源定位代码/audio-classification/macls/optimizer/scheduler.py
create mode 100644 src/声源定位代码/audio-classification/macls/predict.py
create mode 100644 src/声源定位代码/audio-classification/macls/trainer.py
create mode 100644 src/声源定位代码/audio-classification/macls/utils/__init__.py
create mode 100644 src/声源定位代码/audio-classification/macls/utils/checkpoint.py
create mode 100644 src/声源定位代码/audio-classification/macls/utils/record.py
create mode 100644 src/声源定位代码/audio-classification/macls/utils/utils.py
create mode 100644 src/声源定位代码/audio-classification/record_audio.py
create mode 100644 src/声源定位代码/audio-classification/requirements.txt
create mode 100644 src/声源定位代码/audio-classification/setup.py
create mode 100644 src/声源定位代码/audio-classification/tools/download_language_data.sh
create mode 100644 src/声源定位代码/audio-classification/train.py
create mode 100644 src/声源定位代码/back-code/README.md
create mode 100644 src/声源定位代码/back-code/development_board.py
create mode 100644 src/声源定位代码/back-code/pc_server.py
create mode 100644 src/声源定位代码/config.ini
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/.gitignore
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/README.md
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/index.html
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/package-lock.json
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/package.json
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/src/App.vue
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/src/assets/main.css
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/src/components/SourceDataService.js
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/src/main.js
create mode 100644 src/声源定位代码/front-code/sound-vue-frontend/vue.config.js
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_config.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_fft.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_fpioa.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_gpio.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_i2s.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_kpu.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_kpu_classifier.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_mic_array.c
create mode 100644 src/声源定位代码/mic-code/Maix/Maix_utils.c
create mode 100644 src/声源定位代码/mic-code/Maix/include/Maix_config.h
create mode 100644 src/声源定位代码/mic-code/Maix/include/Maix_i2s.h
create mode 100644 src/声源定位代码/mic-code/Maix/include/Maix_kpu.h
create mode 100644 src/声源定位代码/mic-code/Maix/include/modMaix.h
create mode 100644 src/声源定位代码/mic-code/Maix/include/py_cpufreq.h
create mode 100644 src/声源定位代码/mic-code/Maix/modMaix.c
create mode 100644 src/声源定位代码/mic-code/Maix/py_cpufreq.c
create mode 100644 src/声源定位代码/mic-code/init-code/main.py
create mode 100644 src/声源定位代码/mic-code/init-code/main_raw.py
create mode 100644 src/声源定位代码/mic-code/init-code/tcp_listen.py
create mode 100644 src/声源定位代码/mic-code/init-code/test_send.py
create mode 100644 src/声源定位代码/mic-code/init-code/wifi_connection.py
create mode 100644 src/声源定位代码/mic-code/sound_map.py
create mode 100644 src/声源定位代码/mic-code/sound_map_wifi.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/.vscode/settings.json
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/.gitignore
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/demo.iml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/inspectionProfiles/Project_Default.xml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/misc.xml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/modules.xml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/.idea/vcs.xml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/details.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff-details.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.csv
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.csv
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.json
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/.gitignore
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/LICENSE
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/README_en.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/backend/app.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/backend/config.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/backend/requirements.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/index.html
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/package.json
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/App.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/components/AudioUpload.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/components/HistoryList.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/components/PredictionResult.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/main.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/router/index.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/utils/api.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/src/views/HomePage.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/vite.config.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/frontend/yarn.lock
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/start.bat
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/audio-classification-platform/start.sh
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/augmentation.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/cam++.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/ecapa_tdnn.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/eres2net.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/panns.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/res2net.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/resnet_se.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/configs/tdnn.yml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/create_data.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/docs/images/image1.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/docs/images/log.jpg
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/eval.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/extract_features.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/infer.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/infer_record.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/__init__.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/data_utils/__init__.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/data_utils/collate_fn.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/data_utils/featurizer.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/data_utils/reader.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/metric/__init__.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/metric/metrics.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/optimizer/__init__.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/optimizer/scheduler.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/predict.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/trainer.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/utils/__init__.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/utils/checkpoint.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/utils/record.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/macls/utils/utils.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/record_audio.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/requirements.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/setup.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/tools/download_language_data.sh
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/audio-classification/train.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/config.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/create_tables_simple.sql
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/create_tables_simple_mysql.sql
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/db_utils.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/init_database.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/requirements.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/database/setup_database.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/FFVideoFormatConvert.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/FFVideoFormatConvert.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/MapWidget.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/MapWidget.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/QtCameraCapture.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/QtCameraCapture.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/RecordingFlash_32x32.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/ShaderSourceCode.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VLKVideoWidget.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VLKVideoWidget.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VideoObjNetwork.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VideoObjNetwork.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VideoObjUSBCamera.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/VideoObjUSBCamera.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/circle_empty_48x48.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/circle_selected_32x32.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/demo_for_qt.pro
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/demo_for_qt.pro.user
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/image/RecordingFlash_32x32.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/image/circle_empty_48x48.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/image/circle_selected_32x32.png
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/imagepreviewdialog.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/imagepreviewdialog.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/main.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/qml/Map.qml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/qml/TargetMarker.qml
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/res.qrc
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/widget.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/widget.cpp.new
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/widget.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/widget.ui
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/demo_for_qt/widget_new.ui.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/.gitignore
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/flask_app.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/main.py
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/.gitignore
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/index.html
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/package-lock.json
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/package.json
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/src/App.vue
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/src/assets/main.css
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/src/components/SourceDataService.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/src/main.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/gold_eyes/src/sound-vue-frontend/vue.config.js
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/CMakeLists.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/src/image_processor.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/src/image_processor.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/src/main.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/src/zhipu_api.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/identification system/src/zhipu_api.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/move_control_tcp/CMakeLists.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/move_control_tcp/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/move_control_tcp/compile.sh
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/move_control_tcp/tcp_client.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/CMakeLists.txt
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/README.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/build.sh
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/include/mavlink_client.h
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/run.sh
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/src/main.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/src/mavlink_client.cpp
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/demo/workproject/使用说明.md
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/doc/ViewLinkSDK.chm
create mode 100644 src/声源定位代码/基于多模态的战场隐蔽威胁发现和定位系统总代码/Linux_SDK/inc/ViewLink.h
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 0000000..c5715d2
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1 @@
+# 这是一个src
\ No newline at end of file
diff --git a/src/声源定位代码/README_声源定位系统.md b/src/声源定位代码/README_声源定位系统.md
new file mode 100644
index 0000000..d599298
--- /dev/null
+++ b/src/声源定位代码/README_声源定位系统.md
@@ -0,0 +1,216 @@
+# 声源定位系统使用说明
+
+## 系统概述
+
+本系统由开发板端和PC端组成,实现声源定位和枪声识别功能。
+
+### 工作流程
+
+1. **开发板端**:开机后进入录音状态,持续录音并发送给PC端
+2. **PC端**:接收音频数据,使用audio-classification进行枪声识别
+3. **模式切换**:当识别到枪声时,PC端发送指令给开发板切换到定位模式
+4. **声源定位**:开发板在定位模式下实时发送声源定位数据给PC端
+5. **可视化**:PC端实时显示声源定位地图
+
+## 文件说明
+
+### 开发板端文件
+- `development_board_simple.py` - 简化版开发板端主程序(推荐使用)
+- `development_board.py` - 完整版开发板端主程序
+
+### PC端文件
+- `pc_server.py` - PC端服务器程序
+
+## 配置说明
+
+### 开发板端配置
+
+在 `development_board_simple.py` 中修改以下配置:
+
+```python
+# WiFi配置
+WIFI_SSID = "junzekeki" # 替换为你的WiFi SSID
+WIFI_PASSWD = "234567890l" # 替换为你的WiFi密码
+
+# PC端配置
+PC_IP = "192.168.1.100" # PC端IP地址,需要根据实际情况修改
+PC_PORT_AUDIO = 12346 # 音频传输端口
+PC_PORT_CMD = 12347 # 指令传输端口
+PC_PORT_LOCATION = 12348 # 定位数据传输端口
+```
+
+### PC端配置
+
+在 `pc_server.py` 中修改以下配置:
+
+```python
+# 网络配置
+HOST = "0.0.0.0" # 监听所有网络接口
+PORT_AUDIO = 12346 # 音频接收端口
+PORT_CMD = 12347 # 指令发送端口
+PORT_LOCATION = 12348 # 定位数据接收端口
+
+# 枪声识别配置
+GUNSHOT_THRESHOLD = 0.7 # 枪声识别阈值
+RECOGNITION_INTERVAL = 3.0 # 识别间隔(秒)
+```
+
+## 使用步骤
+
+### 1. 环境准备
+
+#### PC端环境
+```bash
+# 安装依赖
+pip install numpy matplotlib soundfile librosa
+
+# 如果使用audio-classification
+cd audio-classification
+pip install -r requirements.txt
+```
+
+#### 开发板端环境
+确保开发板已安装以下模块:
+- `fpioa_manager`
+- `Maix`
+- `board`
+- `network`
+- `socket`
+- `machine`
+
+### 2. 网络配置
+
+1. 确保开发板和PC在同一个WiFi网络下
+2. 获取PC的IP地址(Windows: `ipconfig`, Linux/Mac: `ifconfig`)
+3. 修改开发板端代码中的 `PC_IP` 为PC的实际IP地址
+
+### 3. 启动系统
+
+#### 启动PC端服务器
+```bash
+python pc_server.py
+```
+
+#### 启动开发板端
+将 `development_board_simple.py` 上传到开发板并运行:
+```bash
+python development_board_simple.py
+```
+
+### 4. 系统运行
+
+1. **初始化阶段**:
+ - 开发板自动连接WiFi
+ - 建立与PC端的Socket连接
+ - 进入录音模式
+
+2. **录音模式**:
+ - 开发板持续录音并发送音频数据
+ - PC端接收音频并进行枪声识别
+ - 控制台显示识别结果
+
+3. **定位模式**:
+ - 当检测到枪声时,PC端发送"START_LOCATION"指令
+ - 开发板切换到定位模式
+ - 实时发送声源定位数据
+ - PC端显示实时定位地图
+
+4. **模式切换**:
+ - 可通过关闭程序或发送"STOP_LOCATION"指令返回录音模式
+
+## 通信协议
+
+### 音频数据传输
+- 端口:12346
+- 格式:原始音频字节流(16位,16kHz,单声道)
+
+### 指令传输
+- 端口:12347
+- 格式:UTF-8字符串
+- 指令:
+ - `START_LOCATION` - 切换到定位模式
+ - `STOP_LOCATION` - 切换到录音模式
+
+### 定位数据传输
+- 端口:12348
+- 格式:`X,Y,强度,角度`(CSV格式)
+- 示例:`1.234,2.345,3.456,45.67`
+
+## 故障排除
+
+### 常见问题
+
+1. **WiFi连接失败**
+ - 检查WiFi SSID和密码是否正确
+ - 确保WiFi信号强度足够
+ - 检查开发板WiFi模块是否正常
+
+2. **Socket连接失败**
+ - 检查PC IP地址是否正确
+ - 确保防火墙未阻止端口
+ - 检查网络连接是否正常
+
+3. **音频识别失败**
+ - 检查audio-classification模型是否正确安装
+ - 确认模型文件路径是否正确
+ - 检查音频数据格式是否符合要求
+
+4. **定位数据异常**
+ - 检查麦克风阵列连接
+ - 确认麦克风阵列初始化是否成功
+ - 检查环境噪声是否过大
+
+### 调试方法
+
+1. **查看控制台输出**
+ - 开发板端和PC端都会输出详细的运行日志
+ - 根据日志信息定位问题
+
+2. **网络测试**
+ - 使用ping命令测试网络连通性
+ - 使用telnet测试端口是否开放
+
+3. **音频测试**
+ - 使用现有音频文件测试识别功能
+ - 检查音频数据是否正确接收
+
+## 扩展功能
+
+### 自定义音频识别
+可以修改PC端代码,使用其他音频分类模型或自定义识别逻辑。
+
+### 数据记录
+可以添加数据记录功能,保存音频文件和定位数据。
+
+### 多设备支持
+可以扩展支持多个开发板同时工作。
+
+### 远程控制
+可以添加Web界面进行远程控制和监控。
+
+## 注意事项
+
+1. **安全考虑**
+ - 本系统仅用于测试和演示
+ - 请勿用于实际的安全监控场景
+ - 注意保护个人隐私
+
+2. **性能优化**
+ - 根据实际需求调整识别间隔
+ - 优化网络传输参数
+ - 考虑使用更高效的音频编码
+
+3. **硬件要求**
+ - 开发板需要支持WiFi和麦克风阵列
+ - PC端需要足够的计算能力进行音频识别
+ - 建议使用有线网络连接以提高稳定性
+
+## 技术支持
+
+如有问题,请检查:
+1. 代码配置是否正确
+2. 网络连接是否正常
+3. 硬件连接是否牢固
+4. 依赖库是否正确安装
+
+更多技术细节请参考项目中的其他文档和代码注释。
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/details.md b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/details.md
new file mode 100644
index 0000000..f1a1fd9
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/details.md
@@ -0,0 +1,69 @@
+# Details
+
+Date : 2025-06-10 08:55:17
+
+Directory e:\\pycharm_projects\\AudioClassification-Pytorch-master
+
+Total : 54 files, 6851 codes, 838 comments, 1201 blanks, all 8890 lines
+
+[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
+
+## Files
+| filename | language | code | comment | blank | total |
+| :--- | :--- | ---: | ---: | ---: | ---: |
+| [README.md](/README.md) | Markdown | 302 | 0 | 72 | 374 |
+| [README\_en.md](/README_en.md) | Markdown | 231 | 0 | 45 | 276 |
+| [audio-classification-platform/README.md](/audio-classification-platform/README.md) | Markdown | 96 | 0 | 41 | 137 |
+| [audio-classification-platform/backend/app.py](/audio-classification-platform/backend/app.py) | Python | 255 | 35 | 61 | 351 |
+| [audio-classification-platform/backend/config.py](/audio-classification-platform/backend/config.py) | Python | 22 | 8 | 10 | 40 |
+| [audio-classification-platform/backend/requirements.txt](/audio-classification-platform/backend/requirements.txt) | pip requirements | 7 | 0 | 1 | 8 |
+| [audio-classification-platform/frontend/index.html](/audio-classification-platform/frontend/index.html) | HTML | 25 | 0 | 2 | 27 |
+| [audio-classification-platform/frontend/package.json](/audio-classification-platform/frontend/package.json) | JSON | 24 | 0 | 1 | 25 |
+| [audio-classification-platform/frontend/src/App.vue](/audio-classification-platform/frontend/src/App.vue) | Vue | 88 | 5 | 14 | 107 |
+| [audio-classification-platform/frontend/src/components/AudioRecorder.vue](/audio-classification-platform/frontend/src/components/AudioRecorder.vue) | Vue | 551 | 38 | 102 | 691 |
+| [audio-classification-platform/frontend/src/components/AudioRecorder\_new.vue](/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue) | Vue | 811 | 48 | 162 | 1,021 |
+| [audio-classification-platform/frontend/src/components/AudioUpload.vue](/audio-classification-platform/frontend/src/components/AudioUpload.vue) | Vue | 580 | 28 | 107 | 715 |
+| [audio-classification-platform/frontend/src/components/HistoryList.vue](/audio-classification-platform/frontend/src/components/HistoryList.vue) | Vue | 513 | 25 | 79 | 617 |
+| [audio-classification-platform/frontend/src/components/PredictionResult.vue](/audio-classification-platform/frontend/src/components/PredictionResult.vue) | Vue | 803 | 22 | 117 | 942 |
+| [audio-classification-platform/frontend/src/main.js](/audio-classification-platform/frontend/src/main.js) | JavaScript | 13 | 1 | 5 | 19 |
+| [audio-classification-platform/frontend/src/router/index.js](/audio-classification-platform/frontend/src/router/index.js) | JavaScript | 14 | 0 | 4 | 18 |
+| [audio-classification-platform/frontend/src/utils/api.js](/audio-classification-platform/frontend/src/utils/api.js) | JavaScript | 156 | 25 | 33 | 214 |
+| [audio-classification-platform/frontend/src/views/HomePage.vue](/audio-classification-platform/frontend/src/views/HomePage.vue) | Vue | 692 | 40 | 110 | 842 |
+| [audio-classification-platform/frontend/vite.config.js](/audio-classification-platform/frontend/vite.config.js) | JavaScript | 32 | 0 | 2 | 34 |
+| [audio-classification-platform/start.bat](/audio-classification-platform/start.bat) | Batch | 20 | 0 | 5 | 25 |
+| [audio-classification-platform/start.sh](/audio-classification-platform/start.sh) | Shell Script | 26 | 3 | 8 | 37 |
+| [configs/augmentation.yml](/configs/augmentation.yml) | YAML | 21 | 21 | 5 | 47 |
+| [configs/cam++.yml](/configs/cam++.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/ecapa\_tdnn.yml](/configs/ecapa_tdnn.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/eres2net.yml](/configs/eres2net.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/panns.yml](/configs/panns.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/res2net.yml](/configs/res2net.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/resnet\_se.yml](/configs/resnet_se.yml) | YAML | 43 | 33 | 5 | 81 |
+| [configs/tdnn.yml](/configs/tdnn.yml) | YAML | 43 | 33 | 5 | 81 |
+| [create\_data.py](/create_data.py) | Python | 75 | 9 | 16 | 100 |
+| [eval.py](/eval.py) | Python | 20 | 2 | 5 | 27 |
+| [extract\_features.py](/extract_features.py) | Python | 13 | 2 | 5 | 20 |
+| [infer.py](/infer.py) | Python | 17 | 1 | 6 | 24 |
+| [infer\_record.py](/infer_record.py) | Python | 40 | 7 | 12 | 59 |
+| [macls/\_\_init\_\_.py](/macls/__init__.py) | Python | 1 | 0 | 1 | 2 |
+| [macls/data\_utils/\_\_init\_\_.py](/macls/data_utils/__init__.py) | Python | 0 | 0 | 1 | 1 |
+| [macls/data\_utils/collate\_fn.py](/macls/data_utils/collate_fn.py) | Python | 17 | 4 | 3 | 24 |
+| [macls/data\_utils/featurizer.py](/macls/data_utils/featurizer.py) | Python | 88 | 36 | 9 | 133 |
+| [macls/data\_utils/reader.py](/macls/data_utils/reader.py) | Python | 114 | 33 | 11 | 158 |
+| [macls/metric/\_\_init\_\_.py](/macls/metric/__init__.py) | Python | 0 | 0 | 1 | 1 |
+| [macls/metric/metrics.py](/macls/metric/metrics.py) | Python | 9 | 1 | 3 | 13 |
+| [macls/optimizer/\_\_init\_\_.py](/macls/optimizer/__init__.py) | Python | 26 | 0 | 7 | 33 |
+| [macls/optimizer/scheduler.py](/macls/optimizer/scheduler.py) | Python | 42 | 0 | 7 | 49 |
+| [macls/predict.py](/macls/predict.py) | Python | 124 | 47 | 7 | 178 |
+| [macls/trainer.py](/macls/trainer.py) | Python | 338 | 99 | 20 | 457 |
+| [macls/utils/\_\_init\_\_.py](/macls/utils/__init__.py) | Python | 0 | 0 | 1 | 1 |
+| [macls/utils/checkpoint.py](/macls/utils/checkpoint.py) | Python | 113 | 40 | 10 | 163 |
+| [macls/utils/record.py](/macls/utils/record.py) | Python | 18 | 8 | 6 | 32 |
+| [macls/utils/utils.py](/macls/utils/utils.py) | Python | 99 | 16 | 17 | 132 |
+| [record\_audio.py](/record_audio.py) | Python | 10 | 0 | 5 | 15 |
+| [requirements.txt](/requirements.txt) | pip requirements | 17 | 0 | 1 | 18 |
+| [setup.py](/setup.py) | Python | 43 | 1 | 11 | 55 |
+| [tools/download\_language\_data.sh](/tools/download_language_data.sh) | Shell Script | 19 | 1 | 10 | 30 |
+| [train.py](/train.py) | Python | 25 | 1 | 5 | 31 |
+
+[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff-details.md b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff-details.md
new file mode 100644
index 0000000..55f2906
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff-details.md
@@ -0,0 +1,15 @@
+# Diff Details
+
+Date : 2025-06-10 08:55:17
+
+Directory e:\\pycharm_projects\\AudioClassification-Pytorch-master
+
+Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
+
+[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
+
+## Files
+| filename | language | code | comment | blank | total |
+| :--- | :--- | ---: | ---: | ---: | ---: |
+
+[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.csv b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.csv
new file mode 100644
index 0000000..b7d8d75
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.csv
@@ -0,0 +1,2 @@
+"filename", "language", "", "comment", "blank", "total"
+"Total", "-", , 0, 0, 0
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.md b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.md
new file mode 100644
index 0000000..0cab177
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.md
@@ -0,0 +1,19 @@
+# Diff Summary
+
+Date : 2025-06-10 08:55:17
+
+Directory e:\\pycharm_projects\\AudioClassification-Pytorch-master
+
+Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
+
+[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
+
+## Languages
+| language | files | code | comment | blank | total |
+| :--- | ---: | ---: | ---: | ---: | ---: |
+
+## Directories
+| path | files | code | comment | blank | total |
+| :--- | ---: | ---: | ---: | ---: | ---: |
+
+[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md)
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.txt b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.txt
new file mode 100644
index 0000000..b332216
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/diff.txt
@@ -0,0 +1,22 @@
+Date : 2025-06-10 08:55:17
+Directory : e:\pycharm_projects\AudioClassification-Pytorch-master
+Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines
+
+Languages
++----------+------------+------------+------------+------------+------------+
+| language | files | code | comment | blank | total |
++----------+------------+------------+------------+------------+------------+
++----------+------------+------------+------------+------------+------------+
+
+Directories
++------+------------+------------+------------+------------+------------+
+| path | files | code | comment | blank | total |
++------+------------+------------+------------+------------+------------+
++------+------------+------------+------------+------------+------------+
+
+Files
++----------+----------+------------+------------+------------+------------+
+| filename | language | code | comment | blank | total |
++----------+----------+------------+------------+------------+------------+
+| Total | | 0 | 0 | 0 | 0 |
++----------+----------+------------+------------+------------+------------+
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.csv b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.csv
new file mode 100644
index 0000000..6cde0c8
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.csv
@@ -0,0 +1,56 @@
+"filename", "language", "Python", "pip requirements", "Markdown", "Shell Script", "YAML", "Batch", "JavaScript", "Vue", "JSON", "HTML", "comment", "blank", "total"
+"e:\pycharm_projects\AudioClassification-Pytorch-master\README.md", "Markdown", 0, 0, 302, 0, 0, 0, 0, 0, 0, 0, 0, 72, 374
+"e:\pycharm_projects\AudioClassification-Pytorch-master\README_en.md", "Markdown", 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 45, 276
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\README.md", "Markdown", 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 41, 137
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\app.py", "Python", 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 61, 351
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\config.py", "Python", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 40
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\requirements.txt", "pip requirements", 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\index.html", "HTML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 2, 27
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\package.json", "JSON", 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 1, 25
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\App.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 5, 14, 107
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioRecorder.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 551, 0, 0, 38, 102, 691
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioRecorder_new.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 811, 0, 0, 48, 162, 1021
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioUpload.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 580, 0, 0, 28, 107, 715
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\HistoryList.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 25, 79, 617
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\PredictionResult.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 803, 0, 0, 22, 117, 942
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\main.js", "JavaScript", 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 1, 5, 19
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\router\index.js", "JavaScript", 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 4, 18
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\utils\api.js", "JavaScript", 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 25, 33, 214
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\views\HomePage.vue", "Vue", 0, 0, 0, 0, 0, 0, 0, 692, 0, 0, 40, 110, 842
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\vite.config.js", "JavaScript", 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 2, 34
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\start.bat", "Batch", 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 5, 25
+"e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\start.sh", "Shell Script", 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 3, 8, 37
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\augmentation.yml", "YAML", 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 21, 5, 47
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\cam++.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\ecapa_tdnn.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\eres2net.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\panns.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\res2net.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\resnet_se.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\configs\tdnn.yml", "YAML", 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 33, 5, 81
+"e:\pycharm_projects\AudioClassification-Pytorch-master\create_data.py", "Python", 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 16, 100
+"e:\pycharm_projects\AudioClassification-Pytorch-master\eval.py", "Python", 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 27
+"e:\pycharm_projects\AudioClassification-Pytorch-master\extract_features.py", "Python", 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 20
+"e:\pycharm_projects\AudioClassification-Pytorch-master\infer.py", "Python", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 24
+"e:\pycharm_projects\AudioClassification-Pytorch-master\infer_record.py", "Python", 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 12, 59
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\__init__.py", "Python", 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\__init__.py", "Python", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\collate_fn.py", "Python", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 24
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\featurizer.py", "Python", 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 9, 133
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\reader.py", "Python", 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 11, 158
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\metric\__init__.py", "Python", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\metric\metrics.py", "Python", 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 13
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\optimizer\__init__.py", "Python", 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 33
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\optimizer\scheduler.py", "Python", 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 49
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\predict.py", "Python", 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 7, 178
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\trainer.py", "Python", 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 20, 457
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\__init__.py", "Python", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\checkpoint.py", "Python", 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 10, 163
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\record.py", "Python", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 6, 32
+"e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\utils.py", "Python", 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 132
+"e:\pycharm_projects\AudioClassification-Pytorch-master\record_audio.py", "Python", 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 15
+"e:\pycharm_projects\AudioClassification-Pytorch-master\requirements.txt", "pip requirements", 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 18
+"e:\pycharm_projects\AudioClassification-Pytorch-master\setup.py", "Python", 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 55
+"e:\pycharm_projects\AudioClassification-Pytorch-master\tools\download_language_data.sh", "Shell Script", 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 1, 10, 30
+"e:\pycharm_projects\AudioClassification-Pytorch-master\train.py", "Python", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 5, 31
+"Total", "-", 1509, 24, 629, 45, 322, 20, 215, 4038, 24, 25, 838, 1201, 8890
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.json b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.json
new file mode 100644
index 0000000..922a690
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.json
@@ -0,0 +1 @@
+{"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/record_audio.py":{"language":"Python","code":10,"comment":0,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/train.py":{"language":"Python","code":25,"comment":1,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/setup.py":{"language":"Python","code":43,"comment":1,"blank":11},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/requirements.txt":{"language":"pip requirements","code":17,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/README_en.md":{"language":"Markdown","code":231,"comment":0,"blank":45},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/tools/download_language_data.sh":{"language":"Shell Script","code":19,"comment":1,"blank":10},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/infer.py":{"language":"Python","code":17,"comment":1,"blank":6},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/infer_record.py":{"language":"Python","code":40,"comment":7,"blank":12},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/__init__.py":{"language":"Python","code":1,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/extract_features.py":{"language":"Python","code":13,"comment":2,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/README.md":{"language":"Markdown","code":302,"comment":0,"blank":72},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/create_data.py":{"language":"Python","code":75,"comment":9,"blank":16},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/trainer.py":{"language":"Python","code":338,"comment":99,"blank":20},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/optimizer/__init__.py":{"language":"Python","code":26,"comment":0,"blank":7},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/optimizer/scheduler.py":{"language":"Python","code":42,"comment":0,"blank":7},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/predict.py":{"language":"Python","code":124,"comment":47,"blank":7},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/eval.py":{"language":"Python","code":20,"comment":2,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/tdnn.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/resnet_se.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/panns.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/res2net.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/ecapa_tdnn.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/cam%2B%2B.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/eres2net.yml":{"language":"YAML","code":43,"comment":33,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/utils/utils.py":{"language":"Python","code":99,"comment":16,"blank":17},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/metric/metrics.py":{"language":"Python","code":9,"comment":1,"blank":3},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/configs/augmentation.yml":{"language":"YAML","code":21,"comment":21,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/utils/__init__.py":{"language":"Python","code":0,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/utils/record.py":{"language":"Python","code":18,"comment":8,"blank":6},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/metric/__init__.py":{"language":"Python","code":0,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/utils/checkpoint.py":{"language":"Python","code":113,"comment":40,"blank":10},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/start.sh":{"language":"Shell Script","code":26,"comment":3,"blank":8},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/start.bat":{"language":"Batch","code":20,"comment":0,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/README.md":{"language":"Markdown","code":96,"comment":0,"blank":41},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/data_utils/reader.py":{"language":"Python","code":114,"comment":33,"blank":11},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/data_utils/featurizer.py":{"language":"Python","code":88,"comment":36,"blank":9},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/vite.config.js":{"language":"JavaScript","code":32,"comment":0,"blank":2},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/data_utils/collate_fn.py":{"language":"Python","code":17,"comment":4,"blank":3},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/macls/data_utils/__init__.py":{"language":"Python","code":0,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/main.js":{"language":"JavaScript","code":13,"comment":1,"blank":5},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/views/HomePage.vue":{"language":"Vue","code":692,"comment":40,"blank":110},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/backend/config.py":{"language":"Python","code":22,"comment":8,"blank":10},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/App.vue":{"language":"Vue","code":88,"comment":5,"blank":14},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/package.json":{"language":"JSON","code":24,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/index.html":{"language":"HTML","code":25,"comment":0,"blank":2},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/backend/requirements.txt":{"language":"pip requirements","code":7,"comment":0,"blank":1},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/components/HistoryList.vue":{"language":"Vue","code":513,"comment":25,"blank":79},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/components/AudioUpload.vue":{"language":"Vue","code":580,"comment":28,"blank":107},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/backend/app.py":{"language":"Python","code":255,"comment":35,"blank":61},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/components/PredictionResult.vue":{"language":"Vue","code":803,"comment":22,"blank":117},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue":{"language":"Vue","code":811,"comment":48,"blank":162},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/utils/api.js":{"language":"JavaScript","code":156,"comment":25,"blank":33},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/router/index.js":{"language":"JavaScript","code":14,"comment":0,"blank":4},"file:///e%3A/pycharm_projects/AudioClassification-Pytorch-master/audio-classification-platform/frontend/src/components/AudioRecorder.vue":{"language":"Vue","code":551,"comment":38,"blank":102}}
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.md b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.md
new file mode 100644
index 0000000..ac3e4e6
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.md
@@ -0,0 +1,50 @@
+# Summary
+
+Date : 2025-06-10 08:55:17
+
+Directory e:\\pycharm_projects\\AudioClassification-Pytorch-master
+
+Total : 54 files, 6851 codes, 838 comments, 1201 blanks, all 8890 lines
+
+Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
+
+## Languages
+| language | files | code | comment | blank | total |
+| :--- | ---: | ---: | ---: | ---: | ---: |
+| Vue | 7 | 4,038 | 206 | 691 | 4,935 |
+| Python | 25 | 1,509 | 350 | 240 | 2,099 |
+| Markdown | 3 | 629 | 0 | 158 | 787 |
+| YAML | 8 | 322 | 252 | 40 | 614 |
+| JavaScript | 4 | 215 | 26 | 44 | 285 |
+| Shell Script | 2 | 45 | 4 | 18 | 67 |
+| HTML | 1 | 25 | 0 | 2 | 27 |
+| pip requirements | 2 | 24 | 0 | 2 | 26 |
+| JSON | 1 | 24 | 0 | 1 | 25 |
+| Batch | 1 | 20 | 0 | 5 | 25 |
+
+## Directories
+| path | files | code | comment | blank | total |
+| :--- | ---: | ---: | ---: | ---: | ---: |
+| . | 54 | 6,851 | 838 | 1,201 | 8,890 |
+| . (Files) | 11 | 793 | 23 | 183 | 999 |
+| audio-classification-platform | 19 | 4,728 | 278 | 864 | 5,870 |
+| audio-classification-platform (Files) | 3 | 142 | 3 | 54 | 199 |
+| audio-classification-platform\\backend | 3 | 284 | 43 | 72 | 399 |
+| audio-classification-platform\\frontend | 13 | 4,302 | 232 | 738 | 5,272 |
+| audio-classification-platform\\frontend (Files) | 3 | 81 | 0 | 5 | 86 |
+| audio-classification-platform\\frontend\\src | 10 | 4,221 | 232 | 733 | 5,186 |
+| audio-classification-platform\\frontend\\src (Files) | 2 | 101 | 6 | 19 | 126 |
+| audio-classification-platform\\frontend\\src\\components | 5 | 3,258 | 161 | 567 | 3,986 |
+| audio-classification-platform\\frontend\\src\\router | 1 | 14 | 0 | 4 | 18 |
+| audio-classification-platform\\frontend\\src\\utils | 1 | 156 | 25 | 33 | 214 |
+| audio-classification-platform\\frontend\\src\\views | 1 | 692 | 40 | 110 | 842 |
+| configs | 8 | 322 | 252 | 40 | 614 |
+| macls | 15 | 989 | 284 | 104 | 1,377 |
+| macls (Files) | 3 | 463 | 146 | 28 | 637 |
+| macls\\data_utils | 4 | 219 | 73 | 24 | 316 |
+| macls\\metric | 2 | 9 | 1 | 4 | 14 |
+| macls\\optimizer | 2 | 68 | 0 | 14 | 82 |
+| macls\\utils | 4 | 230 | 64 | 34 | 328 |
+| tools | 1 | 19 | 1 | 10 | 30 |
+
+Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md)
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.txt b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.txt
new file mode 100644
index 0000000..8367acc
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.VSCodeCounter/2025-06-10_08-55-17/results.txt
@@ -0,0 +1,107 @@
+Date : 2025-06-10 08:55:17
+Directory : e:\pycharm_projects\AudioClassification-Pytorch-master
+Total : 54 files, 6851 codes, 838 comments, 1201 blanks, all 8890 lines
+
+Languages
++------------------+------------+------------+------------+------------+------------+
+| language | files | code | comment | blank | total |
++------------------+------------+------------+------------+------------+------------+
+| Vue | 7 | 4,038 | 206 | 691 | 4,935 |
+| Python | 25 | 1,509 | 350 | 240 | 2,099 |
+| Markdown | 3 | 629 | 0 | 158 | 787 |
+| YAML | 8 | 322 | 252 | 40 | 614 |
+| JavaScript | 4 | 215 | 26 | 44 | 285 |
+| Shell Script | 2 | 45 | 4 | 18 | 67 |
+| HTML | 1 | 25 | 0 | 2 | 27 |
+| pip requirements | 2 | 24 | 0 | 2 | 26 |
+| JSON | 1 | 24 | 0 | 1 | 25 |
+| Batch | 1 | 20 | 0 | 5 | 25 |
++------------------+------------+------------+------------+------------+------------+
+
+Directories
++------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
+| path | files | code | comment | blank | total |
++------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
+| . | 54 | 6,851 | 838 | 1,201 | 8,890 |
+| . (Files) | 11 | 793 | 23 | 183 | 999 |
+| audio-classification-platform | 19 | 4,728 | 278 | 864 | 5,870 |
+| audio-classification-platform (Files) | 3 | 142 | 3 | 54 | 199 |
+| audio-classification-platform\backend | 3 | 284 | 43 | 72 | 399 |
+| audio-classification-platform\frontend | 13 | 4,302 | 232 | 738 | 5,272 |
+| audio-classification-platform\frontend (Files) | 3 | 81 | 0 | 5 | 86 |
+| audio-classification-platform\frontend\src | 10 | 4,221 | 232 | 733 | 5,186 |
+| audio-classification-platform\frontend\src (Files) | 2 | 101 | 6 | 19 | 126 |
+| audio-classification-platform\frontend\src\components | 5 | 3,258 | 161 | 567 | 3,986 |
+| audio-classification-platform\frontend\src\router | 1 | 14 | 0 | 4 | 18 |
+| audio-classification-platform\frontend\src\utils | 1 | 156 | 25 | 33 | 214 |
+| audio-classification-platform\frontend\src\views | 1 | 692 | 40 | 110 | 842 |
+| configs | 8 | 322 | 252 | 40 | 614 |
+| macls | 15 | 989 | 284 | 104 | 1,377 |
+| macls (Files) | 3 | 463 | 146 | 28 | 637 |
+| macls\data_utils | 4 | 219 | 73 | 24 | 316 |
+| macls\metric | 2 | 9 | 1 | 4 | 14 |
+| macls\optimizer | 2 | 68 | 0 | 14 | 82 |
+| macls\utils | 4 | 230 | 64 | 34 | 328 |
+| tools | 1 | 19 | 1 | 10 | 30 |
++------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+
+
+Files
++------------------------------------------------------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+
+| filename | language | code | comment | blank | total |
++------------------------------------------------------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+
+| e:\pycharm_projects\AudioClassification-Pytorch-master\README.md | Markdown | 302 | 0 | 72 | 374 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\README_en.md | Markdown | 231 | 0 | 45 | 276 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\README.md | Markdown | 96 | 0 | 41 | 137 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\app.py | Python | 255 | 35 | 61 | 351 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\config.py | Python | 22 | 8 | 10 | 40 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\backend\requirements.txt | pip requirements | 7 | 0 | 1 | 8 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\index.html | HTML | 25 | 0 | 2 | 27 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\package.json | JSON | 24 | 0 | 1 | 25 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\App.vue | Vue | 88 | 5 | 14 | 107 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioRecorder.vue | Vue | 551 | 38 | 102 | 691 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioRecorder_new.vue | Vue | 811 | 48 | 162 | 1,021 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\AudioUpload.vue | Vue | 580 | 28 | 107 | 715 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\HistoryList.vue | Vue | 513 | 25 | 79 | 617 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\components\PredictionResult.vue | Vue | 803 | 22 | 117 | 942 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\main.js | JavaScript | 13 | 1 | 5 | 19 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\router\index.js | JavaScript | 14 | 0 | 4 | 18 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\utils\api.js | JavaScript | 156 | 25 | 33 | 214 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\src\views\HomePage.vue | Vue | 692 | 40 | 110 | 842 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\frontend\vite.config.js | JavaScript | 32 | 0 | 2 | 34 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\start.bat | Batch | 20 | 0 | 5 | 25 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\audio-classification-platform\start.sh | Shell Script | 26 | 3 | 8 | 37 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\augmentation.yml | YAML | 21 | 21 | 5 | 47 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\cam++.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\ecapa_tdnn.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\eres2net.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\panns.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\res2net.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\resnet_se.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\configs\tdnn.yml | YAML | 43 | 33 | 5 | 81 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\create_data.py | Python | 75 | 9 | 16 | 100 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\eval.py | Python | 20 | 2 | 5 | 27 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\extract_features.py | Python | 13 | 2 | 5 | 20 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\infer.py | Python | 17 | 1 | 6 | 24 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\infer_record.py | Python | 40 | 7 | 12 | 59 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\__init__.py | Python | 1 | 0 | 1 | 2 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\__init__.py | Python | 0 | 0 | 1 | 1 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\collate_fn.py | Python | 17 | 4 | 3 | 24 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\featurizer.py | Python | 88 | 36 | 9 | 133 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\data_utils\reader.py | Python | 114 | 33 | 11 | 158 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\metric\__init__.py | Python | 0 | 0 | 1 | 1 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\metric\metrics.py | Python | 9 | 1 | 3 | 13 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\optimizer\__init__.py | Python | 26 | 0 | 7 | 33 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\optimizer\scheduler.py | Python | 42 | 0 | 7 | 49 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\predict.py | Python | 124 | 47 | 7 | 178 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\trainer.py | Python | 338 | 99 | 20 | 457 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\__init__.py | Python | 0 | 0 | 1 | 1 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\checkpoint.py | Python | 113 | 40 | 10 | 163 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\record.py | Python | 18 | 8 | 6 | 32 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\macls\utils\utils.py | Python | 99 | 16 | 17 | 132 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\record_audio.py | Python | 10 | 0 | 5 | 15 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\requirements.txt | pip requirements | 17 | 0 | 1 | 18 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\setup.py | Python | 43 | 1 | 11 | 55 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\tools\download_language_data.sh | Shell Script | 19 | 1 | 10 | 30 |
+| e:\pycharm_projects\AudioClassification-Pytorch-master\train.py | Python | 25 | 1 | 5 | 31 |
+| Total | | 6,851 | 838 | 1,201 | 8,890 |
++------------------------------------------------------------------------------------------------------------------------------------+------------------+------------+------------+------------+------------+
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/.gitignore b/src/声源定位代码/audio-classification/.gitignore
new file mode 100644
index 0000000..92da7e3
--- /dev/null
+++ b/src/声源定位代码/audio-classification/.gitignore
@@ -0,0 +1,296 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+macls.egg-info/
+
+# PyInstaller
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django/Flask stuff
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+instance/
+.webassets-cache
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+Pipfile.lock
+
+# PEP 582
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# Node.js dependencies
+node_modules/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+package-lock.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage/
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage
+.grunt
+
+# Bower dependency directory
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons
+build/Release
+
+# Dependency directories
+jspm_packages/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+.env.local
+.env.production
+
+# parcel-bundler cache
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+
+# Gatsby files
+# Comment in the public line in if your project uses Gatsby
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# Audio Classification specific ignores
+# Model files (usually large)
+*.pth
+*.pt
+*.h5
+*.ckpt
+*.pb
+*.onnx
+*.pkl
+*.joblib
+
+# Dataset directories (usually large audio files)
+dataset/
+dataset/*/audio/
+dataset/*/wav/
+dataset/*/mp3/
+dataset/*/flac/
+# Uncomment if you want to ignore all audio files
+# *.wav
+# *.mp3
+# *.flac
+# *.ogg
+# *.m4a
+# *.aac
+
+# Training artifacts and logs
+log/
+logs/
+output/
+outputs/
+uploads/
+results/
+checkpoints/
+models/
+pretrained_models/
+feature_models/
+runs/
+wandb/
+mlruns/
+.mlflow/
+
+# Temporary files
+temp/
+tmp/
+*.tmp
+test*.py
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# IDE files
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+
+# Audio processing temporary files
+*.spec
+*.mfcc
+*.mel
+
+# Frontend build files
+audio-classification-platform/frontend/dist/
+audio-classification-platform/frontend/build/
+audio-classification-platform/frontend/.vite/
+
+# Uploaded files directory
+audio-classification-platform/backend/uploads/
+
+# Local development configuration
+audio-classification-platform/backend/.env
+audio-classification-platform/frontend/.env.local
\ No newline at end of file
diff --git a/src/声源定位代码/audio-classification/LICENSE b/src/声源定位代码/audio-classification/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/src/声源定位代码/audio-classification/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/src/声源定位代码/audio-classification/README.md b/src/声源定位代码/audio-classification/README.md
new file mode 100644
index 0000000..5e1aa31
--- /dev/null
+++ b/src/声源定位代码/audio-classification/README.md
@@ -0,0 +1,373 @@
+简体中文 | [English](./README_en.md)
+
+# 基于Pytorch实现的声音分类系统
+
+
+
+
+
+
+
+# 前言
+
+本项目是基于Pytorch的声音分类项目,旨在实现对各种环境声音、动物叫声和语种的识别。项目提供了多种声音分类模型,如EcapaTdnn、PANNS、ResNetSE、CAMPPlus和ERes2Net,以支持不同的应用场景。此外,项目还提供了常用的Urbansound8K数据集测试报告和一些方言数据集的下载和使用例子。用户可以根据自己的需求选择适合的模型和数据集,以实现更准确的声音分类。项目的应用场景广泛,可以用于室外的环境监测、野生动物保护、语音识别等领域。同时,项目也鼓励用户探索更多的使用场景,以推动声音分类技术的发展和应用。
+
+**欢迎大家扫码入知识星球或者QQ群讨论,知识星球里面提供项目的模型文件和博主其他相关项目的模型文件,也包括其他一些资源。**
+
+
+

+

+
+
+
+# 目录
+
+- [前言](#前言)
+- [项目特性](#项目特性)
+- [模型测试表](#模型测试表)
+- [安装环境](#安装环境)
+- [创建数据](#创建数据)
+- [修改预处理方法(可选)](#修改预处理方法可选)
+- [提取特征(可选)](#提取特征可选)
+- [训练模型](#训练模型)
+- [评估模型](#评估模型)
+- [预测](#预测)
+- [其他功能](#其他功能)
+
+
+# 使用准备
+
+ - Anaconda 3
+ - Python 3.11
+ - Pytorch 2.0.1
+ - Windows 11 or Ubuntu 22.04
+
+# 项目特性
+
+1. 支持模型:EcapaTdnn、PANNS、TDNN、Res2Net、ResNetSE、CAMPPlus、ERes2Net
+2. 支持池化层:AttentiveStatsPool(ASP)、SelfAttentivePooling(SAP)、TemporalStatisticsPooling(TSP)、TemporalAveragePooling(TAP)
+4. 支持预处理方法:MelSpectrogram、Spectrogram、MFCC、Fbank、Wav2vec2.0、WavLM
+
+**模型论文:**
+
+- EcapaTdnn:[ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation in TDNN Based Speaker Verification](https://arxiv.org/abs/2005.07143v3)
+- PANNS:[PANNs: Large-Scale Pretrained Audio Neural Networks for Audio Pattern Recognition](https://arxiv.org/abs/1912.10211v5)
+- TDNN:[Prediction of speech intelligibility with DNN-based performance measures](https://arxiv.org/abs/2203.09148)
+- Res2Net:[Res2Net: A New Multi-scale Backbone Architecture](https://arxiv.org/abs/1904.01169)
+- ResNetSE:[Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507)
+- CAMPPlus:[CAM++: A Fast and Efficient Network for Speaker Verification Using Context-Aware Masking](https://arxiv.org/abs/2303.00332v3)
+- ERes2Net:[An Enhanced Res2Net with Local and Global Feature Fusion for Speaker Verification](https://arxiv.org/abs/2305.12838v1)
+
+# 模型测试表
+
+| 模型 | Params(M) | 预处理方法 | 数据集 | 类别数量 | 准确率 | 获取模型 |
+|:------------:|:---------:|:-----:|:------------:|:----:|:-------:|:--------:|
+| ResNetSE | 7.8 | Flank | UrbanSound8K | 10 | 0.96233 | 加入知识星球获取 |
+| ERes2NetV2 | 5.4 | Flank | UrbanSound8K | 10 | 0.95662 | 加入知识星球获取 |
+| CAMPPlus | 7.1 | Flank | UrbanSound8K | 10 | 0.95454 | 加入知识星球获取 |
+| EcapaTdnn | 6.4 | Flank | UrbanSound8K | 10 | 0.95227 | 加入知识星球获取 |
+| ERes2Net | 6.6 | Flank | UrbanSound8K | 10 | 0.94292 | 加入知识星球获取 |
+| TDNN | 2.6 | Flank | UrbanSound8K | 10 | 0.93977 | 加入知识星球获取 |
+| PANNS(CNN10) | 5.2 | Flank | UrbanSound8K | 10 | 0.92954 | 加入知识星球获取 |
+| Res2Net | 5.0 | Flank | UrbanSound8K | 10 | 0.92580 | 加入知识星球获取 |
+
+**说明:**
+
+1. 使用的测试集为从数据集中每10条音频取一条,共874条。
+
+## 安装环境
+
+ - 首先安装的是Pytorch的GPU版本,如果已经安装过了,请跳过。
+```shell
+conda install pytorch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 pytorch-cuda=11.8 -c pytorch -c nvidia
+```
+
+ - 安装macls库。
+
+使用pip安装,命令如下:
+```shell
+python -m pip install macls -U -i https://pypi.tuna.tsinghua.edu.cn/simple
+```
+
+**建议源码安装**,源码安装能保证使用最新代码。
+```shell
+git clone https://github.com/yeyupiaoling/AudioClassification-Pytorch.git
+cd AudioClassification-Pytorch/
+pip install .
+```
+
+## 创建数据
+
+生成数据列表,用于下一步的读取需要,`audio_path`为音频文件路径,用户需要提前把音频数据集存放在`dataset/audio`目录下,每个文件夹存放一个类别的音频数据,每条音频数据长度在3秒以上,如 `dataset/audio/鸟叫声/······`。`audio`是数据列表存放的位置,生成的数据类别的格式为 `音频路径\t音频对应的类别标签`,音频路径和标签用制表符 `\t`分开。读者也可以根据自己存放数据的方式修改以下函数。
+
+以Urbansound8K为例,Urbansound8K是目前应用较为广泛的用于自动城市环境声分类研究的公共数据集,包含10个分类:空调声、汽车鸣笛声、儿童玩耍声、狗叫声、钻孔声、引擎空转声、枪声、手提钻、警笛声和街道音乐声。数据集下载地址:[UrbanSound8K.tar.gz](https://aistudio.baidu.com/aistudio/datasetdetail/36625)。以下是针对Urbansound8K生成数据列表的函数。如果读者想使用该数据集,请下载并解压到 `dataset`目录下,把生成数据列表代码改为以下代码。
+
+执行`create_data.py`即可生成数据列表,里面提供了生成多种数据集列表方式,具体看代码。
+```shell
+python create_data.py
+```
+
+生成的列表是长这样的,前面是音频的路径,后面是该音频对应的标签,从0开始,路径和标签之间用`\t`隔开。
+```shell
+dataset/UrbanSound8K/audio/fold2/104817-4-0-2.wav 4
+dataset/UrbanSound8K/audio/fold9/105029-7-2-5.wav 7
+dataset/UrbanSound8K/audio/fold3/107228-5-0-0.wav 5
+dataset/UrbanSound8K/audio/fold4/109711-3-2-4.wav 3
+```
+
+# 修改预处理方法(可选)
+
+配置文件中默认使用的是Fbank预处理方法,如果要使用其他预处理方法,可以修改配置文件中的安装下面方式修改,具体的值可以根据自己情况修改。如果不清楚如何设置参数,可以直接删除该部分,直接使用默认值。
+
+```yaml
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+```
+
+# 提取特征(可选)
+
+在训练过程中,首先是要读取音频数据,然后提取特征,最后再进行训练。其中读取音频数据、提取特征也是比较消耗时间的,所以我们可以选择提前提取好取特征,训练模型的是就可以直接加载提取好的特征,这样训练速度会更快。这个提取特征是可选择,如果没有提取好的特征,训练模型的时候就会从读取音频数据,然后提取特征开始。提取特征步骤如下:
+
+1. 执行`extract_features.py`,提取特征,特征会保存在`dataset/features`目录下,并生成新的数据列表`train_list_features.txt`和`test_list_features.txt`。
+
+```shell
+python extract_features.py --configs=configs/cam++.yml --save_dir=dataset/features
+```
+
+2. 修改配置文件,将`dataset_conf.train_list`和`dataset_conf.test_list`修改为`train_list_features.txt`和`test_list_features.txt`。
+
+
+## 训练模型
+
+接着就可以开始训练模型了,创建 `train.py`。配置文件里面的参数一般不需要修改,但是这几个是需要根据自己实际的数据集进行调整的,首先最重要的就是分类大小`dataset_conf.num_class`,这个每个数据集的分类大小可能不一样,根据自己的实际情况设定。然后是`dataset_conf.batch_size`,如果是显存不够的话,可以减小这个参数。
+
+```shell
+# 单卡训练
+CUDA_VISIBLE_DEVICES=0 python train.py
+# 多卡训练
+CUDA_VISIBLE_DEVICES=0,1 torchrun --standalone --nnodes=1 --nproc_per_node=2 train.py
+```
+
+训练输出日志:
+```
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:14 - ----------- 额外配置参数 -----------
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - configs: configs/ecapa_tdnn.yml
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - local_rank: 0
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - pretrained_model: None
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - resume_model: None
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - save_model_path: models/
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - use_gpu: True
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:17 - ------------------------------------------------
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:19 - ----------- 配置文件参数 -----------
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:22 - dataset_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - aug_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - noise_aug_prob: 0.2
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - noise_dir: dataset/noise
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - speed_perturb: True
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - volume_aug_prob: 0.2
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - volume_perturb: False
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - dataLoader:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - batch_size: 64
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - num_workers: 4
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - do_vad: False
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - eval_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - batch_size: 1
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - max_duration: 20
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - label_list_path: dataset/label_list.txt
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - max_duration: 3
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - min_duration: 0.5
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - sample_rate: 16000
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - spec_aug_args:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - freq_mask_width: [0, 8]
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - time_mask_width: [0, 10]
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - target_dB: -20
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - test_list: dataset/test_list.txt
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - train_list: dataset/train_list.txt
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - use_dB_normalization: True
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - use_spec_aug: True
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:22 - model_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - num_class: 10
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - pooling_type: ASP
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:22 - optimizer_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - learning_rate: 0.001
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - optimizer: Adam
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - scheduler: WarmupCosineSchedulerLR
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:25 - scheduler_args:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - max_lr: 0.001
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - min_lr: 1e-05
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - warmup_epoch: 5
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - weight_decay: 1e-06
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:22 - preprocess_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - feature_method: Fbank
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:25 - method_args:
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:27 - num_mel_bins: 80
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:27 - sample_frequency: 16000
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:22 - train_conf:
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:29 - log_interval: 10
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:29 - max_epoch: 30
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:31 - use_model: EcapaTdnn
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:32 - ------------------------------------------------
+[2023-08-07 22:54:22.213166 WARNING] trainer:__init__:67 - Windows系统不支持多线程读取数据,已自动关闭!
+==========================================================================================
+Layer (type:depth-idx) Output Shape Param #
+==========================================================================================
+EcapaTdnn [1, 10] --
+├─Conv1dReluBn: 1-1 [1, 512, 98] --
+│ └─Conv1d: 2-1 [1, 512, 98] 204,800
+│ └─BatchNorm1d: 2-2 [1, 512, 98] 1,024
+├─Sequential: 1-2 [1, 512, 98] --
+│ └─Conv1dReluBn: 2-3 [1, 512, 98] --
+│ │ └─Conv1d: 3-1 [1, 512, 98] 262,144
+│ │ └─BatchNorm1d: 3-2 [1, 512, 98] 1,024
+│ └─Res2Conv1dReluBn: 2-4 [1, 512, 98] --
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+···································
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ │ └─ModuleList: 3-55 -- (recursive)
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ │ └─ModuleList: 3-55 -- (recursive)
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ └─Conv1dReluBn: 2-13 [1, 512, 98] --
+│ │ └─Conv1d: 3-57 [1, 512, 98] 262,144
+│ │ └─BatchNorm1d: 3-58 [1, 512, 98] 1,024
+│ └─SE_Connect: 2-14 [1, 512, 98] --
+│ │ └─Linear: 3-59 [1, 256] 131,328
+│ │ └─Linear: 3-60 [1, 512] 131,584
+├─Conv1d: 1-5 [1, 1536, 98] 2,360,832
+├─AttentiveStatsPool: 1-6 [1, 3072] --
+│ └─Conv1d: 2-15 [1, 128, 98] 196,736
+│ └─Conv1d: 2-16 [1, 1536, 98] 198,144
+├─BatchNorm1d: 1-7 [1, 3072] 6,144
+├─Linear: 1-8 [1, 192] 590,016
+├─BatchNorm1d: 1-9 [1, 192] 384
+├─Linear: 1-10 [1, 10] 1,930
+==========================================================================================
+Total params: 6,188,490
+Trainable params: 6,188,490
+Non-trainable params: 0
+Total mult-adds (M): 470.96
+==========================================================================================
+Input size (MB): 0.03
+Forward/backward pass size (MB): 10.28
+Params size (MB): 24.75
+Estimated Total Size (MB): 35.07
+==========================================================================================
+[2023-08-07 22:54:26.726095 INFO ] trainer:train:344 - 训练数据:8644
+[2023-08-07 22:54:30.092504 INFO ] trainer:__train_epoch:296 - Train epoch: [1/30], batch: [0/4], loss: 2.57033, accuracy: 0.06250, learning rate: 0.00001000, speed: 19.02 data/sec, eta: 0:06:43
+```
+
+**训练可视化:**
+
+项目的根目录执行下面命令,并网页访问`http://localhost:8040/`,如果是服务器,需要修改`localhost`为服务器的IP地址。
+```shell
+visualdl --logdir=log --host=0.0.0.0
+```
+
+打开的网页如下:
+
+
+
+

+
+
+
+
+# 评估模型
+
+执行下面命令执行评估。
+
+```shell
+python eval.py --configs=configs/bi_lstm.yml
+```
+
+评估输出如下:
+```shell
+[2025-02-03 15:13:25.469242 INFO ] trainer:evaluate:461 - 成功加载模型:models/CAMPPlus_Fbank/best_model/model.pth
+100%|██████████████████████████████| 150/150 [00:00<00:00, 1281.96it/s]
+评估消耗时间:1s,loss:0.61840,accuracy:0.87333
+```
+
+评估会出来输出准确率,还保存了混淆矩阵图片,保存路径`output/images/`,如下。
+
+
+
+

+
+
+
+注意:如果类别标签是中文的,需要设置安装字体才能正常显示,一般情况下Windows无需安装,Ubuntu需要安装。如果Windows确实是缺少字体,只需要[字体文件](https://github.com/tracyone/program_font)这里下载`.ttf`格式的文件,复制到`C:\Windows\Fonts`即可。Ubuntu系统操作如下。
+
+1. 安装字体
+```shell
+git clone https://github.com/tracyone/program_font && cd program_font && ./install.sh
+```
+
+2. 执行下面Python代码
+```python
+import matplotlib
+import shutil
+import os
+
+path = matplotlib.matplotlib_fname()
+path = path.replace('matplotlibrc', 'fonts/ttf/')
+print(path)
+shutil.copy('/usr/share/fonts/MyFonts/simhei.ttf', path)
+user_dir = os.path.expanduser('~')
+shutil.rmtree(f'{user_dir}/.cache/matplotlib', ignore_errors=True)
+```
+
+# 预测
+
+在训练结束之后,我们得到了一个模型参数文件,我们使用这个模型预测音频。
+
+```shell
+python infer.py --audio_path=dataset/UrbanSound8K/audio/fold5/156634-5-2-5.wav
+```
+
+# 其他功能
+
+ - 为了方便读取录制数据和制作数据集,这里提供了录音程序`record_audio.py`,这个用于录制音频,录制的音频采样率为16000,单通道,16bit。
+
+```shell
+python record_audio.py
+```
+
+ - `infer_record.py`这个程序是用来不断进行录音识别,我们可以大致理解为这个程序在实时录音识别。通过这个应该我们可以做一些比较有趣的事情,比如把麦克风放在小鸟经常来的地方,通过实时录音识别,一旦识别到有鸟叫的声音,如果你的数据集足够强大,有每种鸟叫的声音数据集,这样你还能准确识别是那种鸟叫。如果识别到目标鸟类,就启动程序,例如拍照等等。
+
+```shell
+python infer_record.py --record_seconds=3
+```
+
+## 打赏作者
+
+
+
打赏一块钱支持一下作者
+

+
+
+# 参考资料
+
+1. https://github.com/PaddlePaddle/PaddleSpeech
+2. https://github.com/yeyupiaoling/PaddlePaddle-MobileFaceNets
+3. https://github.com/yeyupiaoling/PPASR
+4. https://github.com/alibaba-damo-academy/3D-Speaker
diff --git a/src/声源定位代码/audio-classification/README_en.md b/src/声源定位代码/audio-classification/README_en.md
new file mode 100644
index 0000000..43e1e2a
--- /dev/null
+++ b/src/声源定位代码/audio-classification/README_en.md
@@ -0,0 +1,275 @@
+[简体中文](./README.md) | English
+
+# Sound classification system implemented in Pytorch
+
+
+
+
+
+
+
+**Disclaimer, this document was obtained through machine translation, please check the original document [here](./README.md).**
+
+
+# Introduction
+
+This project is a sound classification project based on Pytorch, aiming to realize the recognition of various environmental sounds, animal calls and languages. Several sound classification models such as EcapaTdnn, PANNS, ResNetSE, CAMPPlus, and ERes2Net are provided to support different application scenarios. In addition, the project also provides the commonly used Urbansound8K dataset test report and some dialect datasets download and use examples. Users can choose suitable models and datasets according to their needs to achieve more accurate sound classification. The project has a wide range of application scenarios, and can be used in outdoor environmental monitoring, wildlife protection, speech recognition and other fields. At the same time, the project also encourages users to explore more usage scenarios to promote the development and application of sound classification technology.
+
+
+# Environment
+
+ - Anaconda 3
+ - Python 3.11
+ - Pytorch 2.0.1
+ - Windows 11 or Ubuntu 22.04
+
+# Project Features
+
+1. Supporting models: EcapaTdnn、PANNS、TDNN、Res2Net、ResNetSE、CAMPPlus、ERes2Net
+2. Supporting pooling: AttentiveStatsPool(ASP)、SelfAttentivePooling(SAP)、TemporalStatisticsPooling(TSP)、TemporalAveragePooling(TAP)
+3. Support preprocessing methods: MelSpectrogram、Spectrogram、MFCC、Fbank、Wav2vec2.0、WavLM
+
+**Model Paper:**
+
+- EcapaTdnn:[ECAPA-TDNN: Emphasized Channel Attention, Propagation and Aggregation in TDNN Based Speaker Verification](https://arxiv.org/abs/2005.07143v3)
+- PANNS:[PANNs: Large-Scale Pretrained Audio Neural Networks for Audio Pattern Recognition](https://arxiv.org/abs/1912.10211v5)
+- TDNN:[Prediction of speech intelligibility with DNN-based performance measures](https://arxiv.org/abs/2203.09148)
+- Res2Net:[Res2Net: A New Multi-scale Backbone Architecture](https://arxiv.org/abs/1904.01169)
+- ResNetSE:[Squeeze-and-Excitation Networks](https://arxiv.org/abs/1709.01507)
+- CAMPPlus:[CAM++: A Fast and Efficient Network for Speaker Verification Using Context-Aware Masking](https://arxiv.org/abs/2303.00332v3)
+- ERes2Net:[An Enhanced Res2Net with Local and Global Feature Fusion for Speaker Verification](https://arxiv.org/abs/2305.12838v1)
+
+# Model Test
+
+| Model | Params(M) | Preprocessing method | Dataset | Number Class | Accuracy |
+|:------------:|:---------:|:--------------------:|:------------:|:------------:|:--------:|
+| ResNetSE | 7.8 | Flank | UrbanSound8K | 10 | 0.96233 |
+| ERes2NetV2 | 5.4 | Flank | UrbanSound8K | 10 | 0.95662 |
+| CAMPPlus | 7.1 | Flank | UrbanSound8K | 10 | 0.95454 |
+| EcapaTdnn | 6.4 | Flank | UrbanSound8K | 10 | 0.95227 |
+| ERes2Net | 6.6 | Flank | UrbanSound8K | 10 | 0.94292 |
+| TDNN | 2.6 | Flank | UrbanSound8K | 10 | 0.93977 |
+| PANNS(CNN10) | 5.2 | Flank | UrbanSound8K | 10 | 0.92954 |
+| Res2Net | 5.0 | Flank | UrbanSound8K | 10 | 0.92580 |
+
+## Installation Environment
+
+ - The GPU version of Pytorch will be installed first, please skip it if you already have it installed.
+```shell
+conda install pytorch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 pytorch-cuda=11.8 -c pytorch -c nvidia
+```
+
+ - Install macls.
+
+Install it using pip with the following command:
+```shell
+python -m pip install macls -U -i https://pypi.tuna.tsinghua.edu.cn/simple
+```
+
+**Source installation is recommended**, which ensures that the latest code is used.
+```shell
+git clone https://github.com/yeyupiaoling/AudioClassification_Pytorch.git
+cd AudioClassification_Pytorch/
+python setup.py install
+```
+
+## Preparing Data
+
+The `audio_path` is the audio file path. The user needs to store the audio dataset in the `dataset/audio` directory in advance. Each folder stores a category of audio data, and the length of each audio data is more than 3 seconds. For example, `dataset/audio/ bird song /······`. `audio` is where the data list is stored, and the format of the generated data category is`audio_path\tcategory_label_audio`, and the audio path and label are separated by a TAB character `\t`. You can also modify the following functions depending on how you store your data:
+
+Taking Urbansound8K as an example, it is a widely used public dataset for automatic urban environmental sound classification research. Urbansound8K contains 10 categories: air condition sound, car whistle sound, children playing sound, dog bark, drilling sound, engine idling sound, gun sound, jackdrill, siren sound, and street music sound. Data set download address: [UrbanSound8K](https://zenodo.org/record/1203745/files/UrbanSound8K.tar.gz). Here is the function to generate a list of data for Urbansound8K. If you want to use this dataset, please download and unzip it into the `dataset` directory and change the code to generate the list of data as follows.
+
+`create_data.py` can be used to generate a list of data sets. There are many ways to generate a list of data sets.
+```shell
+python create_data.py
+```
+
+The resulting list looks like this, with the path to the audio followed by the tag for that audio, starting at 0, and separated by `\t`.
+```shell
+dataset/UrbanSound8K/audio/fold2/104817-4-0-2.wav 4
+dataset/UrbanSound8K/audio/fold9/105029-7-2-5.wav 7
+dataset/UrbanSound8K/audio/fold3/107228-5-0-0.wav 5
+dataset/UrbanSound8K/audio/fold4/109711-3-2-4.wav 3
+```
+
+# Change preprocessing methods
+
+By default, the Fbank preprocessing method is used in the configuration file. If you want to use other preprocessing methods, you can modify the following installation in the configuration file, and the specific value can be modified according to your own situation. If it's not clear how to set the parameters, you can remove that section and just use the default values.
+
+```yaml
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+```
+
+## 训练
+
+Now we can train the model. We will create `train.py`. The parameters in the configuration file generally do not need to be modified, but these few need to be adjusted according to your actual dataset. The first and most important is the class size `dataset_conf.num_class`, which may be different for each dataset. Then there is` dataset_conf.batch_size `, which can be reduced if memory is insufficient.
+
+```shell
+# Single GPU training
+CUDA_VISIBLE_DEVICES=0 python train.py
+# Multi GPU training
+CUDA_VISIBLE_DEVICES=0,1 torchrun --standalone --nnodes=1 --nproc_per_node=2 train.py
+```
+
+Train log:
+```
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:14 - ----------- 额外配置参数 -----------
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - configs: configs/ecapa_tdnn.yml
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - local_rank: 0
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - pretrained_model: None
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - resume_model: None
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - save_model_path: models/
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:16 - use_gpu: True
+[2023-08-07 22:54:22.148973 INFO ] utils:print_arguments:17 - ------------------------------------------------
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:19 - ----------- 配置文件参数 -----------
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:22 - dataset_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - aug_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - noise_aug_prob: 0.2
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - noise_dir: dataset/noise
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - speed_perturb: True
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - volume_aug_prob: 0.2
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - volume_perturb: False
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - dataLoader:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - batch_size: 64
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - num_workers: 4
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - do_vad: False
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - eval_conf:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - batch_size: 1
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - max_duration: 20
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - label_list_path: dataset/label_list.txt
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - max_duration: 3
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - min_duration: 0.5
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:29 - sample_rate: 16000
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:25 - spec_aug_args:
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - freq_mask_width: [0, 8]
+[2023-08-07 22:54:22.202166 INFO ] utils:print_arguments:27 - time_mask_width: [0, 10]
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - target_dB: -20
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - test_list: dataset/test_list.txt
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - train_list: dataset/train_list.txt
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - use_dB_normalization: True
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:29 - use_spec_aug: True
+[2023-08-07 22:54:22.203167 INFO ] utils:print_arguments:22 - model_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - num_class: 10
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - pooling_type: ASP
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:22 - optimizer_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - learning_rate: 0.001
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - optimizer: Adam
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - scheduler: WarmupCosineSchedulerLR
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:25 - scheduler_args:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - max_lr: 0.001
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - min_lr: 1e-05
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:27 - warmup_epoch: 5
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - weight_decay: 1e-06
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:22 - preprocess_conf:
+[2023-08-07 22:54:22.207167 INFO ] utils:print_arguments:29 - feature_method: Fbank
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:25 - method_args:
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:27 - num_mel_bins: 80
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:27 - sample_frequency: 16000
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:22 - train_conf:
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:29 - log_interval: 10
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:29 - max_epoch: 30
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:31 - use_model: EcapaTdnn
+[2023-08-07 22:54:22.208167 INFO ] utils:print_arguments:32 - ------------------------------------------------
+[2023-08-07 22:54:22.213166 WARNING] trainer:__init__:67 - Windows系统不支持多线程读取数据,已自动关闭!
+==========================================================================================
+Layer (type:depth-idx) Output Shape Param #
+==========================================================================================
+EcapaTdnn [1, 10] --
+├─Conv1dReluBn: 1-1 [1, 512, 98] --
+│ └─Conv1d: 2-1 [1, 512, 98] 204,800
+│ └─BatchNorm1d: 2-2 [1, 512, 98] 1,024
+├─Sequential: 1-2 [1, 512, 98] --
+│ └─Conv1dReluBn: 2-3 [1, 512, 98] --
+│ │ └─Conv1d: 3-1 [1, 512, 98] 262,144
+│ │ └─BatchNorm1d: 3-2 [1, 512, 98] 1,024
+│ └─Res2Conv1dReluBn: 2-4 [1, 512, 98] --
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+│ │ └─ModuleList: 3-15 -- (recursive)
+│ │ └─ModuleList: 3-16 -- (recursive)
+···································
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ │ └─ModuleList: 3-55 -- (recursive)
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ │ └─ModuleList: 3-55 -- (recursive)
+│ │ └─ModuleList: 3-56 -- (recursive)
+│ └─Conv1dReluBn: 2-13 [1, 512, 98] --
+│ │ └─Conv1d: 3-57 [1, 512, 98] 262,144
+│ │ └─BatchNorm1d: 3-58 [1, 512, 98] 1,024
+│ └─SE_Connect: 2-14 [1, 512, 98] --
+│ │ └─Linear: 3-59 [1, 256] 131,328
+│ │ └─Linear: 3-60 [1, 512] 131,584
+├─Conv1d: 1-5 [1, 1536, 98] 2,360,832
+├─AttentiveStatsPool: 1-6 [1, 3072] --
+│ └─Conv1d: 2-15 [1, 128, 98] 196,736
+│ └─Conv1d: 2-16 [1, 1536, 98] 198,144
+├─BatchNorm1d: 1-7 [1, 3072] 6,144
+├─Linear: 1-8 [1, 192] 590,016
+├─BatchNorm1d: 1-9 [1, 192] 384
+├─Linear: 1-10 [1, 10] 1,930
+==========================================================================================
+Total params: 6,188,490
+Trainable params: 6,188,490
+Non-trainable params: 0
+Total mult-adds (M): 470.96
+==========================================================================================
+Input size (MB): 0.03
+Forward/backward pass size (MB): 10.28
+Params size (MB): 24.75
+Estimated Total Size (MB): 35.07
+==========================================================================================
+[2023-08-07 22:54:26.726095 INFO ] trainer:train:344 - 训练数据:8644
+[2023-08-07 22:54:30.092504 INFO ] trainer:__train_epoch:296 - Train epoch: [1/30], batch: [0/4], loss: 2.57033, accuracy: 0.06250, learning rate: 0.00001000, speed: 19.02 data/sec, eta: 0:06:43
+```
+
+# Eval
+
+At the end of each training round, we can perform an evaluation, which will output the accuracy. We also save the mixture matrix image, and save the path `output/images/` as follows.
+
+
+# Inference
+
+At the end of the training, we are given a model parameter file, and we use this model to predict the audio.
+
+```shell
+python infer.py --audio_path=dataset/UrbanSound8K/audio/fold5/156634-5-2-5.wav
+```
+
+# Other Functions
+
+ - In order to read the recorded data and make a dataset easily, we provide the recording program `record_audio.py`, which is used to record audio with a sample rate of 16,000, single channel, 16bit.
+
+```shell
+python record_audio.py
+```
+
+ - `infer_record.py`This program is used to continuously perform recording recognition, and we can roughly understand this program as recording recognition in real time. And this should allow us to do some interesting things, like put a microphone in a place where birds often come, and recognize it by recording it in real time, and once you recognize that there's a bird calling, if your dataset is powerful enough, and you have a dataset of every bird calling, then you can identify exactly which bird is calling. If the target bird is identified, the procedure is initiated, such as taking photos, etc.
+
+```shell
+python infer_record.py --record_seconds=3
+```
+
+# Reference
+
+1. https://github.com/PaddlePaddle/PaddleSpeech
+2. https://github.com/yeyupiaoling/PaddlePaddle-MobileFaceNets
+3. https://github.com/yeyupiaoling/PPASR
+4. https://github.com/alibaba-damo-academy/3D-Speaker
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/README.md b/src/声源定位代码/audio-classification/audio-classification-platform/README.md
new file mode 100644
index 0000000..d3ecd35
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/README.md
@@ -0,0 +1,136 @@
+# 声纹识别系统
+
+这是一个基于深度学习的声纹识别系统,包含Flask后端和Vue前端。
+
+## 功能特性
+
+- 🎵 支持多种音频格式上传识别
+- 🎤 实时录音识别功能
+- 📊 置信度可视化展示
+- 📱 响应式设计,支持移动端
+- 📝 识别历史记录
+- 📋 结果导出功能
+
+## 技术栈
+
+### 后端
+- Flask + Flask-CORS
+- PyTorch + MAClsPredictor
+- librosa + soundfile
+
+### 前端
+- Vue 3 + Composition API
+- Element Plus UI框架
+- Axios HTTP客户端
+- Vite构建工具
+
+## 快速开始
+
+### 环境要求
+
+- Python 3.8+
+- Node.js 16+
+- 已训练好的音频分类模型
+
+### 1. 安装后端依赖
+
+```bash
+cd audio-classification-platform/backend
+pip install -r requirements.txt
+```
+
+### 2. 安装前端依赖
+
+```bash
+cd audio-classification-platform/frontend
+npm install
+```
+
+### 3. 启动后端服务
+
+```bash
+cd audio-classification-platform/backend
+python app.py
+```
+
+后端服务将在 http://localhost:5000 启动
+
+### 4. 启动前端服务
+
+```bash
+cd audio-classification-platform/frontend
+npm run dev
+```
+
+前端服务将在 http://localhost:3000 启动
+
+## 使用说明
+
+1. 打开浏览器访问 http://localhost:3000
+2. 首次使用需要初始化模型(确保模型文件路径正确)
+3. 使用文件上传功能或实时录音功能进行音频识别
+4. 查看识别结果和置信度
+5. 可以查看历史识别记录
+
+## 配置说明
+
+### 后端配置
+
+在 `backend/config.py` 中可以配置:
+
+- 模型路径
+- 上传文件限制
+- GPU使用设置
+- 音频处理参数
+
+### 前端配置
+
+在 `frontend/vite.config.js` 中可以配置:
+
+- 开发服务器端口
+- 代理设置
+- 构建选项
+
+## API接口
+
+- `GET /api/health` - 健康检查
+- `POST /api/init` - 初始化模型
+- `POST /api/upload` - 上传音频文件识别
+- `POST /api/predict` - 录音数据识别
+- `GET /api/labels` - 获取分类标签
+- `GET /api/model/info` - 获取模型信息
+
+## 部署
+
+### 生产环境构建
+
+```bash
+# 构建前端
+cd frontend
+npm run build
+
+# 启动后端(推荐使用gunicorn)
+cd backend
+gunicorn -w 4 -b 0.0.0.0:5000 app:app
+```
+
+## 故障排除
+
+1. **模型初始化失败**
+ - 检查模型文件路径是否正确
+ - 确保配置文件存在
+ - 检查GPU驱动(如果使用GPU)
+
+2. **音频上传失败**
+ - 检查文件格式是否支持
+ - 检查文件大小是否超限
+ - 检查网络连接
+
+3. **录音功能不可用**
+ - 检查浏览器麦克风权限
+ - 使用HTTPS协议(录音功能需要)
+ - 检查设备麦克风是否正常
+
+## 许可证
+
+Apache License 2.0
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/backend/app.py b/src/声源定位代码/audio-classification/audio-classification-platform/backend/app.py
new file mode 100644
index 0000000..d9e1caa
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/backend/app.py
@@ -0,0 +1,350 @@
+import os
+import sys
+import tempfile
+import uuid
+from datetime import datetime
+from flask import Flask, request, jsonify, send_from_directory
+from flask_cors import CORS
+from werkzeug.utils import secure_filename
+import librosa
+import soundfile as sf
+import numpy as np
+from loguru import logger
+
+# 添加项目根目录到Python路径
+sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))
+
+from macls.predict import MAClsPredictor
+
+app = Flask(__name__)
+CORS(app) # 允许跨域请求
+
+# 配置
+app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 最大50MB
+app.config['UPLOAD_FOLDER'] = 'uploads'
+app.config['ALLOWED_EXTENSIONS'] = {'wav', 'mp3', 'flac', 'm4a', 'ogg', 'aac'}
+
+# 确保上传目录存在
+os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
+
+# 全局预测器实例
+predictor = None
+
+def allowed_file(filename):
+ """检查文件扩展名是否被允许"""
+ return '.' in filename and \
+ filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
+
+def convert_audio_format(input_path, target_sample_rate=16000):
+ """将音频转换为模型需要的格式"""
+ try:
+ # 使用librosa加载音频,自动转换采样率
+ audio_data, sr = librosa.load(input_path, sr=target_sample_rate)
+
+ # 创建临时文件
+ temp_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
+ temp_path = temp_file.name
+ temp_file.close()
+
+ # 保存为wav格式
+ sf.write(temp_path, audio_data, target_sample_rate)
+
+ return temp_path, audio_data, target_sample_rate
+ except Exception as e:
+ logger.error(f"音频格式转换失败: {str(e)}")
+ raise e
+
+@app.route('/api/health', methods=['GET'])
+def health_check():
+ """健康检查接口"""
+ return jsonify({
+ 'status': 'success',
+ 'message': '服务正常运行',
+ 'timestamp': datetime.now().isoformat()
+ })
+
+@app.route('/api/init', methods=['POST'])
+def init_model():
+ """初始化模型"""
+ global predictor
+ try:
+ data = request.get_json()
+
+ # 默认配置路径
+ configs = data.get('configs', '../../configs/cam++.yml')
+ model_path = data.get('model_path', '../../models/CAMPPlus_Fbank/best_model/')
+ use_gpu = data.get('use_gpu', True)
+
+ # 转换为绝对路径
+ configs = os.path.abspath(os.path.join(os.path.dirname(__file__), configs))
+ model_path = os.path.abspath(os.path.join(os.path.dirname(__file__), model_path))
+
+ if not os.path.exists(configs):
+ return jsonify({
+ 'status': 'error',
+ 'message': f'配置文件不存在: {configs}'
+ }), 400
+
+ if not os.path.exists(model_path):
+ return jsonify({
+ 'status': 'error',
+ 'message': f'模型路径不存在: {model_path}'
+ }), 400
+
+ # 初始化预测器
+ predictor = MAClsPredictor(
+ configs=configs,
+ model_path=model_path,
+ use_gpu=use_gpu
+ )
+
+ logger.info("模型初始化成功")
+
+ return jsonify({
+ 'status': 'success',
+ 'message': '模型初始化成功',
+ 'config': {
+ 'configs': configs,
+ 'model_path': model_path,
+ 'use_gpu': use_gpu
+ }
+ })
+
+ except Exception as e:
+ logger.error(f"模型初始化失败: {str(e)}")
+ return jsonify({
+ 'status': 'error',
+ 'message': f'模型初始化失败: {str(e)}'
+ }), 500
+
+@app.route('/api/upload', methods=['POST'])
+def upload_and_predict():
+ """上传音频文件并进行预测"""
+ global predictor
+
+ if predictor is None:
+ return jsonify({
+ 'status': 'error',
+ 'message': '模型未初始化,请先调用 /api/init 接口'
+ }), 400
+
+ if 'file' not in request.files:
+ return jsonify({
+ 'status': 'error',
+ 'message': '没有上传文件'
+ }), 400
+
+ file = request.files['file']
+
+ if file.filename == '':
+ return jsonify({
+ 'status': 'error',
+ 'message': '没有选择文件'
+ }), 400
+
+ if file and allowed_file(file.filename):
+ try:
+ # 生成唯一文件名
+ filename = secure_filename(file.filename)
+ unique_filename = f"{uuid.uuid4()}_{filename}"
+ filepath = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename)
+
+ # 保存上传的文件
+ file.save(filepath)
+
+ # 转换音频格式
+ converted_path, audio_data, sample_rate = convert_audio_format(filepath)
+
+ # 进行预测
+ start_time = datetime.now()
+ label, score = predictor.predict(audio_data=converted_path)
+ end_time = datetime.now()
+
+ # 计算预测时间
+ prediction_time = (end_time - start_time).total_seconds()
+
+ # 清理临时文件
+ if os.path.exists(converted_path):
+ os.remove(converted_path)
+ # 可选:保留原始文件或删除
+ # os.remove(filepath)
+
+ logger.info(f"预测完成 - 文件: {filename}, 结果: {label}, 得分: {score:.4f}, 耗时: {prediction_time:.3f}s")
+
+ return jsonify({
+ 'status': 'success',
+ 'result': {
+ 'predicted_class': label, # 前端期望的字段名
+ 'confidence': float(score), # 前端期望的字段名
+ 'label': label, # 保持兼容性
+ 'score': float(score), # 保持兼容性
+ 'filename': filename,
+ 'prediction_time': prediction_time,
+ 'audio_info': {
+ 'sample_rate': sample_rate,
+ 'duration': len(audio_data) / sample_rate
+ }
+ }
+ })
+
+ except Exception as e:
+ logger.error(f"预测失败: {str(e)}")
+ return jsonify({
+ 'status': 'error',
+ 'message': f'预测失败: {str(e)}'
+ }), 500
+ else:
+ return jsonify({
+ 'status': 'error',
+ 'message': '不支持的文件格式,支持的格式:wav, mp3, flac, m4a, ogg, aac'
+ }), 400
+
+@app.route('/api/predict', methods=['POST'])
+def predict_audio_data():
+ """直接预测音频数据(用于录音功能)"""
+ global predictor
+
+ if predictor is None:
+ return jsonify({
+ 'status': 'error',
+ 'message': '模型未初始化,请先调用 /api/init 接口'
+ }), 400
+
+ try:
+ data = request.get_json()
+
+ if 'audio_data' not in data:
+ return jsonify({
+ 'status': 'error',
+ 'message': '缺少音频数据'
+ }), 400
+
+ audio_data = np.array(data['audio_data'], dtype=np.float32)
+ sample_rate = data.get('sample_rate', 16000)
+
+ # 创建临时文件
+ temp_file = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
+ temp_path = temp_file.name
+ temp_file.close()
+
+ # 保存音频数据
+ sf.write(temp_path, audio_data, sample_rate)
+
+ # 进行预测
+ start_time = datetime.now()
+ label, score = predictor.predict(audio_data=temp_path)
+ end_time = datetime.now()
+
+ prediction_time = (end_time - start_time).total_seconds()
+ # 清理临时文件
+ os.remove(temp_path)
+
+ logger.info(f"录音预测完成 - 结果: {label}, 得分: {score:.4f}, 耗时: {prediction_time:.3f}s")
+
+ return jsonify({
+ 'status': 'success',
+ 'result': {
+ 'predicted_class': label, # 前端期望的字段名
+ 'confidence': float(score), # 前端期望的字段名
+ 'label': label, # 保持兼容性
+ 'score': float(score), # 保持兼容性
+ 'prediction_time': prediction_time,
+ 'audio_info': {
+ 'sample_rate': sample_rate,
+ 'duration': len(audio_data) / sample_rate
+ }
+ }
+ })
+
+ except Exception as e:
+ logger.error(f"录音预测失败: {str(e)}")
+ return jsonify({
+ 'status': 'error',
+ 'message': f'录音预测失败: {str(e)}'
+ }), 500
+
+@app.route('/api/labels', methods=['GET'])
+def get_labels():
+ """获取分类标签列表"""
+ try:
+ # 读取标签文件
+ label_file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../dataset/label_list.txt'))
+
+ if not os.path.exists(label_file_path):
+ return jsonify({
+ 'status': 'error',
+ 'message': '标签文件不存在'
+ }), 404
+
+ with open(label_file_path, 'r', encoding='utf-8') as f:
+ labels = [line.strip() for line in f.readlines() if line.strip()]
+
+ return jsonify({
+ 'status': 'success',
+ 'labels': labels,
+ 'count': len(labels)
+ })
+
+ except Exception as e:
+ logger.error(f"读取标签失败: {str(e)}")
+ return jsonify({
+ 'status': 'error',
+ 'message': f'读取标签失败: {str(e)}'
+ }), 500
+
+@app.route('/api/model/info', methods=['GET'])
+def get_model_info():
+ """获取模型信息"""
+ global predictor
+
+ if predictor is None:
+ return jsonify({
+ 'status': 'error',
+ 'message': '模型未初始化'
+ }), 400
+
+ try:
+ # 获取模型配置信息
+ return jsonify({
+ 'status': 'success',
+ 'model_info': {
+ 'initialized': True,
+ 'model_type': 'AudioClassification',
+ 'framework': 'PyTorch'
+ }
+ })
+
+ except Exception as e:
+ logger.error(f"获取模型信息失败: {str(e)}")
+ return jsonify({
+ 'status': 'error',
+ 'message': f'获取模型信息失败: {str(e)}'
+ }), 500
+
+@app.errorhandler(413)
+def too_large(e):
+ """文件过大错误处理"""
+ return jsonify({
+ 'status': 'error',
+ 'message': '文件过大,最大支持50MB'
+ }), 413
+
+@app.errorhandler(404)
+def not_found(e):
+ """404错误处理"""
+ return jsonify({
+ 'status': 'error',
+ 'message': '接口不存在'
+ }), 404
+
+@app.errorhandler(500)
+def internal_error(e):
+ """500错误处理"""
+ return jsonify({
+ 'status': 'error',
+ 'message': '服务器内部错误'
+ }), 500
+
+if __name__ == '__main__':
+ logger.info("启动音频分类API服务器...")
+ app.run(host='0.0.0.0', port=5000, debug=True)
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/backend/config.py b/src/声源定位代码/audio-classification/audio-classification-platform/backend/config.py
new file mode 100644
index 0000000..039439f
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/backend/config.py
@@ -0,0 +1,39 @@
+import os
+import sys
+
+# 配置
+class Config:
+ # 模型配置
+ MODEL_CONFIG_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../configs/cam++.yml'))
+ MODEL_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../models/CAMPPlus_Fbank/best_model/'))
+ LABEL_FILE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../dataset/label_list.txt'))
+
+ # Flask配置
+ SECRET_KEY = 'your-secret-key-here'
+ MAX_CONTENT_LENGTH = 50 * 1024 * 1024 # 50MB
+
+ # 文件上传配置
+ UPLOAD_FOLDER = 'uploads'
+ ALLOWED_EXTENSIONS = {'wav', 'mp3', 'flac', 'm4a', 'ogg', 'aac'}
+
+ # 音频处理配置
+ TARGET_SAMPLE_RATE = 16000
+
+ # 日志配置
+ LOG_LEVEL = 'INFO'
+
+ # GPU配置
+ USE_GPU = True
+
+class DevelopmentConfig(Config):
+ DEBUG = True
+
+class ProductionConfig(Config):
+ DEBUG = False
+
+# 根据环境变量选择配置
+config = {
+ 'development': DevelopmentConfig,
+ 'production': ProductionConfig,
+ 'default': DevelopmentConfig
+}
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/backend/requirements.txt b/src/声源定位代码/audio-classification/audio-classification-platform/backend/requirements.txt
new file mode 100644
index 0000000..de8b375
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/backend/requirements.txt
@@ -0,0 +1,7 @@
+Flask==2.3.3
+Flask-CORS==4.0.0
+librosa==0.10.1
+soundfile==0.12.1
+numpy==1.24.3
+loguru==0.7.2
+Werkzeug==2.3.7
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/index.html b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/index.html
new file mode 100644
index 0000000..e8eba15
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ 声纹识别系统
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/package.json b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/package.json
new file mode 100644
index 0000000..39dcbc3
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "audio-classification-frontend",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "serve": "vite preview"
+ }, "dependencies": {
+ "vue": "^3.3.4",
+ "vue-router": "^4.2.4",
+ "axios": "^1.5.0",
+ "element-plus": "^2.3.9",
+ "@element-plus/icons-vue": "^2.1.0",
+ "echarts": "^5.4.3"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^4.3.4",
+ "vite": "^4.4.9",
+ "unplugin-vue-components": "^0.25.2",
+ "unplugin-auto-import": "^0.16.6"
+ }
+}
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/App.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/App.vue
new file mode 100644
index 0000000..0908a7a
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/App.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder.vue
new file mode 100644
index 0000000..d1614fe
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder.vue
@@ -0,0 +1,690 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ statusTitle }}
+
{{ statusText }}
+
+
+
+ 录音时长: {{ formatTime(recordingTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 开始录音
+
+
+
+
+
+
+
+ 停止录音
+
+
+
+ 正在处理...
+
+
+
+
+
+
+
+
+
+
+
+
+ 3秒
+ 快速
+
+
+
+
+ 5秒
+ 推荐
+
+
+
+
+ 10秒
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 时长: {{ formatTime(recordedAudio.duration) }}
+
+
+
+ 大小: {{ formatFileSize(recordedAudio.size) }}
+
+
+
+
+ 识别录音
+
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue
new file mode 100644
index 0000000..73a92b4
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioRecorder_new.vue
@@ -0,0 +1,1020 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ statusTitle }}
+
{{ statusDescription }}
+
+
+ {{ formatTime(recordingTime) }}
+
+
+
+
+
+
+
+
+
+
+
+ 开始录音
+
+
+
+
+
+
+
+ 停止录音
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ formatTime(recordedAudio.duration) }}
+
+
+
+ {{ formatFileSize(recordedAudio.size) }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioUpload.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioUpload.vue
new file mode 100644
index 0000000..2a10b97
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/AudioUpload.vue
@@ -0,0 +1,714 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
✓ 文件上传成功
+
正在进行音频识别...
+
+
+
正在上传并识别中...
+
请稍等,模型正在分析您的音频
+
+
+
+ 点击 或 拖拽 音频文件到此处
+
+
+ 支持 WAV、MP3、FLAC、M4A 等格式
+
+
+ 文件大小限制:50MB
+
+
+
+
+
+
+
+
+
+
+
+
{{ uploadProgress }}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ audioPreview.name }}
+
+
+
+ {{ formatFileSize(audioPreview.size) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/HistoryList.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/HistoryList.vue
new file mode 100644
index 0000000..ac088fa
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/HistoryList.vue
@@ -0,0 +1,616 @@
+
+
+
+
+
+
+
+
+
+ {{ truncateFilename(item.filename) }}
+
+
+
+
+ {{ formatDuration(item.audio_info.duration) }}
+
+
+
+
+ {{ item.prediction_time?.toFixed(3) }}s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/PredictionResult.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/PredictionResult.vue
new file mode 100644
index 0000000..33783a3
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/components/PredictionResult.vue
@@ -0,0 +1,941 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ result.predicted_class || result.label }}
+
+ 置信度: {{ ((result.confidence || result.score) * 100).toFixed(2) }}%
+
+
+
+
+
{{ Math.round((result.confidence || result.score) * 100) }}%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
预测类别
+
{{ result.predicted_class || result.label }}
+
+
+
+
+
+
+
+
+
置信度
+
{{ ((result.confidence || result.score) * 100).toFixed(2) }}%
+
+
+
+
+
+
+
+
+
预测时间
+
{{ formatTime(result.timestamp) }}
+
+
+
+
+
+
+
+
+
音频时长
+
{{ formatDuration(result.audio_info?.duration) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ className }}
+
+
+ 最高
+
+
+
{{ (prob * 100).toFixed(2) }}%
+
+
+
+
+
+
+
+
+
+
+
+
+
暂无预测结果
+
请上传音频文件或录制音频进行识别
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/main.js b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/main.js
new file mode 100644
index 0000000..99badf7
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/main.js
@@ -0,0 +1,18 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import ElementPlus from 'element-plus'
+import 'element-plus/dist/index.css'
+import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+
+const app = createApp(App)
+
+// 注册所有图标
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+ app.component(key, component)
+}
+
+app.use(ElementPlus)
+app.use(router)
+
+app.mount('#app')
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/router/index.js b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/router/index.js
new file mode 100644
index 0000000..3109046
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/router/index.js
@@ -0,0 +1,17 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomePage from '../views/HomePage.vue'
+
+const routes = [
+ {
+ path: '/',
+ name: 'Home',
+ component: HomePage
+ }
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes
+})
+
+export default router
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/utils/api.js b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/utils/api.js
new file mode 100644
index 0000000..0db7b1a
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/utils/api.js
@@ -0,0 +1,213 @@
+import axios from 'axios'
+import { ElMessage } from 'element-plus'
+
+// 创建axios实例
+const api = axios.create({
+ baseURL: '/api',
+ timeout: 30000,
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+})
+
+// 请求拦截器
+api.interceptors.request.use(
+ (config) => {
+ // 可以在这里添加token等认证信息
+ return config
+ },
+ (error) => {
+ return Promise.reject(error)
+ }
+)
+
+// 响应拦截器
+api.interceptors.response.use(
+ (response) => {
+ return response
+ },
+ (error) => {
+ let errorMessage = '请求失败'
+
+ if (error.response) {
+ // 服务器返回错误状态码
+ const { status, data } = error.response
+
+ switch (status) {
+ case 400:
+ errorMessage = data.message || '请求参数错误'
+ break
+ case 401:
+ errorMessage = '未授权访问'
+ break
+ case 403:
+ errorMessage = '禁止访问'
+ break
+ case 404:
+ errorMessage = '请求的资源不存在'
+ break
+ case 413:
+ errorMessage = '文件过大,最大支持50MB'
+ break
+ case 500:
+ errorMessage = data.message || '服务器内部错误'
+ break
+ default:
+ errorMessage = data.message || `请求失败 (${status})`
+ }
+ } else if (error.request) {
+ // 网络错误
+ errorMessage = '网络连接失败,请检查网络设置'
+ } else {
+ // 其他错误
+ errorMessage = error.message || '未知错误'
+ }
+
+ // 显示错误消息
+ ElMessage.error(errorMessage)
+
+ return Promise.reject(new Error(errorMessage))
+ }
+)
+
+// API服务类
+export const apiService = {
+ // 健康检查
+ healthCheck: () => {
+ return api.get('/health')
+ },
+
+ // 初始化模型
+ initModel: (config) => {
+ return api.post('/init', config)
+ },
+ // 上传文件并预测
+ uploadAndPredict: (file, onProgress) => {
+ const formData = new FormData()
+ formData.append('file', file)
+
+ return api.post('/upload', formData, {
+ // 不要手动设置 Content-Type,让浏览器自动设置 boundary
+ onUploadProgress: (progressEvent) => {
+ if (onProgress && progressEvent.total) {
+ const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)
+ onProgress(percent)
+ }
+ }
+ })
+ },
+
+ // 预测音频数据(录音)
+ predictAudioData: (audioData) => {
+ return api.post('/predict', audioData)
+ },
+
+ // 获取标签列表
+ getLabels: () => {
+ return api.get('/labels')
+ },
+
+ // 获取模型信息
+ getModelInfo: () => {
+ return api.get('/model/info')
+ }
+}
+
+// 工具函数
+export const utils = {
+ // 格式化文件大小
+ formatFileSize: (bytes) => {
+ if (bytes === 0) return '0 B'
+
+ const k = 1024
+ const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
+ const i = Math.floor(Math.log(bytes) / Math.log(k))
+
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
+ },
+
+ // 格式化时长
+ formatDuration: (seconds) => {
+ if (!seconds) return '0s'
+
+ const hrs = Math.floor(seconds / 3600)
+ const mins = Math.floor((seconds % 3600) / 60)
+ const secs = Math.floor(seconds % 60)
+
+ if (hrs > 0) {
+ return `${hrs}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
+ } else if (mins > 0) {
+ return `${mins}:${secs.toString().padStart(2, '0')}`
+ } else {
+ return `${secs}s`
+ }
+ },
+
+ // 检查音频文件格式
+ isAudioFile: (file) => {
+ const allowedTypes = ['audio/wav', 'audio/mpeg', 'audio/flac', 'audio/m4a', 'audio/ogg', 'audio/aac']
+ const allowedExtensions = ['wav', 'mp3', 'flac', 'm4a', 'ogg', 'aac']
+
+ const fileExtension = file.name.split('.').pop().toLowerCase()
+
+ return allowedTypes.includes(file.type) || allowedExtensions.includes(fileExtension)
+ },
+
+ // 检查文件大小
+ isFileSizeValid: (file, maxSizeMB = 50) => {
+ const maxSize = maxSizeMB * 1024 * 1024
+ return file.size <= maxSize
+ },
+
+ // 生成唯一ID
+ generateId: () => {
+ return Date.now().toString(36) + Math.random().toString(36).substr(2)
+ },
+
+ // 下载文件
+ downloadFile: (content, filename, type = 'application/json') => {
+ const blob = new Blob([content], { type })
+ const url = URL.createObjectURL(blob)
+
+ const link = document.createElement('a')
+ link.href = url
+ link.download = filename
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ URL.revokeObjectURL(url)
+ },
+
+ // 复制到剪贴板
+ copyToClipboard: async (text) => {
+ try {
+ await navigator.clipboard.writeText(text)
+ return true
+ } catch (error) {
+ console.error('复制失败:', error)
+ return false
+ }
+ },
+
+ // 获取音频时长
+ getAudioDuration: (file) => {
+ return new Promise((resolve, reject) => {
+ const audio = new Audio()
+ const url = URL.createObjectURL(file)
+
+ audio.addEventListener('loadedmetadata', () => {
+ URL.revokeObjectURL(url)
+ resolve(audio.duration)
+ })
+
+ audio.addEventListener('error', (error) => {
+ URL.revokeObjectURL(url)
+ reject(error)
+ })
+
+ audio.src = url
+ })
+ }
+}
+
+export default api
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/views/HomePage.vue b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/views/HomePage.vue
new file mode 100644
index 0000000..f313fea
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/src/views/HomePage.vue
@@ -0,0 +1,841 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
模型状态
+
+ {{ modelStatus === 'ready' ? '✓ 模型已就绪' : '⚠ 模型未初始化' }}
+
+
+
+
+
+
+
+ 初始化模型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/vite.config.js b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/vite.config.js
new file mode 100644
index 0000000..34b05a8
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/vite.config.js
@@ -0,0 +1,33 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import AutoImport from 'unplugin-auto-import/vite'
+import Components from 'unplugin-vue-components/vite'
+import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
+
+export default defineConfig({
+ plugins: [
+ vue(),
+ AutoImport({
+ resolvers: [ElementPlusResolver()],
+ }),
+ Components({
+ resolvers: [ElementPlusResolver()],
+ }),
+ ],
+ server: {
+ port: 3000,
+ host: '0.0.0.0',
+ proxy: {
+ '/api': {
+ target: 'http://localhost:5000',
+ changeOrigin: true,
+ secure: false,
+ }
+ }
+ },
+ build: {
+ outDir: 'dist',
+ assetsDir: 'assets',
+ chunkSizeWarningLimit: 1000
+ }
+})
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/frontend/yarn.lock b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/yarn.lock
new file mode 100644
index 0000000..47a4043
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/frontend/yarn.lock
@@ -0,0 +1,1092 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@antfu/utils@^0.7.5", "@antfu/utils@^0.7.6":
+ version "0.7.10"
+ resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.7.10.tgz#ae829f170158e297a9b6a28f161a8e487d00814d"
+ integrity sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==
+
+"@babel/helper-string-parser@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
+ integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
+
+"@babel/helper-validator-identifier@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
+ integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
+
+"@babel/parser@^7.27.2":
+ version "7.27.4"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.4.tgz#f92e89e4f51847be05427285836fc88341c956df"
+ integrity sha512-BRmLHGwpUqLFR2jzx9orBuX/ABDkj2jLKOXrHDTN2aOKL+jFDDKaRNo9nyYsIl9h/UE/7lMKdDjKQQyxKKDZ7g==
+ dependencies:
+ "@babel/types" "^7.27.3"
+
+"@babel/types@^7.27.3":
+ version "7.27.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.3.tgz#c0257bedf33aad6aad1f406d35c44758321eb3ec"
+ integrity sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==
+ dependencies:
+ "@babel/helper-string-parser" "^7.27.1"
+ "@babel/helper-validator-identifier" "^7.27.1"
+
+"@ctrl/tinycolor@^3.4.1":
+ version "3.6.1"
+ resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31"
+ integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
+
+"@element-plus/icons-vue@^2.1.0", "@element-plus/icons-vue@^2.3.1":
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz#1f635ad5fdd5c85ed936481525570e82b5a8307a"
+ integrity sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==
+
+"@esbuild/android-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
+ integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
+
+"@esbuild/android-arm@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
+ integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
+
+"@esbuild/android-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
+ integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
+
+"@esbuild/darwin-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
+ integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
+
+"@esbuild/darwin-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
+ integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
+
+"@esbuild/freebsd-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
+ integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
+
+"@esbuild/freebsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
+ integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
+
+"@esbuild/linux-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
+ integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
+
+"@esbuild/linux-arm@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
+ integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
+
+"@esbuild/linux-ia32@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
+ integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
+
+"@esbuild/linux-loong64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
+ integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
+
+"@esbuild/linux-mips64el@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
+ integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
+
+"@esbuild/linux-ppc64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
+ integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
+
+"@esbuild/linux-riscv64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
+ integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
+
+"@esbuild/linux-s390x@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
+ integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
+
+"@esbuild/linux-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
+ integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
+
+"@esbuild/netbsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
+ integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
+
+"@esbuild/openbsd-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
+ integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
+
+"@esbuild/sunos-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
+ integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
+
+"@esbuild/win32-arm64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
+ integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
+
+"@esbuild/win32-ia32@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
+ integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
+
+"@esbuild/win32-x64@0.18.20":
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
+ integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
+
+"@floating-ui/core@^1.7.0":
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.0.tgz#1aff27a993ea1b254a586318c29c3b16ea0f4d0a"
+ integrity sha512-FRdBLykrPPA6P76GGGqlex/e7fbe0F1ykgxHYNXQsH/iTEtjMj/f9bpY5oQqbjt5VgZvgz/uKXbGuROijh3VLA==
+ dependencies:
+ "@floating-ui/utils" "^0.2.9"
+
+"@floating-ui/dom@^1.0.1":
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.0.tgz#f9f83ee4fee78ac23ad9e65b128fc11a27857532"
+ integrity sha512-lGTor4VlXcesUMh1cupTUTDoCxMb0V6bm3CnxHzQcw8Eaf1jQbgQX4i02fYgT0vJ82tb5MZ4CZk1LRGkktJCzg==
+ dependencies:
+ "@floating-ui/core" "^1.7.0"
+ "@floating-ui/utils" "^0.2.9"
+
+"@floating-ui/utils@^0.2.9":
+ version "0.2.9"
+ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429"
+ integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
+
+"@jridgewell/sourcemap-codec@^1.5.0":
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
+ integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
+
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+
+"@nodelib/fs.walk@^1.2.3":
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@popperjs/core@npm:@sxzz/popperjs-es@^2.11.7":
+ version "2.11.7"
+ resolved "https://registry.yarnpkg.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz#a7f69e3665d3da9b115f9e71671dae1b97e13671"
+ integrity sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
+
+"@rollup/pluginutils@^5.0.2", "@rollup/pluginutils@^5.0.5", "@rollup/pluginutils@^5.1.4":
+ version "5.1.4"
+ resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.4.tgz#bb94f1f9eaaac944da237767cdfee6c5b2262d4a"
+ integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==
+ dependencies:
+ "@types/estree" "^1.0.0"
+ estree-walker "^2.0.2"
+ picomatch "^4.0.2"
+
+"@types/estree@^1.0.0":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8"
+ integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
+
+"@types/lodash-es@^4.17.6":
+ version "4.17.12"
+ resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b"
+ integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
+ dependencies:
+ "@types/lodash" "*"
+
+"@types/lodash@*", "@types/lodash@^4.14.182":
+ version "4.17.17"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.17.tgz#fb85a04f47e9e4da888384feead0de05f7070355"
+ integrity sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ==
+
+"@types/web-bluetooth@^0.0.16":
+ version "0.0.16"
+ resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz#1d12873a8e49567371f2a75fe3e7f7edca6662d8"
+ integrity sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
+
+"@vitejs/plugin-vue@^4.3.4":
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz#057d2ded94c4e71b94e9814f92dcd9306317aa46"
+ integrity sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==
+
+"@vue/compiler-core@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.16.tgz#2f95f4f17c16c09c57bbf64399075b921506630b"
+ integrity sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==
+ dependencies:
+ "@babel/parser" "^7.27.2"
+ "@vue/shared" "3.5.16"
+ entities "^4.5.0"
+ estree-walker "^2.0.2"
+ source-map-js "^1.2.1"
+
+"@vue/compiler-dom@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.16.tgz#151d8390252975c0b1a773029220fdfcfaa2d743"
+ integrity sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==
+ dependencies:
+ "@vue/compiler-core" "3.5.16"
+ "@vue/shared" "3.5.16"
+
+"@vue/compiler-sfc@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.16.tgz#577f7fd42a46fac8357ffed46e8fb34d32698419"
+ integrity sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==
+ dependencies:
+ "@babel/parser" "^7.27.2"
+ "@vue/compiler-core" "3.5.16"
+ "@vue/compiler-dom" "3.5.16"
+ "@vue/compiler-ssr" "3.5.16"
+ "@vue/shared" "3.5.16"
+ estree-walker "^2.0.2"
+ magic-string "^0.30.17"
+ postcss "^8.5.3"
+ source-map-js "^1.2.1"
+
+"@vue/compiler-ssr@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.16.tgz#3b7874dff771ab2f85fb09be71f6c76a75fcc5ac"
+ integrity sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==
+ dependencies:
+ "@vue/compiler-dom" "3.5.16"
+ "@vue/shared" "3.5.16"
+
+"@vue/devtools-api@^6.6.4":
+ version "6.6.4"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
+ integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
+
+"@vue/reactivity@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.16.tgz#528c535a088b3c1b67f285f1f2211be79425b962"
+ integrity sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==
+ dependencies:
+ "@vue/shared" "3.5.16"
+
+"@vue/runtime-core@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.16.tgz#0a828c322224ada26f81a2e227c3d4aebcb72c7a"
+ integrity sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==
+ dependencies:
+ "@vue/reactivity" "3.5.16"
+ "@vue/shared" "3.5.16"
+
+"@vue/runtime-dom@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.16.tgz#c1bcbcca862b77186f81c92edd5176e74670f078"
+ integrity sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==
+ dependencies:
+ "@vue/reactivity" "3.5.16"
+ "@vue/runtime-core" "3.5.16"
+ "@vue/shared" "3.5.16"
+ csstype "^3.1.3"
+
+"@vue/server-renderer@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.16.tgz#5a68cd1d423d843f74c9e6b37133850abab07c13"
+ integrity sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg==
+ dependencies:
+ "@vue/compiler-ssr" "3.5.16"
+ "@vue/shared" "3.5.16"
+
+"@vue/shared@3.5.16":
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.16.tgz#d5ea7671182742192938a4b4cbf86ef12bef7418"
+ integrity sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==
+
+"@vueuse/core@^9.1.0":
+ version "9.13.0"
+ resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-9.13.0.tgz#2f69e66d1905c1e4eebc249a01759cf88ea00cf4"
+ integrity sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==
+ dependencies:
+ "@types/web-bluetooth" "^0.0.16"
+ "@vueuse/metadata" "9.13.0"
+ "@vueuse/shared" "9.13.0"
+ vue-demi "*"
+
+"@vueuse/metadata@9.13.0":
+ version "9.13.0"
+ resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-9.13.0.tgz#bc25a6cdad1b1a93c36ce30191124da6520539ff"
+ integrity sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
+
+"@vueuse/shared@9.13.0":
+ version "9.13.0"
+ resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-9.13.0.tgz#089ff4cc4e2e7a4015e57a8f32e4b39d096353b9"
+ integrity sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
+ dependencies:
+ vue-demi "*"
+
+acorn@^8.14.0:
+ version "8.14.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
+ integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
+
+anymatch@~3.1.2:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
+ integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
+ dependencies:
+ normalize-path "^3.0.0"
+ picomatch "^2.0.4"
+
+async-validator@^4.2.5:
+ version "4.2.5"
+ resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"
+ integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
+
+axios@^1.5.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.9.0.tgz#25534e3b72b54540077d33046f77e3b8d7081901"
+ integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==
+ dependencies:
+ follow-redirects "^1.15.6"
+ form-data "^4.0.0"
+ proxy-from-env "^1.1.0"
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+binary-extensions@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
+ integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
+
+brace-expansion@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
+ integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
+ dependencies:
+ balanced-match "^1.0.0"
+
+braces@^3.0.3, braces@~3.0.2:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
+ integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
+ dependencies:
+ fill-range "^7.1.1"
+
+call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
+ integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
+ dependencies:
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+
+chokidar@^3.5.3:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
+ integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+combined-stream@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
+ integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
+ dependencies:
+ delayed-stream "~1.0.0"
+
+confbox@^0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06"
+ integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
+
+confbox@^0.2.1:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.2.tgz#8652f53961c74d9e081784beed78555974a9c110"
+ integrity sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==
+
+csstype@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
+dayjs@^1.11.13:
+ version "1.11.13"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
+ integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
+
+debug@^4.3.4:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
+ integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
+ dependencies:
+ ms "^2.1.3"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
+
+dunder-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
+ integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
+ dependencies:
+ call-bind-apply-helpers "^1.0.1"
+ es-errors "^1.3.0"
+ gopd "^1.2.0"
+
+echarts@^5.4.3:
+ version "5.6.0"
+ resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.6.0.tgz#2377874dca9fb50f104051c3553544752da3c9d6"
+ integrity sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==
+ dependencies:
+ tslib "2.3.0"
+ zrender "5.6.1"
+
+element-plus@^2.3.9:
+ version "2.9.11"
+ resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-2.9.11.tgz#c939a8d945330f596b7a35aae0e501ea170874a2"
+ integrity sha512-x4L/6YC8de4JtuE3vpaEugJdQIeHQaHtIYKyk67IeF6dTIiVax45aX4nWOygnh+xX+0gTvL6xO+9BZhPA3G82w==
+ dependencies:
+ "@ctrl/tinycolor" "^3.4.1"
+ "@element-plus/icons-vue" "^2.3.1"
+ "@floating-ui/dom" "^1.0.1"
+ "@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
+ "@types/lodash" "^4.14.182"
+ "@types/lodash-es" "^4.17.6"
+ "@vueuse/core" "^9.1.0"
+ async-validator "^4.2.5"
+ dayjs "^1.11.13"
+ escape-html "^1.0.3"
+ lodash "^4.17.21"
+ lodash-es "^4.17.21"
+ lodash-unified "^1.0.2"
+ memoize-one "^6.0.0"
+ normalize-wheel-es "^1.2.0"
+
+entities@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
+es-define-property@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
+ integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
+
+es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
+ integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
+ dependencies:
+ es-errors "^1.3.0"
+
+es-set-tostringtag@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
+ integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
+ dependencies:
+ es-errors "^1.3.0"
+ get-intrinsic "^1.2.6"
+ has-tostringtag "^1.0.2"
+ hasown "^2.0.2"
+
+esbuild@^0.18.10:
+ version "0.18.20"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
+ integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
+ optionalDependencies:
+ "@esbuild/android-arm" "0.18.20"
+ "@esbuild/android-arm64" "0.18.20"
+ "@esbuild/android-x64" "0.18.20"
+ "@esbuild/darwin-arm64" "0.18.20"
+ "@esbuild/darwin-x64" "0.18.20"
+ "@esbuild/freebsd-arm64" "0.18.20"
+ "@esbuild/freebsd-x64" "0.18.20"
+ "@esbuild/linux-arm" "0.18.20"
+ "@esbuild/linux-arm64" "0.18.20"
+ "@esbuild/linux-ia32" "0.18.20"
+ "@esbuild/linux-loong64" "0.18.20"
+ "@esbuild/linux-mips64el" "0.18.20"
+ "@esbuild/linux-ppc64" "0.18.20"
+ "@esbuild/linux-riscv64" "0.18.20"
+ "@esbuild/linux-s390x" "0.18.20"
+ "@esbuild/linux-x64" "0.18.20"
+ "@esbuild/netbsd-x64" "0.18.20"
+ "@esbuild/openbsd-x64" "0.18.20"
+ "@esbuild/sunos-x64" "0.18.20"
+ "@esbuild/win32-arm64" "0.18.20"
+ "@esbuild/win32-ia32" "0.18.20"
+ "@esbuild/win32-x64" "0.18.20"
+
+escape-html@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+ integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+
+escape-string-regexp@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
+ integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
+
+estree-walker@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
+ integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
+
+estree-walker@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
+ integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
+ dependencies:
+ "@types/estree" "^1.0.0"
+
+exsolve@^1.0.1:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.0.5.tgz#1f5b6b4fe82ad6b28a173ccb955a635d77859dcf"
+ integrity sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==
+
+fast-glob@^3.3.0, fast-glob@^3.3.1, fast-glob@^3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
+ integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.8"
+
+fastq@^1.6.0:
+ version "1.19.1"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5"
+ integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==
+ dependencies:
+ reusify "^1.0.4"
+
+fill-range@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
+ integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+follow-redirects@^1.15.6:
+ version "1.15.9"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
+ integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
+
+form-data@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c"
+ integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ es-set-tostringtag "^2.1.0"
+ mime-types "^2.1.12"
+
+fsevents@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+
+get-intrinsic@^1.2.6:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
+ integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
+ dependencies:
+ call-bind-apply-helpers "^1.0.2"
+ es-define-property "^1.0.1"
+ es-errors "^1.3.0"
+ es-object-atoms "^1.1.1"
+ function-bind "^1.1.2"
+ get-proto "^1.0.1"
+ gopd "^1.2.0"
+ has-symbols "^1.1.0"
+ hasown "^2.0.2"
+ math-intrinsics "^1.1.0"
+
+get-proto@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
+ integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
+ dependencies:
+ dunder-proto "^1.0.1"
+ es-object-atoms "^1.0.0"
+
+glob-parent@^5.1.2, glob-parent@~5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+gopd@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
+ integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
+
+has-symbols@^1.0.3, has-symbols@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
+ integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
+
+has-tostringtag@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
+ integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
+ dependencies:
+ has-symbols "^1.0.3"
+
+hasown@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ dependencies:
+ function-bind "^1.1.2"
+
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
+
+is-core-module@^2.16.0:
+ version "2.16.1"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
+ integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
+ dependencies:
+ hasown "^2.0.2"
+
+is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+
+is-glob@^4.0.1, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+js-tokens@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-9.0.1.tgz#2ec43964658435296f6761b34e10671c2d9527f4"
+ integrity sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==
+
+local-pkg@^0.4.3:
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963"
+ integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==
+
+local-pkg@^0.5.0:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.1.tgz#69658638d2a95287534d4c2fff757980100dbb6d"
+ integrity sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==
+ dependencies:
+ mlly "^1.7.3"
+ pkg-types "^1.2.1"
+
+local-pkg@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-1.1.1.tgz#f5fe74a97a3bd3c165788ee08ca9fbe998dc58dd"
+ integrity sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==
+ dependencies:
+ mlly "^1.7.4"
+ pkg-types "^2.0.1"
+ quansync "^0.2.8"
+
+lodash-es@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
+lodash-unified@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/lodash-unified/-/lodash-unified-1.0.3.tgz#80b1eac10ed2eb02ed189f08614a29c27d07c894"
+ integrity sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
+
+lodash@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+magic-string@^0.30.1, magic-string@^0.30.17, magic-string@^0.30.5:
+ version "0.30.17"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
+ integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+
+math-intrinsics@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
+ integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
+
+memoize-one@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
+ integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
+
+merge2@^1.3.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
+ integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+micromatch@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
+ integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
+ dependencies:
+ braces "^3.0.3"
+ picomatch "^2.3.1"
+
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.12:
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+ dependencies:
+ mime-db "1.52.0"
+
+minimatch@^9.0.3:
+ version "9.0.5"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
+ integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
+ dependencies:
+ brace-expansion "^2.0.1"
+
+mlly@^1.7.3, mlly@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.4.tgz#3d7295ea2358ec7a271eaa5d000a0f84febe100f"
+ integrity sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==
+ dependencies:
+ acorn "^8.14.0"
+ pathe "^2.0.1"
+ pkg-types "^1.3.0"
+ ufo "^1.5.4"
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.11:
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
+ integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
+
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+
+normalize-wheel-es@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz#0fa2593d619f7245a541652619105ab076acf09e"
+ integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
+
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+pathe@^2.0.1, pathe@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716"
+ integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
+
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+picomatch@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
+ integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
+
+pkg-types@^1.2.1, pkg-types@^1.3.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df"
+ integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
+ dependencies:
+ confbox "^0.1.8"
+ mlly "^1.7.4"
+ pathe "^2.0.1"
+
+pkg-types@^2.0.1:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.1.0.tgz#70c9e1b9c74b63fdde749876ee0aa007ea9edead"
+ integrity sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==
+ dependencies:
+ confbox "^0.2.1"
+ exsolve "^1.0.1"
+ pathe "^2.0.3"
+
+postcss@^8.4.27, postcss@^8.5.3:
+ version "8.5.4"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.4.tgz#d61014ac00e11d5f58458ed7247d899bd65f99c0"
+ integrity sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==
+ dependencies:
+ nanoid "^3.3.11"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
+
+proxy-from-env@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
+ integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+
+quansync@^0.2.8:
+ version "0.2.10"
+ resolved "https://registry.yarnpkg.com/quansync/-/quansync-0.2.10.tgz#32053cf166fa36511aae95fc49796116f2dc20e1"
+ integrity sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
+resolve@^1.22.2:
+ version "1.22.10"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
+ integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
+ dependencies:
+ is-core-module "^2.16.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+reusify@^1.0.4:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f"
+ integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==
+
+rollup@^3.27.1:
+ version "3.29.5"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54"
+ integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+ dependencies:
+ queue-microtask "^1.2.2"
+
+scule@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/scule/-/scule-1.3.0.tgz#6efbd22fd0bb801bdcc585c89266a7d2daa8fbd3"
+ integrity sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==
+
+source-map-js@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+strip-literal@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/strip-literal/-/strip-literal-2.1.1.tgz#26906e65f606d49f748454a08084e94190c2e5ad"
+ integrity sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==
+ dependencies:
+ js-tokens "^9.0.1"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
+tslib@2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
+ integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
+
+ufo@^1.5.4:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b"
+ integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==
+
+unimport@^3.4.0:
+ version "3.14.6"
+ resolved "https://registry.yarnpkg.com/unimport/-/unimport-3.14.6.tgz#f01170aa2fb94c4f97b22c0ac2822ef7e8e0726d"
+ integrity sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==
+ dependencies:
+ "@rollup/pluginutils" "^5.1.4"
+ acorn "^8.14.0"
+ escape-string-regexp "^5.0.0"
+ estree-walker "^3.0.3"
+ fast-glob "^3.3.3"
+ local-pkg "^1.0.0"
+ magic-string "^0.30.17"
+ mlly "^1.7.4"
+ pathe "^2.0.1"
+ picomatch "^4.0.2"
+ pkg-types "^1.3.0"
+ scule "^1.3.0"
+ strip-literal "^2.1.1"
+ unplugin "^1.16.1"
+
+unplugin-auto-import@^0.16.6:
+ version "0.16.7"
+ resolved "https://registry.yarnpkg.com/unplugin-auto-import/-/unplugin-auto-import-0.16.7.tgz#f4f1f7ab3fba24129bc38e47f83782684030d6e4"
+ integrity sha512-w7XmnRlchq6YUFJVFGSvG1T/6j8GrdYN6Em9Wf0Ye+HXgD/22kont+WnuCAA0UaUoxtuvRR1u/mXKy63g/hfqQ==
+ dependencies:
+ "@antfu/utils" "^0.7.6"
+ "@rollup/pluginutils" "^5.0.5"
+ fast-glob "^3.3.1"
+ local-pkg "^0.5.0"
+ magic-string "^0.30.5"
+ minimatch "^9.0.3"
+ unimport "^3.4.0"
+ unplugin "^1.5.0"
+
+unplugin-vue-components@^0.25.2:
+ version "0.25.2"
+ resolved "https://registry.yarnpkg.com/unplugin-vue-components/-/unplugin-vue-components-0.25.2.tgz#99d9d02a4066a24e720edbe74a82a4ee6ff86153"
+ integrity sha512-OVmLFqILH6w+eM8fyt/d/eoJT9A6WO51NZLf1vC5c1FZ4rmq2bbGxTy8WP2Jm7xwFdukaIdv819+UI7RClPyCA==
+ dependencies:
+ "@antfu/utils" "^0.7.5"
+ "@rollup/pluginutils" "^5.0.2"
+ chokidar "^3.5.3"
+ debug "^4.3.4"
+ fast-glob "^3.3.0"
+ local-pkg "^0.4.3"
+ magic-string "^0.30.1"
+ minimatch "^9.0.3"
+ resolve "^1.22.2"
+ unplugin "^1.4.0"
+
+unplugin@^1.16.1, unplugin@^1.4.0, unplugin@^1.5.0:
+ version "1.16.1"
+ resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.16.1.tgz#a844d2e3c3b14a4ac2945c42be80409321b61199"
+ integrity sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==
+ dependencies:
+ acorn "^8.14.0"
+ webpack-virtual-modules "^0.6.2"
+
+vite@^4.4.9:
+ version "4.5.14"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.14.tgz#2e652bc1d898265d987d6543ce866ecd65fa4086"
+ integrity sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==
+ dependencies:
+ esbuild "^0.18.10"
+ postcss "^8.4.27"
+ rollup "^3.27.1"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+vue-demi@*:
+ version "0.14.10"
+ resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04"
+ integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
+
+vue-router@^4.2.4:
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.5.1.tgz#47bffe2d3a5479d2886a9a244547a853aa0abf69"
+ integrity sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==
+ dependencies:
+ "@vue/devtools-api" "^6.6.4"
+
+vue@^3.3.4:
+ version "3.5.16"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.16.tgz#f0cde88c2688354f00ff2d77eb295c26440f8c7a"
+ integrity sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w==
+ dependencies:
+ "@vue/compiler-dom" "3.5.16"
+ "@vue/compiler-sfc" "3.5.16"
+ "@vue/runtime-dom" "3.5.16"
+ "@vue/server-renderer" "3.5.16"
+ "@vue/shared" "3.5.16"
+
+webpack-virtual-modules@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"
+ integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==
+
+zrender@5.6.1:
+ version "5.6.1"
+ resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.6.1.tgz#e08d57ecf4acac708c4fcb7481eb201df7f10a6b"
+ integrity sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==
+ dependencies:
+ tslib "2.3.0"
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/start.bat b/src/声源定位代码/audio-classification/audio-classification-platform/start.bat
new file mode 100644
index 0000000..8094d48
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/start.bat
@@ -0,0 +1,24 @@
+@echo off
+echo ================================
+echo 声纹识别系统启动脚本
+echo ================================
+echo.
+
+echo 正在启动后端服务...
+cd /d "%~dp0backend"
+start "后端服务" cmd /k "python app.py"
+
+echo 等待后端服务启动...
+timeout /t 3 /nobreak >nul
+
+echo 正在启动前端服务...
+cd /d "%~dp0frontend"
+start "前端服务" cmd /k "npm run dev"
+
+echo.
+echo 启动完成!
+echo 后端服务: http://localhost:5000
+echo 前端服务: http://localhost:3000
+echo.
+echo 请等待服务完全启动后访问前端地址
+pause
diff --git a/src/声源定位代码/audio-classification/audio-classification-platform/start.sh b/src/声源定位代码/audio-classification/audio-classification-platform/start.sh
new file mode 100644
index 0000000..06674da
--- /dev/null
+++ b/src/声源定位代码/audio-classification/audio-classification-platform/start.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+echo "================================"
+echo " 声纹识别系统启动脚本"
+echo "================================"
+echo
+
+# 获取脚本所在目录
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+
+echo "正在启动后端服务..."
+cd "$SCRIPT_DIR/backend"
+python app.py &
+BACKEND_PID=$!
+
+echo "等待后端服务启动..."
+sleep 3
+
+echo "正在启动前端服务..."
+cd "$SCRIPT_DIR/frontend"
+npm run dev &
+FRONTEND_PID=$!
+
+echo
+echo "启动完成!"
+echo "后端服务: http://localhost:5000"
+echo "前端服务: http://localhost:3000"
+echo
+echo "后端进程 PID: $BACKEND_PID"
+echo "前端进程 PID: $FRONTEND_PID"
+echo
+echo "按 Ctrl+C 停止所有服务"
+
+# 等待用户中断
+trap 'echo "正在停止服务..."; kill $BACKEND_PID $FRONTEND_PID; exit' INT
+wait
diff --git a/src/声源定位代码/audio-classification/configs/augmentation.yml b/src/声源定位代码/audio-classification/configs/augmentation.yml
new file mode 100644
index 0000000..5ffe3c5
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/augmentation.yml
@@ -0,0 +1,46 @@
+# 语速增强
+speed:
+ # 增强概率
+ prob: 1.0
+
+# 音量增强
+volume:
+ # 增强概率
+ prob: 0.0
+ # 最小增益
+ min_gain_dBFS: -15
+ # 最大增益
+ max_gain_dBFS: 15
+
+# 噪声增强
+noise:
+ # 增强概率
+ prob: 0.5
+ # 噪声增强的噪声文件夹
+ noise_dir: 'dataset/noise'
+ # 针对噪声的最小音量增益
+ min_snr_dB: 10
+ # 针对噪声的最大音量增益
+ max_snr_dB: 50
+
+# 混响增强
+reverb:
+ # 增强概率
+ prob: 0.5
+ # 混响增强的混响文件夹
+ reverb_dir: 'dataset/reverb'
+
+# Spec增强
+spec_aug:
+ # 增强概率
+ prob: 0.5
+ # 频域掩蔽的比例
+ freq_mask_ratio: 0.1
+ # 频域掩蔽次数
+ n_freq_masks: 1
+ # 频域掩蔽的比例
+ time_mask_ratio: 0.05
+ # 频域掩蔽次数
+ n_time_masks: 1
+ # 最大时间扭曲
+ max_time_warp: 0
diff --git a/src/声源定位代码/audio-classification/configs/cam++.yml b/src/声源定位代码/audio-classification/configs/cam++.yml
new file mode 100644
index 0000000..ce68da9
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/cam++.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 64
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 8
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型
+ model: 'CAMPPlus'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/ecapa_tdnn.yml b/src/声源定位代码/audio-classification/configs/ecapa_tdnn.yml
new file mode 100644
index 0000000..6c13e50
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/ecapa_tdnn.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 128
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 16
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型
+ model: 'EcapaTdnn'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/eres2net.yml b/src/声源定位代码/audio-classification/configs/eres2net.yml
new file mode 100644
index 0000000..6bc1170
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/eres2net.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 32
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 4
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型,支持ERes2Net、ERes2NetV2
+ model: 'ERes2Net'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/panns.yml b/src/声源定位代码/audio-classification/configs/panns.yml
new file mode 100644
index 0000000..5d000f1
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/panns.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 64
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 8
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+# 所使用的模型,支持PANNS_CNN6、PANNS_CNN10、PANNS_CNN14
+ model: 'PANNS_CNN10'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/res2net.yml b/src/声源定位代码/audio-classification/configs/res2net.yml
new file mode 100644
index 0000000..072e2e4
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/res2net.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 32
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 4
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型
+ model: 'Res2Net'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/resnet_se.yml b/src/声源定位代码/audio-classification/configs/resnet_se.yml
new file mode 100644
index 0000000..5af006d
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/resnet_se.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 32
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 4
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型
+ model: 'ResNetSE'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/configs/tdnn.yml b/src/声源定位代码/audio-classification/configs/tdnn.yml
new file mode 100644
index 0000000..9cd3d2a
--- /dev/null
+++ b/src/声源定位代码/audio-classification/configs/tdnn.yml
@@ -0,0 +1,80 @@
+# 数据集参数
+dataset_conf:
+ dataset:
+ # 过滤最短的音频长度
+ min_duration: 0.4
+ # 最长的音频长度,大于这个长度会裁剪掉
+ max_duration: 3
+ # 音频的采样率
+ sample_rate: 16000
+ # 是否对音频进行音量归一化
+ use_dB_normalization: True
+ # 对音频进行音量归一化的音量分贝值
+ target_dB: -20
+ dataLoader:
+ # 训练的批量大小
+ batch_size: 64
+ # 是否丢弃最后一个样本
+ drop_last: True
+ # 读取数据的线程数量
+ num_workers: 8
+ # 评估的数据要特殊处理
+ eval_conf:
+ # 评估的批量大小
+ batch_size: 8
+ # 最长的音频长度
+ max_duration: 20
+ # 训练数据的数据列表路径
+ train_list: 'dataset/train_list.txt'
+ # 测试数据的数据列表路径
+ test_list: 'dataset/test_list.txt'
+ # 标签列表
+ label_list_path: 'dataset/label_list.txt'
+
+# 数据预处理参数
+preprocess_conf:
+ # 是否使用HF上的Wav2Vec2类似模型提取音频特征
+ use_hf_model: False
+ # 音频预处理方法,也可以叫特征提取方法
+ # 当use_hf_model为False时,支持:MelSpectrogram、Spectrogram、MFCC、Fbank
+ # 当use_hf_model为True时,指定的是HuggingFace的模型或者本地路径,比如facebook/w2v-bert-2.0或者./feature_models/w2v-bert-2.0
+ feature_method: 'Fbank'
+ # 当use_hf_model为False时,设置API参数,更参数查看对应API,不清楚的可以直接删除该部分,直接使用默认值。
+ # 当use_hf_model为True时,可以设置参数use_gpu,指定是否使用GPU提取特征
+ method_args:
+ sample_frequency: 16000
+ num_mel_bins: 80
+
+model_conf:
+ # 所使用的模型
+ model: 'TDNN'
+ # 模型参数
+ model_args:
+ # 分类大小,如果为null,自动通过标签列表获取
+ num_class: null
+
+optimizer_conf:
+ # 优化方法
+ optimizer: 'Adam'
+ # 优化方法参数
+ optimizer_args:
+ lr: 0.001
+ weight_decay: !!float 1e-5
+ # 学习率衰减函数,支持Pytorch支持的和项目提供的WarmupCosineSchedulerLR
+ scheduler: 'WarmupCosineSchedulerLR'
+ # 学习率衰减函数参数
+ scheduler_args:
+ min_lr: !!float 1e-5
+ max_lr: 0.001
+ warmup_epoch: 5
+
+train_conf:
+ # 是否开启自动混合精度
+ enable_amp: False
+ # 是否使用Pytorch2.0的编译器
+ use_compile: False
+ # CrossEntropyLoss类的label_smoothing参数
+ label_smoothing: 0.0
+ # 训练的轮数
+ max_epoch: 60
+ log_interval: 10
diff --git a/src/声源定位代码/audio-classification/create_data.py b/src/声源定位代码/audio-classification/create_data.py
new file mode 100644
index 0000000..da73e90
--- /dev/null
+++ b/src/声源定位代码/audio-classification/create_data.py
@@ -0,0 +1,99 @@
+import os
+
+
+# 生成数据列表
+def get_data_list(audio_path, list_path):
+ sound_sum = 0
+ audios = os.listdir(audio_path)
+ os.makedirs(list_path, exist_ok=True)
+ f_train = open(os.path.join(list_path, 'train_list.txt'), 'w', encoding='utf-8')
+ f_test = open(os.path.join(list_path, 'test_list.txt'), 'w', encoding='utf-8')
+ f_label = open(os.path.join(list_path, 'label_list.txt'), 'w', encoding='utf-8')
+
+ for i in range(len(audios)):
+ f_label.write(f'{audios[i]}\n')
+ sounds = os.listdir(os.path.join(audio_path, audios[i]))
+ for sound in sounds:
+ sound_path = os.path.join(audio_path, audios[i], sound).replace('\\', '/')
+ if sound_sum % 10 == 0:
+ f_test.write(f'{sound_path}\t{i}\n')
+ else:
+ f_train.write(f'{sound_path}\t{i}\n')
+ sound_sum += 1
+ print(f"Audio:{i + 1}/{len(audios)}")
+ f_label.close()
+ f_test.close()
+ f_train.close()
+
+
+# 下载数据方式,执行:./tools/download_3dspeaker_data.sh
+# 生成生成方言数据列表
+def get_language_identification_data_list(audio_path, list_path):
+ labels_dict = {0: 'Standard Mandarin', 3: 'Southwestern Mandarin', 6: 'Central Plains Mandarin',
+ 4: 'JiangHuai Mandarin', 2: 'Wu dialect', 8: 'Gan dialect', 9: 'Jin dialect',
+ 11: 'LiaoJiao Mandarin', 12: 'JiLu Mandarin', 10: 'Min dialect', 7: 'Yue dialect',
+ 5: 'Hakka dialect', 1: 'Xiang dialect', 13: 'Northern Mandarin'}
+
+ with open(os.path.join(list_path, 'train_list.txt'), 'w', encoding='utf-8') as f:
+ train_dir = os.path.join(audio_path, 'train')
+ for root, dirs, files in os.walk(train_dir):
+ for file in files:
+ if not file.endswith('.wav'): continue
+ label = int(file.split('_')[-1].replace('.wav', '')[-2:])
+ file = os.path.join(root, file)
+ f.write(f'{file}\t{label}\n')
+
+ with open(os.path.join(list_path, 'test_list.txt'), 'w', encoding='utf-8') as f:
+ test_dir = os.path.join(audio_path, 'test')
+ for root, dirs, files in os.walk(test_dir):
+ for file in files:
+ if not file.endswith('.wav'): continue
+ label = int(file.split('_')[-1].replace('.wav', '')[-2:])
+ file = os.path.join(root, file)
+ f.write(f'{file}\t{label}\n')
+
+ with open(os.path.join(list_path, 'label_list.txt'), 'w', encoding='utf-8') as f:
+ for i in range(len(labels_dict)):
+ f.write(f'{labels_dict[i]}\n')
+
+
+# 创建UrbanSound8K数据列表
+def create_UrbanSound8K_list(audio_path, metadata_path, list_path):
+ sound_sum = 0
+
+ f_train = open(os.path.join(list_path, 'train_list.txt'), 'w', encoding='utf-8')
+ f_test = open(os.path.join(list_path, 'test_list.txt'), 'w', encoding='utf-8')
+ f_label = open(os.path.join(list_path, 'label_list.txt'), 'w', encoding='utf-8')
+
+ with open(metadata_path) as f:
+ lines = f.readlines()
+
+ labels = {}
+ for i, line in enumerate(lines):
+ if i == 0:continue
+ data = line.replace('\n', '').split(',')
+ class_id = int(data[6])
+ if class_id not in labels.keys():
+ labels[class_id] = data[-1]
+ sound_path = os.path.join(audio_path, f'fold{data[5]}', data[0]).replace('\\', '/')
+ if sound_sum % 10 == 0:
+ f_test.write(f'{sound_path}\t{data[6]}\n')
+ else:
+ f_train.write(f'{sound_path}\t{data[6]}\n')
+ sound_sum += 1
+ for i in range(len(labels)):
+ f_label.write(f'{labels[i]}\n')
+ f_label.close()
+ f_test.close()
+ f_train.close()
+
+
+if __name__ == '__main__':
+ # get_data_list('dataset/audio', 'dataset')
+ # 生成生成方言数据列表
+ # get_language_identification_data_list(audio_path='dataset/language',
+ # list_path='dataset/')
+ # 创建UrbanSound8K数据列表
+ create_UrbanSound8K_list(audio_path='dataset/UrbanSound8K/audio',
+ metadata_path='dataset/UrbanSound8K/metadata/UrbanSound8K.csv',
+ list_path='dataset')
diff --git a/src/声源定位代码/audio-classification/docs/images/image1.png b/src/声源定位代码/audio-classification/docs/images/image1.png
new file mode 100644
index 0000000000000000000000000000000000000000..6bba58a14c8d2e9aea2a11ea36b75a8c7e2c3d40
GIT binary patch
literal 69600
zcmeFZcT`mS)+LHL9mGJ8EE1F~S&*P2p~z7vq6!6)6)18#Dq=uF0YwItB&kqx#z-oH
zWXUSAiX=J1Tbpz4y?y)pzV7k5Uyt`s*En}rx7f9J?O#}Ht~ux0&$Kj@D33E7r=Xyq
zL@D3Yp`bYUj)LOA`J;#76OkYB`{5r+R|P{?T_-D7_dCuQ3iUg#_wAir?QQO!cf&Zl
z*f=?g2wV{m<~x7S)%CuMl%Sx)KMxRaa<czq#`TPIBzNGTMcLg6azWZ(9_?kn{Q2w)x!lWDGQ!XlQ{A4xr*S0@)J+x_8lS~S2@C{qvskP
za>?ym;30RK>k8D@uaS6;9)0*>KdslrR5i&OIpMRq4L5b3G;JErrX!u3jg8H`b+E$S$)UekU9j@^!y*4&UonS1QS(-Vu#F`W
zJ29X7?AeI1sWqZtO?^He8lU#;?8Wi&9l4z~d5hZMHax%a!mA<}A5Wt8cS`tIq0Tzl
zH@#+ed+zv&6S{e3ReB|krkocqPW3z0bp8JMdAUPVj`UJus6N`|A_vF4!E&tE1}Q`A
z_J;r;Nu?+r{m8JeS7BjcKACbCPX@`;37CAlnC$b$aj-nCU&4LXBrqt5S4e1Huxq=H
z)&Jh~_xD*wMOh5u_LHj*V06aJrC4F#I-Wvyu;(xT-OXgLrODSk`dRnBKBsy9@}>G<
zPmRC-OmBfwvhNDII&t^=dkb9Z8BUeaen~!}j)#Xwbysr4yLXqxoQ6zxcUEge4!s+1
zj?V~TzDoW~CC3+5Y*KpvdU$yFaY{=5u*H280Y7S~Z%|N#UF1@Wd9^svIyF-=tU*_~
zkcloxKYWrYW@BK?nFOIr_a%cEH7#v=mVP!lGb2d{UgaZMw{o*I5~WDU&|rH^Gk*WR
zub*dTI#;!7W*aMHQTtXUiU*ha^K%d}pHDy6NMEP1^Xl-b%}aU_MLZ_0zu3N4xaeNn
z4NjFvEj_(R+pes%j3h4}tiPMx?Oen6HzWpKBc9Xnro-*MRgD(tD|4~NPxKd9hr-0B
zARl_n|0>_z*~I?*6gX}E{SU8|>C9HSU6TyWWR1aMn+~q+1)?Cix4=4m;i6_z=es+f
z_43SQ6ciM=xwsT(`b&C3<#u9>ti~Fn%2)dAI8m#^{{CdWo91%H#rB!y*eUYnTuo22
z#Bff1eSK#S=LmygmG|l`7~}Mv5{Ld<1||;zVF^>!Y(lpBA&*4t(Px^n>o>cy4SHaO
zOd72FZEuizt&{afYF~yhaC+OO7$F8>%ctE0(`;A(cCgE08{Mb6)hAjKJ6;G@zl9ZPvohVw
zaMdkmc%~ArW(hlTV=|@FVR5{y$nGlEMqDF-IguD{r!
zd<<`_^9a>r;_?y>yNL3dd>yp3vpF}ly*i8xS%Oh3?6b~lUvDw{?^^KFyK+m0;xL=(
z>hbBqn8vs6b3@J*gSgZlbAMA<_i0v5F|T>^D%E|8#F5(5UYL)S
z*!SM$h=tKi>zB3vewn=?$MF3HtTAl2V2%Qa3Y`v0p)6u|?%c7O{PsGtAJ+XYJ!*U`
z+FZlHdTyvn9S#&Oy0bLd#x;}nEs|R|n8O9Oo_+t!)w+tg>iF{9JD;DV+xO;=e|dH`
zv)^xPUdf`MR}D75aN^vbM_7~%ta}Ki>X|xe`7+jhe$>3Tn$B4?4ezW-xNOdpFj@pZ
zs2EK5SzoY%lcK8+KYRA9cE-(`tYl~yLoeZILM~R17srs}Tlq@{;5N_&R+zFmys;yy
zWCmv9GOlT{RnBQ;rr-L_n>S5~?nAK_tdPp{ygBrhWJ%Wkk@?@JltIzL`3Xjm$Zrxe>ydBkcgfhjt
zP*wvUAD{9W`b}r}va$|gqy4q~5g0hTj}H&UU3DiAs#f~c^3p=9hor4u3wc6OkQkFI)kea?S3+t{f}->GK17)e&*
z4t;O+vv0+ko%Mh8Z0BicXb;4MyuKp4snJAS;4n&ua#s6S@JH
z)rARm9jy;n+gzO;%!Y$dDzW=7a(5)|hv?0RB15W6D#})T$spx29$f4=7*{^??X|p7
z>HRz9&TvGNtNrIEl$=OpM0YbYGG;%aWVCHbkRpkN(P)?h&v9vm2?@OY`Hqui9|>18FE`nkYWf^Cc(6VJYUD!6L^Ad
zsn0Htl$A|TDS5hH`e3BcYuOe%{asr>ORudhMQIt9SJvIH&uw9=7cbXrEf8&otE=L~
z?9!`!H+k6Du8UYTX#v_2gZL^vrKAWuu2p(bEo4jzOHO?-QcHr6jijo#u$XLMLbJ@O
zyvm)$Y&*4{o#7O<>*j;)lWq9^Zu!o}6bwL-Ns%2)l-F{Xftc6QJu$}tL)_AA#atGw
zQ5c9wzz|{C8!#>$!cdl6V<{gAxmt*wx&=wjzvGRGYsh7eh8y=kj7jtjXi?PTlZry-JUH`zfcctSG#IX%?ISNx@wZ*|DD~CGIuH
ziItt)84UuYp&}o2vJ2T_e;znOhH&-`L4E*P(s=34oOuINQ}0+Z6|Th6hNNIv(qm*3
zBzqp9l70oNkVMJ=nBfP(*XGBEKjTDgaNT+4$rra_M}GV&T!t2+hJk?BrQ4SOJC&Kz
z9SI7G1snt|R{yQnlau$*c>V9qkRL9&)}Bke>aJm6=9y++OcV@a6B5#HXlOX()$;9|
z7KC5ANy&XCOi(l`G$LPx8>4X(fgiNLC9h^D3kHhTO~jcKzI6KZ=|g@)uo)Q%9Z%zUv(2o~)pgwa(=X-O5fkuWd1Q$&BTy|bEtPGy^
z?MR)C4LImfv$u-ei;&wSyLU^v$CIj)q&;=Ivh-D}G|CgGUB{zZ0YXG2B&boGIC>tc
zS8DF+S5X+Wf>Z#M1Q*!ZY0jS2O%*Ini}V+G_&V=nyC%2C2AnVHpXZZG)IgO_=e<0h
zwOt#tUy>?dplpll+Fv#F`L}z>8E*30HH+hH$nc+kMYFVUN{#*Cek%HZR?UCU$bJU+
zs2;)E@Pcajz+TaP>f3Rt11GNiVEgO;BK6}RdzJTJNBrw7|Ej%XZX88UarB-V+reu{
z+D2Y`XNP~Gnum{&9f7<~ef#@@2Swqdus;u-zZA%rqOFlp%*9F4yZdH^lgk$0k;(hA
z0c+ahDZO!C5?#Z^MTWn?0XD%Mne|L$=W{9h1fr`^D(&H4ZZa>jY#Q|cc^(&b-frn0
z+Q6KjS6JuP*XQ{gD^Y&CGOO4`DNeg@=h0nR4bPt{dooEIO8H7nEmXLnbTb;sy}Gwd
z671b7;J-ru-Lxg-K1we^Tz;q#BV-hpkdrass6d~h=^(ysg(lCq*_rC#vb?1Idb&Q(
zbT5orVplv|zvV9lHm6^<5N)67?rCUv-okYX8z^KHn~)Q2DxiN^(Y)W@$gzN1TgR!y
zSpV22*Iml<({!0KfLf8JP1^u1WXHT&skPoX}ZxwCS5S
zF^W=5JiH`qMn|3(&$$$XL=8y}nd$p)Jq=^L9zV%)G>oDBZlC28Tw7rhOC_qf
zn4lphq}bX&^L&w|hh0>!2NHDLH?5fq3M{?v%sj4lZ!8Np$2Dwi6*O(F3r}@7h&*_c
zV^L?hJT>8O`sfI;uRtl?&LB4NsxG;&T;J*g1-inW$RH)!A(ZZD8he_3bp6Kx&y|^o
zOnqL#iX#-)@IJanPmqy?7I5hN+sEfplm;A8?XSX4ea$Gl7CU?YUN(kgWzkt5%9pe2
zQbEH;;*D3IliV@U`DTM=U^?@rK&2s_CzdUq>=>%VFT>({uYeR7cB)Logkz?p*Y)9v
zi{=r~DToTXJ$*qb*y0}>wZ)V4SBZ{^~ucV#EaPcq}iTceLrM#V~sa2_BM)nd*A
zh7@%txGvq>7=hK}Ij=yPtw`h1UwC5x1AQ$7D5j%4&C)DUVTC>UODX(|r%Jy$Msr|)
zA1)I}e=kvAB=y2e1C1{>#^2y5BA)uAV%T`q?&NIBpC(2Hirujy!eX|{FBvd>4ztz9
zI7{CRn-(m;DGzZZ+_4`S{WmwC`8XI{&zfs~(uZpfeCFgWBiH@v
z`I2l>i&c%_i!8r53jF7DgOl_1+%^%IOhR3Xb)rV|eW~SCVwzW(q5p~N_olid>-ZiT
zkcu}OO&>?eo2EY)iFEES9?N=$jDX*d5&!eiP>!cU>c|981iwagrA>*In}dU6*%QK?
z*u8JBT(9TO4pwBtA%Wk@x3n7=V>V>sDez9-oO1gO>#9Pd3b?0?pUTYa*w$XU(S8RN
zS~18l;@prl9%IeXT-Yymp?P!vn&A)mv>u3n>zEXlGAe<5b1#xwfwHl@163P9
zl0cQnORpjSWa>GuntnP3)XDm%7-O#=b&=>Ce~w;^7ic|I94O*B(nD^57y-yapPpgYL;8ta3@^H3;Cjd^_MU
zB|~a^nrb${C&}vcLk`u0gkcVS{E~TwZjlTN#LfOe$L*_<=xT5J^hD}OMpt0!NEw!rx7m`8l$@6d9klUOVL4G!~lIe2rAtI8ptBb>I)UEE1FmA~$Hzy&KpB#EU`7y5z-uDWeF=CV@@PW@
z0epv6?=#{sR=70#~I3Du}877Bi)*RNk26mt7|B-FKV4x#XxYZ!}tb}inh9PU1qiEh^$=5kQgp-q`o1xo)PqP_1^iwlK
za@;3wZnz{PQ98!Y_zYsT>w+fKM%h;WgUX
zm7xYA-0qNetT3j~qVA+ZT9tz@1MoGvP_b=i?FQ1BX@#=L06_iT=|IUK8peT;N=B6)
z@4Iu*DU42)+Bi|5^#G5f0A#)20qQ{&m!OdWH;@K5sf;`P$GKO4w9~pJuw*@%_0b4~
z+2KGHST!TnUARNM3Z9Rfo>eiy(8MTubfM3T2&l^6EwmoIODq`;*U
zdbS_dG}Fl-Le0)br$d@bln(69LYIk_P6ybMnICykz<+i@(Zh+dZb@i+Eg#h0_4ED}
z=dRl6>47p`UaOz@QBjVYkK}KN*8Ti;h}cd!R9=lb`$5VM
zy^&lpdj?(jQCN|)ayYrQknVcxs&|p6OZTR4zf1l8D2@nu({3uc)W~cDK?C)J6zAnG
z2cDv!hjk|9KAQs*G6~dJC(IN#l;*G}&0N{$?^YiQ-98mQ_@<%k6z-=07LUOgjbvTM
zbjc1=Hvu7=4I{8IA-5Y#D*gWbd*__XV%&yZVsm;2&h}i&21{shUwhqrMLBS3oM^Q<
z;>&WDP{#$2r3j3T=@SBl{Wx^`;>oTwO
zc<{BhHa+_@@X8Q?Y9=4RmUs3(aHY3wJkG8V_Kj;lY^@RZevVAoH^8kY>lNARcjcf(
z1`YfU=C(T<;jKI$De5L_D5M|TkePMPtQInIK=&nZO)fnprtt$Y8f`@>oD5?#O}{^=
zNSbB4pA^YyqfG0bop7gw7uC-0SVB-OXwm1kSjt~zn(LiW;R*;0z9FBsv(1U>wg}xW
z(}?0wkG)_wbt~4`F}&SMuqA;z+sy&3DHByq_->e~M1^i>$lq9vZXdYvfk9HI`@Kbb
z)oMDG{XPmUWq|ik0)%~}F)%@rAEFg#+1uxwWRZS*G0EeCW~&gC&d7?-(oT5-gb7q
zS9{`}sx!T3%aqs^gSCJdEV6E8X-<|icdA;(Pe;dWM@B?5og5sWe;X^*mlT;QCLYhj
zm@*aIrj4Squ4m!J1l!W5ETAn*tEOGawiboWRviyeG%wqhYwML6e%!x@rS+8rO!^>5
zKCjHg2%nHciBA*3r!fM4#4kOxsx{l?J)L~}&I3vEkq;HDkhLw~ryP=$AdX@8ckws9>Oh4w=FH0`<#(@A>
zULgofklS4kr4=;Gf#pgr?sx0}W?Of)W^=Z}wmtP3!kEC~Y&e$!lVur)cNap~1K-ub
z3{a=Cfzy2+5^@VzVnMGags1V}_3L`8Ef3UULq5XkWzm2UzPTQNG
zHtbM=(1=#e3}u6kMK&FZz#w%1qSbqI^H{I_x*Q)T8sGQiiEZT|;RHUdg(Z}SK4o><
zZSWjz`gYm9&owh{+xF+twQ-I?puY-7(m}0Ip
z3v&UV%*6e-*n4k(t&dXm9;1pzSDTE-TBp`4+q7LEeb^T}RE2?*oMkq+Tdop~N7tBH
zeW2i$L~pEFkecXY>sTV-BObKyqL6iKW8b@aptxCo1tdw}AP{^Muj9H-Dd3PcOM{zK8e_vv4SJ-j{tgGTQ#UMT%q
z%YpOm{|%q;PxXCIV?!tg-g<=rG#|@RwSWEK@IUuN|D*Tdqx1hW%Hh8tF8%5ccEW
zC@5QFz{_h
zKFr8dc1T~{*G}Uh36OyIFDInDFDq35XC+@o`jovU2*^CLqvP~_epXdYizLM
zjX8FcB~(c%gsF_rT=3N;pjfVjcY+FZ!S~}&SE(XU00C4fgJKdmnBYUh!a{&zAqyDP
z4tpDQZgL;eG=G$v48>mLXYE2kep7+yTLcq&(K#FKxxZJ*%{vl5aWIsx
z?wMmKjv9e3tgvyT^P-T@`}!mAd>)R;P~!bmK6W6>>hsT|&*A-I(qUD(v^T>&Zw4eN
zK0ZV*7*N%|`p?5!5ygZ^dUfKwwM?q`4%21VT70smS~ui!=k{^Fc~
zB}aH7(>V2Hr1uV`eLy$tP%E3ht_XrgD9@inSwO=vp;up_s_Gt>0I{W6qt
znD4YEO2O
z74AK9GBQP*JrGL3uwP$kbZV-n*_Bl4LQI`|C`JW`sXsm3*ni3cHr=(;v{u2iiE??T
zQ79g(VEp69lkV~AyU__b`V%dg&--WGP5m`Bx+mZ_JtC%=JBah2IHnEaW?W>dU`wK|
zEA921*@g!4ETx{WQ^{0B*ePH?I{U`jx7IvfswmeNRPR4}|JgI=LI>W>wRs(%O6kO_
zM7^9#n+cM~%XYkMhGloBr2I_Sn&XMGF6ovfM3*{dVQuaFnuX^#j0(dvlGF?ajH-;-
z5~Uhs?eIBk9&T+Dz*)rK(yd*0DsqZ>C(F
zOVRfQjqcRsJsD;ef^h9*)Csz+tO=D+r49j;F!}a?r$+}Fm~+j(KF>s{1@ADPc?0OJ
z7IQi{j+!<-PDsd>)~C#LVFQntQcWDANRGBUNV?C6_)r9QppKH9~UjH6{g
z4@;IfMSIVhlvQuvBKYs<0w8gg-g>u-rDWu?n=|tSvZS?K+zG$gri9sEcrnecm@4gKVq@pX>6d%m~iOC=*A?wr2BMO2G$N8L`9tcChs|5LE-rf79ud6ubv(kQl#SI
zMB$z&+`J^){PlbG&!2sc1(|{UxrYS|La>7o2{}hmyi6yXDNm>l&KB}fhCcm(k9M}L=fL`9IJ&kI(m9!f!0^o7do>q
z_LIBv{nps_SSp8)`(wXpl>rIJzum415^}w`QxXtWWH*0^!k6aiZxk6j}`q|pI&foIz4{E?mt6CMGZFksf6gTE{N`?L=X7IH|1LI|v`Y@(=rj7`l1Qo|Lu
z$`aoT^hcXFE_hhRNklhBsn&?_sU?LlW6B2e`Ax~@BZNwwbhX$>Hx{YUVIhj+Oh6v*
zEqVPOM%Rrt$5!XvTXQQ?ethGz#;Mz`;&iSTtNN!lB$?k8_vaEcGH{%}i3(bOTx+}Q
zFvx>i5VegQ^E1~X_7ykJm8-FIa&lwZR&_IULYmK=0s?&Bqg@7y)QE(H94#j+jmrro
zm$D}*rMAPrQdbxD^RA!%AoY_{3u93H+}+!4vtKfi3`d?q(a5lvPPh@dZEjnpu2`SF
zeL&0Aux2N2K|Sy|n(nQk(AfNs>orrty`5wIj_cad9KBY}xH0Dj-4cRcZk%}?#U&<7
z#eE-vB7b%Cw}*7x&M`~In?|wOo=&n#d^u!2Rw9m+S{C-vLN_qnn3{pJ;sUYP%svI&=
z#HWgUvD|GYtG-?tsc%8&ie5W@DC6!B#Vxnh^%twMikJthAA-BR3Q}h^G;S$BS)eo}
zbn+3V$ypVa=WUa4ct@Tdy60>F**;~oN8-pi<9v#2G-y;
z06!8^_JQWy&Rhc!+js3}5JIRFLgic2A_;cV{xt#x8^@=pY+AE)Y}0ppAh7-xi}j23Umi}ABvU;H&9a_9@it7}Y>
z7nDjI^Us_e^P3imb(=X}p#c2)1yDCk##<7vW+1nM@C=|bbD|KH@C7YD2MSRXZF^w`
zZNI;}6DQ|it(aQ&)dLjJA@4bvsCj|AQ=uEnQ+D9Kz#)Z872sW?YM(ODsdHhL5jV-k
z@a|3qKra*y`AS!&t`Z1M?L|Ws*D&rwvc4OWN#3*J94}er%sMhOdjOVqh4>3Ne|7Kq
z_|$&I+lAV7DAaY!gQyew_ENK)zgez{K#@vB@4FtWj;3!~lqxEXZZG+gIf(5V6{err
z*~jop_nq@uR8-p4z6BNu|7^62pIvSkABU@
ztQ4nBT?n(3??$0*4$)FbHtl9au1Y(qpfApv&s=Zy+M7b)YKX+Up+O5yN
zFYE=yEf=Twm56l;YR~anM$B`%=pv`&99I9P!eQY1aU7a;A(Gu=P_NZmMHE@Rj1;;m
z!Hpz@i1+Zm=0hrke;?*o}Tss
zuUw(~oLR1UjTvH~K1N-`Ma*l1z@%;f)mr#q1gR8N
z5g$RExI-M=*6|DssrlVyRQngecIgeSUZO(USdfM6N~Y>WuV);Iz!m^RerY;8DmPzqWc$)|tHOtT3--OU(j&3J16Nt)$sO3?%jWwGo{-imL5~
zix}psT$-&(I=%U%lLdegH!D4bi)NL~^bzXc|xryDCX*&iPrvHK9PPenyV2c{GP&?T@Ea+&vApz*Z)MyYiy
z-f9xVJ_YvT@vty5=tZnXr#!=Zzx=*G_{*8(Rbo7xD3gsn8N}l$UEV#@EktY&_@m^t
zAZdP*Csb(|BZOJ}`uJeif=A(?W6v?7&LJlm#r7XhkNU>5Mew$tQ&&~~w)Xho_PvrR
zs(AJA+P6>YQjCT+te*su&Vodxbzg2h6&zER;HzT8lIuGv%W@ta!St7Er>oJInfc3@
zdQN>g29ls^5S2B-?$^y;ar-cbpEm*l>}W=C<-1LX&1587+IBY;UaBbact0&-t%6en
z8CP!IvfF`4T&;YAEKL>y?}_TccL5hZSQQ`!gl=%7CfW=miG%HP;1&=EIyI~!R%(O;
zM!W`urox$#P&tj&N~pz*3h!wbV=djyA{2^SzIGy4~`D5x0+Yib5sW#hRk8dVnEzu><{db76rt~MaT
z{`vDz^aNZGXv<%^d-JhbW&Oil+1=o$-{cCoSN#lQhE_FDOG*zhHi{ml^%V!gcrM(S
zZA;PJe@pUyC0Zr#x&Va~d8=_)VoGK0KI^nau3{GZVP06mdw?2i*Xko~IK*>1ck7O@`#BY@pr
z?y&>agN|PgWD3Nt0j7{Fy-eI;DwdotU%u3AEKpqk^Y2y!|F(yRPKa98pL)q6VP6&Ksa{7UTfnOOo>2DuwOGW)W;6
z5Y6H_dK#u!@_&g_0cNt%v4pN(a?r5^+|xLlO&D^-+~wMjIFS*e7#TDWmvl-(K?8+B
z*(2Y(3Y^DO5aT4+qbosR@j@Kr2$_tGJ;+95SoeSnk6@K6=m7E(s5ntLa9=9XsMtQ%
zv1<92B$I;oCHFED#246A;$+Ur!9nfjvY-xWc*t+lp~!I%;ad;_XKZtwpX^In?1xyp
zFV&`iXnMH$AETz3a7FvOdMV#FoQ6cWC}L%f(gC6xQ__!x0>QOElu2^Wk%yjxpM;nu
zGtF!KaH(ML<(8E-qmo$)OY+;W>9x;UI$)XhZ!}Nc&-(`zy>dQK$bI6#p>&?uxAG>Z#p
zn`+m2%-!hErUp#^O|<+FM68)!tFyU4Uy(t@>i~Z$4J&INvUYKuAo(D}FIWvFLMCW7
z2se*-;-muaLqbCgYk#Uo928LcM|jA+Ec|Y(tIFFQ(7al!>}C#PxJ4|BFeI5LDp;jG
zE}PbNiL^>X3&Wnq0v>P!5Ggys1z+|1(+ST$s#kCSZW#K&dG7MUL0ylXE&KfQ
z8?r1wTiAb(Ud#1wOVq)_Yb{{wx?Ebd7X4kZZK
z>5gX_>8}K_Y=A@M-1j_r4f)<_8RZKRfr6AgEpX^e1uLZ32*Q$#(-6)Lyq;bxnL5cw=5Y!ZS7G4Fj7e?foQZIaPF=7n_0S?iD+gc{kN5pCtg@%+{V?%tV&fd@fqdXdxMl?|ii&u0p~A%(^HcJra<=Sg)b
zd-Ru0(n}?Zg`mBRLUE8~j{@th4UKmAeAv^m^g1Eg59d83UDlHm?)~W?x-KNmQg*FD
z*7a?UjQ42SqDEOU5LfW`V*Bt4e}8n%)`iXAKj}3bBPM{GvIAAbZ4STrh-%cVREv;!
z6#?AcKR<_he9E5QtN|aShW(z(IDdxM@!vU!e}UJNo+M7#@0QK+7nx<^$_EF$vIiE&8%(?%Hp-zK*?cJh
z4Ak;e+JPeiuOoDx3X$iw{Q^?gM3dt*-t%o=%1leG^*b20q5M2-DJ|8#qjRK?Plk(>
zqmy5*lAf9UMu^PUz)jLd(X}&`)aQ$u>(Ha9Myu_vwS|B77@ZGM!Y7Y}H(zA|)=g7_
zrL1ZsoIiX1-s}Kh9lHTb2+TO*rre{lFuA6@Q=ktqh@~pN6rNcfz(#X4tdKG!dzQzd
z^QBp0Y57x~$J*!qI1xemu8r^Kw)fq{8BQl-VDPSboaD3+7z#Qt8t^g8Xh@uy>TH#X(5CrcCD7y
zzm|RYJ6_$ijJ}_vLEH|{7p;B_;zJ3pCD4AQ
z&YLx5`|T9toCQ@{PHxn#vle=CFUrMLR3i1vbozt$@mO?TZPxYgqo77rzh{dV`XW(m
zxD%`-*%=l8zPT@7!EM+BnhzwC!BbDou;1_~4`@bbxzx14tW5(=XN^(3Q-Pv%Ih!jp
z9pIEl2tV-IT?3e>IvCv%d8MR37rJ8J-h6fjJQk6P!ROc_ekS*Vq-zW59KdN9A|V1m
zRlyZI4HKZ#2H|G_sC6Ln?MPi{#?@KGZVv`?y?jd)*l^6CHE_OS7>^+p^_c0xWob^I
zeht*+6w(){u-OhE2o!a71S9Kb;{gxg%l)Ao2hpkx+|3=#68FBHA9U?d$K@wGuYgV
z=pdNhDY=wbhV#=`5%0Qy!Uk(c3fVdY?_@^?_Hi~ujK>t<(|Rh0Tk)qR?ahE<&;n
z`z*fn`#lk&SC5+?9OGqUo7z8=!=tbnPB+?o@11~U#KdSeZ*$^TVM%w55J=KR{x#C>
z!~Csaq)P6gs!qtWcNWs=dAq=#CqED3yvnh=MG=MS-0mz}H+1q-8-|?edn&wi+Wk4A
zB9_8aJ8*t5MXA?q8WUGiD53sfWXz|R_px{}Z!O*UTA-%3*kxjLvR$G3&jZfGz9j>m
zq6nPW8mTWkswJ8LPXCT{^}V*0p(Y}cD6S;QPB9JTNlE;O2-J)FtqBW
zK$FfS^oF#&-vK?9+;B0u({$)6H!?rwKJyCc&JP|uhzlFPu?{tg0pc2yZPv?z7>G2m
zwnKcvcIiVvyv_x#zQ_&ei@H(#YbUBjf;piU1h1c__XYo
z+7f94cfJuK1Ak2La%yp+t_m|n*rUk;Hcy0XFJ=boJiNWgxxR4Oe;$9}VK^j2@bGq#
zVYcK(!kz4i=>(>_;{TpVU9^|pALf5tSmZf)O)j7QaO2x|@U-D@IGsoAXr!7UuflG}
zr9yw^__+^A8`DWZA
zstB6+dJqNeL&ckJC(s$E&z!++RLw=ug@*n^E#1F
z71s1pqLErq05nn?A}zN%g$~Z1)t3Xc;7X2kF?Hyx|8AcTlB$%Ko=U|ve;r)T9>FV;
z2c`V<_6CA-z`jslb+0Y?1m8rsm`ZG%fv(O0izSOEn(A{avVP9bCNiyq9m5Mv+l~C?
zV#O3gy=r_H&$LpRwCL2O_-;`|9PO3_EYmaGhO1Km+m*C@G#vJ*I!V>Q4MFH4*TIh$zX@U;4lT
zV!0+l@PHr}J3Do^SFNlF_N`iL9$4-8hy-+jqQsC#3XAWOHgKuR(2I$5+KWU@_2ebf
z@)^E@KguI259Eej=glmGJVIF5DPUo^vHj3)RR{!ijfwTQf1`&@&+XB}4*guM%@V3F
zcbiP}t2VNjuv3jIOC6-C=P#p3kl38_r$c49($I`8E29zlAFefn7%dzA*=nzW0$aB
zYa0P6GKI<|IZEey*RgBTLY+6M)$2RbW}Q4n^Z@LRz}%w@KY#vYkaSK3VDTDStB}@u
zpr3(x-F9uW3EV+k(2!m@L4zbg%5eH=uT
zk|8fuw~B3CKNo6uz16?7&_);Of(Oo^3#6@O@KRc%#bI_q8c3>M`*i|YwR1JQ)zDa(
zigft$_7po9gBCgo!Mg{%W&)YMAUBesyYLAWD*?x;ngvUqLB^}lUYs%cq3QlsUCjog
z_cw~c1Kvg82VNR1cJ_=Cjgj2!tBg*mazEA{04+^yydQ)@Icvso*o`Rm(h5ZC=Ow9)
z)FQkzJn}$T%&rlP&!k4<7j(p(MqZpwcg}mc`I~qLS1MM4_4h3UU!?^}Zm4F?8T`^q
zp{xs}!zd-r3W_pOyKX`P}k#OiG?udfcLz>$u!hnxtQFfm%&jML|HL953Nn3R0z0)gogu;
zq@Yzc8+i-_gk-PLaHWORS@0Ai4mD&bK|^5i_^}Uh)`Qy^dh3xkJH+x0!c7*mb0ZoA
zB+E{M>DAta``W!Alp!69Uf{5#f!>?T7~
zt)@YXRY9g^vMhs~UnL+JY=c7rkVXhWh;;aa2*@CG_p#shvH>*nnL7_&=an{@#Skrb
z)-`)+`NBXW(92H+61zdhDj3Z9A^NF2rbYxYJ4?vQy|jY(qI=`65TD>$j>whr{x4x8T=OMA7#&bNBJ7sm7M2vf`q^PW?ZfP
z)R!QS;rY;Spo`nu$T;UMz(It(L`-RqA3y%&s8Rjw>C8ZD{;Sr^zwYVZ
z$$N=^QuK;oaReh{be_M$`b2kKPu-iLp4(H_mtQJ@v5|Ip&jI*mNRHy;N8#F-PmTvE
zMx&sn$%5yIfN-A#-KQriB;n$LvryT@(R77$^LFoQf=10L|2)9F#$`h1wk7`UHS{3O%Kzj0T(-8tcl3c;`iy`-y
zTV?
zqJKEx6%BOYrV8HlWjd*(g>=}iiURNbFPEbfQ^*C@4-3cs#e0uc?>ox!@j=wy^q1Ph
zI{a{J?^!pDCw;A#y#Eufc`bU=
zmQna-NSxT%)91JpEA`$dC!5RjG%|7^%rail3VA{~cFD{nB<7qXWEqE1WzzTesxxS<
z;}VJ%FWXvcCm#xJG@q+-2quVf^?l!F$o
z-_QBp4rbU2Tx37W$#Dr9;Anc^y?!1gkXv7RC2)I$HGgM~9qH9g`*xb08eLKR9Qx4f
z`-*6!oGptjoW6gi;^mQ&>KCl*cQQ8`rWoZlKYZ)D@4lnbuvbs{oH>grvgNef_KN*(
zND8@{dfIQvtW_Ywqp8;4T5nSL~
z`$sQcKs}RJ-8{D|du;N%HqJ8ZR+LS@IOp4Ov3l9J{FW+}kBcZ0
zImIHDf>IT5St{k`I!dVK;I`eZ%E?)qU@P9S8$Y~JM>xd7mm*6D@h{uT{=h~_0Gpk~
zMhXMoIw~4?>lWPXWkq7?q>|g2vovk*Q>Np^8+5BHO_;AXy8V82V`o{gH(Egd({mc(
zuB>%~p81jI_FXE)Ro-Knx6}z5iI)9ky07!9dFrCg$)6U+Vr$J>~x8F+*i4l0qwr)i=093
zhRj#Ax_R@I0l!vmI+k0g4VJe*JuR#ruc98`Xgh2M&w}vmQ)2C3n@5JWl~SU<%CaHZ
zH&IG|Hh`80eVx`>mm&P93;Rd!bQ9j3zjj;r+sQAJ;MIQ*!Yt95vX
ztM$i6;U2Tii4_rR%bHcQ-s&x#l_RW?-pgd^DJSh!C|nKfIE$jF=O}3@#T6qss`yFb
za^%e0!9#kD3fIh0b6!)&gcRpg$lN3hD%A4IEH>?69$uNuMS8eeDgZ46xE;>SCqh!1
zr%s@cCSJb2q8>k54K5l!qev;1KzL5iJ9zxlT1qI-&&Ag5EZ*s77cKiM3J54-9PxgNjv=N(8l$ci<=MWn@waH6bggFF3S
zaiE}mx-(DEu8RkHf?Nnw-`H$+e1Hp&jTPDb!we;Sma87nYI7nlFyT9;)xH=rAMNr@
z$4r%|%1QlhTm;5@Mhqy)zCu^ulSr)@EVUbtHW8
zecdR**kHw}CJLUk#FU+Xk`+H9w;O(pQolWtn^c=JI*}Zm;c6oZ5bvuf2A(lO4Po*j
zF-|PMB_TXhTOJ6z4o8>OK^(_aho%bw*mN{YC~%F?%|KcW3`BuZ*|`EbiWc6Cm09JQ
zdbd@3&6ca;EEiMqy8p7O8Wq;(=cQXHL8Em}n(DUQK$JoH!8Hza(8+aowJ%EbEno~=OXDg?SwhWxAJr7BKz9+p1f%6c(63sW1)E^eVYI)m_u@_
z{zJZ?F&C(3o3)H0nukCEsPOfMt4>4XBc1w@Q|Ao<10Xiad(a63y|jAgCm2Mmf{{{Q
z5SwRGrUL}5tJ{m@iNIWAU6z8Qld1i)yzZxOoy5l0a_=q}@AYMSe(jNsXx_wB&a7nk
zdZMFKBNgzPi7Jxf7T5kjFKiQ&O{)`-MsPCExUY0n^UhiNmUV;BeLnU>?>{Cg{8rJi
z)gl)AdbeObiIy}+BRE3c6B-Euo4>vuXBJnx^XLe#CArfl{u4YKZh_VgX@Kwk_=tO0
zFDC}OZ`jSe?8Q7@sJBc1^^Hc0JL=(^K<4+Bw0iVguebFin3Z&vZ%t><6!ln^nQ%}2
zxn6P4B`kZ|w`q1LyvCDtJ2sLWZy05Y9=@t0*(~lK%FUS>BScESvLEjx4Nn*1Tg?bz
z8*-+zSnL{Ov=I62(Rv4Xr*G(jb~*nQwB+Wp?!x0^q;z&LIe&mg`G9~QU}qS=InkOS
zt*B^KRTCr8IyxY^JN5i2^t>+o85KSAA~c#KHo;6{SW?hx(W)1A5pMMVq3u23x$fV#
zacOIpLPaH`Y*HelL^fF=dsRkc@6j-lotaQsNs&D>B9d^0LROi{%HI5skGihs_j~U9
ze(wAKyk5`uRoD2=&-e5FywCS}9_Mi!CykKcz(gS3{FUtmfwe34WBOS~Y+QO=hM$IH
zXEzw@`To2v-+W2pzGVK8PMhzLDOFsjQOrW)rVSJ|=R6H~W)>m?t|{ARtV}odw-K%mfbvQ2h{$dn8o)!Jt)wCX~1ndLiS9-fE(YllpZWWP+qG
zfVg?0d94_1x`4$u71)>%woZVwn&G(h>h^{D*1@@JPZ_4Rr`8B01<^0_o`Jx5`<08o^`stK>IN=h5pc%3dc0*FhLtK7G~
zohMAa@K_y}y)~!P%RcGsQRFRWh2#B`~77Vt&+E5=n8p3@-Ccn`&YhBs9
zxr}GO0rKiv`;f*K+w}1hJL*q2zwdZ@7p<(BQ08U6P3Ox9*Oqw-tg#8?@H4_k+gX4*|
z2Us+plUCYo>S5L>PXIAY_RU9NY3RvkJN%reL}6K0Fp|^O5bD*so|Ek8
z1YN1aZFM=hes-jdQG(BT?sb9PSSpy$ghUx)*L;`c3_~WBFnWnrmk*#FJoxU)?
zZ7mx3H7BoP91X30lf&HWt}24|CW?yEcNiTOSPc>Nr(!Na*GH)uOg91<_D-+k9V-O2
z8LV}}q=3!{n#iA^V-`530ch6P_?k&2_3=S$k%XACXZ!{pX3{P$@(20ndW^#*RIyFy
zIrP~U!qssj^~cw$_JGB~qe5j|0AIN*oifta5!;fszVL<4&n{=o>l{nW3)9*~BNnC=
z@94HR89JQmkrr?p-4;IUo4X67eYMftwXGpsDZGZ>sXiv-)m3`A%xjizzix+kU8vR>
zkDE=mI72A7t?Fww)HEEHu;MZ`@7L@x{tpoL9)5mo8Y?{kcu$91r=MSH^V!U))NO4X
zs!qE7oJe7uyu6zE
zdaX-wf2He-z0!Jf^_;E2$JO`iAw>F(NS}P5IJNN{3u3JM&bhKBxr;dK!pxUZ#8gPycy<_Ex0IMX;xp97|NM3
zJH*(Q6#Ieu#?jelqDyz@C|=2bXexRXe9%BcM6;ozvr3L_oPXN)6Kime)YYM}jYXUj
zGPJIMs{@`@yOi(XdiS6v$2`_lJ@?wzvAH>YiQp8M#m7U&9aq7Db{V-!kUP2}L+BO<
zVryDPEOT!TY4-#N8?1Ie2q`$k{c8*osmtGpfENT_)CoE|5l9}yJ8XY8ogC?WqaJKs
zi>2LXnb772@CCMpQs4uI(GgTcfFqJB=9L4yywHNIh@aYFfWAgXt7&qi4ty^^f#RBq
zKFV|W-w}Qy<2_Z&sjCU$S_+UU*ubB0z-2cxx6;op?O+3enU+|S1aTx<898R5`F#hH
zB_0apg6i_0s=GB(n>4??4?4N3+ToO@lw;aCQ>Oj&>BLgckzl&T(%XXz#!-CAUvh3v
zv^!@u&DB4qX-i4_AfKCR3QjJe6Oa7OgkEXU$5WjqByfVNr-mbw({i3(G(;>&yuz9f
zE$W0ZYvxhplC@K=t3L7Xxi7pdt9*W2fh*Bfe4q7Cb6;D^xN)@&MF%O5J9&<%I8j*S
z(h0PyeiLe5s~214(u7G4L3}gCNYA9%)l4_u8cbgG`(zHG+q;#UdGO2UwLe^AFrT_z{|8lj->ux-0ZxL3mG;im?*8)yGuQbJ!1K~eeq
zf3x3Cgqz5T1}@TGZ@(f^le*xm@gzh^`v4vbmuNpK}v>XH&ynFc>ei;=iV(r^mTq?LrZly4F}V|rp1Z7`J2!(A?na)S+$&eNZvyx+%Y
zu-F&QQWX~;t`+Rk$iRDmRl(pPgC&nKU0Ypr##qZSIlqIF@UykI9u>5rV0@=!Z$d8|mvJkMD8cNP6J6+EwG47M$Y2~h~^dU0#~G8
zzb+;;Temz``~H2jM8YLI!fLxK+!E4&)AzdmJb98!;Y;_sjGZ(gNh<95XH4JQXlsJ-
z4vKroV-^#r?uXU#H*XI#8TtCrW%||0?{KU$
z?a;6q{c6vVg4dRYiR14TGZTXsXTy_#jkzvJ_?%@=Ie0o`2~IYz&7!3>G&*M}
z5DZS%M6mSlC)vUTcE%F|1a|>JgRsZ4of%f!t9Gm^n#HOY8D5cAbruWz{TDBGTF&
zvImr5B?u;nBJ7ELthJ+mBl$4`PE3F`A^1T?{t8@T2rnuV
z!Y7pL`5Iceg%0|PqlCalCW7Mv3?CH%`JZ-Ku%4bw%~eX0rKbLsS{?EUUHepsadMAF
z5wi+j|Mn^4AU-FfBNtaKZ*(2YEcnlCC6CsK{pWMA^@$TIx8DW>N2#G`xA^e-6|BA?5z>aQT0y1o%Vt{o8|Z?I8Yh{W)71Y?+kdz(N@MqSzwjckEYJP$>LF
zdlP~-f}lmD%&=8B`Q!^}IOE@Pb=JUBuZcD?s987AIU|zA(-0SA!#carb_8-D!&9Mh
z&}D+gMcC^u!?ao1gKR$(T%ArH?zAiSqh-dqL?x`fUMZ?`aN?dwbYQ%KZ^#pjj%OPtP{;QZ)(G$optWnCmCPUA_aDd>)+uP?Q%EhuJHLA79RI3!PczAjq
zn2*(rV(rW9()kI1&J~ITE3#8Of>I#qh%qs;M?UyO3sQCMlL}(YOggjsOHUZnms!1kxs&ybHD9A
zG7*k9Nf1%84>OQ^;~21_6n;&e{!NhA%DaUHcS{Yr4~2pOkW{`vfy&EURKV*_C@N~i|lwxrln`<|zGdl*hD#k}ukZEba+(q3^tR$48g
z9zbvW&QAftO#CkG`jqD-No8kg_D>Tu{eNk5yaX*CEzf4_=7&^pL?%4;GTKH6$#203
zTqNYdLdtw81Wgze2Y4X4jd0zi7Iap{B8Q_}?E^CsQQ1$+awO+3Z-a$I1I05zc!)|s
zP1Sd-K+s&+R1b{HXiAw)~k@XOA_7M`JMm&nD77eB{K>?6oXphP9b
zhip&zM;XvqXmwcqk_rd3EK;>YSHs41Y50XN^G!C9Y`LciB&mbqUF7p8~u8
zcZbZqG=W#ANMQ?gw2pCNXh=rR7sALETVe`!zZaLE-hp}l
zbM&eYT%mBUA^l@K!B*zJZhb~HS040W(rtuIFucVEtWw-zD7a=?3bWKo+EEhHZ2-E~
zV!~R-hWM}l*Y+gDXKdi-igW))n5C}Wh?urT92e_s;V`!Dm;lyww_3%;1EIHWxU;dL
z>@L(~3T-)DJ(UvsnR-)G6_X77sF_)>(oqYtgtD`DI3#_9&g}l)$eOXQ^e!v;FZ~WB
z$V3?sMft>V2ea}k$7;=OSH4%?5LXBuwar)h)br_NO@qo#FRd-x8jq=u3f?t=afY~M
zhS{w`<&TuhP~7QzU3~cVt#w(w+!V#Ts+5E_R*3=zCP}y6j2$HICH|*hlk6@PK2Oj&
zwfk6VXx%rSmy`}coOwAtWT>Z~01DyG!-1!ra;93ZbD1V9AU*w4
zA)KwjpPH~c4Py&c%VeNG8|FzgW?XwCIrOKhJ+>9pjeI#))3Dd;VyFO3$AI;V=$Zt0
zy&9Fou8W77{So8~Uh%AFqFl4vK9`PsdEIM}ZIjPBox;d_QWD9}1UQO=^tBnpBr?3OZMA2B_|n5pOCX0wCl@!q1JUzM+|
zI9GpPR^+|)KbkN-_bP^7}}I4>^}_>th6KBnPBk}Y)A)eRpb
zgXvD`Uo!qB8O;4(8lFzp1N1+odq+BwtD!x=;ZxjTz)+h?|2v8Vz*jGnsvl@=%-*d(
zrDK^vXQXOxPrTVRPY)y5M@6-pot}~%D2#}aO`@fH^}0>*cPHSt+r{dD^-r<@#x_1J
zNol2foCh6)j#7{ub(>GzeV~cLy%cQpbz?+t84X|rXk{Xs;J3dV40dh+$hcZey{0q=NqIr)i#(9Dl
zn%L1lT1YSPB`LOFqq!jg9Q?t=s5K7$wrvj~;OMiJk_zh;tqJlw)NTeZ*ZPdC&t~;m
zZt~*Zbji_;k@}j&N1Jo~KS~UMelOHILKf6?CTf?MnO%NUZC^vhYmViB(`i_uWII&!
zw%7x3j3*{00Jc;BQ7X9&K|cY4KXSdAJ5m7ItN~koex=@=Hi2VpggAaOU)eqWH=wVT
z@V@|kKgAC>+rm;9XzhMF-jx-)wg(u|kvF&F3n;1|O`PnH9<}3(l53Q6%)PFx63_W4
zIPi()nW)5s>P}J;a(?6-NWn-uAsBv1hz>nTgL<#UuNN@u>N+92R@%1ev+Hl@Q5i
z7b8%!iY7#V*x0+TCMq=9XMZN!H{w7zJGmGN3!Lpv@!vX1!75^=Jhds>wVt7;+HST)
z(sjdYf2UP5gEjw*K9(7w(2#hh%I6nF?mb>Q1?}hM=kH5}OV1%pe+XlZGIDZu=8yGX
z5(R++#PM*r50ZlyL%t!IL@lCE;N@|100eHh6py!
zhbmE;fDR7wS>O0M32QvVGb^%)+Wrx>ga;~Nvx1YvwM
zDCjC$5Lfd%jQgB+(T`-ePDzS;Zvur^{rJ$QUW3!W?3;x6H5k?Ms7XkL|Hc$kKkWX6
zR>4z*3BYB^aO_`z!zPhI6ZI6)Mj^iE3`QvQ_8MrqEl(%6!D2L-D6^Rdw$b(_z{&1?
z%r*Ib!cKB~3P@_z-)}unw+k|rfQ~saHLu%;-+Z&r0mXdF4?HEyVgIzb(lb(qX1f$=
zQk1Giw*{$}IILPc53DUvR&mT-{dxVC5ll=I<>eQ|?DMX{nW8pu_l_;QR37NP>n)u9
zR&P|9Xv-GPA3SQoH*JJ59ch-G-&!Bv+u(BWNLpKFzSA+plZgXVs(CB~vE3X4Fm!p2
zKPR7jHT}>_SXj70AeTjoM(BX@QJI}%Yq2BI)kTdWxn@E(`}FkBzKo#v
zej}Ya3hT!@wwyBlM$MBmKzojWjp;C@*dU+X~KY7GLuu*p8Qeg7c2k*w4wU8(Mu#MCIK~VmIZ2BJb#Jc
z7CWuK4~VHz&T!Z^`Jz{mi4d0>tgN!)e^x$^X?t~(>W-9V5s#bdqhlvx)NQc;*cE1%
zUu*Q_c9Y}Nq;oHsZs%3zywofrn$Wpp4@uxE(O_d{-%u2bid{w1CX@i6L9R1~s+FKN
z!eb%}V@uwebs9242ZR44V6<$#cVsuaiZwALCg@e*>YhU4n#Xh%0feWoc@}YJ%sXFt
z(Kw2ObF3lqt^2=r%arAf;Z?+3nhcC`a?wmrR|ufVK!+X_z=TMeYkr3bUEN@(Q{(2G
zz=6kM2|O1s(n}yKS8PVSUy+c2m*I~?g_`OO8**r*Wxpg&4xHxWRdT}+MHuTBTz56miFc`n?R_BqHV-YBsbfS6%3_P@0WxA>dt;
z4l|fG?(h~bsc(FgIt^oEYJVN^V_A8v)$J^(lM+Onh3a7&1z;EF1fifn&+
zl|iL%kYvbv=Z~$KAnU)+YWB}jmhf9##V_878@Vmroec*<&Hrmv2ZCQBdcUv
zKW)?1&3{xpdqLd0fH(TZ(D?H_PChfWh43?f>kZm(swfa?w8)7VVE(L^93GgkF(o21i
zj$)9B>hH>j_uv5SHrJjsi7XbsUAvm?g)%s_VW%Y38sdcDGUkv(r}bjt(+*N{!C5|Y2A=IbrxK+L*IG(U{ZqKtIe0|kaWkduaws*u>wJZ$V0$FpY
z@{oBGNTR1Y-s~nSq1_tzI!6giq=WGY`oO@oY@*D6UIjMQ$1wEt{f)MqSKub9x76av
z=iQ02kx1>~#0}0T@dlt%qDucS+0O_)<2Nh~z;SFsO
z{IM-`d3NEQ&I?W&>g-?3eTn=G=tb6zPqdiOr-WHFaLtwn`h$@laj0J9q48oFX26oh
zqIQP82B{XPzeuK-B?vx%H4a5W0oC&q2HBBcYb2gVPIz3Rp3=jUo^b!O(O!%uV
zLv@D&Hw*yPwtO4nxgioM<6&`rGV9syrl5fp|v8OWP%!J
zt7vtxWL0Xp7%3ayt#9rGq)9lMC7`)p5r&J5Cq1zp+7*
zb$0+d5$E{#?H1?%FPM*be_&cOg~QZ#?Lh&oWqlt8t?>u*UMBp~%tiA91d9a=G*St}
zi-~FWh|b18?iUl&Y5yB6VgU0FW5%G_MC9NfV>IWEl95U-Gw<$-S-*EhVKScREQA%^?y^Sj~#X3
zk9lhb->KXVTlJvgZ?|9-oUZ3Vn1g|8OE9-B*SOqjL1QMEC$o^5hDLjExx6*IC}fG~
z@-PehDqSxrE`9=Tp^&X^c{5peZfW?yvEo=wu(^96#vsmVo`I-c$fn&*NF{uhM03gc
zf4h79gA9QsPD@=n@%?)4kM9Dkd_Karh+&J0-4f
zF!t;TluI|@4(!pvPyFKZA9*}pKPg_5({HgSMvx)!lgjGf@;Gi;=p}ZTdONE3dw@7+wf@RCf;|=RP^O-5BKKh^2dpJOIWJJB)=&j
zPd@=U5?V^-T(ge1W;DdpN#0*KKpZ7}*Vbff#6Ge%^blay4@~271oeUJ_u`s3gl&hY
ze@u`Q|D1)a_%i^iZRx+wb)P)>&{1C+V$JENN;$(`xmscwx5J(fod|Bep&lK
z_d6JTyUzTtCl>}|&PB@-x(R~Ig7jotlKk2;o|F>H{m|K4I$>=PW+W5JKzDV*dgsX#
zEN>FKV-<#IOV2D|Ug+8oQ9N=qHt4oT%@=4gw82%#_|1bS?%W6-5~&uUKV9C#SxJn#
zBTzOiIBN@=V*V&@C$&60C3razPLe9xE;h$>6rNr0u4>RYH+|Bs}DY%VXN)
zIZ^*~iGy@TDe>Ea{Uxs+y~UYoTHl>%xbkH2U&
zX23r-@3@*np%qvc8=l{@Gg(ixwf|$#@>dhgBV0;Do3#~YJUPGJF4#2Vf81!rOqw?i
zR)f9O*6%R!|oo#uh|b_O9xBVoRf+M=Iv+ug!gZ;{Vyj5<*x{2!)D@(
zFI8~)F$XufSA&g)2>XMxO2Pj&DJWIrApIb{gq_3-`};Pb!CCSR=Ox%Aj!5w(g?ww;
zB%xwp;Y&X#B)Qd6Iba^-aZ@jR{BRTX!%OC6VmjO=J~R52vqx!i+g$
zfa kbZmu$+TMjoIpC5!UTlaoXU01F0m=wCIt=440vap
zw!V=_(2==d`MTsk+QtYcIW1fE&wLU+bT(m1S|`;M-99TxSV&g)zo1X{igyf7bc&U$
z>yFqQvX{T@Rfum&iB!SoMOEnr4GCwZkaJ}dnTMq9<<{RdC(~WypNCbm@sW^cz)?(U
z%`6H6Cs}!U`Q$}RioBAh^$Nwb2?T^5pG7u2`J=VqgQ+)m1}+M5*|6mg%!UB2&{a~1
zyEJIqb_gx;n^78|;mSPHSTX>6S1bEP@2&T5%wv^O+hZ3&C`r2_!{?wddUta|hM|?&
z(h;}!aE_s?#@Fv%7G(ZCmn?zk1!DtwJXGwFl#}skV>iK6NP)G!fLx
znRaPP*)O`5H43bgNAm}0V2CtlBYh|SR)WE$zDo`gB`4`8Ut}mGu3NarWay|TA)z8E
zc}{+wQ6ihZZnUp5lsN)pdhPd-={WW7Az`Tr>nKi(b*p^c$}v{bwIXxEJ)GiNTMp$F
z=1MuC1ophW^c)w3yNg#B$EK){cl(?%E9x6+@^yFd@f@^MPqNm(Xd
zy4j%Vx9-U=&tgbbFcz4pW_G{vZF6^Odn1E{6K{90N>GIiwX~VV(#^%;?M)iL=tJ3JKvB*Bo}SnxZ-40;I?|RkZWcnQ-~q*
zo)zWbk8R%SMblkwJ;m%-SX`>S^PaU8<)B=M_$qn@zDz-vcUj`RWXb{@
z?sBnnf&U&0(MxYl5|s|tJi6YSy}u+N@{0D>w63Y5{%F<6xwevqmYBa{to1Cf`3I>t
zS~XAq;IyI1SEEWGW7#thPsU>52p7gJkebW-%pfHm2V%{8l(uRM85!-_vuB&@2FAwZ
zFgi7(NlaXPOL1{=E4locd{=?dGq3XY?ls%GXeg%LoQmtBqcB}Mg2a7fB-gy8#GARM
zuK9|vwxFQeSj~Oq`K;fk2EZNi
zA+4y-?%lgfVI=VmGr>)HJlL}b9oKK#u7h%roJBPdjuV{d=@tsIYZrgSvqbTIZr{Gm
zee-L`n{mY-W{mUX!YQ9WAhX}Hb7$h^r@|OE)t$3nw>oL}LC-R5I+$C#4<`V#Y9moB
ze5KArU4%}qZ*DFR&^cWs%aopFz@Z!W+r>=P3+34i-m&P}l(TLF%xI2-tGI`vH3d2+t+UGl!6v_M-`|1J2z2Mc;#`
zeNHMSz6R{s-qA6L%cVO9z(+7d#}ClW^n$Sl9I2^@+3RgFb~u)~`T2B==tKfqfecVB
z-_o#q21c5`pvaCx;+$?ZAPcUH6oB76d=Jm6vlvQ^lBoujZR=~@^%z&ujh~?QmJr+n
z9B}M%UC$I
z%f|L+uHV0&ZvUEFb=F~TTU>yi(`-jutV+da!zvSI2W=zGjU2~ac+>Aa`jlm?wU5Dy
z@zv1#kDQi=plzTLNW>YtxD}TuB<#J=-${NdMv)1@`l!42a7U5D!>#)mIM84R1}X}M
z!H65XzFkv;%3l0+zQi!cks^lR4rLp)|Azsfcr`72FZ2ukj9lu>1H
zRKra4{+sohDOXr4eW@;@EkD?r$p}I(Ci$+zaPduWn5o3fbs=1J$>4Cq+mHcEBb|@s
zIO0bg2F?njVh1ty;Hm3%bSF-nC|{l$?TEr4Zuw*dddyBO1uW2-bMp`h4s0uGB{PJvLj>BZ>GwmAMYi~{Z)3~o(FX%8~PM&k|&03JOUrro2Jyx;zN|%JbVRXez
zJoAu2KV|-D0XxkA8pS<(2A+zxzZ-l5&IaZ+M?#GI2{Lt(w{PF7=G{6*IDi~JOnq3u
zF$7jT0HbxAX{f1XqUls3la+@`hR%ZTbJ!hMkUTCmBHV6cFVeAFLeHZdpoC+M730XM
zr(IS9-E2>aVSbBiJVuW?1x*C+D$#XC$-RUxHEcT=H84o-R|0Z>G7Xb-tvBITJZ6E*YM_C
zShfl0P;=Ex$?65BP*2+VhMQXI_eZkL++6rGudw>6PZRZm!-cA=ImL%^bQ~w>1esX7d7kZz#O)r~Q-wqjUtvZP3emdU`IRI91Iy
z-jD0a*4kbpKs(S1{EHB2+tYmP>}eGSL0(>BdQNYTh(^_hCHy`M_XN|lOJt#R2D?qh
zr^nKYbFSBHzm*xsA@0)cWN**fZl4*xO*iDcPPKS`6A2_Qxnn8H%+e1w>X&aiYq!&f
zeBQjLHj1()Ot&CkS8(cb#(EhzEb7jG-wf?vIyB5(Z(q@pqLEuHTdSm%bZKd*$+UTN
z#wFX#&nUfgVLG{3c79w;nukZ+@YTB_gN-^H53V~_I#1Wee|x5a{&^UqkFX1<
zw?7NLe8wVEG>7KM8Bk2#f^a|bHMpz(IlRm*K@vl}QmjzM8*HE6Pfjj^Q_>10hn~8r
zDGLz!j|#rk%E<~I0Et?%4W|bJ?<6r^bIy)xb6>amif0{VW1{YGSHOJf`papZZX-ur
zz195=ss^W3DHomX?+MTs5z~jCn)h;=YuUs^4dp<+zU`RV>Zbj#w^Q9QEF=B+LOFe9
zYTsForzg5Y_yxYdqgcnG_fC88YK5kV(rtQ&I-u3W5<|SzL$pwRb;YZ4AGRyR7fM({
zo{91U_a+uB`PVq#r0dt8jPkeHPPk9Rz#9{R$LOyo>$F{__oJwe6ZRmB^iRP^Gz>wC
z#nR$3YM>j<>)E-ovS<#V_YxR+TR@q)>;@-L1E3GYj)j_>3+@A^C0yU&k5B`|mx|Yt
z4t#6<`WS(a(dQ`McPf~H=d5?nL)Wy^7rowy*{%SKpX8M}HzST6Qx#hLXy(?_E$VyG
zi=+OrL~Cy}+rEd~2e(QUB$!cw^Gw~eB~Ir>p!
zV%e8hlu}{mr+-?k-dI^VS9yDVL@2YqY-BK(yJjKB!tCnUN^)N46JIf!b?j+*u8T7s
zNiiQ9&bE=HG3Li|1ld~!=kUy>S-#-7y#GXur1o9+Memfyd|QS|MmHFfdfh&jeE8Hk
zLC?DJs(bHZ<2ZM3<-ed|7#^?f>M+{R=qN2J^7t;(Yr1;XTr+A|F2zGgE*--k2@w(q
zQwPMnHkQJKwhUCkIwDPhNa99E!D(5;E5=Bb_3AI2K7ym--?+j*8+Bmd5PgH(iiPP}t8sm2>0
zWEyVT;}jhnGsE*~tgp76H8{V;LL%v2+C83Y5^cf?Lfjq?N(D+6E9l?yt-Da_G(NJL
zXz9C^|B{B~kogm8i>+zq?w57cFKwoq@6V4)LyAiFqIB<`@{d2rKGNnB=QjP548$D1tr-~c)E6<_Ft&he3ZIb!ZOkwUov*e#eTahztlaN&YR
zk$q5UY3X7AItx^&bKtn$K+WT0^G-uXT6%j;IJ@0^dVjdZTQ~iikV#1eoMvF~go)c<
z(4V2hf0$ay~LU_zjxZbbZRZ*Rv@CdOT?u?3*`@iFg1fRW$(`zt{s
zQNvb)P+)C+BYzZWRyX8gL_%uXo)-irb@+-zO+V-YxY2dV6V)6XYbwA1vtOAXK!TDH
zS6(f@wQ-pke2NbkgC~Ji4mVY!*)UjTrrGsSEF1XeJl^?IFb72Mp?>m%uy*RZP
zXWO>>ig{v}C8*my_^Xdh48(Mmk1+yK
zpp@!lwyNe^(j&uWIC`}7lWxD-U_Re7Z{l|9^2RXlA58bUry37>5N81A!1(HVDI$=sy%ztFmD&2|A>zSD!Y6(|AS;9O
zB(h)i@27P){qq`G8QlF0Ro9=Jg)wo7uicUoako6a+@IUo(?p%Sc2iWu-Oov-{v49X
z<41e{esi^77#N^{Dz@m&n|v7TA;nZL@K?{evBy&v+M}w+J1$pj#F_qcWURVmx@Inh
z6~H*(p~#^;b!|HsR?kpefp6`Dq^@Hk52-DeX$uE|bcP=B6EA+c;m;z-7vGua<-n#-4iHe
z_k@EcEQOt$_&C_$>7tH6ONPv@zeL-6YT8l
zo$#r4o{T71AReAZ-^G9Dv6{p3x2LhnzP^c-)^Z7@f|{-eZhyVlyW=o8LTyxzP6$h1
zL?hVC%S)u&<5BfC{sCjdj
z&u8IX^78Y?5mQ^TSK(TO2+Hzq1qB_^S|J*i>9yA~*L@outwS_;u9~iQMuffFkw}r(
zZsH8~j*b}OEP&EsZyOw`KygMoBJ^$r5x@|O5;2=`oaml#8#UY`_Rxr&6SS-UT;yj@
zi%B1oPQ!x#3w$9YILP>&A_QIduprQS-0Tj*g#sEbgb_Ke?_|u>>=-XAD3=@U+glNlf9*Z~1c-l@
z`@g?GarZyV9j_u5{Mzkz6kvM&_tLLOMmYOBu>1}*h;b_RQ4H*wC3WRIW|td``!e3W
zHD+gLm|wK|QpDxaPLK0+Fz$+TxVwb&3SkVL`Bml
zxt(*DoSde!zn+-fCKahvkq|hv
zr>w=KIl{J&EP$NJy3N%`{grgFO-#UYcZoi99ah=_}CTU2RH-O-!v`Kh?H%JJkGhH?TSjj_
z;`a65^sQ>niazwOFA9y=k*^Bxzar~)-`h$7!QgS2E+tX7`tQ6bB9if=Zf^S3Oj2+W
zX$yt+9%TXQA)Wb0472wufdV9rJN42iOj6+9)gdL8oPk)4*Si@TtEY8+!zq>vaHp{BR82evo^MIHq%)JsXj4H9&f6qE}*jxegQ$
zh!GpKwYAZofK?!1~7jkp$&H)d8-CxOyjN8k_i`Z#t9RjqSKPxF6TqVC$naenA$E@C+
zwA0qd=k4*zy(xK14^7egepvY})}N9%1+!Rc!D1NJeh&q21^_bfbgRLmXhp{E
zxkz=|m>ke8Q98B5dB7SdaErC{Q~U9E6!{L544^*fBLWs7*P2^gO#0yjT^b%i4
zn06DDH-e(U5Of71Z$XLn3tidpKCHNDzlU-^SC~`8Y@QgkdJ<
zSeIM!-hFptYcKUg@kCCKmC#8a&g#gZK#-|6;r6&pw+o{GgJ{a=m)+UOZSrNix71V!
z*d^sI5El5NmM7)F6f(>Vl=Y_(kOT?L+(857JAwZKVB7Enb>+z!Oy|udV099pi(D`e
z=z}f@U4&E6a-xW-1>!?eLEj6p^IPl_Mh)>>A=o&t@fkt)9Tz_vk|CNs&jg)xk
zUz+R>@;5pcbYPpnHu7%|+*T7Lthr^_w4~c@+iU$IU0sXF_vq$c`Z7`%%k4Szh>xy2
z1mA+lvVu3G(f$~z1G+FV6**6y93^I!d@m-nJ##KV5Z1wIx&3CqAr2i9a0(gl{R}=v
zZ~~)bzv!|G@+r4z%U@=z*rq2?Eg9Hvr={&~m#s>(P;L)%)KnUuJN;rs((v|l)6(eo
z3vq$FH*MO)Rnr{KTU@+->-Knur^0kEoo!l{OX`ix?OcyU`RO$FYM1}Dpn{bwE9v%B
zR3k)}GNM}0$X~)zG;srsMCz8%Uq%mE{dndi1g4u5598n&W1WN1BincI;0NfN0$E)U
zVoc^)1tXPCg_c|-$?i@{T^)^Csa_}VS=L-!Ttq|pKIQgpmZ@p_4|>PAR}M#YH-8{K
z+do>j%7
z*AdyGBYXG01qE*J*b!dKdzj~H>K6yS4L_*KXp`R~vU^xACoHz$bfyDtD9ph{PB3sP
z7HMc`R2wZsneaQBwFwC1>rsZ}Ud=xhN_PbvJQCHxk?4d;r3d$)x>|E@?&xTZp}TEU
z&e1~YR^qahA8bs~H6wMP9#<_buh@}O_j@m_TeoiN=jR8Yqba`Dxj|{M|+6x1x)(6V$x2q
zG6uYkxDs*W<<)E^i&(7oJqHe4!ipT9n0R*nHfigD66`23l;t}9Y3!gdMckTZ(%eRV
zl*#o)XXc(g?NoR
zW}a&k2UF_`N$lMGClOZabo#F`6G^w2!7a|XkzJf3o0f`>%I>>=8TD2AuMXa
zNZzlhFQKw2#6Hw`g71-&o?eUfcT#l$fs=;W3hWG?+YW5Id-u-p4Ev2t`D)_?1ogb0
zG_Ag!DWP5M9r-uXFLMr*@^B`+S)Pxz6PJ)J$N}eRZ-6EaFp-h
zddkD(70R#Nkc)I@A@i+{BPAuB16O(9n3#wN5n^H-`l(1T{H_eyrK#OV03Q2F*r9pz
zIh}Fm?p?*K1p0YLZ0pz&PA(7`n?jbr>e3`X{u<3RBJ9JwB{tO_8)SY5_jVdq)xhvn
z?W9J(Ls`WZcWVx8d*JLG(K}WjY0dU+=P$p2T>&DZ7S~N#Zl5_s!FnLf(P=U$_DD&`
zv#<8nI!8CRcMKk)s$T!;lgRoZ0fET=v3h?x#hoZb*Q(H9F?bY2A*r{l7nr@(_hCPZ
ziCv{2q78q0k9|PFuAIZ3=cv1#Vq|xCdx$$pVtjfRpq2x33)h%D(_CEU`5spJc=y~O
zd+PmM_A1@3D1OX9Gigpl`i+-E@#aWI!S3{Ttq#A{`qsip$<0EOKj`(dgT!eK*OIwY8tq9I?kPA$AML>2VsmXvt%
z-rC{Qb~pWr>A(M%sGR?P&F|v)pQHWn)8f2%Yze?`4x_}9pp0S;;Jn~UW#UT3*c+SP
zpKIah;J|w}_;EN#<tCL*a-AI4j_3>{@pwm(NF-=r@63049F2)5fAvu
z9@{A2X2F>7U;V
zXR7JH_>GCW@ZV61zsr`2Wa5JP=fnP+pZ{;T!Q1=yHMw>*tzApMffEZ*Q1Swf1i;eV
zp5lbNod=mc|02s{!RYbgm1T+m-SS^A6gG~1(&^Gu(;TM
z^9F;ZrQkFaO!_acxIVc5-B@}%qrTo8_nEN0iILxnN7Gy97|w*1^eis0GI)+(VJ^=7
zk&Gid(!4p3$6~zByON>qU@L(AJ$_LxC&=dCa~||8>z``mwjgGT#^5
z5e}))w=OHrMQHY%wV+*g(adviUcc+x$|tdJqyE`0PFuE=E|>2bH*Tkdk?c*1(T5DW
zFstxbC*k_t@X?Z9HrI!1<-6v}IOb|Ne%yRy`oJ&2dDC9;4%0JVR9|KB$h^J1-}5%(
zuZ-Htf)-U$g~60yqYQyFVHBok+THs+%MO-5A^-KLw$c+1hE@dgpLj~joLl@m;^C-e
zt6aK8Sb*MRQia)Yo7l&t`F4$5|A_nhIO}4odh!PvI>M{G_o(_)mxFHC-d@O)nnr!j
z+hxUpMa=)(_(V-Ef9F~I-LusX(`N=Be%6%`{Pm)?(j~F_TKP9wJ3Gg`LaUO(bLFfD
zd`M!iz8d_Q6mP`UX#9@a{%ft@B0v9+?onAAJG%o^o3h>SpHcVeVNiWVzD_Vl^*OSg
zp3zZjYrCY3!gK1|@BS=(qU661A*Bdj)xGgYJP%2U#7OeKpi$4k^Z!q`i0YMU{u=(U)(96WRHndk_Q
zql2!?k7L_Y_U8g@U7l0Ryw#RX@TzEKpjQZ{}z*r?e-z8B8B%mUz6bP3{o}omdDG$w?rQbD;X-&mE}=4lS;GT&6#D_s2?0vN~*heXjV;HJlme9`jWh
zeJA0)Ob*&9-Sy)yYCY+zbIvy!+;HwTO%+`w74M8g%(W<4W}^+J0{HH~vn)Xb%W!aT
z@CSzo9fj)3(y7s?V0y(4v&!5<-@oHyy~k=kifG4N^epu|R3RPf+BWG;65?O7%oE+IxbB)oL9l{+W=!B`y3`?ajB;>=80>f21Sa#~w%QrhoPp|)NBqp!d6DzV4W
z?P}0w4>}xdP4*qNVczP>;@01!jx3XAe*k-}Bdg8YZiKxY*#Q=Bl$dBno1%yFxj2CO
z+$Dlb&{ZOIEtn@&Xm#lnDy8zSu2`twL6(ZFxC!z_647&D(}+N20&@7rRD+=^kUx;~
z3jB!>PeQG{(Ob2X>72EJDU^VJ+Xywe@_2cUXf0(#9XQVu+
z^%TpXQ`U^~d$e^x+O}QD^MaL~oh#?|59_049_A!UtkZd*`&ud#IbN_BQ44QF+@Rz#
z*a8LKQ5Kf%58er*%lP_T_yne3L}N>{f`S#``3E#*s5tdRx@Y21$yP1TcF92j4}-N!
zdiSji4Csg)6?W<`)pPw}1%&!6%)TA@(hu~!2rwTTE77b3&*T;Wgu<0B`<@*z`>qBU
z2yrA6yw(R$x%6RHwJwm#h(rmL*(3hEw!@S{%TxQ{Go*tSjWgOHM56`m>IZo533NPu
zeKkpIrSGM28s-GtS4H$o@b6^xTsBz8^(X|_v>pNH0hOdDy;Rt1kla~>cGA)gT801KMT)RA(4WD*Z96Uo$AS1dfS7|qNvA-Q7(
zqOg;|M+_nj@^5LibUP=MJ&r;jzB5k$PHVmKD5&A
zhbjXI#`(Jo4Ei#z*@|9eV+=+$`t)og!4M*-fax90%{-hA8!v-ZUq_$MvV=unZj$z<
z5_~h@42Q8qL5F$!@YSLM&S1sZgG%l66xiI^-b5Dm4Lk@Gd8C)oh{4Gmp0Tj9Di1dB
z^Fzykp)&I~4Mr9Wy5TzN{re4h1ky3ZK~n2}@5P*kaptYjg3&*1j~92aDE8;LM2@>q
zQT?dNaOO?SQ%ys&VWP<#6C9Yxt{^-xt
zi`(xW93AC1e$>P%)9$UlWyPdi$6(3ne%He(n=~VZ$gH$GbAIpM7M?jYn?foz@udBw
zuL4R20y3nd0MZ|Wo;Cppz;|;ifP72_Im*X(kR&$i%QXpFI=Xv%=_Oy^`YudBR}uV@
z-@bp>wd>;8UO1f&X4N~Odk&DpA_HVA
zbvT;}zNfGYjysjy`>=ISwaUl2_Jr#0l$S+u@e)fe|7V_w60`E)Hjs*l(v<
z>f%#&UtAp1Z!I}u5_c)WW{4rD5ZqNQyABV`x1Dj>&+eZsMdAD72LI+Acj$(;IQSm)
z0Ndt^S;z1`b=pXBeM;xUv6mg|joWo2av+EMH|
z2!;2>CjvTN5gW}C!gmwgh6uQC-TFJ;6*h{#hTGdyfs6_#@xm93d4
z7knbQx2k)P<+;pK6DLlrKE}Sog=h4L%e_|$^m+^EUBuTFf?Tu
z(${xrzSeX2mvlzSh{tWF^XW>7)Ur8OdG{ZxnP^ch#wOL=qH6oDQemfkS*>4o^+I|h+nj|u3C_~8NQhe*u-uro;@BjYa_x*p3#~zzosz?qbS|
z-m~DR>FMc%ppHgN6Mi<*mysBdu~R$bpxUe;46&&Ij8t*wgc`jc@DHFM-y^m5OOq7*
z+#)6Ut-pzY{sKMgb^NoVs?_<1DBo;&fsBmFz4G53ex7qbUD{8~P_1HJKNTSq&Z)Fk
z>taz5FU>0U&!3BY{7ZhYktFEI(7t*;)$pM1<#txbSI6IbDim*w+hlWdi+wX;!>iy0Dclz39p9q-#kwnN_>@RM_Ocd-*$E
z)1{d|x$txc`+?0R?hicnG^ZlbM3)b(SpJl%>T0i+{DAZIFbr1O|q4D)1fCcppWN&JmxRb~np+4R3RQ45;s
zK6^pbgx=lVoeW|`)8o?T((6G}oY?0C8fF#V8-f;7r&lmj1mN>O4?#l^(l8S`bbBy7
zG#9dOG@^8I)Z_5CxI33)mVX9hUL1Fa@osf6$Jx0xPXO}}U-iFGonZUdCCD9J{vNwL
z0HX;(@?m(FWpWVp!pzT~QZR8gnqEL;3Ftn}UI@gKWV4_GK6lCoa(#(=hX_;RZ3OU2
z0nC45WMSz=+g|7S2aAAcnm@#W?lQ^h>S}qQTNfpiO%}nVmbSLGXK{V^!p8eE2!{0K
zOK;sKcx*o^{?^}rIx#WP@_@IuG#HkBNS8HT^G!FyZSM-e^Ne9d;9VI0zBkwA**)ql
zJB!4pq0{ttFTh;L
zU%!7J?Z48JV?6*;wN9flbkLX*=+ZKUT?+w&CSs@xD26O;>d_p};1vws=kSr&)6Z$e
z$G|w4L>uf$V5kMZC|M+8nZQf~Mpv7w5ye_b)PqJs?1E
zgl^Zx5^!vrUP}USH;GrJL37M&*7Og0cwNA`4rYq)Y|Zz-=oC`Lg~yy;FCY6CrGgug
z{RMI~(|o6M@g{r)-5(czglm-cBU@~8S79kEE*^;T+ZYod7SxxYt_=CfE??Pf^i9tz4PAKNN9g*5T8N^RP&k`jtMQi+*3;sTh9GH3!We`J
zO(jCQ22lbup&M`%r+oj~ngI3w1ho50$58P|9Q%FGvChg;uK<@HSLY1>eT|M~fk2(eXv18ZFSO&|n+{rpb>>wlOL
z|CI>!udwi6AjbbqZWe*ne{B+3Wna$`eb-nrFi2AC;`6~42EFUA{H+(}qa+V8s?APt
zC@XswoT9Giugm-vJjkeXJ*M%gf?EGe)AshO8_gYsVI76k%et%{
zZ+3%M@X!PEGjz|M?h|PL{o6Cgh^Fq%%}g*0SJ?M!ZC*;6b?@yu4>)Bk#dn$P}!wdSy|SB%2LmE<^aTS5($i#`%nA
zWi$S*6&T*PL&nWU+C66cbBf1rFySb-we9P#Mj7PraP7D@Un*u%UieKpnn9W3=jT6T
z3kcGGAt?IikM5@1tYXYI|(k&yDrt}palT5xHLXNm+BAD={9LCt34Rdpo+
zg`G$B&(wVRl)J%gt5Zm^g40?0u5Ynz)Vy7va&03YtQ~&e{ps-*H{M{nxVWVI=C<2i
zRG^_w>)nz;cV-xC6sT)A4Wgt
z)+%!J4jR-$B(X5FF&i9yiMi<-*+35a!8fcmN!t$F#BiJ(8P0jYy(7l#ww5pb>lnx9
z%Qhb9=>{@#x6{)H_m+^JfY-qM$1cdRJ?`RTZ?{iD@u!(c>r$!FN6
zCA)3f=QCZkiM8#qV|KcCwrdZ%^r+OIXN+D>`?dP;cIQwZ5b28(f>!XbhGAwPRjzC6
zk_4$6mE)Q46lECi%vJ-K2RxBI|;AY!Kh7^=oHN7HVe{Xf|2V-_dI?GO61)bo7tH(1=Tm)KG|x
z4rYIJgQ=+%8rOs7dfW^(2R}RlX@s`=$WJMhQEl!E^K_?^ESY<@ek&4vH{ul7J`^FY
zFt?i<
ziOp4s?x{I27qqoaZ%Rs?8(|tRpfXcbn|R!Q9J#36GHS}mBB*!Z=Bz|0|Ow+!G{
z8ptHk+zQ(h)i=p~xgP8h{L3?XolGvk{??*LsT&uYjB$#j^`e;wG>nk60Z!CmH1soI
z41?`YjwTyY4>Y8l&Bzb}725$xm_=zIVejvQlMpIZa=e1^9y|!HXJjwP#H7ZB|Eb-t
znels2c+IVd_Yf$3A+4N$E=QVgJ@@ri!S5LCM;_DVtK(HBrkn+HPXwOcwfAbt?*4Rh
zX?1PF2cCdsZE2bXJ95Iq3roU2c1Rx%jK~=maDM6m;bn<#RAE#&(q@e!%&s_tu_%~#
ztJ9k2DXK;Mup54(k653^PZLRmjPUW2*id`n0qBf|Fg~W|Rj!9njcO;J9!R@7cHpMg
z1A~o*xwb={Y`v7D1Z7^!{#|s~6cLJDGy0`mZ5T|
zAHO`r;nJgAFf4li!KcEL2L@ho6#Ln`G%gt~39xBA2oCcS8d1sg2e%yTjyD;z{o6V!
z!a&RvKwbtYiHX_{KrN}?HtoH!^X^)*#~edJPgedW
zJeruTbW0)Q3R>#?fpM$w%H9u>8Umd5fs?B#PQ|_uY5BN7r1d`MY@g=i6q)WCUdfL3
z8@eg3D;0a|SFCoE+g}$iK>5%lxj)}gdr{4G#;E4-<^yMjK40?E6>Y8@$;`<8HM7xa
zS{BCN_L=6Pkl3zAikfqpU4A|3jE{A1zgF*c4}S4#r>aWj
zO%gY~x6+*gZY~9yh3~gd*wsRvpvV@*z$8wLs766MP6c-CYh9aQDfhCO1@aFHG{*A>
zifL>peQvxbigB)Upse~u9FEmJu{?Xz
zH1uMGk6gR<;aV^crQqb!k?O;jmAUN~PPj5CQhXNX>f0t7)eBqhoOFCEOvF<)f!M2q
zhuWdBa=UlQ#Oj%BFi-yRX;%A3blj0dk0oLpZdu9|dMZEo3R(+7B`beX@t4hiHG>1g
z^1x+<0l+wMAx`j2bax6Wv*>t$?4w&lP(Nrc+}hNA|5pkm33~45ibn+<
zt^Zwy6p_;zTqEm2$@g-s-(a{NB5=d&ky6JXdLlTqBwWiyi$7lPE>>twe(i>+v1>7S{pO1g^PI7_&
zuk=oZ^tvM~wVkB=8e-<)c!BZ^vY6EbvC4TmwHExMZiuqATE+#mF4zFffocsFG@6L?
zoYIFF(QPpGIxdMyyFOQ%n;k$-~Lo9j+}e5Ge3#oBqd3
zfm$}^VoRne-&hh?4li3q^{uL4A?2l{;24Kz?ftTozLf$crBu659^vFZPsj%q(hWx9
z*97?D*)5+QyNE8|{O@V&MRLF1BDo)qW5n;Os>n7Q=F(@N0cuLuU6;t?^0%4@r6Xrn
z_0Tbt?=01=|B?|+{E-ofEhJe%l7zzXC^oF(^t><#C$OESS-JAX#iLfmzUOcX{Lv5n
z!v`nVMJQ&AKY9%k(G~}mYP%eXkQMr;Ncw+FA1CMy;Q{?0;BG8dd;bS&J+a!ukL(_q
z6B&kQ|AX5wZLeh}4qTwJ=ZBF>##Zm}Tw4oXdaML%(DN@yug
zrPi8ZLNl^}ct8g%fAEB8peay~ND-P;g|u#S |