From 1c97afed7dbe81e2474598ed20336e7ec70c694b Mon Sep 17 00:00:00 2001
From: Dallas98 <990259227@qq.com>
Date: Tue, 21 Oct 2025 23:00:48 +0800
Subject: [PATCH] init datamate
---
.editorconfig | 21 +
.github/workflows/docker-image-backend.yml | 27 +
.github/workflows/docker-image-frontend.yml | 27 +
.gitignore | 189 +
LICENSE | 20 +
Makefile | 164 +
README-zh.md | 72 +
README.md | 77 +
backend/api-gateway/pom.xml | 55 +
.../gateway/ApiGatewayApplication.java | 77 +
backend/openapi/README.md | 147 +
backend/openapi/specs/data-annotation.yaml | 298 +
backend/openapi/specs/data-cleaning.yaml | 491 +
backend/openapi/specs/data-collection.yaml | 517 +
backend/openapi/specs/data-evaluation.yaml | 630 +
backend/openapi/specs/data-management.yaml | 719 +
backend/openapi/specs/data-synthesis.yaml | 620 +
backend/openapi/specs/execution-engine.yaml | 712 +
backend/openapi/specs/operator-market.yaml | 547 +
.../openapi/specs/pipeline-orchestration.yaml | 639 +
backend/pom.xml | 212 +
.../services/data-annotation-service/pom.xml | 101 +
.../services/data-cleaning-service/img.png | Bin 0 -> 137462 bytes
.../services/data-cleaning-service/img1.png | Bin 0 -> 48601 bytes
.../services/data-cleaning-service/img2.png | Bin 0 -> 92852 bytes
.../services/data-cleaning-service/pom.xml | 87 +
.../DataCleaningServiceConfiguration.java | 22 +
.../application/httpclient/DatasetClient.java | 120 +
.../application/httpclient/RuntimeClient.java | 54 +
.../scheduler/CleaningTaskScheduler.java | 40 +
.../service/CleaningTaskService.java | 186 +
.../service/CleaningTemplateService.java | 95 +
.../converter/OperatorInstanceConverter.java | 33 +
.../domain/model/CreateDatasetRequest.java | 26 +
.../domain/model/DatasetFileResponse.java | 36 +
.../domain/model/DatasetResponse.java | 44 +
.../domain/model/DatasetTypeResponse.java | 23 +
.../cleaning/domain/model/ExecutorType.java | 25 +
.../domain/model/OperatorInstancePo.java | 13 +
.../model/PagedDatasetFileResponse.java | 28 +
.../cleaning/domain/model/TaskProcess.java | 24 +
.../domain/model/TemplateWithInstance.java | 30 +
.../exception/CleanErrorCode.java | 19 +
.../mapper/CleaningResultMapper.java | 9 +
.../mapper/CleaningTaskMapper.java | 21 +
.../mapper/CleaningTemplateMapper.java | 25 +
.../mapper/OperatorInstanceMapper.java | 17 +
.../api/CleaningTaskController.java | 59 +
.../api/CleaningTemplateController.java | 74 +
.../interfaces/dto/CleaningProcess.java | 20 +
.../cleaning/interfaces/dto/CleaningTask.java | 92 +
.../interfaces/dto/CleaningTemplate.java | 33 +
.../dto/CreateCleaningTaskRequest.java | 32 +
.../dto/CreateCleaningTemplateRequest.java | 23 +
.../interfaces/dto/OperatorInstance.java | 22 +
.../interfaces/dto/OperatorResponse.java | 41 +
.../dto/UpdateCleaningTemplateRequest.java | 26 +
.../mappers/CleaningResultMapper.xml | 8 +
.../resources/mappers/CleaningTaskMapper.xml | 56 +
.../mappers/CleaningTemplateMapper.xml | 38 +
.../mappers/OperatorInstanceMapper.xml | 16 +
.../data-collection-service/README.md | 229 +
.../data-collection-service/image.png | Bin 0 -> 80705 bytes
.../data-collection-service/image1.png | Bin 0 -> 53113 bytes
.../data-collection-service/image2.png | Bin 0 -> 68926 bytes
.../data-collection-service/image3.png | Bin 0 -> 109289 bytes
.../services/data-collection-service/pom.xml | 200 +
.../DataCollectionServiceConfiguration.java | 24 +
.../scheduler/TaskSchedulerInitializer.java | 66 +
.../service/CollectionTaskService.java | 85 +
.../service/DataxExecutionService.java | 60 +
.../service/TaskExecutionService.java | 83 +
.../domain/model/CollectionTask.java | 45 +
.../domain/model/DataxTemplate.java | 71 +
.../domain/model/TaskExecution.java | 39 +
.../collection/domain/model/TaskStatus.java | 21 +
.../mapper/CollectionTaskMapper.java | 47 +
.../mapper/TaskExecutionMapper.java | 38 +
.../typehandler/TaskStatusTypeHandler.java | 0
.../runtime/datax/DataxJobBuilder.java | 83 +
.../runtime/datax/DataxProcessRunner.java | 46 +
.../runtime/datax/DataxProperties.java | 17 +
.../converter/CollectionTaskConverter.java | 52 +
.../rest/CollectionTaskController.java | 83 +
.../rest/TaskExecutionController.java | 101 +
.../config/application-datacollection.yml | 23 +
.../mappers/CollectionTaskMapper.xml | 188 +
.../resources/mappers/TaskExecutionMapper.xml | 191 +
.../services/data-evaluation-service/pom.xml | 92 +
.../services/data-management-service/pom.xml | 113 +
.../DataManagementServiceConfiguration.java | 22 +
.../DatasetApplicationService.java | 288 +
.../DatasetFileApplicationService.java | 306 +
.../application/FileMetadataService.java | 127 +
.../application/TagApplicationService.java | 116 +
.../common/enums/DatasetStatusType.java | 41 +
.../common/enums/DatasetType.java | 28 +
.../domain/contants/DatasetConstant.java | 11 +
.../domain/model/dataset/Dataset.java | 146 +
.../domain/model/dataset/DatasetFile.java | 35 +
.../dataset/DatasetFileUploadCheckInfo.java | 18 +
.../domain/model/dataset/StatusConstants.java | 33 +
.../domain/model/dataset/Tag.java | 33 +
.../client/CollectionTaskClient.java | 22 +
.../dto/CollectionTaskDetailResponse.java | 23 +
.../client/dto/LocalCollectionConfig.java | 21 +
.../config/DataManagementConfig.java | 37 +
.../config/DataManagementProperties.java | 82 +
.../exception/DataManagementErrorCode.java | 39 +
.../persistence/mapper/DatasetFileMapper.java | 30 +
.../persistence/mapper/DatasetMapper.java | 33 +
.../persistence/mapper/TagMapper.java | 27 +
.../repository/DatasetFileRepository.java | 27 +
.../repository/DatasetRepository.java | 29 +
.../impl/DatasetFileRepositoryImpl.java | 54 +
.../impl/DatasetRepositoryImpl.java | 73 +
.../converter/DatasetConverter.java | 53 +
.../interfaces/converter/TagConverter.java | 30 +
.../dto/AllDatasetStatisticsResponse.java | 20 +
.../interfaces/dto/CreateDatasetRequest.java | 35 +
.../interfaces/dto/CreateTagRequest.java | 18 +
.../interfaces/dto/DatasetFileResponse.java | 36 +
.../interfaces/dto/DatasetPagingQuery.java | 42 +
.../interfaces/dto/DatasetResponse.java | 47 +
.../dto/DatasetStatisticsResponse.java | 26 +
.../interfaces/dto/DatasetTypeResponse.java | 24 +
.../dto/PagedDatasetFileResponse.java | 28 +
.../interfaces/dto/PagedDatasetResponse.java | 28 +
.../interfaces/dto/TagResponse.java | 22 +
.../interfaces/dto/UpdateDatasetRequest.java | 25 +
.../interfaces/dto/UpdateTagRequest.java | 20 +
.../interfaces/dto/UploadFileRequest.java | 34 +
.../interfaces/dto/UploadFilesPreRequest.java | 22 +
.../interfaces/rest/DatasetController.java | 115 +
.../rest/DatasetFileController.java | 163 +
.../rest/DatasetTypeController.java | 53 +
.../interfaces/rest/TagController.java | 85 +
.../config/application-datamanagement.yml | 11 +
.../resources/mappers/DatasetFileMapper.xml | 98 +
.../main/resources/mappers/DatasetMapper.xml | 152 +
.../src/main/resources/mappers/TagMapper.xml | 111 +
.../services/data-synthesis-service/pom.xml | 92 +
.../services/execution-engine-service/pom.xml | 96 +
backend/services/main-application/pom.xml | 169 +
.../main/DataMatePlatformApplication.java | 49 +
.../datamate/main/config/SecurityConfig.java | 26 +
.../src/main/resources/application.yml | 179 +
.../config/application-datacollection.yml | 23 +
.../config/application-datamanagement.yml | 11 +
.../src/main/resources/log4j2.xml | 42 +
.../services/operator-market-service/img.png | Bin 0 -> 146785 bytes
.../operator-market-service/img_1.png | Bin 0 -> 45904 bytes
.../services/operator-market-service/pom.xml | 94 +
.../OperatorMarketServiceConfiguration.java | 24 +
.../operator/application/CategoryService.java | 62 +
.../operator/application/LabelService.java | 22 +
.../operator/application/OperatorService.java | 76 +
.../domain/converter/OperatorConverter.java | 28 +
.../operator/domain/modal/Category.java | 14 +
.../domain/modal/CategoryRelation.java | 12 +
.../operator/domain/modal/Operator.java | 35 +
.../domain/modal/RelationCategoryDTO.java | 15 +
.../persistence/mapper/CategoryMapper.java | 12 +
.../mapper/CategoryRelationMapper.java | 18 +
.../persistence/mapper/OperatorMapper.java | 27 +
.../interfaces/api/CategoryController.java | 27 +
.../interfaces/api/LabelController.java | 40 +
.../interfaces/api/OperatorController.java | 54 +
.../interfaces/dto/CategoryTreeResponse.java | 22 +
.../interfaces/dto/CreateOperatorRequest.java | 36 +
.../operator/interfaces/dto/Label.java | 13 +
.../interfaces/dto/OperatorResponse.java | 43 +
.../dto/OperatorsListPostRequest.java | 30 +
.../operator/interfaces/dto/SubCategory.java | 18 +
.../interfaces/dto/UpdateOperatorRequest.java | 32 +
.../main/resources/mappers/CategoryMapper.xml | 8 +
.../mappers/CategoryRelationMapper.xml | 24 +
.../main/resources/mappers/OperatorMapper.xml | 96 +
.../pipeline-orchestration-service/pom.xml | 96 +
backend/services/rag-indexer-service/pom.xml | 96 +
.../rag/indexer/RagApplication.java | 17 +
backend/services/rag-query-service/pom.xml | 72 +
backend/shared/domain-common/pom.xml | 37 +
.../datamate/common/domain/AggregateRoot.java | 27 +
.../datamate/common/domain/ValueObject.java | 16 +
.../domain/model/ChunkUploadPreRequest.java | 49 +
.../domain/model/ChunkUploadRequest.java | 36 +
.../common/domain/model/FileUploadResult.java | 24 +
.../common/domain/model/UploadCheckInfo.java | 7 +
.../common/domain/model/base/BaseEntity.java | 61 +
.../common/domain/service/FileService.java | 91 +
.../common/domain/utils/AnalyzerUtils.java | 40 +
.../common/domain/utils/ChunksSaver.java | 134 +
.../common/domain/utils/CommonUtils.java | 24 +
.../common/IgnoreResponseWrap.java | 15 +
.../infrastructure/common/Response.java | 63 +
.../config/EntityMetaObjectHandler.java | 60 +
.../config/GlobalExceptionHandler.java | 54 +
.../config/GlobalResponseHandler.java | 77 +
.../config/MybatisPlusConfig.java | 47 +
.../exception/BusinessAssert.java | 35 +
.../exception/BusinessException.java | 73 +
.../infrastructure/exception/ErrorCode.java | 23 +
.../exception/ErrorCodeImpl.java | 15 +
.../exception/SystemErrorCode.java | 43 +
.../mapper/ChunkUploadRequestMapper.java | 49 +
.../common/interfaces/PagedResponse.java | 44 +
.../common/interfaces/PagingQuery.java | 22 +
.../mappers/ChunkUploadRequestMapper.xml | 65 +
backend/shared/security-common/pom.xml | 46 +
.../datamate/common/security/JwtUtils.java | 106 +
deployment/docker/datamate/docker-compose.yml | 86 +
deployment/docker/datamate/utf8.cnf | 15 +
.../helm/ray/kuberay-operator/Chart.yaml | 24 +
.../crds/ray.io_rayclusters.yaml | 16101 +++++++++++
.../kuberay-operator/crds/ray.io_rayjobs.yaml | 23549 ++++++++++++++++
.../crds/ray.io_rayservices.yaml | 16805 +++++++++++
.../kuberay-operator/templates/_helpers.tpl | 322 +
.../templates/deployment.yaml | 150 +
.../templates/leader_election_role.yaml | 37 +
.../leader_election_role_binding.yaml | 17 +
.../templates/multiple_namespaces_role.yaml | 13 +
.../multiple_namespaces_rolebinding.yaml | 20 +
.../templates/ray_rayjob_editor_role.yaml | 28 +
.../templates/ray_rayjob_viewer_role.yaml | 24 +
.../templates/ray_rayservice_editor_role.yaml | 28 +
.../templates/ray_rayservice_viewer_role.yaml | 24 +
.../ray/kuberay-operator/templates/role.yaml | 9 +
.../templates/rolebinding.yaml | 16 +
.../kuberay-operator/templates/service.yaml | 17 +
.../templates/serviceaccount.yaml | 9 +
.../templates/servicemonitor.yaml | 23 +
.../helm/ray/kuberay-operator/values.yaml | 221 +
deployment/helm/ray/ray-cluster/Chart.yaml | 5 +
.../ray/ray-cluster/templates/_helpers.tpl | 55 +
.../templates/raycluster-cluster.yaml | 407 +
deployment/helm/ray/ray-cluster/values.yaml | 396 +
deployment/helm/ray/service.yaml | 15 +
deployment/kubernetes/backend/deploy.yaml | 120 +
deployment/kubernetes/datax/deploy.yaml | 54 +
deployment/kubernetes/frontend/deploy.yaml | 38 +
deployment/kubernetes/mineru/deploy.yaml | 52 +
deployment/kubernetes/mysql/configmap.yaml | 21 +
deployment/kubernetes/mysql/deploy.yaml | 61 +
.../kubernetes/unstructured/deploy.yaml | 49 +
editions/community/config/application.yml | 181 +
editions/community/config/log4j2.xml | 42 +
editions/enterprise/config/application.yml | 181 +
editions/enterprise/config/log4j2.xml | 42 +
frontend/.gitignore | 28 +
frontend/README.md | 96 +
frontend/eslint.config.js | 23 +
frontend/index.html | 13 +
frontend/package-lock.json | 7125 +++++
frontend/package.json | 49 +
frontend/public/huawei-logo.webp | Bin 0 -> 19172 bytes
frontend/src/components/AddTagPopover.tsx | 129 +
frontend/src/components/CardView.tsx | 291 +
frontend/src/components/DetailHeader.tsx | 137 +
.../src/components/DevelopmentInProgress.tsx | 27 +
frontend/src/components/ErrorBoundary.tsx | 191 +
frontend/src/components/RadioCard.tsx | 70 +
frontend/src/components/SearchControls.tsx | 239 +
frontend/src/components/TagList.tsx | 149 +
frontend/src/components/TagManagement.tsx | 271 +
frontend/src/components/TaskPopover.tsx | 162 +
frontend/src/components/TopLoadingBar.tsx | 69 +
frontend/src/hooks/useDebouncedEffect.ts | 17 +
frontend/src/hooks/useFetchData.ts | 113 +
frontend/src/hooks/useLeavePrompt.ts | 52 +
frontend/src/hooks/useSearchParams.tsx | 18 +
frontend/src/hooks/useStyle.ts | 20 +
frontend/src/index.css | 45 +
frontend/src/main.tsx | 18 +
frontend/src/mock/annotation.tsx | 330 +
frontend/src/mock/cleansing.tsx | 56 +
frontend/src/mock/evaluation.tsx | 290 +
frontend/src/mock/knowledgeBase.tsx | 254 +
frontend/src/mock/mock-apis.cjs | 149 +
frontend/src/mock/mock-core/module-loader.cjs | 25 +
.../src/mock/mock-core/session-helper.cjs | 63 +
frontend/src/mock/mock-core/util.cjs | 30 +
.../error-handle-middleware.cjs | 13 +
frontend/src/mock/mock-middleware/index.cjs | 11 +
.../mock-middleware/send-json-middleawre.cjs | 18 +
.../mock-middleware/set-header-middleware.cjs | 14 +
.../strong-match-middleware.cjs | 13 +
.../src/mock/mock-seed/data-annotation.cjs | 618 +
.../src/mock/mock-seed/data-cleansing.cjs | 544 +
.../src/mock/mock-seed/data-collection.cjs | 231 +
.../src/mock/mock-seed/data-evaluation.cjs | 501 +
.../src/mock/mock-seed/data-management.cjs | 437 +
.../src/mock/mock-seed/data-synthesis.cjs | 522 +
.../mock/mock-seed/knowledge-generation.cjs | 0
.../src/mock/mock-seed/operator-market.cjs | 124 +
frontend/src/mock/mock.cjs | 58 +
frontend/src/mock/nodemon.json | 22 +
frontend/src/mock/operator.tsx | 196 +
frontend/src/mock/ratio.tsx | 193 +
frontend/src/mock/synthesis.tsx | 209 +
frontend/src/pages/Agent/Agent.tsx | 480 +
.../Annotate/AnnotationWorkSpace.tsx | 229 +
.../Annotate/components/AudioAnnotation.tsx | 713 +
.../Annotate/components/ImageAnnotation.tsx | 617 +
.../Annotate/components/TextAnnotation.tsx | 457 +
.../Annotate/components/VideoAnnotation.tsx | 688 +
.../DataAnnotation/Create/CreateTask.tsx | 346 +
.../components/CreateAnnptationTaskDialog.tsx | 98 +
.../components/CustomTemplateDialog.tsx | 225 +
.../DataAnnotation/Detail/TaskDetail.tsx | 0
.../DataAnnotation/Home/DataAnnotation.tsx | 181 +
.../pages/DataAnnotation/annotation.api.ts | 262 +
.../pages/DataAnnotation/annotation.const.tsx | 56 +
.../pages/DataAnnotation/annotation.model.ts | 27 +
.../pages/DataCleansing/Create/CreateTask.tsx | 131 +
.../DataCleansing/Create/CreateTempate.tsx | 119 +
.../pages/DataCleansing/Create/DragDrop.css | 411 +
.../DataCleansing/Create/DragExample.tsx | 430 +
.../Create/components/CreateTaskStepOne.tsx | 119 +
.../components/CreateTemplateStepOne.tsx | 38 +
.../Create/components/OperatorConfig.tsx | 81 +
.../Create/components/OperatorLibrary.tsx | 282 +
.../components/OperatorOrchestration.tsx | 207 +
.../Create/components/ParamConfig.tsx | 234 +
.../Create/hooks/useCreateStepTwo.tsx | 86 +
.../Create/hooks/useDragOperators.ts | 158 +
.../Create/hooks/useOperatorOperations.ts | 155 +
.../pages/DataCleansing/Detail/TaskDetail.tsx | 176 +
.../Detail/components/BasicInfo.tsx | 148 +
.../Detail/components/FileTable.tsx | 503 +
.../Detail/components/LogsTable.tsx | 110 +
.../Detail/components/OperatorTable.tsx | 103 +
.../DataCleansing/Home/DataCleansing.tsx | 61 +
.../Home/components/ProcessFlowDiagram.tsx | 86 +
.../Home/components/TaskList.tsx | 257 +
.../Home/components/TemplateList.tsx | 46 +
.../src/pages/DataCleansing/cleansing.api.ts | 57 +
.../pages/DataCleansing/cleansing.const.tsx | 134 +
.../pages/DataCleansing/cleansing.model.ts | 68 +
.../DataCollection/Create/CreateTask.tsx | 359 +
.../DataCollection/Home/DataCollection.tsx | 44 +
.../Home/components/ExecutionLog.tsx | 153 +
.../Home/components/TaskManagement.tsx | 200 +
.../pages/DataCollection/collection.apis.ts | 60 +
.../pages/DataCollection/collection.const.ts | 69 +
.../pages/DataCollection/collection.model.ts | 52 +
.../DataEvaluation/Create/CreateTask.tsx | 574 +
.../Evaluate/ManualEvaluate.tsx | 407 +
.../DataEvaluation/Home/DataEvaluation.tsx | 484 +
.../Report/EvaluationReport.tsx | 310 +
.../DataEvaluation/data-evaluation.api.ts | 243 +
.../pages/DataEvaluation/data-evaluation.d.ts | 73 +
.../DataManagement/Create/CreateDataset.tsx | 79 +
.../DataManagement/Create/EditDataset.tsx | 101 +
.../Create/components/BasicInformation.tsx | 94 +
.../DataManagement/Detail/DatasetDetail.tsx | 227 +
.../Detail/components/DataLineageFlow.tsx | 52 +
.../Detail/components/DataQuality.tsx | 77 +
.../Detail/components/ImportConfiguration.tsx | 235 +
.../Detail/components/Overview.tsx | 211 +
.../DataManagement/Home/DataManagement.tsx | 350 +
.../src/pages/DataManagement/dataset.api.ts | 198 +
.../pages/DataManagement/dataset.const.tsx | 218 +
.../src/pages/DataManagement/dataset.model.ts | 100 +
.../src/pages/DataManagement/hooks/index.ts | 2 +
.../DataManagement/hooks/useFilesOperation.ts | 124 +
.../DataManagement/hooks/useImportFile.tsx | 61 +
frontend/src/pages/Home/Home.tsx | 314 +
.../Create/KnowledgeBaseCreate.tsx | 671 +
.../Detail/KnowledgeBaseDetail.tsx | 672 +
.../FileDetail/KnowledgeBaseFileDetail.tsx | 695 +
.../Home/KnowledgeGeneration.tsx | 409 +
.../KnowledgeGeneration/knowledge-base.api.ts | 0
.../knowledge-base.const.ts | 0
.../knowledge-base.model.ts | 89 +
frontend/src/pages/Layout/MainLayout.tsx | 23 +
frontend/src/pages/Layout/Sidebar.tsx | 183 +
frontend/src/pages/Layout/TaskUpload.tsx | 217 +
frontend/src/pages/Layout/menu.tsx | 115 +
.../Create/OperatorPluginCreate.tsx | 204 +
.../Create/components/ConfigureStep.tsx | 275 +
.../Create/components/ParsingStep.tsx | 50 +
.../Create/components/PreviewStep.tsx | 25 +
.../Create/components/UploadStep.tsx | 84 +
.../Detail/OperatorPluginDetail.tsx | 356 +
.../Detail/components/ChangeLog.tsx | 34 +
.../Detail/components/Documentation.tsx | 15 +
.../Detail/components/Examples.tsx | 28 +
.../Detail/components/Install.tsx | 105 +
.../Detail/components/Overview.tsx | 167 +
.../Detail/components/Reviews.tsx | 88 +
.../OperatorMarket/Home/OperatorMarket.tsx | 181 +
.../Home/components/Filters.tsx | 179 +
.../OperatorMarket/Home/components/List.tsx | 150 +
.../OperatorMarket/OperatorPluginEdit.tsx | 26 +
.../src/pages/OperatorMarket/operator.api.ts | 243 +
.../pages/OperatorMarket/operator.const.tsx | 9 +
.../pages/OperatorMarket/operator.model.ts | 55 +
.../src/pages/Orchestration/Orchestration.tsx | 842 +
.../pages/Orchestration/WorkflowEditor.tsx | 462 +
.../Orchestration/components/CustomNode.tsx | 159 +
.../src/pages/RatioTask/CreateRatioTask.tsx | 571 +
frontend/src/pages/RatioTask/RatioTask.tsx | 382 +
frontend/src/pages/RatioTask/ratio.d.ts | 24 +
frontend/src/pages/SettingsPage/Settings.tsx | 66 +
.../components/EnvironmentAccess.tsx | 365 +
.../SettingsPage/components/SystemConfig.tsx | 86 +
.../SettingsPage/components/WebhookConfig.tsx | 313 +
.../src/pages/SynthesisTask/CreateTask.tsx | 1250 +
.../pages/SynthesisTask/CreateTemplate.tsx | 302 +
.../src/pages/SynthesisTask/DataSynthesis.tsx | 84 +
.../components/InstructionTemplateTab.tsx | 214 +
.../components/SynthesisTaskTab.tsx | 361 +
.../src/pages/SynthesisTask/synthesis.d.ts | 35 +
.../pages/TaskManagement/TaskManagement.tsx | 0
frontend/src/pages/globals.css | 97 +
frontend/src/providers/MultiProvider.js | 29 +
frontend/src/routes/routes.ts | 268 +
frontend/src/utils/file.util.ts | 79 +
frontend/src/utils/loading.ts | 55 +
frontend/src/utils/request.ts | 526 +
frontend/src/utils/unit.ts | 295 +
frontend/src/vite-env.d.ts | 1 +
frontend/tailwind.config.ts | 76 +
frontend/tsconfig.app.json | 32 +
frontend/tsconfig.json | 7 +
frontend/tsconfig.node.json | 25 +
frontend/vite.config.ts | 42 +
runtime/datax/nfsreader/pom.xml | 80 +
.../nfsreader/src/main/assembly/package.xml | 35 +
.../plugin/reader/nfsreader/MountUtil.java | 121 +
.../plugin/reader/nfsreader/NfsReader.java | 112 +
.../nfsreader/src/main/resources/plugin.json | 6 +
.../main/resources/plugin_job_template.json | 7 +
runtime/datax/nfswriter/pom.xml | 77 +
.../nfswriter/src/main/assembly/package.xml | 35 +
.../plugin/writer/nfswriter/MountUtil.java | 121 +
.../plugin/writer/nfswriter/NfsWriter.java | 100 +
.../plugin/writer/nfswriter/ShellUtil.java | 43 +
.../nfswriter/src/main/resources/plugin.json | 6 +
.../main/resources/plugin_job_template.json | 8 +
runtime/datax/package.xml | 585 +
runtime/datax/pom.xml | 308 +
runtime/ops/README.md | 89 +
.../examples/text_length_filter/metadata.json | 49 +
.../examples/text_length_filter/operator.py | 135 +
runtime/ops/filter/__init__.py | 29 +
.../__init__.py | 6 +
.../metadata.yml | 31 +
.../process.py | 73 +
.../resources/hit_stopwords.txt | 1039 +
.../__init__.py | 6 +
.../metadata.yml | 25 +
.../process.py | 51 +
.../__init__.py | 6 +
.../metadata.yml | 25 +
.../process.py | 49 +
.../resources/special_token.txt | 50 +
.../__init__.py | 6 +
.../metadata.yml | 16 +
.../process.py | 127 +
.../wechat_qrcode_model.py | 23 +
.../img_blurred_images_cleaner/__init__.py | 6 +
.../img_blurred_images_cleaner/metadata.yml | 25 +
.../img_blurred_images_cleaner/process.py | 50 +
.../img_duplicated_images_cleaner/__init__.py | 6 +
.../metadata.yml | 16 +
.../img_duplicated_images_cleaner/process.py | 109 +
.../sql/sql_config.json | 5 +
.../img_similar_images_cleaner/__init__.py | 6 +
.../img_similar_images_cleaner/metadata.yml | 25 +
.../img_similar_images_cleaner/process.py | 238 +
.../sql/sql_config.json | 6 +
.../filter/remove_duplicate_file/__init__.py | 6 +
.../filter/remove_duplicate_file/metadata.yml | 25 +
.../filter/remove_duplicate_file/process.py | 158 +
.../remove_duplicate_file/sql/sql_config.json | 6 +
.../__init__.py | 6 +
.../metadata.yml | 25 +
.../process.py | 116 +
.../resources/political.txt | 321 +
.../resources/sexual.txt | 288 +
.../resources/special_symbols.txt | 50 +
.../resources/violent.txt | 452 +
.../__init__.py | 6 +
.../metadata.yml | 34 +
.../process.py | 54 +
runtime/ops/formatter/__init__.py | 25 +
.../ops/formatter/file_exporter/__init__.py | 6 +
.../ops/formatter/file_exporter/metadata.yml | 16 +
.../ops/formatter/file_exporter/process.py | 144 +
.../ops/formatter/img_formatter/__init__.py | 6 +
.../ops/formatter/img_formatter/metadata.yml | 16 +
.../ops/formatter/img_formatter/process.py | 35 +
.../ops/formatter/slide_formatter/__init__.py | 6 +
.../formatter/slide_formatter/metadata.yml | 16 +
.../ops/formatter/slide_formatter/process.py | 36 +
.../ops/formatter/text_formatter/__init__.py | 6 +
.../ops/formatter/text_formatter/metadata.yml | 16 +
.../ops/formatter/text_formatter/process.py | 44 +
.../ops/formatter/word_formatter/__init__.py | 6 +
.../ops/formatter/word_formatter/metadata.yml | 16 +
.../ops/formatter/word_formatter/process.py | 68 +
runtime/ops/llms/__init__.py | 25 +
.../llms/qa_condition_evaluator/__init__.py | 10 +
.../llms/qa_condition_evaluator/metadata.yml | 16 +
.../llms/qa_condition_evaluator/process.py | 98 +
.../resources/examples.json | 36 +
.../resources/readme.md | 107 +
.../resources/template.txt | 17 +
.../llms/text_quality_evaluation/__init__.py | 6 +
.../llms/text_quality_evaluation/constant.py | 43 +
.../llms/text_quality_evaluation/metadata.yml | 16 +
.../llms/text_quality_evaluation/process.py | 113 +
.../text_quality_evaluation/prompt_config.py | 32 +
.../resources/examples.json | 98 +
.../resources/template.txt | 17 +
runtime/ops/mapper/__init__.py | 52 +
.../ops/mapper/content_cleaner/__init__.py | 6 +
.../ops/mapper/content_cleaner/metadata.yml | 16 +
runtime/ops/mapper/content_cleaner/process.py | 64 +
.../credit_card_number_cleaner/__init__.py | 6 +
.../credit_card_number_cleaner/metadata.yml | 16 +
.../credit_card_number_cleaner/process.py | 83 +
runtime/ops/mapper/email_cleaner/__init__.py | 6 +
runtime/ops/mapper/email_cleaner/metadata.yml | 16 +
runtime/ops/mapper/email_cleaner/process.py | 47 +
runtime/ops/mapper/emoji_cleaner/__init__.py | 6 +
runtime/ops/mapper/emoji_cleaner/metadata.yml | 16 +
runtime/ops/mapper/emoji_cleaner/process.py | 27 +
.../mapper/extra_space_cleaner/__init__.py | 6 +
.../mapper/extra_space_cleaner/metadata.yml | 17 +
.../ops/mapper/extra_space_cleaner/process.py | 69 +
.../resources/special_token.txt | 53 +
.../full_width_characters_cleaner/__init__.py | 6 +
.../metadata.yml | 18 +
.../full_width_characters_cleaner/process.py | 46 +
.../garble_characters_cleaner/__init__.py | 6 +
.../garble_characters_cleaner/metadata.yml | 17 +
.../garble_characters_cleaner/process.py | 54 +
.../resources/charset.json | 24 +
.../ops/mapper/html_tag_cleaner/__init__.py | 6 +
.../ops/mapper/html_tag_cleaner/metadata.yml | 16 +
.../ops/mapper/html_tag_cleaner/process.py | 80 +
.../ops/mapper/id_number_cleaner/__init__.py | 6 +
.../ops/mapper/id_number_cleaner/metadata.yml | 16 +
.../ops/mapper/id_number_cleaner/process.py | 116 +
.../resources/area_code_enum.txt | 3264 +++
runtime/ops/mapper/img_denoise/__init__.py | 6 +
runtime/ops/mapper/img_denoise/metadata.yml | 17 +
runtime/ops/mapper/img_denoise/process.py | 60 +
.../mapper/img_direction_correct/__init__.py | 6 +
.../img_direction_correct/base_model.py | 38 +
.../mapper/img_direction_correct/metadata.yml | 17 +
.../mapper/img_direction_correct/process.py | 139 +
.../img_enhanced_brightness/__init__.py | 6 +
.../img_enhanced_brightness/metadata.yml | 16 +
.../mapper/img_enhanced_brightness/process.py | 100 +
.../mapper/img_enhanced_contrast/__init__.py | 6 +
.../mapper/img_enhanced_contrast/metadata.yml | 16 +
.../mapper/img_enhanced_contrast/process.py | 71 +
.../img_enhanced_saturation/__init__.py | 6 +
.../img_enhanced_saturation/metadata.yml | 17 +
.../mapper/img_enhanced_saturation/process.py | 81 +
.../mapper/img_enhanced_sharpness/__init__.py | 6 +
.../img_enhanced_sharpness/metadata.yml | 17 +
.../mapper/img_enhanced_sharpness/process.py | 69 +
.../__init__.py | 6 +
.../metadata.yml | 17 +
.../img_perspective_transformation/process.py | 147 +
runtime/ops/mapper/img_resize/__init__.py | 6 +
runtime/ops/mapper/img_resize/metadata.yml | 35 +
runtime/ops/mapper/img_resize/process.py | 40 +
.../ops/mapper/img_shadow_remove/__init__.py | 6 +
.../ops/mapper/img_shadow_remove/metadata.yml | 17 +
.../ops/mapper/img_shadow_remove/process.py | 72 +
runtime/ops/mapper/img_type_unify/__init__.py | 6 +
.../ops/mapper/img_type_unify/metadata.yml | 30 +
runtime/ops/mapper/img_type_unify/process.py | 41 +
.../mapper/img_watermark_remove/__init__.py | 6 +
.../mapper/img_watermark_remove/metadata.yml | 26 +
.../mapper/img_watermark_remove/process.py | 160 +
.../watermark_ocr_model.py | 25 +
.../invisible_characters_cleaner/__init__.py | 7 +
.../invisible_characters_cleaner/metadata.yml | 16 +
.../invisible_characters_cleaner/process.py | 30 +
.../ops/mapper/ip_address_cleaner/__init__.py | 6 +
.../mapper/ip_address_cleaner/metadata.yml | 16 +
.../ops/mapper/ip_address_cleaner/process.py | 74 +
.../knowledge_relation_slice/__init__.py | 6 +
.../graph_sim_func.py | 108 +
.../knowledge_relation.py | 184 +
.../knowledge_slice.py | 23 +
.../knowledge_relation_slice/metadata.yml | 16 +
.../knowledge_relation_slice/process.py | 46 +
runtime/ops/mapper/legend_cleaner/__init__.py | 6 +
.../ops/mapper/legend_cleaner/metadata.yml | 16 +
runtime/ops/mapper/legend_cleaner/process.py | 41 +
.../mapper/phone_number_cleaner/__init__.py | 6 +
.../mapper/phone_number_cleaner/metadata.yml | 16 +
.../mapper/phone_number_cleaner/process.py | 51 +
.../mapper/political_word_cleaner/__init__.py | 6 +
.../political_word_cleaner/metadata.yml | 16 +
.../mapper/political_word_cleaner/process.py | 67 +
.../resources/political.txt | 321 +
.../resources/special_symbols.txt | 50 +
.../remove_duplicate_sentences/__init__.py | 6 +
.../remove_duplicate_sentences/metadata.yml | 16 +
.../remove_duplicate_sentences/process.py | 68 +
.../__init__.py | 6 +
.../metadata.yml | 16 +
.../process.py | 70 +
.../resources/sexual.txt | 288 +
.../resources/special_symbols.txt | 50 +
.../resources/violent.txt | 452 +
runtime/ops/mapper/text_to_word/__init__.py | 6 +
runtime/ops/mapper/text_to_word/metadata.yml | 16 +
runtime/ops/mapper/text_to_word/process.py | 328 +
.../mapper/traditional_chinese/__init__.py | 6 +
.../mapper/traditional_chinese/metadata.yml | 16 +
.../ops/mapper/traditional_chinese/process.py | 33 +
.../mapper/unicode_space_cleaner/__init__.py | 6 +
.../mapper/unicode_space_cleaner/metadata.yml | 16 +
.../mapper/unicode_space_cleaner/process.py | 29 +
runtime/ops/mapper/url_cleaner/__init__.py | 6 +
runtime/ops/mapper/url_cleaner/metadata.yml | 16 +
runtime/ops/mapper/url_cleaner/process.py | 36 +
.../ops/mapper/xml_tag_cleaner/__init__.py | 6 +
.../ops/mapper/xml_tag_cleaner/metadata.yml | 16 +
runtime/ops/mapper/xml_tag_cleaner/process.py | 68 +
runtime/ops/requirements.txt | 22 +
runtime/ops/slicer/__init__.py | 22 +
runtime/ops/slicer/segmentation/__init__.py | 6 +
runtime/ops/slicer/segmentation/metadata.yml | 16 +
runtime/ops/slicer/segmentation/process.py | 62 +
.../slide_annotation_slicer/__init__.py | 6 +
.../slide_annotation_slicer/metadata.yml | 16 +
.../slicer/slide_annotation_slicer/process.py | 117 +
.../slicer/slide_simple_slicer/__init__.py | 6 +
.../slicer/slide_simple_slicer/metadata.yml | 43 +
.../ops/slicer/slide_simple_slicer/process.py | 98 +
runtime/ops/user/__init__.py | 27 +
runtime/python-executor/README.md | 89 +
runtime/python-executor/datamate/__init__.py | 1 +
.../datamate/common/__init__.py | 0
.../datamate/common/error_code.py | 98 +
.../datamate/common/utils/__init__.py | 59 +
.../datamate/common/utils/aho_corasick.py | 115 +
.../datamate/common/utils/bytes_transform.py | 66 +
.../datamate/common/utils/custom_importer.py | 30 +
.../datamate/common/utils/lazy_loader.py | 229 +
.../datamate/common/utils/llm_request.py | 118 +
.../common/utils/load_offline_module.py | 109 +
.../datamate/common/utils/registry.py | 102 +
.../datamate/common/utils/text_splitter.py | 171 +
.../python-executor/datamate/core/__init__.py | 0
.../python-executor/datamate/core/base_op.py | 381 +
.../python-executor/datamate/core/constant.py | 8 +
.../python-executor/datamate/core/dataset.py | 213 +
.../datamate/operator_runtime.py | 163 +
.../python-executor/datamate/ops/__init__.py | 22 +
.../datamate/scheduler/__init__.py | 6 +
.../datamate/scheduler/cmd_task_scheduler.py | 214 +
.../datamate/scheduler/func_task_scheduler.py | 133 +
.../datamate/scheduler/scheduler.py | 160 +
.../datamate/sql_manager/__init__.py | 2 +
.../sql_manager/persistence_atction.py | 176 +
.../datamate/sql_manager/sql/sql_config.json | 17 +
.../datamate/sql_manager/sql_manager.py | 52 +
.../datamate/wrappers/__init__.py | 6 +
.../datamate/wrappers/data_juicer_wrapper.py | 6 +
.../datamate/wrappers/datamate_executor.py | 131 +
.../datamate/wrappers/datamate_wrapper.py | 15 +
runtime/python-executor/pyproject.toml | 76 +
scripts/db/00-database-init.sql | 1 +
scripts/db/data-cleaning-init.sql | 103 +
scripts/db/data-collection-init.sql | 160 +
scripts/db/data-common-init.sql | 15 +
scripts/db/data-management-init.sql | 156 +
scripts/db/data-operator-init.sql | 223 +
scripts/images/backend/Dockerfile | 45 +
scripts/images/backend/settings.xml | 68 +
scripts/images/backend/start.sh | 8 +
scripts/images/datax/Dockerfile | 33 +
scripts/images/datax/app.py | 52 +
scripts/images/frontend/Dockerfile | 17 +
scripts/images/frontend/edm.conf | 16 +
scripts/images/mineru/Dockerfile | 22 +
scripts/images/runtime/Dockerfile | 24 +
scripts/images/unstructured/Dockerfile | 9 +
scripts/images/unstructured/app.py | 61 +
scripts/save_images.sh | 103 +
692 files changed, 135442 insertions(+)
create mode 100644 .editorconfig
create mode 100644 .github/workflows/docker-image-backend.yml
create mode 100644 .github/workflows/docker-image-frontend.yml
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 Makefile
create mode 100644 README-zh.md
create mode 100644 README.md
create mode 100644 backend/api-gateway/pom.xml
create mode 100644 backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
create mode 100644 backend/openapi/README.md
create mode 100644 backend/openapi/specs/data-annotation.yaml
create mode 100644 backend/openapi/specs/data-cleaning.yaml
create mode 100644 backend/openapi/specs/data-collection.yaml
create mode 100644 backend/openapi/specs/data-evaluation.yaml
create mode 100644 backend/openapi/specs/data-management.yaml
create mode 100644 backend/openapi/specs/data-synthesis.yaml
create mode 100644 backend/openapi/specs/execution-engine.yaml
create mode 100644 backend/openapi/specs/operator-market.yaml
create mode 100644 backend/openapi/specs/pipeline-orchestration.yaml
create mode 100644 backend/pom.xml
create mode 100644 backend/services/data-annotation-service/pom.xml
create mode 100644 backend/services/data-cleaning-service/img.png
create mode 100644 backend/services/data-cleaning-service/img1.png
create mode 100644 backend/services/data-cleaning-service/img2.png
create mode 100644 backend/services/data-cleaning-service/pom.xml
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/DataCleaningServiceConfiguration.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/application/httpclient/DatasetClient.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/application/httpclient/RuntimeClient.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/application/scheduler/CleaningTaskScheduler.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/application/service/CleaningTaskService.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/application/service/CleaningTemplateService.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/converter/OperatorInstanceConverter.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/CreateDatasetRequest.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/DatasetFileResponse.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/DatasetResponse.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/DatasetTypeResponse.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/ExecutorType.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/OperatorInstancePo.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/PagedDatasetFileResponse.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/TaskProcess.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/domain/model/TemplateWithInstance.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/infrastructure/exception/CleanErrorCode.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/infrastructure/persistence/mapper/CleaningResultMapper.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/infrastructure/persistence/mapper/CleaningTaskMapper.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/infrastructure/persistence/mapper/CleaningTemplateMapper.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/infrastructure/persistence/mapper/OperatorInstanceMapper.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/api/CleaningTaskController.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/api/CleaningTemplateController.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/CleaningProcess.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/CleaningTask.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/CleaningTemplate.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/CreateCleaningTaskRequest.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/CreateCleaningTemplateRequest.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/OperatorInstance.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/OperatorResponse.java
create mode 100644 backend/services/data-cleaning-service/src/main/java/com/datamate/cleaning/interfaces/dto/UpdateCleaningTemplateRequest.java
create mode 100644 backend/services/data-cleaning-service/src/main/resources/mappers/CleaningResultMapper.xml
create mode 100644 backend/services/data-cleaning-service/src/main/resources/mappers/CleaningTaskMapper.xml
create mode 100644 backend/services/data-cleaning-service/src/main/resources/mappers/CleaningTemplateMapper.xml
create mode 100644 backend/services/data-cleaning-service/src/main/resources/mappers/OperatorInstanceMapper.xml
create mode 100644 backend/services/data-collection-service/README.md
create mode 100644 backend/services/data-collection-service/image.png
create mode 100644 backend/services/data-collection-service/image1.png
create mode 100644 backend/services/data-collection-service/image2.png
create mode 100644 backend/services/data-collection-service/image3.png
create mode 100644 backend/services/data-collection-service/pom.xml
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/DataCollectionServiceConfiguration.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/application/scheduler/TaskSchedulerInitializer.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/application/service/CollectionTaskService.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/application/service/DataxExecutionService.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/application/service/TaskExecutionService.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/domain/model/CollectionTask.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/domain/model/DataxTemplate.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/domain/model/TaskExecution.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/domain/model/TaskStatus.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/persistence/mapper/CollectionTaskMapper.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/persistence/mapper/TaskExecutionMapper.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/persistence/typehandler/TaskStatusTypeHandler.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/runtime/datax/DataxJobBuilder.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/runtime/datax/DataxProcessRunner.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/infrastructure/runtime/datax/DataxProperties.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/interfaces/converter/CollectionTaskConverter.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/interfaces/rest/CollectionTaskController.java
create mode 100644 backend/services/data-collection-service/src/main/java/com/datamate/collection/interfaces/rest/TaskExecutionController.java
create mode 100644 backend/services/data-collection-service/src/main/resources/config/application-datacollection.yml
create mode 100644 backend/services/data-collection-service/src/main/resources/mappers/CollectionTaskMapper.xml
create mode 100644 backend/services/data-collection-service/src/main/resources/mappers/TaskExecutionMapper.xml
create mode 100644 backend/services/data-evaluation-service/pom.xml
create mode 100644 backend/services/data-management-service/pom.xml
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/DataManagementServiceConfiguration.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/DatasetApplicationService.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/DatasetFileApplicationService.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/FileMetadataService.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/application/TagApplicationService.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/common/enums/DatasetStatusType.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/common/enums/DatasetType.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/contants/DatasetConstant.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/Dataset.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/DatasetFile.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/DatasetFileUploadCheckInfo.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/StatusConstants.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/domain/model/dataset/Tag.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/client/CollectionTaskClient.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/client/dto/CollectionTaskDetailResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/client/dto/LocalCollectionConfig.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/config/DataManagementConfig.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/config/DataManagementProperties.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/exception/DataManagementErrorCode.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/mapper/DatasetFileMapper.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/mapper/DatasetMapper.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/mapper/TagMapper.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/repository/DatasetFileRepository.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/repository/DatasetRepository.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/repository/impl/DatasetFileRepositoryImpl.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/infrastructure/persistence/repository/impl/DatasetRepositoryImpl.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/converter/DatasetConverter.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/converter/TagConverter.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/AllDatasetStatisticsResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/CreateDatasetRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/CreateTagRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetFileResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetPagingQuery.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetStatisticsResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/DatasetTypeResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/PagedDatasetFileResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/PagedDatasetResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/TagResponse.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/UpdateDatasetRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/UpdateTagRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/UploadFileRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/dto/UploadFilesPreRequest.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/rest/DatasetController.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/rest/DatasetFileController.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/rest/DatasetTypeController.java
create mode 100644 backend/services/data-management-service/src/main/java/com/datamate/datamanagement/interfaces/rest/TagController.java
create mode 100644 backend/services/data-management-service/src/main/resources/config/application-datamanagement.yml
create mode 100644 backend/services/data-management-service/src/main/resources/mappers/DatasetFileMapper.xml
create mode 100644 backend/services/data-management-service/src/main/resources/mappers/DatasetMapper.xml
create mode 100644 backend/services/data-management-service/src/main/resources/mappers/TagMapper.xml
create mode 100644 backend/services/data-synthesis-service/pom.xml
create mode 100644 backend/services/execution-engine-service/pom.xml
create mode 100644 backend/services/main-application/pom.xml
create mode 100644 backend/services/main-application/src/main/java/com/datamate/main/DataMatePlatformApplication.java
create mode 100644 backend/services/main-application/src/main/java/com/datamate/main/config/SecurityConfig.java
create mode 100644 backend/services/main-application/src/main/resources/application.yml
create mode 100644 backend/services/main-application/src/main/resources/config/application-datacollection.yml
create mode 100644 backend/services/main-application/src/main/resources/config/application-datamanagement.yml
create mode 100644 backend/services/main-application/src/main/resources/log4j2.xml
create mode 100644 backend/services/operator-market-service/img.png
create mode 100644 backend/services/operator-market-service/img_1.png
create mode 100644 backend/services/operator-market-service/pom.xml
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/OperatorMarketServiceConfiguration.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/application/CategoryService.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/application/LabelService.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/application/OperatorService.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/domain/converter/OperatorConverter.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/domain/modal/Category.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/domain/modal/CategoryRelation.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/domain/modal/Operator.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/domain/modal/RelationCategoryDTO.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/infrastructure/persistence/mapper/CategoryMapper.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/infrastructure/persistence/mapper/CategoryRelationMapper.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/infrastructure/persistence/mapper/OperatorMapper.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/api/CategoryController.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/api/LabelController.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/api/OperatorController.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/CategoryTreeResponse.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/CreateOperatorRequest.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/Label.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/OperatorResponse.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/OperatorsListPostRequest.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/SubCategory.java
create mode 100644 backend/services/operator-market-service/src/main/java/com/datamate/operator/interfaces/dto/UpdateOperatorRequest.java
create mode 100644 backend/services/operator-market-service/src/main/resources/mappers/CategoryMapper.xml
create mode 100644 backend/services/operator-market-service/src/main/resources/mappers/CategoryRelationMapper.xml
create mode 100644 backend/services/operator-market-service/src/main/resources/mappers/OperatorMapper.xml
create mode 100644 backend/services/pipeline-orchestration-service/pom.xml
create mode 100644 backend/services/rag-indexer-service/pom.xml
create mode 100644 backend/services/rag-indexer-service/src/main/java/com/dataengine/rag/indexer/RagApplication.java
create mode 100644 backend/services/rag-query-service/pom.xml
create mode 100644 backend/shared/domain-common/pom.xml
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/AggregateRoot.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/ValueObject.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/model/ChunkUploadPreRequest.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/model/ChunkUploadRequest.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/model/FileUploadResult.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/model/UploadCheckInfo.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/model/base/BaseEntity.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/service/FileService.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/utils/AnalyzerUtils.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/utils/ChunksSaver.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/domain/utils/CommonUtils.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/common/IgnoreResponseWrap.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/common/Response.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/config/EntityMetaObjectHandler.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/config/GlobalExceptionHandler.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/config/GlobalResponseHandler.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/config/MybatisPlusConfig.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/BusinessAssert.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/BusinessException.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/ErrorCode.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/ErrorCodeImpl.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/exception/SystemErrorCode.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/infrastructure/mapper/ChunkUploadRequestMapper.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/interfaces/PagedResponse.java
create mode 100644 backend/shared/domain-common/src/main/java/com/datamate/common/interfaces/PagingQuery.java
create mode 100644 backend/shared/domain-common/src/main/resources/mappers/ChunkUploadRequestMapper.xml
create mode 100644 backend/shared/security-common/pom.xml
create mode 100644 backend/shared/security-common/src/main/java/com/datamate/common/security/JwtUtils.java
create mode 100644 deployment/docker/datamate/docker-compose.yml
create mode 100644 deployment/docker/datamate/utf8.cnf
create mode 100644 deployment/helm/ray/kuberay-operator/Chart.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/crds/ray.io_rayclusters.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/crds/ray.io_rayjobs.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/crds/ray.io_rayservices.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/_helpers.tpl
create mode 100644 deployment/helm/ray/kuberay-operator/templates/deployment.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/leader_election_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/leader_election_role_binding.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/multiple_namespaces_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/multiple_namespaces_rolebinding.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/ray_rayjob_editor_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/ray_rayjob_viewer_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/ray_rayservice_editor_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/ray_rayservice_viewer_role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/role.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/rolebinding.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/service.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/serviceaccount.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/templates/servicemonitor.yaml
create mode 100644 deployment/helm/ray/kuberay-operator/values.yaml
create mode 100644 deployment/helm/ray/ray-cluster/Chart.yaml
create mode 100644 deployment/helm/ray/ray-cluster/templates/_helpers.tpl
create mode 100644 deployment/helm/ray/ray-cluster/templates/raycluster-cluster.yaml
create mode 100644 deployment/helm/ray/ray-cluster/values.yaml
create mode 100644 deployment/helm/ray/service.yaml
create mode 100644 deployment/kubernetes/backend/deploy.yaml
create mode 100644 deployment/kubernetes/datax/deploy.yaml
create mode 100644 deployment/kubernetes/frontend/deploy.yaml
create mode 100644 deployment/kubernetes/mineru/deploy.yaml
create mode 100644 deployment/kubernetes/mysql/configmap.yaml
create mode 100644 deployment/kubernetes/mysql/deploy.yaml
create mode 100644 deployment/kubernetes/unstructured/deploy.yaml
create mode 100644 editions/community/config/application.yml
create mode 100644 editions/community/config/log4j2.xml
create mode 100644 editions/enterprise/config/application.yml
create mode 100644 editions/enterprise/config/log4j2.xml
create mode 100644 frontend/.gitignore
create mode 100644 frontend/README.md
create mode 100644 frontend/eslint.config.js
create mode 100644 frontend/index.html
create mode 100644 frontend/package-lock.json
create mode 100644 frontend/package.json
create mode 100644 frontend/public/huawei-logo.webp
create mode 100644 frontend/src/components/AddTagPopover.tsx
create mode 100644 frontend/src/components/CardView.tsx
create mode 100644 frontend/src/components/DetailHeader.tsx
create mode 100644 frontend/src/components/DevelopmentInProgress.tsx
create mode 100644 frontend/src/components/ErrorBoundary.tsx
create mode 100644 frontend/src/components/RadioCard.tsx
create mode 100644 frontend/src/components/SearchControls.tsx
create mode 100644 frontend/src/components/TagList.tsx
create mode 100644 frontend/src/components/TagManagement.tsx
create mode 100644 frontend/src/components/TaskPopover.tsx
create mode 100644 frontend/src/components/TopLoadingBar.tsx
create mode 100644 frontend/src/hooks/useDebouncedEffect.ts
create mode 100644 frontend/src/hooks/useFetchData.ts
create mode 100644 frontend/src/hooks/useLeavePrompt.ts
create mode 100644 frontend/src/hooks/useSearchParams.tsx
create mode 100644 frontend/src/hooks/useStyle.ts
create mode 100644 frontend/src/index.css
create mode 100644 frontend/src/main.tsx
create mode 100644 frontend/src/mock/annotation.tsx
create mode 100644 frontend/src/mock/cleansing.tsx
create mode 100644 frontend/src/mock/evaluation.tsx
create mode 100644 frontend/src/mock/knowledgeBase.tsx
create mode 100644 frontend/src/mock/mock-apis.cjs
create mode 100644 frontend/src/mock/mock-core/module-loader.cjs
create mode 100644 frontend/src/mock/mock-core/session-helper.cjs
create mode 100644 frontend/src/mock/mock-core/util.cjs
create mode 100644 frontend/src/mock/mock-middleware/error-handle-middleware.cjs
create mode 100644 frontend/src/mock/mock-middleware/index.cjs
create mode 100644 frontend/src/mock/mock-middleware/send-json-middleawre.cjs
create mode 100644 frontend/src/mock/mock-middleware/set-header-middleware.cjs
create mode 100644 frontend/src/mock/mock-middleware/strong-match-middleware.cjs
create mode 100644 frontend/src/mock/mock-seed/data-annotation.cjs
create mode 100644 frontend/src/mock/mock-seed/data-cleansing.cjs
create mode 100644 frontend/src/mock/mock-seed/data-collection.cjs
create mode 100644 frontend/src/mock/mock-seed/data-evaluation.cjs
create mode 100644 frontend/src/mock/mock-seed/data-management.cjs
create mode 100644 frontend/src/mock/mock-seed/data-synthesis.cjs
create mode 100644 frontend/src/mock/mock-seed/knowledge-generation.cjs
create mode 100644 frontend/src/mock/mock-seed/operator-market.cjs
create mode 100644 frontend/src/mock/mock.cjs
create mode 100644 frontend/src/mock/nodemon.json
create mode 100644 frontend/src/mock/operator.tsx
create mode 100644 frontend/src/mock/ratio.tsx
create mode 100644 frontend/src/mock/synthesis.tsx
create mode 100644 frontend/src/pages/Agent/Agent.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Annotate/AnnotationWorkSpace.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/AudioAnnotation.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/ImageAnnotation.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/TextAnnotation.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Annotate/components/VideoAnnotation.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Create/CreateTask.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Create/components/CreateAnnptationTaskDialog.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Create/components/CustomTemplateDialog.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Detail/TaskDetail.tsx
create mode 100644 frontend/src/pages/DataAnnotation/Home/DataAnnotation.tsx
create mode 100644 frontend/src/pages/DataAnnotation/annotation.api.ts
create mode 100644 frontend/src/pages/DataAnnotation/annotation.const.tsx
create mode 100644 frontend/src/pages/DataAnnotation/annotation.model.ts
create mode 100644 frontend/src/pages/DataCleansing/Create/CreateTask.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/CreateTempate.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/DragDrop.css
create mode 100644 frontend/src/pages/DataCleansing/Create/DragExample.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/CreateTaskStepOne.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/CreateTemplateStepOne.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/OperatorConfig.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/OperatorLibrary.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/OperatorOrchestration.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/components/ParamConfig.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/hooks/useCreateStepTwo.tsx
create mode 100644 frontend/src/pages/DataCleansing/Create/hooks/useDragOperators.ts
create mode 100644 frontend/src/pages/DataCleansing/Create/hooks/useOperatorOperations.ts
create mode 100644 frontend/src/pages/DataCleansing/Detail/TaskDetail.tsx
create mode 100644 frontend/src/pages/DataCleansing/Detail/components/BasicInfo.tsx
create mode 100644 frontend/src/pages/DataCleansing/Detail/components/FileTable.tsx
create mode 100644 frontend/src/pages/DataCleansing/Detail/components/LogsTable.tsx
create mode 100644 frontend/src/pages/DataCleansing/Detail/components/OperatorTable.tsx
create mode 100644 frontend/src/pages/DataCleansing/Home/DataCleansing.tsx
create mode 100644 frontend/src/pages/DataCleansing/Home/components/ProcessFlowDiagram.tsx
create mode 100644 frontend/src/pages/DataCleansing/Home/components/TaskList.tsx
create mode 100644 frontend/src/pages/DataCleansing/Home/components/TemplateList.tsx
create mode 100644 frontend/src/pages/DataCleansing/cleansing.api.ts
create mode 100644 frontend/src/pages/DataCleansing/cleansing.const.tsx
create mode 100644 frontend/src/pages/DataCleansing/cleansing.model.ts
create mode 100644 frontend/src/pages/DataCollection/Create/CreateTask.tsx
create mode 100644 frontend/src/pages/DataCollection/Home/DataCollection.tsx
create mode 100644 frontend/src/pages/DataCollection/Home/components/ExecutionLog.tsx
create mode 100644 frontend/src/pages/DataCollection/Home/components/TaskManagement.tsx
create mode 100644 frontend/src/pages/DataCollection/collection.apis.ts
create mode 100644 frontend/src/pages/DataCollection/collection.const.ts
create mode 100644 frontend/src/pages/DataCollection/collection.model.ts
create mode 100644 frontend/src/pages/DataEvaluation/Create/CreateTask.tsx
create mode 100644 frontend/src/pages/DataEvaluation/Evaluate/ManualEvaluate.tsx
create mode 100644 frontend/src/pages/DataEvaluation/Home/DataEvaluation.tsx
create mode 100644 frontend/src/pages/DataEvaluation/Report/EvaluationReport.tsx
create mode 100644 frontend/src/pages/DataEvaluation/data-evaluation.api.ts
create mode 100644 frontend/src/pages/DataEvaluation/data-evaluation.d.ts
create mode 100644 frontend/src/pages/DataManagement/Create/CreateDataset.tsx
create mode 100644 frontend/src/pages/DataManagement/Create/EditDataset.tsx
create mode 100644 frontend/src/pages/DataManagement/Create/components/BasicInformation.tsx
create mode 100644 frontend/src/pages/DataManagement/Detail/DatasetDetail.tsx
create mode 100644 frontend/src/pages/DataManagement/Detail/components/DataLineageFlow.tsx
create mode 100644 frontend/src/pages/DataManagement/Detail/components/DataQuality.tsx
create mode 100644 frontend/src/pages/DataManagement/Detail/components/ImportConfiguration.tsx
create mode 100644 frontend/src/pages/DataManagement/Detail/components/Overview.tsx
create mode 100644 frontend/src/pages/DataManagement/Home/DataManagement.tsx
create mode 100644 frontend/src/pages/DataManagement/dataset.api.ts
create mode 100644 frontend/src/pages/DataManagement/dataset.const.tsx
create mode 100644 frontend/src/pages/DataManagement/dataset.model.ts
create mode 100644 frontend/src/pages/DataManagement/hooks/index.ts
create mode 100644 frontend/src/pages/DataManagement/hooks/useFilesOperation.ts
create mode 100644 frontend/src/pages/DataManagement/hooks/useImportFile.tsx
create mode 100644 frontend/src/pages/Home/Home.tsx
create mode 100644 frontend/src/pages/KnowledgeGeneration/Create/KnowledgeBaseCreate.tsx
create mode 100644 frontend/src/pages/KnowledgeGeneration/Detail/KnowledgeBaseDetail.tsx
create mode 100644 frontend/src/pages/KnowledgeGeneration/FileDetail/KnowledgeBaseFileDetail.tsx
create mode 100644 frontend/src/pages/KnowledgeGeneration/Home/KnowledgeGeneration.tsx
create mode 100644 frontend/src/pages/KnowledgeGeneration/knowledge-base.api.ts
create mode 100644 frontend/src/pages/KnowledgeGeneration/knowledge-base.const.ts
create mode 100644 frontend/src/pages/KnowledgeGeneration/knowledge-base.model.ts
create mode 100644 frontend/src/pages/Layout/MainLayout.tsx
create mode 100644 frontend/src/pages/Layout/Sidebar.tsx
create mode 100644 frontend/src/pages/Layout/TaskUpload.tsx
create mode 100644 frontend/src/pages/Layout/menu.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Create/OperatorPluginCreate.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Create/components/ConfigureStep.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Create/components/ParsingStep.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Create/components/PreviewStep.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Create/components/UploadStep.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/OperatorPluginDetail.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/ChangeLog.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/Documentation.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/Examples.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/Install.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/Overview.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Detail/components/Reviews.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Home/OperatorMarket.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Home/components/Filters.tsx
create mode 100644 frontend/src/pages/OperatorMarket/Home/components/List.tsx
create mode 100644 frontend/src/pages/OperatorMarket/OperatorPluginEdit.tsx
create mode 100644 frontend/src/pages/OperatorMarket/operator.api.ts
create mode 100644 frontend/src/pages/OperatorMarket/operator.const.tsx
create mode 100644 frontend/src/pages/OperatorMarket/operator.model.ts
create mode 100644 frontend/src/pages/Orchestration/Orchestration.tsx
create mode 100644 frontend/src/pages/Orchestration/WorkflowEditor.tsx
create mode 100644 frontend/src/pages/Orchestration/components/CustomNode.tsx
create mode 100644 frontend/src/pages/RatioTask/CreateRatioTask.tsx
create mode 100644 frontend/src/pages/RatioTask/RatioTask.tsx
create mode 100644 frontend/src/pages/RatioTask/ratio.d.ts
create mode 100644 frontend/src/pages/SettingsPage/Settings.tsx
create mode 100644 frontend/src/pages/SettingsPage/components/EnvironmentAccess.tsx
create mode 100644 frontend/src/pages/SettingsPage/components/SystemConfig.tsx
create mode 100644 frontend/src/pages/SettingsPage/components/WebhookConfig.tsx
create mode 100644 frontend/src/pages/SynthesisTask/CreateTask.tsx
create mode 100644 frontend/src/pages/SynthesisTask/CreateTemplate.tsx
create mode 100644 frontend/src/pages/SynthesisTask/DataSynthesis.tsx
create mode 100644 frontend/src/pages/SynthesisTask/components/InstructionTemplateTab.tsx
create mode 100644 frontend/src/pages/SynthesisTask/components/SynthesisTaskTab.tsx
create mode 100644 frontend/src/pages/SynthesisTask/synthesis.d.ts
create mode 100644 frontend/src/pages/TaskManagement/TaskManagement.tsx
create mode 100644 frontend/src/pages/globals.css
create mode 100644 frontend/src/providers/MultiProvider.js
create mode 100644 frontend/src/routes/routes.ts
create mode 100644 frontend/src/utils/file.util.ts
create mode 100644 frontend/src/utils/loading.ts
create mode 100644 frontend/src/utils/request.ts
create mode 100644 frontend/src/utils/unit.ts
create mode 100644 frontend/src/vite-env.d.ts
create mode 100644 frontend/tailwind.config.ts
create mode 100644 frontend/tsconfig.app.json
create mode 100644 frontend/tsconfig.json
create mode 100644 frontend/tsconfig.node.json
create mode 100644 frontend/vite.config.ts
create mode 100644 runtime/datax/nfsreader/pom.xml
create mode 100644 runtime/datax/nfsreader/src/main/assembly/package.xml
create mode 100644 runtime/datax/nfsreader/src/main/java/com/modelengine/edatamate/plugin/reader/nfsreader/MountUtil.java
create mode 100644 runtime/datax/nfsreader/src/main/java/com/modelengine/edatamate/plugin/reader/nfsreader/NfsReader.java
create mode 100644 runtime/datax/nfsreader/src/main/resources/plugin.json
create mode 100644 runtime/datax/nfsreader/src/main/resources/plugin_job_template.json
create mode 100644 runtime/datax/nfswriter/pom.xml
create mode 100644 runtime/datax/nfswriter/src/main/assembly/package.xml
create mode 100644 runtime/datax/nfswriter/src/main/java/com/modelengine/edatamate/plugin/writer/nfswriter/MountUtil.java
create mode 100644 runtime/datax/nfswriter/src/main/java/com/modelengine/edatamate/plugin/writer/nfswriter/NfsWriter.java
create mode 100644 runtime/datax/nfswriter/src/main/java/com/modelengine/edatamate/plugin/writer/nfswriter/ShellUtil.java
create mode 100644 runtime/datax/nfswriter/src/main/resources/plugin.json
create mode 100644 runtime/datax/nfswriter/src/main/resources/plugin_job_template.json
create mode 100644 runtime/datax/package.xml
create mode 100644 runtime/datax/pom.xml
create mode 100644 runtime/ops/README.md
create mode 100644 runtime/ops/examples/text_length_filter/metadata.json
create mode 100644 runtime/ops/examples/text_length_filter/operator.py
create mode 100644 runtime/ops/filter/__init__.py
create mode 100644 runtime/ops/filter/file_with_high_repeat_phrase_rate_filter/__init__.py
create mode 100644 runtime/ops/filter/file_with_high_repeat_phrase_rate_filter/metadata.yml
create mode 100644 runtime/ops/filter/file_with_high_repeat_phrase_rate_filter/process.py
create mode 100644 runtime/ops/filter/file_with_high_repeat_phrase_rate_filter/resources/hit_stopwords.txt
create mode 100644 runtime/ops/filter/file_with_high_repeat_word_rate_filter/__init__.py
create mode 100644 runtime/ops/filter/file_with_high_repeat_word_rate_filter/metadata.yml
create mode 100644 runtime/ops/filter/file_with_high_repeat_word_rate_filter/process.py
create mode 100644 runtime/ops/filter/file_with_high_special_char_rate_filter/__init__.py
create mode 100644 runtime/ops/filter/file_with_high_special_char_rate_filter/metadata.yml
create mode 100644 runtime/ops/filter/file_with_high_special_char_rate_filter/process.py
create mode 100644 runtime/ops/filter/file_with_high_special_char_rate_filter/resources/special_token.txt
create mode 100644 runtime/ops/filter/img_advertisement_images_cleaner/__init__.py
create mode 100644 runtime/ops/filter/img_advertisement_images_cleaner/metadata.yml
create mode 100644 runtime/ops/filter/img_advertisement_images_cleaner/process.py
create mode 100644 runtime/ops/filter/img_advertisement_images_cleaner/wechat_qrcode_model.py
create mode 100644 runtime/ops/filter/img_blurred_images_cleaner/__init__.py
create mode 100644 runtime/ops/filter/img_blurred_images_cleaner/metadata.yml
create mode 100644 runtime/ops/filter/img_blurred_images_cleaner/process.py
create mode 100644 runtime/ops/filter/img_duplicated_images_cleaner/__init__.py
create mode 100644 runtime/ops/filter/img_duplicated_images_cleaner/metadata.yml
create mode 100644 runtime/ops/filter/img_duplicated_images_cleaner/process.py
create mode 100644 runtime/ops/filter/img_duplicated_images_cleaner/sql/sql_config.json
create mode 100644 runtime/ops/filter/img_similar_images_cleaner/__init__.py
create mode 100644 runtime/ops/filter/img_similar_images_cleaner/metadata.yml
create mode 100644 runtime/ops/filter/img_similar_images_cleaner/process.py
create mode 100644 runtime/ops/filter/img_similar_images_cleaner/sql/sql_config.json
create mode 100644 runtime/ops/filter/remove_duplicate_file/__init__.py
create mode 100644 runtime/ops/filter/remove_duplicate_file/metadata.yml
create mode 100644 runtime/ops/filter/remove_duplicate_file/process.py
create mode 100644 runtime/ops/filter/remove_duplicate_file/sql/sql_config.json
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/__init__.py
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/metadata.yml
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/process.py
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/resources/political.txt
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/resources/sexual.txt
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/resources/special_symbols.txt
create mode 100644 runtime/ops/filter/remove_file_with_many_sensitive_words/resources/violent.txt
create mode 100644 runtime/ops/filter/remove_file_with_short_or_long_length/__init__.py
create mode 100644 runtime/ops/filter/remove_file_with_short_or_long_length/metadata.yml
create mode 100644 runtime/ops/filter/remove_file_with_short_or_long_length/process.py
create mode 100644 runtime/ops/formatter/__init__.py
create mode 100644 runtime/ops/formatter/file_exporter/__init__.py
create mode 100644 runtime/ops/formatter/file_exporter/metadata.yml
create mode 100644 runtime/ops/formatter/file_exporter/process.py
create mode 100644 runtime/ops/formatter/img_formatter/__init__.py
create mode 100644 runtime/ops/formatter/img_formatter/metadata.yml
create mode 100644 runtime/ops/formatter/img_formatter/process.py
create mode 100644 runtime/ops/formatter/slide_formatter/__init__.py
create mode 100644 runtime/ops/formatter/slide_formatter/metadata.yml
create mode 100644 runtime/ops/formatter/slide_formatter/process.py
create mode 100644 runtime/ops/formatter/text_formatter/__init__.py
create mode 100644 runtime/ops/formatter/text_formatter/metadata.yml
create mode 100644 runtime/ops/formatter/text_formatter/process.py
create mode 100644 runtime/ops/formatter/word_formatter/__init__.py
create mode 100644 runtime/ops/formatter/word_formatter/metadata.yml
create mode 100644 runtime/ops/formatter/word_formatter/process.py
create mode 100644 runtime/ops/llms/__init__.py
create mode 100644 runtime/ops/llms/qa_condition_evaluator/__init__.py
create mode 100644 runtime/ops/llms/qa_condition_evaluator/metadata.yml
create mode 100644 runtime/ops/llms/qa_condition_evaluator/process.py
create mode 100644 runtime/ops/llms/qa_condition_evaluator/resources/examples.json
create mode 100644 runtime/ops/llms/qa_condition_evaluator/resources/readme.md
create mode 100644 runtime/ops/llms/qa_condition_evaluator/resources/template.txt
create mode 100644 runtime/ops/llms/text_quality_evaluation/__init__.py
create mode 100644 runtime/ops/llms/text_quality_evaluation/constant.py
create mode 100644 runtime/ops/llms/text_quality_evaluation/metadata.yml
create mode 100644 runtime/ops/llms/text_quality_evaluation/process.py
create mode 100644 runtime/ops/llms/text_quality_evaluation/prompt_config.py
create mode 100644 runtime/ops/llms/text_quality_evaluation/resources/examples.json
create mode 100644 runtime/ops/llms/text_quality_evaluation/resources/template.txt
create mode 100644 runtime/ops/mapper/__init__.py
create mode 100644 runtime/ops/mapper/content_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/content_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/content_cleaner/process.py
create mode 100644 runtime/ops/mapper/credit_card_number_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/credit_card_number_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/credit_card_number_cleaner/process.py
create mode 100644 runtime/ops/mapper/email_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/email_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/email_cleaner/process.py
create mode 100644 runtime/ops/mapper/emoji_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/emoji_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/emoji_cleaner/process.py
create mode 100644 runtime/ops/mapper/extra_space_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/extra_space_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/extra_space_cleaner/process.py
create mode 100644 runtime/ops/mapper/extra_space_cleaner/resources/special_token.txt
create mode 100644 runtime/ops/mapper/full_width_characters_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/full_width_characters_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/full_width_characters_cleaner/process.py
create mode 100644 runtime/ops/mapper/garble_characters_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/garble_characters_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/garble_characters_cleaner/process.py
create mode 100644 runtime/ops/mapper/garble_characters_cleaner/resources/charset.json
create mode 100644 runtime/ops/mapper/html_tag_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/html_tag_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/html_tag_cleaner/process.py
create mode 100644 runtime/ops/mapper/id_number_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/id_number_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/id_number_cleaner/process.py
create mode 100644 runtime/ops/mapper/id_number_cleaner/resources/area_code_enum.txt
create mode 100644 runtime/ops/mapper/img_denoise/__init__.py
create mode 100644 runtime/ops/mapper/img_denoise/metadata.yml
create mode 100644 runtime/ops/mapper/img_denoise/process.py
create mode 100644 runtime/ops/mapper/img_direction_correct/__init__.py
create mode 100644 runtime/ops/mapper/img_direction_correct/base_model.py
create mode 100644 runtime/ops/mapper/img_direction_correct/metadata.yml
create mode 100644 runtime/ops/mapper/img_direction_correct/process.py
create mode 100644 runtime/ops/mapper/img_enhanced_brightness/__init__.py
create mode 100644 runtime/ops/mapper/img_enhanced_brightness/metadata.yml
create mode 100644 runtime/ops/mapper/img_enhanced_brightness/process.py
create mode 100644 runtime/ops/mapper/img_enhanced_contrast/__init__.py
create mode 100644 runtime/ops/mapper/img_enhanced_contrast/metadata.yml
create mode 100644 runtime/ops/mapper/img_enhanced_contrast/process.py
create mode 100644 runtime/ops/mapper/img_enhanced_saturation/__init__.py
create mode 100644 runtime/ops/mapper/img_enhanced_saturation/metadata.yml
create mode 100644 runtime/ops/mapper/img_enhanced_saturation/process.py
create mode 100644 runtime/ops/mapper/img_enhanced_sharpness/__init__.py
create mode 100644 runtime/ops/mapper/img_enhanced_sharpness/metadata.yml
create mode 100644 runtime/ops/mapper/img_enhanced_sharpness/process.py
create mode 100644 runtime/ops/mapper/img_perspective_transformation/__init__.py
create mode 100644 runtime/ops/mapper/img_perspective_transformation/metadata.yml
create mode 100644 runtime/ops/mapper/img_perspective_transformation/process.py
create mode 100644 runtime/ops/mapper/img_resize/__init__.py
create mode 100644 runtime/ops/mapper/img_resize/metadata.yml
create mode 100644 runtime/ops/mapper/img_resize/process.py
create mode 100644 runtime/ops/mapper/img_shadow_remove/__init__.py
create mode 100644 runtime/ops/mapper/img_shadow_remove/metadata.yml
create mode 100644 runtime/ops/mapper/img_shadow_remove/process.py
create mode 100644 runtime/ops/mapper/img_type_unify/__init__.py
create mode 100644 runtime/ops/mapper/img_type_unify/metadata.yml
create mode 100644 runtime/ops/mapper/img_type_unify/process.py
create mode 100644 runtime/ops/mapper/img_watermark_remove/__init__.py
create mode 100644 runtime/ops/mapper/img_watermark_remove/metadata.yml
create mode 100644 runtime/ops/mapper/img_watermark_remove/process.py
create mode 100644 runtime/ops/mapper/img_watermark_remove/watermark_ocr_model.py
create mode 100644 runtime/ops/mapper/invisible_characters_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/invisible_characters_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/invisible_characters_cleaner/process.py
create mode 100644 runtime/ops/mapper/ip_address_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/ip_address_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/ip_address_cleaner/process.py
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/__init__.py
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/graph_sim_func.py
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/knowledge_relation.py
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/knowledge_slice.py
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/metadata.yml
create mode 100644 runtime/ops/mapper/knowledge_relation_slice/process.py
create mode 100644 runtime/ops/mapper/legend_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/legend_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/legend_cleaner/process.py
create mode 100644 runtime/ops/mapper/phone_number_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/phone_number_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/phone_number_cleaner/process.py
create mode 100644 runtime/ops/mapper/political_word_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/political_word_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/political_word_cleaner/process.py
create mode 100644 runtime/ops/mapper/political_word_cleaner/resources/political.txt
create mode 100644 runtime/ops/mapper/political_word_cleaner/resources/special_symbols.txt
create mode 100644 runtime/ops/mapper/remove_duplicate_sentences/__init__.py
create mode 100644 runtime/ops/mapper/remove_duplicate_sentences/metadata.yml
create mode 100644 runtime/ops/mapper/remove_duplicate_sentences/process.py
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/process.py
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/resources/sexual.txt
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/resources/special_symbols.txt
create mode 100644 runtime/ops/mapper/sexual_and_violent_word_cleaner/resources/violent.txt
create mode 100644 runtime/ops/mapper/text_to_word/__init__.py
create mode 100644 runtime/ops/mapper/text_to_word/metadata.yml
create mode 100644 runtime/ops/mapper/text_to_word/process.py
create mode 100644 runtime/ops/mapper/traditional_chinese/__init__.py
create mode 100644 runtime/ops/mapper/traditional_chinese/metadata.yml
create mode 100644 runtime/ops/mapper/traditional_chinese/process.py
create mode 100644 runtime/ops/mapper/unicode_space_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/unicode_space_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/unicode_space_cleaner/process.py
create mode 100644 runtime/ops/mapper/url_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/url_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/url_cleaner/process.py
create mode 100644 runtime/ops/mapper/xml_tag_cleaner/__init__.py
create mode 100644 runtime/ops/mapper/xml_tag_cleaner/metadata.yml
create mode 100644 runtime/ops/mapper/xml_tag_cleaner/process.py
create mode 100644 runtime/ops/requirements.txt
create mode 100644 runtime/ops/slicer/__init__.py
create mode 100644 runtime/ops/slicer/segmentation/__init__.py
create mode 100644 runtime/ops/slicer/segmentation/metadata.yml
create mode 100644 runtime/ops/slicer/segmentation/process.py
create mode 100644 runtime/ops/slicer/slide_annotation_slicer/__init__.py
create mode 100644 runtime/ops/slicer/slide_annotation_slicer/metadata.yml
create mode 100644 runtime/ops/slicer/slide_annotation_slicer/process.py
create mode 100644 runtime/ops/slicer/slide_simple_slicer/__init__.py
create mode 100644 runtime/ops/slicer/slide_simple_slicer/metadata.yml
create mode 100644 runtime/ops/slicer/slide_simple_slicer/process.py
create mode 100644 runtime/ops/user/__init__.py
create mode 100644 runtime/python-executor/README.md
create mode 100644 runtime/python-executor/datamate/__init__.py
create mode 100644 runtime/python-executor/datamate/common/__init__.py
create mode 100644 runtime/python-executor/datamate/common/error_code.py
create mode 100644 runtime/python-executor/datamate/common/utils/__init__.py
create mode 100644 runtime/python-executor/datamate/common/utils/aho_corasick.py
create mode 100644 runtime/python-executor/datamate/common/utils/bytes_transform.py
create mode 100644 runtime/python-executor/datamate/common/utils/custom_importer.py
create mode 100644 runtime/python-executor/datamate/common/utils/lazy_loader.py
create mode 100644 runtime/python-executor/datamate/common/utils/llm_request.py
create mode 100644 runtime/python-executor/datamate/common/utils/load_offline_module.py
create mode 100644 runtime/python-executor/datamate/common/utils/registry.py
create mode 100644 runtime/python-executor/datamate/common/utils/text_splitter.py
create mode 100644 runtime/python-executor/datamate/core/__init__.py
create mode 100644 runtime/python-executor/datamate/core/base_op.py
create mode 100644 runtime/python-executor/datamate/core/constant.py
create mode 100644 runtime/python-executor/datamate/core/dataset.py
create mode 100644 runtime/python-executor/datamate/operator_runtime.py
create mode 100644 runtime/python-executor/datamate/ops/__init__.py
create mode 100644 runtime/python-executor/datamate/scheduler/__init__.py
create mode 100644 runtime/python-executor/datamate/scheduler/cmd_task_scheduler.py
create mode 100644 runtime/python-executor/datamate/scheduler/func_task_scheduler.py
create mode 100644 runtime/python-executor/datamate/scheduler/scheduler.py
create mode 100644 runtime/python-executor/datamate/sql_manager/__init__.py
create mode 100644 runtime/python-executor/datamate/sql_manager/persistence_atction.py
create mode 100644 runtime/python-executor/datamate/sql_manager/sql/sql_config.json
create mode 100644 runtime/python-executor/datamate/sql_manager/sql_manager.py
create mode 100644 runtime/python-executor/datamate/wrappers/__init__.py
create mode 100644 runtime/python-executor/datamate/wrappers/data_juicer_wrapper.py
create mode 100644 runtime/python-executor/datamate/wrappers/datamate_executor.py
create mode 100644 runtime/python-executor/datamate/wrappers/datamate_wrapper.py
create mode 100644 runtime/python-executor/pyproject.toml
create mode 100644 scripts/db/00-database-init.sql
create mode 100644 scripts/db/data-cleaning-init.sql
create mode 100644 scripts/db/data-collection-init.sql
create mode 100644 scripts/db/data-common-init.sql
create mode 100644 scripts/db/data-management-init.sql
create mode 100644 scripts/db/data-operator-init.sql
create mode 100644 scripts/images/backend/Dockerfile
create mode 100644 scripts/images/backend/settings.xml
create mode 100644 scripts/images/backend/start.sh
create mode 100644 scripts/images/datax/Dockerfile
create mode 100644 scripts/images/datax/app.py
create mode 100644 scripts/images/frontend/Dockerfile
create mode 100644 scripts/images/frontend/edm.conf
create mode 100644 scripts/images/mineru/Dockerfile
create mode 100644 scripts/images/runtime/Dockerfile
create mode 100644 scripts/images/unstructured/Dockerfile
create mode 100644 scripts/images/unstructured/app.py
create mode 100644 scripts/save_images.sh
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..65ede07
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,21 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{java,kt}]
+indent_size = 4
+
+[*.{py}]
+indent_size = 4
+
+[*.{md}]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
diff --git a/.github/workflows/docker-image-backend.yml b/.github/workflows/docker-image-backend.yml
new file mode 100644
index 0000000..9548050
--- /dev/null
+++ b/.github/workflows/docker-image-backend.yml
@@ -0,0 +1,27 @@
+name: Backend Docker Image CI
+
+on:
+ push:
+ branches: [ "develop_930" ]
+ paths:
+ - 'backend/**'
+ - 'scripts/images/backend/**'
+ - '.github/workflows/docker-image-backend.yml'
+ pull_request:
+ branches: [ "develop_930" ]
+ paths:
+ - 'backend/**'
+ - 'scripts/images/backend/**'
+ - '.github/workflows/docker-image-backend.yml'
+ workflow_dispatch:
+
+jobs:
+
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build the Backend Docker image
+ run: make build-backend
diff --git a/.github/workflows/docker-image-frontend.yml b/.github/workflows/docker-image-frontend.yml
new file mode 100644
index 0000000..2e0fb3f
--- /dev/null
+++ b/.github/workflows/docker-image-frontend.yml
@@ -0,0 +1,27 @@
+name: Frontend Docker Image CI
+
+on:
+ push:
+ branches: [ "develop_930" ]
+ paths:
+ - 'frontend/**'
+ - 'scripts/images/frontend/**'
+ - '.github/workflows/docker-image-frontend.yml'
+ pull_request:
+ branches: [ "develop_930" ]
+ paths:
+ - 'frontend/**'
+ - 'scripts/images/frontend/**'
+ - '.github/workflows/docker-image-frontend.yml'
+ workflow_dispatch:
+
+jobs:
+
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: Build the Frontend Docker image
+ run: make build-frontend
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0136fb7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,189 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# next.js build output
+.next
+
+# Java
+*.class
+*.jar
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# Maven
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+
+# Gradle
+.gradle
+build/
+!gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+# IntelliJ IDEA
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+
+# Eclipse
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+.recommenders
+
+# Python
+__pycache__/
+*.py[cod]
+*$py.class
+*.so
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyEnv
+.python-version
+
+# pipenv
+Pipfile.lock
+
+# Celery beat schedule file
+celerybeat-schedule
+
+# 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
+
+# Docker
+*.dockerignore
+
+# OS
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# IDE
+.vscode/
+*.sublime-project
+*.sublime-workspace
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..caad1ca
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+# DataMate Open Source License
+
+DataMate is licensed under the MIT License, with the following additional conditions:
+
+DataMate is permitted to be used commercially, including as a backend service for other applications or as an application development platform for enterprises. However, when the following conditions are met, you must contact the producer to obtain a commercial license:
+
+a. Multi-tenant SaaS service: Unless explicitly authorized by DataMate in writing, you may not use the DataMate source code to operate a multi-tenant SaaS service.
+b. LOGO and copyright information: In the process of using DataMate's frontend, you may not remove or modify the LOGO or copyright information in the DataMate console or applications. This restriction is inapplicable to uses of Nexent that do not involve its frontend.
+
+Please contact zhangyafeng2@huawei.com by email to inquire about licensing matters.
+
+As a contributor, you should agree that:
+
+a. The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
+b. Your contributed code may be used for commercial purposes, such as DataMate's cloud business.
+
+Apart from the specific conditions mentioned above, all other rights and restrictions follow the MIT License.
+Detailed information about the MIT License can be found at: https://opensource.org/licenses/MIT
+
+Copyright © 2025 Huawei Technologies Co., Ltd.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..6c453f1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,164 @@
+MAKEFLAGS += --no-print-directory
+
+VERSION ?= latest
+NAMESPACE ?= datamate
+
+.PHONY: build-%
+build-%:
+ $(MAKE) $*-docker-build
+
+.PHONY: build
+build: backend-docker-build frontend-docker-build runtime-docker-build
+
+.PHONY: create-namespace
+create-namespace:
+ @kubectl get namespace $(NAMESPACE) > /dev/null 2>&1 || kubectl create namespace $(NAMESPACE)
+
+.PHONY: install-%
+install-%:
+ifeq ($(origin INSTALLER), undefined)
+ @echo "Choose a deployment method:"
+ @echo "1. Docker"
+ @echo "2. Kubernetes/Helm"
+ @echo -n "Enter choice: "
+ @read choice; \
+ case $$choice in \
+ 1) INSTALLER=docker ;; \
+ 2) INSTALLER=k8s ;; \
+ *) echo "Invalid choice" && exit 1 ;; \
+ esac; \
+ $(MAKE) $*-$$INSTALLER-install
+else
+ $(MAKE) $*-$(INSTALLER)-install
+endif
+
+.PHONY: install
+install: install-data-mate
+
+.PHONY: uninstall-%
+uninstall-%:
+ifeq ($(origin INSTALLER), undefined)
+ @echo "Choose a deployment method:"
+ @echo "1. Docker"
+ @echo "2. Kubernetes/Helm"
+ @echo -n "Enter choice: "
+ @read choice; \
+ case $$choice in \
+ 1) INSTALLER=docker ;; \
+ 2) INSTALLER=k8s ;; \
+ *) echo "Invalid choice" && exit 1 ;; \
+ esac; \
+ $(MAKE) $*-$$INSTALLER-uninstall
+else
+ $(MAKE) $*-$(INSTALLER)-uninstall
+endif
+
+.PHONY: uninstall
+uninstall: uninstall-data-mate
+
+# build
+.PHONY: mineru-docker-build
+mineru-docker-build:
+ docker build -t mineru:$(VERSION) . -f scripts/images/mineru/Dockerfile
+
+.PHONY: datax-docker-build
+datax-docker-build:
+ docker build -t datax:$(VERSION) . -f scripts/images/datax/Dockerfile
+
+.PHONY: unstructured-docker-build
+unstructured-docker-build:
+ docker build -t unstructured:$(VERSION) . -f scripts/images/unstructured/Dockerfile
+
+.PHONY: backend-docker-build
+backend-docker-build:
+ docker build -t backend:$(VERSION) . -f scripts/images/backend/Dockerfile
+
+.PHONY: frontend-docker-build
+frontend-docker-build:
+ docker build -t frontend:$(VERSION) . -f scripts/images/frontend/Dockerfile
+
+.PHONY: runtime-docker-build
+runtime-docker-build:
+ docker build -t runtime:$(VERSION) . -f scripts/images/runtime/Dockerfile
+
+.PHONY: backend-docker-install
+backend-docker-install:
+ cd deployment/docker/data-mate && docker-compose up -d backend
+
+.PHONY: backend-docker-uninstall
+backend-docker-uninstall:
+ cd deployment/docker/data-mate && docker-compose down backend
+
+.PHONY: frontend-docker-install
+frontend-docker-install:
+ cd deployment/docker/data-mate && docker-compose up -d frontend
+
+.PHONY: frontend-docker-uninstall
+frontend-docker-uninstall:
+ cd deployment/docker/data-mate && docker-compose down frontend
+
+.PHONY: runtime-docker-install
+runtime-docker-install:
+ cd deployment/docker/data-mate && docker-compose up -d runtime
+
+.PHONY: runtime-docker-uninstall
+runtime-docker-uninstall:
+ cd deployment/docker/data-mate && docker-compose down runtime
+
+.PHONY: runtime-k8s-install
+runtime-k8s-install: create-namespace
+ helm upgrade kuberay-operator deployment/helm/ray/kuberay-operator --install -n $(NAMESPACE)
+ helm upgrade raycluster deployment/helm/ray/ray-cluster/ --install -n $(NAMESPACE)
+ kubectl apply -f deployment/helm/ray/service.yaml -n $(NAMESPACE)
+
+.PHONY: runtime-k8s-uninstall
+runtime-k8s-uninstall:
+ helm uninstall raycluster -n $(NAMESPACE)
+ helm uninstall kuberay-operator -n $(NAMESPACE)
+ kubectl delete -f deployment/helm/ray/service.yaml -n $(NAMESPACE)
+
+.PHONY: unstructured-k8s-install
+unstructured-k8s-install: create-namespace
+ kubectl apply -f deployment/kubernetes/unstructured/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: mysql-k8s-install
+mysql-k8s-install: create-namespace
+ kubectl create configmap init-sql --from-file=scripts/db/ --dry-run=client -o yaml | kubectl apply -f - -n $(NAMESPACE)
+ kubectl apply -f deployment/kubernetes/mysql/configmap.yaml -n $(NAMESPACE)
+ kubectl apply -f deployment/kubernetes/mysql/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: mysql-k8s-uninstall
+mysql-k8s-uninstall:
+ kubectl delete configmap init-sql -n $(NAMESPACE)
+ kubectl delete -f deployment/kubernetes/mysql/configmap.yaml -n $(NAMESPACE)
+ kubectl delete -f deployment/kubernetes/mysql/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: backend-k8s-install
+backend-k8s-install: create-namespace
+ kubectl apply -f deployment/kubernetes/backend/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: backend-k8s-uninstall
+backend-k8s-uninstall:
+ kubectl delete -f deployment/kubernetes/backend/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: frontend-k8s-install
+frontend-k8s-install: create-namespace
+ kubectl apply -f deployment/kubernetes/frontend/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: frontend-k8s-uninstall
+frontend-k8s-uninstall:
+ kubectl delete -f deployment/kubernetes/frontend/deploy.yaml -n $(NAMESPACE)
+
+.PHONY: data-mate-docker-install
+data-mate-docker-install:
+ cd deployment/docker/datamate && docker-compose up -d
+
+.PHONY: data-mate-docker-uninstall
+data-mate-docker-uninstall:
+ cd deployment/docker/datamate && docker-compose down
+
+.PHONY: data-mate-k8s-install
+data-mate-k8s-install: create-namespace mysql-k8s-install backend-k8s-install frontend-k8s-install runtime-k8s-install
+
+.PHONY: data-mate-k8s-uninstall
+data-mate-k8s-uninstall: mysql-k8s-uninstall backend-k8s-uninstall frontend-k8s-uninstall runtime-k8s-uninstall
diff --git a/README-zh.md b/README-zh.md
new file mode 100644
index 0000000..b135be8
--- /dev/null
+++ b/README-zh.md
@@ -0,0 +1,72 @@
+# DataMate 一站式数据工作平台
+
+
+
+[](https://github.com/ModelEngine-Group/DataMate/actions/workflows/docker-image-backend.yml)
+[](https://github.com/ModelEngine-Group/DataMate/actions/workflows/docker-image-frontend.yml)
+
+
+
+
+
+**DataMate是面向模型微调与RAG检索的企业级数据处理平台,支持数据归集、数据管理、算子市场、数据清洗、数据合成、数据标注、数据评估、知识生成等核心功能。
+**
+
+[简体中文](./README-zh.md) | [English](./README.md)
+
+如果您喜欢这个项目,希望您能给我们一个Star⭐️!
+
+
+
+## 🌟 核心特性
+
+- **核心模块**:数据归集、数据管理、算子市场、数据清洗、数据合成、数据标注、数据评估、知识生成
+- **可视化编排**:拖拽式数据处理流程设计
+- **算子生态**:丰富的内置算子和自定义算子支持
+
+## 🚀 快速开始
+
+### 前置条件
+
+- Git (用于拉取源码)
+- Make (用于构建和安装)
+- Docker (用于构建镜像和部署服务)
+- Docker-Compose (用于部署服务-docker方式)
+- kubernetes (用于部署服务-k8s方式)
+- Helm (用于部署服务-k8s方式)
+
+### 拉取代码
+
+```bash
+git clone git@github.com:ModelEngine-Group/DataMate.git
+```
+
+### 镜像构建
+
+```bash
+make build
+```
+
+### Docker安装
+
+```bash
+make install INSTALLER=docker
+```
+
+### kubernetes安装
+
+```bash
+make install INSTALLER=k8s
+```
+
+## 🤝 贡献指南
+
+感谢您对本项目的关注!我们非常欢迎社区的贡献,无论是提交 Bug 报告、提出功能建议,还是直接参与代码开发,都能帮助项目变得更好。
+
+• 📮 [GitHub Issues](../../issues):提交 Bug 或功能建议。
+
+• 🔧 [GitHub Pull Requests](../../pulls):贡献代码改进。
+
+## 📄 许可证
+
+DataMate 基于 [MIT](LICENSE) 开源,您可以在遵守许可证条款的前提下自由使用、修改和分发本项目的代码。
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b80be8d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,77 @@
+# DataMate All-in-One Data Work Platform
+
+
+
+[](https://github.com/ModelEngine-Group/DataMate/actions/workflows/docker-image-backend.yml)
+[](https://github.com/ModelEngine-Group/DataMate/actions/workflows/docker-image-frontend.yml)
+
+
+
+
+
+**DataMate is an enterprise-level data processing platform for model fine-tuning and RAG retrieval, supporting core
+functions such as data collection, data management, operator marketplace, data cleaning, data synthesis, data
+annotation, data evaluation, and knowledge generation.**
+
+[简体中文](./README-zh.md) | [English](./README.md)
+
+If you like this project, please give it a Star⭐️!
+
+
+
+## 🌟 Core Features
+
+- **Core Modules**: Data Collection, Data Management, Operator Marketplace, Data Cleaning, Data Synthesis, Data
+ Annotation, Data Evaluation, Knowledge Generation.
+- **Visual Orchestration**: Drag-and-drop data processing workflow design.
+- **Operator Ecosystem**: Rich built-in operators and support for custom operators.
+
+## 🚀 Quick Start
+
+### Prerequisites
+
+- Git (for pulling source code)
+- Make (for building and installing)
+- Docker (for building images and deploying services)
+- Docker-Compose (for service deployment - Docker method)
+- Kubernetes (for service deployment - k8s method)
+- Helm (for service deployment - k8s method)
+
+### Clone the Code
+
+```bash
+git clone git@github.com:ModelEngine-Group/DataMate.git
+```
+
+### Build Images
+
+```bash
+make build
+```
+
+### Docker Installation
+
+```bash
+make install INSTALLER=docker
+```
+
+### Kubernetes Installation
+
+```bash
+make install INSTALLER=k8s
+```
+
+## 🤝 Contribution Guidelines
+
+Thank you for your interest in this project! We warmly welcome contributions from the community. Whether it's submitting
+bug reports, suggesting new features, or directly participating in code development, all forms of help make the project
+better.
+
+• 📮 [GitHub Issues](../../issues): Submit bugs or feature suggestions.
+
+• 🔧 [GitHub Pull Requests](../../pulls): Contribute code improvements.
+
+## 📄 License
+
+DataMate is open source under the [MIT](LICENSE) license. You are free to use, modify, and distribute the code of this
+project in compliance with the license terms.
diff --git a/backend/api-gateway/pom.xml b/backend/api-gateway/pom.xml
new file mode 100644
index 0000000..c6284e6
--- /dev/null
+++ b/backend/api-gateway/pom.xml
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+
+
+ com.datamate
+ data-mate-platform
+ 1.0.0-SNAPSHOT
+ ../pom.xml
+
+
+ api-gateway
+ API Gateway
+ API网关服务
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-gateway
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis-reactive
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java b/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
new file mode 100644
index 0000000..a9073ce
--- /dev/null
+++ b/backend/api-gateway/src/main/java/com/datamate/gateway/ApiGatewayApplication.java
@@ -0,0 +1,77 @@
+package com.datamate.gateway;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * API Gateway & Auth Service Application
+ * 统一的API网关和认证授权微服务
+ * 提供路由、鉴权、限流等功能
+ */
+@SpringBootApplication
+@ComponentScan(basePackages = {
+ "com.datamate.gateway",
+ "com.datamate.shared"
+})
+public class ApiGatewayApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ApiGatewayApplication.class, args);
+ }
+
+ @Bean
+ public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
+ return builder.routes()
+ // 数据归集服务路由
+ .route("data-collection", r -> r.path("/api/data-collection/**")
+ .uri("lb://data-collection-service"))
+
+ // 数据管理服务路由
+ .route("data-management", r -> r.path("/api/data-management/**")
+ .uri("lb://data-management-service"))
+
+ // 算子市场服务路由
+ .route("operator-market", r -> r.path("/api/operators/**")
+ .uri("lb://operator-market-service"))
+
+ // 数据清洗服务路由
+ .route("data-cleaning", r -> r.path("/api/cleaning/**")
+ .uri("lb://data-cleaning-service"))
+
+ // 数据合成服务路由
+ .route("data-synthesis", r -> r.path("/api/synthesis/**")
+ .uri("lb://data-synthesis-service"))
+
+ // 数据标注服务路由
+ .route("data-annotation", r -> r.path("/api/annotation/**")
+ .uri("lb://data-annotation-service"))
+
+ // 数据评估服务路由
+ .route("data-evaluation", r -> r.path("/api/evaluation/**")
+ .uri("lb://data-evaluation-service"))
+
+ // 流程编排服务路由
+ .route("pipeline-orchestration", r -> r.path("/api/pipelines/**")
+ .uri("lb://pipeline-orchestration-service"))
+
+ // 执行引擎服务路由
+ .route("execution-engine", r -> r.path("/api/execution/**")
+ .uri("lb://execution-engine-service"))
+
+ // 认证服务路由
+ .route("auth-service", r -> r.path("/api/auth/**")
+ .uri("lb://auth-service"))
+
+ // RAG服务路由
+ .route("rag-indexer", r -> r.path("/api/rag/indexer/**")
+ .uri("lb://rag-indexer-service"))
+ .route("rag-query", r -> r.path("/api/rag/query/**")
+ .uri("lb://rag-query-service"))
+
+ .build();
+ }
+}
diff --git a/backend/openapi/README.md b/backend/openapi/README.md
new file mode 100644
index 0000000..18fbe63
--- /dev/null
+++ b/backend/openapi/README.md
@@ -0,0 +1,147 @@
+# OpenAPI Code Generation Configuration
+# 基于YAML生成API代码的配置文件
+
+## Maven Plugin Configuration for Spring Boot
+# 在各个服务的pom.xml中添加以下插件配置:
+
+```xml
+
+
+ org.openapitools
+ openapi-generator-maven-plugin
+ 6.6.0
+
+
+
+ generate
+
+
+ ${project.basedir}/../../openapi/specs/${project.artifactId}.yaml
+ spring
+
+ com.datamate.${project.name}.interfaces.api
+ com.datamate.${project.name}.interfaces.dto
+
+ true
+ true
+ true
+ true
+ true
+ java8
+ true
+ true
+ true
+ springdoc
+
+
+
+
+
+```
+
+## Gradle Plugin Configuration (Alternative)
+# 如果使用Gradle,可以使用以下配置:
+
+```gradle
+plugins {
+ id 'org.openapi.generator' version '6.6.0'
+}
+
+openApiGenerate {
+ generatorName = "spring"
+ inputSpec = "$rootDir/openapi/specs/${project.name}.yaml"
+ outputDir = "$buildDir/generated-sources/openapi"
+ apiPackage = "com.datamate.${project.name}.interfaces.api"
+ modelPackage = "com.datamate.${project.name}.interfaces.dto"
+ configOptions = [
+ interfaceOnly: "true",
+ useTags: "true",
+ skipDefaultInterface: "true",
+ hideGenerationTimestamp: "true",
+ java8: "true",
+ dateLibrary: "java8",
+ useBeanValidation: "true",
+ performBeanValidation: "true",
+ useSpringBoot3: "true",
+ documentationProvider: "springdoc"
+ ]
+}
+```
+
+## Frontend TypeScript Client Generation
+# 为前端生成TypeScript客户端:
+
+```bash
+# 安装 OpenAPI Generator CLI
+npm install -g @openapitools/openapi-generator-cli
+
+# 生成TypeScript客户端
+openapi-generator-cli generate \
+ -i openapi/specs/data-annotation-service.yaml \
+ -g typescript-axios \
+ -o frontend/packages/api-client/src/generated/annotation \
+ --additional-properties=supportsES6=true,npmName=@datamate/annotation-api,npmVersion=1.0.0
+```
+
+## Usage in Services
+# 在各个服务中使用生成的代码:
+
+1. **在 interfaces 层实现生成的API接口**:
+```java
+@RestController
+@RequestMapping("/api/v1/annotation")
+public class AnnotationTaskController implements AnnotationTasksApi {
+
+ private final AnnotationTaskApplicationService annotationTaskService;
+
+ @Override
+ public ResponseEntity getAnnotationTasks(
+ Integer page, Integer size, String status) {
+ // 实现业务逻辑
+ return ResponseEntity.ok(annotationTaskService.getTasks(page, size, status));
+ }
+}
+```
+
+2. **在 application 层使用生成的DTO**:
+```java
+@Service
+public class AnnotationTaskApplicationService {
+
+ public AnnotationTaskPageResponse getTasks(Integer page, Integer size, String status) {
+ // 业务逻辑实现
+ // 使用生成的DTO类型
+ }
+}
+```
+
+## Build Integration
+# 构建集成脚本位置:scripts/build/generate-api.sh
+
+```bash
+#!/bin/bash
+# 生成所有服务的API代码
+
+OPENAPI_DIR="openapi/specs"
+SERVICES=(
+ "data-annotation-service"
+ "data-management-service"
+ "operator-market-service"
+ "data-cleaning-service"
+ "data-synthesis-service"
+ "data-evaluation-service"
+ "pipeline-orchestration-service"
+ "execution-engine-service"
+ "rag-indexer-service"
+ "rag-query-service"
+ "api-gateway"
+ "auth-service"
+)
+
+for service in "${SERVICES[@]}"; do
+ echo "Generating API for $service..."
+ mvn -f backend/services/$service/pom.xml openapi-generator:generate
+done
+
+echo "All APIs generated successfully!"
+```
diff --git a/backend/openapi/specs/data-annotation.yaml b/backend/openapi/specs/data-annotation.yaml
new file mode 100644
index 0000000..771d8a5
--- /dev/null
+++ b/backend/openapi/specs/data-annotation.yaml
@@ -0,0 +1,298 @@
+openapi: 3.0.3
+info:
+ title: Data Annotation Service API
+ description: 数据标注服务API - 智能预标注、人工平台、主动学习
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8080
+ description: Development server
+
+tags:
+ - name: annotation-tasks
+ description: 标注任务管理
+ - name: annotation-data
+ description: 标注数据管理
+ - name: pre-annotation
+ description: 智能预标注
+ - name: active-learning
+ description: 主动学习
+
+paths:
+ /api/v1/annotation/tasks:
+ get:
+ tags:
+ - annotation-tasks
+ summary: 获取标注任务列表
+ description: 分页获取标注任务列表
+ parameters:
+ - name: page
+ in: query
+ description: 页码
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ description: 每页大小
+ schema:
+ type: integer
+ default: 20
+ - name: status
+ in: query
+ description: 任务状态
+ schema:
+ type: string
+ enum: [PENDING, IN_PROGRESS, COMPLETED, PAUSED]
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnnotationTaskPageResponse'
+ '400':
+ description: 请求参数错误
+ '500':
+ description: 服务器内部错误
+
+ post:
+ tags:
+ - annotation-tasks
+ summary: 创建标注任务
+ description: 创建新的标注任务
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateAnnotationTaskRequest'
+ responses:
+ '201':
+ description: 创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnnotationTaskResponse'
+ '400':
+ description: 请求参数错误
+ '500':
+ description: 服务器内部错误
+
+ /api/v1/annotation/tasks/{taskId}:
+ get:
+ tags:
+ - annotation-tasks
+ summary: 获取标注任务详情
+ parameters:
+ - name: taskId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnnotationTaskResponse'
+ '404':
+ description: 任务不存在
+
+ put:
+ tags:
+ - annotation-tasks
+ summary: 更新标注任务
+ parameters:
+ - name: taskId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateAnnotationTaskRequest'
+ responses:
+ '200':
+ description: 更新成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/AnnotationTaskResponse'
+
+ /api/v1/annotation/pre-annotate:
+ post:
+ tags:
+ - pre-annotation
+ summary: 智能预标注
+ description: 使用AI模型进行智能预标注
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreAnnotationRequest'
+ responses:
+ '200':
+ description: 预标注成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PreAnnotationResponse'
+
+components:
+ schemas:
+ AnnotationTaskResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 任务ID
+ name:
+ type: string
+ description: 任务名称
+ description:
+ type: string
+ description: 任务描述
+ type:
+ type: string
+ enum: [TEXT_CLASSIFICATION, NAMED_ENTITY_RECOGNITION, OBJECT_DETECTION, SEMANTIC_SEGMENTATION]
+ description: 标注类型
+ status:
+ type: string
+ enum: [PENDING, IN_PROGRESS, COMPLETED, PAUSED]
+ description: 任务状态
+ datasetId:
+ type: string
+ description: 数据集ID
+ progress:
+ type: number
+ format: double
+ description: 进度百分比
+ createdAt:
+ type: string
+ format: date-time
+ description: 创建时间
+ updatedAt:
+ type: string
+ format: date-time
+ description: 更新时间
+
+ CreateAnnotationTaskRequest:
+ type: object
+ required:
+ - name
+ - type
+ - datasetId
+ properties:
+ name:
+ type: string
+ description: 任务名称
+ description:
+ type: string
+ description: 任务描述
+ type:
+ type: string
+ enum: [TEXT_CLASSIFICATION, NAMED_ENTITY_RECOGNITION, OBJECT_DETECTION, SEMANTIC_SEGMENTATION]
+ description: 标注类型
+ datasetId:
+ type: string
+ description: 数据集ID
+ configuration:
+ type: object
+ description: 标注配置
+
+ UpdateAnnotationTaskRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 任务名称
+ description:
+ type: string
+ description: 任务描述
+ status:
+ type: string
+ enum: [PENDING, IN_PROGRESS, COMPLETED, PAUSED]
+ description: 任务状态
+
+ AnnotationTaskPageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/AnnotationTaskResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ PreAnnotationRequest:
+ type: object
+ required:
+ - taskId
+ - dataIds
+ properties:
+ taskId:
+ type: string
+ description: 标注任务ID
+ dataIds:
+ type: array
+ items:
+ type: string
+ description: 待预标注的数据ID列表
+ modelId:
+ type: string
+ description: 预标注模型ID
+ confidence:
+ type: number
+ format: double
+ description: 置信度阈值
+
+ PreAnnotationResponse:
+ type: object
+ properties:
+ taskId:
+ type: string
+ description: 任务ID
+ processedCount:
+ type: integer
+ description: 已处理数据数量
+ successCount:
+ type: integer
+ description: 成功预标注数量
+ results:
+ type: array
+ items:
+ type: object
+ properties:
+ dataId:
+ type: string
+ annotations:
+ type: array
+ items:
+ type: object
+ confidence:
+ type: number
+ format: double
+
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+
+security:
+ - BearerAuth: []
diff --git a/backend/openapi/specs/data-cleaning.yaml b/backend/openapi/specs/data-cleaning.yaml
new file mode 100644
index 0000000..ff49274
--- /dev/null
+++ b/backend/openapi/specs/data-cleaning.yaml
@@ -0,0 +1,491 @@
+openapi: 3.0.3
+info:
+ title: Data Cleaning Service API
+ description: 数据清洗服务API - 策略/规则、流程编排对接
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8084
+ description: Development server
+
+tags:
+ - name: CleaningTask
+ description: 数据清洗任务管理
+ - name: CleaningTemplate
+ description: 数据清洗模板管理
+
+paths:
+ /ray/log:
+ get:
+ summary: 获取ray日志文件
+ deprecated: false
+ description: ''
+ tags: [ ]
+ parameters: [ ]
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ type: object
+ properties: { }
+ headers: { }
+ security: [ ]
+ /cleaning/tasks:
+ get:
+ summary: 查询数据清洗任务列表
+ deprecated: false
+ description: 获取所有数据清洗任务或根据查询参数筛选任务。
+ tags:
+ - CleaningTask
+ parameters:
+ - name: status
+ in: query
+ description: 根据任务状态筛选 (e.g., pending, running, completed, failed)
+ required: false
+ schema:
+ type: string
+ - name: keywords
+ in: query
+ description: 关键字
+ required: false
+ schema:
+ type: string
+ - name: page
+ in: query
+ description: 分页数
+ required: true
+ schema:
+ type: integer
+ - name: size
+ in: query
+ description: 分页单页数
+ required: true
+ schema:
+ type: integer
+ responses:
+ '200':
+ description: 成功获取任务列表
+ content:
+ application/json:
+ schema:
+ type: array
+ items: &ref_1
+ $ref: '#/components/schemas/CleaningTask'
+ headers: { }
+ security: [ ]
+ post:
+ summary: 创建新的数据清洗任务
+ deprecated: false
+ description: 可以直接创建任务或基于现有模板创建任务。
+ tags:
+ - CleaningTask
+ parameters: [ ]
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateCleaningTaskRequest'
+ examples: { }
+ responses:
+ '201':
+ description: 任务创建成功
+ content:
+ application/json:
+ schema: *ref_1
+ headers: { }
+ security: [ ]
+ /cleaning/tasks/{taskId}:
+ get:
+ summary: 获取单个数据清洗任务详情
+ deprecated: false
+ description: 根据任务ID获取任务的详细信息。
+ tags:
+ - CleaningTask
+ parameters:
+ - name: taskId
+ in: path
+ description: 任务的唯一标识符
+ required: true
+ example: ''
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 成功获取任务详情
+ content:
+ application/json:
+ schema: *ref_1
+ headers: { }
+ security: [ ]
+ delete:
+ summary: 删除数据清洗任务
+ deprecated: false
+ description: 根据任务ID删除指定的任务。
+ tags:
+ - CleaningTask
+ parameters:
+ - name: taskId
+ in: path
+ description: 任务的唯一标识符
+ required: true
+ example: ''
+ schema:
+ type: string
+ responses:
+ '204':
+ description: 任务删除成功
+ headers: { }
+ security: [ ]
+ /cleaning/templates:
+ get:
+ summary: 查询数据清洗模板列表
+ deprecated: false
+ description: 获取所有可用的数据清洗模板。
+ tags:
+ - CleaningTemplate
+ parameters: [ ]
+ responses:
+ '200':
+ description: 成功获取模板列表
+ content:
+ application/json:
+ schema:
+ type: array
+ items: &ref_2
+ $ref: '#/components/schemas/CleaningTemplate'
+ headers: { }
+ security: [ ]
+ post:
+ summary: 创建新的数据清洗模板
+ deprecated: false
+ description: 定义一个新的数据清洗模板。
+ tags:
+ - CleaningTemplate
+ parameters: [ ]
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateCleaningTemplateRequest'
+ responses:
+ '201':
+ description: 模板创建成功
+ content:
+ application/json:
+ schema: *ref_2
+ headers: { }
+ security: [ ]
+ /cleaning/templates/{templateId}:
+ get:
+ summary: 获取单个数据清洗模板详情
+ deprecated: false
+ description: 根据模板ID获取模板的详细信息。
+ tags:
+ - CleaningTemplate
+ parameters:
+ - name: templateId
+ in: path
+ description: 模板的唯一标识符
+ required: true
+ example: ''
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 成功获取模板详情
+ content:
+ application/json:
+ schema: *ref_2
+ headers: { }
+ security: [ ]
+ put:
+ summary: 更新数据清洗模板
+ deprecated: false
+ description: 根据模板ID更新模板的全部信息。
+ tags:
+ - CleaningTemplate
+ parameters:
+ - name: templateId
+ in: path
+ description: 模板的唯一标识符
+ required: true
+ example: ''
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateCleaningTemplateRequest'
+ responses:
+ '200':
+ description: 模板更新成功
+ content:
+ application/json:
+ schema: *ref_2
+ headers: { }
+ security: [ ]
+ delete:
+ summary: 删除数据清洗模板
+ deprecated: false
+ description: 根据模板ID删除指定的模板。
+ tags:
+ - CleaningTemplate
+ parameters:
+ - name: templateId
+ in: path
+ description: 模板的唯一标识符
+ required: true
+ example: ''
+ schema:
+ type: string
+ responses:
+ '204':
+ description: 模板删除成功
+ headers: { }
+ security: [ ]
+
+components:
+ schemas:
+ OperatorInstance:
+ type: object
+ properties:
+ id:
+ type: string
+ overrides:
+ type: object
+ properties: { }
+ additionalProperties:
+ type: object
+ properties: { }
+ required:
+ - id
+ - overrides
+ CleaningProcess:
+ type: object
+ properties:
+ process:
+ type: number
+ format: float
+ description: 进度百分比
+ totalFileNum:
+ type: integer
+ description: 总文件数量
+ finishedFileNum:
+ type: integer
+ description: 已完成文件数量
+ required:
+ - process
+ - totalFileNum
+ - finishedFileNum
+ OperatorResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 算子ID
+ name:
+ type: string
+ description: 算子名称
+ description:
+ type: string
+ description: 算子描述
+ version:
+ type: string
+ description: 算子版本
+ inputs:
+ type: string
+ description: 输入类型
+ outputs:
+ type: string
+ description: 输入类型
+ runtime:
+ type: string
+ description: 运行时设置
+ settings:
+ type: string
+ description: 算子参数
+ isStar:
+ type: boolean
+ description: 是否收藏
+ createdAt:
+ type: string
+ format: date-time
+ description: 创建时间
+ updatedAt:
+ type: string
+ format: date-time
+ description: 更新时间
+ required:
+ - inputs
+ - outputs
+ - runtime
+ - settings
+ - isStar
+ UpdateCleaningTemplateRequest:
+ type: object
+ required:
+ - name
+ - instance
+ - id
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description: 模板名称
+ description:
+ type: string
+ description: 模板描述
+ instance:
+ type: array
+ items: &ref_3
+ $ref: '#/components/schemas/OperatorInstance'
+ description: 模板定义的清洗规则和配置
+ CreateCleaningTemplateRequest:
+ type: object
+ required:
+ - name
+ - instance
+ properties:
+ name:
+ type: string
+ description: 模板名称
+ description:
+ type: string
+ description: 模板描述
+ instance:
+ type: array
+ items: *ref_3
+ description: 任务的具体配置(如果非模板创建,则直接定义)'
+ CleaningTemplate:
+ type: object
+ required:
+ - id
+ - name
+ - instance
+ - createdAt
+ properties:
+ id:
+ type: string
+ description: 模板唯一标识符
+ name:
+ type: string
+ description: 模板名称
+ description:
+ type: string
+ description: 模板描述
+ instance:
+ type: array
+ items: &ref_4
+ $ref: '#/components/schemas/OperatorResponse'
+ description: 模板定义的清洗规则和配置
+ createdAt:
+ type: string
+ format: date-time
+ description: 模板创建时间
+ updatedAt:
+ type: string
+ format: date-time
+ description: 模板最后更新时间
+ CreateCleaningTaskRequest:
+ type: object
+ required:
+ - name
+ - instance
+ - srcDatasetId
+ - srcDatasetName
+ - destDatasetName
+ - destDatasetType
+ properties:
+ name:
+ type: string
+ description: 任务名称
+ description:
+ type: string
+ description: 任务描述
+ srcDatasetId:
+ type: string
+ srcDatasetName:
+ type: string
+ destDatasetName:
+ type: string
+ destDatasetType:
+ type: string
+ instance:
+ type: array
+ items: *ref_3
+ description: 任务的具体配置(如果非模板创建,则直接定义)
+ ErrorResponse:
+ type: object
+ properties:
+ error:
+ type: string
+ description: 错误类型
+ message:
+ type: string
+ description: 错误详细信息
+ CleaningTask:
+ type: object
+ required:
+ - id
+ - name
+ - status
+ - createdAt
+ - startedAt
+ properties:
+ id:
+ type: string
+ description: 任务唯一标识符
+ name:
+ type: string
+ description: 任务名称
+ description:
+ type: string
+ description: 任务描述
+ srcDatasetId:
+ type: string
+ description: 源数据集id
+ srcDatasetName:
+ type: string
+ description: 源数据集名称
+ destDatasetId:
+ type: string
+ description: 目标数据集id
+ destDatasetName:
+ type: string
+ description: 目标数据集名称
+ status:
+ type: string
+ description: 任务当前状态
+ enum:
+ - pending
+ - running
+ - completed
+ - failed
+ templateId:
+ type: string
+ description: 关联的模板ID(如果基于模板创建)
+ instance:
+ type: array
+ items: *ref_4
+ description: 任务的具体配置(如果非模板创建,则直接定义)
+ progress:
+ $ref: '#/components/schemas/CleaningProcess'
+ createdAt:
+ type: string
+ description: 任务创建时间
+ format: date-time
+ startedAt:
+ type: string
+ format: date-time
+ description: 任务开始时间
+ finishedAt:
+ type: string
+ format: date-time
+ description: 任务最后更新时间
+ securitySchemes: { }
diff --git a/backend/openapi/specs/data-collection.yaml b/backend/openapi/specs/data-collection.yaml
new file mode 100644
index 0000000..cc2731f
--- /dev/null
+++ b/backend/openapi/specs/data-collection.yaml
@@ -0,0 +1,517 @@
+openapi: 3.0.3
+info:
+ title: Data Collection Service API
+ description: |
+ 数据归集服务API,基于数据归集实现数据采集和归集功能。
+
+ 主要功能:
+ - 数据归集任务创建和管理
+ - 数据同步任务执行
+ - 任务监控和状态查询
+ - 执行日志查看
+
+ version: 1.0.0
+
+servers:
+ - url: http://localhost:8090/api/v1/collection
+ description: Development server
+
+tags:
+ - name: CollectionTask
+ description: 数据归集任务管理(包括模板查询)
+ - name: TaskExecution
+ description: 任务执行管理
+
+paths:
+ /data-collection/tasks:
+ get:
+ operationId: getTasks
+ tags: [CollectionTask]
+ summary: 获取归集任务列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: status
+ in: query
+ schema:
+ $ref: '#/components/schemas/TaskStatus'
+ - name: name
+ in: query
+ description: 任务名称关键字搜索
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 归集任务列表
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PagedCollectionTaskSummary'
+
+ post:
+ operationId: createTask
+ tags: [CollectionTask]
+ summary: 创建归集任务
+ description: 创建新的数据归集任务
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateCollectionTaskRequest'
+ responses:
+ '201':
+ description: 归集任务创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CollectionTaskResponse'
+
+ /data-collection/tasks/{id}:
+ get:
+ operationId: getTaskDetail
+ tags: [CollectionTask]
+ summary: 获取归集任务详情
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 归集任务详情
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CollectionTaskResponse'
+ '404':
+ description: 归集任务不存在
+
+ put:
+ operationId: updateTask
+ tags: [CollectionTask]
+ summary: 更新归集任务
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateCollectionTaskRequest'
+ responses:
+ '200':
+ description: 归集任务更新成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CollectionTaskResponse'
+
+ delete:
+ operationId: deleteTask
+ tags: [CollectionTask]
+ summary: 删除归集任务
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '204':
+ description: 归集任务删除成功
+
+ /tasks/{id}/execute:
+ post:
+ tags: [TaskExecution]
+ summary: 执行归集任务
+ description: 立即执行指定的归集任务
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '201':
+ description: 任务执行已启动
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/TaskExecutionResponse'
+
+ /tasks/{id}/executions:
+ get:
+ tags: [TaskExecution]
+ summary: 获取任务执行记录
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ responses:
+ '200':
+ description: 任务执行记录列表
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PagedTaskExecutions'
+
+ /executions/{id}:
+ get:
+ tags: [TaskExecution]
+ summary: 获取执行详情
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 执行详情
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/TaskExecutionDetail'
+
+ delete:
+ tags: [TaskExecution]
+ summary: 停止任务执行
+ parameters:
+ - name: id
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '204':
+ description: 任务执行已停止
+
+ /templates:
+ get:
+ tags: [CollectionTask]
+ summary: 获取DataX模板列表
+ description: 获取可用的DataX任务模板列表,用于创建任务时选择
+ parameters:
+ - name: sourceType
+ in: query
+ description: 源数据源类型过滤
+ schema:
+ type: string
+ - name: targetType
+ in: query
+ description: 目标数据源类型过滤
+ schema:
+ type: string
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ responses:
+ '200':
+ description: 归集模板列表
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PagedDataxTemplates'
+
+components:
+ schemas:
+ TaskStatus:
+ type: string
+ enum:
+ - DRAFT
+ - READY
+ - RUNNING
+ - SUCCESS
+ - FAILED
+ - STOPPED
+ description: |
+ 任务和执行状态枚举:
+ - DRAFT: 草稿状态
+ - READY: 就绪状态
+ - RUNNING: 运行中
+ - SUCCESS: 执行成功 (对应原来的COMPLETED/SUCCESS)
+ - FAILED: 执行失败
+ - STOPPED: 已停止
+
+ SyncMode:
+ type: string
+ enum: [ONCE, SCHEDULED]
+ description: 同步方式:一次性(ONCE) 或 定时(SCHEDULED)
+
+ CollectionTaskSummary:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ status:
+ $ref: '#/components/schemas/TaskStatus'
+ syncMode:
+ $ref: '#/components/schemas/SyncMode'
+ lastExecutionId:
+ type: string
+ description: 最后执行ID
+ createdAt:
+ type: string
+ format: date-time
+ updatedAt:
+ type: string
+ format: date-time
+ description: 任务列表摘要信息(不包含详细配置与调度表达式)
+
+ CollectionTaskResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ config:
+ type: object
+ additionalProperties: true
+ description: 归集配置,包含源端和目标端配置信息
+ status:
+ $ref: '#/components/schemas/TaskStatus'
+ syncMode:
+ $ref: '#/components/schemas/SyncMode'
+ scheduleExpression:
+ type: string
+ description: Cron调度表达式 (仅当 syncMode = SCHEDULED 时有效)
+ lastExecutionId:
+ type: string
+ description: 最后执行ID
+ createdAt:
+ type: string
+ format: date-time
+ updatedAt:
+ type: string
+ format: date-time
+
+ CreateCollectionTaskRequest:
+ type: object
+ required:
+ - name
+ - config
+ - syncMode
+ properties:
+ name:
+ type: string
+ description: 任务名称
+ minLength: 1
+ maxLength: 100
+ description:
+ type: string
+ description: 任务描述
+ maxLength: 500
+ config:
+ type: object
+ description: 归集配置,包含源端和目标端配置信息
+ additionalProperties: true
+ syncMode:
+ $ref: '#/components/schemas/SyncMode'
+ scheduleExpression:
+ type: string
+ description: Cron调度表达式 (syncMode=SCHEDULED 时必填)
+
+ UpdateCollectionTaskRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 任务名称
+ minLength: 1
+ maxLength: 100
+ description:
+ type: string
+ description: 任务描述
+ maxLength: 500
+ config:
+ type: object
+ description: 归集配置,包含源端和目标端配置信息
+ additionalProperties: true
+ syncMode:
+ $ref: '#/components/schemas/SyncMode'
+ scheduleExpression:
+ type: string
+ description: Cron调度表达式 (syncMode=SCHEDULED 时必填)
+
+ PagedCollectionTaskSummary:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/CollectionTaskSummary'
+ totalElements:
+ type: integer
+ totalPages:
+ type: integer
+ number:
+ type: integer
+ size:
+ type: integer
+
+ PagedCollectionTasks:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/CollectionTaskResponse'
+ totalElements:
+ type: integer
+ totalPages:
+ type: integer
+ number:
+ type: integer
+ size:
+ type: integer
+
+ TaskExecutionResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ taskId:
+ type: string
+ taskName:
+ type: string
+ status:
+ $ref: '#/components/schemas/TaskStatus'
+ startedAt:
+ type: string
+ format: date-time
+
+ TaskExecutionDetail:
+ type: object
+ properties:
+ id:
+ type: string
+ taskId:
+ type: string
+ taskName:
+ type: string
+ status:
+ $ref: '#/components/schemas/TaskStatus'
+ progress:
+ type: number
+ format: double
+ minimum: 0
+ maximum: 100
+ recordsTotal:
+ type: integer
+ recordsProcessed:
+ type: integer
+ recordsSuccess:
+ type: integer
+ recordsFailed:
+ type: integer
+ throughput:
+ type: number
+ format: double
+ dataSizeBytes:
+ type: integer
+ startedAt:
+ type: string
+ format: date-time
+ completedAt:
+ type: string
+ format: date-time
+ durationSeconds:
+ type: integer
+ errorMessage:
+ type: string
+
+ PagedTaskExecutions:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/TaskExecutionDetail'
+ totalElements:
+ type: integer
+ totalPages:
+ type: integer
+ number:
+ type: integer
+ size:
+ type: integer
+
+ DataxTemplateSummary:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ sourceType:
+ type: string
+ description: 源数据源类型
+ targetType:
+ type: string
+ description: 目标数据源类型
+ description:
+ type: string
+ version:
+ type: string
+ isSystem:
+ type: boolean
+ description: 是否为系统模板
+ createdAt:
+ type: string
+ format: date-time
+
+ PagedDataxTemplates:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/DataxTemplateSummary'
+ totalElements:
+ type: integer
+ totalPages:
+ type: integer
+ number:
+ type: integer
+ size:
+ type: integer
diff --git a/backend/openapi/specs/data-evaluation.yaml b/backend/openapi/specs/data-evaluation.yaml
new file mode 100644
index 0000000..4a6b23a
--- /dev/null
+++ b/backend/openapi/specs/data-evaluation.yaml
@@ -0,0 +1,630 @@
+openapi: 3.0.3
+info:
+ title: Data Evaluation Service API
+ description: 数据评估服务API - 质量、适配性、价值评估
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8086
+ description: Development server
+
+tags:
+ - name: quality-evaluation
+ description: 数据质量评估
+ - name: compatibility-evaluation
+ description: 适配性评估
+ - name: value-evaluation
+ description: 价值评估
+ - name: evaluation-reports
+ description: 评估报告
+
+paths:
+ /api/v1/evaluation/quality:
+ post:
+ tags:
+ - quality-evaluation
+ summary: 数据质量评估
+ description: 对数据集进行质量评估,包括完整性、准确性、一致性等
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QualityEvaluationRequest'
+ responses:
+ '200':
+ description: 评估成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QualityEvaluationResponse'
+
+ /api/v1/evaluation/quality/{evaluationId}:
+ get:
+ tags:
+ - quality-evaluation
+ summary: 获取质量评估结果
+ parameters:
+ - name: evaluationId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/QualityEvaluationDetailResponse'
+
+ /api/v1/evaluation/compatibility:
+ post:
+ tags:
+ - compatibility-evaluation
+ summary: 适配性评估
+ description: 评估数据集与目标模型或任务的适配性
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CompatibilityEvaluationRequest'
+ responses:
+ '200':
+ description: 评估成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CompatibilityEvaluationResponse'
+
+ /api/v1/evaluation/value:
+ post:
+ tags:
+ - value-evaluation
+ summary: 价值评估
+ description: 评估数据集的商业价值和使用价值
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ValueEvaluationRequest'
+ responses:
+ '200':
+ description: 评估成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ValueEvaluationResponse'
+
+ /api/v1/evaluation/reports:
+ get:
+ tags:
+ - evaluation-reports
+ summary: 获取评估报告列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: type
+ in: query
+ schema:
+ $ref: '#/components/schemas/EvaluationType'
+ - name: datasetId
+ in: query
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EvaluationReportPageResponse'
+
+ /api/v1/evaluation/reports/{reportId}:
+ get:
+ tags:
+ - evaluation-reports
+ summary: 获取评估报告详情
+ parameters:
+ - name: reportId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/EvaluationReportDetailResponse'
+
+ /api/v1/evaluation/reports/{reportId}/export:
+ get:
+ tags:
+ - evaluation-reports
+ summary: 导出评估报告
+ parameters:
+ - name: reportId
+ in: path
+ required: true
+ schema:
+ type: string
+ - name: format
+ in: query
+ schema:
+ type: string
+ enum: [PDF, EXCEL, JSON]
+ default: PDF
+ responses:
+ '200':
+ description: 导出成功
+ content:
+ application/octet-stream:
+ schema:
+ type: string
+ format: binary
+
+ /api/v1/evaluation/batch:
+ post:
+ tags:
+ - evaluation-reports
+ summary: 批量评估
+ description: 对多个数据集进行批量评估
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/BatchEvaluationRequest'
+ responses:
+ '202':
+ description: 批量评估任务已提交
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/BatchEvaluationResponse'
+
+components:
+ schemas:
+ QualityEvaluationRequest:
+ type: object
+ required:
+ - datasetId
+ - metrics
+ properties:
+ datasetId:
+ type: string
+ description: 数据集ID
+ metrics:
+ type: array
+ items:
+ $ref: '#/components/schemas/QualityMetric'
+ description: 评估指标
+ sampleSize:
+ type: integer
+ description: 采样大小
+ parameters:
+ type: object
+ description: 评估参数
+
+ QualityEvaluationResponse:
+ type: object
+ properties:
+ evaluationId:
+ type: string
+ status:
+ $ref: '#/components/schemas/EvaluationStatus'
+ overallScore:
+ type: number
+ format: double
+ description: 总体质量分数
+ metrics:
+ type: array
+ items:
+ $ref: '#/components/schemas/QualityMetricResult'
+ recommendations:
+ type: array
+ items:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+
+ QualityEvaluationDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/QualityEvaluationResponse'
+ - type: object
+ properties:
+ detailedResults:
+ $ref: '#/components/schemas/DetailedQualityResults'
+ visualizations:
+ type: array
+ items:
+ $ref: '#/components/schemas/VisualizationData'
+
+ CompatibilityEvaluationRequest:
+ type: object
+ required:
+ - datasetId
+ - targetType
+ properties:
+ datasetId:
+ type: string
+ targetType:
+ $ref: '#/components/schemas/TargetType'
+ targetConfig:
+ type: object
+ description: 目标配置(模型、任务等)
+ evaluationCriteria:
+ type: array
+ items:
+ $ref: '#/components/schemas/CompatibilityCriterion'
+
+ CompatibilityEvaluationResponse:
+ type: object
+ properties:
+ evaluationId:
+ type: string
+ compatibilityScore:
+ type: number
+ format: double
+ results:
+ type: array
+ items:
+ $ref: '#/components/schemas/CompatibilityResult'
+ suggestions:
+ type: array
+ items:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+
+ ValueEvaluationRequest:
+ type: object
+ required:
+ - datasetId
+ - valueCriteria
+ properties:
+ datasetId:
+ type: string
+ valueCriteria:
+ type: array
+ items:
+ $ref: '#/components/schemas/ValueCriterion'
+ marketContext:
+ type: object
+ description: 市场环境信息
+ businessContext:
+ type: object
+ description: 业务环境信息
+
+ ValueEvaluationResponse:
+ type: object
+ properties:
+ evaluationId:
+ type: string
+ valueScore:
+ type: number
+ format: double
+ monetaryValue:
+ type: number
+ format: double
+ description: 货币价值估算
+ strategicValue:
+ type: number
+ format: double
+ description: 战略价值评分
+ results:
+ type: array
+ items:
+ $ref: '#/components/schemas/ValueResult'
+ insights:
+ type: array
+ items:
+ type: string
+
+ EvaluationReportResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ datasetId:
+ type: string
+ type:
+ $ref: '#/components/schemas/EvaluationType'
+ status:
+ $ref: '#/components/schemas/EvaluationStatus'
+ overallScore:
+ type: number
+ format: double
+ summary:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+ completedAt:
+ type: string
+ format: date-time
+
+ EvaluationReportPageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/EvaluationReportResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ EvaluationReportDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/EvaluationReportResponse'
+ - type: object
+ properties:
+ qualityResults:
+ $ref: '#/components/schemas/QualityEvaluationResponse'
+ compatibilityResults:
+ $ref: '#/components/schemas/CompatibilityEvaluationResponse'
+ valueResults:
+ $ref: '#/components/schemas/ValueEvaluationResponse'
+ attachments:
+ type: array
+ items:
+ $ref: '#/components/schemas/ReportAttachment'
+
+ BatchEvaluationRequest:
+ type: object
+ required:
+ - datasetIds
+ - evaluationTypes
+ properties:
+ datasetIds:
+ type: array
+ items:
+ type: string
+ evaluationTypes:
+ type: array
+ items:
+ $ref: '#/components/schemas/EvaluationType'
+ parameters:
+ type: object
+
+ BatchEvaluationResponse:
+ type: object
+ properties:
+ batchId:
+ type: string
+ status:
+ type: string
+ totalTasks:
+ type: integer
+ submittedAt:
+ type: string
+ format: date-time
+
+ QualityMetric:
+ type: string
+ enum:
+ - COMPLETENESS
+ - ACCURACY
+ - CONSISTENCY
+ - VALIDITY
+ - UNIQUENESS
+ - TIMELINESS
+
+ QualityMetricResult:
+ type: object
+ properties:
+ metric:
+ $ref: '#/components/schemas/QualityMetric'
+ score:
+ type: number
+ format: double
+ details:
+ type: object
+ issues:
+ type: array
+ items:
+ $ref: '#/components/schemas/QualityIssue'
+
+ DetailedQualityResults:
+ type: object
+ properties:
+ fieldAnalysis:
+ type: array
+ items:
+ $ref: '#/components/schemas/FieldAnalysis'
+ distributionAnalysis:
+ $ref: '#/components/schemas/DistributionAnalysis'
+ correlationAnalysis:
+ $ref: '#/components/schemas/CorrelationAnalysis'
+
+ TargetType:
+ type: string
+ enum:
+ - LANGUAGE_MODEL
+ - CLASSIFICATION_MODEL
+ - RECOMMENDATION_SYSTEM
+ - CUSTOM_TASK
+
+ CompatibilityCriterion:
+ type: string
+ enum:
+ - FORMAT_COMPATIBILITY
+ - SCHEMA_COMPATIBILITY
+ - SIZE_ADEQUACY
+ - DISTRIBUTION_MATCH
+ - FEATURE_COVERAGE
+
+ CompatibilityResult:
+ type: object
+ properties:
+ criterion:
+ $ref: '#/components/schemas/CompatibilityCriterion'
+ score:
+ type: number
+ format: double
+ status:
+ type: string
+ enum: [PASS, WARN, FAIL]
+ details:
+ type: string
+
+ ValueCriterion:
+ type: string
+ enum:
+ - RARITY
+ - DEMAND
+ - QUALITY
+ - COMPLETENESS
+ - TIMELINESS
+ - STRATEGIC_IMPORTANCE
+
+ ValueResult:
+ type: object
+ properties:
+ criterion:
+ $ref: '#/components/schemas/ValueCriterion'
+ score:
+ type: number
+ format: double
+ impact:
+ type: string
+ enum: [LOW, MEDIUM, HIGH]
+ explanation:
+ type: string
+
+ EvaluationType:
+ type: string
+ enum:
+ - QUALITY
+ - COMPATIBILITY
+ - VALUE
+ - COMPREHENSIVE
+
+ EvaluationStatus:
+ type: string
+ enum:
+ - PENDING
+ - RUNNING
+ - COMPLETED
+ - FAILED
+
+ QualityIssue:
+ type: object
+ properties:
+ type:
+ type: string
+ severity:
+ type: string
+ enum: [LOW, MEDIUM, HIGH, CRITICAL]
+ description:
+ type: string
+ affectedRecords:
+ type: integer
+ suggestions:
+ type: array
+ items:
+ type: string
+
+ FieldAnalysis:
+ type: object
+ properties:
+ fieldName:
+ type: string
+ dataType:
+ type: string
+ nullCount:
+ type: integer
+ uniqueCount:
+ type: integer
+ statistics:
+ type: object
+
+ DistributionAnalysis:
+ type: object
+ properties:
+ distributions:
+ type: array
+ items:
+ type: object
+ outliers:
+ type: array
+ items:
+ type: object
+ patterns:
+ type: array
+ items:
+ type: string
+
+ CorrelationAnalysis:
+ type: object
+ properties:
+ correlationMatrix:
+ type: array
+ items:
+ type: array
+ items:
+ type: number
+ significantCorrelations:
+ type: array
+ items:
+ type: object
+
+ VisualizationData:
+ type: object
+ properties:
+ type:
+ type: string
+ enum: [CHART, GRAPH, HISTOGRAM, HEATMAP]
+ title:
+ type: string
+ data:
+ type: object
+ config:
+ type: object
+
+ ReportAttachment:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ type:
+ type: string
+ size:
+ type: integer
+ format: int64
+ downloadUrl:
+ type: string
+
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+
+security:
+ - BearerAuth: []
diff --git a/backend/openapi/specs/data-management.yaml b/backend/openapi/specs/data-management.yaml
new file mode 100644
index 0000000..d77083b
--- /dev/null
+++ b/backend/openapi/specs/data-management.yaml
@@ -0,0 +1,719 @@
+openapi: 3.0.3
+info:
+ title: Data Management Service API
+ description: |
+ 数据管理服务API,提供数据集的创建、管理和文件操作功能。
+
+ 主要功能:
+ - 数据集的创建和管理
+ - 多种数据集类型支持(图像、文本、音频、视频、多模态等)
+ - 数据集文件管理
+ - 数据集标签和元数据管理
+ - 数据集统计信息
+ version: 1.0.0
+
+servers:
+ - url: http://localhost:8092/api/v1/data-management
+ description: Development server
+
+tags:
+ - name: Dataset
+ description: 数据集管理
+ - name: DatasetFile
+ description: 数据集文件管理
+ - name: DatasetType
+ description: 数据集类型管理
+ - name: Tag
+ description: 标签管理
+
+paths:
+ /data-management/datasets:
+ get:
+ tags: [Dataset]
+ operationId: getDatasets
+ summary: 获取数据集列表
+ description: 分页查询数据集列表,支持按类型、标签等条件筛选
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ description: 页码,从0开始
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ description: 每页大小
+ - name: type
+ in: query
+ schema:
+ type: string
+ description: 数据集类型过滤
+ - name: tags
+ in: query
+ schema:
+ type: string
+ description: 标签过滤,多个标签用逗号分隔
+ - name: keyword
+ in: query
+ schema:
+ type: string
+ description: 关键词搜索(名称、描述)
+ - name: status
+ in: query
+ schema:
+ type: string
+ enum: [ACTIVE, INACTIVE, PROCESSING]
+ description: 数据集状态过滤
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PagedDatasetResponse'
+ '400':
+ description: 请求参数错误
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+
+ post:
+ tags: [Dataset]
+ operationId: createDataset
+ summary: 创建数据集
+ description: 创建新的数据集
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateDatasetRequest'
+ responses:
+ '201':
+ description: 创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetResponse'
+ '400':
+ description: 请求参数错误
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+
+ /data-management/datasets/{datasetId}:
+ get:
+ tags: [Dataset]
+ operationId: getDatasetById
+ summary: 获取数据集详情
+ description: 根据ID获取数据集详细信息
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetResponse'
+ '404':
+ description: 数据集不存在
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+
+ put:
+ tags: [Dataset]
+ summary: 更新数据集
+ operationId: updateDataset
+ description: 更新数据集信息
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateDatasetRequest'
+ responses:
+ '200':
+ description: 更新成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetResponse'
+ '404':
+ description: 数据集不存在
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+
+ delete:
+ tags: [Dataset]
+ operationId: deleteDataset
+ summary: 删除数据集
+ description: 删除指定的数据集
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ responses:
+ '204':
+ description: 删除成功
+ '404':
+ description: 数据集不存在
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+
+ /data-management/datasets/{datasetId}/files:
+ get:
+ tags: [DatasetFile]
+ summary: 获取数据集文件列表
+ operationId: getDatasetFiles
+ description: 分页获取数据集中的文件列表
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ description: 页码,从0开始
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ description: 每页大小
+ - name: fileType
+ in: query
+ schema:
+ type: string
+ description: 文件类型过滤
+ - name: status
+ in: query
+ schema:
+ type: string
+ enum: [UPLOADED, PROCESSING, COMPLETED, ERROR]
+ description: 文件状态过滤
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PagedDatasetFileResponse'
+
+ post:
+ tags: [DatasetFile]
+ summary: 上传文件到数据集
+ operationId: uploadDatasetFile
+ description: 向指定数据集上传文件
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ requestBody:
+ required: true
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ file:
+ type: string
+ format: binary
+ description: 要上传的文件
+ description:
+ type: string
+ description: 文件描述
+ responses:
+ '201':
+ description: 上传成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetFileResponse'
+
+ /data-management/datasets/{datasetId}/files/{fileId}:
+ get:
+ tags: [DatasetFile]
+ summary: 获取文件详情
+ description: 获取数据集中指定文件的详细信息
+ operationId: getDatasetFileById
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ - name: fileId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 文件ID
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetFileResponse'
+
+ delete:
+ tags: [DatasetFile]
+ summary: 删除文件
+ operationId: deleteDatasetFile
+ description: 从数据集中删除指定文件
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ - name: fileId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 文件ID
+ responses:
+ '204':
+ description: 删除成功
+
+ /data-management/datasets/{datasetId}/files/{fileId}/download:
+ get:
+ tags: [DatasetFile]
+ operationId: downloadDatasetFile
+ summary: 下载文件
+ description: 下载数据集中的指定文件
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ - name: fileId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 文件ID
+ responses:
+ '200':
+ description: 文件内容
+ content:
+ application/octet-stream:
+ schema:
+ type: string
+ format: binary
+
+ /data-management/dataset-types:
+ get:
+ operationId: getDatasetTypes
+ tags: [DatasetType]
+ summary: 获取数据集类型列表
+ description: 获取所有支持的数据集类型
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/DatasetTypeResponse'
+
+ /data-management/tags:
+ get:
+ tags: [Tag]
+ operationId: getTags
+ summary: 获取标签列表
+ description: 获取所有可用的标签
+ parameters:
+ - name: keyword
+ in: query
+ schema:
+ type: string
+ description: 标签名称关键词搜索
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/TagResponse'
+
+ post:
+ tags: [Tag]
+ operationId: createTag
+ summary: 创建标签
+ description: 创建新的标签
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateTagRequest'
+ responses:
+ '201':
+ description: 创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/TagResponse'
+
+ /data-management/datasets/{datasetId}/statistics:
+ get:
+ tags: [Dataset]
+ operationId: getDatasetStatistics
+ summary: 获取数据集统计信息
+ description: 获取数据集的统计信息(文件数量、大小、完成度等)
+ parameters:
+ - name: datasetId
+ in: path
+ required: true
+ schema:
+ type: string
+ description: 数据集ID
+ responses:
+ '200':
+ description: 成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatasetStatisticsResponse'
+
+components:
+ schemas:
+ PagedDatasetResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/DatasetResponse'
+ page:
+ type: integer
+ description: 当前页码
+ size:
+ type: integer
+ description: 每页大小
+ totalElements:
+ type: integer
+ description: 总元素数
+ totalPages:
+ type: integer
+ description: 总页数
+ first:
+ type: boolean
+ description: 是否为第一页
+ last:
+ type: boolean
+ description: 是否为最后一页
+
+ DatasetResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 数据集ID
+ name:
+ type: string
+ description: 数据集名称
+ description:
+ type: string
+ description: 数据集描述
+ type:
+ $ref: '#/components/schemas/DatasetTypeResponse'
+ status:
+ type: string
+ enum: [ACTIVE, INACTIVE, PROCESSING]
+ description: 数据集状态
+ tags:
+ type: array
+ items:
+ $ref: '#/components/schemas/TagResponse'
+ description: 标签列表
+ dataSource:
+ type: string
+ description: 数据源
+ targetLocation:
+ type: string
+ description: 目标位置
+ fileCount:
+ type: integer
+ description: 文件数量
+ totalSize:
+ type: integer
+ format: int64
+ description: 总大小(字节)
+ completionRate:
+ type: number
+ format: float
+ description: 完成率(0-100)
+ createdAt:
+ type: string
+ format: date-time
+ description: 创建时间
+ updatedAt:
+ type: string
+ format: date-time
+ description: 更新时间
+ createdBy:
+ type: string
+ description: 创建者
+
+ CreateDatasetRequest:
+ type: object
+ required:
+ - name
+ - type
+ properties:
+ name:
+ type: string
+ description: 数据集名称
+ minLength: 1
+ maxLength: 100
+ description:
+ type: string
+ description: 数据集描述
+ maxLength: 500
+ type:
+ type: string
+ description: 数据集类型
+ tags:
+ type: array
+ items:
+ type: string
+ description: 标签列表
+ dataSource:
+ type: string
+ description: 数据源
+ targetLocation:
+ type: string
+ description: 目标位置
+
+ UpdateDatasetRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 数据集名称
+ maxLength: 100
+ description:
+ type: string
+ description: 数据集描述
+ maxLength: 500
+ tags:
+ type: array
+ items:
+ type: string
+ description: 标签列表
+ status:
+ type: string
+ enum: [ACTIVE, INACTIVE]
+ description: 数据集状态
+
+ DatasetTypeResponse:
+ type: object
+ properties:
+ code:
+ type: string
+ description: 类型编码
+ name:
+ type: string
+ description: 类型名称
+ description:
+ type: string
+ description: 类型描述
+ supportedFormats:
+ type: array
+ items:
+ type: string
+ description: 支持的文件格式
+ icon:
+ type: string
+ description: 图标
+
+ PagedDatasetFileResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/DatasetFileResponse'
+ page:
+ type: integer
+ description: 当前页码
+ size:
+ type: integer
+ description: 每页大小
+ totalElements:
+ type: integer
+ description: 总元素数
+ totalPages:
+ type: integer
+ description: 总页数
+ first:
+ type: boolean
+ description: 是否为第一页
+ last:
+ type: boolean
+ description: 是否为最后一页
+
+ DatasetFileResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 文件ID
+ fileName:
+ type: string
+ description: 文件名
+ originalName:
+ type: string
+ description: 原始文件名
+ fileType:
+ type: string
+ description: 文件类型
+ fileSize:
+ type: integer
+ format: int64
+ description: 文件大小(字节)
+ status:
+ type: string
+ enum: [UPLOADED, PROCESSING, COMPLETED, ERROR]
+ description: 文件状态
+ description:
+ type: string
+ description: 文件描述
+ filePath:
+ type: string
+ description: 文件路径
+ uploadTime:
+ type: string
+ format: date-time
+ description: 上传时间
+ uploadedBy:
+ type: string
+ description: 上传者
+
+ TagResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 标签ID
+ name:
+ type: string
+ description: 标签名称
+ color:
+ type: string
+ description: 标签颜色
+ description:
+ type: string
+ description: 标签描述
+ usageCount:
+ type: integer
+ description: 使用次数
+
+ CreateTagRequest:
+ type: object
+ required:
+ - name
+ properties:
+ name:
+ type: string
+ description: 标签名称
+ minLength: 1
+ maxLength: 50
+ color:
+ type: string
+ description: 标签颜色
+ pattern: '^#[0-9A-Fa-f]{6}$'
+ description:
+ type: string
+ description: 标签描述
+ maxLength: 200
+
+ DatasetStatisticsResponse:
+ type: object
+ properties:
+ totalFiles:
+ type: integer
+ description: 总文件数
+ completedFiles:
+ type: integer
+ description: 已完成文件数
+ totalSize:
+ type: integer
+ format: int64
+ description: 总大小(字节)
+ completionRate:
+ type: number
+ format: float
+ description: 完成率(0-100)
+ fileTypeDistribution:
+ type: object
+ additionalProperties:
+ type: integer
+ description: 文件类型分布
+ statusDistribution:
+ type: object
+ additionalProperties:
+ type: integer
+ description: 状态分布
+
+ ErrorResponse:
+ type: object
+ properties:
+ error:
+ type: string
+ description: 错误代码
+ message:
+ type: string
+ description: 错误消息
+ timestamp:
+ type: string
+ format: date-time
+ description: 错误时间
+ path:
+ type: string
+ description: 请求路径
diff --git a/backend/openapi/specs/data-synthesis.yaml b/backend/openapi/specs/data-synthesis.yaml
new file mode 100644
index 0000000..c7de7d3
--- /dev/null
+++ b/backend/openapi/specs/data-synthesis.yaml
@@ -0,0 +1,620 @@
+openapi: 3.0.3
+info:
+ title: Data Synthesis Service API
+ description: 数据合成服务API - 指令、COT蒸馏、多模态合成
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8085
+ description: Development server
+
+tags:
+ - name: synthesis-templates
+ description: 合成模板管理
+ - name: synthesis-jobs
+ description: 合成任务管理
+ - name: instruction-tuning
+ description: 指令调优
+ - name: cot-distillation
+ description: COT蒸馏
+
+paths:
+ /api/v1/synthesis/templates:
+ get:
+ tags:
+ - synthesis-templates
+ summary: 获取合成模板列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: type
+ in: query
+ schema:
+ $ref: '#/components/schemas/SynthesisType'
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisTemplatePageResponse'
+
+ post:
+ tags:
+ - synthesis-templates
+ summary: 创建合成模板
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateSynthesisTemplateRequest'
+ responses:
+ '201':
+ description: 创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisTemplateResponse'
+
+ /api/v1/synthesis/templates/{templateId}:
+ get:
+ tags:
+ - synthesis-templates
+ summary: 获取合成模板详情
+ parameters:
+ - name: templateId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisTemplateDetailResponse'
+
+ put:
+ tags:
+ - synthesis-templates
+ summary: 更新合成模板
+ parameters:
+ - name: templateId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateSynthesisTemplateRequest'
+ responses:
+ '200':
+ description: 更新成功
+
+ /api/v1/synthesis/jobs:
+ get:
+ tags:
+ - synthesis-jobs
+ summary: 获取合成任务列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: status
+ in: query
+ schema:
+ $ref: '#/components/schemas/JobStatus'
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisJobPageResponse'
+
+ post:
+ tags:
+ - synthesis-jobs
+ summary: 创建合成任务
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateSynthesisJobRequest'
+ responses:
+ '201':
+ description: 任务创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisJobResponse'
+
+ /api/v1/synthesis/jobs/{jobId}:
+ get:
+ tags:
+ - synthesis-jobs
+ summary: 获取合成任务详情
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SynthesisJobDetailResponse'
+
+ /api/v1/synthesis/jobs/{jobId}/execute:
+ post:
+ tags:
+ - synthesis-jobs
+ summary: 执行合成任务
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 任务开始执行
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/JobExecutionResponse'
+
+ /api/v1/synthesis/instruction-tuning:
+ post:
+ tags:
+ - instruction-tuning
+ summary: 指令调优数据合成
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/InstructionTuningRequest'
+ responses:
+ '200':
+ description: 合成成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/InstructionTuningResponse'
+
+ /api/v1/synthesis/cot-distillation:
+ post:
+ tags:
+ - cot-distillation
+ summary: COT蒸馏数据合成
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/COTDistillationRequest'
+ responses:
+ '200':
+ description: 蒸馏成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/COTDistillationResponse'
+
+components:
+ schemas:
+ SynthesisTemplateResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ type:
+ $ref: '#/components/schemas/SynthesisType'
+ category:
+ type: string
+ modelConfig:
+ $ref: '#/components/schemas/ModelConfig'
+ enabled:
+ type: boolean
+ createdAt:
+ type: string
+ format: date-time
+
+ SynthesisTemplateDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/SynthesisTemplateResponse'
+ - type: object
+ properties:
+ promptTemplate:
+ type: string
+ parameters:
+ type: object
+ examples:
+ type: array
+ items:
+ $ref: '#/components/schemas/SynthesisExample'
+
+ SynthesisTemplatePageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/SynthesisTemplateResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ CreateSynthesisTemplateRequest:
+ type: object
+ required:
+ - name
+ - type
+ - promptTemplate
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ type:
+ $ref: '#/components/schemas/SynthesisType'
+ category:
+ type: string
+ promptTemplate:
+ type: string
+ modelConfig:
+ $ref: '#/components/schemas/ModelConfig'
+ parameters:
+ type: object
+
+ UpdateSynthesisTemplateRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ promptTemplate:
+ type: string
+ enabled:
+ type: boolean
+ parameters:
+ type: object
+
+ SynthesisJobResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ templateId:
+ type: string
+ status:
+ $ref: '#/components/schemas/JobStatus'
+ progress:
+ type: number
+ format: double
+ targetCount:
+ type: integer
+ generatedCount:
+ type: integer
+ startTime:
+ type: string
+ format: date-time
+ endTime:
+ type: string
+ format: date-time
+ createdAt:
+ type: string
+ format: date-time
+
+ SynthesisJobDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/SynthesisJobResponse'
+ - type: object
+ properties:
+ template:
+ $ref: '#/components/schemas/SynthesisTemplateResponse'
+ statistics:
+ $ref: '#/components/schemas/SynthesisStatistics'
+ samples:
+ type: array
+ items:
+ $ref: '#/components/schemas/GeneratedSample'
+
+ SynthesisJobPageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/SynthesisJobResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ CreateSynthesisJobRequest:
+ type: object
+ required:
+ - name
+ - templateId
+ - targetCount
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ templateId:
+ type: string
+ targetCount:
+ type: integer
+ parameters:
+ type: object
+ seedData:
+ type: array
+ items:
+ type: object
+
+ JobExecutionResponse:
+ type: object
+ properties:
+ executionId:
+ type: string
+ status:
+ type: string
+ message:
+ type: string
+
+ InstructionTuningRequest:
+ type: object
+ required:
+ - baseInstructions
+ - targetDomain
+ - count
+ properties:
+ baseInstructions:
+ type: array
+ items:
+ type: string
+ targetDomain:
+ type: string
+ count:
+ type: integer
+ modelConfig:
+ $ref: '#/components/schemas/ModelConfig'
+ parameters:
+ type: object
+
+ InstructionTuningResponse:
+ type: object
+ properties:
+ jobId:
+ type: string
+ generatedInstructions:
+ type: array
+ items:
+ $ref: '#/components/schemas/GeneratedInstruction'
+ statistics:
+ $ref: '#/components/schemas/GenerationStatistics'
+
+ COTDistillationRequest:
+ type: object
+ required:
+ - sourceModel
+ - targetFormat
+ - examples
+ properties:
+ sourceModel:
+ type: string
+ targetFormat:
+ type: string
+ enum: [QA, INSTRUCTION, REASONING]
+ examples:
+ type: array
+ items:
+ $ref: '#/components/schemas/COTExample'
+ parameters:
+ type: object
+
+ COTDistillationResponse:
+ type: object
+ properties:
+ jobId:
+ type: string
+ distilledData:
+ type: array
+ items:
+ $ref: '#/components/schemas/DistilledCOTData'
+ statistics:
+ $ref: '#/components/schemas/DistillationStatistics'
+
+ SynthesisType:
+ type: string
+ enum:
+ - INSTRUCTION_TUNING
+ - COT_DISTILLATION
+ - DIALOGUE_GENERATION
+ - TEXT_AUGMENTATION
+ - MULTIMODAL_SYNTHESIS
+ - CUSTOM
+
+ JobStatus:
+ type: string
+ enum:
+ - PENDING
+ - RUNNING
+ - COMPLETED
+ - FAILED
+ - CANCELLED
+
+ ModelConfig:
+ type: object
+ properties:
+ modelName:
+ type: string
+ temperature:
+ type: number
+ format: double
+ maxTokens:
+ type: integer
+ topP:
+ type: number
+ format: double
+ frequencyPenalty:
+ type: number
+ format: double
+
+ SynthesisExample:
+ type: object
+ properties:
+ input:
+ type: string
+ output:
+ type: string
+ explanation:
+ type: string
+
+ SynthesisStatistics:
+ type: object
+ properties:
+ totalGenerated:
+ type: integer
+ successfulGenerated:
+ type: integer
+ failedGenerated:
+ type: integer
+ averageLength:
+ type: number
+ format: double
+ uniqueCount:
+ type: integer
+
+ GeneratedSample:
+ type: object
+ properties:
+ id:
+ type: string
+ content:
+ type: string
+ score:
+ type: number
+ format: double
+ metadata:
+ type: object
+ createdAt:
+ type: string
+ format: date-time
+
+ GeneratedInstruction:
+ type: object
+ properties:
+ instruction:
+ type: string
+ input:
+ type: string
+ output:
+ type: string
+ quality:
+ type: number
+ format: double
+
+ GenerationStatistics:
+ type: object
+ properties:
+ totalGenerated:
+ type: integer
+ averageQuality:
+ type: number
+ format: double
+ diversityScore:
+ type: number
+ format: double
+
+ COTExample:
+ type: object
+ properties:
+ question:
+ type: string
+ reasoning:
+ type: string
+ answer:
+ type: string
+
+ DistilledCOTData:
+ type: object
+ properties:
+ question:
+ type: string
+ reasoning:
+ type: string
+ answer:
+ type: string
+ confidence:
+ type: number
+ format: double
+
+ DistillationStatistics:
+ type: object
+ properties:
+ totalProcessed:
+ type: integer
+ successfulDistilled:
+ type: integer
+ averageConfidence:
+ type: number
+ format: double
+
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+
+security:
+ - BearerAuth: []
diff --git a/backend/openapi/specs/execution-engine.yaml b/backend/openapi/specs/execution-engine.yaml
new file mode 100644
index 0000000..276782a
--- /dev/null
+++ b/backend/openapi/specs/execution-engine.yaml
@@ -0,0 +1,712 @@
+openapi: 3.0.3
+info:
+ title: Execution Engine Service API
+ description: 执行引擎服务API - 与Ray/DataX/Python执行器对接
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8088
+ description: Development server
+
+tags:
+ - name: jobs
+ description: 作业管理
+ - name: executors
+ description: 执行器管理
+ - name: resources
+ description: 资源管理
+ - name: monitoring
+ description: 监控管理
+
+paths:
+ /api/v1/jobs:
+ get:
+ tags:
+ - jobs
+ summary: 获取作业列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: status
+ in: query
+ schema:
+ $ref: '#/components/schemas/JobStatus'
+ - name: executor
+ in: query
+ schema:
+ $ref: '#/components/schemas/ExecutorType'
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/JobPageResponse'
+
+ post:
+ tags:
+ - jobs
+ summary: 提交作业
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/SubmitJobRequest'
+ responses:
+ '201':
+ description: 作业提交成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/JobResponse'
+
+ /api/v1/jobs/{jobId}:
+ get:
+ tags:
+ - jobs
+ summary: 获取作业详情
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/JobDetailResponse'
+
+ delete:
+ tags:
+ - jobs
+ summary: 取消作业
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 取消成功
+
+ /api/v1/jobs/{jobId}/logs:
+ get:
+ tags:
+ - jobs
+ summary: 获取作业日志
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ - name: follow
+ in: query
+ description: 是否实时跟踪日志
+ schema:
+ type: boolean
+ default: false
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/JobLog'
+
+ /api/v1/jobs/{jobId}/retry:
+ post:
+ tags:
+ - jobs
+ summary: 重试作业
+ parameters:
+ - name: jobId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 重试成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/JobResponse'
+
+ /api/v1/executors:
+ get:
+ tags:
+ - executors
+ summary: 获取执行器列表
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/ExecutorResponse'
+
+ post:
+ tags:
+ - executors
+ summary: 注册执行器
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/RegisterExecutorRequest'
+ responses:
+ '201':
+ description: 注册成功
+
+ /api/v1/executors/{executorId}:
+ get:
+ tags:
+ - executors
+ summary: 获取执行器详情
+ parameters:
+ - name: executorId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ExecutorDetailResponse'
+
+ put:
+ tags:
+ - executors
+ summary: 更新执行器
+ parameters:
+ - name: executorId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateExecutorRequest'
+ responses:
+ '200':
+ description: 更新成功
+
+ /api/v1/resources/clusters:
+ get:
+ tags:
+ - resources
+ summary: 获取集群信息
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/ClusterInfo'
+
+ /api/v1/resources/nodes:
+ get:
+ tags:
+ - resources
+ summary: 获取节点信息
+ parameters:
+ - name: clusterId
+ in: query
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/NodeInfo'
+
+ /api/v1/monitoring/metrics:
+ get:
+ tags:
+ - monitoring
+ summary: 获取监控指标
+ parameters:
+ - name: metric
+ in: query
+ schema:
+ type: string
+ - name: start
+ in: query
+ schema:
+ type: string
+ format: date-time
+ - name: end
+ in: query
+ schema:
+ type: string
+ format: date-time
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/MetricsResponse'
+
+components:
+ schemas:
+ JobResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ status:
+ $ref: '#/components/schemas/JobStatus'
+ executorType:
+ $ref: '#/components/schemas/ExecutorType'
+ priority:
+ type: integer
+ progress:
+ type: number
+ format: double
+ submittedAt:
+ type: string
+ format: date-time
+ startedAt:
+ type: string
+ format: date-time
+ completedAt:
+ type: string
+ format: date-time
+ submittedBy:
+ type: string
+
+ JobDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/JobResponse'
+ - type: object
+ properties:
+ configuration:
+ $ref: '#/components/schemas/JobConfiguration'
+ resources:
+ $ref: '#/components/schemas/ResourceRequirement'
+ metrics:
+ $ref: '#/components/schemas/JobMetrics'
+ artifacts:
+ type: array
+ items:
+ $ref: '#/components/schemas/JobArtifact'
+ dependencies:
+ type: array
+ items:
+ type: string
+
+ JobPageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/JobResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ SubmitJobRequest:
+ type: object
+ required:
+ - name
+ - executorType
+ - configuration
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ executorType:
+ $ref: '#/components/schemas/ExecutorType'
+ priority:
+ type: integer
+ minimum: 1
+ maximum: 10
+ default: 5
+ configuration:
+ $ref: '#/components/schemas/JobConfiguration'
+ resources:
+ $ref: '#/components/schemas/ResourceRequirement'
+ dependencies:
+ type: array
+ items:
+ type: string
+ timeoutSeconds:
+ type: integer
+
+ JobConfiguration:
+ type: object
+ properties:
+ script:
+ type: string
+ description: 执行脚本或代码
+ arguments:
+ type: array
+ items:
+ type: string
+ description: 执行参数
+ environment:
+ type: object
+ description: 环境变量
+ files:
+ type: array
+ items:
+ $ref: '#/components/schemas/FileReference'
+ packages:
+ type: array
+ items:
+ type: string
+ description: 依赖包列表
+
+ ResourceRequirement:
+ type: object
+ properties:
+ cpuCores:
+ type: number
+ format: double
+ memoryGB:
+ type: number
+ format: double
+ gpuCount:
+ type: integer
+ diskGB:
+ type: number
+ format: double
+ nodeSelector:
+ type: object
+ description: 节点选择器
+
+ ExecutorResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ type:
+ $ref: '#/components/schemas/ExecutorType'
+ status:
+ $ref: '#/components/schemas/ExecutorStatus'
+ version:
+ type: string
+ capabilities:
+ type: array
+ items:
+ type: string
+ registeredAt:
+ type: string
+ format: date-time
+ lastHeartbeat:
+ type: string
+ format: date-time
+
+ ExecutorDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/ExecutorResponse'
+ - type: object
+ properties:
+ configuration:
+ type: object
+ resources:
+ $ref: '#/components/schemas/ExecutorResources'
+ currentJobs:
+ type: array
+ items:
+ $ref: '#/components/schemas/JobResponse'
+ statistics:
+ $ref: '#/components/schemas/ExecutorStatistics'
+
+ RegisterExecutorRequest:
+ type: object
+ required:
+ - name
+ - type
+ - endpoint
+ properties:
+ name:
+ type: string
+ type:
+ $ref: '#/components/schemas/ExecutorType'
+ endpoint:
+ type: string
+ capabilities:
+ type: array
+ items:
+ type: string
+ configuration:
+ type: object
+
+ UpdateExecutorRequest:
+ type: object
+ properties:
+ status:
+ $ref: '#/components/schemas/ExecutorStatus'
+ configuration:
+ type: object
+
+ ClusterInfo:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ type:
+ type: string
+ enum: [RAY, KUBERNETES, YARN, STANDALONE]
+ status:
+ type: string
+ enum: [ACTIVE, INACTIVE, ERROR]
+ nodeCount:
+ type: integer
+ totalCpuCores:
+ type: integer
+ totalMemoryGB:
+ type: number
+ format: double
+ totalGpuCount:
+ type: integer
+ availableResources:
+ $ref: '#/components/schemas/ResourceInfo'
+
+ NodeInfo:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ clusterId:
+ type: string
+ status:
+ type: string
+ enum: [ACTIVE, INACTIVE, BUSY, ERROR]
+ resources:
+ $ref: '#/components/schemas/ResourceInfo'
+ usage:
+ $ref: '#/components/schemas/ResourceUsage'
+ lastUpdate:
+ type: string
+ format: date-time
+
+ MetricsResponse:
+ type: object
+ properties:
+ metric:
+ type: string
+ dataPoints:
+ type: array
+ items:
+ $ref: '#/components/schemas/MetricDataPoint'
+ aggregation:
+ type: object
+
+ JobLog:
+ type: object
+ properties:
+ timestamp:
+ type: string
+ format: date-time
+ level:
+ type: string
+ enum: [DEBUG, INFO, WARN, ERROR]
+ source:
+ type: string
+ message:
+ type: string
+
+ JobMetrics:
+ type: object
+ properties:
+ cpuUsage:
+ type: number
+ format: double
+ memoryUsage:
+ type: number
+ format: double
+ diskUsage:
+ type: number
+ format: double
+ networkIO:
+ type: object
+ duration:
+ type: integer
+ format: int64
+
+ JobArtifact:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ type:
+ type: string
+ enum: [LOG, OUTPUT, CHECKPOINT, MODEL]
+ size:
+ type: integer
+ format: int64
+ path:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+
+ FileReference:
+ type: object
+ properties:
+ name:
+ type: string
+ path:
+ type: string
+ type:
+ type: string
+ enum: [LOCAL, HDFS, S3, HTTP]
+
+ ExecutorResources:
+ type: object
+ properties:
+ total:
+ $ref: '#/components/schemas/ResourceInfo'
+ available:
+ $ref: '#/components/schemas/ResourceInfo'
+ allocated:
+ $ref: '#/components/schemas/ResourceInfo'
+
+ ExecutorStatistics:
+ type: object
+ properties:
+ totalJobs:
+ type: integer
+ successfulJobs:
+ type: integer
+ failedJobs:
+ type: integer
+ averageExecutionTime:
+ type: number
+ format: double
+ uptime:
+ type: integer
+ format: int64
+
+ ResourceInfo:
+ type: object
+ properties:
+ cpuCores:
+ type: number
+ format: double
+ memoryGB:
+ type: number
+ format: double
+ gpuCount:
+ type: integer
+ diskGB:
+ type: number
+ format: double
+
+ ResourceUsage:
+ type: object
+ properties:
+ cpuUsagePercent:
+ type: number
+ format: double
+ memoryUsagePercent:
+ type: number
+ format: double
+ diskUsagePercent:
+ type: number
+ format: double
+
+ MetricDataPoint:
+ type: object
+ properties:
+ timestamp:
+ type: string
+ format: date-time
+ value:
+ type: number
+ format: double
+ tags:
+ type: object
+
+ JobStatus:
+ type: string
+ enum:
+ - SUBMITTED
+ - PENDING
+ - RUNNING
+ - COMPLETED
+ - FAILED
+ - CANCELLED
+ - TIMEOUT
+
+ ExecutorType:
+ type: string
+ enum:
+ - RAY
+ - DATAX
+ - PYTHON
+ - SPARK
+ - FLINK
+ - CUSTOM
+
+ ExecutorStatus:
+ type: string
+ enum:
+ - ACTIVE
+ - INACTIVE
+ - BUSY
+ - ERROR
+ - MAINTENANCE
+
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+
+security:
+ - BearerAuth: []
diff --git a/backend/openapi/specs/operator-market.yaml b/backend/openapi/specs/operator-market.yaml
new file mode 100644
index 0000000..8a6c172
--- /dev/null
+++ b/backend/openapi/specs/operator-market.yaml
@@ -0,0 +1,547 @@
+openapi: 3.0.1
+info:
+ title: Operator Market Service API
+ description: |
+ 算子市场服务API,提供算子的发布、管理和订阅功能。
+
+ 主要功能:
+ - 算子发布和管理
+ - 算子版本控制
+ - 算子评分和评论
+ - 算子分类和标签
+ - 算子下载和安装
+ version: 1.0.0
+tags:
+ - name: Operator
+ - name: Category
+ - name: Label
+paths:
+ /operators/list:
+ post:
+ summary: 获取算子列表
+ deprecated: false
+ description: 分页查询算子列表,支持按分类、标签等条件筛选
+ tags:
+ - Operator
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ page:
+ type: integer
+ description: 页数
+ size:
+ type: integer
+ description: 单页数量
+ categories:
+ type: array
+ items:
+ type: integer
+ description: 分类id列表
+ operatorName:
+ type: string
+ description: 算子名称
+ labelName:
+ type: string
+ description: 标签名称
+ isStar:
+ type: boolean
+ description: 是否收藏
+ required:
+ - page
+ - size
+ - categories
+ examples: {}
+ responses:
+ '200':
+ description: 成功返回算子列表
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/OperatorResponse'
+ headers: {}
+ security: []
+ /operators/create:
+ post:
+ summary: 创建新算子
+ deprecated: false
+ description: 创建并发布一个新的算子
+ tags:
+ - Operator
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateOperatorRequest'
+ example: null
+ responses:
+ '201':
+ description: 算子创建成功
+ content:
+ application/json:
+ schema: &ref_0
+ $ref: '#/components/schemas/OperatorResponse'
+ headers: {}
+ security: []
+ /operators/upload:
+ post:
+ summary: 上传新算子
+ deprecated: false
+ description: 创建并发布一个新的算子
+ tags:
+ - Operator
+ parameters: []
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ file:
+ type: string
+ format: binary
+ example: ''
+ description:
+ type: string
+ example: ''
+ examples: {}
+ responses:
+ '201':
+ description: 算子创建成功
+ content:
+ application/json:
+ schema: *ref_0
+ headers: {}
+ security: []
+ /operators/{id}:
+ get:
+ summary: 获取算子详情
+ deprecated: false
+ description: 根据ID获取算子的详细信息
+ tags:
+ - Operator
+ parameters:
+ - name: id
+ in: path
+ description: 算子ID
+ required: true
+ example: ''
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 成功返回算子详情
+ content:
+ application/json:
+ schema: *ref_0
+ headers: {}
+ '404':
+ description: 算子不存在
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
+ headers: {}
+ security: []
+ put:
+ summary: 更新算子信息
+ deprecated: false
+ description: 根据ID更新算子信息
+ tags:
+ - Operator
+ parameters:
+ - name: id
+ in: path
+ description: 算子ID
+ required: true
+ example: ''
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateOperatorRequest'
+ example: null
+ responses:
+ '200':
+ description: 算子更新成功
+ content:
+ application/json:
+ schema: *ref_0
+ headers: {}
+ security: []
+ /category:
+ post:
+ summary: 创建算子分类
+ deprecated: false
+ description: ''
+ tags:
+ - Category
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 名称
+ parentId:
+ type: integer
+ description: 父分类id
+ required:
+ - name
+ - parentId
+ responses:
+ '201':
+ description: ''
+ headers: {}
+ security: []
+ delete:
+ summary: 删除算子分类
+ deprecated: false
+ description: ''
+ tags:
+ - Category
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ id:
+ type: integer
+ description: ID 编号
+ required:
+ - id
+ responses:
+ '204':
+ description: ''
+ headers: {}
+ security: []
+ /categories/tree:
+ get:
+ summary: 获取算子分类列表
+ deprecated: false
+ description: 获取所有可用的算子分类
+ tags:
+ - Category
+ parameters: []
+ responses:
+ '200':
+ description: 成功返回分类列表
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: object
+ properties:
+ id:
+ type: integer
+ name:
+ type: string
+ count:
+ type: integer
+ categories:
+ $ref: '#/components/schemas/CategoryResponse'
+ required:
+ - id
+ - name
+ - count
+ - categories
+ headers: {}
+ security: []
+ /labels:
+ get:
+ summary: 获取算子标签列表
+ deprecated: false
+ description: 获取所有算子的标签
+ tags:
+ - Label
+ parameters:
+ - name: page
+ in: query
+ description: 页码,从0开始
+ required: false
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ description: 每页大小
+ required: false
+ schema:
+ type: integer
+ default: 20
+ - name: keyword
+ in: query
+ description: 关键词搜索
+ required: false
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 成功返回标签列表
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/LabelResponse'
+ headers: {}
+ security: []
+ post:
+ summary: 创建标签
+ deprecated: false
+ description: 批量创建标签
+ tags:
+ - Label
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 名称
+ required:
+ - name
+ example: veniam
+ responses:
+ '201':
+ description: 创建成功
+ headers: {}
+ security: []
+ delete:
+ summary: 删除标签
+ deprecated: false
+ description: 批量删除标签
+ tags:
+ - Label
+ parameters: []
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: integer
+ format: int64
+ description: 标签id列表
+ example: null
+ responses:
+ '204':
+ description: 删除成功
+ headers: {}
+ security: []
+ /labels/{id}:
+ put:
+ summary: 更新标签
+ deprecated: false
+ description: 更新标签
+ tags:
+ - Label
+ parameters:
+ - name: id
+ in: path
+ description: 标签ID
+ required: true
+ example: ''
+ schema:
+ type: string
+ requestBody:
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/UpdateLabelRequest'
+ example: null
+ responses:
+ '200':
+ description: 更新成功
+ headers: {}
+ security: []
+components:
+ schemas:
+ UpdateLabelRequest:
+ type: object
+ required:
+ - id
+ - name
+ properties:
+ id:
+ type: integer
+ description: 标签id
+ name:
+ type: string
+ description: 标签名称
+ Response:
+ type: object
+ properties:
+ code:
+ type: string
+ message:
+ type: string
+ data:
+ type: object
+ properties: {}
+ required:
+ - code
+ - message
+ - data
+ LabelResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 标签ID
+ name:
+ type: string
+ description: 标签名称
+ SubCategory:
+ type: object
+ properties:
+ id:
+ type: integer
+ description: 分类id
+ name:
+ type: string
+ description: 分类名称
+ count:
+ type: integer
+ type:
+ type: string
+ description: 分类类型(0:预置,1:自定义)
+ parentId:
+ type: integer
+ description: 父分类id
+ required:
+ - id
+ - name
+ - type
+ - parentId
+ - count
+ CategoryResponse:
+ type: array
+ items:
+ $ref: '#/components/schemas/SubCategory'
+ UpdateOperatorRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description: 算子名称
+ description:
+ type: string
+ description: 算子描述
+ version:
+ type: string
+ description: 算子版本
+ category:
+ type: string
+ description: 算子分类
+ documentation:
+ type: string
+ description: 文档内容
+ ErrorResponse:
+ type: object
+ properties:
+ error:
+ type: string
+ description: 错误代码
+ message:
+ type: string
+ description: 错误信息
+ timestamp:
+ type: string
+ format: date-time
+ description: 错误时间
+ OperatorResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ description: 算子ID
+ name:
+ type: string
+ description: 算子名称
+ description:
+ type: string
+ description: 算子描述
+ version:
+ type: string
+ description: 算子版本
+ inputs:
+ type: string
+ description: 输入类型
+ outputs:
+ type: string
+ description: 输入类型
+ categories:
+ type: array
+ description: 算子分类列表
+ items:
+ type: integer
+ runtime:
+ type: string
+ description: 运行时设置
+ settings:
+ type: string
+ description: 算子参数
+ isStar:
+ type: boolean
+ description: 是否收藏
+ createdAt:
+ type: string
+ format: date-time
+ description: 创建时间
+ updatedAt:
+ type: string
+ format: date-time
+ description: 更新时间
+ required:
+ - language
+ - modal
+ - inputs
+ - outputs
+ - runtime
+ - settings
+ - isStar
+ CreateOperatorRequest:
+ type: object
+ required:
+ - name
+ - description
+ - version
+ - category
+ properties:
+ name:
+ type: string
+ description: 算子名称
+ description:
+ type: string
+ description: 算子描述
+ version:
+ type: string
+ description: 算子版本
+ category:
+ type: string
+ description: 算子分类
+ documentation:
+ type: string
+ description: 文档内容
+ securitySchemes: {}
+servers: []
diff --git a/backend/openapi/specs/pipeline-orchestration.yaml b/backend/openapi/specs/pipeline-orchestration.yaml
new file mode 100644
index 0000000..8a2de68
--- /dev/null
+++ b/backend/openapi/specs/pipeline-orchestration.yaml
@@ -0,0 +1,639 @@
+openapi: 3.0.3
+info:
+ title: Pipeline Orchestration Service API
+ description: 流程编排服务API - 可视化、模板、执行计划
+ version: 1.0.0
+ contact:
+ name: Data Mate Platform Team
+
+servers:
+ - url: http://localhost:8087
+ description: Development server
+
+tags:
+ - name: pipelines
+ description: 流水线管理
+ - name: pipeline-templates
+ description: 流水线模板
+ - name: executions
+ description: 执行管理
+ - name: workflows
+ description: 工作流编排
+
+paths:
+ /api/v1/pipelines:
+ get:
+ tags:
+ - pipelines
+ summary: 获取流水线列表
+ parameters:
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ - name: size
+ in: query
+ schema:
+ type: integer
+ default: 20
+ - name: status
+ in: query
+ schema:
+ $ref: '#/components/schemas/PipelineStatus'
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PipelinePageResponse'
+
+ post:
+ tags:
+ - pipelines
+ summary: 创建流水线
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreatePipelineRequest'
+ responses:
+ '201':
+ description: 创建成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PipelineResponse'
+
+ /api/v1/pipelines/{pipelineId}:
+ get:
+ tags:
+ - pipelines
+ summary: 获取流水线详情
+ parameters:
+ - name: pipelineId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PipelineDetailResponse'
+
+ put:
+ tags:
+ - pipelines
+ summary: 更新流水线
+ parameters:
+ - name: pipelineId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdatePipelineRequest'
+ responses:
+ '200':
+ description: 更新成功
+
+ /api/v1/pipelines/{pipelineId}/execute:
+ post:
+ tags:
+ - executions
+ summary: 执行流水线
+ parameters:
+ - name: pipelineId
+ in: path
+ required: true
+ schema:
+ type: string
+ requestBody:
+ required: false
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ExecutePipelineRequest'
+ responses:
+ '200':
+ description: 执行开始
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PipelineExecutionResponse'
+
+ /api/v1/executions:
+ get:
+ tags:
+ - executions
+ summary: 获取执行历史
+ parameters:
+ - name: pipelineId
+ in: query
+ schema:
+ type: string
+ - name: status
+ in: query
+ schema:
+ $ref: '#/components/schemas/ExecutionStatus'
+ - name: page
+ in: query
+ schema:
+ type: integer
+ default: 0
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ExecutionPageResponse'
+
+ /api/v1/executions/{executionId}:
+ get:
+ tags:
+ - executions
+ summary: 获取执行详情
+ parameters:
+ - name: executionId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ExecutionDetailResponse'
+
+ /api/v1/executions/{executionId}/stop:
+ post:
+ tags:
+ - executions
+ summary: 停止执行
+ parameters:
+ - name: executionId
+ in: path
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 停止成功
+
+ /api/v1/templates:
+ get:
+ tags:
+ - pipeline-templates
+ summary: 获取模板列表
+ parameters:
+ - name: category
+ in: query
+ schema:
+ type: string
+ responses:
+ '200':
+ description: 获取成功
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineTemplateResponse'
+
+ post:
+ tags:
+ - pipeline-templates
+ summary: 创建模板
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreatePipelineTemplateRequest'
+ responses:
+ '201':
+ description: 创建成功
+
+components:
+ schemas:
+ PipelineResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ status:
+ $ref: '#/components/schemas/PipelineStatus'
+ version:
+ type: string
+ category:
+ type: string
+ tags:
+ type: array
+ items:
+ type: string
+ createdBy:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+ lastModified:
+ type: string
+ format: date-time
+
+ PipelineDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/PipelineResponse'
+ - type: object
+ properties:
+ definition:
+ $ref: '#/components/schemas/PipelineDefinition'
+ parameters:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineParameter'
+ dependencies:
+ type: array
+ items:
+ type: string
+ statistics:
+ $ref: '#/components/schemas/PipelineStatistics'
+
+ PipelinePageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ CreatePipelineRequest:
+ type: object
+ required:
+ - name
+ - definition
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ category:
+ type: string
+ definition:
+ $ref: '#/components/schemas/PipelineDefinition'
+ parameters:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineParameter'
+ tags:
+ type: array
+ items:
+ type: string
+
+ UpdatePipelineRequest:
+ type: object
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ definition:
+ $ref: '#/components/schemas/PipelineDefinition'
+ status:
+ $ref: '#/components/schemas/PipelineStatus'
+
+ ExecutePipelineRequest:
+ type: object
+ properties:
+ parameters:
+ type: object
+ description: 执行参数
+ environment:
+ type: string
+ description: 执行环境
+ priority:
+ type: integer
+ description: 优先级
+
+ PipelineExecutionResponse:
+ type: object
+ properties:
+ executionId:
+ type: string
+ pipelineId:
+ type: string
+ status:
+ $ref: '#/components/schemas/ExecutionStatus'
+ startTime:
+ type: string
+ format: date-time
+ message:
+ type: string
+
+ ExecutionResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ pipelineId:
+ type: string
+ pipelineName:
+ type: string
+ status:
+ $ref: '#/components/schemas/ExecutionStatus'
+ progress:
+ type: number
+ format: double
+ startTime:
+ type: string
+ format: date-time
+ endTime:
+ type: string
+ format: date-time
+ duration:
+ type: integer
+ format: int64
+ description: 执行时长(毫秒)
+
+ ExecutionDetailResponse:
+ allOf:
+ - $ref: '#/components/schemas/ExecutionResponse'
+ - type: object
+ properties:
+ steps:
+ type: array
+ items:
+ $ref: '#/components/schemas/ExecutionStep'
+ logs:
+ type: array
+ items:
+ $ref: '#/components/schemas/ExecutionLog'
+ metrics:
+ $ref: '#/components/schemas/ExecutionMetrics'
+ artifacts:
+ type: array
+ items:
+ $ref: '#/components/schemas/ExecutionArtifact'
+
+ ExecutionPageResponse:
+ type: object
+ properties:
+ content:
+ type: array
+ items:
+ $ref: '#/components/schemas/ExecutionResponse'
+ totalElements:
+ type: integer
+ format: int64
+ totalPages:
+ type: integer
+ size:
+ type: integer
+ number:
+ type: integer
+
+ PipelineTemplateResponse:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ description:
+ type: string
+ category:
+ type: string
+ version:
+ type: string
+ definition:
+ $ref: '#/components/schemas/PipelineDefinition'
+ usageCount:
+ type: integer
+ createdAt:
+ type: string
+ format: date-time
+
+ CreatePipelineTemplateRequest:
+ type: object
+ required:
+ - name
+ - definition
+ properties:
+ name:
+ type: string
+ description:
+ type: string
+ category:
+ type: string
+ definition:
+ $ref: '#/components/schemas/PipelineDefinition'
+
+ PipelineDefinition:
+ type: object
+ properties:
+ nodes:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineNode'
+ edges:
+ type: array
+ items:
+ $ref: '#/components/schemas/PipelineEdge'
+ settings:
+ type: object
+ description: 流水线设置
+
+ PipelineNode:
+ type: object
+ properties:
+ id:
+ type: string
+ type:
+ type: string
+ enum: [OPERATOR, CONDITION, LOOP, PARALLEL]
+ name:
+ type: string
+ operatorId:
+ type: string
+ configuration:
+ type: object
+ position:
+ $ref: '#/components/schemas/NodePosition'
+
+ PipelineEdge:
+ type: object
+ properties:
+ id:
+ type: string
+ source:
+ type: string
+ target:
+ type: string
+ condition:
+ type: string
+ type:
+ type: string
+ enum: [SUCCESS, FAILURE, ALWAYS]
+
+ NodePosition:
+ type: object
+ properties:
+ x:
+ type: number
+ y:
+ type: number
+
+ PipelineParameter:
+ type: object
+ properties:
+ name:
+ type: string
+ type:
+ type: string
+ required:
+ type: boolean
+ defaultValue:
+ type: string
+ description:
+ type: string
+
+ PipelineStatistics:
+ type: object
+ properties:
+ totalExecutions:
+ type: integer
+ successfulExecutions:
+ type: integer
+ failedExecutions:
+ type: integer
+ averageDuration:
+ type: number
+ format: double
+ lastExecutionTime:
+ type: string
+ format: date-time
+
+ ExecutionStep:
+ type: object
+ properties:
+ id:
+ type: string
+ nodeId:
+ type: string
+ name:
+ type: string
+ status:
+ $ref: '#/components/schemas/ExecutionStatus'
+ startTime:
+ type: string
+ format: date-time
+ endTime:
+ type: string
+ format: date-time
+ duration:
+ type: integer
+ format: int64
+ message:
+ type: string
+
+ ExecutionLog:
+ type: object
+ properties:
+ timestamp:
+ type: string
+ format: date-time
+ level:
+ type: string
+ enum: [DEBUG, INFO, WARN, ERROR]
+ nodeId:
+ type: string
+ message:
+ type: string
+
+ ExecutionMetrics:
+ type: object
+ properties:
+ totalNodes:
+ type: integer
+ completedNodes:
+ type: integer
+ failedNodes:
+ type: integer
+ cpuUsage:
+ type: number
+ format: double
+ memoryUsage:
+ type: number
+ format: double
+ throughput:
+ type: number
+ format: double
+
+ ExecutionArtifact:
+ type: object
+ properties:
+ id:
+ type: string
+ name:
+ type: string
+ type:
+ type: string
+ size:
+ type: integer
+ format: int64
+ path:
+ type: string
+ createdAt:
+ type: string
+ format: date-time
+
+ PipelineStatus:
+ type: string
+ enum:
+ - DRAFT
+ - ACTIVE
+ - INACTIVE
+ - DEPRECATED
+
+ ExecutionStatus:
+ type: string
+ enum:
+ - PENDING
+ - RUNNING
+ - SUCCESS
+ - FAILED
+ - CANCELLED
+ - SKIPPED
+
+ securitySchemes:
+ BearerAuth:
+ type: http
+ scheme: bearer
+ bearerFormat: JWT
+
+security:
+ - BearerAuth: []
diff --git a/backend/pom.xml b/backend/pom.xml
new file mode 100644
index 0000000..682eaa0
--- /dev/null
+++ b/backend/pom.xml
@@ -0,0 +1,212 @@
+
+
+ 4.0.0
+
+ com.datamate
+ data-mate-platform
+ 1.0.0-SNAPSHOT
+ pom
+
+ DataMatePlatform
+ 一站式数据工作平台,面向模型微调与RAG检索
+
+
+ 21
+ 21
+ UTF-8
+
+ 3.5.6
+ 2025.0.0
+ 8.0.33
+ 42.6.0
+ 3.2.0
+ 8.11.0
+ 5.10.0
+ 2.2.0
+ 0.2.6
+ 3.0.2
+ 3.1.0
+ 3.3.0
+ 3.5.14
+ 1.6.3
+ 1.18.32
+ 0.2.0
+ 5.4.0
+ 2.21.1
+
+
+
+
+ shared/domain-common
+ shared/security-common
+
+
+ services/data-management-service
+ services/data-collection-service
+ services/operator-market-service
+ services/data-cleaning-service
+ services/data-synthesis-service
+ services/data-annotation-service
+ services/data-evaluation-service
+ services/pipeline-orchestration-service
+ services/execution-engine-service
+
+
+ services/rag-indexer-service
+ services/rag-query-service
+
+
+ services/main-application
+
+
+ api-gateway
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring-boot.version}
+ pom
+ import
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ ${springdoc.version}
+
+
+ org.openapitools
+ jackson-databind-nullable
+ ${jackson-databind-nullable.version}
+
+
+ jakarta.validation
+ jakarta.validation-api
+ ${jakarta-validation.version}
+
+
+
+ jakarta.persistence
+ jakarta.persistence-api
+ ${jakarta.persistence.version}
+
+
+
+ com.baomidou
+ mybatis-plus-bom
+ ${mybatis-plus.version}
+ pom
+ import
+
+
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+
+ org.apache.poi
+ poi
+ ${poi.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ ${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ ${spring-boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-logging
+
+
+
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+ ${mybatis-plus.version}
+
+
+ com.baomidou
+ mybatis-plus-jsqlparser
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-log4j2
+ ${spring-boot.version}
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+
+
+
+ org.apache.poi
+ poi
+ ${poi.version}
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring-boot.version}
+
+
+
+
diff --git a/backend/services/data-annotation-service/pom.xml b/backend/services/data-annotation-service/pom.xml
new file mode 100644
index 0000000..a91d058
--- /dev/null
+++ b/backend/services/data-annotation-service/pom.xml
@@ -0,0 +1,101 @@
+
+
+ 4.0.0
+
+
+ com.datamate
+ data-mate-platform
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+
+ data-annotation-service
+ Data Annotation Service
+ 数据标注服务
+
+
+
+ com.datamate
+ domain-common
+ ${project.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+
+ org.springdoc
+ springdoc-openapi-starter-webmvc-ui
+ 2.0.4
+
+
+ org.openapitools
+ jackson-databind-nullable
+ 0.2.6
+
+
+ jakarta.validation
+ jakarta.validation-api
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ org.openapitools
+ openapi-generator-maven-plugin
+ 6.6.0
+
+
+
+ generate
+
+
+ ${project.basedir}/../../openapi/specs/data-annotation.yaml
+ spring
+
+ com.datamate.annotation.interfaces.api
+ com.datamate.annotation.interfaces.dto
+
+ true
+ true
+ true
+ true
+ true
+ java8
+ true
+ true
+ true
+ springdoc
+
+
+
+
+
+
+
+
+
diff --git a/backend/services/data-cleaning-service/img.png b/backend/services/data-cleaning-service/img.png
new file mode 100644
index 0000000000000000000000000000000000000000..cee23b96cb639020b9aaa339e5a4e2212622df8d
GIT binary patch
literal 137462
zcmeFZXEa>j8$TKo6J_0Em{x}y-%X|Xwk_KEky4%dh|~8LG<1`iQYx;
z+~b>X$?yN_zPM}M`{K^B7PHUU`|SPn=kq*=|Erghcd;L0-@0|{uC&zi*SBunQMq;N
zwj(A87!m9feRk{Chg;ImMU)(MHtWpn9w^rzdyLk`ahmCL#}Ro%Ss9L6C&iXu2@2Yh
z_g#0ZFOUc<82m~Qlfd8)`z$2asTJy{QrOP
zR>+@3K&{f==lF@y5qRp^smhP`2YFCWZwrpaJV^;6{)2*npqR_zLqDN3Ehj{V%^cg#
zWmm*`l=BYJi9-{90AE1<{lQbb=O^*1-vFv`%?{}gF;_PI+nP4u(*BjvKgcng&
zcG8!HTGa`e;mzGFpXsprBppAoYc822u4u6v))?|jEYdEMm=vIjE@TFHkYpG|EVma>Q%G
z7;N^2VTK~f6PuK1Wu%h{;kc+CVT=l-^@0U0fB{ap?IErOSAj@G1)IpIfFz>Ju4Hn-
z0ZK@P{jOIaXgPM^xvnV_F?WNOoit;^FikGV_TDRS>qX&HWyCZnjRq0n2g!`nErSNa
zl4)f$E|%WXAndYLki{8lV2MkX6l__}rlbs*_F9l^NJIkvwGv(6zK@sbu0CE4Tcz5XcqRLn*s|nJe{{hYr=Xuw!qlZu5%7_t;%ZOsd;1*uv7k>pQrX1>O5RRkQ
z!wyOq;4GXC*q@aV8cZ=7piIiB59-RuY}wAS^@imdim|9X^g!k`WuzQ52W5PzTEwu4HUx8ZTs>tkeM1j<$Y6ZJkKFGEhA70)4
zgn#1#kW3aLSSU0mH`~TyRKTGpe-jJLQ0o4x+4^I4WD07;Vf%7-=3dX7bIFJpm#t-d
zr{LMdX7g(ZD3X0`Tj=DCN=CKBam<}Ygdu(OsBBWza*>$joa2L0`L!WT?%b>(QU}%d
z%4w_9^va4J&$hD~934e_d-oeNIj_yv|Ffwafjp~y5$EoeS_3(#TGwm?q<=ZWzY|1C
zp$Lsh!h~uP#zcWLX*_{LoNl-2a2O&1g0zHyC2~>2u%ZrrNFeYv0u0E4Y!8Sa2i2_(
zkZwGr1eN5(^%^XpmPzP&cMdF*4t{UDf^JARQ?(doj3kTQmpMB7$$8hVG(2G2(29b^
zDpKQq2n;@>_wb`%Y=)MGZDI9ZkYra-nJ;Lh#o=P!GBo*0ZOS^~%_UjG(}GdHg`BP$
znW@dTV*^(^F>R03Mcn$m(0ryM)IW;;!I=1xrD;c|?1mFup6UowY&FqRRH_nkq6ajD
z-$>xXEpjLs2d=2t
zBtLrF#HI6TX@b{ZU0jHThklD09|O{DpXR)!G?I}jt9I=($w*3^05cL(_SyEld^fF~
z%N!cXL`uG5wWDUIvP%A+wMBjCxZXRzU4{;O4Tko?ilpwx*b~M?fGearL7K+g5Lp;n
zX$~kr5*ibQnW=$rT4%FVN0^(mgY=fi{0xxU&=?hP)M;M0tHAucCrvMC->!Vtm`BaE
zuh5XWuy(k_p0?7L*203fpv5t|r+ukMQ(h`vZaNg_c_k{2gV!#qniyI>KPnsPX
z@r{tm@+16TzFyd>>xoTh?>Q4LTWC8Od0Ky>a)_X1*#+P@T0+*bemw!CeWlvJa__{|y$ZYg5k^!y46cD0wF)Z&PrjBy3!sFU*GGV9@8@F&LOnk#
zLDkal!)DbHIpEA{gb#~+9<$m!49A$A}qEza+)0n?G%BQ{HkF7|2b)D@RMLF6eJ
z^@M&&;G=lok`+TZ?Ioi_zx(?>CHuQ67aUW9d(YZy=<@P6UQ;c{CHjZpT)mQ#T#~(d
zF0)k}CL(WNQN4_D+%WWZ`%jJA^w^~jK`)$NfU1=N3in72;JYbROai##SpguKX
zWD=OGoq*C8FnP3|6WySpjfPZZq<9Y~?NnEx1oe>tP7m44PBBEX?sri^0zJe|Dh-}7
zt2M#ks)|eam%9NC3B0yBruG&&u|2ZI$-Q|wI^UCsI<}siJrKW4`E<;*f~E-?U@G!!
z8~zrxG<5x|p7ZYV%x%?NcK3YpfW7_fC5pPYJS}Xzo5EWoPWNV+@-BKdy@Ed2EHsIi6d;XnnbcBCP_1ndH`3gq0?sr*n)u(y
zX#IIH(PwppiZXA34AP=Y*KE^?~$&uLel*e2`-4&EaeTs{(;$!QjDTq|u^9AJq|C
z%8G5Q_g32oJ_YgM{5;_QeAPMX``l|Sx$B`<3bm~xiR!2?ELZ0{0!dGvmFgl(u=ifc
ztzGT<33t|Z(wR@SkF`o}_a4V~j0;iWes$$$txSB5Np!myWesk$93nXKqVXPujv@ti
z!t4vPe)7be=p+OEzFNunhuK8gv5=vEPWpk>%lkT`$J5Tm7+Rl#ZH``w8h%jp(GV$~
z4JwVl@lWC$_OCLp`wSFr_8|M#pvBR*f4UyYf{CSBA2qez8U;BiLtuWfD~#V
zL->@q
zW!N%eoMVVRYj+EcVBV&3Q{p@!pi{n+@X5HVt|U&K#FiQlf&52}i8V2kypuqgnh55~
zHZ3qMVE#l9#YV^he0UeED0)5)tg^^yh&+|I_YR_Xt%en&3i!!W$6uXGsIIs7$GbWc
zMx3$Kevrz4`}vgzvN_R-%A%leg%t_kp4ju_fxukkf5;}XB%kXtUfR#yd0)G8mCmzi
zc@$rY8sF=4@yfSo44z}xM=sSDnDadxFO8+~9KeJ#K{hR}N0Ry{OoLTG%jAzCn`?m9
ztDj=+4i1MxLayx?95IS
z>z{^imBea#^F;cr$o%W#=!2C&%X&dRs=L{M_fWyi%=kc3ilX|?4S{XQ(d5eh1Uwg2
zOg^lrNeUXH0a5wFOyohhhtV9Ad(~2ly=k!X$)dg~dWQ6&sJrUBW>6o+F*;deQSuP^
zxGUx2(MPOqEU_8%0weQvYOR=x2=X?@SPeuv6;rAbHjJXca90p
zy|xjnxry6-lTB9@w|YQ&hq|KBnDg+RCU=Kl3zd;$M<)&ZgvRC&dq&g3X)iQ4rxrWV^|@w)GyV6sC~hfG9S{oxD!uU*#|mz>X5eR
z+LxiKIuSaNZp152RMFFqAt%Tj3A#iWmfL+d4vKXArYl%hQNT!CjM~0nv3*PQ`S>*j
zD@jHp0gc1@*4LQVzwkcY`$r$1CxSb?P>X=6d8GEX1cjRf!8fKF(zo@X=~lXQxGd^f5Z0=T9qK7a|ofZqnoaN;0_v@o>6n
zCDIO%=6m?~@FTVJ%#v-ZdV3G*E@2t?w6lcMl2u^Ota;si^MHmFfo~=mE<@bI&o<1l
z?46t3<-b;W6P&~YPDY_9o?}n>ORS5|c8Dg{Ia#BdOKn#)X$eYaeDS=RZqvcHpaQ*6
zX9&ywyxE<`@dpzCJ)o&0UPfyM-zLp~s(oo27}N-FW2|i@RN8y^m7s9CnJJ4Vno3j0
zZAGVNku5K4`dLZZ@`YURseg#?NJpfD9COs8+~gT{&bN9@a}Le@UtY6o-pxray2>$#
zj19~HFHi8sdYl0+*Lh*`pj)@WCaC}kzVis3XiSvYeZ*W`9hvxIo9eryGAo^3r@Bbp_a52udq`TsIZ>bxFyY5x|Px2oSM_Le=2IB|ojV
zsbE=Xuk)e8hC4s-Swy=pT4S9uvIqZ4oLJ@MZI;x7{E`g2qKyQHv>*
zxDw?P4^~-CQAfmIuDE2g9&{M8+-+hxh~oCS0OX6;5UGrl?pU-Q@8aG(H@jcLJ#w;S?I
zBLhBGSIs-VcJJIpRJG&v+DJtn9uy^(bSP6;)BAWOOKJ^7ZzoL9Z4aY?;SB+yFE8GnR!8DRTJi%W
zGwrRM?z8ObI-Lbtb;Lz}i0;3-nEvdx2H-lg#@5(WkujXpGkGMH81B>Q`5rEY<8sqekOFbu@+sE*lu|NhlV4Ws567;;O)NJm1
z#Jpv(!813^eUaZCxlvDYapvhUhC5dg9I2|apXb_Ed9Czg%B=CF(fAe)xuZ6aT{=L4
z*a9cPPe=n+^kM#4mC3fY5Le6#2mb2FIIV)ry=>>$@n*9iWuw5MimHZ1zhbCt87g7Q
zaIeQbLNU!rElkGX4RXzA_?ydIe`miBzVFUBZ^!h@v3gIw^3oc!NOB{?5>zkrGNHas
zZ$Mp7^`DUA!*ELyIO@wy);lgUtL~+SKr=)FDI;Xd0I2{8tkx#L<|l~Rx4*a@tPG90
zKI!?9Xvu@3%ED2L%p>3;(fy<29Gz&ke)JV6O+_;JyADasft#sE4lW8DK{+#7_!%dug0
zIWN>NkcFH4_Fs+&9rJTg5nfwAgM1J&a69MVm0}{E;h&~ChZpp^-pWV?Xd?D$!K)V;F}gsu^5=XqcLRDW
zF#v;=L~aToMUbJaInXnf0QlO%8W$edO$9Xqei@@^L`JHOpvCkRqz
z>DJ!guEbi~u%U*v^E0tFX2bAMDc^A`>-wPff?c)Ep|VR9ReQwW6LWD2yR>2+RFMXiir
zsb+7$srGu)K=-YRE3WMU?O`UD~yd^_!;=Q=MHl3^24-;mU7W
z?eb(>niRb&aG|>FYM@H9oSgT#r*47np3$apYH$pPb*bfLx3BkPnJ>E_J_Yz6V%|!B
z76tfLb|5*9T|faA7wSay#7h-OHiU&IjhgxIbQtu#Q1IJb{_?V-$M)G
zO10Q^WyOE68|v%8cv}Tom26-*(c(rfi1+$^CzUedd^{?-AHQhj2))MZ=Vao-{H45#XG{Z{6b4_zSpW75nl4qhvbyhoV(1OJ$&
zTf)UANSddR?)w;q3Sg-Iq3-m>>)abyQ~anD)ug)ank$HSlw$vylQbf_;uL#MMbLb(
z6s2|*jbHsPGV;TrPaHD_ZW8A3D28cYKT$$waGl3I4I&8TtbyCgU$U?*y>Hk4unt?6
zXHvS-mAX&y!sLr0*13ykyfIJA`unZf9M{1|M;SlKbzXsYz
zxv6-F^eMhRbQ7}|tK(e9Wsi>ALE!X$)`4ws#}lC!{c;SSx$6ym*b)~lA;zSou%We*6t;q
zx6386{0}OliLku)AJBR$@a>&4RBaBpLN*V?{ujKx+YL$^qV#@HL|lS8cn(*jR6}!l
zlzt}>w+gl2Jykz4<=V0#0Mx3ksQW-J6Eac3^{Y-1Ec-LTb*t_$U2j21SaULF_Pq8H
zx4}fNDVEx3JO{2hxeGKMNZ7;bn)aV3o%>f6&>0iPn6at%rgU}a1O8s%y1Mc}duLx1
zO8ll1()zeaYYfsgeE?urXRoAs_Xi0m0eDn{NiCrS)jrm|W7
zw##X|ZRN%{;yY34livjmDdeKihv`JwPD&pi!r<#3b;8k5bp)@*ePZ7+4-!ulemMBf
zzroTmp_2S`1zVsyZ*Kn3Mt_l=&A5B)BYC?Tt|uQ}y4
zO|OWU(DY;gdFO0WyFX5lbDE)o%*a(nY}?hB<$?5MmOWT)Rsk<~Qz&WSgaAp*tN+rR
z4~tEiU?>wr_AV$u01^lkV+@gX>44?VLHUFOu*66S3b5vZ%tP2tSifOqDDewaUJgo0
z4M@MiM<=fLn9!(YOpyaikChST(i;s24DgCTC1lS}WduXnRlta+T#voHV(wp1uOZTe
z2C*%517RK=yedT3=Y)xIzcX`0F>W-@!~TKZnd%2
zc{@vc(3!nAQ;{wnC!QysdDOvqiHW3Od9u3orLMl5QFHNR*UNoFypKmCbqR_2xWWCR
zAA`=kvf>2x&WzPKL~&JZQ^a)SA72lDwsI=G!~b=~*;c0Tt(vsNmsXCqV$H)8_692%
zXN{!C4{IWfVXf+Pp<`oVXb)4OGwT&~g!Hw7UJi}WX<602)7IdD*B?PRjWl7*4tASY
z=bWN*AWZ}bPJFu
z21CuK`T5xOWYWr#M0z~qydrW4)twj_PR*7LzTrNQ*Qw5une?_T&ctxE
z!f@Ykk+!z_iQc8Oe9_@$t>YiX-+!pO`cTykD{82OLrCpVH)>baY&*k`8Fz|qasPv!^O@TcAw07A9-kqsFQ6q2%q<+
zb~{CGwMOC;mhSIOctsMnfU5}TRtmnFR6a^=s>@#{)AQ0Q?9LW%qp;VUG=!BeN=@q5eycjXXNy_30WV3)5RNG~?Cm
zLhMGB14<=jsFxP0ZJm#AC-vNWF%zCDXRgHE6Q39KtJmHsHDgd+HHnpm-Dqm!PGiu7
zs!9k~jk)~yh&T26k|VVyRYRpvgPz_59ru!W64|}`Tbc&%3*Tlr?I&~-O15y?-G{}=
z{W?6cz_~vI
zO0%WZwv;a%Iy{dAiq`??NOjelgfbuo7ozZDh1wd7wdpyB}z1
z0)9qzz9QGr%`hd;EyXOQ6s
z@3u8#V?-|F5+)UCTr|?ufbi4B)5XTTyrRxKV^GWXTa|L@ubAYwM=!=j
z%C}nHg!)S95b&i}=AfmEY&3NX{%F^lTh``Lw2|q1T6=H3a@etMIEQ=oss&qPLQ?0M
z+M(i3@d!yAtE8@sQDgm`yunUu=c!DAp7pa;sM>i_OYB-kTXo--hJuPp#R96a`V5-J
zWQJP#%G4(lpHMgds%Bu*tf5G6?K^$mSGlQYqaF>&A02GX#~)c4<4>*Erw+18Klz%pt6>?FTgGAU|9>4{Z38UTSK!vVYR8o-1^#MqAw}gK=4Z
zrM8xq+R7!IW!McNr=bv;l&Al6Dn&X(*=+*@UxK5>%Zmd&l@
z>QOgFdjcj0syc0>%2hj1G=eLVy!1VK)S~+2-KM-|P9AnP_Ndhw;uqsoc1k_*TCX&E
z_~YbchDu&ItVi|GyxAjL8wo6Fz8GFFJ9`L}b_i89yDvF35v4L}6ff9l!xb_vQ|twn
z{q6CpgQGKzBFMKh3I&X~3?8V-CdzyRFXyVWPAHAi#lNL?aMRRSTQZ(3_Iuf|ltwxA
zMI;|vp8G@DM9J{;_^6uH)KoY%pHby$nA3XaAbY22Y%?RSJ5Ug>b_s`YLFx%xN`z_`
z->EEr=ZVK1jWCk!3g~vU=cLd|=C)Sx-~ML3sl~TD$I`&O&$XsPomOI3tzu(b^f)8)
z?@)psfTJ@{oPE?%Zl1JU++FWSk~U(d*M*>7@mUOor;|oPUPuU$!K&m
zSn@ClZ=1iCna@J`GcN|yCvTBwmnu&%yKRMSk5{XVG69XBcvGPSAgs3tC|!ahnMcq1
zQVaq6vB<9#Cj$vO(R6=>X2Y~P!VwjiAx}CjL4sb@ns0W^KXLr?$u`g?S;3`UY5YA9
zj`zA{#PuB+=Nj#@>hODFui|P`6(fDayg84eWz;!oHX1iefU=`FApO!0Nu088!8JTw
zd&=8JWStFt4dhuS%c{%=zSB>r8*tiixaVEF=jThOEQSb1KOP--|IIUDQ-lRF`=0mW
zUkP5Tu7ERP3=b|W6zIpe4;ui0wz7;65L65ZP3a-Bk2MI1nb1kIfi#d(P3uObHkN|D
zhMC|k+zd=`LPh494=uL%Zb8i%RVLy4Hc>Dp-ZSb{M!f*wqu`l482pzw3{
z=!1;E`TJT9i(Pk(XUmFlIWk%Dno91)Nvg5-NxALx5n&am`-7v=5+tspqa}wIQ-BU;vvf+m|ineSUY!7I081gDhBygKCPlXM4qi
zI2ve1Z;-4Fu)4Cc{(5jLLi!YAmPIpe_rX4+^h(xJn3rY26W;|RqiGr+j|RZrS2RwP
zki@Y_uxND%s*L@OD-&zt7$d7VA)6byb@B~M{w~lMN?br(fv8&ZsR5D@=wiC*4{`u7
z4rN4hH;8}&!$ch%^#edDF*O{M;yWU-<#G;CgG-^9fMKwtElc=>;|+oaPUmdNY^jeBwu4AfoFRy!EY*S4m
zQR#SK&`v-n(Lp%ZFvsHkWE`gSS*cePnf>UN5$7v9mNK?EUrBZFnjWLAVdU64p_oyp
zNs+UAi}&nmmX@N`yTrF2bs9;k))Z}2$FRoiY?f>5TIp12&(8MDp3`v+7RH`^?+dzY
z35RsDV8`k@M^acNt0OQ9$9DLX6yi#aTY~h=aS;pTmR{9y_jaE4#FpFb8|YaKXUm;^
zm)>LHM<|0w-4J(O(y49P`?AA@sl&PN1_ysZo}mpYPdXWzLG$RRtbZIBjBM>4a3vSa
zDpy#VKog(F#d3)yx{>e!fa>za;Aw-a&VH}!;oE_S5_Q9PzqJ;gNjwhPcRUrNB%2Z7
zZg7b3m_0v;-^Ne{`Zj$4Y=PFZ0|;prfP(xgs}YiLRUP5Qk7r~2R~HMAiq~B+Y7pKu
zBgI`4(m;UX8<6w;T}RR?HRK~=*_b&E^>QU?R~0Qs@z0*9A;zYx*4s64@WS)i@8_9j
z<{H}Tbe!8!>1-q|X^?&Hvwo*++1ja{Rh9PB7S3nBMy}#+qlRPU>=b(RgGa+WEQLp8
z{yVFsX2NU?xAhEKzOb~(GsQVFyG?aj%P~^!zFsJ;2E$Br-!`l#t)MYtGeP_CT*VN&
zZJ`_xFMAIyf;LoPr`cHS>+DAZryxsm@#Q)3Wd`!a5suljy#&v_J6l*WcL|5G@_5>F
zeW?_|Yg#R3o(!Dt8H}G|?r|g!^V5qh_~fx7CqMH~B&zVU-rLrXznrsoQNIT
zCz9(c{MLWJYJP3#J4xsPE7<0oi*hBtq9D`cIF*CxNr1DmBHKt4GcxpBeWw5C1BRm5
z$i0t}I!ER1c;%Q`OUt$PCE*y0inw1}V>?)eLOZ|dLjn)x#9R!fKza*$dF^_K>h^;J
zJjGY%87}?=lxqv16EkPJIZURHi!&HTi+v3_TD
zvwC25VDf!kM)_fl8B>pH12qSyE{&FnDXmuh;1lbmsV+o>XhG1L^X|s@ufrNsKMWBFP|fidX7W0`@c(4K7kA=XoyB(e&P_utLNSCj?V@ZHBsUosmdMJ-ZShk4
z_TfXS%7X_T>HR!)`Q~%>qZEx|{=|%fI*Gmv2gG|)wb7I!(q1k!(Tr?{dGtC7u~*P|
zFbPMd!C?iLzxDa(Wtpi~mY#>YxIka>+veQlZ%!<6GdfD;;g+M*W%-CRO(T2x&UYq0
z;`_@y7sdW%F@7&E4uAwHRK3>XytbqE;Y*|E1%(%!3kGtbhcAYf4A)H)>E)B7xUH&w
zbdz)6`IYm7Nh1s8|1V9SP%;&+S9cGACP$*T5luqxX3|8TaQL%T}PJ
zjd*LgTQ0YSj$~F^j)=`~wtOh|odB`Z&hJ-+)V)-7kl#5D+AfICfxN#w`&_ZXtuZxO
zP+o>#Uo$HD?QDh*QZXi8qxBNyKSc9VOh&Y1K647_EeMt
z9CziiMwFc)I^GXS@VJrAcjFz*27b&x=ed02QI;6@R%iWfDR$sP-iZt&s+sVG>L&>p
zsw86l;*jo-qaJ(OCgX+2PuTFniW@|XFW#BFcc$;rBK;295NJ()`NeYC=KXnsTvi@)
zf||jy>2y`eW1|K28Wl{pSDDK>99DgCud554&e%)%|HU>Qu&|y`!mL
zXFKkA6NoV(FiU_MF@N!_
zswhCfK2(`}A{VqFSR_%XG*6u-t|gv#S6;Q|O+i9ou`5?V#@y&v6>afK6u<9idQW>-
zTw-E{qenB18}VlX%9cE4Uf&2!Lc6^mpVCYV^B=I^(AO`4vpUAv@o1oH3Lq=N!D?
zZ!nc5Zt8s}C54KGDOc2XHDRVMpD$ol41di(84%`@){y+9lZ{;Wp6cFhEmgSni|tRh
z<7y-+UdP6l22B9{$XgK$zwRCtm|SFNIfeT!K{z*6>DY0Bp5;}6SNtu%T$M$KxD*#2
z-q647e6ZQI-pEY(Nmg=T{tuy1OGZ8%mfywv53E2vBz9SJ@HyNNd3eBEQ{(bzMxgdl
zUg?IRk&&vTk*bR%owpNBHOrka+{-<@6V5HfShSY0&c)K>BKnZUuE!_33QX{L8Uzxr
z7^NnxyeRFOsku6Oyk9DF_{=G-*g)z$)tGf))3442$$V!@U&CAzK
zf!$_r&`_15pHcjMrNiOh&E}RNTq~afb4~goO)}-^jn=?vAVF$M^PU$wo|LIKF1rCp27B1KIe{&mnl_}j#Cqzx(V(J
z>XSCD%JqL>usH9vCFD_je%rIBOV8{58$EK}9g}?Z#PC?ITv<1S?pQ~UIFLH9)Aed7
zX#pUDmn0`%P-1-nI&bfGz%$(~qVIw-%2MS$!#;X_Ixqp*e2#VJuPrKgkWKRmoJks+
zxYXRQHQMW9`1#BUl-_k|raIr(Nd1PEsx&-^57v!w$$X>O3^EIO`9hSm%kj44B
zO-!6&XCfHw=PuG6Q5Gk+t3xf%blnhE-HI^uTJF;X{IUDFxG|tiDP{6!M
zQWMS<2W6EJ(~|yr?rPncj;7m#J$n+d=~PpmlN@yEJygODwVE7589l_07+P{N8G>5W
zf2ENaNR7;CQV-zLRdK|^H+fQbVSc<@;!m=a=SyFe4Lf?cHn!$-q1R7^*}-;b8)d{I@ODZkas&_8lneV=5AD3K|sfxIj{YmXzs{us);O)TS23Q%nU+wK}nHd
zLmzd-?C3Gk5VT};i+7q~xKMkVLwn=&;INIVUM=w2T_BpvMA2B;SY@)zvxIlchGWPE
zUhTG+{F{-t5ayJch)hwSlX%(gkTkHt3Fnapgy8lsU{pEYd^k9}=78yPtzRAJ-tloAkTbh;!K;42Q!u7F)5@i<
z&szh##wybdp)J5AJgY0={Yc1cRK~O>9&v{OfZ)>UmLoG~I)pwMU;pilZ|R{mRunOy
zFEGdOl7-a(&5JVJP3SDLxwyAG{4H7xEvb-#NOys&msjYsSJCY9_?*hBIY8eUz`
zQ-gyB9|3UK?LY7Ko&YN{!DqmVuG3(}uEv88aHJnF<$>Uo!n=BdGH>422leHY%Nbk<4Tr-6F3j9p{@(NKtz(tF=X#ZKiGcS-5;<{_;l
z&J&t5bIHb2{O-c1r@H^WXLKusUnLuL3u4%2udy?3+EiQoZ%(Yl%c9ZFoJH>?m1+32C%63iqvUqG3P!Q%2_h<375u
zAxh^rUQ=%#)A$*>So@f`TmSi>3MzH-+f7^erM{pr@Fn&O)ltuHF}jb`5P!?^ty{!k
zc!L<12r7mq=zo`%Ao|tR%5?!jT&duY{yD*IRmIO|GxCGJWPRsyp~%Ib^js9-k`oT2
z(w%+|`hzz>d&nOYx+VPSPsaU!@glV;lD=NJQgQ9wx2fs`CbGJJ$#n|>8ya2OeD|#;
z@zXq{UFG#765xHM1PRq(-vs4g8HJ0Kce=^$ul{(w`LVG%!}M6ziI@O$Mt;}C$bxhN
z9v41Tt#E2=aA4!$#GByb|GW+Dmq6|zBWYDQMHesAOb4`NR4P_k4-sPec(eca&h*WU
zQc&Zs&+!G8SyY;`%}nicUB@H1*n>DbN-2#XeH&J^VJ%%Og%2=M6O0OJA4|E&L3QAV=RocHcsHN^i+G=2bs
z|M{S&Eno=FpEF-rH-fzWr2cEIBGjMXzdRuNe{YE|Q`zpMY&*B_((YqwbkyGCi0P&_
zrr8$^QCQwB33H-of4c9e4vgzZIMwFq&td>4dx7=)KoS~f0uu2%%iFyTEEbczb?zfO
zecjhW_I+3L<2WEEk=d}wMd}i?37kqAuNM@lM@jYaeZD%E9KV`Wt{2DLJk;{1D?LSZ
zLMruXPW{YodoqMQ)_`HE}zIr20wlB9pqbAQfpy58Q`#?Kb}QDyHjI)$wQU
z>C@BRtfY0fgMp;o1*}D|lZ;AOaQhv7_P`YBvkyNUfRh=+AW&jJusK8rt>_+!jPY5V
zQwTL|_Ug$`eKePSPsul*^c{G%Grt?fqkFy1W7joHpXAzG^@&QT|JsymZ@pEHC3Y
z2&94UMj)B~lCyqHsRj?@{TZ#vvO}Ua!**`c_mBC)W_E>Est!bqch+1Ehfr>e-N1`Y
z?Lqnu54^3{ynd{$^X*%PL^(^-Ml%h%=^q!XKgdkB(RDC0cEHQu50hoqTnwhJ3GPXS
zUq&>Oko5q|UFg`>D}5>}WN@)94D6vAfxOXDtO)l$;RENcB+9vuejyT4
zif_A?(=w~S+s?T@d#1lH^N~X|4quatf^&o>$>p-QzrTki)Q-aBh53Z*@Nk%8=Fh&d
zyE7N~9TbwkZ!3S2lwFwmc6B+r{bVfBda!h9O
zIFdsujxhM`wg|%u{yD1xU%j{^V~oMaCMx`&sxY#j?z)nxp1u8Ztb=8D^Gu_+g=1>~
zH(g{f&+&ony)fPR3Gaub|1e?3Ne&km@n?W
zlw$HXI$Jw^rS+*nU#c|SdRJ}PJw56>dz}VB);vora8fP)s49vM*lul8*8A^SCo;4i
zkNz72C3}!31NZGN{Jor^|BCk<8DKKnU;kwXzBs<9Wqs_NWzpaY!P9N0l*QmYrav{{
zZM+wRVX(naA0ifmYr3tt*JbB9r{vvTuUt#%3nv?%&e9KGvuonCign9%6w}-L%yvva
zq0dV;*PCcK$1wZ%tdb5p-jf+5U~W>e{*vtn+_9Ee5tD|1UOKHuNO
z#SSJj0853R9k@yz<>338Na%Zf3SvmSe(I#`-^@W>BE%y(Vuuan8jH#_xI=;MR}sWw
zyw?hQf8YBekkZ`&*x(oBZ`ObElC4A|n(o2seB*zICxJfWo6zZwglyJ+&*3}Iy@pf~
zT%#9lJMvWu_F8K)N>{2JgKn927gzeE%8D!J8oe|O*NhKO7i8B?E~N#1Qd(P|FL{XT
zT{tT8x_g8L|NSVD-;a7&Aj^Hr&CSi)12>wiU8EyLE|K+^(@CEf&&Jf+<0=gpQ*==h
zV%dvl%K0va8&{iVy3WND`c3G10QZ0-l%B)qpSw(OcK;Hjy9~e8wn+bMD0v#Ec6P7W
zH5twpB9_%U|FQ4ORs~M`m;}+U&WW4ypK*YT
ztUjHi`6WV}f6XNRtr{iNzt`?JI7>^OzEj4aP0ddz{_#K#6o&wrNJ`S;C(}
z#KLjYXTMhSHB$?KUq6|ValrIGL$=KIVmx}`TwwT$bUQ#=D!2Bk
z`XZD}>SnXPziReb=#p71Ctur_9)+#Mu`k+tM^4Vl>}bsiExq-x-Tjh|x{=y`V!Xe+
ztFa&c_2`aKCDj~80_$brN%gE1=DkEGg)8Is5Zn;U7)$Z9@DBw>KjSLf4&S+Z=L0w4`n_<{
zFkLbaiCKhkh~=-V7+w>8uYsqEzNhNue1=^a8kIurq*ZI{Lho2F##lV}E5S({&P&81pAubb~39*G?u?%m;{
zycrK%b67#LpUQRKot-qWnmUULzIH8My=MRK$MA7_oBxpJE;ocUDtH1Yo;?mfer
z=(hOL_n-(WO%drLAfR-l*C6=Ras+;?5`WEbNQGwv=vj2!L6a}kEA6e;t?F&Nz+8uT*
zggF;1r=Y-}`*eON^WK$}x}Dc^F?dUE^2HOLoL=<#4hCb$h-PtBg>pMuG7NpQpp!X+
zi+has*8TB_a&J8HJx+=dMcrV<9$GkrmW0}=#V=LD0+gR(FR(_q;1#Aci$7_X#DzjJ
zH@0j*Oo+QgM2_L`)ZvqO<~1hAX^e2rXvtUMh?_&yLoBBbzu(bhD4T%})n`4%fT|?I
z`aYF<$q?kn9Pb@ez}?W#QK~FYX`F52qxv%2a)s#2#BZa1x!Z6bd~|p+8$ArGkbgHY
zZ=pcHf{&zvAAzoh~0#4lr5>L5H;iK_(dTX@vZIqRrD-X
z#B`_PiuxU8Qq{m>)Ey2*8tS4BWcCgA6+O>{zO6O
zVF}zwH7Apuq@MaTlRv{ts}=jnoC=fssw$oH&-Mfubp3MDk}}@G8ONi#)){G0KFxS2
zp_Ao=r4(etF`!=`F62D0g6x}hD~G-QzHq!HoQ29^4PJrFeha!X&R18)Iq?XqUxElB
zQ>i}zp|}8zy`jPZNXv$FV4WR7kisL-$bx)BFho69U{OnPL6^_eUo!!p##GVf&+S@G#C(w7#Cp~*nEYTTw(%6=L;
z$4?$jxq#mI@N7D-@!kAo)M-`oGLaf=|5gYeQ5eNrKf*V<=sOGX^*qu84BuA~|+4O2+d2ep)
z(a3F-&@~w`nYv8GmoQZQol?hab-#tf2~J+G^QPYwlBxpza}=rP_l5*|`nwiBx@mD~{Q$)%@=XpvQnT-L+a%6We%Sp?EAA*l*p8Y+;MV
zC_RmMjf_$2(i!>3GoFX7_l|^80-!!V8Q7GW)ps@f`^)Z}fE#Gzt2nLKbSsaq*k4%o
zSc-fBkT&k7Z;wr)ErGB*a>f{4NmlbpvQ&?-&jHEq8b;UKT6I=mzt%DxJMMyY_3wPM
zjOIG(=vc_+8cdygb90>tPBDm-`<+UwYJE>(E6G~R-f|kpEyr*B)+hSH26w!>wq#^8
z*ry@o0l_mdEZ|}HFOBw6_plgX60DwM2ye`9Fv}h`b=uuU+Wd^ymwz
zuhk5)Jj7s`K!_s#vZJjm8B+zf4Mx^y3QaHMZ
zhx#DNTtnkg46!kN!MArT8%9E5H5;1`lcKY*IO7Kr`%L=7g%#cQU601EqV5$8dVJ$E
zWFW~w)~qa71g7HE&{q-x+TW;*l;$+WDD=yE1-=DTWe`|_6CTc;tNsO07bwh9!jPDF
z#B||qD{(b)qv@!jg``MJ4c*X$_v^B+ms+`W2<1$Wsfu6%iF5IsBwFfE2TK)AsP=Du
zxofW|!$v>IE_t-~;+U2qmD>2Ws6lhUu+5rUzZuTfjO%r&-=aKDUmYLX|EoV{dD0l`yk9wGXCfOgd6U-+N`=sAwi*C4mS%dGJ0v5S2juI5>Il{
z`7FIzZXw^uAX@$#Si(E;rbTBdcLy|;lJSMa0J95}2<8Jm?|{7-?h>K0$mCZP2|nWb
z*_b4(Xxn95(#fE|;I~ZSee$ZqSnn~!ruSs8QzY2k-(yE~kIq_t{dVFQ4zL^8Rzd4{
z>niBWAvhUgc0W83N$yezTu$NxG4Uw>3#Qld1
z(ZoiL9S=MHdK#LR7agmZ2o6_=j74W6az^n@^CUvizvLaUNq^amZx!78#;Pb56J-7t
z!entmQ>0s_g$SojO)$ADoE?3-6#KEm*YICeq|b^p7?0lFlL%|6neYF*&>bC4-
zrehV;FOtF^d>oe`Kg#$sq-(R9iIElMfrCR+*)Bt&j)~)!7F@Na%d-8AVAo*8m)-j4
zLElRXN7+n-&t47A7ae+~cWEMM@jgOXD4T`mlXW*cjwx?x_e^PIw1aoM$XB4nH=2h&_QmFiZN
z&AfWASO0}wRUcjD8pPlmkzf+xs^dzx<74l$z(0mT4;(>W)1Dc~iRwSZAs;OG%lHsV
z|HjEcr5?bo#_7A7F{>|^2Y)U88!X;`2QPixfjH%tjW!%~eg)h!znHw+Jl_FabZ|>%
zay~u;J517en$tnU8p@SXSRLffdb52%)G^ggwl#=@KZY&~xuSv{EB7p=`3AR%gY7l_
z%Nl*JL%*Ss|Flz|W(0`NpM2Rm0qKIGKwtkK66RWm{6049mD@Wz=kcr8zlhJ7vGOfCwJvwT4)*AOWJ4#D$ri~pZRaU-ot*H~H
zM`@gse66dSX;!YLcLZxmIEj)c?-hFY{hF8(pH{o5iH(Er4KwkzUS=-6KqR34n8E&F
z)|u#BoU%h_K4)cKU}!!yjlPxe5LfO
zMhnlLY!y$zI}F=yt@rRc$~KBPJDaz*SLSdhf<6`e#_C0Ec+dlpkOubrFL3DLmDko`
zYSZ6}T+S6U*fuZ~$8K%bJR{$6wHyTd@-oU2P{s@F
zfUDofjaj0W&PpT^=Lqsi)D0$_R)RLN_N5SZZ2G8svA=^>?9se6}QwX)O&r~
z?PT?xvjV;O#W$pd7?@5wy1PQya{XLtGt{tJ!LH^f8SET)7CDdDrgHst-cI8y9s7y(
z<7A!Q*Bi8(-25t2k)k!c9iKzQtRcakk+*VpU44X$DCT--xG)v{UGe^?zAJ
z&6ERVH&PfNWj~$9>$lrg^X@$coZ>F~^4_5oN(f^3-uH#jyVH?7di#p698`i`nYjV>
z>|C)Y6|o#g{6yUMt5UZ;UMjZB>OAO2NGgg=^!|TdyFZ-$)P1QAQVHhB0+*w#uN2tO
zag`^cHwsCdzE`?k*ynj6n>JLR?xg`Vx;Wq&`=(UhDXA
zGOEmCud3tHwR6xVg4rJ9jBpRp;J=&wHsy+^5;PKILU-Kvk
zTtQSSVFhlqMY3HMHx4~kfmBaw?L;GGh)z~;b`|2`T?}&+SU9^Z2(qYNg6M~acX6L0
z-8mNaJnsv^I1mrQ9%Ww3q;-M;fO(BuP$&sRTlE`D#GB8fJH>vTSponhxKv0>Li1um
zOZfKx%4%ut(`s`u0Qhy+yGs>{#O4#83t!n?OTeIi{+Hp
zwpY>8jfRZN_r3P?v1Ce33Iq${`OKi;u831hH5&`Yiz46_z0Lau)JoFQ~FL4>HQ}uG|gh
zw?qFKBHq&pI(C^ijDGI8T4je2$4rarn?Y_o7=`=q#P{Y!2he%H&0x2+0DNnIQ-=47
zqeD5rphlDoslAr`G?n*Jd}2yo^anaI!M2|si*i@L<+M?;E?!_$G6B^8{2u0?Y9@#3
z>2+7BqfsT4pL9AS0ZRxg{U>CR!ejp!Z;Q|8)UI0mUE8W5Va!WEK2vGyJJA8*EHGjt
z=XP*nD2T4(IXT~juktI2NI1`X0TiNN0;$i8OBpEcU8)avTpMrPRR#U}RgM3W^7v{d
z|D$)@VkPa%VsrklgL1N>TA~AozTb;P&;P2K`EtFIAi0%gNB
znIQZux9ba1B=llZB`Gcu2d*8i45DvmlEOD3Ek(#^@VSZ00tewG!5vE3#ay_|Iirl+T8
zXU`25RZsgE0V9dJ77fUy3&&vsqquYCC?%{2h3G5oEN`fS1t4UOpBu_V^Jz&BIwG`v
z8AB9)=XSju5DC3FnFCsjqc1p-CW-!}PA_S`HdC$RUbt{u^o332pJQYLo4C&2M>?j;
zc3!W`^3#tOn>Z_^NmGUx(gy)j^MF>>=lJ!B`XI|=QnS@!SnWNMe_J~{r)P6dvdovM
z1O}?wiK+$}o7p|q`)z6#U?1>&;(hJ6f@dq1WJ2-0R4#C4Cpa}3<$t8_*8SL2U=Ekd
zpbi&E#`TDM>l-N1g#RWC&qN|mC63-&_kI^dhF#xmuOE9Aa7UW(rf?g)Yg6Wqn?O3L
zY#8n#PY8ifl6^~xq@=6g{mDW*qX*LTA#0E?ksXtdC&yj-Azrhv3Iem4f?fH;;YC47
zS7Tn_Dp-iz==TRSR*NPdLHWAwV+SK{%?mVd79|Dp)dho(m~Fi`>P$5onP?dZ&Gil^
ztt8!yf3iVi!%2hqwlW|)WYUD|>;Ichwa?@92sxvGP;vs$N{>T=%*USeP-bqJy=1&6
zRoU~&LR{3egRZW*6Aib*ObCf=n9pdIx};n05wc*Th<>akinz;?0F^r@>NqW#HD_ch
zNjLe!uBtyg--)44Ah?P{p7uTwAEh3tywKw$dJ%IyuNCFPiP9Ck%|9JC-jrXnB06;m
zA(Q?jsAU>NCS6Cih*+7Hq*2E`bd;pY%gs%6Vdi4Oaq`ect90HdYG?F2fG&iejg6`s
zSFt@EZnj`9dm^VDzVVIts6&|`)HYV-a8_M#M^U%^r~7mda4HE!F*(vi*ODI_3mo~N
z6fcfsurrK7WM)JZRE$AU+`msK(e9+O2ZNu)?s>fnNNO7FSYAj*fQ?7DuidT9m@yVg
zkB~XY(i=(pBt^3B62jExx7n6!(p!|+FpBMu*Wplhmanb13sM)1*qEiI&{tweCj@3v
z-z|qe$fY^Xq&3%b+U%aH_&m$=E8ACghntqV!(7jQ+h7#t1)NIt)wnv<0Tl;0;F{Y+
z$Qb0x*ajacfG-qe+;M!kjSYnDz0E8uD}%u#a!&ew(Hi>uW4Sh)<>W2i)P~Ne1NWCc
z2+_kmF`@smmLjlId#Zov9(Fdit=T-x|l$mtO+{xqLH+~&2zK!b;~@}T%&QRW%zcS
zZV$0;`{iS!`Ih?Wr3o3ut|WJV5wU)l_DPJ!`qpnxfuVtcACYof?mljAZra*$bV{*t
zadGkSCNLlS?OvX2BmL8!j~=NaXZ6Trn*H7wo?Eqy;4bOY_`-(;on6k9muzQB8fs_U
z7_JEe{=Ry#tqm3>;oJEm6S1+Jl*PbMkQ}Fe-WB3j8oChz8{h5k#O~8A2Lm72EgP17
zC~V6GFs_%b5|2YkkC8^Xhr#SoX1vq3Jx>s_z!Gq4uxa0QN4AAazt2~ky^id~P!nuoe
z&t4L#D~;Uwgr@X#BLh^;LUU}9%f3V4;%!v!%-QtjMD=%uBlvNuQl%Ovcq
zjp{Do(&VlThpi31a5e>4%;8&r!?_uE{GO$&sq;OEr^e2ie0P|HKY#X<^)Xe8!|w{8u-C$7Q<9fF*1h6!65qKjC^;kAom9b<
zE|@C8kW?DI=k&?CntJrp?~3U#8{h`Twx6_o+mFmA!V}%U@;wS78_K%$wCnz1ka1mt
zf9UDMsYn%!iufMHxZd--o^B>Vc+=@pC`b?2_L|j83SBNKWV@s==90qBOA0lvC|Mpfk3*RHm%m|E9jg;~A+kW-CVn590h1rysTqQ6O_RERH@omW|*LPiv
zaT9cDtPj|;;Rhiu0%l?l2L}lrpeJP7J;|PuMaU?t1*nHBT>QNdTF<4>EH8vc!ha#O
zUsop7fsULdJnBZ`|XHy<#RO--abv2UKZ>|^m4sfz`yDRYJ*AOCV&~lXwJ&C6fk2+q$FddnGi%@-+0c&D
zCofX;ywfLpN1LuEKD(isN#vkTCo8Tmr}lD+oBSI66(<=%iTZ5IwTOvEPA`W7QM2J@
zGhDREVOka(_XxLx)?FN5Ma(9j)c1dp#D}&q&g%9nulyDariBn;V3Z8T8C
zqr&W!B~6-yNu?9WcB3-x`<~3>Q35_<;CW=Pdz$w-6%rrM{aiNkI%sPh0WeDxU`iQ
ztSgJ}kFffUp0-0BHG|9$YD#_)hmP_L`5Q#kG~#bFac#ELECGSB!LyFPS*`H9L$b4{
zIs7Tk+KLTI79AWq1DVMdpDQRqL`n9R93BV?_@kXx&(He&K9>fXD5pwV+x2|v{2Wkc
zG22N4Hq|R*%~Sx`fz&AC*iCy^B=$2%d5@h*0M#?
z%{*PrqP9i&3pwp!nXMckwf3sE;U`lQrfE7+QZ~E4$e(`y7CMrfst}>l^)-#_
zKl`rl?XfvMQP!h8eYPzVNJ^a?Wnqz^?K?8sb2uB$yf1qxNLM~0Y#$dyLNDpxmaiht
zJ!_pJ$<}#hhkmzD>TK8J$d5YPLiWrLP!EauleY1mtg7zPQ-R*T+nvo?19{l6vv*h8
z8k*1~A6UQEZq2eUIcMJ+Hgqc<;}dW|U?%)rhyWMx>?+v(Hj|Kf0
z-i(05{5VfOj{7(`&Hv-s!6P3@SI=4S%N8NXVR?`vYvQ;aUE9*0iP&@XCtKL;ZfA^G
z%p0y=npWkak$UR2|EDm6BfIT)uM#NMYw6WWtwdzM$Lr3(GRwo-`1m$*tRSd=20O(g
z&t^4--?saEI$LID5W1r;YOpipJyN|9Mzi{iK)|{4$en|ix-DO_6MJpt=4Rw|chkiv{3l7{Ky=d?A8WJua5cB#c=Xv9cTfevXj`s
z`b>gl;l8dZL4*mx5T^4;}Kg9UENP)
z%X$l2A)=b!eu$^N56ijVfvwnsD|_M;DrtVt_xn5y2ymjH*E^XRs7cTPA5)64zo~DF
zG)mNVx9$({3Hgv>_l_u3_)*x@tBDz-?^0QZlAt#pXbtM>ljqI1dT^mkLfnTiFC6*>
z_YFvVNMwZZ_fqpYXLCfu(F;=|S{^vAdt&vzaq;23RLMkJk4<&{oVCSHzW(C6k$1?U
z$!Q9TO5*nWU21-%uQ7)C+&L=Ll5h29c7wK09S&`WG|OD(cK^f-qtHjl9s>9=vGw`$
zBl$Un{;V0oKDEN!r&IhY@MTW8(6pW>42-LlA!NM9b{QalvIuPOs!2!C}OW6_xjsO
zsQJes5p%0vQjY50L$Fiiqug6tYkvx{S^>mPI04q$+7oNyh?yUKsJY2k0a37J!
zLXX?NZ*V+8rGj3)Ilk_HYbu%0dag){{H&-&pBfo<1ix9bJQF);$fq5igZYui#+_G?
z?_ljj2c=+$`B_jSw3{@Ln?44KFxkn;2yR1LMO8*r;p2q+v2us+Zif~+2$T#HnQ;~KdgQY
zVJ&Q67N)T+IETLt=L2axT=8QHBD))xhQ|#2J53}d!Sj0ekCU)pEM4;r2O5r_rmCD_
ziW2krpxw6lj~tqE1Xz425vP^f(wi;voMLxsf@-}s0}_ujB3u1YEfmN;!@ZpdOibsP
zHK8=g+4+;3$%O0WV7-JyUJJdMT(5Q%uw#QM43avo^m%=i{T4`tPSU~-{bwXdoz@xY
zTZbNwq$G)EUZQ483ayI#V(7ul+rt&WkHV9m`e>bDPVS+jtD}wd;XkU?77Zv6KUL$t
zEu}Mm@QiQ7b7g)gbY&K4yGL5K{-UF4Mi{!+Fy+d&e0p*`JiJ6-Zv}SlDH)sPJqUBg
zB*%I=58r?{+2ee(=5NTit&<<;e+hM1S^B)?rfHt-TkL?S`v!hx=26q*Ga9l`(v%A2
zM(Qn&_TB|Y=(e1g5(VxF>jZycBKfN{At5(a9=!lr{atpCNpaeL`GG$
zf)QV*1)F0$Ir)&!5utFr+X93+qvP_3&-9g9Ghl%V?mbX{Fp7L1V?Q3{)a_xh3~UVH
z>%p&;HKCX4a#8_7DJ*Y`yQzHiK^Qh1r}{28mPs)3`S~n-S`P6*N0tVfPp(azS#Cw0
z1g)+(CXBPZlm51c(#u=L%gDDx=Y9j*TL#egi9rzurie2QOu1v2+G_Jb)_ihya{idG
z_MChS0n1h~QG69P!%R{#N7i_hdh-y~uilw-#QG9(Psp%C#_1DVBE2ryi
zscW-d`*Pu*Qv7FNR(>4VUE#2Ra>_u*avdzc*K&xr
zqnXiyLkNx9KJt3ylakey{Gh~DHnqf9r-kpZXPaOE8!nv>4--VDrbfFR*p;@!Z2cbf
zs#NQ+5S=gAr17Y!g+I)onk>_jA
zmZN3)GALQXtB8J}8#eaelq7x^;Ssc7{g~8xxHDa!;2Xbsh;Xdd`*@(pnc)DuTaYlP2K_1cmw5(>-9TkQ_UNQjVDw-(9$S
zENWqT%nBF`YxOMlb@7y>Nu!{E&{0Z{Z+qUPOdzx{CkMKw-cW7ty_J-7o-$tCi)774
z^Qeuja{R>5@9V(C9S4JICK6B9k*xhm0#CfqFbd#JdviHeRg|t)y<
zv9E)O9+H$~=T^jcuG0g-<)*mo_%4oiJT~ckv-Cs1yqL-kFh$;11qwNGwsw+DN(w#G
z`-zsx_}Qvc+E7aBcf3yTY(Z2@Z|$5`i&E(LCH`cUX0$_`<>%7*u+A8GP+dta1<
zl|)HuXdb*WAu4IP3u88^3~rwtFz}poSEG_}Jo->o-h^2djkj7GMlXCwaAwGd-_tyr
z;Ya#2D3+fuEjaPD*Gv^I%bE4Su{gdLlt@AUg$HHWTg#`wx^nj}kXET5<=4x2-vQh!cQ)MHplZ&p}4
zcDMD4&=HV_w6X4t6LgN<>RFwLq2qt*fAX_)-9x;v
zsmBn>vo~(2`P3c8zfur_gWJuHf`*bkvyLu+m!axiBvIGeRao?_pn0BEvj`x|JG6a!HWVzSI82UlA
z0naa%Y8~?{OUc}(8BuYmx&_eQ>6!#}sUHLD31mV(+tSB2
z;!%6IBkXk54_m!6FwY>fQbZ0E;A}5}6N*sN&&l6+>xVEuJ^JTwjR4U`BaqF+QiX&X
z){2^q&UpeePkz8Efyglo>@ydyTB}WS>JL|%0ULl_LsNXVaYfQte^ey)jGe|NrzV2}3ceroW7ZK^>uty(K
zmFk5s+8BKwr6#C&Ih
zyr|h+QXXgz9oBj#H>V9}9GfN^Lbc}M&BAZQ_qQ;(=xgiGnFC!Gf{8RKCe~Q2@OWPA
z?I_Bem&afP7mAk>pNKom_6Une;!c~E@}vxyZ!F~X%t<`)9}t<%ImvmW50UmGK19Dz
zP{MbAgWa8Agc~<58mK6uM;LDx(8V|BbHRwf$?&lHbPg-6>zrLa_z`w&m6%_Mg-Bfo#VrG_?F?>KevZT117GWOe
z^BBs-8x4uxjZ(YJ^C-2Dndmj#-gx~8Xwm6D9YSI~!Ko#|L_LEARNLHtUX!x-6<6pR
ziJ_q@J9)X=VBp&dx+yFr=r_8Q7~LsOlGWB$1b;L47$^)&QC}8rBRN&7$5bLx%5s_p
zlJwYrqWv6Mdq50{HB0?@na!FB6@4lCPt#JaZTa6@?L5xzgU`nrrhYAq{oPp_K>B)w
zMQQ61WIU?D)wO4!=6Ayp!7&F>tR`tAx2h7A`0MrNq>Ugc`MEkLbM5VAwYeQd&8Mh_
z#uzL=1K=4~98*Oc!9bsP#jVUSmkieM+gf(Z)S7Lb?he|94_dW-ofly@_f?N4)uJ^M
zuGx;S#B7|>kbCafv;TY+R^AlR10=a&{Wua`9-WyrK8`X;w5F8!kQJzRz{yvAtD|$6
zzl@&LKY6;OX-9X5ioAw(cEBmgaU({?aM6KKm9S_k=DWXPu)u4V*VqX9(`xrZHAPiV
zhtb|MY@S9;NE?eX=m%o|JQJ_mgpPsV^#HRdEF7uy3Utz}^&t5X=p^PtxfIaTY>I!%
z}yqi9S&)RrR{1f5{Kw?d9XyZdUddj!I(JsmI2x`d#*%p@s
z59H}cf&oO8%~xZ|Wi=~YXzHT~?piN#)U?rlzFU*($^)>njSme5t72rlY
z{!wK}8F&dS6@*@zDX=O5oF!yDm$=M#{~l#RLoRBee~*F=_Ale))s;a}{tx~g?c#!=
z{>!rXd@v#kHUfbr2x%?#GR(?HBkO-_$xP!D8WZbwHNEDe;@Y96&NQ=JA%*zAH2DDtA{-C
zwvLubw_EdnCnK#OpXX8++GWcug;VmnN0G?(&iLoc`f`AXop-e}CaU4UV#dG20qo_1I$vZsQ)9k+YKu6RXO$z&8jtrn4i
zqj~kV`Er5d7iovlpplm9#Vum$DLs|M@GIPwb?I
z0s3b=?7Zx}27js0X3`H>$A;eOnIa}8BQBQv_q_dsd^~AJqxkKl-3TLrOxp!Z9Flm`y`%;RRfq%s-b*5hwiQn;bkahzpgcK9+nRpuZj1)9)
zTl!I6^?j1Si_U9uMeOZTOib>BBcO?TMjAFodSIl4tH^N0E9dH;C#$9KP6_|13ZtyN
zygXQXSw-PYZhG0v)N+I8Rj0#HNiLa
zmgrZIHhA9ry~x`}c@yYl^Zp;j7tgh7nY!P+4*bJp`=y~+YI7@&V;q^wvq@`oTQ>(O
z?yg!g?^;WlV@W6J)#)mqAs3mGpFQ^CsC|0I%ve;wYdwXS+f7pBuUeC_)aeIM`w$xk
z=mMSJ|~371i@=uL_=~P?W$*P0fbNI{9@Y
zl#C8G43$ivwJ5VAuF945&~YoC$tBm?%?(;1OS;5T(*^@bPwZ*g3W^x2J1%B`r}Aw^
zSBUADqHMA}!MRQC>=}=j%g%S$uc1Y&^5uxGSp6qH5y^vKngrd^5rbn<0r>|07x;3w
zuiCbH%U);aUA)Ju9U!`qQb)e7f$#pOn*(=-JM2AP@!JiDpFyy@YPbbQELI-Z4#AD#
z=un}yU6W7?;BhUd7@uhh6(Js>y8J%q(ojSj{P=>G5ygpwOJTl7zwNBC()VM0$U>He3rI;
zXTD*`LV|o37DkRW5{jqYF?LnHN=064C#@d$9Uea^;^Zz$J~G)DoBhVt500Bw9S`(+
z9dTp4UTIik*gfSO)dow-eYOSTqnnr4)wyR9Xj_+PM2DMN<{A~8f8@lGz96!Gkmb=6!g7#XS17*6f<1jKL?|3=HQ9@?bSIoYO6ZDURm!JCruXf
zT`(J)geD2USJ?sk>
zlW*90@vE@OR|;`zSl;>%QhG=v;P~Q)9Z#|=isY=%ImBjdJXqF<=4*)iC9Lu!o_0|Y&p69
zFZK8LQmYYQ+meEk{JfN}$xIvt~z|zHI3uv6gqf)e?0QrQ*er)=yt;h_3g2KqY6gA
zO97T=#WnZX!_L~iQYaIdKs?vQ@iZEE2}aw_xTi6zMC1tYbMk7&Uq(Jh)!}Wf0Xvu?
zSuU0Ced<`stsXJ_Ek+LB&SshRyR0fnl2(KBZ1NG*!s{jQ!)wctIE<|{q?X-H#{c;r
z@Odu?GY;6^Ku)Uu`5$>*U@@St*F|Il85f`Bm(1t>E0zIsVugEpK-tQYwb9eH>c3w$
zy&WAAB?v#-LwQVGVt8L&snV%2^LKYim3CCI}?K--K1jN#h5fZy_m0#ZbR+;_q!3#yTlQueAg
zAA5_Z_zw4?ReF09ikBaV`K#*)sgTE9yg;rcV0?s`9|N{_SAS)>1zVym1G*soI!W~$Qdg}aN;CA{tThwY)56A3n>yCl>pt~N%eZ(=z}__#R)FxDk6L0=v``Q
zARxDu;#q*7%5sE~j#RXD+6EE}Twya@sqY
z+*cg(n<8JypY<762YJU$DWX
zWO$Mnz5E$+k^^DvPAD<*fd_W~na;QM2j&iF`gr4U3-o?MY}Z$NC=w0CFDoVV5gT?D
zE_rm$R%`(l-jdD@(hM-JjTZK6MtfXi(b9A&H)#Z7P#moX)p$=Qm#@{I;0F1=e9e3P
zCSBjYZb6}kdq*;g$dZ&w&x}IHnO{XPrcF-Xy_Fe3ua8;Yg68<{)iqlulXiRRXzXXj
z?xoVDqt1QZ?Fa$}TQb&vW9~;Z0Inw1xVbneMTK2(2&lv<3Zkq7{?c$pf*VC(T9!G+
z!#2fJh(WYRI6uHXi*gIU^4#9Juj0p{k1gQ%30UFzA_zBykh;&mwc5W<|JKIF`weCj
zvdacO1>9z>QFt41u&M~fL@KkD)G21SjCi_wr%x*@&JEad)^87uHD9$*@r&cu$IWJ0
z6NfvvJt-Zxnab@rSt>xL{f+|=qAvqE?MZYmg#we3PrjFth)6VS!6W0*7u99PnI#$)0XHp3ip-F1}91_X5FgDc>k+
zY|dimrPfHARo6G>sAgm3Qu6gU{Gbh;jL0N0s7>yG;;(*
zxXi}6b!S1T{elEJxP(huNdIOee5sRsVPa4p-7P1&qztzRmd*8It4??q~ido?c$ZVFq}CkJN(M+grDO98Yunbm(v_
z%eK}UN*_yL!%(NoZQmhM#2XD({7EnwKY9_R)8A{mh$@$fy^S@8E
zGFZaUV_%iVokzb8QZTPi_~8<%zc;yOOrhu3Fsx%d43q=sepavV2`Kg`T`SUY
z3!g<7?N-w<{n0gbJ0w<3n4X?t%CI>v-n&LkEBV03xWQ!jKtH^#zI)rIzNPN@r1Y`W
zQmIlQ1r_<NMu7^OnFm=VaO6toTRuffhb1txk#pP{zo~>s)p|JmY6tzS%V#
z%f_KL38YZhQRyB42Oc?692#OD(OLClg)IM>00~J
z$M}S4tpF!3-^-X!#=-;+0GK+m+>~#-rCqfVd?P{POQpbb;Pv)m*l(0{cei~58P&h}
z;0+)Z)4FX5V`}_PsAFtiQdkzJs}&y~mk>L{!OqUj$;n>hqq{_TZ)tgz!vlq?m=X6F
z*bFQA^ol12W+81N?saE5E0*%W#9Ck9OZFqI4fS$-Ebn%}zjVAE1^~#g$!*IbAnwu$
z9vK+Ag*!Cw#Kp(WaBy*RKVfIraZ9W*)XUAaAsUo{3v9$`^d`W3Sy+yj++r!UOmr@i
z@OVlC6Nk-@O+eT^Y`ALYIWP<)t>5}S3RIZ_B!1~)*A80e?kQPH)iE;q@OFP5{}#*y
z_3Ng#f9Gv>9$>v@BAsmlPG37TjLa)tS_y%--ZxIpq9ww=F@g
z!DORSlM+seD%((cPhEnS&CYw?_TyjI$bmdQ(SjFaRXkc`CoM}*|Y=-O6E+7dH4lIE^E}Uy)_ck
zzr;BVNYZ%6K6q#BzkUivv!4KoM;lYm$j2)klL*-x+rz|`L
zkgpm6S7Q6{5)vLZ#qmq4Q1W)Vybm8N_5gf2<_`h|SadzN-hPX&Y3dR1{BgvWioB*C
zuEbhGW_4&45A;vmb|x(#B^i
zsO}+1SK=g8X?l+VN?Z!36z6XNVL9{2*-PX?XP(8vE=)32w{J2vH54j~NX=>Yu<^C=o8o`6IM`fzxJn%d%zBs1Z
zYi#Z%$_5D}{EgWO2=osxzVYo#m7+Y0DxG(VUaAC3i;vW0EQv|#>&hxAm17!(zrKgx
z?-L0T#*+jrFz%#>VzTaimD^@fl}O(K{-ul^rVRO!rJoTGV4N@>G|`#&+(R
z(^gJ3aB1z;j*_V^r98hHvT7)PDX!QpU6%fh(svs>O?i2JwnNgk-m=~m713hi5ChSj
zaWO5*%PVc|6r++%7YU~9?CekHP`3jWB9208Wq=c^`1X#HJ~)@u5?D0b%A7C!%X-d+
zIH|4@iEUucB|En#z05tfr!Zv7?;D_ybll{m7dBCqc6N2;3-#r}8D9r!jJIIW;xx
zzafB!D?lGq6EvPa?Jpbve5G#4qy=*w_QLO00F&mDk^*4hO-ofAbfI?xd+^V%5FU>!
z*1u{HH|$GIO>I}N;RjgEkASth+{a;o3E{paC8$l?bCq@;(oKo?`#xxo24319^bQKRJaW|@#
z0|?WuzQisldQhQgvx2EeSP4K_1!-HeT=RZxhb+Gs{SS+D=)FLnZ9L3AT9Uzts#uwn
z#D?XT2R!Bb!>L7ZB^OSHIL6^q@z68+v#aXL-nO(+$auC`NWkF=^00tND4VJ#l(kh~3a(thW8#>i3_z
zH6UNK=Trg^r1=^$iSDUe8Yvd1^U0jXhO70@Mky;
z{VqJEAx2q4MUGbA^nvzSS%iM37PZo9LaM%xWokd&&Me<=vU=XH5tOP{Zf*`Gne^2*
zU;OsG&GU?0K=SW!ird}Y%}evR{o57X?VF2=ii(KCVm6Y>ZR2W4cm)$q;>hG6SZOrm
za(~jZk@0jw@N}}^)f>6Lzt5oG&6XnV-h(e5u=LSIoB8RmO&t56=A
zN&q@_F`&WhrcZ{&t-C32BMMt%&1Zr6+1Ja;DN)qseab7oaT@7ac;{ZjX}i&lce)G!
z$tBIY`rWT?zOOrqx^n#g!B&
zmdm~VF3ENVK%;knx|pUmy%SPf;dWp3&fqGo*ht5so5eb!YNiv)D-=QSd3zRPo4wp~Y1W#+Ff+E1qtaHs0je17M!#{q0ucub(G)h2V
z^j?7`@BX%*aE1hjI6-mms4fOS4v6#*B
z){v5tZsIIocdv!>mc-@b@_J|-i5Pr%5xuO}7eJ&3N;;b6Z4hm*1boF55QV{rOD6OJ
zg!Ak;FnDPb{f1G0i@{a%;bwppC~T}D_mwNdTKx<)(g3*fp_>HQYnEH1s#^(Ec#mi9
zWLin(Zl{AW6%pB2GbIZZ$}EO1cJ;y3p8A(2`bjlz9a~Y$swZvpBL)T`R0M+%LY!zk
zmJ)UbW7YX@a2FgE3s?Q-6=5#L4PAyU5^5|){ch%eCWTKMB^$;ln8l|YdWySn441o`
z%Vi$#ZUH4
zs8z~pcd~BBv9`8$b+~ByC}L{B$$QiHbudSIp%9rtT+qp5?)W&&zISLxuyfs#Ns#nrdo^F)<`X
zefoXGHK`J6<(^NEo;Pux&btM9ES5{f7~&yP$rRy6pMH}l(OM#nm#P{Bdck=mdOze(YFY&Ve93y~?lhvM#ZSK*ViN~Q9cqfAK^k)BZ>z6w
zO1XX^CjP<+P1SiI3qS4K^5+9dy*=blHWo4ad+
zmA0RG(kZuRdp6EY>BTetC9h9JXGsY>@CpK?ZQ&-1^70PbA+1uMo
z-t>68S7D7+Rq(ss;{l>ubYioS~tT%3haT$t-HpFEkfS5r{094!ACP-YEJiuKENN2Pq5EdVsM4h%M^
z>=xb0hi-8BtZng!s&)t{`R}7?3XB^_M>L$z*GbldtFgJIDl`r~I7^*wy)R6fV~Wf4
zp8{()ODKL9Pn-7F0_2d~rNMnwS4GOZX|rd1Za=1^^%9S>_Gy-V!or6*`NPMBY5+Q6
zkl!S0ZkVt8cQ6F9xl0waynIly^j18BzJj%WVpWc7@<1G&C$Oj6^=}}V-Baf2S=!T|
z$&1OE8PDT3I6*%|Ksq5N-jtM-OMsRFj)Q>BiVvx4%EV?rIXXJKL@fuLm7I(_m&@~W
zyiV1$M6)3_F7BHK5wH_=Eiw${U&vFa>_ey1ay#E1TWoN&T&R)iw))!{2w|k6qWWAy
zZOU`EUs)m3%|b%5v6GiZOH0dQR@%Yk{Vx^xDksHSB+<|^zXR%+!GCF*z7)1LkGoIp+hRpKeH}1MseG+k)lk)
z?(zWRWNu=i1WHz^H7te1HI;ZQ1%+=o_x-T5zr=bDtX$&Zbt7fxtMG(-6YopqP`BQ`&giuOH5RdDw6?Ju|axdDj+JYq=a29v%m0^8NcSy2^?Q
zkuY2eM+S2t{Hn}My*6)9E>ACZ?SlL1`j@1k+~#PUQ^SDIk0H-m-yv3b?bZye>9#N6
z&3?Xqi_L10Y|XRy(CRO(RcEydEWqPMsprE<4?$07XR%tf_-p5#@tozSN5B_r7QN;Y
z!f*Q*ai85j?nNQ=2guJLz$9dkLd-xlCTkctwfJlvEb3A_E`W=0FL1SIcboGEz^$%@
zqf#`^cef+7$+dr@3XXF6+hbcvnrMxdD>#!YBJl3MCPS<=SsE+`v=rZ9l_uouv)hoi
zl-Z4kY*-Fz(S!rh`T{`9)SZRjGIruW>6-Mb17*@YCFitO
z!qnuS`?kap0Ki}MJAYuTL1VewCrLU)kL#N**<7d7NLgx3&-Up<%TPoG=zRM;fD#yn@lM1|DVU
zwua-fT5r1rEZO<9jXHV!1=4rV)2Ouj^E}?gdfU82U9x37ZkKZ)KbUgVc3Sl%c-R(Y
zEWD*X$juY|=ej<8R0M72J33TD+p4RTNmJ7AJuKp#YwuF`!Ykh*rU44
z`3kmr9^LI7w*7*Wz~3gDh4P8G@Z?4&Uc&*LO66~<&D6__w(ElckI2eYlTbvWu2Q4x
zs_8DMDD^uNSUi=|U~To~Eh?Fb0ReRRbD`&Y1*9rq5
z*;=?X0w}R+K>p137rR1Ya|_G_N97j0K7g$nny%&1c-S6dJNNgD7!~8U5-*u#Gk6ar>Kj@$uQJ(q}HdgK{@%vEuSSe+cag?O3g|Uh~7<
zea?o?|B%>6xVk4UVQ9NC=ye7>n*vEB3>?zz!DY?Dao%F6f7Jc`{hn9v+p{YUX&?{9
z78&2W7*6HBn`wExXgF#v!l2b^bP^#1a@x_W(=@6rD+R!ml$FzXJ)6_hb*_(BZw2mv
zq$@(XlgYF=>wNn^dr6?Acc(RAqfr@A(%BWzskRUE2fE|XI`k#}iUDpC21T$TJ58_d;BpHpSSw5~eDL9N-=*;~McL{V}
zl!8c?)NAT%nlnh~wFj$s4&~oCZVMuAttFYPVA5|`s!>FHGj-+vW*wcR6
zWNo=wSbkKZbK6RBoCFoFuaZi}ryEIsX?{4c97w#CxKYZ>JKE7e>TF~(c+vX?$0K}R
zkH(JG(IypR;~n|0-1aAbyY~0Z+@TA^Ei6j7I#)aVr^w!5s?*m$1Z&?DCBJh}*s1?N
z1td@os98uDFz>l@qHzP29t8TcCQ|VXCB41sW3Q4<5bbw^Z%XF#_2!nbY90qhkAuPl
zJHd4Xyh+?Z5@hd?4Y7IzlEtYFNM{~r*x=W>%sf3`po8T1OR=y+M`h+P=b^X~c}DX)
zYHWTnz#1i%t7JcQ|E!`F*c4E-Kj3K(QUdH?sbZ)eL?V1encEcSLciy2Y>GFQg(?lI
zv0JPON$KG+T~u_})~)0$#(@Kb3#6QaXe#FB2f=jB-|ykulUOZz9?mCr5%%!VSVws7
zimk=t44wmM9YZdlaIP
z@cCQwNjHvGsq$hfhkaq{!n0=q01lvr0QS3itaRYM!)24v)NHcfn_gdE?+V7K<*^}q
z5$bAu!!mE5ga+MN<ueWD&(_)`JoCie4Ll=b^w9}oeCE}8_tL$L&+=7l#1p?810H4)^tV#yq(n#mr7!hYR*Ya0WciXR|e+3A!$ySbI&=u!KY9#
ztJy5Q*=$*4Bue$DQDrD5gWhzpYG`OE(DcJ-p{lA{fkW4LEWpptFKoJ=;d!^PoXYL$
zu-+R1xCwJs+;SiG$Z3>9$A6$kHMD6hsPaj
zt$?|rmq=?TCua2HX+rf$8|`zkm`fi+uEom;ZP~u2wiNPww%&o53oOR^nh;lTg-R^M=Mlwuy0A3&2#@~F`H(}h#9
z0zET*ub1PS)GnWZz9VNXlS~Z{-2#`}uAG?ZgXdC+?`SszftrTKyf2dEcHmhnfy51B
zuv1lc;?h*wd|LNKV6cQY3HeAc5i&&m0
z1xBZ19s7@EIII>v&g^9tpZ;M+O;pb?lOmA$pvu`Pc==9v3#UWNzas#&)5uZMozDKH
zXJdymJk0a#C+k+p9Kh*oDKC$117YLu`OThZT-82+mSnZXB-ZS0_em^m#!|7K0tq?$
zWvFjb4gP3Se;>^~;1Zj0;|re`W!kN=XHw;jD*19@4X42!kRS5iZM@a2N@;OB16X5#
zaMgC8E-jm^>QHz5wu>+IImLfgub?$76>{ExgdzDwdW_5-JEbYwcI{Gg&xWR@Ouha=afVVT;>q&WiDe>bKI~^ri-;gNp>J3-;{OKN9^fT$)e{eqpQI
z@4WdPyZK1Alwk;j<4jJlc%e!}NoFF;h4rJ0|98wjo@n~#_h7C&hE1K_XdBQ?eUA&D-^=bt*EL}Wp^
z__HcrQ`7AKjrx8v6k-4JV4<13Zb@mf8v~PQuTGUAGULPJbDUj5BYDFOAbOP^bve=fcbe6|6ewQb5npuRRSO4!9uF~lGMA>i>%r+6cmA&ax7{iIsafe!gwXq^bg%t
zdq%=(yVRa3FQ7dJOT7%gpw(o*`Xgl-0N!Wy{D-YUDcQhNz(s2QZdHSxh%+%ULF}3T
zgozc4d}dLM*%vmR6Va%!e|NZl_kRIt@qZ)H>w}GGDqMa;e~{8DT^y4!bX0Bm2NeB?
z!4>HD%EpyeYe7p~Sc}No13X#Wz{Z-1l2t!*ohqd0X@4qu=T?#0hCwCmEwd_*7fy$m-RV3{V%=e2HT$ArwQSDJCf@z-
z@<1JihY_9;RX4TzTbI}_*Wfddp7#D`ac)y!_q{9EoT-OWIK2s!VDeM`g)}I)_L?4G
z^Dru!+Z2s#73MTU@#$t>+EL?sGcs}M`*pK$x%xjEunv2}j=np00vR<4#-pjEWbxPm
zCv44o*JI-pnWmgJJg-uIBl@#;LP;T^ZTyf$!r54fcm!jXK@_~I7rcd=p^F?@wh@Z6
zzWPimfTy=(X?opp{#{QW0VBe0mi+|%no)a?OkkRQH>(P|@~|rK9w7?O^0dE$`5!5y
zLj)J{sIPQOr=t^m3GBI7@2{9Rh(!DMH~MmXUTDnk0G*QA1ijatH}ygeL8(Q};MfDG
zjLmh0tqte-M(e)^Lj4F6!@ZCO_>r-VV|x&(!4|;y0-yJTT)q66FYk|qBS6$^spsYX
zxDW$P8-u3-8&IR4tH*Zz{Tq^75IFJi-*cfxnWdz()a|80n^^7vP{M#4f>2!1zv1C+h*;PSjY?VQ8ZOTXCBZYztDP!Vne0~Hl^moDSBbiBf5
z%Cmq%=T_|+Fmh(uCZ%WYMZs%o))WXFYGoCt2vgpDwgA)-o0kXh%UHVoDUDp*%#srw
z270*SFN1TrOm~YYYr53LW!@1e!Y$HJpMQO#JgwC(e4+&8lV2>S7a=mLO
z#*87Eg1VE2WVGEL6fA+tjSIop3$P}Cnb&czN-#FDep41F!J^yFsl=2JaAGC|p?SB(
z4wSo_JBk)x-HuQTy_XNFl!gUc(`G+@7ju`Tw-?FYy_}3fOvNsMludIC&IVMghyM4b
zg(?HMi)Y)LqG^};JomEOj{|lH2BP2icM+%ok_uqi4y0i}YrO~hKx%fe-Q}_q-y7|>
zPd1jZ*sCna70XY1z4Qn238@stBUK+bD6D2}x$SI9#AxrXi!wh+XoHq#J?%L_#c@>h
z8D!o&5^F`DiKgu6HGK+bB{6h^u<<_Fa=wi5gIwpgwZcKp_Njy;e<8LUa|F+m?3K1a
zjKpF|YY3h)8JbESO?<)g>rJ4=LuliTIpU2);;psfb9=xqA|D%^+{FYF=-(J7-sc2m
zN#B(orhsnB0J(rFfnpD02tZf4Uv#^jb*Ht8iE|@fHVE*Il*fKn%Jmav<#m}?Zg_|r
zO@jvX9(@zF48OEhph~B(<8zG;1YZ8@l8TRNLm6$1-pk{h42nTv1vldxafdB-oZ0Rg19nF$f
z4wE(kg=bj
zDsaz~?2{okr~+6bAdDr#1Fp_!x4qb2<+|y=4Jj_c)q@Po+TEuE^PUOAo*^r!W&VY&
zk~H!5M1W}bs^CA{>t^6Eyi7*uqiK`=t|v$0J(|bU6fv60yXxnLih18^b^rflaI5Ny
zuYYDp-O|3_f^USN;zLz-tX_sJtRiavKU-jMO%Fam?h*2yc7boJoLSMRus#1ZKE|Hu
zWsFg(;;GP>YG_7uq3KhqiibEdBDDC1JwQR=O>4p6miI6FDfrIIShx}k-kUg{Dqr2w
zIc8JRfBmFJ&wmDjau2(}xX3bCB!J?Ju6$(lj4r-|f!Y?H)}BO?ct0(BgI4f3Fk$I!l6PPe^>D&yMo`^QG;}d=?7thqyc(U>B1Cc#{QHx3DCN*Ix~>oQL}i844;h
z^}a?~6ff7a+*!;dsls}X7?>5);|dg1yea~beqv%{uBy&7bbsf(c7k0V^qJkX_s))q
zR_P8!d>XzcCe*nseyQ@)S;IwqcF}pRLFIH0G}JlFecLOj