From 6e2e5fdd5b486b4f2be053952a1c6f87b70a2b29 Mon Sep 17 00:00:00 2001 From: chen <2710907404@qq.com> Date: Mon, 17 Mar 2025 10:28:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E8=B4=B5=E9=98=B3?= =?UTF-8?q?=E7=A6=81=E6=AF=92=E6=A3=80=E9=AA=8C=E9=89=B4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dlp-drugtesting-api/pom.xml | 47 + .../inspetion/api/entity/EntrustInfo.java | 59 + .../api/entity/IdentificationBookDTO.java | 190 ++ .../inspetion/api/entity/MaterialDto.java | 108 + .../inspetion/api/entity/SampleInfo.java | 47 + .../inspetion/api/entity/TargetObject.java | 78 + .../inspetion/api/entity/TestRecord.java | 96 + .../inspetion/api/entity/TestResult.java | 24 + .../api/entity/TestResultDetail.java | 19 + .../feign/RemoteTestToIdentifyService.java | 40 + ...eTestToIdentifyServiceFallbackFactory.java | 23 + ...moteTestToIdentifyServiceFallbackImpl.java | 42 + .../inspetion/api/vo/TestRecordVo.java | 19 + .../digital/laboratory/platform/AppTest.java | 38 + .../assets/image-20240417101824328.png | Bin 0 -> 9837 bytes .../assets/image-20240417101958546.png | Bin 0 -> 8873 bytes .../assets/image-20240417102214943.png | Bin 0 -> 168397 bytes dlp-drugtesting-biz/pom.xml | 269 ++ .../inspection/DlpDrugTestingApplication.java | 23 + .../FeignOauth2RequestInterceptor.java | 37 + .../inspection/constant/BusinessType.java | 38 + .../inspection/constant/CompoundMassKV.java | 45 + .../inspection/constant/MaterialType.java | 15 + .../constant/NumberTransferHanZi.java | 45 + .../constant/SampleInjectorConstant.java | 281 ++ .../constant/SewageCompoundNameTransform.java | 62 + .../constant/SewageReportColumn.java | 72 + .../inspection/constant/StdSolutionNum.java | 18 + .../constant/TaskTestDataStatus.java | 52 + .../constant/TestDataFileStructConstant.java | 17 + .../inspection/constant/TestDataType.java | 50 + .../constant/TestRecordArgumentType.java | 30 + .../constant/TestRecordFileUrl.java | 26 + .../TestRecordSampleDataConstant.java | 62 + .../controller/AssignmentInfoController.java | 148 + .../controller/EntrustInfoController.java | 132 + .../controller/IdentifyBookController.java | 36 + .../controller/SampleInfoController.java | 105 + .../controller/SampleInjectorController.java | 120 + .../controller/ScreenInfoController.java | 76 + .../SewageDrugInspectReportController.java | 64 + .../controller/TaskInfoController.java | 101 + .../controller/TestRecordController.java | 215 ++ ...stRecordInstrumentConditionController.java | 82 + .../TestRecordInstrumentController.java | 98 + .../TestRecordMethodController.java | 91 + .../TestRecordReagentController.java | 99 + .../TestRecordSampleDataController.java | 302 ++ .../TestRecordSampleSolutionController.java | 80 + .../TestRecordStandardSolutionController.java | 82 + .../controller/TestTemplateController.java | 87 + .../dto/AnalysisTestResultPageDTO.java | 35 + .../inspection/dto/AppraisalProcessDto.java | 13 + .../inspection/dto/AssignmentInfoDto.java | 19 + .../platform/inspection/dto/AuditDataDTO.java | 28 + .../inspection/dto/BaseCaseDataDto.java | 20 + .../platform/inspection/dto/BusinessDto.java | 10 + .../inspection/dto/DataSolutionSampleDTO.java | 47 + .../inspection/dto/DeleteTestAtlasDTO.java | 25 + .../inspection/dto/EntrustInfoDto.java | 10 + .../dto/ExportSewageAnalystReportsDTO.java | 42 + .../inspection/dto/HairSewageDataDto.java | 118 + .../inspection/dto/NPSCaseTestDataDto.java | 69 + .../inspection/dto/NPSCaseTestResultDto.java | 40 + .../inspection/dto/NPSCaseTestSampleData.java | 35 + .../dto/QueryTestResultPageDTO.java | 43 + .../dto/RegionalDrugConsumptionDTO.java | 59 + .../inspection/dto/ReportConfigDTO.java | 26 + .../dto/ResetSampleInjectorDTO.java | 54 + .../inspection/dto/SCCaseDataDto.java | 12 + .../dto/SampleInjectorExcelDTO.java | 87 + .../dto/SaveQuantitativeResultsDTO.java | 33 + .../inspection/dto/SewageDataDto.java | 51 + .../platform/inspection/dto/TaskInfoDto.java | 12 + .../inspection/dto/TaskTestDataDTO.java | 61 + .../inspection/dto/TaskTestDataPageDTO.java | 38 + .../inspection/dto/TemplateDeleteDto.java | 10 + .../inspection/dto/TestRecordArgumentDto.java | 18 + .../inspection/dto/TestRecordDto.java | 14 + .../dto/TestRecordSampleSolutionDto.java | 11 + .../dto/TestRecordStandardSolutionDto.java | 16 + .../dto/UpdateCompoundCnNameDto.java | 12 + .../dto/UpdateEntrustTestDataDTO.java | 29 + .../inspection/entity/AssignmentInfo.java | 53 + .../inspection/entity/SampleInjector.java | 95 + .../inspection/entity/ScreenInfo.java | 38 + .../platform/inspection/entity/TaskInfo.java | 55 + .../entity/TestRecordInstrument.java | 28 + .../entity/TestRecordInstrumentCondition.java | 27 + .../inspection/entity/TestRecordMethod.java | 32 + .../TestRecordQualitativeCondition.java | 42 + .../inspection/entity/TestRecordReagent.java | 28 + .../entity/TestRecordSampleData.java | 69 + .../entity/TestRecordSampleSolution.java | 36 + .../entity/TestRecordStandardSolution.java | 83 + .../inspection/entity/TestTemplate.java | 46 + .../event/AuditDataExecutionEvent.java | 24 + .../event/FinishTestExecutionEvent.java | 12 + .../AuditDataExecutionEventListener.java | 31 + .../FinishTestExecutionEventListener.java | 22 + .../mapper/AssignmentInfoMapper.java | 16 + .../inspection/mapper/EntrustInfoMapper.java | 16 + .../inspection/mapper/SampleInfoMapper.java | 28 + .../mapper/SampleInjectorMapper.java | 38 + .../inspection/mapper/ScreenInfoMapper.java | 16 + .../inspection/mapper/TaskInfoMapper.java | 16 + .../TestRecordInstrumentConditionMapper.java | 23 + .../mapper/TestRecordInstrumentMapper.java | 16 + .../inspection/mapper/TestRecordMapper.java | 28 + .../mapper/TestRecordMethodMapper.java | 16 + .../mapper/TestRecordReagentMapper.java | 16 + .../mapper/TestRecordSampleDataMapper.java | 70 + .../TestRecordSampleSolutionMapper.java | 9 + .../TestRecordStandardSolutionMapper.java | 17 + .../inspection/mapper/TestTemplateMapper.java | 24 + .../service/AssignmentInfoService.java | 34 + .../service/EntrustInfoService.java | 27 + .../service/IdentifyBookDataService.java | 30 + .../inspection/service/SampleInfoService.java | 49 + .../service/SampleInjectorService.java | 59 + .../inspection/service/ScreenInfoService.java | 31 + .../SewageDrugInspectReportService.java | 14 + .../inspection/service/TaskInfoService.java | 61 + .../TestRecordInstrumentConditionService.java | 42 + .../service/TestRecordInstrumentService.java | 34 + .../service/TestRecordMethodService.java | 28 + .../service/TestRecordReagentService.java | 36 + .../service/TestRecordSampleDataService.java | 162 + .../TestRecordSampleSolutionService.java | 30 + .../inspection/service/TestRecordService.java | 92 + .../TestRecordStandardSolutionService.java | 31 + .../service/TestTemplateService.java | 32 + .../impl/AssignmentInfoServiceImpl.java | 501 ++++ .../service/impl/EntrustInfoServiceImpl.java | 184 ++ .../impl/IdentifyBookDataServiceImpl.java | 346 +++ .../service/impl/SampleInfoServiceImpl.java | 395 +++ .../impl/SampleInjectorServiceImpl.java | 465 +++ .../service/impl/ScreenInfoServiceImpl.java | 148 + .../SewageDrugInspectReportServiceImpl.java | 2652 +++++++++++++++++ .../service/impl/TaskInfoServiceImpl.java | 1489 +++++++++ ...tRecordInstrumentConditionServiceImpl.java | 433 +++ .../impl/TestRecordInstrumentServiceImpl.java | 220 ++ .../impl/TestRecordMethodServiceImpl.java | 149 + .../impl/TestRecordReagentServiceImpl.java | 264 ++ .../impl/TestRecordSampleDataServiceImpl.java | 1915 ++++++++++++ .../TestRecordSampleSolutionServiceImpl.java | 371 +++ .../service/impl/TestRecordServiceImpl.java | 1529 ++++++++++ ...TestRecordStandardSolutionServiceImpl.java | 423 +++ .../service/impl/TestTemplateServiceImpl.java | 278 ++ .../platform/inspection/utils/PageUtils.java | 52 + .../inspection/utils/TestDataFileUtil.java | 63 + .../inspection/utils/TextEncodeUtil.java | 144 + .../utils/datafile/HairDataFileUtil.java | 92 + .../utils/datafile/NPSDataFileUtil.java | 235 ++ .../utils/datafile/SewageDataFileUtil.java | 157 + .../utils/datafile/hair/HairDataStruct.java | 20 + .../datafile/hair/HairSewageCompoundData.java | 35 + .../utils/datafile/nps/NPSDataFileStruct.java | 55 + .../datafile/nps/NPSTestDetailDataStruct.java | 32 + .../utils/sewagereport/AxisYVal.java | 30 + .../utils/sewagereport/BarLineChartForm.java | 31 + .../utils/sewagereport/ChartForm.java | 27 + .../utils/sewagereport/PieChartForm.java | 27 + .../utils/sewagereport/TableCreateUtils.java | 675 +++++ .../utils/sewagereport/TableForm.java | 40 + .../utils/sewagereport/WordUtils.java | 917 ++++++ .../inspection/vo/AssignmentInfoVo.java | 14 + .../inspection/vo/ESTBusinessInfoVO.java | 23 + .../platform/inspection/vo/ProcedureVo.java | 34 + .../inspection/vo/ResultConcentrationVO.java | 22 + .../platform/inspection/vo/SampleInfoVo.java | 9 + .../vo/TestRecordInstrumentConditionVo.java | 9 + .../inspection/vo/TestRecordSolutionVO.java | 33 + .../vo/TestRecordStandardSolutionVo.java | 10 + .../inspection/vo/TestResultBusinessVO.java | 65 + .../inspection/vo/TestTemplateVo.java | 17 + .../src/main/resources/banner.txt | 13 + .../src/main/resources/bootstrap.yml | 56 + .../resources/mapper/SampleInfoMapper.xml | 54 + .../resources/mapper/SampleInjectorMapper.xml | 37 + .../TestRecordInstrumentConditionMapper.xml | 42 + .../resources/mapper/TestRecordMapper.xml | 49 + .../mapper/TestRecordSampleDataMapper.xml | 138 + .../TestRecordStandardSolutionMapper.xml | 48 + .../resources/mapper/TestTemplateMapper.xml | 49 + .../resources/template/templateStyles.docx | Bin 0 -> 12878 bytes .../inspection/test/JFreeChartTest.java | 424 +++ .../platform/inspection/test/LcTest.java | 58 + .../platform/inspection/test/MyEnumTest.java | 30 + .../inspection/test/entity/UserInfo.java | 18 + ...定系统 -- 数据文件解析方式.md | 138 + doc/污水检验鉴定系统文档.docx | Bin 0 -> 857237 bytes doc/消费量报表规则.md | 84 + pom.xml | 20 + 194 files changed, 22737 insertions(+) create mode 100644 dlp-drugtesting-api/pom.xml create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/EntrustInfo.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/IdentificationBookDTO.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/MaterialDto.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/SampleInfo.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TargetObject.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestRecord.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResult.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResultDetail.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/RemoteTestToIdentifyService.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/factory/RemoteTestToIdentifyServiceFallbackFactory.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/fallback/RemoteTestToIdentifyServiceFallbackImpl.java create mode 100644 dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/vo/TestRecordVo.java create mode 100644 dlp-drugtesting-api/src/test/java/digital/laboratory/platform/AppTest.java create mode 100644 dlp-drugtesting-biz/assets/image-20240417101824328.png create mode 100644 dlp-drugtesting-biz/assets/image-20240417101958546.png create mode 100644 dlp-drugtesting-biz/assets/image-20240417102214943.png create mode 100644 dlp-drugtesting-biz/pom.xml create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/DlpDrugTestingApplication.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/Interceptor/FeignOauth2RequestInterceptor.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/BusinessType.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/CompoundMassKV.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/MaterialType.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/NumberTransferHanZi.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SampleInjectorConstant.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageCompoundNameTransform.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageReportColumn.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/StdSolutionNum.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TaskTestDataStatus.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataFileStructConstant.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataType.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordArgumentType.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordFileUrl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordSampleDataConstant.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/AssignmentInfoController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/EntrustInfoController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/IdentifyBookController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInfoController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInjectorController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/ScreenInfoController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SewageDrugInspectReportController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TaskInfoController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentConditionController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordMethodController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordReagentController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleDataController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleSolutionController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordStandardSolutionController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestTemplateController.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AnalysisTestResultPageDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AppraisalProcessDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AssignmentInfoDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AuditDataDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BaseCaseDataDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BusinessDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DataSolutionSampleDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DeleteTestAtlasDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/EntrustInfoDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ExportSewageAnalystReportsDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/HairSewageDataDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestDataDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestResultDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestSampleData.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/QueryTestResultPageDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/RegionalDrugConsumptionDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ReportConfigDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ResetSampleInjectorDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SCCaseDataDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SampleInjectorExcelDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SaveQuantitativeResultsDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SewageDataDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskInfoDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataPageDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TemplateDeleteDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordArgumentDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleSolutionDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordStandardSolutionDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateCompoundCnNameDto.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateEntrustTestDataDTO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/AssignmentInfo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/SampleInjector.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/ScreenInfo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TaskInfo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrument.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrumentCondition.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordMethod.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordQualitativeCondition.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordReagent.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleSolution.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordStandardSolution.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestTemplate.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/AuditDataExecutionEvent.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/FinishTestExecutionEvent.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/AuditDataExecutionEventListener.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/FinishTestExecutionEventListener.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/AssignmentInfoMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/EntrustInfoMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInfoMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInjectorMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/ScreenInfoMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TaskInfoMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentConditionMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMethodMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordReagentMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleDataMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleSolutionMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordStandardSolutionMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestTemplateMapper.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/AssignmentInfoService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/EntrustInfoService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/IdentifyBookDataService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInfoService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInjectorService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/ScreenInfoService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SewageDrugInspectReportService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TaskInfoService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentConditionService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordMethodService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordReagentService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleSolutionService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordStandardSolutionService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestTemplateService.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/AssignmentInfoServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/EntrustInfoServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/IdentifyBookDataServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInfoServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInjectorServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/ScreenInfoServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SewageDrugInspectReportServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TaskInfoServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentConditionServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordMethodServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordReagentServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleSolutionServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordStandardSolutionServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestTemplateServiceImpl.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/PageUtils.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TestDataFileUtil.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TextEncodeUtil.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/HairDataFileUtil.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/NPSDataFileUtil.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/SewageDataFileUtil.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairDataStruct.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairSewageCompoundData.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSDataFileStruct.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSTestDetailDataStruct.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/AxisYVal.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/BarLineChartForm.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/ChartForm.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/PieChartForm.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableCreateUtils.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableForm.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/WordUtils.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/AssignmentInfoVo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ESTBusinessInfoVO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ProcedureVo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ResultConcentrationVO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/SampleInfoVo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordInstrumentConditionVo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSolutionVO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordStandardSolutionVo.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestResultBusinessVO.java create mode 100644 dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestTemplateVo.java create mode 100644 dlp-drugtesting-biz/src/main/resources/banner.txt create mode 100644 dlp-drugtesting-biz/src/main/resources/bootstrap.yml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/SampleInfoMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/SampleInjectorMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/TestRecordInstrumentConditionMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/TestRecordMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/TestRecordStandardSolutionMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/mapper/TestTemplateMapper.xml create mode 100644 dlp-drugtesting-biz/src/main/resources/template/templateStyles.docx create mode 100644 dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/JFreeChartTest.java create mode 100644 dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/LcTest.java create mode 100644 dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/MyEnumTest.java create mode 100644 dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/entity/UserInfo.java create mode 100644 doc/检验鉴定系统 -- 数据文件解析方式.md create mode 100644 doc/污水检验鉴定系统文档.docx create mode 100644 doc/消费量报表规则.md create mode 100644 pom.xml diff --git a/dlp-drugtesting-api/pom.xml b/dlp-drugtesting-api/pom.xml new file mode 100644 index 0000000..f812515 --- /dev/null +++ b/dlp-drugtesting-api/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + digital.laboratory.platform + dlp-drugtesting + 2022.10.11-snapshots + + dlp-drugtesting-api + jar + dlp-drugtesting-api + + UTF-8 + + + + + + digital.laboratory.platform + dlp-common-swagger + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-common-feign + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-common-mybatis + 2022.10.11-snapshots + + + digital.laboratory.platform + dlp-admin-api + 2022.10.11-snapshots + + + junit + junit + 3.8.1 + test + + + diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/EntrustInfo.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/EntrustInfo.java new file mode 100644 index 0000000..79991e7 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/EntrustInfo.java @@ -0,0 +1,59 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.time.LocalDateTime; + +/* + *@title EntrustInfo + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 14:58 + */ +@Data +@TableName(value = "b_entrustInfo", autoResultMap = true) +@ApiModel(value = "委托信息", description = "委托信息") +public class EntrustInfo extends BaseEntity { + private String id; + private String businessType;//业务类型 + private String caseName;//案件名称 + private String caseBrief;//案情简要 + private String entrustNo;//委托编号 + private String entrustDepartment;//委托单位 + private String identityDepartment;//鉴定单位 + private String acceptNo;//受理编号 + private LocalDateTime acceptDate;//受理日期 + private String deliver1Name;//送检人姓名 + private String deliver1Phone;//送检人电话 + private String deliver1Position;//送检人职务 + private String deliver1Cert;//证件类型 + private String deliver1No;//证件号码 + private String deliver2Name;//送检人姓名 + private String deliver2Phone;//送检人电话 + private String deliver2Position;//送检人职务 + private String deliver2Cert;//证件类型 + private String deliver2No;//证件号码 + private Integer source;//数据来源 + private String materialType;//检材类别(缴获物和生物样本) + private String entrustRequirement;//鉴定要求,从检材中的鉴定要求提取组合而成 eg:对检材中四氢大麻酚进行定性定量分析,对合成大麻素类物质进行定性分析。 + private Integer status;//0:未分配 1:已分配 2:实验中 3:鉴定完毕 + private String reportReceiveMode; // 文书领取方式 + private String postAddress; // 邮寄地址 + private String synEntrustId;//送检受理系统中的委托ID + @TableField(exist = false) + private String businessTypeName; + @TableField(exist = false) + private Boolean isDistribution;//是否被分配 + + @ApiModelProperty(value="检材数量") + @TableField(exist = false) + private Integer materialNum; + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/IdentificationBookDTO.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/IdentificationBookDTO.java new file mode 100644 index 0000000..713119e --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/IdentificationBookDTO.java @@ -0,0 +1,190 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import lombok.Data; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author xy + * @version 1.0 + * @title IdentificationBookDTO 提供给文书系统的数据格式 + * @description + * @create 2024/3/11 10:12 + */ +@Data +public class IdentificationBookDTO { + private EntrustInfo entrustInfo;//委托信息 + private List sampleInfoList;//对应的检材 + private String testMethod;//检验方法 + private String testProcessDes;//检验过程 + private String testResult;//检验结果 + private String testOptUser;//检验人 + private String testStartDate;//检验开始日期 + private String testFinishDate;//检验完成日期 + + // eg:1号检材中未检出四氢大麻酚,检出合成大麻素类物质MDMB-4en-PINACA; + // 2号检材中未检出四氢大麻酚,检出合成大麻素类物质MDMB-4en-PINACA。 + + private static String getNumberByMaterialNo(String materialNo){ + Pattern pattern = Pattern.compile("\\d+"); + + Matcher matcher = pattern.matcher(materialNo); + + while (matcher.find()) { + return matcher.group(0); + } + return ""; + } + public static void main(String[] args) { + List sampleList=new ArrayList<>(); + TestResult t1=new TestResult(); + t1.setMaterialNo("1号"); + t1.setCompoundName("化合物1"); + t1.setIsFind(1); + t1.setOrderNo(1); + TestResult t2=new TestResult(); + t2.setMaterialNo("1号"); + t2.setCompoundName("化合物2"); + t2.setIsFind(1); + t2.setOrderNo(1); + TestResult t3=new TestResult(); + t3.setMaterialNo("1号"); + t3.setCompoundName("化合物3"); + t3.setIsFind(0); + t3.setOrderNo(1); + sampleList.add(t1); + sampleList.add(t2); + sampleList.add(t3); + TestResult t4=new TestResult(); + t4.setMaterialNo("2号"); + t4.setCompoundName("化合物1"); + t4.setIsFind(0); + t4.setOrderNo(2); + TestResult t5=new TestResult(); + t5.setMaterialNo("2号"); + t5.setCompoundName("化合物2"); + t5.setIsFind(0); + t5.setOrderNo(2); + TestResult t6=new TestResult(); + t6.setMaterialNo("2号"); + t6.setCompoundName("化合物3"); + t6.setIsFind(1); + t6.setOrderNo(2); + sampleList.add(t4); + sampleList.add(t5); + sampleList.add(t6); + + TestResult t7=new TestResult(); + t7.setMaterialNo("3号"); + t7.setCompoundName("化合物1"); + t7.setIsFind(0); + t7.setOrderNo(3); + TestResult t8=new TestResult(); + t8.setMaterialNo("3号"); + t8.setCompoundName("化合物2"); + t8.setIsFind(0); + t8.setOrderNo(3); + TestResult t9=new TestResult(); + t9.setMaterialNo("3号"); + t9.setCompoundName("化合物3"); + t9.setIsFind(1); + t9.setOrderNo(3); + sampleList.add(t7); + sampleList.add(t8); + sampleList.add(t9); + + //按照检材编号先分组,这样的话,如果有n个检材,m个化合物,那么就会分成n组,每组中就m条数据 + Map> collectMap = sampleList.stream().collect(Collectors.groupingBy(m -> m.getMaterialNo())); + //我们把每组中的List 数据再次分组,分组按检出和未检出分,这样就会得到2个组,一个组是检出的,一个组是未检出的 + Map>> ret=new HashMap<>(); + collectMap.forEach((k,v)->{ + Map> tmp1Map= v.stream().collect(Collectors.groupingBy(m -> m.getIsFind())); + ret.put(k,tmp1Map); + }); + + //将3条合并为一条 + //将检出和未检出合并成一条,创建一个对象来存储 + List testResultDetailList=new ArrayList<>(); + ret.forEach((k,v)->{ + StringBuffer sb1=new StringBuffer(); + StringBuffer sb2=new StringBuffer(); + v.forEach((k1,v1)->{ + //这个map中只有2个值,第一个表示未检出的化合物,第2个表示检出的化合物 + if(k1==0){ + //未检出 + v1.forEach(item->{ + sb1.append(item.getCompoundName()).append(","); + }); + } + if(k1==1){ + //检出 + v1.forEach(item->{ + sb2.append(item.getCompoundName()).append(","); + }); + } + }); + if(sb1.length()>0){ + sb1.delete(sb1.length()-1,sb1.length());//删除最后一个 , + } + if(sb2.length()>0){ + sb2.delete(sb2.length()-1,sb2.length());//删除最后一个 , + } + // + TestResultDetail eg=new TestResultDetail(); + eg.setMaterialNo(k); + eg.setFindCompounds(sb2.toString()); + eg.setNoFindCompounds(sb1.toString()); + testResultDetailList.add(eg); + }); + testResultDetailList.forEach(item->{ + String str1=item.getMaterialNo()+"检材中检出了"+item.getFindCompounds(); + String str2=item.getMaterialNo()+"检材中未检出"+item.getNoFindCompounds(); + System.out.println(str1); + System.out.println(str2); + System.out.println("-----------------------------"); + }); + //现在对上面的数据进行从新分组,按检出+化合物的形式 + Map> temp2 = testResultDetailList.stream().collect( + Collectors.groupingBy(m -> m.getFindCompounds() + m.getNoFindCompounds())); + //这里需要排一个序,检材编号小的应该放在前面,大的放在后面,所以使用values中的值来给map进行排序 + List>> targetList=new ArrayList>>(temp2.entrySet()); + targetList.sort(new Comparator>>() { + @Override + public int compare(Map.Entry> mp1, Map.Entry> mp2) { + int materialNo1 = getMinMaterialNo(mp1.getValue()); + int materialNo2 = getMinMaterialNo(mp2.getValue()); + return materialNo1-materialNo2; + } + }); + targetList.forEach((target)->{ + + StringBuffer sbNo=new StringBuffer(); + + target.getValue().forEach(item->{ + sbNo.append(item.getMaterialNo()).append(","); + }); + if(sbNo.length()>0){ + sbNo.delete(sbNo.length()-1,sbNo.length());//删除最后一个 , + } + System.out.println(sbNo.toString()+"检材未检出"+target.getValue().get(0).getNoFindCompounds()+"--- 检出了"+target.getValue().get(0).getFindCompounds()); + }); + } + + //获取检材中最小的一个检材编号 + private static int getMinMaterialNo(List materialList){ + materialList.sort(new Comparator() { + @Override + public int compare(TestResultDetail t1, TestResultDetail t2) { + int mNo1= Integer.parseInt(getNumberByMaterialNo(t1.getMaterialNo())); + int mNo2= Integer.parseInt(getNumberByMaterialNo(t2.getMaterialNo())); + return mNo1-mNo2; + } + }); + return Integer.parseInt(getNumberByMaterialNo(materialList.get(0).getMaterialNo())); + } + + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/MaterialDto.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/MaterialDto.java new file mode 100644 index 0000000..7ba8ee2 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/MaterialDto.java @@ -0,0 +1,108 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import digital.laboratory.platform.sys.entity.DrugLite; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.List; + + +/** + * 检材信息 + */ +@Data +@ApiModel(value = "检材信息:用户接受其他系统提供的检材信息") +public class MaterialDto extends BaseEntity { + + /** + * 检材id + */ + @ApiModelProperty(value = "检材id") + private String id; + + /** + * 检材编号 + */ + @ApiModelProperty(value = "检材编号") + private String imNo; + + @ApiModelProperty(value = "委托id") + private String entrustmentId; + + /** + * 检材名称 + */ + @ApiModelProperty(value = "检材名称") + private String name; + + /** + * 检材类别:继承所取物证的类别或从物证类别选择 + */ + @ApiModelProperty(value = "检材类别:继承所取物证的类别或从物证类别选择") + private String type; + + @ApiModelProperty(value = "检材颜色:继承所取物证颜色或手动填入") + private String color; + + /** + * 检材性状:继承所取物证性状或从物证性状类别选择 + */ + @ApiModelProperty(value = "检材性状:继承所取物证性状或从物证性状类别选择") + private String form; + + + /** + * 检材情况之承载物数量, 例如 5 颗, 3包 + */ + @ApiModelProperty(value = "检材情况之承载物数量, 例如 5 颗, 3包") + private Integer fundQuantity; + + /** + * 检材情况之承载物单位, 例如 5 颗, 3包 + */ + @ApiModelProperty(value = "检材情况之承载物单位, 例如 5 颗, 3包") + private String fundUnit; + + /** + * 检材数量, 例如 3.8 克 或 4.5毫升 + */ + @ApiModelProperty(value = "检材数量, 例如 3.8 克 或 4.5毫升") + private BigDecimal quantity; + + /** + * 计量单位, 例如 3.8 克 或 4.5毫升 + */ + @ApiModelProperty(value = "计量单位, 例如 3.8 克 或 4.5毫升") + private String unit; + + @ApiModelProperty(value = "检材受理编号") + private String acceptNo; + + /** + * 候选毒品列表(drug 对象的 json array) + */ + @ApiModelProperty(value = "候选毒品列表(drug 对象的 json array)") + private List candidateDrugs; + + private BigDecimal sample1Quantity; + + private String sampleName; + + private String sampleCode; + + private Integer orderNo; + + private BigDecimal sample1RepeatWeigh; + + private String formName; + + private Integer analysisOption;//分析项目,代替原来的定性分析,定量分析字段 1.定性分析 2.定量分析 3.定性定量分析 4.关联性判断 5。其他 + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/SampleInfo.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/SampleInfo.java new file mode 100644 index 0000000..f7dfc43 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/SampleInfo.java @@ -0,0 +1,47 @@ +package digital.laboratory.platform.inspetion.api.entity; +/* + *@title SampleInfo + *@description + *@author xy + *@version 1.0 + *@create 2023/12/13 11:00 + */ + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.util.List; + +@Data +@TableName(value = "b_sampleInfo", autoResultMap = true) +@ApiModel(value = "样本信息", description = "样本信息") +public class SampleInfo extends BaseEntity { + private String id; + private String sampleName; + private String acceptNo; + private Double quality; //送检的时候送检质量 + private String unit;//单位 + private Double sampleQuality;//受理的时候的质量 + private String sampleQualityUnit;//受理的时候的质量单位 + private Integer source;//数据来源-手动录入或系统接口录入 + private String businessId;//业务ID + private Integer status; // 0 未分配 1已分配 + private String businessType;//委托检验鉴定、任务检验鉴定、筛查检验鉴定 + private String form;//检材性状 + private String color;//检材颜色 + Integer analysisOption;//定量分析字段 1.定性分析 2.定量分析 3.定性定量分析 4.关联性判断 5。其他 + Integer orderNo;//委托中检材的序号 + @TableField(typeHandler = FastjsonTypeHandler.class) + private List targetObject;//筛查物列表 + + //用来转换type类型的中文 + @TableField(exist = false) + private String businessTypeName; + + @TableField(exist = false) + private Boolean isDistribution;//是否被分配 +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TargetObject.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TargetObject.java new file mode 100644 index 0000000..0052ff6 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TargetObject.java @@ -0,0 +1,78 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TargetObject { + /** + * ID + */ + @ApiModelProperty(value = "Id") + private String id; + + + /** + * 英文名 + */ + @ApiModelProperty(value = "英文名") + private String englishName; + + /** + * 毒品类型 + */ + @ApiModelProperty(value = "毒品类型") + private String drugType; + + /** + * 发布时间 + */ + @ApiModelProperty(value = "发布时间") + private String publishTime; + + /** + * 实行时间 + */ + @ApiModelProperty(value = "实行时间") + private String implementTime; + + /** + * 备注 + */ + @ApiModelProperty(value = "备注") + private String comments; + + @ApiModelProperty(value = "code") + private String code; + + /** + * 毒品名称 + */ + @ApiModelProperty(value = "毒品名称") + private String name; + + /** + * 别名 + */ + @ApiModelProperty(value = "别名") + private String alias; + + /** + * CAS号 + */ + @ApiModelProperty(value = "CAS号") + private String casCode; + + /** + * 来源 + */ + @ApiModelProperty(value = "来源") + + private String source; + + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestRecord.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestRecord.java new file mode 100644 index 0000000..d863a23 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestRecord.java @@ -0,0 +1,96 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import com.alibaba.fastjson.annotation.JSONField; +import com.alibaba.fastjson.annotation.JSONType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import com.fasterxml.jackson.annotation.JsonFormat; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDate; +import java.util.List; + +/* + *@title TestRecord + *@description 检验记录 + *@author xy + *@version 1.0 + *@create 2023/12/18 9:39 + */ +@Data +@TableName(value = "b_test_record", autoResultMap = true) +@ApiModel(value = "检验记录", description = "检验记录") +public class TestRecord extends BaseEntity { + @ApiModelProperty(value = "id") + private String id; + @ApiModelProperty(value = "待检验样本ID") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List sampleTestList;//待检验样本ID + @ApiModelProperty(value = "使用到的设备ID") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List deviceIdList;//使用到的设备ID + + @ApiModelProperty(value = "使用到的试剂耗材") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List reagentConsumablesList;//使用到的试剂耗材 + + @ApiModelProperty(value = "使用到的标准溶液") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List standardSolution;//使用到的标准溶液 + + @ApiModelProperty(value = "使用到的样本溶液") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List sampleSolution;//使用到的样本溶液 + + @ApiModelProperty(value = "使用到的检验方法") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List testMethodList;//使用到的检验方法 + @ApiModelProperty(value = "仪器设备使用条件") + @TableField(typeHandler = FastjsonTypeHandler.class) + private List deviceUseCondition;//仪器设备使用条件 + @ApiModelProperty(value = "检验人") + private String testUserId;//检验人 + + @ApiModelProperty(value = "检验编号") + private String testSerialNumber;//检验编号 + + @ApiModelProperty(value = "样本溶液处理过程") + private String sampleSolutionProcessing;//样本溶液处理过程 + + @ApiModelProperty(value = "标准溶液处理过程") + private String standardSolutionProcessing;//标准溶液处理过程 + + @ApiModelProperty(value = "检验过程描述") + private String testProcessDes;//检验过程描述 + + @ApiModelProperty(value = "模板名称") + private String templateName;//模板名称 + + @ApiModelProperty(value = + "创建实验:0\n" + + "正在上机:1\n" + + "结果分析:2\n" + + "提交审核:3\n" + + "提交审批:4\n" + + "实验完成:5\n" + + "出具文书:6") + private Integer status; + + @ApiModelProperty(value = "实验类型(业务类型)") + private String businessType; + + @ApiModelProperty(value = "实验图谱-存储图谱文件名,一般为pdf,格式为['p1.pdf,p2.pdf']") + private String testAtlas; + + @ApiModelProperty("实验开始时间") + @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8") + private LocalDate testStartDate; + + @ApiModelProperty("实验结束时间") + @JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8") + private LocalDate testEndDate; +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResult.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResult.java new file mode 100644 index 0000000..857e5b5 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResult.java @@ -0,0 +1,24 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestResult + * @description + * @create 2024/3/13 18:02 + */ +@Data +public class TestResult { + private Integer orderNo;//检材序号 + private String materialNo;//检材名称 + private String compoundName;//化合物名称 + private Integer isFind;// 0 未检出 1 检出 + private String testId; + + //private String findCompounds;//检出的化合物列表 + //private String noFindCompounds;//未检出的化合物列表 + + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResultDetail.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResultDetail.java new file mode 100644 index 0000000..0d35492 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/entity/TestResultDetail.java @@ -0,0 +1,19 @@ +package digital.laboratory.platform.inspetion.api.entity; + +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestResultDetail + * @description + * @create 2024/3/13 22:31 + */ +@Data +public class TestResultDetail { + private String materialNo; + private String findCompounds; + private String noFindCompounds; + private Integer isFind; + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/RemoteTestToIdentifyService.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/RemoteTestToIdentifyService.java new file mode 100644 index 0000000..2e7f377 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/RemoteTestToIdentifyService.java @@ -0,0 +1,40 @@ +package digital.laboratory.platform.inspetion.api.feign; + +import digital.laboratory.platform.inspetion.api.entity.IdentificationBookDTO; +import digital.laboratory.platform.inspetion.api.feign.factory.RemoteTestToIdentifyServiceFallbackFactory; +import digital.laboratory.platform.common.core.constant.SecurityConstants; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import io.swagger.annotations.ApiOperation; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title 检验系统对文书系统提供的接口 + * @description + * @create 2024/2/26 15:01 + */ +@FeignClient(contextId = "remoteTestToIdentifyService", value ="dlp-drugtesting-biz", + fallbackFactory = RemoteTestToIdentifyServiceFallbackFactory.class) +public interface RemoteTestToIdentifyService { + /** + * 提供读取实验数据的接口 + * @param businessId + * @return + */ + @GetMapping(value="/identifyBookData/getIdentifyBookDataByBusinessId", headers = SecurityConstants.HEADER_FROM_IN) + public R getIdentifyBookDataByBusinessId(@RequestParam("businessId") String businessId); + + @PostMapping(value="/identifyBookData/getTestFinishBusinessData", headers = SecurityConstants.HEADER_FROM_IN) + public R getTestFinishBusinessData(@RequestBody List synedIdList); + + @PostMapping("/testRecord/queryTestRecordInfoByBusinessId") + @ApiOperation("根据业务id获取实验信息") + public R> queryTestRecordInfoByBusinessId(@RequestBody List businessIds); + +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/factory/RemoteTestToIdentifyServiceFallbackFactory.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/factory/RemoteTestToIdentifyServiceFallbackFactory.java new file mode 100644 index 0000000..9e2cdd0 --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/factory/RemoteTestToIdentifyServiceFallbackFactory.java @@ -0,0 +1,23 @@ +package digital.laboratory.platform.inspetion.api.feign.factory; + +import digital.laboratory.platform.inspetion.api.feign.RemoteTestToIdentifyService; +import digital.laboratory.platform.inspetion.api.feign.fallback.RemoteTestToIdentifyServiceFallbackImpl; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * @author xy + * @version 1.0 + * @title RemoteFlowManagerServiceFallbackFactory + * @description + * @create 2024/1/17 18:07 + */ +@Component +public class RemoteTestToIdentifyServiceFallbackFactory implements FallbackFactory { + @Override + public RemoteTestToIdentifyService create(Throwable throwable) { + RemoteTestToIdentifyServiceFallbackImpl remoteFlowManagerServiceFallback=new RemoteTestToIdentifyServiceFallbackImpl(); + remoteFlowManagerServiceFallback.setCause(throwable); + return remoteFlowManagerServiceFallback; + } +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/fallback/RemoteTestToIdentifyServiceFallbackImpl.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/fallback/RemoteTestToIdentifyServiceFallbackImpl.java new file mode 100644 index 0000000..1f2728f --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/feign/fallback/RemoteTestToIdentifyServiceFallbackImpl.java @@ -0,0 +1,42 @@ +package digital.laboratory.platform.inspetion.api.feign.fallback; + +import digital.laboratory.platform.inspetion.api.entity.IdentificationBookDTO; +import digital.laboratory.platform.inspetion.api.feign.RemoteTestToIdentifyService; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title RemoteTestToIdentifyServiceFallbackImpl + * @description + * @create 2024/1/17 18:07 + */ +@Slf4j +@Component +public class RemoteTestToIdentifyServiceFallbackImpl implements RemoteTestToIdentifyService { + @Setter + private Throwable cause; + + @Override + public R getIdentifyBookDataByBusinessId(String businessId) { + //log.error("feign 获取鉴定文书信息失败,请联系管理员:{}", identificationBookDTO.getCaseName(), cause); + return null; + } + + @Override + public R getTestFinishBusinessData(List synedIdList) { + return null; + } + + @Override + public R> queryTestRecordInfoByBusinessId(List businessIds) { + return null; + } +} diff --git a/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/vo/TestRecordVo.java b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/vo/TestRecordVo.java new file mode 100644 index 0000000..74f717a --- /dev/null +++ b/dlp-drugtesting-api/src/main/java/digital/laboratory/platform/inspetion/api/vo/TestRecordVo.java @@ -0,0 +1,19 @@ +package digital.laboratory.platform.inspetion.api.vo; + +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import lombok.Data; + +import java.util.List; + +@Data +public class TestRecordVo extends TestRecord { + + private String testUserName; + private List testMethodName; + + private String instrumentConditionUrl; + + private String instrumentConditionFileName; + + private String businessTypeName; +} diff --git a/dlp-drugtesting-api/src/test/java/digital/laboratory/platform/AppTest.java b/dlp-drugtesting-api/src/test/java/digital/laboratory/platform/AppTest.java new file mode 100644 index 0000000..6304505 --- /dev/null +++ b/dlp-drugtesting-api/src/test/java/digital/laboratory/platform/AppTest.java @@ -0,0 +1,38 @@ +package digital.laboratory.platform; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/dlp-drugtesting-biz/assets/image-20240417101824328.png b/dlp-drugtesting-biz/assets/image-20240417101824328.png new file mode 100644 index 0000000000000000000000000000000000000000..f0ac1b8a4d29723291cf6a71352d21ca73803f94 GIT binary patch literal 9837 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 literal 0 HcmV?d00001 diff --git a/dlp-drugtesting-biz/assets/image-20240417102214943.png b/dlp-drugtesting-biz/assets/image-20240417102214943.png new file mode 100644 index 0000000000000000000000000000000000000000..8d2916064509b685428a291620a19e89c7002cd9 GIT binary patch literal 168397 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 z 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ν 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Þo*UI%;N_izX2)CO_V^dE+;}@wL3WeEISRS>^zu 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 X>_Q*&v^(e!00000NkvXXu0mjf3^LLk literal 0 HcmV?d00001 diff --git a/dlp-drugtesting-biz/pom.xml b/dlp-drugtesting-biz/pom.xml new file mode 100644 index 0000000..6609121 --- /dev/null +++ b/dlp-drugtesting-biz/pom.xml @@ -0,0 +1,269 @@ + + 4.0.0 + + digital.laboratory.platform + dlp-drugtesting + 2022.10.11-snapshots + + dlp-drugtesting-biz + jar + dlp-drugtesting-biz + + UTF-8 + 1.8 + 1.8 + 5.7.1 + + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + 2021.1 + + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-config + 2021.1 + + + + digital.laboratory.platform + dlp-common-swagger + + + + + + + + + digital.laboratory.platform + dlp-common-feign + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-common-security + 2022.10.11-snapshots + + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.boot + spring-boot-starter-test + test + + + + digital.laboratory.platform + dlp-common-core + 2022.10.11-snapshots + + + + mysql + mysql-connector-java + 8.0.28 + + + + org.springframework.boot + spring-boot-starter-undertow + + + + digital.laboratory.platform + dlp-common-log + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-common-seata + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-admin-api + 2022.10.11-snapshots + + + digital.laboratory.platform + dlp-drugtesting-api + 2022.10.11-snapshots + + + digital.laboratory.platform + dlp-sewage-api + 2022.10.11-snapshots + + + digital.laboratory.platform + dlp-common-oss + 2022.10.11-snapshots + + + + commons-io + commons-io + 2.11.0 + + + + digital.laboratory.platform + dlp-upload-api + 2022.10.11-snapshots + + + + digital.laboratory.platform + dlp-basic-commonservice-api + 2022.10.11-snapshots + + + + + com.deepoove + poi-tl + 1.12.0 + + + + com.alibaba + easyexcel + 3.1.3 + + + org.apache.poi + poi + + + org.apache.poi + poi-ooxml + + + org.apache.poi + poi-ooxml-schemas + + + + + + digital.laboratory.platform + dlp-common-remote-word2pdf + 2022.10.11-snapshots + + + org.apache.poi + poi + 5.2.3 + + + + org.apache.poi + poi-ooxml + 5.2.3 + + + org.apache.poi + poi-ooxml-schemas + 4.1.2 + + + + org.apache.poi + poi-ooxml-full + 5.2.3 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + -Xlint:unchecked + + 3.8.1 + + + org.springframework.boot + spring-boot-maven-plugin + + + io.fabric8 + docker-maven-plugin + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.3.0 + + + timestamp-property + + timestamp-property + + + timestamp + yyyy-MM-dd HH:mm:ss + zh_CN + Asia/Shanghai + + + + + + + + maven-resources-plugin + 3.1.0 + + UTF-8 + + + xlsx + xls + docx + + + + + copy-resource-one + install + + copy-resources + + + ${basedir}/../../out + + + ${basedir}/target + + ${project.artifactId}.jar + + + + + + + + + + + + ${project.basedir}/src/main/resources + true + + + + diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/DlpDrugTestingApplication.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/DlpDrugTestingApplication.java new file mode 100644 index 0000000..fc7b48f --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/DlpDrugTestingApplication.java @@ -0,0 +1,23 @@ +package digital.laboratory.platform.inspection; + +import digital.laboratory.platform.common.feign.annotation.EnableDLPFeignClients; +import digital.laboratory.platform.common.security.annotation.EnableDLPResourceServer; +import digital.laboratory.platform.common.swagger.annotation.EnableDLPSwagger2; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; + +@Configuration +@EnableDLPSwagger2 +@EnableDLPFeignClients +@EnableDiscoveryClient +@EnableDLPResourceServer +@SpringBootApplication(scanBasePackages="digital.laboratory.platform") +public class DlpDrugTestingApplication { + + public static void main(String[] args) { + SpringApplication.run(DlpDrugTestingApplication.class, args); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/Interceptor/FeignOauth2RequestInterceptor.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/Interceptor/FeignOauth2RequestInterceptor.java new file mode 100644 index 0000000..1104923 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/Interceptor/FeignOauth2RequestInterceptor.java @@ -0,0 +1,37 @@ +package digital.laboratory.platform.inspection.Interceptor; + +import feign.RequestInterceptor; +import feign.RequestTemplate; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; + +/** + * Feign 请求拦截器 + * Feign Client 向业务系统发出请求的时候, 把 Token 带上, 以用户自己的身份调用业务系统。 + * 目的是在业务系统中识别用户是谁, 允许或禁止用户进行对应的操作。 + */ + + +@Configuration +public class FeignOauth2RequestInterceptor implements RequestInterceptor { + + private final String AUTHORIZATION_HEADER = "Authorization"; + private final String BEARER_TOKEN_TYPE = "Bearer"; + + @Override + public void apply(RequestTemplate requestTemplate) { +System.out.println(String.format("dlp-entrustment, FeignOauth2RequestInterceptor()...")); + SecurityContext securityContext = SecurityContextHolder.getContext(); + Authentication authentication = securityContext.getAuthentication(); + if (authentication != null && authentication.getDetails() instanceof OAuth2AuthenticationDetails) { + OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); +System.out.println(String.format("FeignOauth2RequestInterceptor() Authorization, token=%s", details.getTokenValue())); + requestTemplate.header(AUTHORIZATION_HEADER, String.format("%s %s", BEARER_TOKEN_TYPE, details.getTokenValue())); + } + + } +} + diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/BusinessType.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/BusinessType.java new file mode 100644 index 0000000..c252d2d --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/BusinessType.java @@ -0,0 +1,38 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +@Getter +public enum BusinessType { + NPS_CASE("10001", "缴获物检验"), + BOINT_CASE("10002", "生物样本案件"), + + + BOINT_JOB("20001", "毛发任务"), + SEWAGE_JOB("20002", "污水任务"), + SCREENING_EVENT("30001", "筛查事件"); + + BusinessType(String businessType, String businessTypeName) { + this.businessType = businessType; + this.businessTypeName = businessTypeName; + } + private final String businessType; + private final String businessTypeName; + + public static String getBusinessTypeName(String businessType) { + for (BusinessType type : values()) { + if (businessType.equals(type.businessType)) { + return type.businessTypeName; + } + } + throw new RuntimeException(String.format("没有获取到%s相关的Name", businessType)); + } + public static BusinessType getBusinessTypeByType(String businessType) { + for (BusinessType type : values()) { + if (businessType.equals(type.businessType)) { + return type; + } + } + throw new RuntimeException(String.format("没有获取到%s相关的Name", businessType)); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/CompoundMassKV.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/CompoundMassKV.java new file mode 100644 index 0000000..3ea8d4a --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/CompoundMassKV.java @@ -0,0 +1,45 @@ +package digital.laboratory.platform.inspection.constant; + +/** + * @author xy + * @version 1.0 + * @title compoundMassKV 化合物名称与Mass的对应关系 + * @description + * @create 2024/2/18 18:02 + */ + +public enum CompoundMassKV { + COMPOUND_ABFUBINACA("AB-FUBINACA", 109), + COMPOUND_2FA("2-FA", 44), + COMPOUND_3FA("3-FA", 44), + COMPOUND_4FA("4-FA", 44), + COMPOUND_Phentermine("Phentermine", 58), + COMPOUND_MPA("MPA", 58), + COMPOUND_2FMA("2-FMA", 58), + COMPOUND_3FMA("3-FMA", 58), + COMPOUND_4FMA("4-FMA", 58), + COMPOUND_HEROIN("Heroin", 327), + COMPOUND_MEDETOMIDINE("Medetomidine", 0), + ; + + private String name; + private int code; + CompoundMassKV(String _name , int _code) { + this.name=_name; + this.code=_code; + } + public int getCode() { + return code; + } + public String getCompoundName() { + return name; + } + public static int getCodeByName(String _name) { + for (CompoundMassKV enumObj : CompoundMassKV.values()) { + if (enumObj.getCompoundName().equals(_name)) { + return enumObj.code; + } + } + return -1; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/MaterialType.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/MaterialType.java new file mode 100644 index 0000000..102f0f3 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/MaterialType.java @@ -0,0 +1,15 @@ +package digital.laboratory.platform.inspection.constant; + +public enum MaterialType { + + BIOLOGICAL_SAMPLE("inVivo"),//生物样本 + SEIZURE("inVitro"),//缴获物 + OTHER("other");//其他 + private final String type; + MaterialType(String type) { + this.type = type; + } + public String getType() { + return type; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/NumberTransferHanZi.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/NumberTransferHanZi.java new file mode 100644 index 0000000..ceb78f0 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/NumberTransferHanZi.java @@ -0,0 +1,45 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +@Getter +public enum NumberTransferHanZi { + ZERO(0, "零"), + ONE(1, "一"), + + + TWO(2, "二"), + THREE(3, "三"), + FOUR(4, "四"), + FIVE(5, "五"), + SIX(6, "六"), + + + SEVEN(7, "七"), + EIGHT(8, "八"), + NINE(9, "九"), + TEN(10, "十"), + ELEVEN(11, "十一一"), + + + TWELVE(12, "十二"), + THIRTEEN(13, "十三"), + FOURTEEN(14, "十四"), + ; + + NumberTransferHanZi(int number, String hanZi) { + this.number = number; + this.hanZi = hanZi; + } + private final int number; + private final String hanZi; + + public static String getHanZiNameByNumber(int number) { + for (NumberTransferHanZi type : values()) { + if (number == type.number) { + return type.hanZi; + } + } + throw new RuntimeException(String.format("没有获取到%s相关的汉字", number)); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SampleInjectorConstant.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SampleInjectorConstant.java new file mode 100644 index 0000000..4efe032 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SampleInjectorConstant.java @@ -0,0 +1,281 @@ +package digital.laboratory.platform.inspection.constant; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; + +/** 相关导出进样位置信息中excel 中对应的类型type +* date: 2024/2/19 15:30 +* @author: Chen +* @since JDK 1.8 +* Description: +*/ +public interface SampleInjectorConstant { + + // 进样类型 + String BLANK = "Blank"; + + String STANDARD = "Standard"; + + String QC = "QC"; + + String ANALYTE = "Analyte"; + + // 溶液名称 + String BLANK_NAME = "空白溶液"; + String STANDARD_NAME = "标准溶液"; + String QC_NAME = "质控溶液"; + + String MIX_STANDARD_NAME = "标准混合溶液"; + + String NORMAL_NAME = "样本溶液"; + + /**************************************************进样方盘的初始数据********************************************************************/ + JSONArray P_1 = JSON.parseArray("[" + + "{ name: 'A1', value: ['A', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A2', value: ['A', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A3', value: ['A', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A4', value: ['A', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A5', value: ['A', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A6', value: ['A', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A7', value: ['A', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A8', value: ['A', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + "{ name: 'A9', value: ['A', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1' }," + + + "{ name: 'B1', value: ['B', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B2', value: ['B', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B3', value: ['B', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B4', value: ['B', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B5', value: ['B', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B6', value: ['B', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B7', value: ['B', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B8', value: ['B', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'B9', value: ['B', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + + "{ name: 'C1', value: ['C', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C2', value: ['C', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C3', value: ['C', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C4', value: ['C', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C5', value: ['C', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C6', value: ['C', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C7', value: ['C', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C8', value: ['C', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'C9', value: ['C', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + + "{ name: 'D1', value: ['D', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D2', value: ['D', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D3', value: ['D', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D4', value: ['D', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D5', value: ['D', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D6', value: ['D', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D7', value: ['D', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D8', value: ['D', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'D9', value: ['D', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + + "{ name: 'E1', value: ['E', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E2', value: ['E', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E3', value: ['E', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E4', value: ['E', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E5', value: ['E', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E6', value: ['E', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E7', value: ['E', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E8', value: ['E', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + "{ name: 'E9', value: ['E', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-1'}," + + + "{ name: 'F1', value: ['F', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F2', value: ['F', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F3', value: ['F', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F4', value: ['F', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F5', value: ['F', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F6', value: ['F', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F7', value: ['F', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F8', value: ['F', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "{ name: 'F9', value: ['F', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-1'}," + + "]"); + + JSONArray P_2 = JSON.parseArray("[" + + "{ name: 'A1', value: ['A', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A2', value: ['A', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A3', value: ['A', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A4', value: ['A', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A5', value: ['A', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A6', value: ['A', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A7', value: ['A', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A8', value: ['A', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + "{ name: 'A9', value: ['A', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2' }," + + + "{ name: 'B1', value: ['B', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B2', value: ['B', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B3', value: ['B', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B4', value: ['B', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B5', value: ['B', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B6', value: ['B', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B7', value: ['B', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B8', value: ['B', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'B9', value: ['B', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + + "{ name: 'C1', value: ['C', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C2', value: ['C', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C3', value: ['C', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C4', value: ['C', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C5', value: ['C', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C6', value: ['C', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C7', value: ['C', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C8', value: ['C', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'C9', value: ['C', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + + "{ name: 'D1', value: ['D', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D2', value: ['D', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D3', value: ['D', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D4', value: ['D', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D5', value: ['D', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D6', value: ['D', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D7', value: ['D', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D8', value: ['D', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'D9', value: ['D', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + + "{ name: 'E1', value: ['E', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E2', value: ['E', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E3', value: ['E', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E4', value: ['E', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E5', value: ['E', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E6', value: ['E', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E7', value: ['E', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E8', value: ['E', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + "{ name: 'E9', value: ['E', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-2'}," + + + "{ name: 'F1', value: ['F', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F2', value: ['F', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F3', value: ['F', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F4', value: ['F', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F5', value: ['F', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F6', value: ['F', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F7', value: ['F', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F8', value: ['F', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "{ name: 'F9', value: ['F', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-2'}," + + "]"); + + JSONArray P_3 = JSON.parseArray("[" + + "{ name: 'A1', value: ['A', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A2', value: ['A', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A3', value: ['A', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A4', value: ['A', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A5', value: ['A', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A6', value: ['A', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A7', value: ['A', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A8', value: ['A', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + "{ name: 'A9', value: ['A', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3' }," + + + "{ name: 'B1', value: ['B', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B2', value: ['B', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B3', value: ['B', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B4', value: ['B', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B5', value: ['B', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B6', value: ['B', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B7', value: ['B', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B8', value: ['B', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'B9', value: ['B', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + + "{ name: 'C1', value: ['C', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C2', value: ['C', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C3', value: ['C', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C4', value: ['C', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C5', value: ['C', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C6', value: ['C', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C7', value: ['C', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C8', value: ['C', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'C9', value: ['C', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + + "{ name: 'D1', value: ['D', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D2', value: ['D', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D3', value: ['D', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D4', value: ['D', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D5', value: ['D', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D6', value: ['D', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D7', value: ['D', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D8', value: ['D', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'D9', value: ['D', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + + "{ name: 'E1', value: ['E', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E2', value: ['E', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E3', value: ['E', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E4', value: ['E', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E5', value: ['E', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E6', value: ['E', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E7', value: ['E', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E8', value: ['E', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + "{ name: 'E9', value: ['E', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-3'}," + + + "{ name: 'F1', value: ['F', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F2', value: ['F', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F3', value: ['F', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F4', value: ['F', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F5', value: ['F', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F6', value: ['F', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F7', value: ['F', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F8', value: ['F', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "{ name: 'F9', value: ['F', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-3'}," + + "]"); + + JSONArray P_4 = JSONArray.parseArray("[" + + "{ name: 'A1', value: ['A', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A2', value: ['A', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A3', value: ['A', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A4', value: ['A', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A5', value: ['A', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A6', value: ['A', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A7', value: ['A', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A8', value: ['A', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + "{ name: 'A9', value: ['A', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4' }," + + + "{ name: 'B1', value: ['B', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B2', value: ['B', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B3', value: ['B', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B4', value: ['B', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B5', value: ['B', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B6', value: ['B', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B7', value: ['B', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B8', value: ['B', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'B9', value: ['B', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + + "{ name: 'C1', value: ['C', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C2', value: ['C', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C3', value: ['C', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C4', value: ['C', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C5', value: ['C', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C6', value: ['C', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C7', value: ['C', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C8', value: ['C', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'C9', value: ['C', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + + "{ name: 'D1', value: ['D', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D2', value: ['D', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D3', value: ['D', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D4', value: ['D', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D5', value: ['D', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D6', value: ['D', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D7', value: ['D', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D8', value: ['D', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'D9', value: ['D', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + + "{ name: 'E1', value: ['E', '1'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E2', value: ['E', '2'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E3', value: ['E', '3'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E4', value: ['E', '4'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E5', value: ['E', '5'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E6', value: ['E', '6'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E7', value: ['E', '7'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E8', value: ['E', '8'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + "{ name: 'E9', value: ['E', '9'], active: false,injectorCount: 1,sampleNo: \"\" ,frameNumber:'P-4'}," + + + "{ name: 'F1', value: ['F', '1'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F2', value: ['F', '2'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F3', value: ['F', '3'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F4', value: ['F', '4'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F5', value: ['F', '5'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F6', value: ['F', '6'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F7', value: ['F', '7'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F8', value: ['F', '8'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "{ name: 'F9', value: ['F', '9'], active: false,injectorCount: 1,sampleNo: \"\",frameNumber:'P-4'}," + + "]"); + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageCompoundNameTransform.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageCompoundNameTransform.java new file mode 100644 index 0000000..ade99e3 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageCompoundNameTransform.java @@ -0,0 +1,62 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +/** + * 转换化合物名称和大数据平台上传的名称一致 + */ +@Getter +public enum SewageCompoundNameTransform { + + Methamphetamine("MA,AM","冰毒"), // 甲基苯丙胺、苯丙胺(甲基苯丙胺代谢物) + + Heroin("Mor,O6", "海洛因"), // 吗啡(海洛因二级代谢产物)、O6-单乙酰吗啡(海洛因一级代谢产物) + + Codeine("Cod","可待因"), // 可待因 + + Cocaine("Coc,BZE", "可卡因"), // 可卡因、苯甲酰爱康宁(可卡因代谢物) + + MDMA("MDMA,MDA","摇头丸"), // 3,4-亚甲基二氧甲基苯丙胺(摇头丸MDMA)、3,4-亚甲基二氧基苯丙胺(摇头丸代谢物) + + Ketamine("Keta,NK","氯胺酮"), // 氯胺酮、去甲氯胺酮(氯胺酮代谢物) + + Fentanyl("Fen", "芬太尼"), + + ; + + private String targetName; + private String describe; + + SewageCompoundNameTransform(String targetName, String describe) { + this.targetName = targetName; + this.describe = describe; + } + + /** + * 根据sourceName 获取转换的大数据平台化合物名称,如果没有,则返回原始值 + * @param sourceName + * @return + */ + public static String transferName(String sourceName) { + for (SewageCompoundNameTransform enumObj : SewageCompoundNameTransform.values()) { + if (enumObj.getTargetName().contains(sourceName)) { + return enumObj.describe; + } + } + return null; + } + + /** + * 根据sourceName 获取枚举 + * @param sourceName + * @return + */ + public static SewageCompoundNameTransform getEnumBySourceName(String sourceName) { + for (SewageCompoundNameTransform enumObj : SewageCompoundNameTransform.values()) { + if (enumObj.getTargetName().equals(sourceName)) { + return enumObj; + } + } + return null; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageReportColumn.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageReportColumn.java new file mode 100644 index 0000000..c4b311a --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/SewageReportColumn.java @@ -0,0 +1,72 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +public enum SewageReportColumn { + COLUMN_1("样品编号", "red", ""), + COLUMN_2("污水处理厂名称", "red", ""), + COLUMN_3("所在地(省)", "red", ""), + COLUMN_4("所在地(市)", "red", ""), + COLUMN_5("所在地(区/县)", "", ""), + COLUMN_6("采样时间", "", ""), + COLUMN_7("污水厂服务人口(万人)", "", ""), + COLUMN_8("生活污水占比", "", ""), + COLUMN_9("流量(万立方米/天)", "", ""), + COLUMN_10("人均日吸烟(支)", "", ""), + COLUMN_11("可替宁排泄量(mg/千人天)", "", ""), + COLUMN_12("测算人口(千人)", "", ""), + COLUMN_13("可替宁(ng/L)", "red", ""), + COLUMN_14("可待因(ng/L)", "red", ""), + COLUMN_15("MDA(ng/L)", "red", ""), + COLUMN_16("MDMA(ng/L)", "red", ""), + COLUMN_17("可卡因(ng/L)", "red", ""), + COLUMN_18("苯甲酰爱康宁(ng/L)", "red", ""), + COLUMN_19("吗啡(ng/L)", "red", ""), + COLUMN_20("O6-单乙酰吗啡(ng/L)", "red", ""), + COLUMN_21("甲基苯丙胺(ng/L)", "red", "red"), + COLUMN_22("苯丙胺(ng/L)", "red", ""), + COLUMN_23("氯胺酮(ng/L)", "red", "red"), + COLUMN_24("去甲氯胺酮(ng/L)", "red", ""), + COLUMN_25("四氢大麻酸(ng/L)", "red", ""), + COLUMN_26("", "", ""), + COLUMN_27("吗啡负荷量(mg/千人﹒天)", "", ""), + COLUMN_28("可待因负荷量(mg/千人﹒天)", "", ""), + COLUMN_29("可待因转化为吗啡负荷量(mg/千人﹒天)", "", ""), + COLUMN_30("医用吗啡负荷量(mg/千人﹒天)", "", ""), + COLUMN_31("MA/AM", "red", "red"), + COLUMN_32("K/NK", "red", "red"), + COLUMN_33("", "", ""), + COLUMN_34("人均消耗量(mg/千人﹒天)", "", "pink"), + COLUMN_35("Heroin", "", ""), + COLUMN_36("MA", "", ""), + COLUMN_37("K", "", ""), + COLUMN_38("MDMA", "", ""), + COLUMN_39("COC", "", ""), + COLUMN_40("THC", "", ""), + COLUMN_41("", "", ""), + COLUMN_42("", "", ""), + COLUMN_43("总消耗量", "", "pink"), + COLUMN_44("Heroin", "", ""), + COLUMN_45("MA", "", ""), + COLUMN_46("K", "", ""), + COLUMN_47("MDMA", "", ""), + COLUMN_48("COC", "", ""), + COLUMN_49("THC", "", ""); + private final String columnName; + private final String fontColor; + private final String backgroundColor; + + public String getColumnName() { + return columnName; + } + + public String getFontColor() { + return fontColor; + } + + public String getBackgroundColor() { + return backgroundColor; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/StdSolutionNum.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/StdSolutionNum.java new file mode 100644 index 0000000..98526d5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/StdSolutionNum.java @@ -0,0 +1,18 @@ +package digital.laboratory.platform.inspection.constant; + +public enum StdSolutionNum { + SIMPLE_SOLUTION("Sin"), + MIXED_SOLUTION("Mix"), + BLANK_SOLUTION("BLK"), + QC_SOLUTION("QC"), + BLANK_SAMPLE_SOLUTION("BLS"); + private final String prefix; + + StdSolutionNum(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TaskTestDataStatus.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TaskTestDataStatus.java new file mode 100644 index 0000000..f5eb536 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TaskTestDataStatus.java @@ -0,0 +1,52 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +/** + * 任务审核状态 + */ +@Getter +public enum TaskTestDataStatus { + + REJECT(-1, "审核审批不通过"), + WAIT_REVIEW(0, "待审核"), + REVIEWED(1, "已审核"), + APPROVED(2, "已审批"), + UPLOADED(3, "已上传") + ; + private int code; + private String message; + + TaskTestDataStatus(int code, String message) { + this.code = code; + this.message = message; + } + + /** + * 根据code 值获取状态名称 + * @param code + * @return + */ + public static String getStatusNameByCode(int code) { + for (TaskTestDataStatus status : values()) { + if (code == status.getCode()) { + return status.getMessage(); + } + } + throw new RuntimeException(String.format("没有获取到code 为 %s相关的状态名", code)); + } + + /*** + * 根据code 获取enum + * @param code + * @return + */ + public static TaskTestDataStatus getEnumByCode(int code) { + for (TaskTestDataStatus status : values()) { + if (code == status.getCode()) { + return status; + } + } + throw new RuntimeException(String.format("没有获取到code 为 %s相关的枚举", code)); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataFileStructConstant.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataFileStructConstant.java new file mode 100644 index 0000000..9e2aa4c --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataFileStructConstant.java @@ -0,0 +1,17 @@ +package digital.laboratory.platform.inspection.constant; + +import java.util.Arrays; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TestDataFileStructConstant + * @description + * @create 2024/1/9 14:40 + */ + +public class TestDataFileStructConstant { + public static List TEST_DATA_FILE_NPS_STRUCT= Arrays.asList("Header","File Information", + "Sample Information","Original Files","File Description","MS Quantitative Results"); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataType.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataType.java new file mode 100644 index 0000000..48468e7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestDataType.java @@ -0,0 +1,50 @@ +package digital.laboratory.platform.inspection.constant; + +/** + * @author xy + * @version 1.0 + * @title TestDataType 检验数据的格式类型枚举 + * @description + * @create 2024/1/9 10:23 + */ + +public enum TestDataType { + //这三种是沃特斯的数据文件的格式类型 + WaterS_QuantifyCompoundSummaryReport(10001,"WATERS Quantify Compound Summary Report"), + WaterS_QuantifySampleSummaryReport(10002, "WATERS Quantify Sample Summary Report"), + WaterS_TabSeparator(10003, "WATERS 液相色谱导出的 tab 分隔数据文件"), + //这三种是岛津的数据文件的格式 + Shimadzu_Common_File(20000, "岛津通用格式"), + Shimadzu_MCPeakTable(20001, "岛津 定性峰表 SHIMADZU MC Peak Table"), + Shimadzu_MSQuantitativeResults(20002, "岛津 组分定量结果 SHIMADZU MS Quantitative Results"), + //这2种是安捷伦的数据文件格式 + Angient_TSV(30001, "ANGIENT TSV"), + Angient_CSV(30002, "ANGIENT CSV"); + private int eCode; + private String description; + TestDataType(int _code,String _description){ + this.description=_description; + this.eCode=_code; + } + + public int getECode() { + return eCode; + } + + public String getDescription() { + return description; + } + /** + * 根据code 获取对应的描述 + * @param _code + * @return + */ + public static String getDescriptionByCode(int _code) { + for (TestDataType enumObj : TestDataType.values()) { + if (enumObj.getECode() == _code) { + return enumObj.description; + } + } + return "未知数据格式"; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordArgumentType.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordArgumentType.java new file mode 100644 index 0000000..65da7d2 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordArgumentType.java @@ -0,0 +1,30 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +@Getter +public enum TestRecordArgumentType { + + TEST_RECORD_ARGUMENT_INSTRUMENT("testRecordInstrument"),//实验仪器 + TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION("testRecordInstrumentCondition"),//实验仪器条件 + TEST_RECORD_ARGUMENT_METHOD("testRecordMethod"),//实验方法 + TEST_RECORD_ARGUMENT_REAGENT("testRecordReagent"),//实验试剂耗材、标准物质 + TEST_RECORD_ARGUMENT_SAMPLE_DATA("testRecordSampleData"),//实验样本 + TEST_RECORD_ARGUMENT_SAMPLE_SOLUTION("testRecordSampleSolution"),//实验样本溶液 + TEST_RECORD_ARGUMENT_STANDARD_SOLUTION("testRecordStandardSolution");//实验标准溶液 + + private final String type; + + TestRecordArgumentType(String type) { + this.type = type; + } + + public static String getType(String type) { + for (TestRecordArgumentType constans : values()) { + if (constans.getType().equals(type)) { + return constans.getType(); + } + } + return ""; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordFileUrl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordFileUrl.java new file mode 100644 index 0000000..0e1ddb4 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordFileUrl.java @@ -0,0 +1,26 @@ +package digital.laboratory.platform.inspection.constant; + +import lombok.Getter; + +@Getter +public enum TestRecordFileUrl { + + TEMPORARY_PATH("C:\\tmp\\upload\\"), + TEST_RECORD_BIOLOGICAL_SAMPLE_TEMPLATE("template/生物样本检验记录模板.docx"), + TEST_RECORD_BIOLOGICAL_SAMPLE_INSTRUMENT_CONDITION_TEMPLATE("template/生物样本仪器条件模板.docx"), + TEST_RECORD_SEIZURE_TEMPLATE("template/缴获物检验记录模板.docx"), + TEST_RECORD_SEIZURE_INSTRUMENT_CONDITION_TEMPLATE("template/缴获物仪器条件模板.docx"), + TEST_RECORD_CATALOGUE("document" + "/" + "testRecord"), + TEST_TEMPLATE_CATALOGUE("document" + "/" + "testTemplate"), + TEST_ATLAS_PATH("testRecord/testAtlas/") + ; + private final String fileUrl; + + TestRecordFileUrl(String fileUrl) { + this.fileUrl = fileUrl; + } + + public String getFileUrl() { + return fileUrl; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordSampleDataConstant.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordSampleDataConstant.java new file mode 100644 index 0000000..abc190d --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/constant/TestRecordSampleDataConstant.java @@ -0,0 +1,62 @@ +package digital.laboratory.platform.inspection.constant; + +/** + * 关于计算检验数据中的相对误差、离子丰度比相对误差的一些常量数据 + */ +public interface TestRecordSampleDataConstant { + // 毛发案件 + double HAIR_CASE_POSITIVE_RT_ERROR = 2.5; // 保留时间相对误差(正负2.5%) + + + double HAIR_CASE_NEGATIVE_RT_ERROR = -2.5; // 保留时间相对误差(正负2.5%) - + + double HAIR_CASE_ION_ABUNDANCE_RATIO_1 = 0.5; // 离子丰度比 中的比较值1 50% + + double HAIR_CASE_ION_ABUNDANCE_RATIO_2 = 0.2; // 离子丰度比 中的比较值2 20% + + double HAIR_CASE_ION_ABUNDANCE_RATIO_3 = 0.1; // 离子丰度比 中的比较值3 10% + + double HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_1 = 20d; // 离子丰度比 > 50% 的最大允许偏差范围(正负20%) + + + double HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_1 = -20d; // 离子丰度比 > 50% 的最大允许偏差范围(正负20%) - + + double HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_2 = 25d; // 20% < 离子丰度比 < 50% 的最大允许偏差范围(正负25%) + + + double HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_2 = -25d; // 20% < 离子丰度比 < 50% 的最大允许偏差范围(正负25%) - + + double HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_3 = 30d; // 10% < 离子丰度比 < 20% 的最大允许偏差范围(正负30%) + + + double HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_3 = -30d; // 10% < 离子丰度比 < 20% 的最大允许偏差范围(正负30%) - + + double HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_4 = 50d; // 离子丰度比 < 10% 的最大允许偏差范围(正负50%) + + + double HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_4 = -50d; // 离子丰度比 < 10% 的最大允许偏差范围(正负50%) - + + + /**********************************************关于溶液类型的常量值*******************************************************************/ + + String SAMPLE_TYPE_QC = "QC"; // 质控样品 + + String SAMPLE_TYPE_ANALYTE = "Analyte"; // 检材样本 + + String SAMPLE_TYPE_STD = "STD"; // 标准物质 + + /******************************************管理 判断是否符合 的常量****************************************************/ + String IS = "是"; + + String NO = "否"; + + /************************************************ 检出 或 未检出 常量属性 *****************************************************************/ + String CHECK_OUT = "检出"; + + String NOT_CHECK_OUT = "未检出"; + + /***********************************************组装数据时常用的自定义健**********************************************************/ + String LABEL = "label"; // 对应的中午 + + String PROP = "prop"; // 对应的英文值名称 + + /**************************************************化合物基峰的字典类型值******************************************************************/ + + String COMPOUND_BASIC_PEAK = "compound_basic_peak"; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/AssignmentInfoController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/AssignmentInfoController.java new file mode 100644 index 0000000..5f0483e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/AssignmentInfoController.java @@ -0,0 +1,148 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.AssignmentInfoDto; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.service.AssignmentInfoService; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import digital.laboratory.platform.inspection.vo.AssignmentInfoVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.security.Principal; +import java.util.List; + +/* + *@title TaskInfoController + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:24 + */ +@RestController +@RequestMapping("/assignmentInfo") +@Api(tags = "05-分配信息管理", description = "分配信息管理") +public class AssignmentInfoController { + @Resource + private AssignmentInfoService assignmentInfoService; + + //添加接口 + @PostMapping("/addAssignmentInfo") + @ApiOperation(value = "添加分配信息", notes = "添加分配信息") + public R addAssignmentInfo(@RequestBody List assignmentInfoDtoList, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + assignmentInfoDtoList.forEach(item -> { + item.setAssignUser(dlpUser.getId()); + item.setAssignUserName(dlpUser.getName()); + }); + + List assignmentInfoList = null; + try { + assignmentInfoList = assignmentInfoService.addAssignmentInfo(assignmentInfoDtoList); + } catch (RuntimeException e) { + e.printStackTrace(); + return R.failed(e.getMessage()); + } + + if (assignmentInfoList != null) { + return R.ok(assignmentInfoList, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //修改接口 + @PostMapping("/cancelAssignmentInfo") + @ApiOperation(value = "撤销分配信息", notes = "") + public R cancelAssignmentInfo(@RequestBody List assignmentInfoList) { + boolean ret = assignmentInfoService.cancelAssignmentInfo(assignmentInfoList); + if (ret) { + return R.ok(ret, "撤销成功"); + } else { + return R.failed("false", "撤销失败"); + } + } + + //删除数据 + @GetMapping("/deleteAssignmentInfo") + @ApiOperation(value = "删除分配信息", notes = "") + public R deleteAssignmentInfo(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = assignmentInfoService.deleteAssignmentInfo(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getAssignmentInfoPageList") + @ApiOperation(value = "获取分页数据", notes = "opCode 0:分配者查询已分配记录 1:接收者查询下发给自己的任务;") + public R getTaskPageList(Page page, AssignmentInfoDto assignmentInfoDto, HttpServletRequest httpServletRequest) { + //opCode 0:分配者查询已分配记录 1:接收者查询下发给自己的任务; + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + if (assignmentInfoDto.getOpCode() == 0) { + assignmentInfoDto.setAssignUser(dlpUser.getId()); + } else { + assignmentInfoDto.setTestUser(dlpUser.getId()); + } + return R.ok(assignmentInfoService.getAssignmentInfoPageList(page, assignmentInfoDto), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getAssignmentInfoList") + @ApiOperation(value = "获取列表", notes = "opCode 0:分配者查询已分配记录 1:接收者查询下发给自己的任务;") + public R getAssignmentInfoList(AssignmentInfoDto assignmentInfoDto, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + if (assignmentInfoDto.getOpCode() == 0) { + assignmentInfoDto.setAssignUser(dlpUser.getId()); + } else { + assignmentInfoDto.setTestUser(dlpUser.getId()); + } + return R.ok(assignmentInfoService.getAssignmentInfoList(assignmentInfoDto), "获取数据成功"); + } + + /** + * 根据业务ID批量撤销分配信息 + * + * @param bussinessIdList + * @return + */ + @PostMapping("/cancelByBusiness") + @ApiOperation(value = "根据业务ID批量撤销分配信息", notes = "根据业务ID批量撤销分配信息") + public R cancelByBusiness(@RequestBody List bussinessIdList) { + boolean ret = assignmentInfoService.cancelByBusiness(bussinessIdList); + if (ret) { + return R.ok(ret, "撤销成功"); + } else { + return R.failed("false", "撤销失败"); + } + } + + /** + * 查询已分配的类别为委托的任务列表 + * + * @param page + * @param keywords 查询参数 + * @return + */ + @GetMapping("/getCancelEntrustPage") + @ApiOperation(value = "查询已分配的类别为委托的任务列表", notes = "查询已分配的类别为委托的任务列表") + public R> getAssignedEntrustPage(Page page, String keywords) { + return R.ok(assignmentInfoService.getAssignedEntrustPage(page, keywords), "查询成功!"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/EntrustInfoController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/EntrustInfoController.java new file mode 100644 index 0000000..9df5edc --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/EntrustInfoController.java @@ -0,0 +1,132 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.BusinessType; +import digital.laboratory.platform.inspection.constant.TestRecordFileUrl; +import digital.laboratory.platform.inspection.dto.EntrustInfoDto; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspection.service.EntrustInfoService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/* + *@title EntrustInfoController + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@RestController +@RequestMapping("/entrustInfo") +@Api(tags = "01-委托基本信息管理", description = "委托基本信息管理") +public class EntrustInfoController { + @Resource + private EntrustInfoService entrustInfoService; + + @Resource + private TestRecordService testRecordService; + + @Resource + private OssFile ossFile; + + //添加接口 + @PostMapping("/addEntrustInfo") + @ApiOperation(value = "添加委托基本信息", notes = "添加委托基本信息,同时也作为其他系统调用的外部接口") + public R addEntrustInfo(@RequestBody EntrustInfoDto entrustInfo) { + EntrustInfo ret = entrustInfoService.addEntrustInfo(entrustInfo); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + + } + + //修改接口 + @PostMapping("/updateEntrustInfo") + @ApiOperation(value = "修改委托基本信息", notes = "") + public R updateEntrustInfo(@RequestBody EntrustInfo entrustInfo) { + EntrustInfo ret = entrustInfoService.updateEntrustInfo(entrustInfo); + if (ret != null) { + return R.ok(ret, "修改成功"); + } else { + return R.failed("false", "修改失败"); + } + } + + //删除数据 + @DeleteMapping("/deleteEntrustInfo") + @ApiOperation(value = "删除委托基本信息", notes = "") + public R deleteEntrustInfo(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = entrustInfoService.deleteEntrustInfo(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getEntrustPageList") + @ApiOperation(value = "获取分页数据", notes = "") + public R> getEntrustPageList(Page page, Integer status, EntrustInfo entrustInfo, String keywords) { + if (entrustInfo == null) { + entrustInfo = new EntrustInfo(); + } + return R.ok(entrustInfoService.getEntrustPageList(page, status, entrustInfo, keywords), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getEntrustList") + @ApiOperation(value = "获取列表", notes = "") + public R getEntrustList(EntrustInfo entrustInfo) { + if (entrustInfo == null) { + entrustInfo = new EntrustInfo(); + } + return R.ok(entrustInfoService.getEntrustList(entrustInfo), "获取数据成功"); + } + + //检查是否有重复编号 + @GetMapping("/checkRepeatNo") + @ApiOperation(value = "检查是否有重复编号", notes = "检查是否有重复编号") + public R checkRepeatNo(String acceptNo, String id) { + return R.ok(entrustInfoService.checkRepeatNo(acceptNo, id)); + } + + @GetMapping("/createInspectionRecord") + @ApiOperation(value = "生成检验记录", notes = "参数 :businessId、businessType:10001 或 10002") + public R getPrintData(String businessId, String businessType) throws Exception { + String fileName = ""; + if (businessType.equals(BusinessType.BOINT_CASE.getBusinessType())) { + fileName = "生物样本检验记录.docx"; + } else { + fileName = "缴获物检验记录.docx"; + } + //判断是否生成了检验记录 + List fileNameList = ossFile.fileList(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + businessId); + boolean isCreate = fileNameList.contains(fileName); + //如果生成了 就直接返回word地址 + if (isCreate) { + return R.ok(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + businessId + "/" + fileName, "创建成功!"); + } + //如果没有生成,那么现在创建检验记录 + boolean ret = testRecordService.createInspectionRecord(businessId); + if (ret) { + return R.ok(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + businessId + "/" + fileName, "创建成功!"); + + } else { + return R.failed("创建失败!"); + } + } +} + diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/IdentifyBookController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/IdentifyBookController.java new file mode 100644 index 0000000..86e1fdf --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/IdentifyBookController.java @@ -0,0 +1,36 @@ +package digital.laboratory.platform.inspection.controller; + +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.service.IdentifyBookDataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title 鉴定文书数据接口,主要为文书系统提供接口 + * @description + * @create 2024/3/13 11:01 + */ +@RestController +@RequestMapping("/identifyBookData") +@Api(tags = "16-鉴定报告数据提供服务接口", description = "鉴定报告数据提供服务接口") +public class IdentifyBookController { + @Resource + private IdentifyBookDataService identifyBookDataService; + //对文书系统提供获取实验数据 + @GetMapping("/getIdentifyBookDataByBusinessId") + @ApiOperation(value = "获取检验数据") + public R getIdentifyBookDataByBusinessId(String businessId){ + return identifyBookDataService.getIdentifyBookDataByBusinessId(businessId); + } + @PostMapping("/getTestFinishBusinessData") + @ApiOperation(value = "获取待制作文书列表") + public R getTestFinishBusinessData(@RequestBody List synedIdList){ + return identifyBookDataService.getTestFinishBusinessData(synedIdList); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInfoController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInfoController.java new file mode 100644 index 0000000..7be4026 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInfoController.java @@ -0,0 +1,105 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspection.service.SampleInfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.security.Principal; + +/* + *@title TaskInfoController + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:24 + */ +@RestController +@RequestMapping("/sampleInfo") +@Api(tags = "04-样本基本信息管理", description = "样本基本信息管理") +public class SampleInfoController { + @Resource + private SampleInfoService sampleInfoService; + + //添加接口 + @PostMapping("/addSampleInfo") + @ApiOperation(value = "添加样本基本信息", notes = "添加样本基本信息,同时也作为其他系统调用的外部接口") + public R addSampleInfo(@RequestBody SampleInfo sampleInfo) { + SampleInfo ret = sampleInfoService.addSampleInfo(sampleInfo); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + + } + + //修改接口 + @PostMapping("/updateSampleInfo") + @ApiOperation(value = "修改任务基本信息", notes = "") + public R updateSampleInfo(@RequestBody SampleInfo sampleInfo) { + SampleInfo ret = sampleInfoService.updateSampleInfo(sampleInfo); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //删除数据 + @DeleteMapping("/deleteSampleInfo") + @ApiOperation(value = "删除样本基本信息", notes = "") + public R deleteSampleInfo(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = sampleInfoService.deleteSampleInfo(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getSampleInfoPageList") + @ApiOperation(value = "获取分页数据", notes = "") + public R getSampleInfoPageList(Page page, SampleInfo sampleInfo) { + return R.ok(sampleInfoService.getSampleInfoPageList(page, sampleInfo), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getSampleInfoList") + @ApiOperation(value = "获取列表", notes = "") + public R getSampleInfoList(SampleInfo sampleInfo) { + return R.ok(sampleInfoService.getSampleInfoList(sampleInfo), "获取数据成功"); + } + + @GetMapping("/getPageForTestRecord") + @ApiOperation(value = "在实验阶段获取该用户获得分配的检材列表", notes = "在实验阶段获取该用户获得分配的检材列表") + public R getPageForTestRecord(Page page, String testId, String keywords, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(sampleInfoService.getPageForTestRecord(page, dlpUser, testId,keywords), "获取数据成功"); + } + + + @PutMapping("/useSample") + @ApiOperation(value = "在实验阶段使用检材或取消使用检材", notes = "在实验阶段使用检材或取消使用检材") + public R useTestRecordSample(@RequestBody TestRecordArgumentDto argumentDto) { + return sampleInfoService.useTestRecordSample(argumentDto) ? R.ok("操作成功!") : R.failed("操作失败!"); + } + + @GetMapping("/checkRepeatNo") + @ApiOperation(value = "检查是否有重复编号", notes = "检查是否有重复编号") + public R checkRepeatNo(String acceptNo,String id) { + return sampleInfoService.checkRepeatNo(acceptNo,id) ? R.ok(true,"操作成功!") : R.failed(false,"操作失败!"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInjectorController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInjectorController.java new file mode 100644 index 0000000..f3f0742 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SampleInjectorController.java @@ -0,0 +1,120 @@ +package digital.laboratory.platform.inspection.controller; + +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.ResetSampleInjectorDTO; +import digital.laboratory.platform.inspection.entity.SampleInjector; +import digital.laboratory.platform.inspection.service.SampleInjectorService; +import digital.laboratory.platform.inspection.vo.TestRecordSolutionVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.util.List; + +@RestController +@RequestMapping("/sampleInjector") +@Api(tags = "14-进样器信息相关接口管理", description = "14-进样器信息相关接口管理") +public class SampleInjectorController { + + @Resource + private SampleInjectorService sampleInjectorService; + + @GetMapping + @ApiOperation(value = "根据实验id获取进样信息", notes = "根据实验id获取进样信息") + @ApiImplicitParam(name = "testId", value = "实验id", required = true) + public R getByTestId(@RequestParam("testId") String testId) { + SampleInjector one = null; + try { + one = sampleInjectorService.getByTestId(testId); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("进样信息查询失败!"); + } + return R.ok(one); + } + + @GetMapping("/materialList") + @ApiOperation(value = "检材列表", notes = "检材列表") + @ApiImplicitParams({ + @ApiImplicitParam(name = "testId", value = "实验id", required = true), + @ApiImplicitParam(name = "key", value = "查询数据字段, 仅支持编号查询", required = false) + }) + public R> queryMaterialList(@RequestParam("testId") String testId, + @RequestParam(value = "key", required = false) String key) { + List resultList = null; + try { + resultList = sampleInjectorService.queryMaterialList(testId, key); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("查询列表失败!"); + } + return R.ok(resultList); + } + + @PostMapping("/saveSampleInjector") + @ApiOperation(value = "保存进样信息", notes = "保存进样信息,进样位置信息使用json存储,直方图(方盘有4个json数组,外层是个大数组): [\n" + + " [{ sampleNo: '', injectorCount: '', name: 'A1', value: ['A', '1'], active: false, frameNumber: '' },\n" + + " { sampleNo: '', injectorCount: '', name: 'A2', value: ['A', '2'], active: false, frameNumber: '' }]," + + " [{ sampleNo: '', injectorCount: '', name: 'A1', value: ['A', '1'], active: false, frameNumber: '' },\\n\" +\n" + + " { sampleNo: '', injectorCount: '', name: 'A2', value: ['A', '2'], active: false, frameNumber: '' }]],\n" + + " 圆盘:[\n" + + " {\n" + + " \"sampleNo\": ''," + + " \"injectorCount\": ''," + + " \"frameNumber\": ''," + + " \"index\": 1,\n" + + " \"active\": false,\n" + + " \"title\": 1\n" + + " },\n" + + " {\n" + + " \"sampleNo\": ''," + + " \"injectorCount\": ''," + + " \"frameNumber\": ''," + + " \"index\": 2,\n" + + " \"active\": false,\n" + + " \"title\": 6\n" + + " }]; sampleNo 溶液编号、injectorCount 进样次数、frameNumber 架号") + public R saveSampleInjector(@Valid @RequestBody SampleInjector sampleInjector) { + SampleInjector resultInfo = null; + try { + resultInfo = sampleInjectorService.saveSampleInjector(sampleInjector); + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof RuntimeException) { + return R.failed(e.getMessage()); + } + return R.failed("保存失败!"); + } + return R.ok(resultInfo); + } + + @PutMapping("/reset") + @ApiOperation(value = "重置进样信息", notes = "重置进样信息") + public R reset(@Valid @RequestBody ResetSampleInjectorDTO dto) { + SampleInjector resultInfo = null; + try { + resultInfo = sampleInjectorService.reset(dto); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("重置失败!"); + } + return R.ok(resultInfo); + } + + @GetMapping("/export") + @ApiOperation(value = "进样信息导出", notes = "根据实验id查询对应的进样信息导出") + @ApiImplicitParam(name = "id", value = "进样信息的id", required = true) + public void exportSampleInjectorInfoToExcel(@RequestParam("id") String id, HttpServletResponse response) { + try { + sampleInjectorService.exportSampleInjectorInfoToExcel(id, response); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/ScreenInfoController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/ScreenInfoController.java new file mode 100644 index 0000000..9104acf --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/ScreenInfoController.java @@ -0,0 +1,76 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.entity.ScreenInfo; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.service.ScreenInfoService; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/* + *@title TaskInfoController + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:24 + */ +@RestController +@RequestMapping("/screenInfo") +@Api(tags = "03-筛查基本信息管理", description = "筛查基本信息管理") +public class ScreenInfoController { + @Resource + private ScreenInfoService screenInfoService; + //添加接口 + @PostMapping("/addScreenInfo") + @ApiOperation(value = "添加筛查基本信息",notes = "添加筛查基本信息,同时也作为其他系统调用的外部接口") + public R addScreenInfo(@RequestBody ScreenInfo screenInfo){ + ScreenInfo ret=screenInfoService.addScreenInfo(screenInfo); + if(ret!=null){ + return R.ok(ret,"添加成功"); + }else { + return R.failed("false","添加失败"); + } + + } + //修改接口 + @PostMapping("/updateScreenInfo") + @ApiOperation(value = "修改筛查基本信息",notes = "") + public R updateScreenInfo(@RequestBody ScreenInfo screenInfo){ + ScreenInfo ret=screenInfoService.updateScreenInfo(screenInfo); + if(ret!=null){ + return R.ok(ret,"添加成功"); + }else { + return R.failed("false","添加失败"); + } + } + //删除数据 + @DeleteMapping("/deleteScreenInfo") + @ApiOperation(value = "删除筛查基本信息",notes = "") + public R deleteScreenInfo(String id){ + Assert.notBlank(id,"参数id不能为空"); + boolean ret=screenInfoService.deleteScreenInfo(id); + if(ret){ + return R.ok("true","删除成功"); + }else { + return R.failed("false","删除成功"); + } + } + //显示列表分页 + @GetMapping("/getScreenPageList") + @ApiOperation(value = "获取分页数据",notes = "") + public R getScreenPageList(Page page,ScreenInfo screenInfo,String keywords){ + return R.ok(screenInfoService.getScreenPageList(page,screenInfo,keywords),"获取数据成功"); + } + //显示列表 + @GetMapping("/getScreenList") + @ApiOperation(value = "获取列表",notes = "") + public R getScreenList(ScreenInfo screenInfo,String keywords){ + return R.ok(screenInfoService.getScreenList(screenInfo,keywords),"获取数据成功"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SewageDrugInspectReportController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SewageDrugInspectReportController.java new file mode 100644 index 0000000..4ba9ae8 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/SewageDrugInspectReportController.java @@ -0,0 +1,64 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.ExportSewageAnalystReportsDTO; +import digital.laboratory.platform.inspection.dto.SewageDataDto; +import digital.laboratory.platform.inspection.dto.TaskInfoDto; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.entity.TestRecordSampleData; +import digital.laboratory.platform.inspection.service.SewageDrugInspectReportService; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import digital.laboratory.platform.inspection.service.TestRecordSampleDataService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.List; + +/** + *@title TaskInfoController + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:24 + */ +@RestController +@RequestMapping("/sewageReport") +@Api(tags = "17-污水专项检测毒品分析报告", description = "污水专项检测毒品分析报告") +public class SewageDrugInspectReportController { + @Resource + private SewageDrugInspectReportService sewageDrugInspectReportService; + + @Resource + private TestRecordSampleDataService testRecordSampleDataService; + + @ApiOperation(value = "导出污水专项检测毒品分析报告") + @PostMapping("/exportSewageAnalystReports") + public R exportSewageAnalystReports(@RequestBody ExportSewageAnalystReportsDTO dto){ + try { + String reportWord = sewageDrugInspectReportService.generateSewageDrugInspectReportWord(dto); + return R.ok(reportWord); + } catch (Exception e) { + e.printStackTrace(); + } + return R.failed(); + } +// +// @ApiOperation(value = "更新数据") +// @PostMapping("/updateData") +// public R updateData(){ +// boolean update = testRecordSampleDataService +// .update(Wrappers.lambdaUpdate() +// .eq(TestRecordSampleData::getTestId, "BC4234B2FF08F7E8CE1ED881DB374EA8") +// .eq(TestRecordSampleData::getSampleConcentration, 0) +// .set(TestRecordSampleData::getSampleConcentration, 2.123)); +// return R.ok(update); +// } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TaskInfoController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TaskInfoController.java new file mode 100644 index 0000000..c8c8414 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TaskInfoController.java @@ -0,0 +1,101 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.ExportSewageAnalystReportsDTO; +import digital.laboratory.platform.inspection.dto.SewageDataDto; +import digital.laboratory.platform.inspection.dto.TaskInfoDto; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.time.LocalDate; +import java.io.IOException; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TaskInfoController + * @description + * @create 2023/12/8 11:24 + */ +@RestController +@RequestMapping("/taskInfo") +@Api(tags = "02-任务基本信息管理", description = "任务基本信息管理") +public class TaskInfoController { + @Resource + private TaskInfoService taskInfoService; + + //添加接口 + @PostMapping("/addTaskInfo") + @ApiOperation(value = "添加任务基本信息", notes = "添加任务基本信息,同时也作为其他系统调用的外部接口") + public R addTaskInfo(@RequestBody TaskInfoDto taskInfo) { + TaskInfo ret = taskInfoService.addTaskInfo(taskInfo); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + + } + + //修改接口 + @PostMapping("/updateTaskInfo") + @ApiOperation(value = "修改任务基本信息", notes = "") + public R updateTaskInfo(@RequestBody TaskInfo taskInfo) { + TaskInfo ret = taskInfoService.updateTaskInfo(taskInfo); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //删除数据 + @GetMapping("/deleteTaskInfo") + @ApiOperation(value = "删除任务基本信息", notes = "") + public R deleteTaskInfo(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = taskInfoService.deleteTaskInfo(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getTaskPageList") + @ApiOperation(value = "获取分页数据", notes = "") + public R getTaskPageList(Page page, TaskInfo taskInfo, String keywords) { + return R.ok(taskInfoService.getTaskPageList(page, taskInfo, keywords), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getTaskList") + @ApiOperation(value = "获取列表", notes = "") + public R getTaskList(TaskInfo taskInfo, String keywords) { + return R.ok(taskInfoService.getTaskList(taskInfo, keywords), "获取数据成功"); + } + + @PostMapping("/create/sewageReport") + @ApiOperation(value = "导出污水消费量计算Excel,参数:dailySmokingPerCapita为人均日吸烟量(支)") + public R createSewageReport(String taskId, Double dailySmokingPerCapita) throws IOException { + List sewageReportData = taskInfoService.createSewageReportData(taskId, dailySmokingPerCapita); + String filePath = taskInfoService.createSewageReportExcel(sewageReportData, taskId); + return R.ok(filePath, "生成成功!"); + } + + @PostMapping("/exportSewageAnalystReports") + @ApiOperation(value = "导出污水专项检测毒品分析报告", notes = "按月份导出") + public R exportSewageAnalystReports(@RequestBody ExportSewageAnalystReportsDTO dto) { + return taskInfoService.exportSewageAnalystReports(dto); + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java new file mode 100644 index 0000000..48534e5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordController.java @@ -0,0 +1,215 @@ +package digital.laboratory.platform.inspection.controller; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.amazonaws.services.s3.model.AmazonS3Exception; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.annotation.JsonFormat; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO; +import digital.laboratory.platform.inspection.dto.TestRecordDto; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.vo.ProcedureVo; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.activation.MimetypesFileTypeMap; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.security.Principal; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title TestRecordController + * @description 检验记录控制器 + * @create 2023/12/19 11:50 + */ +@RestController +@RequestMapping("/testRecord") +@Api(tags = "06-检验记录管理", description = "检验记录管理") +public class TestRecordController { + + @Resource + private TestRecordService testRecordService; + + @Resource + private OssFile ossFile; + + /** + * 创建实验记录 + */ + @PostMapping("/createTestInstance") + @ApiOperation(value = "创建实验", notes = "创建实验") + public R createTestInstance(@RequestBody TestRecordDto testRecord, HttpServletRequest httpServletRequest) throws Exception { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + TestRecord testInstance = testRecordService.createTestInstance(testRecord, dlpUser); + return testInstance != null ? R.ok(testInstance, "创建成功!") : R.failed("创建失败!"); + } + + @PutMapping("/updateTestInstance") + @ApiOperation(value = "修改实验", notes = "修改实验") + public R updateTestInstance(@RequestBody TestRecord testRecord) { + TestRecord testInstance = testRecordService.updateTestInstance(testRecord); + return testInstance != null ? R.ok(testInstance, "修改成功!") : R.failed("修改失败!"); + } + + @GetMapping("/getById") + @ApiOperation(value = "通过实验Id查询实验信息", notes = "通过实验Id查询实验信息") + public R getTestRecord(String id, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testRecordService.getTestRecord(id, dlpUser), "查询成功!"); + } + + @GetMapping("/getByIdTest") + @ApiOperation(value = "通过实验Id查询实验信息", notes = "通过实验Id查询实验信息") + public R getByIdTest(String id, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testRecordService.getById(id), "查询成功!"); + } + + @GetMapping("/getPage") + @ApiOperation(value = "分页查询实验信息", notes = "分页查询实验信息") + public R> getTestRecordPageList(Page page, HttpServletRequest httpServletRequest, + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") LocalDateTime startTime, + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") LocalDateTime endTime, + String businessType) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testRecordService.getTestRecordPageList(page, dlpUser, startTime, endTime, businessType), "查询成功!"); + } + + @GetMapping("/getList") + @ApiOperation(value = "列表查询实验信息", notes = "列表查询实验信息") + public R> getTestRecordList(HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testRecordService.getTestRecordList(dlpUser), "查询成功!"); + } + + @PutMapping("/useTemplate") + @ApiOperation(value = "使用模板", notes = "使用模板") + public R useTemplate(String testId, String templateId) throws Exception { + return R.ok(testRecordService.useTemplate(testId, templateId), "使用成功!"); + } + + @GetMapping("/getProcedure") + @ApiOperation(value = "获取步骤是否完成的参数") + public R getProcedure(String testId) { + return R.ok(testRecordService.getProcedure(testId), "数据获取成功!"); + } + + + @GetMapping("/solutionPage") + @ApiOperation(value = "分页查询实验中所有溶液编号") + public R getResultSolutionPage(Page page, String testId) { + return R.ok(testRecordService.getResultSolutionPage(page, testId), "数据获取成功!"); + } + + @DeleteMapping + @ApiOperation(value = "通过实验ID删除这个实验") + public R delTestRecord(String testId) { + return testRecordService.delTestRecord(testId) ? R.ok("删除成功!") : R.failed(" 删除失败!"); + } + + @PostMapping("/uploadTestAtlas") + @ApiOperation(value = "上传该实验的实验图谱") + @ApiImplicitParams({ + @ApiImplicitParam(name = "testId", value = "实验id", required = true) + }) + public R uploadTestAtlas(@RequestParam("testId") String testId, @RequestPart("file") MultipartFile file) { + // ? R.ok("上传实验图谱成功!") : R.failed("上传实验图谱删除失败!") + try { + return testRecordService.uploadTestAtlas(testId, file); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("系统出错,请联系管理员!"); + } + } + + @GetMapping("/getTestAtlasList") + @ApiOperation(value = "获取图谱列表") + @ApiImplicitParam(name = "testId", value = "该实验图谱关联的实验id") + public R getTestAtlasList(@RequestParam("testId") String testId) { + return testRecordService.getTestAtlasList(testId); + } + + @GetMapping("/getTestAtlasListByBusinessId") + @ApiOperation(value = "根据业务id获取图谱列表") + @ApiImplicitParam(name = "businessId", value = "该实验图谱关联的实验id") + public R getTestAtlasListByBusinessId(@RequestParam("businessId") String businessId) { + try { + return testRecordService.getTestAtlasListByBusinessId(businessId); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("系统出错,请联系管理员!"); + } + } + + @DeleteMapping("/deleteTestAtlas") + @ApiOperation(value = "删除图谱,支持批量删除") + public R deleteTestAtlas(@RequestBody @Valid DeleteTestAtlasDTO dto) { + try { + return testRecordService.deleteTestAtlas(dto); + } catch (Exception e) { + e.printStackTrace(); + return R.failed(e.getMessage()); + } + } + + @GetMapping("/getTestAtlasByFileId") + @ApiOperation(value = "根据实验id和文件id获取图片") + @ApiImplicitParam(name = "testId", value = "该实验图谱关联的实验id") + public void getTestAtlasByFileId(@RequestParam("testId") String testId, + @RequestParam("fileId") String fileId, + HttpServletResponse httpServletResponse) throws IOException { + try { + TestRecord testRecord = testRecordService.getById(testId); + JSONArray jsonArray = JSONArray.parseArray(testRecord.getTestAtlas()); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject object = jsonArray.getJSONObject(i); + if (object.getString("fileId").equals(fileId)) { + ossFile.fileGet(object.getString("path"), httpServletResponse.getOutputStream()); + httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(object.getString("fileName"))); + break; + } + } + }catch (AmazonS3Exception s3e) { + httpServletResponse.sendError(s3e.getStatusCode(), s3e.toString()); + } catch (Exception e) { + httpServletResponse.sendError(501, e.toString()); + } +// return R.ok(ossFile.fileList(TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl()+testId)); + } + + @PostMapping("/queryTestRecordInfoByBusinessId") + @ApiOperation("根据业务id获取实验信息") + public R> queryTestRecordInfoByBusinessId(@RequestBody List businessIds) { + try { + return testRecordService.queryTestRecordInfoByBusinessId(businessIds); + } catch (Exception e) { + e.printStackTrace(); + return R.failed(e.getMessage()); + } + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentConditionController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentConditionController.java new file mode 100644 index 0000000..aab9cf1 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentConditionController.java @@ -0,0 +1,82 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.util.StrUtil; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.constant.TestRecordFileUrl; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordInstrumentCondition; +import digital.laboratory.platform.inspection.service.TestRecordInstrumentConditionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController +@RequestMapping("/testRecord_instrumentCondition") +@Api(tags = "12-检验记录-仪器的使用条件", description = "检验记录-仪器的使用条件") +public class TestRecordInstrumentConditionController { + + @Resource + private TestRecordInstrumentConditionService testRecordInstrumentConditionService; + + + @ApiOperation(value = "添加实验仪器条件", notes = "添加实验仪器条件") + @PostMapping("/addInstrumentCondition") + public R addInstrumentCondition(@RequestBody TestRecordInstrumentCondition testRecordInstrumentCondition) { + TestRecordInstrumentCondition instrumentCondition = testRecordInstrumentConditionService.addInstrumentCondition(testRecordInstrumentCondition); + return instrumentCondition != null ? R.ok(instrumentCondition, "添加成功!") : R.failed("添加失败!"); + } + + @ApiOperation(value = "选择不同的模板类型,为实验创建仪器条件模板", notes = "type 1:(生物样本模板),-1 :(缴获物样本模板)") + @PostMapping("/createWord") + public R createConditionWordByTest(String testId) throws Exception { + boolean ret = testRecordInstrumentConditionService.createConditionWordByTest(testId); + return ret ? R.ok(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + "仪器条件.docx", "创建成功!") : R.failed("创建失败!"); + } + + @ApiOperation(value = "选择不同的模板类型,为模板创建仪器条件模板", notes = "type 1:(生物样本模板),-1 :(缴获物样本模板)") + @PostMapping("/createWordTem") + public R createConditionWordByTemplate(String templateId) throws Exception { + boolean ret = testRecordInstrumentConditionService.createConditionWordByTemplate(templateId); + return ret ? R.ok(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + templateId + "/" + "仪器条件.docx", "创建成功!") : R.failed("创建失败!"); + } + + @ApiOperation(value = "修改实验仪器条件", notes = "修改实验仪器条件") + @PostMapping("/updateInstrumentCondition") + public R updateInstrumentCondition(@RequestBody TestRecordInstrumentCondition testRecordInstrumentCondition) { + TestRecordInstrumentCondition instrumentCondition = testRecordInstrumentConditionService.updateInstrumentCondition(testRecordInstrumentCondition); + return instrumentCondition != null ? R.ok(instrumentCondition, "修改成功!") : R.failed("修改失败!"); + } + + @ApiOperation(value = "删除实验仪器条件", notes = "删除实验仪器条件") + @DeleteMapping("/delInstrumentCondition") + public R delInstrumentCondition(String id) { + return testRecordInstrumentConditionService.delInstrumentCondition(id) ? R.ok("删除成功!") : R.failed("删除失败!"); + } + + @ApiOperation(value = "通过ID查询仪器条件") + @GetMapping("/getConditionById") + public R getInstrumentConditionById(String testId) { + return R.ok(testRecordInstrumentConditionService.getInstrumentConditionByTestId(testId)); + } + + + @ApiOperation(value = "为模板添加或移除仪器条件", notes = "为模板添加或移除仪器条件") + @PutMapping("/useConditionToTemplate") + public R useInstrumentConditionToTemplate(@RequestBody TestRecordArgumentDto argumentDto) { + return testRecordInstrumentConditionService.useInstrumentConditionToTemplate(argumentDto) ? R.ok("添加成功!") : R.failed("添加失败!"); + } + + @PutMapping("/merge") + public R mergeFileByBiologicalSample(String testId) throws Exception { + return testRecordInstrumentConditionService.mergeFile(testId) ? R.ok("合并成功!") : R.failed("合并失败!"); + } + + @GetMapping("/generatedOrNot") + @ApiOperation(value = "判断是否创建了仪器条件模板", notes = "判断是否创建了仪器条件模板") + public R generatedOrNot(String testId) { + String filePath = testRecordInstrumentConditionService.generatedOrNot(testId); + return StrUtil.isNotBlank(filePath) ? R.ok(filePath) : R.failed("没有创建好仪器条件模板!"); + } +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentController.java new file mode 100644 index 0000000..2e55294 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordInstrumentController.java @@ -0,0 +1,98 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.entity.TestRecordInstrument; +import digital.laboratory.platform.inspection.service.TestRecordInstrumentService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * @author xy + * @version 1.0 + * @title TestRecordInstrumentController + * @description 实验中使用到的仪器设备 + * @create 2023/12/19 11:48 + */ +@RestController +@RequestMapping("/testRecord_instrument") +@Api(tags = "07-检验记录-使用仪器管理", description = "检验记录-使用仪器管理") +public class TestRecordInstrumentController { + @Resource + private TestRecordInstrumentService testRecordInstrumentService; + + //添加 + @PostMapping("/addInstrument") + @ApiOperation(value = "添加设备仪器", notes = "添加设备仪器") + public R addInstrument(@RequestBody TestRecordInstrument testRecordInstrument) { + TestRecordInstrument ret = testRecordInstrumentService.addTestRecordInstrument(testRecordInstrument); + if (ret != null) { + return R.ok(ret, "添加实验仪器设备成功"); + } else { + return R.failed("false", "添加实验仪器设备失败"); + } + } + + //修改接口 + @PostMapping("/updateInstrument") + @ApiOperation(value = "修改实验设备仪器", notes = "") + public R updateInstrument(@RequestBody TestRecordInstrument testRecordInstrument) { + TestRecordInstrument ret = testRecordInstrumentService.updateTestRecordInstrument(testRecordInstrument); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //删除数据 + @DeleteMapping("/deleteInstrument") + @ApiOperation(value = "删除实验设备仪器信息", notes = "") + public R deleteInstrument(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = testRecordInstrumentService.deleteTestRecordInstrument(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getInstrumentPageList") + @ApiOperation(value = "获取实验中仪器设备分页数据", notes = "") + public R getInstrumentPageList(Page page, String testId, String keywords, Integer opCode) { + return R.ok(testRecordInstrumentService.getTestRecordInstrumentPageList(page, testId,keywords,opCode), "获取数据成功"); + } + + @GetMapping("/getInstrumentToTemplatePage") + @ApiOperation(value = "获取模板中仪器设备分页数据", notes = "") + public R getTemplateInstrumentPageList(Page page, String templateId, String keywords, Integer opCode) { + return R.ok(testRecordInstrumentService.getTemplateInstrumentPageList(page, templateId,keywords,opCode), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getInstrumentList") + @ApiOperation(value = "获取列表", notes = "") + public R getInstrumentList(TestRecordInstrument testRecordInstrument) { + return R.ok(testRecordInstrumentService.getTestRecordInstrumentList(testRecordInstrument), "获取数据成功"); + } + + @PutMapping("/useInstrument") + @ApiOperation(value = "添加或移除实验过程中使用的仪器设备", notes = "添加或移除实验过程中使用的仪器设备") + public R useTestRecordInstrument(@RequestBody TestRecordArgumentDto testRecordArgumentDto) { + return testRecordInstrumentService.useTestRecordInstrument(testRecordArgumentDto) ? R.ok("添加成功!") : R.failed("添加失败!"); + } + + @PutMapping("/useInstrumentToTemplate") + @ApiOperation(value = "添加或移除模板中使用的仪器设备", notes = "添加或移除模板中使用的仪器设备") + public R useTemplateInstrument(@RequestBody TestRecordArgumentDto testRecordArgumentDto) { + return testRecordInstrumentService.useTemplateInstrument(testRecordArgumentDto) ? R.ok("添加成功!") : R.failed("添加失败!"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordMethodController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordMethodController.java new file mode 100644 index 0000000..ae00144 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordMethodController.java @@ -0,0 +1,91 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import digital.laboratory.platform.inspection.service.TestRecordMethodService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * @author xy + * @version 1.0 + * @title TestRecordMethodController + * @description + * @create 2023/12/19 15:25 + */ +@RestController +@RequestMapping("/testRecord_method") +@Api(tags = "08-检验记录-使用方法管理", description = "检验记录-使用方法管理") +public class TestRecordMethodController { + @Resource + private TestRecordMethodService testRecordMethodService; + + //添加 + @PostMapping("/addMethod") + @ApiOperation(value = "添加实验使用方法", notes = "添加设备仪器") + public R addMethod(@RequestBody TestRecordMethod testRecordMethod) { + TestRecordMethod ret = testRecordMethodService.addTestRecordMethod(testRecordMethod); + if (ret != null) { + return R.ok(ret, "添加实验方法成功"); + } else { + return R.failed("false", "添加实验方法失败"); + } + } + + //修改接口 + @PostMapping("/updateMethod") + @ApiOperation(value = "修改实验使用方法", notes = "") + public R updateMethod(@RequestBody TestRecordMethod testRecordMethod) { + TestRecordMethod ret = testRecordMethodService.updateTestRecordMethod(testRecordMethod); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //删除数据 + @DeleteMapping("/deleteMethod") + @ApiOperation(value = "删除实验使用方法", notes = "") + public R deleteMethod(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = testRecordMethodService.deleteTestRecordMethod(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getMethodPageList") + @ApiOperation(value = "获取分页数据", notes = "") + public R getMethodPageList(Page page, TestRecordMethod testRecordMethod) { + return R.ok(testRecordMethodService.getTestRecordMethodPageList(page, testRecordMethod), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getMethodList") + @ApiOperation(value = "获取列表", notes = "") + public R getMethodList(TestRecordMethod testRecordMethod) { + return R.ok(testRecordMethodService.getTestRecordMethodList(testRecordMethod), "获取数据成功"); + } + + @PutMapping("/useMethod") + @ApiOperation(value = "使用方法、取消使用方法", notes = "testRecordId:实验ID、methodId:方法ID、opCode:1使用,-1取消使用") + public R useTestRecordMethod(@RequestBody TestRecordArgumentDto argumentDto) { + return testRecordMethodService.useTestRecordMethod(argumentDto) ? R.ok("操作成功!") : R.failed("操作失败!"); + } + + @PutMapping("/useMethodToTemplate") + @ApiOperation(value = "针对模板使用方法、取消使用方法", notes = "templateId:模板ID、methodId:方法ID、opCode:1使用,-1取消使用") + public R useTemplateMethod(@RequestBody TestRecordArgumentDto argumentDto) { + return testRecordMethodService.useTemplateMethod(argumentDto) ? R.ok("操作成功!") : R.failed("操作失败!"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordReagentController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordReagentController.java new file mode 100644 index 0000000..2e564d9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordReagentController.java @@ -0,0 +1,99 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import digital.laboratory.platform.inspection.entity.TestRecordReagent; +import digital.laboratory.platform.inspection.service.TestRecordMethodService; +import digital.laboratory.platform.inspection.service.TestRecordReagentService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +/** + * @author xy + * @version 1.0 + * @title TestRecordReagent + * @description 实验用到的试剂耗材,标准物质 + * @create 2023/12/20 10:07 + */ +@RestController +@RequestMapping("/testRecord_reagent") +@Api(tags = "09-检验记录-使用的试剂耗材,标准物质管理", description = "检验记录-使用的试剂耗材,标准物质管理") +public class TestRecordReagentController { + @Resource + private TestRecordReagentService testRecordReagentService; + + //添加 + @PostMapping("/addReagent") + @ApiOperation(value = "添加实验使用的试剂耗材、标准物质", notes = "添加实验使用的试剂耗材、标准物质") + public R addReagent(@RequestBody TestRecordReagent testRecordReagent) { + TestRecordReagent ret = testRecordReagentService.addTestRecordReagent(testRecordReagent); + if (ret != null) { + return R.ok(ret, "添加数据成功"); + } else { + return R.failed("false", "添加数据失败"); + } + } + + //修改接口 + @PutMapping("/updateReagent") + @ApiOperation(value = "修改实验使用试剂耗材、标准物质", notes = "") + public R updateReagent(@RequestBody TestRecordReagent testRecordReagent) { + TestRecordReagent ret = testRecordReagentService.updateTestRecordReagent(testRecordReagent); + if (ret != null) { + return R.ok(ret, "添加成功"); + } else { + return R.failed("false", "添加失败"); + } + } + + //删除数据 + @DeleteMapping("/deleteReagent") + @ApiOperation(value = "删除实验使用试剂耗材、标准物质", notes = "") + public R deleteReagent(String id) { + Assert.notBlank(id, "参数id不能为空"); + boolean ret = testRecordReagentService.deleteTestRecordReagent(id); + if (ret) { + return R.ok("true", "删除成功"); + } else { + return R.failed("false", "删除成功"); + } + } + + //显示列表分页 + @GetMapping("/getReagentPageList") + @ApiOperation(value = "获取实验中试剂耗材分页数据", notes = "参数:" + "\n" + "1.testId:实验ID" + "\n" + "2.keywords:查询参数" + "\n" + "3.category:试剂耗材类别(传入试剂耗材/标准物质二选一即可)" + "\n" + "4.opCode:传入1或-1(1是查询所有(去重),-1是查询这个实验下的所有)") + public R getReagentPageList(Page page, String testId, String keywords, String category, Integer opCode) { + return R.ok(testRecordReagentService.getTestRecordReagentPageList(page, testId, keywords, category, opCode), "获取数据成功"); + } + + //显示列表 + @GetMapping("/getReagentList") + @ApiOperation(value = "获取实验中试剂耗材列表数据", notes = "获取实验中试剂耗材列表数据") + public R getReagentList(String testId, String category) { + return R.ok(testRecordReagentService.getTestRecordReagentList(testId, category), "获取数据成功"); + } + + @PutMapping("/useReagent") + @ApiOperation(value = "添加或移除实验过程中的试剂耗材", notes = "testRecordId:实验ID、reagentId:试剂耗材ID、opCode:1使用,-1取消使用") + public R useTestRecordReagent(@RequestBody TestRecordArgumentDto testRecordArgumentDto) { + return testRecordReagentService.useTestRecordReagent(testRecordArgumentDto) ? R.ok("添加成功!") : R.failed("添加失败!"); + } + + @PutMapping("/useReagentToTemplate") + @ApiOperation(value = "添加或移除模板中的试剂耗材", notes = "testRecordId:实验ID、reagentId:试剂耗材ID、opCode:1使用,-1取消使用") + public R useTestTemplateReagent(@RequestBody TestRecordArgumentDto testRecordArgumentDto) { + return testRecordReagentService.useTestTemplateReagent(testRecordArgumentDto) ? R.ok("添加成功!") : R.failed("添加失败!"); + } + + @GetMapping("/getReagentToTemplatePage") + @ApiOperation(value = "获取模板中试剂耗材分页数据", notes = "参数:" + "\n" + "1.templateId:模板ID" + "\n" + "2.keywords:查询参数" + "\n" + "3.category:试剂耗材类别(传入试剂耗材/标准物质二选一即可)" + "\n" + "4.opCode:传入1或-1(1是查询所有(去重),-1是查询这个模板下的所有)") + public R getReagentToTemplatePageList(Page page, String templateId, String keywords, String category, Integer opCode) { + return R.ok(testRecordReagentService.getTestTemplateReagentPageList(page, templateId, keywords, category, opCode), "获取数据成功"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleDataController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleDataController.java new file mode 100644 index 0000000..a58d8b7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleDataController.java @@ -0,0 +1,302 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.constant.BusinessType; +import digital.laboratory.platform.inspection.dto.*; +import digital.laboratory.platform.inspection.entity.TestRecordSampleData; +import digital.laboratory.platform.inspection.service.TestRecordSampleDataService; +import digital.laboratory.platform.inspection.utils.TestDataFileUtil; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct; +import digital.laboratory.platform.inspection.vo.TestResultBusinessVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.apache.ibatis.exceptions.TooManyResultsException; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; +import java.security.Principal; +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleDataController 实验数据控制器 + * @description + * @create 2024/1/19 15:57 + */ +@RestController +@RequestMapping("/testRecord_TestData") +@Api(tags = "15-检验记录-实验数据管理服务", description = "检验记录-实验数据管理服务接口") +public class TestRecordSampleDataController { + + @Resource + private TestRecordSampleDataService testRecordSampleDataService; + + //解析数据文件 + @PostMapping("/parseTestData") + @ApiOperation(value = "上传检验数据文件", notes = "上传检验数据文件") + @ApiImplicitParams({ + @ApiImplicitParam(name = "fileTypeCode", value = "上传的文件格式,10001 岛津 | 10002 沃特斯毛发案件 | 20002 沃特斯任务 | 20001 沃特斯毛发任务", required = true), + @ApiImplicitParam(name = "testId", value = "实验id", required = true) + }) + public R parseTestData(@RequestPart("file") MultipartFile file, + @RequestParam("fileTypeCode") String fileTypeCode, + @RequestParam("testId") String testId) { + try { + testRecordSampleDataService.validateTestStatus(testId); + switch (BusinessType.getBusinessTypeByType(fileTypeCode)) { + case SCREENING_EVENT: + case NPS_CASE: { + List retDataList = TestDataFileUtil.analysisNpsDataFile(file);//NPS文件解析 + // 先删除这个实验id有关的数据在插入下新数据 + testRecordSampleDataService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + Boolean saveTestDataFromNps = testRecordSampleDataService.saveTestDataFromNps(retDataList, testId); + return saveTestDataFromNps ? R.ok(true, "上传数据成功") : R.failed(false, "上传数据失败!"); + } + case BOINT_CASE: { + Map> hairCompoundDataMap = TestDataFileUtil.analysisWtsDataFile(file, 1);//毛发案件文件解析 /毛发任务文件解析 + // 先删除这个实验id有关的数据在插入下新数据 + testRecordSampleDataService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + Boolean saveTestDataHairCase = testRecordSampleDataService.saveTestDataHairCase(hairCompoundDataMap, testId); + return saveTestDataHairCase ? R.ok(true, "上传数据成功") : R.failed(false, "上传数据失败!"); + } + case SEWAGE_JOB: { + // /污水任务文件解析 + Map> sewageCompoundDataMap = TestDataFileUtil.analysisWtsDataFile(file, 2);//毛发案件文件解析 /毛发任务文件解析 + // 先删除这个实验id有关的数据在插入下新数据 + testRecordSampleDataService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + Boolean saveTestDataHairCase = testRecordSampleDataService.saveTestDataHairSewageTask(sewageCompoundDataMap, testId, fileTypeCode); + return saveTestDataHairCase ? R.ok(true, "上传数据成功") : R.failed(false, "上传数据失败!"); + } + case BOINT_JOB: { + // /毛发任务文件解析 + Map> hairCompoundDataMap = TestDataFileUtil.analysisWtsDataFile(file, 1);//毛发案件文件解析 /毛发任务文件解析 + // 先删除这个实验id有关的数据在插入下新数据 + testRecordSampleDataService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + Boolean saveTestDataHairCase = testRecordSampleDataService.saveTestDataHairSewageTask(hairCompoundDataMap, testId, fileTypeCode); + return saveTestDataHairCase ? R.ok(true, "上传数据成功") : R.failed(false, "上传数据失败!"); + } + } + } catch (Exception err) { + err.printStackTrace(); + if (err instanceof RuntimeException) { + return R.failed(err.getMessage()); + } + return R.failed("上传文件异常,请检查数据文件"); + } + return R.failed("上传文件异常,请检查数据文件"); + } + + //手动录入结果的保存 -nps + @PostMapping("/saveNpsManualData") + @ApiOperation(value = "保存手动录入的实验结果数据", notes = "保存手动录入的实验结果数据") + private R saveNpsManualData(@RequestBody List npsDataFileStruct, String testId) { + return R.ok(testRecordSampleDataService.saveTestDataFromNps(npsDataFileStruct, testId)); + } + + @PutMapping("/saveQuantitativeResults") + @ApiOperation(value = "保存实验数据的定量结果", notes = "保存实验数据的定量结果") + private R saveQuantitativeResults(@RequestBody SaveQuantitativeResultsDTO dto) { + boolean success = false; + try { + success = testRecordSampleDataService.saveQuantitativeResults(dto); + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof TooManyResultsException) { + return R.failed(String.format("在上样编号 %s 中检测化合物 %s 在不同的实验中出现重复!", dto.getSampleName(), dto.getCompoundName())); + } else if (e instanceof RuntimeException) { + return R.failed(e.getMessage()); + } + return R.failed("系统出错,请联系管理员!"); + } + return R.ok(success); + } + + @DeleteMapping("/deleteQuantitativeResults") + @ApiOperation(value = "删除实验数据的定量结果", notes = "删除实验数据的定量结果, 这里的删除只是把定量结果制空") + private R deleteQuantitativeResults(@RequestParam("testSampleDataId") String testSampleDataId) { + boolean deleted = false; + try { + deleted = testRecordSampleDataService.deleteQuantitativeResults(testSampleDataId); + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof RuntimeException) { + return R.failed("删除失败!" + e.getMessage()); + } + return R.failed("删除失败!"); + } + return R.ok(deleted); + } + + @PutMapping("/updateEntrustTestData") + @ApiOperation(value = "修改导入的实验数据", notes = "修改导入的实验数据") + private R updateEntrustTestData(@RequestBody UpdateEntrustTestDataDTO dto) { + try { + testRecordSampleDataService.validateTestStatus(dto.getTestId()); + List list = dto.getList(); + if (CollUtil.isNotEmpty(list)) { + for (UpdateEntrustTestDataDTO updateEntrustTestDataDTO : list) { + testRecordSampleDataService.updateEntrustTestData(updateEntrustTestDataDTO); + } + return R.ok("实验数据保存成功"); + } else { + return R.ok(testRecordSampleDataService.updateEntrustTestData(dto)); + } + } catch (Exception e) { + e.printStackTrace(); + if (e instanceof RuntimeException) { + return R.failed("实验数据保存失败!" + e.getMessage()); + } + return R.failed("实验数据保存失败!"); + } + } + + //分析获取检验结果 + @GetMapping("/getAnalysisTestResult") + @ApiOperation(value = "获取实验结果", notes = "获取实验结果, 其中 " + + "targetRtTime 目标物保留时间," + + "stdRtTime 标准物保留时间," + + "rtTimeError 保留时间相对误差," + + "rtTimeWithinError 保留时间是否在误差范围内") + @ApiImplicitParams({ + @ApiImplicitParam(name = "testId", value = "实验id", required = true), + @ApiImplicitParam(name = "type", value = "检验数据的类型,比如说是nps的还是毛发案件的", required = true) + }) + public R getAnalysisTestResult(@RequestParam("testId") String testId, @RequestParam("type") String type) { + if (type.equals(BusinessType.BOINT_CASE.getBusinessType()) + || type.equals(BusinessType.NPS_CASE.getBusinessType()) + || type.equals(BusinessType.SCREENING_EVENT.getBusinessType())) { + return R.ok(testRecordSampleDataService.getSampleTestDataByTestId(testId, type)); + } else { + // 任务实验数据 + Map map = testRecordSampleDataService.queryTaskTestResult(testId); + return R.ok(map); + } + } + + @PostMapping("/getAnalysisTestResultPage") + @ApiOperation(value = "分页查询-获取实验结果", notes = "分页查询-获取实验结果") + public R> getAnalysisTestResultPage(@RequestBody @Valid AnalysisTestResultPageDTO pageDTO) { + Page page = null; + try { + page = testRecordSampleDataService.getSampleTestDataByTestIdPage(pageDTO); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("查询失败,系统异常!"); + } + return R.ok(page); + } + + @GetMapping("/getSampleTestDataByBusinessId") + @ApiOperation(value = "根据业务id查询检验数据, 这里的业务id可能是委托id 、 筛查id、 任务id", notes = "根据业务id查询检验数据, 这里的业务id可能是委托id 、 筛查id、 任务id") + @ApiImplicitParams({ + @ApiImplicitParam(name = "businessId", value = "业务id", required = true), + @ApiImplicitParam(name = "type", value = "查询的业务类型, 10000 委托 | 20000 任务 | 30000 筛查", required = false) + }) + public R getSampleTestDataByBusiness(@RequestParam("businessId") String businessId, Integer type) { + List sampleTestDataByBusiness = null; + try { + if (type != null && type.equals(20000)) { + // 20000 代表该业务id是任务的 + Map map = testRecordSampleDataService.queryTaskTestResultByBusiness(businessId); + return R.ok(map); + } + sampleTestDataByBusiness = testRecordSampleDataService.getSampleTestDataByBusiness(businessId); + } catch (Exception e) { + e.printStackTrace(); + if (e.getMessage().contains("Duplicate key")) { + return R.failed("查询失败,系统异常,数据中在同一个化合物中有重复编号存在!"); + } else if (e instanceof RuntimeException) { + return R.failed("查询失败,系统异常!" + e.getMessage()); + } + return R.failed("查询失败,系统异常!"); + } + return R.ok(sampleTestDataByBusiness); + } + + // 实验结果等相关接口 + @PostMapping("/queryTestResultPage") + @ApiOperation(value = "实验结果查询中分页查询", notes = "实验结果查询中分页查询, 10000 委托、20000 任务、 30000 筛查") + public R> queryTestResultPage(@RequestBody QueryTestResultPageDTO dto, HttpServletRequest theHttpServletRequest) { + Principal principal = theHttpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + IPage resultPage = null; + try { + resultPage = testRecordSampleDataService.queryTestResultPage( + new Page(dto.getCurrent(), dto.getSize()), + dto, dlpUser); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("分页查询出错,详细信息请查看控制台!"); + } + + return R.ok(resultPage); + } + + @PostMapping("/finishTest") + @ApiOperation(value = "完成实验", notes = "完成实验") + @ApiImplicitParam(name = "testId", value = "实验id", required = true) + public R finishTest(@RequestParam("testId") String testId) { +// testRecordSampleDataService.finishTest(testId); + try { + return testRecordSampleDataService.finishTest(testId); + } catch (Exception e) { + e.printStackTrace(); + return R.failed(e.getMessage()); + } + } + + @PostMapping("/queryWaitApproveTaskTestDataPage") + @ApiOperation(value = "分页查询-获取审核的任务检验数据", notes = "分页查询-获取审核的任务检验数据") + public R queryWaitApproveTaskTestDataPage(@RequestBody @Valid TaskTestDataPageDTO pageDTO) { + Map map = null; + try { + map = testRecordSampleDataService.queryWaitApproveTaskTestDataPage(pageDTO); + } catch (Exception e) { + e.printStackTrace(); + return R.failed("查询失败,系统异常!"); + } + return R.ok(map); + } + + @PutMapping("/audit") + @ApiOperation(value = "审核审批数据", notes = "审核审批数据") + public R audit(@RequestBody @Valid AuditDataDTO auditDataDTO, HttpServletRequest httpServletRequest) { + return testRecordSampleDataService.auditTaskTestData(auditDataDTO, httpServletRequest); + } + + + private void NPSTestResultAnalysis(List npsDataFileStructList) { + //NPS的分析暂时只考虑定性分析,定性分析的逻辑如下 + // 1、获取定性分析的条件, 2、循环该实验下的所有检材的数据,根据定性条件判断获取分析结果 + + } + + + @PutMapping("/updateCompoundCnName") + @ApiOperation(value = "添加中文化合物名称", notes = "添加中文化合物名称") + public R updateCompoundCnName(@RequestBody UpdateCompoundCnNameDto dto) { + List list = testRecordSampleDataService.list(Wrappers.lambdaQuery() + .in(TestRecordSampleData::getId, dto.getIdList())); + + list.forEach(testRecordSampleData -> { + testRecordSampleData.setCompoundCnName(dto.getCompoundCnName()); + testRecordSampleDataService.updateById(testRecordSampleData); + }); + return R.ok("更新成功!"); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleSolutionController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleSolutionController.java new file mode 100644 index 0000000..2118763 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordSampleSolutionController.java @@ -0,0 +1,80 @@ +package digital.laboratory.platform.inspection.controller; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordSampleSolutionDto; +import digital.laboratory.platform.inspection.entity.TestRecordSampleSolution; +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import digital.laboratory.platform.inspection.service.TestRecordSampleSolutionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@RestController +@RequestMapping("/testRecord_sampleSolution") +@Api(tags = "10-检验记录-使用的样本溶液,样本溶液管理", description = "检验记录-使用的样本溶液,样本溶液管理") +public class TestRecordSampleSolutionController { + + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService; + + @PostMapping("/addSolution") + @ApiOperation(value = "添加实验样本溶液", notes = "添加实验过程中使用的样本溶液") + public R addTestRecordSampleSolution(@RequestBody TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + TestRecordSampleSolution testRecordSampleSolution = testRecordSampleSolutionService.addTestRecordSampleSolution(testRecordSampleSolutionDto); + return testRecordSampleSolution != null ? R.ok(testRecordSampleSolution, "添加成功!") : R.failed("添加失败!"); + } + + @DeleteMapping("/delSolution") + @ApiOperation(value = "删除实验样本溶液", notes = "删除实验过程中使用的样本溶液") + + public R delTestRecordSampleSolution(String id) { + return testRecordSampleSolutionService.delTestRecordSampleSolution(id) ? R.ok("删除成功!") : R.failed("删除失败!"); + } + + @PutMapping("/updateSolution") + @ApiOperation(value = "修改实验样本溶液", notes = "修改实验过程中使用的样本溶液") + public R updateTestRecordSampleSolution(@RequestBody TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + TestRecordSampleSolution testRecordSampleSolution = testRecordSampleSolutionService.updateTestRecordSampleSolution(testRecordSampleSolutionDto); + return testRecordSampleSolution != null ? R.ok(testRecordSampleSolution, "修改成功!") : R.failed("修改失败!"); + } + + @GetMapping("/getSolutionList") + @ApiOperation(value = "通过实验(检验)ID查询样本溶液集合", notes = "通过实验(检验)ID查询样本溶液集合") + public R> getSolutionList(String testId, String keywords) { + return R.ok(testRecordSampleSolutionService.getSolutionList(testId, keywords), "查询成功"); + } + + @GetMapping("/getSolutionPage") + @ApiOperation(value = "通过实验(检验)ID查询样本溶液分页集合", notes = "通过实验(检验)ID查询样本溶液分页集合") + public R> getSolutionPage(Page page, String testId, String keywords) { + return R.ok(testRecordSampleSolutionService.getSolutionPage(page, testId, keywords), "查询成功"); + } + + @PutMapping("/matchingWeighing") + @ApiOperation(value = "通过实验ID匹配样本溶液质量与计算浓度", notes = "通过实验ID匹配样本溶液质量与计算浓度") + public R> matchingWeighing(String id) { + List testRecordSampleSolutionList = testRecordSampleSolutionService.matchingWeighing(id); + return testRecordSampleSolutionList != null ? R.ok(testRecordSampleSolutionList, "匹配成功!") : R.failed("匹配失败!"); + } + + + @PostMapping("/createTaskSamSol") + @ApiOperation(value = "根据任务类型实验中选择的检材创建对应的样本溶液", notes = "根据任务类型实验中选择的检材创建对应的样本溶液") + public R createTaskSamSol(String testId) { + return testRecordSampleSolutionService.createTaskSamSol(testId) ? R.ok("创建成功!") : R.failed("创建失败!"); + } + + @PostMapping("/copy") + @ApiOperation(value = "根据已有样本溶液创建多个样本溶液",notes = "参数 testRecordSampleSolutionDto:已有样本溶液对象;testRecordSampleSolutionDto中的materialIdList:需要创建的对应检材ID集合") + public R copySolution(@RequestBody TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + List recordSampleSolutions = testRecordSampleSolutionService.copySolution(testRecordSampleSolutionDto); + return recordSampleSolutions != null ? R.ok(recordSampleSolutions, "创建成功!") : R.failed("创建失败!"); + } +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordStandardSolutionController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordStandardSolutionController.java new file mode 100644 index 0000000..7a745b9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestRecordStandardSolutionController.java @@ -0,0 +1,82 @@ +package digital.laboratory.platform.inspection.controller; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordStandardSolutionDto; +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import digital.laboratory.platform.inspection.service.TestRecordStandardSolutionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@RestController +@RequestMapping("/testRecord_standardSolution") +@Api(tags = "11-检验记录-使用的标准溶液,标准溶液", description = "检验记录-使用的标准溶液,标准溶液") + +public class TestRecordStandardSolutionController { + @Resource + private TestRecordStandardSolutionService testRecordStandardSolutionService; + + @PostMapping("/addSolution") + @ApiOperation(value = "添加实验标准溶液", notes = "添加实验过程中使用的标准溶液") + public R addTestRecordStandardSolution(@RequestBody TestRecordStandardSolutionDto testRecordStandardSolution) { + return testRecordStandardSolutionService.addTestRecordStandardSolution(testRecordStandardSolution) != null ? R.ok(testRecordStandardSolution, "添加成功!") : R.failed("添加失败!"); + } + + @PostMapping("/addBlankSolution") + @ApiOperation(value = "添加空白溶剂、空白样品 type 1:空白溶剂 -1:空白样品", notes = "添加空白溶剂、空白样品 type 1:空白溶剂 -1:空白样品") + public R addBlankSolution(String testId,Integer type) { + TestRecordStandardSolution testRecordStandardSolution = testRecordStandardSolutionService.addBlankSolution(testId,type); + return testRecordStandardSolution != null ? R.ok(testRecordStandardSolution, "添加成功!") : R.failed("添加失败!"); + } + + @PostMapping("/addQCSolution") + @ApiOperation(value = "添加质控溶液", notes = "添加质控溶液") + public R createQualityControlSol(String testId) { + List qualityControlSol = testRecordStandardSolutionService.createQualityControlSol(testId); + return qualityControlSol.size()>0 ? R.ok(qualityControlSol, "添加成功!") : R.failed("添加失败!"); + } + + @DeleteMapping("/delSolution") + @ApiOperation(value = "删除实验标准溶液", notes = "删除实验过程中使用的标准溶液") + public R delTestRecordStandardSolution(String id) { + return testRecordStandardSolutionService.delTestRecordStandardSolution(id) ? R.ok("删除成功!") : R.failed("删除失败!"); + } + + @PutMapping("/updateSolution") + @ApiOperation(value = "修改实验标准溶液", notes = "修改实验过程中使用的标准溶液") + public R updateTestRecordStandardSolution(@RequestBody TestRecordStandardSolutionDto testRecordStandardSolutionDto) { + return testRecordStandardSolutionService.updateTestRecordStandardSolution(testRecordStandardSolutionDto) != null ? R.ok(testRecordStandardSolutionDto, "修改成功") : R.failed("修改失败!"); + } + + @GetMapping("/getSolutionPage") + @ApiOperation(value = "通过实验(检验)ID查询标准溶液分页集合", notes = "通过实验(检验)ID查询标准溶液分页集合") + public R> getTestRecordStandardSolutionPage(Page page, String testId, String keywords) { + return R.ok(testRecordStandardSolutionService.getTestRecordStandardSolutionPage(page, testId, keywords), "查询成功!"); + } + + @GetMapping("/getSolutionList") + @ApiOperation(value = "通过实验(检验)ID查询标准溶液集合", notes = "通过实验(检验)ID查询标准溶液集合") + public R> getTestRecordStandardSolutionList(String testId, String keywords) { + return R.ok(testRecordStandardSolutionService.getTestRecordStandardSolutionList(testId, keywords), "查询成功!"); + } + + @PutMapping("/matchingWeighing") + @ApiOperation(value = "通过实验ID匹配标准溶液质量与计算浓度", notes = "通过实验ID匹配标准溶液质量与计算浓度") + public R> matchingWeighing(String id) { + List testRecordStandardSolutions = testRecordStandardSolutionService.matchingWeighing(id); + return testRecordStandardSolutions != null ? R.ok(testRecordStandardSolutions, "匹配成功!") : R.failed("匹配失败!"); + } + + @GetMapping("/detection") + @ApiOperation(value = "判断实验中是否存在至少一瓶标准溶液", notes = "判断实验中是否存在至少一瓶标准溶液") + public R detection(String testId) { + return R.ok(testRecordStandardSolutionService.detection(testId)); + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestTemplateController.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestTemplateController.java new file mode 100644 index 0000000..ca2b5e1 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/controller/TestTemplateController.java @@ -0,0 +1,87 @@ +package digital.laboratory.platform.inspection.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.TemplateDeleteDto; +import digital.laboratory.platform.inspection.entity.TestTemplate; +import digital.laboratory.platform.inspection.service.TestTemplateService; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.security.Principal; +import java.util.List; + +@RestController +@RequestMapping("/test_template") +@Api(tags = "13-实验模板", description = "实验模板") +public class TestTemplateController { + @Resource + private TestTemplateService testTemplateService; + + @PostMapping("/createTemplate/{testId}") + @ApiOperation(value = "根据实验创建模板") + public R createTemplate(@RequestBody TestTemplate testTemplate, HttpServletRequest httpServletRequest, @PathVariable String testId) throws Exception { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + TestTemplate template = testTemplateService.createTemplate(testTemplate, testId, dlpUser); + return template != null ? R.ok(template, "创建成功!") : R.failed("创建失败!"); + } + + @PutMapping("/editTemplate") + @ApiOperation(value = "修改模版信息") + public R editTemplate(TestTemplate testTemplate) { + return testTemplateService.editTemplate(testTemplate) != null ? R.ok(testTemplate, "修改成功!") : R.failed("修改失败!"); + } + + @PutMapping("/publishTemplate") + @ApiOperation(value = "通过ID发布模板") + public R publishTemplate(String id) { + TestTemplateVo template = testTemplateService.publishTemplate(id); + return template != null ? R.ok(template, "发布成功!") : R.failed("发布失败!"); + } + + @PutMapping("/blockTemplate") + @ApiOperation(value = "通过ID停用模板") + public R blockTemplate(String id) { + TestTemplateVo template = testTemplateService.blockTemplate(id); + return template != null ? R.ok(template, "停用成功!") : R.failed("停用失败!"); + } + + @GetMapping("/getTemplateById") + @ApiOperation(value = "通过ID查询模板信息") + public R getTemplateById(String id) { + return R.ok(testTemplateService.getTemplateById(id), "数据获取成功!"); + } + + @GetMapping("/getTemplatePage") + @ApiOperation(value = "分页查询模板信息") + public R getTemplateVoPage(Page page, Integer opCode, HttpServletRequest httpServletRequest, String keywords) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testTemplateService.getTemplateVoPage(page, opCode, dlpUser, keywords), "数据获取成功!"); + } + + @GetMapping("/getTemplateList") + @ApiOperation(value = "列表查询模板信息(创建实验时)") + public R getTemplateVoList(HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return R.ok(testTemplateService.getTemplateVoList(dlpUser), "数据获取成功!"); + } + + @DeleteMapping() + @ApiOperation(value = "根据ID删除模板") + public R delTemplate(@RequestBody ListidList, HttpServletRequest httpServletRequest) { + Principal principal = httpServletRequest.getUserPrincipal(); + DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal(); + return testTemplateService.delTemplate(idList, dlpUser) ? R.ok("删除成功!") : R.failed("删除失败!"); + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AnalysisTestResultPageDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AnalysisTestResultPageDTO.java new file mode 100644 index 0000000..8277fed --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AnalysisTestResultPageDTO.java @@ -0,0 +1,35 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 获取实验数据分页查询DTO类 + */ +@Data +@ApiModel(value = "AnalysisTestResultPageDTO", description = "获取实验数据分页查询DTO类") +public class AnalysisTestResultPageDTO { + + @ApiModelProperty("分页参数,每页多少条") + private long size = 10L; + + @ApiModelProperty("分页参数, 当前页") + private long current = 1L; + + @ApiModelProperty("实验id") + @NotBlank(message = "参数不全,请检查参数是否符合!") + private String testId; + + @ApiModelProperty("获取数据类型, 检验数据的类型,比如说是nps的还是毛发案件的") + private String type; + + // 搜索参数 待定 + @ApiModelProperty("关键字") + private String keyword; + + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AppraisalProcessDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AppraisalProcessDto.java new file mode 100644 index 0000000..6889b74 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AppraisalProcessDto.java @@ -0,0 +1,13 @@ +package digital.laboratory.platform.inspection.dto; + +import lombok.Data; + +@Data +public class AppraisalProcessDto { + + private String appraisalProcess; + + public AppraisalProcessDto(String appraisalProcess) { + this.appraisalProcess = appraisalProcess; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AssignmentInfoDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AssignmentInfoDto.java new file mode 100644 index 0000000..69d11d9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AssignmentInfoDto.java @@ -0,0 +1,19 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class AssignmentInfoDto extends AssignmentInfo { + + @ApiModelProperty(value = "类型 1 : 按业务分配 -1:按检材分配") + Integer type; + @ApiModelProperty(value = "查询参数") + private Integer opCode; + + @ApiModelProperty(value = "搜索参数") + private String keywords; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AuditDataDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AuditDataDTO.java new file mode 100644 index 0000000..98e80ed --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/AuditDataDTO.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 审核数据请求参数DTO + */ +@Data +@ApiModel(value = "AuditDataDTO", description = "审核数据请求参数DTO") +public class AuditDataDTO { + + @ApiModelProperty("任务检验数据的编号列表") + @NotEmpty(message = "未选择审核的数据!") + private List sampleNoList; + + @ApiModelProperty("操作类型, -1 审核审批不通过 | 1 审核通过 | 2 审批通过 ") + @Min(value = -1, message = "操作值不匹配!") + @Max(value = 3, message = "操作值不匹配!") + private Integer opCode; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BaseCaseDataDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BaseCaseDataDto.java new file mode 100644 index 0000000..83e34c3 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BaseCaseDataDto.java @@ -0,0 +1,20 @@ +package digital.laboratory.platform.inspection.dto; + +import java.util.List; + +/** + * 为了复用,通过BaseCaseDataDto 作为参数类型,在其中传递不同的具体子类对象 + */ +public abstract class BaseCaseDataDto { + // 定义抽象方法和属性 + public abstract String getTestId(); + public abstract String getTargetConcentration(); + public abstract String getStdConcentration(); + public abstract String getCompoundName(); + public abstract double getTargetRtTime(); + public abstract double getStdRtTime(); + public abstract String getRtTimeWithinError(); + public abstract List getTestSampleDataList(); + public abstract int getIsDetected();//是否检出目标化合物 + public abstract String getSampleType();//样本类型- QC(质控) STD(标准品) Analyte(待测样品) +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BusinessDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BusinessDto.java new file mode 100644 index 0000000..deaf849 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/BusinessDto.java @@ -0,0 +1,10 @@ +package digital.laboratory.platform.inspection.dto; + +import lombok.Data; + +@Data +public class BusinessDto { + + private String businessId; + private String businessType; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DataSolutionSampleDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DataSolutionSampleDTO.java new file mode 100644 index 0000000..660f304 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DataSolutionSampleDTO.java @@ -0,0 +1,47 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 封装检验数据、样本溶液、检材连表查询的DTO类 + */ +@Data +@ApiModel(value = "DataSolutionSampleDTO", description = "封装检验数据、样本溶液、检材连表查询的DTO类") +public class DataSolutionSampleDTO { + + @ApiModelProperty("检验数据id") + private String sampleDataId; + + @ApiModelProperty("检验数据结果json") + private String dataResultJson; + + @ApiModelProperty("化合物名称") + private String compoundName; + + @ApiModelProperty("是否检出,是否检出该物质 1检出 0 未检出") + private Integer isDetected; + + @ApiModelProperty("溶液编号") + private String sampleNo; + + @ApiModelProperty("检验id") + private String testId; + + @ApiModelProperty("检材id") + private String materialId; + + @ApiModelProperty("检材名称") + private String sampleName; + + @ApiModelProperty("业务id") + private String businessId; + + @ApiModelProperty("化合物浓度") + private Double sampleConcentration; + + @ApiModelProperty("委托中检材的序号") + private Integer orderNo;//委托中检材的序号 + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DeleteTestAtlasDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DeleteTestAtlasDTO.java new file mode 100644 index 0000000..bfde0cc --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/DeleteTestAtlasDTO.java @@ -0,0 +1,25 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 删除图谱DTO参数 + */ +@Data +@ApiModel(value = "DeleteTestAtlasDTO", description = "删除图谱DTO参数") +public class DeleteTestAtlasDTO { + + @ApiModelProperty("检验id") + @NotBlank(message = "实验id不能为空!") + private String testId; + + @ApiModelProperty("删除的文件id列表") + @NotEmpty(message = "文件id不能为空!") + private List fileIds; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/EntrustInfoDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/EntrustInfoDto.java new file mode 100644 index 0000000..15777cd --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/EntrustInfoDto.java @@ -0,0 +1,10 @@ +package digital.laboratory.platform.inspection.dto; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import lombok.Data; + +import java.util.List; +@Data +public class EntrustInfoDto extends EntrustInfo { + private List materialList; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ExportSewageAnalystReportsDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ExportSewageAnalystReportsDTO.java new file mode 100644 index 0000000..012d9cb --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ExportSewageAnalystReportsDTO.java @@ -0,0 +1,42 @@ +package digital.laboratory.platform.inspection.dto; + +import com.alibaba.fastjson.JSONArray; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.web.bind.annotation.RequestParam; + +import java.time.LocalDate; +import java.util.List; + +@Data +@ApiModel(value = "ExportSewageAnalystReportsDTO", description = "导出污水专项检测毒品分析报告") +public class ExportSewageAnalystReportsDTO { + + @ApiModelProperty("任务id") + String jobId; + +// @ApiModelProperty("月份") +// LocalDate month; + + @ApiModelProperty("省名称") + String provinceName = "陕西省"; + + @ApiModelProperty("省地区编码") + String provinceCode = "610000"; + + @ApiModelProperty("是否生成依托咪酯相关的数据, 默认不生成") + private Boolean generateEtomidateTable = false; + + @ApiModelProperty("人均日吸烟(支)") + private Double dailySmokingPerCapita; + + @ApiModelProperty("常见毒品及其代谢物") + private List commonDrugAndMetabolites; + + @ApiModelProperty("人口标记物") + private List populationMarkers; + + @ApiModelProperty("报告配置") + private JSONArray reportConfig; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/HairSewageDataDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/HairSewageDataDto.java new file mode 100644 index 0000000..b9e1ba5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/HairSewageDataDto.java @@ -0,0 +1,118 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title HairCaseDataDto 毛发案件 数据文件解析信息 + * @description + * @create 2024/1/19 10:40 + */ +@Data +@ApiModel(value = "HairCaseDataDto", description = "毛发案件 数据文件解析信息") +public class HairSewageDataDto extends BaseCaseDataDto { + + @ApiModelProperty("对应的检验数据id") + private String testSampleDataId; + + @ApiModelProperty("目标物编号") + private String sampleNo; + + @ApiModelProperty("目标物名称") + private String sampleName; + + @ApiModelProperty("所属实验的ID") + private String testId;//所属实验的ID + + @ApiModelProperty("目标物保留时间") + private double targetRtTime;//目标物保留时间 + + @ApiModelProperty("模板目标物保留时间") + private String tmpTargetRtTime;//模板目标物保留时间 + + @ApiModelProperty("目标物浓度 ng/mL") + private String targetConcentration;//目标物浓度 ng/mL + + @ApiModelProperty("标准物保留时间") + private double stdRtTime;//标准物保留时间 + + @ApiModelProperty("标准物浓度") + private String stdConcentration;//标准物浓度 + + @ApiModelProperty("保留时间相对误差(%)") + private double rtTimeError;//保留时间相对偏差 + + @ApiModelProperty("模板保留时间相对误差(%)") + private String tmpRtTimeError;//保留时间相对偏差 + + @ApiModelProperty("保留时间是否在误差范围内, 是否符合") + private String rtTimeWithinError;//保留时间是否在误差范围内 + + @ApiModelProperty("定性离子对-上") + private String qualitativeIonPairUp; + + @ApiModelProperty("定性离子对-下") + private String qualitativeIonPairDown; + + @ApiModelProperty("峰面积-上") + private double peakAreaUp; + + @ApiModelProperty("模板峰面积-上") + private String tmpPeakAreaUp; + + @ApiModelProperty("峰面积-下") + private double peakAreaDown; + + @ApiModelProperty("模板峰面积-下") + private String tmpPeakAreaDown; + + @ApiModelProperty("离子丰度比") + private double ionAbundanceRatio; + + @ApiModelProperty("模板离子丰度比") + private String tmpIonAbundanceRatio; + + @ApiModelProperty("离子丰度比相对偏差(%)") + private double ionAbundanceRatioWithinError; + + @ApiModelProperty("模板离子丰度比相对偏差(%)") + private String tmpIonAbundanceRatioWithinError; + + @ApiModelProperty("是否检出") + private String whetherCheckOut; + + @ApiModelProperty("化合物名称") + private String compoundName; + + @ApiModelProperty("是否检出目标化合物") + private int isDetected;//是否检出目标化合物 + + @ApiModelProperty("样本类型- QC(质控) STD(标准品) Analyte(待测样品)") + private String sampleType;//样本类型- QC(质控) STD(标准品) Analyte(待测样品) + + @ApiModelProperty("检验数据详情") + private List testSampleDataList;//检验数据详情 + + @ApiModelProperty("封装定性离子对和峰面积") + private List> maps;//检验数据详情 + + @ApiModelProperty("业务类型") + private String businessType; + + @ApiModelProperty("定量结果") + private String quantitativeResults; + + @ApiModelProperty("化合物的中文名称") + private String compoundCnName; + +} + + + diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestDataDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestDataDto.java new file mode 100644 index 0000000..4015681 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestDataDto.java @@ -0,0 +1,69 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title NPSCaseTestData NPS 案件定性数据文件对象--原始数据 + * @description + * @create 2024/1/19 10:39 + */ +@Data +public class NPSCaseTestDataDto extends BaseCaseDataDto{ + + @ApiModelProperty("对应的检验数据id") + private String testSampleDataId; + + private String sampleNo; + private String sampleName; + private String testId;//所属实验的ID + private double targetRtTime;//目标物保留时间 + private String targetConcentration;//目标物浓度 + private double stdRtTime;//标准物保留时间 + private String stdConcentration;//标准物浓度 + private double rtTimeError;//保留时间相对偏差 + private String rtTimeWithinError;//保留时间是否在误差范围内 + private int isDetected;//是否检出目标化合物 + private String sampleType;//样本类型- QC(质控) STD(标准品) Analyte(待测样品) + private List testSampleDataList;//检验数据详情 + + @ApiModelProperty("是否检出") + private String whetherCheckOut; + + @ApiModelProperty("业务类型") + private String businessType; + + @ApiModelProperty("定量结果") + private String quantitativeResults; + + @ApiModelProperty("化合物名称") + private String compoundName; + + @ApiModelProperty("化合物的中文名称") + private String compoundCnName; + + //返回化合物名称 + /*public String getCompoundName(){ + String compoundName=""; + for (NPSTestDetailDataStruct npsTestDetailDataStruct : testSampleDataList) { + compoundName=npsTestDetailDataStruct.getName(); + break; + } + return compoundName; + }*/ + /*private String getDetectedResult(){ + if(isDetected==1){ + whetherCheckOut = "检出"+getCompoundName(); + return whetherCheckOut; + }else { + whetherCheckOut = "未检出"+getCompoundName(); + return whetherCheckOut; + } + + }*/ +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestResultDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestResultDto.java new file mode 100644 index 0000000..eadcd32 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestResultDto.java @@ -0,0 +1,40 @@ +package digital.laboratory.platform.inspection.dto; + +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title NPSCaseTestResultDto NPS 案件数据结果对象,这个需要加入标准溶液的数据信息 + * @description + * @create 2024/1/19 11:20 + */ +@Data +public class NPSCaseTestResultDto { + + private String sampleId; + private String sampleName; + + private Double targetRetentionTime;//目标物保留时间 + private Double stdRetentionTime;//参考标准物质保留时间 + private Integer rtErrorValue;//保留时间误差值,就是目标物保留时间与参考标准物质保留时间的差值 + private Boolean isInErrorRange;//是否在误差范围内,true 在误差范围内,false 不在误差范围内 + + private Double stdIar2;//参考物质离子丰度比 + private Double stdIar3;//参考物质离子丰度比 + private Double stdIar4;//参考物质离子丰度比 + + private Double targetIar2;//检材离子丰度比2 + private Double targetIar3;//检材离子丰度比2 + private Double targetIar4;//检材离子丰度比2 + + private Double errorIarValue2;//碎片2的误差 + private Double errorIarValue3;//碎片3的误差 + private Double errorIarValue4;//碎片4的误差 + + + + + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestSampleData.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestSampleData.java new file mode 100644 index 0000000..873ac33 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/NPSCaseTestSampleData.java @@ -0,0 +1,35 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct; +import lombok.Data; + +@Data +public class NPSCaseTestSampleData { + private String sampleNo; + private String targetConcentration;//目标物浓度 + private String targetRtTime;//目标物保留时间 + private String stdRtTime;//标准物保留时间 + private String stdConcentration;//标准物浓度 + private String rtTimeError;//保留时间相对偏差 + private String rtTimeWithinError;//保留时间是否在误差范围内 + private String id; + private String name; + private String type; + private String mass;//mz 质荷比 + private String retTime;//保留时间 + private String startTime; + private String endTime; + private String area;//峰面积 + private String stdRetTime; + private String sn; + private String abundanceRatio;//丰度比,如果是基峰,我们设置为1,丰度比的公式为自己的峰面积/基峰峰面积 + private String abundanceRatio_std;// 标准物质的丰度比 + private String abundanceRatioError;//丰度比偏差,如果是基峰不需要比,公式是 (自己的丰度比-标准品的MZ对应丰度比)/标准品的MZ对应丰度比 + private String errorRange;//误差范围 + private String withinError;//丰度比偏差是否在误差范围内 + private int isBasePeak;//是否是基峰,0 不是基峰 1 是基峰 + + private String compoundName;//化合物名称 + private int isDetected;//是否检出 0:未检出 1:检出 +} + diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/QueryTestResultPageDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/QueryTestResultPageDTO.java new file mode 100644 index 0000000..60559f4 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/QueryTestResultPageDTO.java @@ -0,0 +1,43 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.Date; + +/** + * 实验结果查询分页查询 + */ +@Data +@ApiModel(value = "QueryTestResultPageDTO", description = "实验结果查询分页查询的参数") +public class QueryTestResultPageDTO { + + @ApiModelProperty("分页参数,每页多少条") + private long size = 10L; + + @ApiModelProperty("分页参数, 当前页") + private long current = 1L; + + @ApiModelProperty("类型,10000 委托、20000 任务、 30000 筛查") + @NotNull(message = "参数不全, 请检查参数是否符合!") + private Integer type; + + @ApiModelProperty("关键字") + private String keyword; + + @ApiModelProperty("录入人-查询") + private String createBy; + + @ApiModelProperty("开始时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime startTime; + + @ApiModelProperty("结束时间") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime endTime; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/RegionalDrugConsumptionDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/RegionalDrugConsumptionDTO.java new file mode 100644 index 0000000..ca7724f --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/RegionalDrugConsumptionDTO.java @@ -0,0 +1,59 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 各行政区主要毒品总消费量表 数据DTO 数据传输对象 + */ +@Data +@ApiModel(value = "RegionalDrugConsumptionDTO", description = "各行政区主要毒品总消费量表 数据DTO") +public class RegionalDrugConsumptionDTO { + + @ApiModelProperty("行政区域") + private String regional; + + @ApiModelProperty("人均消耗量Heroin 海洛因") + private String pccHeroin;//人均消耗量Heroin + + @ApiModelProperty("人均消耗量MA 冰毒") + private String pccMa;//人均消耗量MA + + @ApiModelProperty("人均消耗量K 氯胺酮") + private String pccK;//人均消耗量K + + @ApiModelProperty("人均消耗量MDMA") + private String pccMdma;//人均消耗量MDMA + + @ApiModelProperty("人均消耗量COC 可卡因") + private String pccCoc;//人均消耗量COC + + @ApiModelProperty("人均消耗量Fen 芬太尼") + private String pccFen;//人均消耗量Fen + + @ApiModelProperty("人均消耗量 - 综合") + private String pccTotal;//人均消耗量 - 综合 + + @ApiModelProperty("总消耗量Heroin 海洛因") + private String tcHeroin;//总消耗量Heroin + + @ApiModelProperty("总消耗量MA 冰毒") + private String tcMa;//总消耗量MA + + @ApiModelProperty("总消耗量K 氯胺酮") + private String tcK;//总消耗量K + + @ApiModelProperty("总消耗量MDMA 摇头丸") + private String tcMdma;//总消耗量MDMA + + @ApiModelProperty("总消耗量COC 可卡因") + private String tcCoc;//总消耗量COC + + @ApiModelProperty("总消耗量Fen 芬太尼") + private String tcFen;//总消耗量Fen + + @ApiModelProperty("总消费量(克/天) 综合") + private String tcTotal;//总消耗了THC + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ReportConfigDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ReportConfigDTO.java new file mode 100644 index 0000000..de539f9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ReportConfigDTO.java @@ -0,0 +1,26 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 生成污水报告或者毛发报告的配置信息 + */ +@Data +@ApiModel(value = "ReportConfigDTO", description = "生成污水报告或者毛发报告的配置信息") +public class ReportConfigDTO { + + @ApiModelProperty(value = "字典类型") + private String dictType; + + @ApiModelProperty(value = "字典名称") + private String dictLabel; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "区分外层数据和里层的数据, 1 是外层 2 是里层或者为空") + private String type; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ResetSampleInjectorDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ResetSampleInjectorDTO.java new file mode 100644 index 0000000..5b29308 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/ResetSampleInjectorDTO.java @@ -0,0 +1,54 @@ +package digital.laboratory.platform.inspection.dto; + +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.annotation.TableField; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 重置进样信息位置请求参数 + */ +@Data +@ApiModel(value = "ResetSampleInjectorDTO", description = "重置进样信息位置请求参数") +public class ResetSampleInjectorDTO { + + @ApiModelProperty("进样信息的id") + @NotBlank(message = "参数不全,进样信息的id不能为空!") + private String id; + + + @ApiModelProperty("进样位置信息数组") + private JSONArray injectorInfo; + + /** + * 方盘-进样位置信息-1, 临时参数 + *//* + @ApiModelProperty("方盘-进样位置信息-1, 临时参数") + @TableField(exist = false) + private JSONArray injectorInfo1; + + *//** + * 方盘-进样位置信息-2, 临时参数 + *//* + @ApiModelProperty("方盘-进样位置信息-2, 临时参数") + @TableField(exist = false) + private JSONArray injectorInfo2; + + *//** + * 方盘-进样位置信息-3, 临时参数 + *//* + @ApiModelProperty("方盘-进样位置信息-3, 临时参数") + @TableField(exist = false) + private JSONArray injectorInfo3; + + *//** + * 方盘-进样位置信息-4, 临时参数 + *//* + @ApiModelProperty("方盘-进样位置信息-4, 临时参数") + @TableField(exist = false) + private JSONArray injectorInfo4;*/ +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SCCaseDataDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SCCaseDataDto.java new file mode 100644 index 0000000..019ea50 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SCCaseDataDto.java @@ -0,0 +1,12 @@ +package digital.laboratory.platform.inspection.dto; + +/** + * @author xy + * @version 1.0 + * @title SCCaseDataDto + * @description + * @create 2024/1/19 10:41 + */ + +public class SCCaseDataDto { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SampleInjectorExcelDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SampleInjectorExcelDTO.java new file mode 100644 index 0000000..179f19a --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SampleInjectorExcelDTO.java @@ -0,0 +1,87 @@ +package digital.laboratory.platform.inspection.dto; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "SampleInjectorExcelDTO", description = "进样信息导出excel中的每一行数据DTO类") +public class SampleInjectorExcelDTO { + // @ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器; + @ExcelProperty(value = "FILE_NAME") + @ApiModelProperty(value = "溶液编号") + private String fileName; + + @ExcelProperty(value = "FILE_TEXT") + @ApiModelProperty(value = "溶液浓度") + private String fileText; + + @ExcelProperty(value = "MS_FILE") + @ApiModelProperty("默认空白") + private String msFile; + + @ExcelProperty(value = "MS_TUNE_FILE") + @ApiModelProperty(value = "") + private String msTuneFile; + + @ExcelProperty(value = "INLET_FILE") + @ApiModelProperty(value = "") + private String inletFile; + + @ExcelProperty(value = "SAMPLE_LOCATION") + @ApiModelProperty("检材进样位置") + private String sampleLocation; + + @ExcelProperty(value = "SAMPLE_GROUP") + @ApiModelProperty(value = "") + private String sampleGroup; + + @ExcelProperty(value = "TYPE") + @ApiModelProperty(value = "溶液类型") + private String type; + + @ExcelProperty(value = "ID") + @ApiModelProperty("") + private String id; + + @ExcelProperty(value = "CONC_A") + @ApiModelProperty(value = "") + private String concA; + + @ExcelProperty(value = "CONC_B") + @ApiModelProperty(value = "") + private String concB; + + @ExcelProperty(value = "CONC_C") + @ApiModelProperty("") + private String concC; + + @ExcelProperty(value = "CONC_D") + @ApiModelProperty(value = "") + private String concD; + + @ExcelProperty(value = "CONC_E") + @ApiModelProperty(value = "") + private String concE; + + @ExcelProperty(value = "CONC_F") + @ApiModelProperty("") + private String concF; + + @ExcelProperty(value = "INJ_VOL") + @ApiModelProperty(value = "") + private String injVol; + + @ExcelProperty(value = "QUAN_REF") + @ApiModelProperty(value = "") + private String quanRef; + + @ExcelProperty(value = "METH_DB") + @ApiModelProperty("") + private String methDb; + + @ExcelProperty(value = "Index") + @ApiModelProperty(value = "") + private Integer index; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SaveQuantitativeResultsDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SaveQuantitativeResultsDTO.java new file mode 100644 index 0000000..5640722 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SaveQuantitativeResultsDTO.java @@ -0,0 +1,33 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * 保存实验数据的定量结果 + */ +@Data +@ApiModel(value = "SaveQuantitativeResultsDTO", description = "保存实验数据的定量结果") +public class SaveQuantitativeResultsDTO { + + @ApiModelProperty("目标物上样编号 --- 生物样本检验时的参数为上样编号") + private String sampleName; + + @ApiModelProperty("目标物检材编号 -- 缴获物检验时的参数为检材编号") + private String sampleNo; + + @ApiModelProperty("化合物名称") + @NotBlank(message = "参数不全,请检查参数!") + private String compoundName; + + @ApiModelProperty("定量结果") + @NotBlank(message = "参数不全,请检查参数!") + private String quantitativeResults; + + /*@ApiModelProperty("保存的数据类型") + @NotBlank(message = "参数不全,请检查参数!") + private String type;*/ +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SewageDataDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SewageDataDto.java new file mode 100644 index 0000000..676251e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/SewageDataDto.java @@ -0,0 +1,51 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.sewage.vo.SewageJobIdentificationMaterialVO; +import lombok.Data; + +@Data +@SuppressWarnings("all") +public class SewageDataDto extends SewageJobIdentificationMaterialVO { + private Double cotinineConcentration = 0.0;//可替宁(ng/L) + private Double codeineConcentration = 0.0;//可待因(ng/L) + private Double mdaConcentration = 0.0;//MDA(ng/L) + private Double mdmaConcentration = 0.0;//MDMA(ng/L) + private Double cocaineConcentration = 0.0;//可卡因(ng/L) + private Double benzoylecgonineConcentration = 0.0;//苯甲酰爱康宁(ng/L) + private Double morphineConcentration = 0.0;//吗啡(ng/L) + private Double acetylmorphineConcentration = 0.0;//O6-单乙酰吗啡(ng/L) + private Double methamphetamineConcentration = 0.0;//甲基苯丙胺(ng/L) + private Double amphetamineConcentration = 0.0;//苯丙胺(ng/L) + private Double ketamineConcentration = 0.0;//氯胺酮(ng/L) + private Double norketamineConcentration = 0.0;//去甲氯胺酮(ng/L) + private Double thcConcentration = 0.0;//四氢大麻酸(ng/L) + private Double fenConcentration = 0.0;//芬太尼(ng/L) + private Double etomidateConcentration = 0.0;//依托咪酯(ng/L) + private Double dailySmokingPerCapita;//人均日吸烟 + private Double cotinineExcretion;//可替宁排泄量(mg/千人天) + private Double estimatedPopulation;//测算人口(千人) + private Double morphineLoad;//吗啡负荷量 + private Double codeineLoad;//可待因负荷量 + private Double codeineIsConvertedToMorphineLoad;//可待因转化为吗啡负荷量 + private Double medicalMorphineLoad;//医用吗啡负荷量 + private Double MA_AM; + private Double K_NK; + private Double pccHeroin;//人均消耗量Heroin + private Double pccMa;//人均消耗量MA + + private Double pccK;//人均消耗量K + + private Double pccMdma;//人均消耗量MDMA + private Double pccCoc;//人均消耗量COC + private Double pccThc;//人均消耗量THC + private Double pccFen;//人均消耗量Fen + + private Double tcHeroin;//总消耗量Heroin + private Double tcMa;//总消耗量MA + private Double tcK;//总消耗量K + private Double tcMdma;//总消耗量MDMA + private Double tcCoc;//总消耗量COC + private Double tcThc;//总消耗量THC + private Double tcFen;//总消耗了Fen + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskInfoDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskInfoDto.java new file mode 100644 index 0000000..bca5fef --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskInfoDto.java @@ -0,0 +1,12 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import lombok.Data; + +import java.util.List; + +@Data +public class TaskInfoDto extends TaskInfo { + List materialList; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataDTO.java new file mode 100644 index 0000000..8588a83 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataDTO.java @@ -0,0 +1,61 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 获取任务数据的DTO类 + */ +@Data +@ApiModel(value = "TaskTestDataDTO", description = "获取任务数据的DTO类") +public class TaskTestDataDTO { + + @ApiModelProperty("检验数据id") + private String sampleDataId; + + @ApiModelProperty("检验数据结果json") + private String dataResultJson; + + @ApiModelProperty("化合物名称") + private String compoundName; + + @ApiModelProperty("是否检出,是否检出该物质 1检出 0 未检出") + private Integer isDetected; + + @ApiModelProperty("溶液编号") + private String sampleNo; + + @ApiModelProperty("检验id") + private String testId; + + @ApiModelProperty("检材id") + private String materialId; + + @ApiModelProperty("检材名称") + private String sampleName; + + @ApiModelProperty("检材编号") + private String acceptNo; + + @ApiModelProperty("业务id") + private String businessId; + + @ApiModelProperty("任务名称") + private String taskName; + + @ApiModelProperty("业务类型") + private String businessType; + + @ApiModelProperty("任务数据审核状态") + private Integer status; + + @ApiModelProperty("对应的检材含这个化合物浓度") + private Double sampleConcentration; + + @ApiModelProperty("数据生成时间") + private LocalDateTime createTime; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataPageDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataPageDTO.java new file mode 100644 index 0000000..934bb10 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TaskTestDataPageDTO.java @@ -0,0 +1,38 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; + +/** + * 获取任务审核数据时分页查询参数 + */ +@Data +@ApiModel(value = "TaskTestDataPageDTO", description = "获取任务审核数据时分页查询参数") +public class TaskTestDataPageDTO { + + @ApiModelProperty("分页参数,每页多少条") + @Min(value = 10, message = "每页条数不能小于10") + private int size = 10; + + @ApiModelProperty("分页参数, 当前页") + @Min(value = 1, message = "当前页不能小于1") + private int current = 1; + + // 搜索参数 待定 + @ApiModelProperty("关键字, 支持任务名称,检材名称") + private String keyword; + + // 搜索参数 待定 + @ApiModelProperty("业务类型") + private String businessType; + + // 状态值 + @ApiModelProperty("状态, 1 任务审核列表 | 2 任务审批列表") + @Max(value = 2, message = "最大值为2") + @Min(value = 1, message = "最小值不能小于1") + private Integer status; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TemplateDeleteDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TemplateDeleteDto.java new file mode 100644 index 0000000..8be002b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TemplateDeleteDto.java @@ -0,0 +1,10 @@ +package digital.laboratory.platform.inspection.dto; + +import lombok.Data; + +import java.util.List; +@Data +public class TemplateDeleteDto { + + List idList; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordArgumentDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordArgumentDto.java new file mode 100644 index 0000000..3f02130 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordArgumentDto.java @@ -0,0 +1,18 @@ +package digital.laboratory.platform.inspection.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class TestRecordArgumentDto { + + @ApiModelProperty(value = "实验ID") + private String testRecordId; + @ApiModelProperty("参数ID:例如试剂耗材ID、设备ID等") + private String argumentId; + @ApiModelProperty(value = "区分是添加还是移除 1:添加 -1:移除") + private Integer opCode; + + @ApiModelProperty(value = "模板ID") + private String templateId; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordDto.java new file mode 100644 index 0000000..f3aca15 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordDto.java @@ -0,0 +1,14 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import lombok.Data; + +import java.util.List; + +@Data +public class TestRecordDto extends TestRecord { + + List businessDtoList; + + private String templateId; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleSolutionDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleSolutionDto.java new file mode 100644 index 0000000..0b4868d --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordSampleSolutionDto.java @@ -0,0 +1,11 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.entity.TestRecordSampleSolution; +import lombok.Data; + +import java.util.List; + +@Data +public class TestRecordSampleSolutionDto extends TestRecordSampleSolution { + List materialIdList; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordStandardSolutionDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordStandardSolutionDto.java new file mode 100644 index 0000000..7341c78 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/TestRecordStandardSolutionDto.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.dto; + +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class TestRecordStandardSolutionDto extends TestRecordStandardSolution { + @ApiModelProperty(value = "编号后缀,使用单个标准物质时必填") + private Integer orderNum; + + @ApiModelProperty(value = "混合标准溶液名称集合") + private List standardNameList; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateCompoundCnNameDto.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateCompoundCnNameDto.java new file mode 100644 index 0000000..cb251ed --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateCompoundCnNameDto.java @@ -0,0 +1,12 @@ +package digital.laboratory.platform.inspection.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class UpdateCompoundCnNameDto { + + private List idList; + private String compoundCnName; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateEntrustTestDataDTO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateEntrustTestDataDTO.java new file mode 100644 index 0000000..7d77cab --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/dto/UpdateEntrustTestDataDTO.java @@ -0,0 +1,29 @@ +package digital.laboratory.platform.inspection.dto; + +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 修改导入的实验数据的参数DTO类 + */ +@Data +@ApiModel(value = "UpdateEntrustTestDataDTO", description = "修改导入的实验数据的参数DTO类") +public class UpdateEntrustTestDataDTO { + + @ApiModelProperty("保存的数据类型") + private String type; + + @ApiModelProperty("修改的具体数据信息") + private JSONObject param; + + @ApiModelProperty("修改的具体数据信息") + private String testId; + + @ApiModelProperty("只有该实验第一次保存数据时会接收这个参数,其他情况该参数为空") + List list; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/AssignmentInfo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/AssignmentInfo.java new file mode 100644 index 0000000..3766db7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/AssignmentInfo.java @@ -0,0 +1,53 @@ +package digital.laboratory.platform.inspection.entity; +/* + *@title AssignmentInfo + *@description 分配信息 + *@author xy + *@version 1.0 + *@create 2023/12/13 10:50 + */ + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@TableName(value = "b_assignmentInfo", autoResultMap = true) +@ApiModel(value = "分配信息", description = "分配信息") +public class AssignmentInfo extends BaseEntity { + private String id; + + @ApiModelProperty(value = "业务名称") + private String businessName; + + @ApiModelProperty(value = "业务类型") + private String businessType; + + @ApiModelProperty(value = "接收者Id") + private String testUser; + @ApiModelProperty(value = "分配者Id") + private String assignUser; + + @ApiModelProperty(value = "业务Id") + private String businessId; + + @ApiModelProperty(value = "样本ID") + private String sampleId; + + @ApiModelProperty(value = "样本名称") + private String sampleName; + + @ApiModelProperty(value = "接收者姓名") + private String testUserName; + + @ApiModelProperty(value = "分配者姓名") + private String assignUserName; + + //用来转换type类型的中文 + @TableField(exist = false) + private String businessTypeName; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/SampleInjector.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/SampleInjector.java new file mode 100644 index 0000000..bda44ea --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/SampleInjector.java @@ -0,0 +1,95 @@ +package digital.laboratory.platform.inspection.entity; + +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title 进样器管理 + * @description + * @create 2024/1/17 11:32 + */ +@Data +@TableName(value = "b_sample_injector", autoResultMap = true) +@ApiModel(value = "进样器信息", description = "进样器信息") +public class SampleInjector extends BaseEntity { + + @ApiModelProperty("主键id") + private String id; + + /** + * 进样器类型 1、圆盘进样器,2、方盘进样器 + */ + @ApiModelProperty("进样器类型 1、圆盘进样器,2、方盘进样器,0 未选择") + @NotNull(message = "请选择进样器类型!") + private Integer type = 0; + + /** + * 进样信息,位置信息,以json格式存储 + */ + @ApiModelProperty("进样信息,位置信息,以json格式存储") + private String injectorInfo; + + /** + * 检验ID,进样信息是属于某次试验的进样信息 + */ + @ApiModelProperty("检验ID,进样信息是属于某次试验的进样信息") + @NotBlank(message = "检验id不能为空!") + private String testId; + /** + * 空白起始位置 + */ + @ApiModelProperty("空白起始位置") + private Integer blankStartPosition; + + /** + * 空白穿插次数 + */ + @ApiModelProperty("空白穿插次数") + private Integer insertNumber; + + /** + * 是否已经保存, 默认false + */ + @ApiModelProperty("是否可以重置标识, true 可以重置, false 不能重置") + private boolean resetFlag = true; + +// /** +// * 方盘-进样位置信息-1, 临时参数 +// */ +// @ApiModelProperty("方盘-进样位置信息-1, 临时参数") +// @TableField(exist = false) +// private JSONArray injectorInfo1 = new JSONArray(); +// +// /** +// * 方盘-进样位置信息-2, 临时参数 +// */ +// @ApiModelProperty("方盘-进样位置信息-2, 临时参数") +// @TableField(exist = false) +// private JSONArray injectorInfo2 = new JSONArray(); +// +// /** +// * 方盘-进样位置信息-3, 临时参数 +// */ +// @ApiModelProperty("方盘-进样位置信息-3, 临时参数") +// @TableField(exist = false) +// private JSONArray injectorInfo3 = new JSONArray(); +// +// /** +// * 方盘-进样位置信息-4, 临时参数 +// */ +// @ApiModelProperty("方盘-进样位置信息-4, 临时参数") +// @TableField(exist = false) +// private JSONArray injectorInfo4 = new JSONArray(); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/ScreenInfo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/ScreenInfo.java new file mode 100644 index 0000000..67d798b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/ScreenInfo.java @@ -0,0 +1,38 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/* + *@title DrugScreen + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:33 + */ +@Data +@TableName("b_case_screen") +@ApiModel(value = "案前筛查信息", description = "案前筛查信息") +public class ScreenInfo extends BaseEntity { + private String id; + private String caseName; + private LocalDateTime obtainTime; + private String businessType;//业务类型 + private Integer source; + private String distributionSituation; //区分是否已被分配以及分配的数量 + private String originalId;//原筛查ID + @TableField(exist = false) + private String businessTypeName = "筛查事件"; + @TableField(exist = false) + private List materialList; + + @TableField(exist = false) + private Boolean isDistribution; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TaskInfo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TaskInfo.java new file mode 100644 index 0000000..b433bd1 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TaskInfo.java @@ -0,0 +1,55 @@ +package digital.laboratory.platform.inspection.entity; + +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/* + *@title TaskInfo + *@description 任务信息实体 + *@author xy + *@version 1.0 + *@create 2023/12/7 15:17 + */ +@Data +@TableName(value = "b_taskInfo", autoResultMap = true) +@ApiModel(value = "任务信息", description = "任务信息") +public class TaskInfo extends BaseEntity { + private String id; + private String taskName;//任务名称 + private String businessType;//业务类型 + private LocalDateTime taskStartDate;//任务开始日期 + private LocalDateTime taskEndDate;//任务截止日期 + private Integer source;//0,系统录入 1,手工录入 + private String originalId;//原任务ID 可能是污水任务或者毛发任务 + private String distributionSituation; //区分是否已被分配以及分配的数量 + + private String compounds;//[{"compound1":"aaaa","english":"ab-fui"}] + + @ApiModelProperty(value = "生成报告的配置") + @TableField(value = "report_config", typeHandler = FastjsonTypeHandler.class) + private JSONArray reportConfig; + + @TableField(exist = false) + List materialList; + + @TableField(exist = false) + private String businessTypeName; + + @TableField(exist = false) + // 化合物json数组 + private JSONArray compoundsJsonArray; + + @TableField(exist = false) + private Boolean isDistribution; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrument.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrument.java new file mode 100644 index 0000000..53ba835 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrument.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/* + *@title TestRecordInstrument + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 11:12 + */ +@Data +@TableName("b_test_record_instrument") +@ApiModel(value = "实验中用到的仪器设备", description = "实验中用到的仪器设备") +public class TestRecordInstrument extends BaseEntity { + private String id; + private String instrumentNumber;//设备编号 + private String instrumentName;//设备名称 + private String instrumentProvider;//厂家名称 + private String instrumentTypeNo;//型号 + private Integer source;//来源,0 代表系统推送,1 代表手动录入 + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrumentCondition.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrumentCondition.java new file mode 100644 index 0000000..f22e5de --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordInstrumentCondition.java @@ -0,0 +1,27 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestRecordInstrumentCondition 仪器使用条件 + * @description + * @create 2024/1/11 9:39 + */ +@Data +@TableName(value = "b_test_record_use_condition",autoResultMap = true) +@ApiModel(value = "实验中设备仪器条件", description = "实验中设备仪器条件") +public class TestRecordInstrumentCondition extends BaseEntity { + private String id; + private String testId;//检验ID + @TableField(typeHandler = FastjsonTypeHandler.class) + private String conditionData;//仪器条件内容(json 格式) + private Integer businessFlag;//判断是7楼还是六楼的业务 + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordMethod.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordMethod.java new file mode 100644 index 0000000..cc56f7d --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordMethod.java @@ -0,0 +1,32 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.time.LocalDate; + +/* + *@title TestRecordInstrument + *@description 实验中用到的实验方法 + *@author xy + *@version 1.0 + *@create 2023/12/19 11:12 + */ +@Data +@TableName("b_test_record_Method") +@ApiModel(value = "实验中用到的实验方法", description = "实验中用到的实验方法") +public class TestRecordMethod extends BaseEntity { + private String id; + private String methodName;//方法名称 + private String methodDescribe;//方法描述 + private String methodRange;//范围 + private String methodLevel;//方法等级(国际、行标等) + private String methodFileNumber;//文件编号 + private LocalDate methodApprovalTime;//批准时间 + private LocalDate methodImplementTime;//实施时间 + private Integer source;//来源,0 代表系统推送,1 代表手动录入 + private String previewUrl;//方法Office地址 +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordQualitativeCondition.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordQualitativeCondition.java new file mode 100644 index 0000000..9d9b726 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordQualitativeCondition.java @@ -0,0 +1,42 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @description + * 保留时间的最大误差允许范围是 正负1% + *

+ * 离子丰度比相对偏差(检材离子丰度比与标准物质离子丰度比之间的差值 d),根据文件中的规则设定,规则是: + *

+ * 1、d>50% 相对偏差为:正负 10% + *

+ * 2、d>20%~50% d小于等于50%,大于20% 相对偏差为:正负 15% + *

+ * 3、d>10%~20% 小于等于20%,大于10% 相对偏差为:正负 20% + *

+ * 4、d<=10% 小于等于10% 相对偏差为:正负 50% + * @create 2024/1/30 17:28 + * + */ +@Data +@TableName(value = "b_test_record_qualitative_condition",autoResultMap = true) +public class TestRecordQualitativeCondition { + private String id; + @ApiModelProperty(value="保留时间相对误差") + private Double rtError; + @ApiModelProperty(value="是否包含保留时间上限: 0=不包含; 1=包含") + private Boolean includeRtErrorMax; + @ApiModelProperty(value="是否包含保留时间下限: 0=不包含; 1=包含") + private Boolean includeRtErrorMin; + @ApiModelProperty(value="是否包含离子丰度偏差下限: 0=不包含; 1=包含") + private Boolean includeRatioLow; + @ApiModelProperty(value="是否包含离子丰度偏差上限: 0=不包含; 1=包含") + private Boolean includeRatioHigh; + + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordReagent.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordReagent.java new file mode 100644 index 0000000..6d63e31 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordReagent.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestRecordReagent + * @description 试剂耗材 + * @create 2023/12/20 11:02 + */ +@Data +@TableName("b_test_record_reagent_consumables") +@ApiModel(value = "实验中用到的试剂耗材", description = "实验中用到的试剂耗材") +public class TestRecordReagent extends BaseEntity { + private String id; + private String reagentConsumableName;//试剂耗材标准物质名称 + private String category;// 类别,表示是 试剂 还是 耗材 ,还是标准物质 + private String specifications; //型号规格 + private String purityGrade;//纯度等级,只有试剂有这个属性,当为耗材时为空 + private String number;//标准物质的编号,只有类型是标准物质的时候才设置 + private Integer sortIndex;// 排序 + private Integer source;//数据来源 + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java new file mode 100644 index 0000000..96cd573 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleData.java @@ -0,0 +1,69 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleSolution + * @description 实验结果数据 + * @create 2023/12/20 11:36 + */ +@Data +@TableName(value = "b_test_record_sampledata", autoResultMap = true) +@ApiModel(value = "实验中样本检测结果数据", description = "实验中样本检测结果数据") +public class TestRecordSampleData extends BaseEntity { + private String id; + + private String testId;//实验ID,记录是哪次实验做的这个检材 + + @ApiModelProperty("数据从机器中导出的唯一标识, 目前只有生物样本案件需要") + private String name;//数据从机器中导出的唯一标识 + + private String sampleNo;//样本编号 + + private String compoundName;//检测的化合物(目标化合物) + + private String stdConcentration;//标准品的浓度 + + private String sampleConcentration;//样本的浓度 ng/mL + + private String rtTimeWithinError;//保留时间是否在误差范围 ±1 以内 + + private double targetRtTime;//目标物保留时间 + + private double stdRtTime;//标准物保留时间 + + private int isDetected;//是否检出目标化合物 + + private String sampleType;//样本类型- QC(质控) STD(标准品) Analyte(待测样品) + + private String dataJson;//实验数据-原始数据,以JSON的形式来存储该样本的实验数据 + + private String dataResultJson;//检验数据结果 + + private String compoundCnName;//检测的化合物的中文名字 + + @ApiModelProperty("任务数据审核状态, 状态:\n" + + "0 待审核,\n" + + "1 已审核,\n" + + "2 已审批, \n" + + "3 已上传 \n" + + "上传到大数据平台(仅针对任务数据, 其他业务类型的数据默认0)") + private Integer status; + + private String getDetectedResult() { + if (isDetected == 1) { + return "检出" + compoundName; + } else { + return "未检出" + compoundName; + } + + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleSolution.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleSolution.java new file mode 100644 index 0000000..0d53e33 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordSampleSolution.java @@ -0,0 +1,36 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleSolution + * @description 样本溶液 + * @create 2023/12/20 11:36 + */ +@Data +@TableName("b_test_record_sample_solution") +@ApiModel(value = "实验中配置的样本溶液", description = "实验中配置的样本溶液") +public class TestRecordSampleSolution extends BaseEntity { + private String id; + private String sampleNo;//样品编号 + private String sampleShape;//样品性状 + private String dilutionName;//稀释溶剂名称 + private String extractionName;//提取溶剂名称 + private String constantVolume;//定容体积 + private String dilutionFactor;//稀释倍数 + private String originalConcentration;//原始浓度 + private String resultConcentration;//结果浓度 + private String weighingValue;//称取质量 + private String testId;//检验Id + private String materialId;//检材ID,表示这个溶液来自于 哪个检材 + @TableField(exist = false) + private String printSampleName;//打印检验记录中出现的名称:1号检材、2号检材 + private String remark; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordStandardSolution.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordStandardSolution.java new file mode 100644 index 0000000..e4502f6 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestRecordStandardSolution.java @@ -0,0 +1,83 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.common.mybatis.base.BaseEntity; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 标准溶液实体类。 + * + * 该类表示在实验过程中配置的标准溶液的相关信息。 + */ +@Data +@TableName(value = "b_test_record_standard_solution", autoResultMap = true) +@ApiModel(value = "TestRecordStandardSolution", description = "实验中配置的标准溶液") +public class TestRecordStandardSolution extends BaseEntity { + + @ApiModelProperty(value = "标准溶液ID") + private String id; + + @ApiModelProperty(value = "标准溶液编号") + private String number; + + @ApiModelProperty(value = "用到的标准物质名称,例如:甲基苯丙胺") + private String standardName; + + @ApiModelProperty(value = "稀释物质名称,例如:甲醇") + private String dilutionName; + + @ApiModelProperty(value = "定容体积") + private String constantVolume; + + @ApiModelProperty(value = "稀释倍数") + private String dilutionFactor; + + @ApiModelProperty(value = "原始浓度") + private String originalConcentration; + + @ApiModelProperty(value = "结果浓度") + private String resultConcentration; + + @ApiModelProperty(value = "结果浓度单位") + private String resultConcentrationUnit; + + @ApiModelProperty(value = "称取质量/移取体积") + private String weighingMoving; + + @ApiModelProperty(value = "检验ID") + private String testId; + + @ApiModelProperty(value = "选取标准物质数量(如果=1,则为单个标准物质溶液;如果>1,则为混合标准溶液;==0,则为空白溶液)") + private Integer standardSubstanceCount; + + @ApiModelProperty(value = "制备日期") + private LocalDateTime madeDate; + + @ApiModelProperty(value = "有效期") + private LocalDateTime expirationDate; + + @ApiModelProperty(value = "溶液类型(如质控溶液QC、标准工作溶液STD、空白溶液BLK)") + private String solutionType; + + @ApiModelProperty(value = "英文名,用于生成溶液编号") + private String englishName; + + @TableField(typeHandler = FastjsonTypeHandler.class) + @ApiModelProperty(value = "标准物质ID数组") + private List standardSubstanceNumList; + + @TableField(exist = false) + @ApiModelProperty(value = "打印制备日期", hidden = true) + private String madeDatePrint; + + @TableField(exist = false) + @ApiModelProperty(value = "打印有效期", hidden = true) + private String expirationDatePrint; +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestTemplate.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestTemplate.java new file mode 100644 index 0000000..b0dd166 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/entity/TestTemplate.java @@ -0,0 +1,46 @@ +package digital.laboratory.platform.inspection.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TestTemplate 检验模板实体 + * @description + * @create 2024/1/11 9:44 + */ +@TableName("b_test_template") +@ApiModel(value = "模板信息", description = "模板信息") +@Data +public class TestTemplate { + //仪器设备 + //试剂耗材 + //实验方法 + //仪器使用条件 + private String id; + private String name;//模板名称 + private boolean nature;//模板性质/公有-私有 0 =私有 1=公有 + private Integer status;//模板状态 0 =停用 1=启用 + private String author;//模板作者 + private Integer useCount;//模板被使用的次数 + private LocalDateTime createDate;//模板创建日期 + private LocalDateTime publishDate;//模板发布日期 + private String introduce;//模板介绍 + @TableField(typeHandler = FastjsonTypeHandler.class) + private List testMethods;//模板用到的实验方法 + @TableField(typeHandler = FastjsonTypeHandler.class) + private List deviceUseCondition;//仪器使用条件 + @TableField(typeHandler = FastjsonTypeHandler.class) + private List reagentConsumables;//使用的试剂耗材 + @TableField(typeHandler = FastjsonTypeHandler.class) + private List deviceIdList;//使用的仪器设备 + + private String businessType;//模板类型 +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/AuditDataExecutionEvent.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/AuditDataExecutionEvent.java new file mode 100644 index 0000000..e91f3ad --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/AuditDataExecutionEvent.java @@ -0,0 +1,24 @@ +package digital.laboratory.platform.inspection.event; + +import org.springframework.context.ApplicationEvent; + +import java.util.List; + +/** + * 审核数据 自定义事件 + */ + +public class AuditDataExecutionEvent extends ApplicationEvent { + + private final List sampleNoList; + + + public AuditDataExecutionEvent(Object source, List sampleNoList) { + super(source); + this.sampleNoList = sampleNoList; + } + + public List getSampleNoList() { + return sampleNoList; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/FinishTestExecutionEvent.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/FinishTestExecutionEvent.java new file mode 100644 index 0000000..f651ead --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/event/FinishTestExecutionEvent.java @@ -0,0 +1,12 @@ +package digital.laboratory.platform.inspection.event; + +import org.springframework.context.ApplicationEvent; + +/** + * 监听实验完成 === 自定义事件类 + */ +public class FinishTestExecutionEvent extends ApplicationEvent { + public FinishTestExecutionEvent(Object source) { + super(source); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/AuditDataExecutionEventListener.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/AuditDataExecutionEventListener.java new file mode 100644 index 0000000..2d06b77 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/AuditDataExecutionEventListener.java @@ -0,0 +1,31 @@ +package digital.laboratory.platform.inspection.listener; + +import digital.laboratory.platform.inspection.event.AuditDataExecutionEvent; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/*** + * 审核数据实验事件监听器 在审批数据成功后需要执行的方法 + */ +@Slf4j +@Component +public class AuditDataExecutionEventListener implements ApplicationListener { + + @Resource + private TaskInfoService taskInfoService; + + + @Override + public void onApplicationEvent(AuditDataExecutionEvent event) { + log.info("审核数据 监听器执行中 .........................."); + try { + taskInfoService.createUploadItem(event.getSampleNoList()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/FinishTestExecutionEventListener.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/FinishTestExecutionEventListener.java new file mode 100644 index 0000000..8f17cfb --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/listener/FinishTestExecutionEventListener.java @@ -0,0 +1,22 @@ +package digital.laboratory.platform.inspection.listener; + +import digital.laboratory.platform.inspection.event.FinishTestExecutionEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +/*** + * 完成实验事件监听器 在完成实验后需要执行的方法 + */ +@Slf4j +@Component +public class FinishTestExecutionEventListener implements ApplicationListener { + @Override + @Async + public void onApplicationEvent(FinishTestExecutionEvent event) { + + log.info("完成实验监听器执行中........"); + + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/AssignmentInfoMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/AssignmentInfoMapper.java new file mode 100644 index 0000000..dec205a --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/AssignmentInfoMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import org.apache.ibatis.annotations.Mapper; + +/* + *@title EntrustInfoMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Mapper +public interface AssignmentInfoMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/EntrustInfoMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/EntrustInfoMapper.java new file mode 100644 index 0000000..f7468ec --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/EntrustInfoMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import org.apache.ibatis.annotations.Mapper; + +/* + *@title EntrustInfoMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Mapper +public interface EntrustInfoMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInfoMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInfoMapper.java new file mode 100644 index 0000000..9846704 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInfoMapper.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/* + *@title EntrustInfoMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Mapper +public interface SampleInfoMapper extends BaseMapper { + + List getSampleInfoList(@Param(value = "businessId") String businessId, @Param(value = "testUser") String testUser); + IPage getFullSampleInfoList(@Param("page") Page page, @Param(Constants.WRAPPER)LambdaQueryWrapper queryWrapper); + +// List getSampleInfoByAcceptNo(@Param(value = "acceptNo") String acceptNo, @Param(value = "idList") List idList); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInjectorMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInjectorMapper.java new file mode 100644 index 0000000..0b25821 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/SampleInjectorMapper.java @@ -0,0 +1,38 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspection.entity.SampleInjector; +import digital.laboratory.platform.inspection.vo.ResultConcentrationVO; +import digital.laboratory.platform.inspection.vo.TestRecordSolutionVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** +* 进样器mapper接口 +* date: 2024/2/18 17:04 +* @author: Chen +* @since JDK 1.8 +* Description: +*/ +@Mapper +public interface SampleInjectorMapper extends BaseMapper { + /** + * 获取进样信息中的检材列表 + * @param qw + * @return + */ + List queryMaterialList(@Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 查询相关样本或者标准品溶液结果浓度 + * @param qw + * @return + */ + List queryResultConcentrationList(@Param(Constants.WRAPPER) QueryWrapper qw); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/ScreenInfoMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/ScreenInfoMapper.java new file mode 100644 index 0000000..7029489 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/ScreenInfoMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.ScreenInfo; +import org.apache.ibatis.annotations.Mapper; + +/* + *@title EntrustInfoMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Mapper +public interface ScreenInfoMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TaskInfoMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TaskInfoMapper.java new file mode 100644 index 0000000..10a2675 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TaskInfoMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import org.apache.ibatis.annotations.Mapper; + +/* + *@title EntrustInfoMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Mapper +public interface TaskInfoMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentConditionMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentConditionMapper.java new file mode 100644 index 0000000..f0868f7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentConditionMapper.java @@ -0,0 +1,23 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspection.entity.TestRecordInstrumentCondition; +import digital.laboratory.platform.inspection.vo.TestRecordInstrumentConditionVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface TestRecordInstrumentConditionMapper extends BaseMapper { + + IPage getTestRecordInstrumentConditionVoMapPage(Page page, @Param(Constants.WRAPPER) LambdaQueryWrapper qw); + + List getTestRecordInstrumentConditionVoMapList(@Param(Constants.WRAPPER) LambdaQueryWrapper qw); + + TestRecordInstrumentConditionVo getTestRecordInstrumentConditionVoMapByTestId(@Param(value = "testId") String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentMapper.java new file mode 100644 index 0000000..b3be5fa --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordInstrumentMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; +/* + *@title TestRecordInstrumentMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 11:45 + */ + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.TestRecordInstrument; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TestRecordInstrumentMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMapper.java new file mode 100644 index 0000000..d735d4b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMapper.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.mapper; +/* + *@title TestRecordMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 11:43 + */ + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface TestRecordMapper extends BaseMapper { + TestRecordVo getTestRecordMapById(@Param(value = "id") String id); + + IPage getTestRecordMapPage(Page page, @Param(Constants.WRAPPER) LambdaQueryWrapper qw); + List getTestRecordMapList(@Param(Constants.WRAPPER) LambdaQueryWrapper qw); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMethodMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMethodMapper.java new file mode 100644 index 0000000..9319eac --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordMethodMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import org.apache.ibatis.annotations.Mapper; + +/* + *@title TestRecordMethodMapper + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 11:46 + */ +@Mapper +public interface TestRecordMethodMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordReagentMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordReagentMapper.java new file mode 100644 index 0000000..58bba30 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordReagentMapper.java @@ -0,0 +1,16 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.TestRecordReagent; +import org.apache.ibatis.annotations.Mapper; + +/** + * @author xy + * @version 1.0 + * @title TestRecordReagentMapper + * @description + * @create 2023/12/20 11:10 + */ +@Mapper +public interface TestRecordReagentMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleDataMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleDataMapper.java new file mode 100644 index 0000000..2c268ac --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleDataMapper.java @@ -0,0 +1,70 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspection.dto.DataSolutionSampleDTO; +import digital.laboratory.platform.inspection.dto.TaskTestDataDTO; +import digital.laboratory.platform.inspection.entity.TestRecordSampleData; +import digital.laboratory.platform.inspection.vo.ESTBusinessInfoVO; +import digital.laboratory.platform.inspection.vo.TestResultBusinessVO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleDataMapper + * @description + * @create 2024/1/18 11:06 + */ +@Mapper +public interface TestRecordSampleDataMapper extends BaseMapper { + + /** + * 通过业务id查询委托表、筛查表、任务表 + * @param qw + * @return + */ + List queryESTBusinessInfoList(@Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 实验结果查询中分页查询 + * @param page + * @param qw + * @return + */ + IPage queryTestResultTaskPage(Page page, @Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 实验结果查询中列表查询 + * @param qw + * @return + */ + List queryTestResultTaskList(@Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 通过业务id查询委托表、筛查表、任务表(以检验数据表为主表) + * @param qw + * @return + */ + List queryDataSolutionSampleDTOList(@Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 根据业务id 查询检材内容,然后通过检材id关联查询溶液,最后通过溶液编号查询数据(以检材表为主表) + * @param qw + * @return + */ + List getTestDataListByBusiness(@Param(Constants.WRAPPER) QueryWrapper qw); + + /** + * 获取任务检验数据中 + * @param qw + * @return + */ + List queryWaitApproveTaskTestDataList(@Param(Constants.WRAPPER) QueryWrapper qw); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleSolutionMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleSolutionMapper.java new file mode 100644 index 0000000..bfb5431 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordSampleSolutionMapper.java @@ -0,0 +1,9 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.laboratory.platform.inspection.entity.TestRecordSampleSolution; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface TestRecordSampleSolutionMapper extends BaseMapper { +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordStandardSolutionMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordStandardSolutionMapper.java new file mode 100644 index 0000000..5f82a9b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestRecordStandardSolutionMapper.java @@ -0,0 +1,17 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface TestRecordStandardSolutionMapper extends BaseMapper { + IPage getTestRecordStandardSolutionMapPage(Page page, @Param(value = "testId") String testId); + + List getTestRecordStandardSolutionMapList(@Param(value = "testId") String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestTemplateMapper.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestTemplateMapper.java new file mode 100644 index 0000000..e0cb671 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/mapper/TestTemplateMapper.java @@ -0,0 +1,24 @@ +package digital.laboratory.platform.inspection.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.laboratory.platform.inspection.entity.TestTemplate; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +@Mapper +public interface TestTemplateMapper extends BaseMapper { + + TestTemplateVo getTestTemplateMapById(@Param(value = "id")String id); + + IPage getTestTemplateMapPage(Page page,@Param(Constants.WRAPPER) LambdaQueryWrapper queryWrapper); + List getTestTemplateMapList(@Param(Constants.WRAPPER) LambdaQueryWrapper queryWrapper); + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/AssignmentInfoService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/AssignmentInfoService.java new file mode 100644 index 0000000..11c0b39 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/AssignmentInfoService.java @@ -0,0 +1,34 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.AssignmentInfoDto; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.vo.AssignmentInfoVo; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Objects; + +/* + *@title AssignmentInfoService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +public interface AssignmentInfoService extends IService { + List addAssignmentInfo(List assignmentInfoDtoList);//添加任务信息 + public boolean cancelAssignmentInfo(List assignmentInfoList); + Boolean deleteAssignmentInfo(String id);//删除任务信息 + IPage getAssignmentInfoPageList(Page page, AssignmentInfoDto assignmentInfoDto); + List getAssignmentInfoList(AssignmentInfoDto assignmentInfoDto); + Boolean checkExist(String id); + + + boolean cancelByBusiness(List businessIdList); + + IPage getAssignedEntrustPage(Page page, String keywords); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/EntrustInfoService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/EntrustInfoService.java new file mode 100644 index 0000000..2af408c --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/EntrustInfoService.java @@ -0,0 +1,27 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.EntrustInfoDto; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; + +import java.util.List; + +/* + *@title EntrustInfoService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +public interface EntrustInfoService extends IService { + EntrustInfo addEntrustInfo(EntrustInfoDto entrustInfo);//添加委托信息 + EntrustInfo updateEntrustInfo(EntrustInfo entrustInfo);//修改委托信息 + Boolean deleteEntrustInfo(String id);//删除委托信息 + IPage getEntrustPageList(Page page,Integer status, EntrustInfo entrustInfo, String keywords); + List getEntrustList(EntrustInfo entrustInfo); + Boolean checkExist(String id); + + boolean checkRepeatNo(String accept,String id); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/IdentifyBookDataService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/IdentifyBookDataService.java new file mode 100644 index 0000000..823e2ed --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/IdentifyBookDataService.java @@ -0,0 +1,30 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.core.util.R; +import org.apache.poi.ss.formula.functions.T; + +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title IdentifyBookDataService + * @description + * @create 2024/3/13 11:08 + */ + +public interface IdentifyBookDataService { + /** + * 获取鉴定文书需要的数据 + * @param businessId + * @return + */ + R getIdentifyBookDataByBusinessId(String businessId); + + /** + * 获取完成实验的数据 + * @return + */ + R getTestFinishBusinessData(List synedIdList); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInfoService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInfoService.java new file mode 100644 index 0000000..4a500bc --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInfoService.java @@ -0,0 +1,49 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/* + *@title SampleInfoService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +public interface SampleInfoService extends IService { + SampleInfo addSampleInfo(SampleInfo sampleInfo);//添加样本信息 + + SampleInfo updateSampleInfo(SampleInfo sampleInfo);//修改样本信息 + + Boolean deleteSampleInfo(String id);//删除样本信息 + + IPage getSampleInfoPageList(Page page, SampleInfo sampleInfo); + + List getSampleInfoList(SampleInfo sampleInfo); + + Boolean checkExist(String id); + + IPage getPageForTestRecord(Page page, DLPUser dlpUser, String testId, String keywords); + + @Transactional + boolean useTestRecordSample(TestRecordArgumentDto testRecordArgumentDto); + + List getSampleInfoListForBusiness(String businessId, String testUser); + + boolean checkRepeatNo(String acceptNo,String id); + + /**复制其他系统检材内容 + * @param sampleInfo + * @param material + * @param type 0:委托 1:任务 2:筛查 + */ + void copy(SampleInfo sampleInfo, MaterialDto material, Integer type); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInjectorService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInjectorService.java new file mode 100644 index 0000000..1201d84 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SampleInjectorService.java @@ -0,0 +1,59 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.ResetSampleInjectorDTO; +import digital.laboratory.platform.inspection.entity.SampleInjector; +import digital.laboratory.platform.inspection.vo.TestRecordSolutionVO; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; + +/** + * 进样器service 接口 + */ +public interface SampleInjectorService extends IService { + + /** + * 保存进样信息 + * @param sampleInjector + * @return + */ + SampleInjector saveSampleInjector(SampleInjector sampleInjector); + + /** + * 检材列表查询 + * @param testId + * @param key + * @return + */ + List queryMaterialList(String testId, String key); + + /** + * 导出进样信息excel表 + * @param id + * @param response + */ + void exportSampleInjectorInfoToExcel(String id, HttpServletResponse response); + + /** + * 重置进样信息 + * @param dto + * @return + */ + SampleInjector reset(ResetSampleInjectorDTO dto); + + /** + * 根据实验id获取,数据为空则初始部分数据返回 + * @param testId + * @return + */ + SampleInjector getByTestId(String testId); + + /** + * 判断当前进样器是否保存了进样位置信息 + * @param testId + * @return + */ + boolean whetherSave(String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/ScreenInfoService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/ScreenInfoService.java new file mode 100644 index 0000000..e3c6b7b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/ScreenInfoService.java @@ -0,0 +1,31 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.entity.ScreenInfo; +import digital.laboratory.platform.inspection.entity.TaskInfo; + +import java.util.List; + +/* + *@title EntrustInfoService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +public interface ScreenInfoService extends IService { + ScreenInfo addScreenInfo(ScreenInfo screenInfo);//添加任务信息 + + ScreenInfo updateScreenInfo(ScreenInfo screenInfo);//修改任务信息 + + Boolean deleteScreenInfo(String id);//删除任务信息 + + IPage getScreenPageList(Page page, ScreenInfo screenInfo, String keywords); + + List getScreenList(ScreenInfo screenInfo, String keywords); + + Boolean checkExist(String id); + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SewageDrugInspectReportService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SewageDrugInspectReportService.java new file mode 100644 index 0000000..349d8d2 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/SewageDrugInspectReportService.java @@ -0,0 +1,14 @@ +package digital.laboratory.platform.inspection.service; + +import digital.laboratory.platform.inspection.dto.ExportSewageAnalystReportsDTO; + +/** + * 污水专项检测毒品分析报告 相关接口 + */ +public interface SewageDrugInspectReportService { + + /** + * 生成污水样品毒品检测分析报告 + */ + String generateSewageDrugInspectReportWord(ExportSewageAnalystReportsDTO dto) throws Exception; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TaskInfoService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TaskInfoService.java new file mode 100644 index 0000000..8604221 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TaskInfoService.java @@ -0,0 +1,61 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.ExportSewageAnalystReportsDTO; +import digital.laboratory.platform.inspection.dto.SewageDataDto; +import digital.laboratory.platform.inspection.dto.TaskInfoDto; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.sewage.vo.SewageJobIdentificationMaterialVO; + +import java.time.LocalDate; +import java.io.IOException; +import java.util.List; + +/* + *@title EntrustInfoService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +public interface TaskInfoService extends IService { + + /** + * 根据目标任务的开始时间进行排序 取4个任务的id + * @param targetTask + * @return + */ + List getTaskIdByOrderStartTimeLimit4(TaskInfo targetTask); + + TaskInfo addTaskInfo(TaskInfoDto taskInfo);//添加任务信息 + TaskInfo updateTaskInfo(TaskInfo taskInfo);//修改任务信息 + Boolean deleteTaskInfo(String id);//删除任务信息 + IPage getTaskPageList(Page page, TaskInfo taskInfo,String keywords); + List getTaskList(TaskInfo taskInfo,String keywords); + Boolean checkExist(String id); + + void createUploadItem(List sampleNos); + + List createSewageReportData(String taskId, Double dailySmokingPerCapita); + + /** + * 根据污水任务检材列表和人均日吸烟 处理报表数据,最后返回数据列表 + * @param dailySmokingPerCapita + * @param voList + * @return + */ + List processSewageDataDtos(Double dailySmokingPerCapita, List voList); + +// String createSewageReportExcel(List sewageDataDtos) throws IOException; + + /** + * 导出污水专项检测毒品分析报告 + * @param dto + * @return + */ + R exportSewageAnalystReports(ExportSewageAnalystReportsDTO dto); + String createSewageReportExcel(List sewageDataDtos,String id) throws IOException; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentConditionService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentConditionService.java new file mode 100644 index 0000000..f54648e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentConditionService.java @@ -0,0 +1,42 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordInstrumentCondition; +import digital.laboratory.platform.inspection.vo.TestRecordInstrumentConditionVo; +import org.apache.commons.fileupload.FileItem; + +import java.io.File; +import java.util.List; + +public interface TestRecordInstrumentConditionService extends IService { + TestRecordInstrumentCondition addInstrumentCondition(TestRecordInstrumentCondition testRecordInstrumentCondition); + + boolean delInstrumentCondition(String id); + + TestRecordInstrumentCondition updateInstrumentCondition(TestRecordInstrumentCondition testRecordInstrumentCondition); + + TestRecordInstrumentCondition getInstrumentConditionByTestId(String id); + + + boolean useInstrumentConditionToTemplate(TestRecordArgumentDto testRecordArgumentDto); + + + List copyCondition(List idList, String testId); + + String generatedOrNot(String testId); + + boolean createConditionWordByTest(String testId) throws Exception; + + //为模板创建仪器条件word + boolean createConditionWordByTemplate(String templateId) throws Exception; + + void copyConditionWord(String templateId, String testId) throws Exception; + + boolean mergeFile(String testId) throws Exception; + + //todo:一个文件类型转换的封装方法 + FileItem getMultipartFile(File file, String fieldName); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentService.java new file mode 100644 index 0000000..41be600 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordInstrumentService.java @@ -0,0 +1,34 @@ +package digital.laboratory.platform.inspection.service; +/* + *@title TestRecordInstrumentService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 14:40 + */ + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordInstrument; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +public interface TestRecordInstrumentService extends IService { + TestRecordInstrument addTestRecordInstrument(TestRecordInstrument testRecordInstrument);//添加实验使用仪器信息 + TestRecordInstrument updateTestRecordInstrument(TestRecordInstrument testRecordInstrument);//修改实验使用仪器信息 + Boolean deleteTestRecordInstrument(String id);//删除实验使用仪器信息 + IPage getTestRecordInstrumentPageList(Page page, String testId, String keywords, Integer opCode); + + IPage getTemplateInstrumentPageList(Page page, String templateId, String keywords, Integer opCode); + + List getTestRecordInstrumentList(TestRecordInstrument testRecordInstrument); + Boolean checkExist(String id); + + boolean useTestRecordInstrument(TestRecordArgumentDto testRecordArgumentDto); + + @Transactional(rollbackFor = Exception.class) + boolean useTemplateInstrument(TestRecordArgumentDto testRecordArgumentDto); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordMethodService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordMethodService.java new file mode 100644 index 0000000..30d0010 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordMethodService.java @@ -0,0 +1,28 @@ +package digital.laboratory.platform.inspection.service; +/* + *@title TestRecordMethodService + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 14:49 + */ + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; + +import java.util.List; +public interface TestRecordMethodService extends IService { + TestRecordMethod addTestRecordMethod(TestRecordMethod testRecordMethod);//添加实验使用方法 + TestRecordMethod updateTestRecordMethod(TestRecordMethod testRecordMethod);//修改实验使用方法 + Boolean deleteTestRecordMethod(String id);//删除实验使用方法 + IPage getTestRecordMethodPageList(Page page, TestRecordMethod testRecordMethod); + List getTestRecordMethodList(TestRecordMethod testRecordMethod); + Boolean checkExist(String id); + + boolean useTestRecordMethod(TestRecordArgumentDto testRecordArgumentDto); + + boolean useTemplateMethod(TestRecordArgumentDto testRecordArgumentDto); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordReagentService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordReagentService.java new file mode 100644 index 0000000..c48ad48 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordReagentService.java @@ -0,0 +1,36 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import digital.laboratory.platform.inspection.entity.TestRecordReagent; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TestRecordReagentService + * @description + * @create 2023/12/20 11:12 + */ + +public interface TestRecordReagentService extends IService { + TestRecordReagent addTestRecordReagent(TestRecordReagent testRecordReagent);//添加实验使用方法 + TestRecordReagent updateTestRecordReagent(TestRecordReagent testRecordReagent);//修改实验使用方法 + Boolean deleteTestRecordReagent(String id);//删除实验使用方法 + IPage getTestRecordReagentPageList(Page page, String testId, String keywords, String category, Integer opCode); + List getTestRecordReagentList(String testId, String category); + + Boolean checkExist(String id); + + boolean useTestRecordReagent(TestRecordArgumentDto testRecordArgumentDto); + + @Transactional(rollbackFor = Exception.class) + boolean useTestTemplateReagent(TestRecordArgumentDto testRecordArgumentDto); + + IPage getTestTemplateReagentPageList(Page page, String templateId, String keywords, String category, Integer opCode); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java new file mode 100644 index 0000000..e7d21a8 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleDataService.java @@ -0,0 +1,162 @@ +package digital.laboratory.platform.inspection.service; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.*; +import digital.laboratory.platform.inspection.entity.TestRecordSampleData; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct; +import digital.laboratory.platform.inspection.vo.TestResultBusinessVO; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleDataService + * @description + * @create 2024/1/18 11:04 + */ + +public interface TestRecordSampleDataService extends IService { + + /** + * 校验实验状态是否完成,完成则提升不能修改数据 + * @param testId + */ + void validateTestStatus(String testId); + + //保存检验数据结果 + Boolean saveTestData(List testRecordSampleDataList); + + Boolean saveTestDataFromNps(List npsDataFileStructList,String testId); + + //获取检验记录中的样品信息数据 + List getNPSSampleTestDataByTestId(String testId); + + /** + * 根据业务id查询检验数据 + * @param businessId + * @return + */ + List getSampleTestDataByBusiness(String businessId); + + /** + * 毛发案件检验数据读取处理保存到数据库 + * + * @param hairCompoundDataMap 文件数据map + * @param testId 实验id + * @return + */ + Boolean saveTestDataHairCase(Map> hairCompoundDataMap, String testId); + + List getSampleTestDataByTestId(String testId, String type); + + /** + * 分页查询 根据实验id获取不同类型的数据 + * @param pageDTO + * @return + */ + Page getSampleTestDataByTestIdPage(AnalysisTestResultPageDTO pageDTO); + + /** + * 分页查询 获取审核的任务检验数据, header 是自定义头 data 是分页对象 + * @param pageDTO + * @return + */ + Map queryWaitApproveTaskTestDataPage(TaskTestDataPageDTO pageDTO); + + /** + * 毛发、污水任务检验数据导入并保存到数据库 + * + * @param sewageCompoundDataMap + * @param testId + * @param fileTypeCode + * @return + */ + Boolean saveTestDataHairSewageTask(Map> sewageCompoundDataMap, String testId, String fileTypeCode); + + /** + * 实验结果查询中分页查询 + * @param testResultBusinessVOPage + * @param dto + * @return + */ + IPage queryTestResultPage(Page testResultBusinessVOPage, QueryTestResultPageDTO dto, Object... arg); + + /** + * 修改导入的实验数据 + * + * @param dto + * @return + */ + JSONObject updateEntrustTestData(UpdateEntrustTestDataDTO dto); + + /** + * 获取任务实验结果数据 + * @param testId + * @return + */ + Map queryTaskTestResult(String testId); + + /** + * 根据业务id获取任务实验结果数据 + * @param businessId + * @return + */ + Map queryTaskTestResultByBusiness(String businessId); + + /** + * 保存实验数据的定量结果 + * @param dto + * @return + */ + boolean saveQuantitativeResults(SaveQuantitativeResultsDTO dto); + + /** + * 删除实验数据的定量结果 + * @param testSampleDataId + * @return + */ + boolean deleteQuantitativeResults(String testSampleDataId); + + /** + * 判断当前实验数据是否保存 + * @param testId + * @return + */ + boolean whetherSave(String testId); + + /** + * 根据业务id生成定性结果 + * @param businessId + * @return + */ + String generateQualitativeResults(String businessId); + + /** + * 完成实验 + * @param testId + * @return + */ + R finishTest(String testId); + + /** + * 审核审批数据 + * + * @param auditDataDTO + * @param httpServletRequest + * @return + */ + R auditTaskTestData(AuditDataDTO auditDataDTO, HttpServletRequest httpServletRequest); + + + //获取标准品样品信息数据 + // List getStdSampleTestDataByTestId(String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleSolutionService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleSolutionService.java new file mode 100644 index 0000000..d362302 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordSampleSolutionService.java @@ -0,0 +1,30 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordSampleSolutionDto; +import digital.laboratory.platform.inspection.entity.TestRecordSampleSolution; + +import java.util.List; + +public interface TestRecordSampleSolutionService extends IService { + TestRecordSampleSolution addTestRecordSampleSolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto); + + boolean delTestRecordSampleSolution(String id); + + TestRecordSampleSolution updateTestRecordSampleSolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto); + + List getSolutionList(String testId,String keywords); + + IPage getSolutionPage(Page page, String testId,String keywords); + + List matchingWeighing(String testId); + + boolean createTaskSamSol(String testId); + + List copySolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto); + + void isLoadSample(String acceptNo, String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java new file mode 100644 index 0000000..3f8ec0e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordService.java @@ -0,0 +1,92 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO; +import digital.laboratory.platform.inspection.dto.TestRecordDto; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspection.vo.ProcedureVo; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +public interface TestRecordService extends IService { + @Transactional + TestRecord createTestInstance(TestRecordDto testRecord, DLPUser dlpUser) throws Exception; + + TestRecord updateTestInstance(TestRecord testRecord); + + TestRecordVo getTestRecord(String id, DLPUser dlpUser); + + IPage getTestRecordPageList(Page page, DLPUser dlpUser, LocalDateTime startTime, LocalDateTime endTime, String businessType); + + ListgetTestRecordList(DLPUser dlpUser); + + boolean updateTestRecordArgument(String testId, String testRecordArgumentId, String argument,Integer opCode); + + TestRecord useTemplate(String testId, String templateId) throws Exception; + + ProcedureVo getProcedure(String testId); + + Map getPrintData(String businessId) throws Exception; + + boolean createInspectionRecordByBiological(String businessId) throws Exception; + + boolean createInspectionRecord(String businessId) throws Exception; + + @Transactional(rollbackFor = Exception.class) + boolean delTestRecord(String testId); + + Page getResultSolutionPage(Page page, String testId); + + /** + * 上传实验图谱(单个) + * @param testId + * @param file + * @return + */ + R uploadTestAtlas(String testId, MultipartFile file) throws Exception; + + /** + * 上传实验图谱(批量) + * @param testId + * @param files + * @return + */ + R uploadTestAtlasBatch(String testId, List files); + + /** + * 获取该实验id的实验图谱 + * @param testId + * @return + */ + R getTestAtlasList(String testId); + + /** + * 删除实验图谱 + * @param dto + * @return + */ + R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception; + + /** + * 根据业务id获取实验图谱 + * @param businessId + * @return + */ + R getTestAtlasListByBusinessId(String businessId); + + /** + * 根据业务id获取实验信息 + * @param businessIds + * @return + */ + R> queryTestRecordInfoByBusinessId(List businessIds); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordStandardSolutionService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordStandardSolutionService.java new file mode 100644 index 0000000..e2c8ac4 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestRecordStandardSolutionService.java @@ -0,0 +1,31 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.inspection.dto.TestRecordStandardSolutionDto; +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +public interface TestRecordStandardSolutionService extends IService { + TestRecordStandardSolution addTestRecordStandardSolution(TestRecordStandardSolutionDto testRecordStandardSolution); + + TestRecordStandardSolution addBlankSolution(String testId,Integer type); + + List createQualityControlSol(String testId); + + boolean delTestRecordStandardSolution(String id); + + TestRecordStandardSolution updateTestRecordStandardSolution(TestRecordStandardSolutionDto testRecordStandardSolutionDto); + + IPage getTestRecordStandardSolutionPage(Page page,String testId, String keywords); + + List getTestRecordStandardSolutionList(String testId, String keywords); + + @Transactional + List matchingWeighing(String testId); + + boolean detection(String testId); +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestTemplateService.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestTemplateService.java new file mode 100644 index 0000000..daebcb3 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/TestTemplateService.java @@ -0,0 +1,32 @@ +package digital.laboratory.platform.inspection.service; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.TemplateDeleteDto; +import digital.laboratory.platform.inspection.entity.TestTemplate; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; + +import java.util.List; + +public interface TestTemplateService extends IService { + TestTemplate createTemplate(TestTemplate testTemplate, String testId, DLPUser dlpUser) throws Exception; + + TestTemplate editTemplate(TestTemplate testTemplate); + + boolean delTemplate(List idList, DLPUser dlpUser); + + boolean updateTestTemplate(String templateId, String argumentId, String argument, Integer opCode); + + TestTemplateVo publishTemplate(String id); + + TestTemplateVo blockTemplate(String id); + + TestTemplateVo getTemplateById(String id); + + IPage getTemplateVoPage(Page page, Integer opCode,DLPUser dlpUser, String keywords); + + List getTemplateVoList(DLPUser dlpUser); + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/AssignmentInfoServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/AssignmentInfoServiceImpl.java new file mode 100644 index 0000000..214ee05 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/AssignmentInfoServiceImpl.java @@ -0,0 +1,501 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import digital.laboratory.platform.inspection.constant.BusinessType; +import digital.laboratory.platform.inspection.dto.AssignmentInfoDto; +import digital.laboratory.platform.inspection.entity.*; +import digital.laboratory.platform.inspection.mapper.AssignmentInfoMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspection.utils.PageUtils; +import digital.laboratory.platform.inspection.vo.AssignmentInfoVo; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/* + *@title AssignmentInfoServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/13 11:46 + */ +@Service +@Slf4j +public class AssignmentInfoServiceImpl extends ServiceImpl implements AssignmentInfoService { + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private EntrustInfoService entrustInfoService; + + @Resource + private ScreenInfoService screenInfoService; + + @Resource + private TaskInfoService taskInfoService; + + /** + * 创建分配任务信息 + * + * @param assignmentInfoDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public List addAssignmentInfo(List assignmentInfoDtoList) { + List assignmentInfos = new ArrayList<>(); + //1:通过业务 -1:通过检材 + Integer type = assignmentInfoDtoList.get(0).getType(); + //按业务进行分配 + if (type == 1) { + for (AssignmentInfoDto assignmentInfoDto : assignmentInfoDtoList) { + String businessId = assignmentInfoDto.getBusinessId(); + String businessType = assignmentInfoDto.getBusinessType(); + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId)); + if (businessType.startsWith("1")) { + List infoList = this.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, businessId)); + if (infoList != null && infoList.size() > 0 && !(infoList.get(0).getTestUser().equals(assignmentInfoDto.getTestUser()))) { + throw new RuntimeException(String.format("业务:" + infoList.get(0).getBusinessName() + "已分配给工作人员:" + infoList.get(0).getTestUserName() + ",如需继续分配,只能继续选择该工作人员,或者撤销已分配的任务后重新进分配!")); + } + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + entrustInfo.setStatus(1); + entrustInfoService.updateById(entrustInfo); + } else if (businessType.startsWith("2")) { + List infoList = this.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, businessId)); + if (infoList != null && infoList.size() > 0) { + throw new RuntimeException(String.format("业务:" + infoList.get(0).getBusinessName() + "中部分或全部检材已分配给其它工作人员,无法进行业务分配,你可以尝试点击右侧的分配检材功能继续进行分配!")); + } + TaskInfo taskInfo = taskInfoService.getById(businessId); + taskInfo.setDistributionSituation(sampleInfoList.size() + "/" + sampleInfoList.size()); + taskInfoService.updateById(taskInfo); + } else { + List infoList = this.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, businessId)); + if (infoList != null && infoList.size() > 0) { + throw new RuntimeException(String.format("业务:" + infoList.get(0).getBusinessName() + "中部分或全部检材已分配给其它工作人员,无法进行业务分配,你可以尝试点击右侧的分配检材功能继续进行分配!")); + } + ScreenInfo screenInfo = screenInfoService.getById(businessId); + screenInfo.setDistributionSituation(sampleInfoList.size() + "/" + sampleInfoList.size()); + screenInfoService.updateById(screenInfo); + } + if (CollUtil.isEmpty(sampleInfoList)) { + throw new RuntimeException("当前业务检材列表为空!不能添加分配信息。"); + } + + for (SampleInfo sampleInfo : sampleInfoList) { + AssignmentInfo assignmentInfo = new AssignmentInfo(); + BeanUtils.copyProperties(assignmentInfoDto, assignmentInfo); + assignmentInfo.setId(IdWorker.get32UUID().toUpperCase()); + assignmentInfo.setSampleId(sampleInfo.getId()); + assignmentInfo.setSampleName(sampleInfo.getSampleName()); + sampleInfo.setStatus(1); + assignmentInfos.add(assignmentInfo); + } + sampleInfoService.updateBatchById(sampleInfoList); + } + return this.saveBatch(assignmentInfos) ? assignmentInfos : null; + } else { + SampleInfo sampleInfo = sampleInfoService.getById(assignmentInfoDtoList.get(0).getSampleId()); + String businessType = sampleInfo.getBusinessType(); + String businessId = sampleInfo.getBusinessId(); + + ArrayList idList = new ArrayList<>(); + assignmentInfoDtoList.forEach(item -> idList.add(item.getSampleId())); + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId)); + List sampleInfos = sampleInfoService.list(Wrappers.lambdaQuery().in(SampleInfo::getId, idList)); + sampleInfos.forEach(item -> item.setStatus(1)); + sampleInfoService.updateBatchById(sampleInfos); + + List assignmentInfoList = this.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, businessId)); + int count = 0; + //计算分配情况 + if (assignmentInfoList != null && assignmentInfoList.size() > 0) { + count = assignmentInfoList.size() + assignmentInfoDtoList.size(); + } else { + count = assignmentInfoDtoList.size(); + } + String businessName = ""; + if (businessType.startsWith("1")) { + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + entrustInfo.setStatus(1); + businessName = entrustInfo.getCaseName(); + entrustInfoService.updateById(entrustInfo); + + } else if (businessType.startsWith("2")) { + TaskInfo taskInfo = taskInfoService.getById(businessId); + //分配情况 + taskInfo.setDistributionSituation(count + "/" + sampleInfoList.size()); + businessName = taskInfo.getTaskName(); + taskInfoService.updateById(taskInfo); + + } else { + ScreenInfo screenInfo = screenInfoService.getById(businessId); + //分配情况 + screenInfo.setDistributionSituation(count + "/" + sampleInfoList.size()); + businessName = screenInfo.getCaseName(); + screenInfoService.updateById(screenInfo); + } + for (AssignmentInfoDto assignmentInfoDto : assignmentInfoDtoList) { + AssignmentInfo assignmentInfo = new AssignmentInfo(); + BeanUtils.copyProperties(assignmentInfoDto, assignmentInfo); + assignmentInfo.setId(IdWorker.get32UUID().toUpperCase()); + assignmentInfo.setBusinessId(businessId); + assignmentInfo.setBusinessType(businessType); + assignmentInfo.setBusinessName(businessName); + assignmentInfos.add(assignmentInfo); + } + return this.saveBatch(assignmentInfos) ? assignmentInfos : null; + } + } + +// //通过业务ID创建 +// if (businessIdList != null && businessIdList.size() > 0) { +// for (String businessId : businessIdList) { +// List infoList = this.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, businessId)); +// if (infoList != null && infoList.size() > 0) { +// AssignmentInfo assignmentInfo = infoList.get(0); +// if (assignmentInfo.getBusinessType().startsWith("1") && !(assignmentInfo.getTestUser().equals(assignmentInfoDto.getTestUser()))) { +// throw new RuntimeException(String.format("业务:" + assignmentInfo.getBusinessName() + "已分配给工作人员:" + assignmentInfo.getTestUserName() + ",如需继续分配,只能继续选择该工作人员,或者撤销已分配的任务后重新进分配!")); +// } +// if (!assignmentInfo.getBusinessType().startsWith("1")) { +// throw new RuntimeException(String.format("业务:" + assignmentInfo.getBusinessName() + "中部分或全部检材已分配给其它工作人员,无法进行业务分配,你可以尝试点击右侧的分配检材功能继续进行分配!")); +// } +// } +// List list = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId).eq(SampleInfo::getStatus, 0)); +// String businessName = ""; +// String status = ""; +// status = "分配情况:" + sampleInfoList.size() + "/" + sampleInfoList.size(); +// if (businessType.startsWith("1")) { +// EntrustInfo entrustInfo = entrustInfoService.getById(businessId); +// businessName = entrustInfo.getCaseName(); +// entrustInfo.setStatus(1); +// } else if (businessType.startsWith("3")) { +// ScreenInfo screenInfo = screenInfoService.getById(businessId); +// screenInfo.setStatus(status); +// businessName = screenInfo.getCaseName(); +// } else { +// TaskInfo taskInfo = taskInfoService.getById(businessId); +// businessName = taskInfo.getTaskName(); +// taskInfo.setStatus(status); +// } +// for (SampleInfo sampleInfo : list) { +// AssignmentInfo assignmentInfo = new AssignmentInfo(); +// BeanUtils.copyProperties(assignmentInfoDto, assignmentInfo); +// assignmentInfo.setId(IdWorker.get32UUID().toUpperCase()); +// assignmentInfo.setSampleId(sampleInfo.getId()); +// assignmentInfo.setSampleName(sampleInfo.getSampleName()); +// assignmentInfo.setBusinessId(businessId); +// assignmentInfo.setBusinessName(businessName); +// assignmentInfo.setBusinessType(sampleInfo.getBusinessType()); +// sampleInfo.setStatus(1); +// assignmentInfoList.add(assignmentInfo); +// sampleInfoList.add(sampleInfo); +// } +// +// sampleInfoList.addAll(sampleInfoList); +// } +// //通过样本ID创建 +// } else if (sampleIdList != null && sampleIdList.size() > 0) { +// SampleInfo sample = sampleInfoService.getById(sampleIdList.get(0)); +// String businessId = sample.getBusinessId(); +// +// for (String sampleId : sampleIdList) { +// SampleInfo sampleInfo = sampleInfoService.getById(sampleId); +// String businessName = ""; +// String status = ""; +// if (businessType.equals("筛查检验鉴定")) { +// ScreenInfo screenInfo = screenInfoService.getById(sampleInfo.getBusinessId()); +// businessName = screenInfo.getCaseName(); +// } else { +// TaskInfo taskInfo = taskInfoService.getById(sampleInfo.getBusinessId()); +// businessName = taskInfo.getTaskName(); +// } +// AssignmentInfo assignmentInfo = new AssignmentInfo(); +// BeanUtils.copyProperties(assignmentInfoDto, assignmentInfo); +// assignmentInfo.setId(IdWorker.get32UUID().toUpperCase()); +// assignmentInfo.setSampleId(sampleInfo.getId()); +// assignmentInfo.setSampleName(sampleInfo.getSampleName()); +// assignmentInfo.setBusinessName(businessName); +// assignmentInfo.setBusinessId(sampleInfo.getBusinessId()); +// assignmentInfo.setBusinessType(sampleInfo.getBusinessType()); +// sampleInfo.setStatus(1); +// assignmentInfoList.add(assignmentInfo); +// sampleInfoList.add(sampleInfo); +// } +// } else { +// throw new RuntimeException(String.format("至少传入一种类型的ID数组")); +// } +// if (this.saveBatch(assignmentInfoList) && sampleInfoService.updateBatchById(sampleInfoList)) { +// return assignmentInfoList; +// } else { +// return null; +// } +// } + + /** + * 撤销分配任务 + * + * @param assignmentInfoList + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean cancelAssignmentInfo(List assignmentInfoList) { + List sampleInfos = new ArrayList<>(); + for (AssignmentInfo assignmentInfo : assignmentInfoList) { + SampleInfo sampleInfo = sampleInfoService.getById(assignmentInfo.getSampleId()); + if (sampleInfo.getStatus() == 2) { + throw new RuntimeException(String.format("已使用检材%s进行实验,无法撤销!", sampleInfo.getSampleName())); + } + sampleInfo.setStatus(0); + sampleInfos.add(sampleInfo); + } + return this.removeBatchByIds(assignmentInfoList) && sampleInfoService.updateBatchById(sampleInfos); + } + + /** + * 删除分配任务 + * + * @param id + * @return + */ + @Override + public Boolean deleteAssignmentInfo(String id) { + return this.removeById(id); + } + + /** + * 分页查询 + * + * @param page + * @param assignmentInfoDto + * @return + */ + @Override + public IPage getAssignmentInfoPageList(Page page, AssignmentInfoDto assignmentInfoDto) { + //查询参数:可以是业务名称、样本名称、分配者姓名、接收者姓名 + String keywords = assignmentInfoDto.getKeywords(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery().and(StringUtils.isNotBlank(keywords), queryWrapper -> queryWrapper + .like(AssignmentInfo::getBusinessName, keywords) + .or() + .like(AssignmentInfo::getSampleName, keywords) + .or() + .like(AssignmentInfo::getAssignUserName, keywords) + .or() + .like(AssignmentInfo::getTestUserName, keywords)) + .eq(StringUtils.isNotBlank(assignmentInfoDto.getAssignUser()), AssignmentInfo::getAssignUser, assignmentInfoDto.getAssignUser()) + .eq(StringUtils.isNotBlank(assignmentInfoDto.getTestUser()), AssignmentInfo::getTestUser, assignmentInfoDto.getTestUser()) + //这里前端由于无法一次性传入两个type,所以通过前缀来分类查询,例如2: 查询污水与毛发任务 + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("1"), AssignmentInfo::getBusinessType, 1) + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("2"), AssignmentInfo::getBusinessType, 2) + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("3"), AssignmentInfo::getBusinessType, 3) + .orderByDesc(AssignmentInfo::getCreateTime); + + if (StringUtils.isNotBlank(assignmentInfoDto.getTestUser())) {//检验人员查看我的待办 + List retList = this.list(wrapper); + Map> map = retList.stream().collect(Collectors.groupingBy(obj -> obj.getBusinessId())); + List assignmentInfoVos = new ArrayList<>(); + Set keySet = map.keySet(); + for (String key : keySet) { + List assignmentInfos = map.get(key); + AssignmentInfoVo assignmentInfoVo = new AssignmentInfoVo(); + BeanUtils.copyProperties(map.get(key).get(0), assignmentInfoVo); + assignmentInfoVo.setSampleId(""); + assignmentInfoVo.setSampleName(""); + List sampleInfos = new ArrayList<>(); + for (AssignmentInfo info : assignmentInfos) { + SampleInfo sampleInfo = sampleInfoService.getById(info.getSampleId()); + if (sampleInfo.getStatus() == 1) { + sampleInfos.add(sampleInfo); + } + } + assignmentInfoVo.setSampleInfoList(sampleInfos); + if (sampleInfos.size() > 0) { + assignmentInfoVos.add(assignmentInfoVo); + } + } + return new PageUtils().getPages(page.getCurrent(), page.getSize(), assignmentInfoVos); + } else { + //管理者查看所有分配信息 + IPage ret = this.page(page, wrapper); + List records = ret.getRecords(); + records.forEach(item -> { + item.setBusinessTypeName(BusinessType.getBusinessTypeName(item.getBusinessType())); + }); + return ret; + } + } + + /** + * 列表查询 + * + * @param assignmentInfoDto + * @return + */ + @Override + public List getAssignmentInfoList(AssignmentInfoDto assignmentInfoDto) { + //查询参数:可以是业务名称、样本名称、分配者姓名、接收者姓名 + String keywords = assignmentInfoDto.getKeywords(); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery().and(StringUtils.isNotBlank(keywords), queryWrapper -> queryWrapper + .like(AssignmentInfo::getBusinessName, keywords) + .or() + .like(AssignmentInfo::getSampleName, keywords) + .or() + .like(AssignmentInfo::getAssignUserName, keywords) + .or() + .like(AssignmentInfo::getTestUserName, keywords)) + .eq(StringUtils.isNotBlank(assignmentInfoDto.getAssignUser()), AssignmentInfo::getAssignUser, assignmentInfoDto.getAssignUser()) + .eq(StringUtils.isNotBlank(assignmentInfoDto.getTestUser()), AssignmentInfo::getTestUser, assignmentInfoDto.getTestUser()) + //这里前端由于无法一次性传入两个type,所以通过前缀来分类查询,例如2: 查询污水与毛发任务 + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("1"), AssignmentInfo::getBusinessType, 1) + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("2"), AssignmentInfo::getBusinessType, 2) + .likeRight(StringUtils.isNotBlank(assignmentInfoDto.getBusinessType()) && assignmentInfoDto.getBusinessType().startsWith("3"), AssignmentInfo::getBusinessType, 3) + .orderByDesc(AssignmentInfo::getCreateTime); + + if (StringUtils.isNotBlank(assignmentInfoDto.getTestUser())) {//检验人员查看我的待办 + List retList = this.list(wrapper); + Map> map = retList.stream().collect(Collectors.groupingBy(obj -> obj.getBusinessId())); + List assignmentInfoVos = new ArrayList<>(); + Set keySet = map.keySet(); + for (String key : keySet) { + List assignmentInfos = map.get(key); + String businessType = assignmentInfos.get(0).getBusinessType(); + AssignmentInfoVo assignmentInfoVo = new AssignmentInfoVo(); + BeanUtils.copyProperties(map.get(key).get(0), assignmentInfoVo); + assignmentInfoVo.setBusinessTypeName(BusinessType.getBusinessTypeName(businessType)); + assignmentInfoVo.setSampleId(""); + assignmentInfoVo.setSampleName(""); + List sampleInfos = new ArrayList<>(); + for (AssignmentInfo info : assignmentInfos) { + SampleInfo sampleInfo = sampleInfoService.getById(info.getSampleId()); + if (sampleInfo.getStatus() == 1) { + sampleInfos.add(sampleInfo); + } + } + if (sampleInfos.size() > 0) { + Collections.sort(sampleInfos, new Comparator() { + @Override + public int compare(SampleInfo o1, SampleInfo o2) { + return o1.getAcceptNo().compareTo(o2.getAcceptNo()); + } + }); + } + sampleInfos.forEach(o -> o.setBusinessTypeName(BusinessType.getBusinessTypeName(o.getBusinessType()))); + assignmentInfoVo.setSampleInfoList(sampleInfos); + if (sampleInfos.size() > 0) { + assignmentInfoVos.add(assignmentInfoVo); + } + } + return assignmentInfoVos; + } else { + //管理者查看所有分配信息 + List list = this.list(wrapper); + for (AssignmentInfo assignmentInfo : list) { + assignmentInfo.setBusinessTypeName(BusinessType.getBusinessTypeName(assignmentInfo.getBusinessType())); + } + return list; + } + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(AssignmentInfo::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + /** + * 批量撤销类别为委托的分配任务信息 + * + * @param businessIdList + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean cancelByBusiness(List businessIdList) { + ArrayList sampleInfos = new ArrayList<>(); + businessIdList.forEach(item -> { + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, item)); + if (sampleInfoList.get(0).getBusinessType().startsWith("1")) { + EntrustInfo entrustInfo = entrustInfoService.getById(item); + entrustInfo.setStatus(0); + entrustInfoService.updateById(entrustInfo); + } + sampleInfoList.forEach(obj -> { + if (obj.getStatus() == 2) { + throw new RuntimeException(String.format("已使用检材%s进行实验,无法撤销!", obj.getSampleName())); + } + obj.setStatus(0); + sampleInfos.add(obj); + }); + }); + return this.remove(Wrappers.lambdaQuery().in(AssignmentInfo::getBusinessId, businessIdList)) && sampleInfoService.updateBatchById(sampleInfos); + } + + /** + * 查询类别为委托的已分配任务列表 + * + * @param page + * @param keywords 接收者名、业务名 + * @return + */ + @Override + public IPage getAssignedEntrustPage(Page page, String keywords) { + ArrayList assignmentInfoVos = new ArrayList<>(); + List assignmentInfoList = this.list(Wrappers.lambdaQuery() + .and(StringUtils.isNotBlank(keywords), queryWrapper -> queryWrapper + .like(AssignmentInfo::getTestUserName, keywords) + .or() + .like(AssignmentInfo::getBusinessName, keywords)) + .and(queryWrapper -> queryWrapper + .eq(AssignmentInfo::getBusinessType, "10001") + .or() + .eq(AssignmentInfo::getBusinessType, "10002"))); + Map> map = assignmentInfoList.stream().collect(Collectors.groupingBy(item -> item.getBusinessId())); + Set keySet = map.keySet(); + //按业务分个组~~~ + keySet.forEach(key -> { + List infoList = map.get(key); + + AssignmentInfoVo assignmentInfoVo = new AssignmentInfoVo(); + BeanUtils.copyProperties(infoList.get(0), assignmentInfoVo); + assignmentInfoVo.setSampleCount(infoList.size()); + assignmentInfoVo.setSampleName(""); + assignmentInfoVo.setSampleId(""); + assignmentInfoVo.setBusinessTypeName(BusinessType.getBusinessTypeName(infoList.get(0).getBusinessType())); + /*if (infoList.get(0).getBusinessType().equals("10001")) { + assignmentInfoVo.setBusinessTypeName("NPS案件"); + } else { + assignmentInfoVo.setBusinessTypeName("生物样本案件"); + }*/ + assignmentInfoVos.add(assignmentInfoVo); + }); + //按时间排个序~~~ + Collections.sort(assignmentInfoVos, new Comparator() { + @Override + public int compare(AssignmentInfoVo o1, AssignmentInfoVo o2) { + return o1.getCreateTime().compareTo(o2.getCreateTime()); + } + }); + return new PageUtils().getPages(page.getCurrent(), page.getSize(), assignmentInfoVos); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/EntrustInfoServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/EntrustInfoServiceImpl.java new file mode 100644 index 0000000..25492b5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/EntrustInfoServiceImpl.java @@ -0,0 +1,184 @@ +package digital.laboratory.platform.inspection.service.impl; + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.dto.EntrustInfoDto; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspection.mapper.EntrustInfoMapper; +import digital.laboratory.platform.inspection.service.AssignmentInfoService; +import digital.laboratory.platform.inspection.service.EntrustInfoService; +import digital.laboratory.platform.inspection.service.SampleInfoService; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/* + *@title EntrustInfoServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/7 15:31 + */ +@Service +@Slf4j +public class EntrustInfoServiceImpl extends ServiceImpl implements EntrustInfoService { + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private AssignmentInfoService assignmentInfoService; + + @Override + @Transactional(rollbackFor = Exception.class) + public EntrustInfo addEntrustInfo(EntrustInfoDto entrustInfo) { + List materialList = entrustInfo.getMaterialList(); + + if (StringUtils.isBlank(entrustInfo.getId())) { + entrustInfo.setId(IdWorker.get32UUID()); + log.info("保存对象entrustInfo的ID为空,由系统生成一个给它使用 {}", entrustInfo.getId()); + } + if (entrustInfo.getMaterialType().equals("1")) { + entrustInfo.setBusinessType("10002"); + } else if (entrustInfo.getMaterialType().equals("0")) { + entrustInfo.setBusinessType("10001"); + } + //读取检材信息 + if (materialList != null && materialList.size() > 0) { + ArrayList sampleInfos = new ArrayList<>(); + for (MaterialDto material : materialList) { + SampleInfo sampleInfo = new SampleInfo(); + sampleInfoService.copy(sampleInfo, material, 0); + sampleInfo.setBusinessId(entrustInfo.getId()); + sampleInfo.setBusinessType(entrustInfo.getBusinessType()); + sampleInfos.add(sampleInfo); + } + sampleInfoService.saveBatch(sampleInfos); + } + entrustInfo.setStatus(0); + boolean ret = this.save(entrustInfo); + if (ret) { + log.info("{} 保存成功", entrustInfo); + return entrustInfo; + } else { + log.info("{} 保存失败", entrustInfo); + return null; + } + } + + @Override + public EntrustInfo updateEntrustInfo(EntrustInfo entrustInfo) { + if (entrustInfo.getSource() == 0) { + throw new RuntimeException(String.format("数据是其他系统推送录入的,不能修改")); + } + boolean ret = this.updateById(entrustInfo); + if (ret) { + return entrustInfo; + } else { + return null; + } + } + + @Override + public Boolean deleteEntrustInfo(String id) { + List assignmentInfoList = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, id)); + if (assignmentInfoList.size() > 0) { + throw new RuntimeException(String.format("当前业务已被分配,无法删除!")); + } + return this.removeById(id); + } + + @Override + public IPage getEntrustPageList(Page page, Integer status, EntrustInfo entrustInfo, String keywords) { + IPage ret = this.page(page, Wrappers.lambdaQuery() + .and(StringUtils.isNotBlank(keywords), qw -> qw.like(EntrustInfo::getAcceptNo, keywords).or() + .like(EntrustInfo::getCaseName, keywords)) + .eq(StringUtils.isNotBlank(entrustInfo.getAcceptNo()), EntrustInfo::getAcceptNo, entrustInfo.getAcceptNo()) + .eq(StringUtils.isNotBlank(entrustInfo.getEntrustDepartment()), EntrustInfo::getEntrustDepartment, entrustInfo.getEntrustDepartment()) + .eq(entrustInfo.getSource() != null, EntrustInfo::getSource, entrustInfo.getSource()) + .eq(StringUtils.isNotBlank(entrustInfo.getId()), EntrustInfo::getId, entrustInfo.getId()) + .like(StringUtils.isNotBlank(entrustInfo.getCaseName()), EntrustInfo::getCaseName, entrustInfo.getCaseName()) + .eq(entrustInfo.getStatus() != null, EntrustInfo::getStatus, status) + .orderByDesc(EntrustInfo::getCreateTime)); + List records = ret.getRecords(); + for (EntrustInfo info : records) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + if (info.getBusinessType().equals("10001")) { + info.setBusinessTypeName("缴获物案件"); + } else { + info.setBusinessTypeName("生物样本案件"); + } + } + return ret; + } + + @Override + public List getEntrustList(EntrustInfo entrustInfo) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(StringUtils.isNotBlank(entrustInfo.getAcceptNo()), EntrustInfo::getAcceptNo, entrustInfo.getAcceptNo()) + .eq(StringUtils.isNotBlank(entrustInfo.getEntrustDepartment()), EntrustInfo::getEntrustDepartment, entrustInfo.getEntrustDepartment()) + .eq(entrustInfo.getSource() != null, EntrustInfo::getSource, entrustInfo.getSource()) + .like(StringUtils.isNotBlank(entrustInfo.getCaseName()), EntrustInfo::getCaseName, entrustInfo.getCaseName()) + .eq(StringUtils.isNotBlank(entrustInfo.getId()), EntrustInfo::getId, entrustInfo.getId()) + .orderByDesc(EntrustInfo::getUpdateTime)); + for (EntrustInfo info : retList) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + if (info.getBusinessType().equals("10001")) { + info.setBusinessTypeName("NPS案件"); + } else { + info.setBusinessTypeName("生物样本案件"); + } + } + return retList; + } + + /** + * 如果存在,返回true,否则返回false + * + * @param id + * @return + */ + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(EntrustInfo::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + //检查是否具有重复的编号 + @Override + public boolean checkRepeatNo(String accept, String id) { + if (StringUtils.isNotBlank(id)) { + return true; + } + EntrustInfo entrustInfo = this.getOne(Wrappers.lambdaQuery().eq(EntrustInfo::getAcceptNo, accept)); + return entrustInfo == null ? true : false; + } + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/IdentifyBookDataServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/IdentifyBookDataServiceImpl.java new file mode 100644 index 0000000..1a9b139 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/IdentifyBookDataServiceImpl.java @@ -0,0 +1,346 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.entity.*; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspetion.api.entity.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author xy + * @version 1.0 + * @title IdentifyBookDataServiceImpl + * @description + * @create 2024/3/13 11:09 + */ +@Service +@Slf4j +public class IdentifyBookDataServiceImpl implements IdentifyBookDataService { + @Resource + private TestRecordService testRecordService;//实验记录 + @Resource + private EntrustInfoService entrustInfoService;//委托信息 + @Resource + private SampleInfoService sampleInfoService;//检材信息 + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService;//样本溶液的service + @Resource + private TestRecordStandardSolutionService testRecordStandardSolutionService;//标准溶液的service + @Resource + private TestRecordSampleDataService testRecordSampleDataService;//检验数据 + @Resource + private TestRecordMethodService testRecordMethodService;//检验方法 + + /** + * 获取完成实验的数据/获取符合制作文书的数据 + * @return + */ + @Override + public R getTestFinishBusinessData(List synedIdList) { + List entrustInfoList = entrustInfoService.list(Wrappers.lambdaQuery() + .ge(EntrustInfo::getStatus, 3) + .notIn(CollectionUtils.isNotEmpty(synedIdList),EntrustInfo::getId,synedIdList)); + if (CollUtil.isNotEmpty(entrustInfoList)) { + Map> sampleGroupByBusinessId = sampleInfoService + .list(Wrappers.lambdaQuery() + .in(SampleInfo::getBusinessId, + entrustInfoList + .stream() + .map(EntrustInfo::getId) + .collect(Collectors.toList()))) + .stream() + .collect(Collectors.groupingBy(SampleInfo::getBusinessId)); + for (EntrustInfo entrustInfo : entrustInfoList) { + List sampleInfos = sampleGroupByBusinessId.get(entrustInfo.getId()); + entrustInfo.setMaterialNum(sampleInfos.size()); + } + } + return R.ok(entrustInfoList,"获取数据成功"); + } + /** + * 获取文书的数据 + * @param businessId + * @return + */ + @Override + public R getIdentifyBookDataByBusinessId(String businessId) { + //一个委托案件,只能属于一个实验,不允许一个委托中的检材分配到2个实验中做实验,这个是前提 + if(ObjectUtils.isNotEmpty(businessId)){ + IdentificationBookDTO identificationBookDTO = buildBookDataDetail(businessId); + return R.ok(identificationBookDTO,"构建数据成功"); + }else { + log.info("参数业务id不能为空,请检查参数{}",businessId); + return R.failed("参数业务id不能为空,请检查参数"+businessId); + } + } + //构建文书数据 + private IdentificationBookDTO buildBookDataDetail(String businessId){ + IdentificationBookDTO bookData=new IdentificationBookDTO(); + //委托信息 + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + bookData.setEntrustInfo(entrustInfo); + //检材 + List sampleList= sampleInfoService.list(Wrappers.lambdaQuery() + .eq(SampleInfo::getBusinessId, businessId).orderByAsc(SampleInfo::getAcceptNo)); + bookData.setSampleInfoList(sampleList); + + //设置检验结果 + List testRecordSampleSolutionList = getTestRecordSampleSolution(sampleList);//样本溶液 + List testRecordSampleDataList = getTestRecordSampleData(sampleList);//样本溶液对应的数据 + List testResultsList = buildTestResult(testRecordSampleDataList, testRecordSampleSolutionList, sampleList);//构建检验结果 + TestRecord testRecordInfo = getTestRecordInfo(testRecordSampleSolutionList); + //实验信息 + bookData.setTestMethod(getTestMethods(testRecordSampleSolutionList));//设置用到的实验方法 + //设置检验过程 + bookData.setTestProcessDes(testRecordInfo.getTestProcessDes());//设置检验过程 + bookData.setTestResult(testRecordSampleDataService.generateQualitativeResults(businessId)); + //bookData.setTestResult(buildTestResultDes(testResultsList));//检验结果 + //检验日期 + + DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); + bookData.setTestStartDate(sdf.format(testRecordInfo.getCreateTime())); + bookData.setTestOptUser(testRecordInfo.getTestUserId()); + bookData.setTestFinishDate(sdf.format(testRecordInfo.getUpdateTime())); + return bookData; + } + //获取业务的实验对象 + private TestRecord getTestRecordInfo(List testRecordSampleSolutionList){ + List testIdList= testRecordSampleSolutionList.stream().map(s -> s.getTestId()).collect(Collectors.toList()); + List distinctTestId= testIdList.stream().distinct().collect(Collectors.toList());//去重复 + if(distinctTestId.size()!=1){ + throw new RuntimeException("一个案件中的检材只能允许分配到一个实验中去做"); + } + String testId= distinctTestId.get(0); + TestRecord testRecord= testRecordService.getById(testId); + return testRecord; + } + //获取实验方法 + private String getTestMethods(List testRecordSampleSolutionList){ + TestRecord testRecordInfo= getTestRecordInfo(testRecordSampleSolutionList); + List testMethodList= testRecordInfo.getTestMethodList(); + List methodsList = testRecordMethodService.list(Wrappers.lambdaQuery() + .in(TestRecordMethod::getId, testMethodList)); + List methodsName = methodsList.stream().map(s -> s.getMethodName()).collect(Collectors.toList()); + StringBuffer sbMethodNameStr=new StringBuffer(); + methodsName.forEach(item->{ + sbMethodNameStr.append(item).append(","); + }); + sbMethodNameStr.delete(sbMethodNameStr.length()-1,sbMethodNameStr.length()); + return sbMethodNameStr.toString(); + } + //获取sampleData + private List getTestRecordSampleData(List sampleInfoList){ + List testRecordSampleSolution = getTestRecordSampleSolution(sampleInfoList); + if (CollUtil.isNotEmpty(testRecordSampleSolution)) { + List sampleNoList= testRecordSampleSolution.stream().map(m -> m.getSampleNo()).collect(Collectors.toList());//得到样本溶液编号 + //根据样本溶液编号查出对应的样本溶液检验数据 + List sampleTestDataList= getTestRecordData(sampleNoList); + return sampleTestDataList; + } + + return null; + } + //获取样本溶液 + private List getTestRecordSampleSolution( List sampleInfoList){ + List materialIdList= sampleInfoList.stream().map(m -> m.getId()).collect(Collectors.toList()); + if (CollUtil.isEmpty(materialIdList)) { + log.error("检材列表为空!"); + return null; + } + //查出对应的样本溶液 + List sampleSolutionList = testRecordSampleSolutionService.list(Wrappers.lambdaQuery() + .in(TestRecordSampleSolution::getMaterialId, materialIdList)); + return sampleSolutionList; + } + //构建TestResult + private List buildTestResult(List testRecordSampleDataList, + List testRecordSampleSolutionList,List sampleInfoList){ + //结果:应该是加入实验的检材的结果,目前暂定受理的检材我们按照受理顺序,全部定义为 1号检材,2号检材,3号检材等 + //拿出实验数据中的所有实验样本编号,就是数据文件中的sampleId,也是溶液编号中的溶液编号, + List sampleNoList= testRecordSampleDataList.stream().map(s -> s.getSampleNo()).collect(Collectors.toList()); + //取出检材ID + List okTestRecordSampleSolutionIdList=new ArrayList<>(); + testRecordSampleSolutionList.forEach(item->{ + //如果溶液在提供的溶液编号中,则取出来 + if(sampleNoList.contains(item.getSampleNo())){ + okTestRecordSampleSolutionIdList.add(item.getMaterialId()); + } + }); + List retTestResult=new ArrayList<>(); + for (TestRecordSampleData testRecordSampleData : testRecordSampleDataList) { + TestResult eg=new TestResult(); + SampleInfo sampleInfo=getSampleInfoBySampleId(testRecordSampleSolutionList, + sampleInfoList,testRecordSampleData.getSampleNo()); + eg.setCompoundName(testRecordSampleData.getCompoundName()); + eg.setMaterialNo(sampleInfo.getOrderNo()+"号"); + eg.setOrderNo(sampleInfo.getOrderNo()); + eg.setIsFind(testRecordSampleData.getIsDetected()); + eg.setTestId(testRecordSampleData.getTestId()); + retTestResult.add(eg); + } + return retTestResult; + } + //根据sampleID获取对应的检材信息 + private SampleInfo getSampleInfoBySampleId(List testRecordSampleSolutionList, + List sampleInfoList,String sampleId){ + List sampleSolutionList = testRecordSampleSolutionList.stream() + .filter(s -> s.getSampleNo().equals(sampleId)).collect(Collectors.toList()); + String materialId=""; + if(sampleSolutionList.size()>0){ + if(sampleSolutionList.size()>1){ + log.info("溶液编号重复 {} ",sampleId); + }else{ + materialId= sampleSolutionList.get(0).getMaterialId(); + } + } + List retObj=new ArrayList<>(); + for (SampleInfo sampleInfo : sampleInfoList) { + if(sampleInfo.getId().equals(materialId)){ + //找到 + retObj.add(sampleInfo); + } + } + if(retObj.size()!=1){ + log.info("存在重复的检材"); + return null; + } + if(retObj.size()==0){ + log.info("未查询到检材"); + return null; + }else { + return retObj.get(0); + } + } + //构建实验结果 + private List buildTestResultDes(List resultList){ + //按照检材编号先分组,这样的话,如果有n个检材,m个化合物,那么就会分成n组,每组中就m条数据 + Map> resultMap1 = resultList.stream().collect(Collectors.groupingBy(m -> m.getMaterialNo())); + //我们把每组中的List 数据再次分组,分组按检出和未检出分,这样就会得到2个组,一个组是检出的,一个组是未检出的 + Map>> resultMap2=new HashMap<>(); + resultMap1.forEach((k,v)->{ + //按检材编号分组,分成检出和未检出2组 + Map> tmp1Map= v.stream().collect(Collectors.groupingBy(m -> m.getIsFind())); + resultMap2.put(k,tmp1Map);//1号 检出 与未检出 + }); + // 对 resultMap2进行合并,然后再次分组 + List testResultDetailList=new ArrayList<>(); + resultMap2.forEach((k,v)->{ + Map> tmp2Map=v;//这个map中只有2个key,key为0代表未检出的集合,key为1表示检出的集合 + TestResultDetail testResultDetail= buildCompoundList(tmp2Map, k); + testResultDetailList.add(testResultDetail); + }); + // 对 testResultDetailList 进行 分组 + //现在对上面的数据进行从新分组,按检出+化合物的形式 + Map> temp2 = testResultDetailList.stream().collect( + Collectors.groupingBy(m -> m.getFindCompounds() + m.getNoFindCompounds())); + List testResultDes= testResultSorted(temp2); + return testResultDes; + } + //对第一个结果进行排序 + private List testResultSorted(Map> tmpMap){ + List>> targetList=new ArrayList>>(tmpMap.entrySet()); + targetList.sort(new Comparator>>() { + @Override + public int compare(Map.Entry> mp1, Map.Entry> mp2) { + int materialNo1 = getMinMaterialNo(mp1.getValue()); + int materialNo2 = getMinMaterialNo(mp2.getValue()); + return materialNo1-materialNo2; + } + }); + List testResultDes=new ArrayList<>(); + targetList.forEach((target)->{ + StringBuffer sbNo=new StringBuffer(); + target.getValue().forEach(item->{ + sbNo.append(item.getMaterialNo()).append(","); + }); + if(sbNo.length()>0){ + sbNo.delete(sbNo.length()-1,sbNo.length());//删除最后一个 , + } + testResultDes.add(sbNo.toString()+"检材未检出"+target.getValue().get(0).getNoFindCompounds()+",检出了"+target.getValue().get(0).getFindCompounds()); + }); + return testResultDes; + } + /** + * 构造出一个检材一共检出了多少个化合物和未检出多少化合物 + * @param mapCompound + * @param materialNo + * @return + */ + private TestResultDetail buildCompoundList(Map> mapCompound,String materialNo){ + + StringBuffer findCompounds=new StringBuffer();//检出化合物的集合 + StringBuffer noFindCompounds=new StringBuffer();//未检出化合物的集合 + mapCompound.forEach((k1,v1)->{ + if(k1==0){ + //未检出 + v1.forEach(item->{ + noFindCompounds.append(item.getCompoundName()).append(","); + }); + } + if(k1==1){ + //检出 + v1.forEach(item->{ + findCompounds.append(item.getCompoundName()).append(","); + }); + } + }); + if(findCompounds.length()>0){ + findCompounds.delete(findCompounds.length()-1,findCompounds.length());//删除最后一个 , + } + if(noFindCompounds.length()>0){ + noFindCompounds.delete(noFindCompounds.length()-1,noFindCompounds.length());//删除最后一个 , + } + TestResultDetail eg=new TestResultDetail(); + eg.setMaterialNo(materialNo); + eg.setFindCompounds(findCompounds.toString()); + eg.setNoFindCompounds(noFindCompounds.toString()); + return eg; + } + + private int getMinMaterialNo(List materialList){ + materialList.sort(new Comparator() { + @Override + public int compare(TestResultDetail t1, TestResultDetail t2) { + int mNo1= Integer.parseInt(getNumberByMaterialNo(t1.getMaterialNo())); + int mNo2= Integer.parseInt(getNumberByMaterialNo(t2.getMaterialNo())); + return mNo1-mNo2; + } + }); + return Integer.parseInt(getNumberByMaterialNo(materialList.get(0).getMaterialNo())); + } + + /** + * 根据编号获取排序值 + * @param materialNo + * @return + */ + private String getNumberByMaterialNo(String materialNo){ + Pattern pattern = Pattern.compile("\\d+"); + Matcher matcher = pattern.matcher(materialNo); + while (matcher.find()) { + return matcher.group(0); + } + return ""; + } + /** + * 根据溶液编号(sampleNo)获取仪器检测数据 + * @param sampleNoList + * @return + */ + private List getTestRecordData(List sampleNoList){ + return testRecordSampleDataService.list(Wrappers.lambdaQuery() + .in(TestRecordSampleData::getSampleNo, sampleNoList)); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInfoServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInfoServiceImpl.java new file mode 100644 index 0000000..cdcd571 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInfoServiceImpl.java @@ -0,0 +1,395 @@ +package digital.laboratory.platform.inspection.service.impl; +/* + *@title SampleInfoServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:10 + */ + +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.*; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.SampleInfoMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspetion.api.entity.*; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.sys.entity.DrugLite; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +@Service +@Slf4j +public class SampleInfoServiceImpl extends ServiceImpl implements SampleInfoService { + + @Resource + private AssignmentInfoService assignmentInfoService; + @Resource + private TestRecordService testRecordService; + @Resource + private TestRecordMapper testRecordMapper; + + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService; + @Resource + private TestRecordSampleDataService testRecordSampleDataService; + + @Resource + @Lazy + private EntrustInfoService entrustInfoService; + + @Override + @Transactional(rollbackFor = Exception.class) + public SampleInfo addSampleInfo(SampleInfo sampleInfo) { + if (StringUtils.isBlank(sampleInfo.getId())) { + sampleInfo.setId(IdWorker.get32UUID()); + log.info("保存对象sampleInfo的ID为空,由系统生成一个给它使用 {}", sampleInfo.getId()); + } + List sampleInfos = new ArrayList<>(); + if (sampleInfo.getBusinessType().startsWith("1")) { + EntrustInfo entrustInfo = entrustInfoService.getById(sampleInfo.getBusinessId()); + sampleInfos = this.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, sampleInfo.getBusinessId()).orderByAsc(SampleInfo::getOrderNo)); + //鉴定要求与顺序号 + if (sampleInfos != null && sampleInfos.size() > 0) { + sampleInfos.add(sampleInfo); + sampleInfo.setOrderNo(sampleInfos.size()); + entrustInfo.setEntrustRequirement(this.getNameDesStrForEntrust(sampleInfos)); + } else { + sampleInfos.add(sampleInfo); + sampleInfo.setOrderNo(1); + entrustInfo.setEntrustRequirement(this.getNameDesStrForEntrust(sampleInfos)); + } + entrustInfoService.updateById(entrustInfo); + } + sampleInfo.setStatus(0); + boolean ret = this.save(sampleInfo); + if (ret) { + log.info("{} 保存成功", sampleInfo); + return sampleInfo; + } else { + log.info("{} 保存失败", sampleInfo); + return null; + } + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public SampleInfo updateSampleInfo(SampleInfo sampleInfo) { + if (sampleInfo.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + return null; + } + if (sampleInfo.getBusinessType().startsWith("1")) { + EntrustInfo entrustInfo = entrustInfoService.getById(sampleInfo.getBusinessId()); + List sampleInfoList = this.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, sampleInfo.getBusinessId())); + //鉴定要求 + entrustInfo.setEntrustRequirement(this.getNameDesStrForEntrust(sampleInfoList)); + entrustInfoService.updateById(entrustInfo); + } + boolean ret = this.updateById(sampleInfo); + if (ret) { + return sampleInfo; + } else { + return null; + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteSampleInfo(String id) { + SampleInfo sampleInfo = this.getById(id); + if (sampleInfo.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + throw new RuntimeException(String.format("数据是其他系统推送录入的,不能修改")); + } + //查询顺序号大于被删除的全部检材 + List sampleInfoList = this.list(Wrappers.lambdaQuery() + .eq(SampleInfo::getBusinessId, sampleInfo.getBusinessId()) + .gt(SampleInfo::getOrderNo, sampleInfo.getOrderNo())); + + //将后面的顺序号减一 保持不断号 + if (sampleInfoList != null && sampleInfoList.size() > 0) { + sampleInfoList.forEach(item -> { + item.setOrderNo(item.getOrderNo() - 1); + }); + } + this.updateBatchById(sampleInfoList); + return this.removeById(id); + } + + @Override + public IPage getSampleInfoPageList(Page page, SampleInfo sampleInfo) { + IPage ret = this.page(page, Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(sampleInfo.getSampleName()), SampleInfo::getSampleName, sampleInfo.getSampleName()) + .eq(sampleInfo.getStatus() != null, SampleInfo::getStatus, sampleInfo.getStatus()) + .orderByAsc(SampleInfo::getOrderNo)); + return ret; + } + + @Override + public List getSampleInfoList(SampleInfo sampleInfo) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(SampleInfo::getBusinessId, sampleInfo.getBusinessId()) + .like(StringUtils.isNotBlank(sampleInfo.getSampleName()), SampleInfo::getSampleName, sampleInfo.getSampleName()) + .eq(sampleInfo.getStatus() != null, SampleInfo::getStatus, sampleInfo.getStatus()) + .orderByAsc(SampleInfo::getOrderNo)); + + for (SampleInfo info : retList) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getSampleId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + } + return retList; + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(SampleInfo::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + /** + * 分页查询 + * + * @param page + * @param dlpUser + * @param testId + * @param keywords 样本编号、样本名称、业务名称查询参数 + * @return + */ + @Override// + public IPage getPageForTestRecord(Page page, DLPUser dlpUser, String testId, String keywords) { + if (StringUtils.isNotBlank(testId)) {//查询这个实验下面绑定的检材列表 + TestRecordVo testRecordVo = testRecordMapper.getTestRecordMapById(testId); + List sampleTestList = testRecordVo.getSampleTestList(); + if (sampleTestList == null || sampleTestList.size() == 0) { + sampleTestList.add("");//这一步操作是为了保证下面查询的时候不出错,如果没有对应的ID集合,那么应该就查不出来 + } + return baseMapper.getFullSampleInfoList(page, Wrappers.lambdaQuery() + .in(SampleInfo::getId, sampleTestList) + .orderByAsc(SampleInfo::getOrderNo)); + } else { + Integer status = 1;//代表已分配但未加入实验的检材的状态 + List assignmentInfoList = assignmentInfoService.list(Wrappers.lambdaQuery().in(AssignmentInfo::getTestUser, dlpUser.getId())); + ArrayList idList = new ArrayList<>(); + if (assignmentInfoList != null && assignmentInfoList.size() > 0) { + assignmentInfoList.forEach(item -> idList.add(item.getSampleId())); + } + if (idList == null || idList.size() == 0) { + idList.add("");//这一步操作是为了保证下面查询的时候不出错,如果没有对应的ID集合,那么应该就查不出来 + } + return baseMapper.getFullSampleInfoList(page, Wrappers.lambdaQuery() + .and(StringUtils.isNotBlank(keywords), qw -> qw + .like(SampleInfo::getAcceptNo, keywords) + .or() + .like(SampleInfo::getSampleName, keywords) + .or() + .like(SampleInfo::getBusinessType, keywords)) + .in(SampleInfo::getId, idList).eq(SampleInfo::getStatus, status).orderByAsc(SampleInfo::getOrderNo)); + } + } + + /** + * 向实验添加或移除检材 + * + * @param testRecordArgumentDto + * @return + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean useTestRecordSample(TestRecordArgumentDto testRecordArgumentDto) { + SampleInfo sampleInfo = this.getById(testRecordArgumentDto.getArgumentId()); + TestRecord testRecord = testRecordService.getById(testRecordArgumentDto.getTestRecordId()); + if (testRecordArgumentDto.getOpCode() == -1) { + testRecordSampleSolutionService.isLoadSample(sampleInfo.getAcceptNo(), testRecordArgumentDto.getTestRecordId()); + List sampleDataList = testRecordSampleDataService.list(Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getTestId, testRecordArgumentDto.getTestRecordId()) + .eq(TestRecordSampleData::getSampleNo, sampleInfo.getAcceptNo())); + if (testRecord.getBusinessType().startsWith("1") && sampleDataList.size() > 0) { + throw new RuntimeException(String.format("当前检材已存在上机数据,无法移除!")); + } + } + if (testRecordArgumentDto.getOpCode() == 1) { + if (sampleInfo.getStatus() != 1) { + throw new RuntimeException(String.format("当前检材状态有误,请选择状态为1的检材")); + } + sampleInfo.setStatus(2); + } else { + if (sampleInfo.getStatus() != 2) { + throw new RuntimeException(String.format("当前检材状态有误,请选择状态为2的检材")); + } + sampleInfo.setStatus(1); + } + return this.updateById(sampleInfo) && testRecordService.updateTestRecordArgument(testRecordArgumentDto.getTestRecordId(), sampleInfo.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_SAMPLE_DATA.getType(), testRecordArgumentDto.getOpCode()); + } + + /** + * 通过业务ID,查询这个业务下分配给自己的检材 + * + * @param businessId + * @param testUser + * @return + */ + @Override + public List getSampleInfoListForBusiness(String businessId, String testUser) { + return baseMapper.getSampleInfoList(businessId, testUser); + } + + /** + * 检查样本编号是否重复 + * + * @param acceptNo + * @param id + * @return + */ + @Override + public boolean checkRepeatNo(String acceptNo, String id) { + if (StringUtils.isNotBlank(id)) { + return true; + } + SampleInfo sampleInfo = this.getOne(Wrappers.lambdaQuery().eq(SampleInfo::getAcceptNo, acceptNo)); + return sampleInfo == null && StringUtils.isNotBlank(acceptNo) ? true : false; + } + + @Override + /**复制其他系统检材内容 + * @param sampleInfo + * @param material + * @param type 0:委托 1:任务 2:筛查 + */ + public void copy(SampleInfo sampleInfo, MaterialDto material, Integer type) { + sampleInfo.setId(IdWorker.get32UUID().toUpperCase()); + sampleInfo.setStatus(0); + if (StringUtils.isNotBlank(material.getFormName())) { + sampleInfo.setForm(material.getFormName()); + } else { + sampleInfo.setForm("/"); + } + if (StringUtils.isNotBlank(material.getColor())) { + sampleInfo.setColor(material.getColor()); + } else { + sampleInfo.setColor("/"); + } + if (type == 0 || type == 2) { + sampleInfo.setSampleName(material.getName()); + sampleInfo.setAcceptNo(material.getAcceptNo()); + } else if (type == 1) { + sampleInfo.setSampleName(material.getSampleName()); + sampleInfo.setAcceptNo(material.getImNo()); + } + if (material.getQuantity() != null && !(material.getQuantity().compareTo(BigDecimal.ZERO) == 0)) { + sampleInfo.setQuality(material.getQuantity().doubleValue()); + } else { + sampleInfo.setQuality(0.0); + } + if (material.getSample1RepeatWeigh() != null && !(material.getSample1RepeatWeigh().compareTo(BigDecimal.ZERO) == 0)) { + sampleInfo.setSampleQuality(material.getSample1RepeatWeigh().doubleValue()); + } else { + sampleInfo.setSampleQuality(0.0); + } + if (StringUtils.isNotBlank(material.getFundUnit())) { + sampleInfo.setSampleQualityUnit(material.getFundUnit()); + } else { + sampleInfo.setSampleQualityUnit("/"); + } + sampleInfo.setSource(0); + //检材的筛查物列表 + List candidateDrugs = material.getCandidateDrugs(); + if (candidateDrugs != null && candidateDrugs.size() > 0) { + ArrayList targetObjects = new ArrayList<>(); + for (DrugLite candidateDrug : candidateDrugs) { + TargetObject targetObject = new TargetObject(); + BeanUtils.copyProperties(candidateDrug, targetObject); + targetObjects.add(targetObject); + } + sampleInfo.setTargetObject(targetObjects); + } + if (StringUtils.isNotBlank(material.getUnit())) { + sampleInfo.setUnit(material.getUnit()); + } else { + sampleInfo.setUnit("/"); + } + if (type == 0 || type == 2 && StringUtils.isNotBlank(material.getAcceptNo())) { + String acceptNo = material.getAcceptNo(); + int lastIndexOf = acceptNo.lastIndexOf("-"); + sampleInfo.setOrderNo(Integer.parseInt(acceptNo.substring(lastIndexOf + 1))); + } + if (material.getAnalysisOption() != null) { + sampleInfo.setAnalysisOption(material.getAnalysisOption()); + } + } + + public String getNameDesStrForEntrust(List sampleInfos) { + //格式 + //对 xx号,xx号检材中的xx1、xx2进行 xx 分析, + //对1号、2号检材中的海洛因、甲基苯丙胺进行定量分析 + // 1.定性,2.定量 3.定性定量 4.关联性性 5.其他 + String result = ""; + //将检材排序 + Collections.sort(sampleInfos, new Comparator() { + @Override + public int compare(SampleInfo o1, SampleInfo o2) { + return o1.getOrderNo() - o2.getOrderNo(); + } + }); + for (int i = 0; i < sampleInfos.size(); i++) { + StringBuffer sbMaterialName = new StringBuffer(); + StringBuffer sbDrugDes = new StringBuffer(); + String analysisDes = ""; + StringBuffer sbAnalysisDes = new StringBuffer(); + SampleInfo sampleInfo = sampleInfos.get(i); + analysisDes = sampleInfo.getOrderNo() + "号"; + sbMaterialName.append(sampleInfo.getOrderNo() + "号").append(","); + String toJSONString = JSONArray.toJSONString(sampleInfo.getTargetObject()); + List drugLiteList = JSONArray.parseArray(toJSONString, TargetObject.class); + drugLiteList.forEach(item -> { + sbDrugDes.append(item.getName()).append("、"); + }); + sbDrugDes.delete(sbDrugDes.length() - 1, sbDrugDes.length());//删除多余的连接号 + if (sampleInfo.getAnalysisOption() == 1) { + sbAnalysisDes.append("定性"); + } else if (sampleInfo.getAnalysisOption() == 2) { + sbAnalysisDes.append("定量"); + } else { + sbAnalysisDes.append("定性定量"); + } + String req1 = "对" + analysisDes + "检材中的"; + String req2 = sbDrugDes.toString(); + String req3 = "进行" + sbAnalysisDes.toString() + "分析,"; + if (i == sampleInfos.size() - 1) { + result = result + req1 + req2 + "进行" + sbAnalysisDes.toString() + "分析。"; + } else { + result = result + req1 + req2 + req3; + } + } + return result; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInjectorServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInjectorServiceImpl.java new file mode 100644 index 0000000..c7cbfdf --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SampleInjectorServiceImpl.java @@ -0,0 +1,465 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.constant.SampleInjectorConstant; +import digital.laboratory.platform.inspection.constant.StdSolutionNum; +import digital.laboratory.platform.inspection.dto.ResetSampleInjectorDTO; +import digital.laboratory.platform.inspection.dto.SampleInjectorExcelDTO; +import digital.laboratory.platform.inspection.entity.SampleInjector; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspection.mapper.SampleInjectorMapper; +import digital.laboratory.platform.inspection.service.SampleInjectorService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.vo.ResultConcentrationVO; +import digital.laboratory.platform.inspection.vo.TestRecordSolutionVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 进样器信息接口实现类 + */ +@Slf4j +@Service +public class SampleInjectorServiceImpl extends ServiceImpl implements SampleInjectorService { + + @Resource + private TestRecordService testRecordService; + + /** + * 保存进样信息 + * @param sampleInjector + * @return SampleInjector + */ + @Override + @Transactional(rollbackFor = Exception.class) + public SampleInjector saveSampleInjector(SampleInjector sampleInjector) { + // 处理方盘,判断编号有没有重复放置 + if (sampleInjector.getType() == 2) { + Set sampleNoSet = new HashSet<>(); + int primalSize = 0; + // 合并方盘数组 + JSONArray injectorTypeArray = getJsonArrayByInjectorType(sampleInjector); + for (int i = 0; i < injectorTypeArray.size(); i++) { + JSONObject jsonObject = injectorTypeArray.getJSONObject(i); + String sampleNo = jsonObject.getString("sampleNo"); + if (StrUtil.isNotBlank(sampleNo)) { + sampleNoSet.add(sampleNo); + if (sampleNoSet.size() > primalSize) { + primalSize = sampleNoSet.size(); + } else { + throw new RuntimeException(String.format("溶液编号为 %s 的溶液重复放置,请取出来重新放置!", sampleNo)); + } + } + } + } + // 开始处理保存的数据 + boolean notBlank = StrUtil.isNotBlank(sampleInjector.getId()); + sampleInjector.setResetFlag(true);// 保存设置的重置的标识 + if (notBlank) { + SampleInjector oldInfo = this.getById(sampleInjector.getId()); + if (oldInfo == null) { + throw new RuntimeException(String.format("id为 %s 的进样信息不存在!", sampleInjector.getId())); + } + this.updateById(sampleInjector); + } else { + sampleInjector.setId(IdWorker.get32UUID()); + this.save(sampleInjector); + } + // 判断是否在上机,并更新状态值 + if (judgeOnTheMachine(sampleInjector)){ + testRecordService.update(Wrappers.lambdaUpdate() + .eq(TestRecord::getId, sampleInjector.getTestId()) + .set(TestRecord::getStatus, 1)); + } + return sampleInjector; + } + + /** + * 检材列表查询 + * @param testId + * @param key + * @return + */ + @Override + public List queryMaterialList(String testId, String key) { + TestRecord testInfo = testRecordService.getById(testId); + if (testInfo == null) { + throw new RuntimeException(String.format("查询不到检验任务id为 %s 的信息!", testId)); + } + // 查询是否已经进样 + SampleInjector one = this.getOne(Wrappers.lambdaQuery().eq(SampleInjector::getTestId, testId)); + + // 根据进样器类型返回json数组 + JSONArray jsonArray = getJsonArrayByInjectorType(one); + JSONArray finalJsonArray = jsonArray; + Map> testRecordSolutionVOSGroupByType = baseMapper.queryMaterialList(Wrappers.query() + .eq("T.test_id", testId) + .orderByDesc("T.number") + .and(StrUtil.isNotBlank(key), + wrapper -> wrapper.like("T.number", key))) + .parallelStream().peek(item -> { + // 根据其编号判断其溶液类型 + String number = item.getNumber(); + if (number.contains(StdSolutionNum.BLANK_SOLUTION.getPrefix())) { + + item.setTypeName(SampleInjectorConstant.BLANK_NAME); + } else if (number.contains(StdSolutionNum.SIMPLE_SOLUTION.getPrefix())) { + + item.setTypeName(SampleInjectorConstant.STANDARD_NAME); + } else if (number.contains(StdSolutionNum.MIXED_SOLUTION.getPrefix())) { + item.setTypeName(SampleInjectorConstant.MIX_STANDARD_NAME); + } else { + item.setTypeName(SampleInjectorConstant.NORMAL_NAME); + } + // 处理已经进样的数据 + if (finalJsonArray != null) { + for (int i = 0; i < finalJsonArray.size(); i++) { + JSONObject jsonObject = finalJsonArray.getJSONObject(i); + String sampleNo = jsonObject.getString("sampleNo"); + if (StrUtil.isNotBlank(sampleNo) && item.getNumber().equals(sampleNo)) { + item.setInjectorCount(jsonObject.getInteger("injectorCount")); + item.setFrameNumber(jsonObject.getString("frameNumber")); + String injectorLocation = one.getType() == 1 ? jsonObject.getString("title") : jsonObject.getString("name"); + item.setInjectorLocation(injectorLocation); + } + } + } + }).collect(Collectors.toList()).stream().collect(Collectors.groupingBy(TestRecordSolutionVO::getTypeName)); + + // 根据分类封装结果 + List testRecordSolutionVOS = new ArrayList<>(); + if (testRecordSolutionVOSGroupByType.containsKey(SampleInjectorConstant.NORMAL_NAME)) { + testRecordSolutionVOS.addAll(testRecordSolutionVOSGroupByType.get(SampleInjectorConstant.NORMAL_NAME)); + } + if (testRecordSolutionVOSGroupByType.containsKey(SampleInjectorConstant.BLANK_NAME)) { + testRecordSolutionVOS.addAll(testRecordSolutionVOSGroupByType.get(SampleInjectorConstant.BLANK_NAME)); + } + if (testRecordSolutionVOSGroupByType.containsKey(SampleInjectorConstant.MIX_STANDARD_NAME)) { + testRecordSolutionVOS.addAll(testRecordSolutionVOSGroupByType.get(SampleInjectorConstant.MIX_STANDARD_NAME)); + } + if (testRecordSolutionVOSGroupByType.containsKey(SampleInjectorConstant.STANDARD_NAME)) { + testRecordSolutionVOS.addAll(testRecordSolutionVOSGroupByType.get(SampleInjectorConstant.STANDARD_NAME)); + } + return testRecordSolutionVOS; + } + + /** + * 导出进样信息excel表 + * @param id + * @param response + */ + @Override + public void exportSampleInjectorInfoToExcel(String id, HttpServletResponse response){ + // 先查询进样信息,取出进样位置信息 + SampleInjector sampleInjector = this.getById(id); + if (sampleInjector == null) { + throw new RuntimeException("进样信息查询失败!"); + } + Map resultConcentrationVOMap = baseMapper.queryResultConcentrationList(Wrappers.query().eq("T.test_id", sampleInjector.getTestId())).stream().collect(Collectors.toMap(ResultConcentrationVO::getNumber, ResultConcentrationVO::getResultConcentration)); + List list = getSampleInjectorExportDataByDisk(sampleInjector, resultConcentrationVOMap); +// ServletOutputStream outputStream = null; + try { + + this.setExcelResponseProp(response, "进样表-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日-HH时mm分ss秒"))); +// outputStream = response.getOutputStream(); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + EasyExcel.write(byteArrayOutputStream) + .head(SampleInjectorExcelDTO.class) + .excelType(ExcelTypeEnum.CSV) + .sheet("进样表") + .doWrite(list); + response.getOutputStream().write(byteArrayOutputStream.toByteArray()); + response.getOutputStream().flush(); + + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * 重置进样信息 + * @param dto + * @return + */ + @Override + public SampleInjector reset(ResetSampleInjectorDTO dto) { + /*// 转json成map处理 + if (dto.getType() == 2) { // 如果是方盘先合并数组,在处理 + dto.setInjectorInfo( + mergeSquareInjectorInfo( + dto.getInjectorInfo1(), + dto.getInjectorInfo2(), + dto.getInjectorInfo3(), + dto.getInjectorInfo4() + ) + ); + } + List> injectorInfo = JSONArray.toJavaObject(dto.getInjectorInfo(), List.class); + // 使用并行流处理 + injectorInfo.parallelStream().forEach( item -> { + String sampleNo = item.get("sampleNo").toString(); + if (StrUtil.isNotBlank(sampleNo)) { + item.put("sampleNo", ""); + item.put("injectorCount", ""); + if (item.containsKey("active")) { + item.put("active", false); + } else { + item.put("selected", false); + } + } + + });*/ + + this.update(Wrappers.lambdaUpdate().eq(SampleInjector::getId, dto.getId()) + .set(SampleInjector::getInjectorInfo, null) + .set(SampleInjector::getType, 0) + .set(SampleInjector::isResetFlag, false) + .set(SampleInjector::getBlankStartPosition, null) + .set(SampleInjector::getInsertNumber, null)); + return this.getById(dto.getId()); + } + + /** + * 根据实验id获取,数据为空则初始部分数据返回 + * @param testId + * @return + */ + @Override + public SampleInjector getByTestId(String testId) { + SampleInjector sampleInjector = this.getOne(Wrappers.lambdaQuery().eq(SampleInjector::getTestId, testId)); + if (sampleInjector == null) { + sampleInjector = new SampleInjector(); + sampleInjector.setTestId(testId); + // 查询不到设置保存标记为false + sampleInjector.setResetFlag(false); + + } /*else if (sampleInjector.getType() == 2){ + // 方盘,取出json 处理 + JSONArray jsonArray = JSON.parseArray(sampleInjector.getInjectorInfo()); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + String frameNumber = jsonObject.getString("frameNumber"); + if (frameNumber.equals("P-1")) { + sampleInjector.getInjectorInfo1().add(jsonObject); + } else if (frameNumber.equals("P-2")) { + sampleInjector.getInjectorInfo2().add(jsonObject); + } else if (frameNumber.equals("P-3")) { + sampleInjector.getInjectorInfo3().add(jsonObject); + } else if (frameNumber.equals("P-4")) { + sampleInjector.getInjectorInfo4().add(jsonObject); + } else { + + } + } + } + // 第一次访问或者可以重置的都初始方盘数据 + if (sampleInjector.getId() == null || !sampleInjector.isResetFlag()) { + // 这里不管是圆盘还是方盘都返回方盘初始化的数组,前端根据情况选择参数 + sampleInjector.setInjectorInfo1(SampleInjectorConstant.P_1); + sampleInjector.setInjectorInfo2(SampleInjectorConstant.P_2); + sampleInjector.setInjectorInfo3(SampleInjectorConstant.P_3); + sampleInjector.setInjectorInfo4(SampleInjectorConstant.P_4); + }*/ + return sampleInjector; + } + + /** + * 判断当前进样器是否保存了进样位置信息 + * @param testId + * @return + */ + @Override + public boolean whetherSave(String testId) { + SampleInjector sampleInjector = this.getOne(Wrappers.lambdaQuery() + .eq(SampleInjector::getTestId, testId) + .eq(SampleInjector::isResetFlag, true) + .isNotNull(SampleInjector::getInjectorInfo)); + // 判断不为null, 则执行下面代码 + if (sampleInjector != null) { + return judgeOnTheMachine(sampleInjector); + } + return false; + } + + /** + * 判断是否正在上机 + * @param sampleInjector + * @return + */ + private boolean judgeOnTheMachine(SampleInjector sampleInjector) { + JSONArray injectorJsonArray = getJsonArrayByInjectorType(sampleInjector); + for (int i = 0; i < injectorJsonArray.size(); i++) { + JSONObject jsonObject = injectorJsonArray.getJSONObject(i); + String sampleNo = jsonObject.getString("sampleNo"); + boolean active = jsonObject.getBoolean("active"); + if (StrUtil.isNotBlank(sampleNo) && active) { + return true; + } + } + return false; + } + + /** + * 设置响应结果 + * + * @param response 响应结果对象 + * @param rawFileName 文件名 + * @throws UnsupportedEncodingException 不支持编码异常 + */ + private void setExcelResponseProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException { + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// "application/vnd.ms-excel" "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode(rawFileName, "UTF-8"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".csv"); + } + + /** + * 组装圆盘进样信息导出的数据 + * + * @param sampleInjector + * @param resultConcentrationVOMap + */ + private List getSampleInjectorExportDataByDisk(SampleInjector sampleInjector, Map resultConcentrationVOMap) { + // new 一个返回的结果列表 + List list = new ArrayList<>(); + // 根据进样器类型返回json数组 + JSONArray jsonArray = getJsonArrayByInjectorType(sampleInjector); + + int index = 1; // 导出表时的index值 + Integer blankCount = 1; // 空白穿插时的统计 + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + String sampleNo = jsonObject.getString("sampleNo"); // 默认取溶液编号 + if (StrUtil.isNotBlank(sampleNo)) { + if (sampleInjector.getBlankStartPosition() != null + && index == sampleInjector.getBlankStartPosition() + && !sampleNo.contains(StdSolutionNum.BLANK_SOLUTION.getPrefix())) { + // 判断是空白起始插入位置,空白开始插入 + list.addAll(blankInsert(sampleInjector.getInsertNumber(), blankCount)); + } + // 溶液编号不为空,证明这个进样盘号有检材 + SampleInjectorExcelDTO excelDTO = new SampleInjectorExcelDTO(); + excelDTO.setFileName(sampleNo); + excelDTO.setId(index == 1 ? "ID" : "ID" + (index)); + if (sampleInjector.getType() == 1) { + excelDTO.setSampleLocation(jsonObject.get("title").toString()); + } else { + excelDTO.setSampleLocation(jsonObject.getString("frameNumber") + "-" + jsonObject.getString("name")); + } + excelDTO.setIndex(index); + + if (CollUtil.isNotEmpty(resultConcentrationVOMap)) { + excelDTO.setFileText(resultConcentrationVOMap.get(sampleNo)); + } + if (sampleNo.contains(StdSolutionNum.BLANK_SOLUTION.getPrefix())) { + excelDTO.setType(SampleInjectorConstant.BLANK); + } else if (sampleNo.contains(StdSolutionNum.SIMPLE_SOLUTION.getPrefix())) { + excelDTO.setType(SampleInjectorConstant.STANDARD); + } + list.add(excelDTO); + + /*if (sampleInjector.getBlankStartPosition() != null && index == sampleInjector.getBlankStartPosition()) { + // 判断是空白起始插入位置,空白结束插入 + list.addAll(blankInsert(sampleInjector.getInsertNumber(), false)); + }*/ + index++; + } + } + return list; + } + + /** + * 空白穿插 + * @param insertNumber + * @param blankCount 是否是开始穿插, true 是, false 不是 + */ + + private List blankInsert(Integer insertNumber, Integer blankCount) { + List blankInsertList = new ArrayList<>(); + for (int i = 1; i <= insertNumber; i++) { + SampleInjectorExcelDTO blankExcelDTO = new SampleInjectorExcelDTO(); + + blankExcelDTO.setFileName(StdSolutionNum.BLANK_SOLUTION.getPrefix() + i); + + blankExcelDTO.setType(SampleInjectorConstant.BLANK); + blankInsertList.add(blankExcelDTO); + blankCount++; + } + return blankInsertList; + } + + /** + * 处理方盘的位置信息,把四个数组合并成一个 + * @param injectorInfo1 p-1 + * @param injectorInfo2 p-2 + * @param injectorInfo3 p-3 + * @param injectorInfo4 p-4 + * @return 返回json数组 + */ + private JSONArray mergeSquareInjectorInfo(JSONArray injectorInfo1, + JSONArray injectorInfo2, + JSONArray injectorInfo3, + JSONArray injectorInfo4) { + + if (CollUtil.isEmpty(injectorInfo1) + || CollUtil.isEmpty(injectorInfo2) + || CollUtil.isEmpty(injectorInfo3) + || CollUtil.isEmpty(injectorInfo4)) { + throw new RuntimeException("方盘参数不全,请检查参数是否合法!"); + } + // 合并四个数组到一个数组 + JSONArray resultArray = new JSONArray(); + resultArray.addAll(injectorInfo1); + resultArray.addAll(injectorInfo2); + resultArray.addAll(injectorInfo3); + resultArray.addAll(injectorInfo4); + return resultArray; + + } + + + /** + * 根据进样器类型返回json数组 + * @param one + * @return + */ + private static JSONArray getJsonArrayByInjectorType(SampleInjector one) { + // 处理已经进样的数据 + JSONArray jsonArray = new JSONArray(); + if (one != null && StrUtil.isNotBlank(one.getInjectorInfo())) { + // todo 返回列表时 相关检材的进样盘号也需要查询处理 + if (one.getType() == 1) { + jsonArray = JSON.parseArray(one.getInjectorInfo()); + } else if (one.getType() == 2){ + JSONArray totalArray = JSON.parseArray(one.getInjectorInfo()); + for (int i = 0; i < totalArray.size(); i++) { + jsonArray.addAll(totalArray.getJSONArray(i)); + } + } + } + return jsonArray; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/ScreenInfoServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/ScreenInfoServiceImpl.java new file mode 100644 index 0000000..5e7998e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/ScreenInfoServiceImpl.java @@ -0,0 +1,148 @@ +package digital.laboratory.platform.inspection.service.impl; +/* + *@title ScreenInfoServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:57 + */ + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspection.entity.ScreenInfo; +import digital.laboratory.platform.inspection.mapper.ScreenInfoMapper; +import digital.laboratory.platform.inspection.service.AssignmentInfoService; +import digital.laboratory.platform.inspection.service.SampleInfoService; +import digital.laboratory.platform.inspection.service.ScreenInfoService; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +@Service +@Slf4j +public class ScreenInfoServiceImpl extends ServiceImpl implements ScreenInfoService { + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private AssignmentInfoService assignmentInfoService; + + @Override + @Transactional(rollbackFor = Exception.class) + public ScreenInfo addScreenInfo(ScreenInfo screenInfo) { + //设置业务类型 + screenInfo.setBusinessType("30001"); + if (StringUtils.isBlank(screenInfo.getId())) { + screenInfo.setId(IdWorker.get32UUID()); + log.info("保存对象entrustInfo的ID为空,由系统生成一个给它使用 {}", screenInfo.getId()); + } + ScreenInfo info = this.getOne(Wrappers.lambdaQuery().eq(ScreenInfo::getOriginalId, screenInfo.getOriginalId())); + if (info != null) { + throw new RuntimeException(String.format("当前筛查任务已经同步至检验鉴定系统,无需再次同步!")); + } + List materialList = screenInfo.getMaterialList(); + if (materialList != null && materialList.size() > 0) { + List sampleInfos = new ArrayList<>(); + for (MaterialDto material : materialList) { + SampleInfo sampleInfo = new SampleInfo(); + sampleInfoService.copy(sampleInfo, material, 2); + sampleInfo.setBusinessType(screenInfo.getBusinessType()); + sampleInfo.setBusinessId(screenInfo.getId()); + sampleInfos.add(sampleInfo); + } + sampleInfoService.saveBatch(sampleInfos); + } + boolean ret = this.save(screenInfo); + if (ret) { + log.info("{} 保存成功", screenInfo); + return screenInfo; + } else { + log.info("{} 保存失败", screenInfo); + return null; + } + } + + @Override + public ScreenInfo updateScreenInfo(ScreenInfo screenInfo) { + if (screenInfo.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + return null; + } + boolean ret = this.updateById(screenInfo); + if (ret) { + return screenInfo; + } else { + return null; + } + } + + @Override + public Boolean deleteScreenInfo(String id) { + List assignmentInfos = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, id)); + if (assignmentInfos.size() > 0) { + throw new RuntimeException(String.format("当前业务已被分配,无法删除!")); + } + + return this.removeById(id); + } + + @Override + public IPage getScreenPageList(Page page, ScreenInfo screenInfo,String keywords) { + IPage ret = this.page(page, Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(keywords), ScreenInfo::getCaseName,keywords) + .eq(StringUtils.isNotBlank(screenInfo.getId()), ScreenInfo::getId, screenInfo.getId()) + .orderByDesc(ScreenInfo::getCreateTime)); + + for (ScreenInfo info : ret.getRecords()) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + } + + return ret; + } + + @Override + public List getScreenList(ScreenInfo screenInfo,String keywords) { + List retList = this.list(Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(keywords), ScreenInfo::getCaseName, keywords) + .eq(StringUtils.isNotBlank(screenInfo.getId()), ScreenInfo::getId, screenInfo.getId()) + .orderByDesc(ScreenInfo::getCreateTime)); + + for (ScreenInfo info : retList) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + } + return retList; + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(ScreenInfo::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SewageDrugInspectReportServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SewageDrugInspectReportServiceImpl.java new file mode 100644 index 0000000..fa24ce5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/SewageDrugInspectReportServiceImpl.java @@ -0,0 +1,2652 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import digital.laboratory.platform.common.core.constant.CommonConstants; +import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.NumberTransferHanZi; +import digital.laboratory.platform.inspection.dto.ExportSewageAnalystReportsDTO; +import digital.laboratory.platform.inspection.dto.RegionalDrugConsumptionDTO; +import digital.laboratory.platform.inspection.dto.ReportConfigDTO; +import digital.laboratory.platform.inspection.dto.SewageDataDto; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.service.SampleInfoService; +import digital.laboratory.platform.inspection.service.SewageDrugInspectReportService; +import digital.laboratory.platform.inspection.service.TaskInfoService; +import digital.laboratory.platform.inspection.utils.sewagereport.*; +import digital.laboratory.platform.sewage.feign.RemoteSewageJobIdentificationMaterialService; +import digital.laboratory.platform.sewage.vo.SewageJobIdentificationMaterialVO; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.xwpf.usermodel.BreakType; +import org.apache.poi.xwpf.usermodel.ParagraphAlignment; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.Year; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/*** + * 污水专项检测毒品分析报告 相关接口 + */ +@Slf4j +@Service +public class SewageDrugInspectReportServiceImpl implements SewageDrugInspectReportService { + + @Resource + private TaskInfoService taskInfoService; + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private RemoteSewageJobIdentificationMaterialService remoteSewageJobIdentificationMaterialService; + + @Resource + private OssFile ossFile; + + // 保留1位小数的数值格式 + private final static DecimalFormat keep1DecimalPlace = new DecimalFormat("#.#"); + + private final static DateTimeFormatter chineseYearDoubleMonthFormatter = DateTimeFormatter.ofPattern("yyyy年MM月"); + private final static DateTimeFormatter chineseDateFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); + private final static DateTimeFormatter chineseYearSingleMonthFormatter = DateTimeFormatter.ofPattern("yyyy年M月"); + + + /** + * 生成污水样品毒品检测分析报告 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public String generateSewageDrugInspectReportWord(ExportSewageAnalystReportsDTO dto) throws Exception{ + // 目前的污水报告 只针对于 陕西省的 默认设置参数为陕西省 + dto.setProvinceCode("610000"); + dto.setProvinceName("陕西省"); + // 陕西省各地市名称 + List cityNameList = new ArrayList<>(Arrays.asList("西安市","宝鸡市","咸阳市","铜川市","渭南市","延安市","榆林市","汉中市","安康市","商洛市")); + // 获取任务信息,得到任务的开始日期 + TaskInfo taskInfo = taskInfoService.getOne(Wrappers.lambdaQuery().eq(TaskInfo::getId, dto.getJobId())); + // 更新任务中报告配置的信息 + taskInfo.setReportConfig(dto.getReportConfig()); + taskInfoService.updateById(taskInfo); + // 数据 + String yearMonth = taskInfo.getTaskStartDate().format(chineseYearDoubleMonthFormatter ); + // 目前字典中的单位名称不统一,这里暂时写死,后期在改 + String organization = "国家毒品实验室陕西分中心"; + String generateDate = LocalDate.now().format(chineseDateFormatter); + String province = dto.getProvinceName(); + // 获取目前任务之前的四个任务信息 + List taskIdByOrderStartTimeLimit4 = taskInfoService.getTaskIdByOrderStartTimeLimit4(taskInfo); + + // 对任务进行排序, 获取到根据开始时间升序的任务列表 + List taskInfoList = getTaskInfos(taskIdByOrderStartTimeLimit4, taskInfo); + + // 这里的数据是按照任务的开始时间升序顺序对应的 + List> sewageDataDtoLists = getSewageTaskDataForAYear(taskInfoList, dto); + + // feign 接口调用获取 污水检材 + List data = getSewageJobIdentificationMaterialVOS(dto, taskInfo); + + // 使用stream 流进行排序 + List dateSortedByAcceptTime = data.stream() + .sorted((d1, d2) -> d1.getAcceptTime().compareTo(d2.getAcceptTime())) + .collect(Collectors.toList()); + List dateSortedByCollectTime = data.stream() + .sorted((d1, d2) -> d1.getCollectTime().compareTo(d2.getCollectTime())) + .collect(Collectors.toList()); + String collectDate1 = dateSortedByAcceptTime.get(0).getAcceptTime().format(chineseDateFormatter); + String collectDate2 = dateSortedByAcceptTime.get(dateSortedByAcceptTime.size()-1).getAcceptTime().format(chineseDateFormatter); + + String samplingDate1 = dateSortedByCollectTime.get(0).getCollectTime().format(chineseDateFormatter); + String samplingDate2 = dateSortedByCollectTime.get(dateSortedByCollectTime.size()-1).getCollectTime().format(chineseDateFormatter); + int materialNum = data.size(); // 本次样本数量 + + // 统计这些样本的地市数量 + Set cityCount = data.stream().map(SewageJobIdentificationMaterialVO::getCollectPlaceCityCode).collect(Collectors.toSet()); + + // 获取每个样品的数据 + List sewageDataDtos = taskInfoService.processSewageDataDtos(dto.getDailySmokingPerCapita(), data); + sewageDataDtoLists.add(sewageDataDtos); // 添加到 sewageDataDtoLists 方便后续进行陕西省毒品滥用情况分析 + // 统计这些样本来自多少个污水厂 + Set sewagePlantNum = sewageDataDtos.stream().map(o -> StrUtil.split(o.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + + // 获取污水数据并根据地市分组 + Map> sewageDataGroupByMap = getSewageDataGroupByCityNameMap(sewageDataDtos); + // 获取陕西省各行政区主要毒品总消费量表数据 + List regionalDrugConsumptionDTOList = fetchRegionalDrugConsumption(sewageDataGroupByMap); + + // 取列表最后一个,最后一个是计算全省的 + RegionalDrugConsumptionDTO allProvince = regionalDrugConsumptionDTOList.get(regionalDrugConsumptionDTOList.size() - 1); + + // 根据行政区转map,方便后续的陕西省各污水厂服务区及各行政区毒品千人均消费量表 读取地区平均 + Map regionalDrugConsumptionDTOMap = regionalDrugConsumptionDTOList.stream().collect(Collectors.toMap(RegionalDrugConsumptionDTO::getRegional, Function.identity())); + + // 取四个任务的开始日期 + List taskStartDateList = getTaskStartDateList(taskInfoList, DateTimeFormatter.ofPattern("yyyy-MM")); + // 中国格式的日期 + List taskStartDateChinaFormatList = getTaskStartDateList(taskInfoList, chineseYearSingleMonthFormatter); + + List> allMergeMegionalDrugConsumptionDTOList = getAllMergeBeforeMegionalDrugConsumptionDTOList(sewageDataDtoLists, taskInfoList); + + // 把前面季度的全省毒品消费量和当前季度的放到一个list里,目的是为了后面的报告中 比较使用到 + List allTaskProvinceDrugConsumptionList = new ArrayList<>(); + extractedProvinceDrugConsumeData(allMergeMegionalDrugConsumptionDTOList, allTaskProvinceDrugConsumptionList, allProvince); + + // 生成word文档 + XWPFDocument doc = new XWPFDocument(); + // resourceLoader.getResource("classpath:template/templateStyles.docx").getInputStream() 获取resource目录下的模板文件 + ByteArrayInputStream filePath = getTemplateStyleFilePath(); // 获取模板路径 + WordUtils.setDocumentStyle(doc, filePath); + + generateHomePage(doc, yearMonth, organization, generateDate, province); + + WordUtils.createDocTitle(doc, yearMonth + "份"+ province +"污水专项检测毒品分析报告", false); + + WordUtils.createParagraphTitle(doc, "一、工作概况", false, 2); + WordUtils.createParagraph( + doc, + ParagraphAlignment.LEFT, + organization + + "自"+ collectDate1 +"至"+ collectDate2 + + "收到"+ province + cityCount.size() +"个地市共"+ + materialNum +"份污水样品(包含"+ sewagePlantNum.size() +"个污水处理厂),各污水处理厂监测点采样日期在" + + samplingDate1 +"至" + samplingDate2 + "。本次检测分析的物质包括以下13种,检测结果为各目标物的浓度数据(单位:纳克/升):", + false, + 2); + + // 获取常见毒品及其代谢物 === "甲基苯丙胺、苯丙胺(甲基苯丙胺代谢物);氯胺酮、去甲氯胺酮(氯胺酮代谢物);吗啡(海洛因二级代谢产物)、O6-单乙酰吗啡(海洛因一级代谢产物);" + + // "可待因;可卡因、苯甲酰爱康宁(可卡因代谢物);3,4-亚甲基二氧甲基苯丙胺(摇头丸MDMA)、3,4-亚甲基二氧基苯丙胺(摇头丸代谢物);芬太尼。" + List reportConfigDTOSFilterHeroin = dto.getCommonDrugAndMetabolites().stream().filter(o -> !o.getDictLabel().contains("海洛因")).collect(Collectors.toList()); + String commonDrugMetabolites = getCommonDrugMetabolites(reportConfigDTOSFilterHeroin); + + WordUtils.createParagraphAndBold(doc, ParagraphAlignment.LEFT, "常见毒品及其代谢物("+ reportConfigDTOSFilterHeroin.size() +"种):", + commonDrugMetabolites, false, 2); + // 人口标记物(1种):可替宁(烟草代谢物)。 + String populationMarkingMaterial = getPopulationMarking(dto.getPopulationMarkers()); + WordUtils.createParagraphAndBold(doc, ParagraphAlignment.LEFT, "人口标记物("+ dto.getPopulationMarkers().size() +"种):", + populationMarkingMaterial, false, 2); + + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, "根据各毒品目标物的浓度,并综合污水处理厂进水流量、人口标记物浓度," + + "计算了各污水处理厂服务区、各行政区的毒品千人均消费量和毒品总消费量,形成本分析报告。", false, 2); + + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "(注:特别指出,本次检测工作只对收到的" + materialNum + "份污水样品进行分析评估,由于仅采集两天样品进行分析,数据结果仅供参考,个别异常数据还需深入研究,特此说明)", + "", + false, + 2); + + // 第二 + WordUtils.createParagraphTitle(doc, "二、全省总体情况", false, 2); + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, yearMonth + "份,陕西省毒品消费结构:", false, 2); + + // 设置饼图数据 + PieChartForm pieChartForm = generateCommonDrugConsumeStructureChart(allProvince); + WordUtils.createPieChart(doc, pieChartForm, "图1 陕西省常见毒品消费结构图"); + + Map inspectResultAnalysisMap = getInspectResultAnalysis(pieChartForm, allProvince); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "根据检测结果分析:" + inspectResultAnalysisMap.get("resultAnalysis").toString(), + "", + false, + 2); + + // 全省监测区域内容生成 + String provinceMonitorsDrugConsumeContent = getProvinceMonitorsDrugConsumeContent(inspectResultAnalysisMap, allProvince); + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, provinceMonitorsDrugConsumeContent, false, 2); + + // todo 待完成 + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "各毒品滥用现状如下:", + "", + false, + 2); + + + // 循环生成各毒品的滥用现状 + /* + * 原文 + * 冰毒 2023年2月份在54%的污水厂有冰毒及其代谢物检出。 + * 全省冰毒的千人均消费量为2.5毫克/千人/天,核算陕西省冰毒的总消费量为39.4克/天。 + * 西安冰毒总消费量为32.5克/天,占全省总消费量的82.5%。 + */ + String methamphetamineAbuseCurrentSituation = getMethamphetamineAbuseCurrentSituation(yearMonth, sewageDataDtos, regionalDrugConsumptionDTOMap, allProvince, sewagePlantNum); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "冰毒 ", + methamphetamineAbuseCurrentSituation, + false, + 2); + + /* 原文 + * 海洛因 2023年2月在98%的污水处理厂均有吗啡检出(海洛因的代谢物)。 + * 陕西省海洛因的千人均消费量18毫克/千人/天,核算海洛因的总消费量为285.3克/天。 + * 特别指出,根据污水中的吗啡和可待因的浓度计算海洛因消费量时, + * 粗略扣除了合法药物、医用吗啡以及磷酸可待因代谢吗啡的干扰, + * 但未充分考虑干扰的区域性和季节性差异,因而存在一定误差,结果仅供参考。 + */ + String heroinAbuseCurrentSituation = getHeroinAbuseCurrentSituation(yearMonth, sewageDataDtos, regionalDrugConsumptionDTOMap, allProvince, sewagePlantNum); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "海洛因 ", + heroinAbuseCurrentSituation, + false, + 2); + + /* 原文 + * 氯胺酮 2023年2月在9.3%的污水处理厂均有氯胺酮检出, + * 与2022年相比,2023年2月份氯胺酮滥用明显增加,在西安、宝鸡、安康、渭南和榆林5个地市(19个污水处理厂)中均有检出, + * 氯胺酮浓度范围为0.3~2.9 ng/L,后续检测中可持续关注。 + */ + String ketamineAbuseCurrentSituation = getDrugAbuseCurrentSituation( + yearMonth, + sewageDataDtos, + allTaskProvinceDrugConsumptionList, + sewagePlantNum, + sewageDataDto -> sewageDataDto.getKetamineConcentration() != 0, + Comparator.comparing(SewageDataDto::getKetamineConcentration), + SewageDataDto::getKetamineConcentration, + "氯胺酮"); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "氯胺酮 ", + ketamineAbuseCurrentSituation, + false, + 2); + /* 原文 + * 可卡因 本次监测中,在汉中市宁强县污水处理厂中有12.7ng/L的可卡因检出, + * 其他地市均未检出,说明全省范围的明显滥用,需长期关注,掌握变化趋势。 + */ + String cocaineAbuseCurrentSituation = getDrugAbuseCurrentSituation( + yearMonth, + sewageDataDtos, + allTaskProvinceDrugConsumptionList, + sewagePlantNum, + sewageDataDto -> sewageDataDto.getCocaineConcentration() != 0, + Comparator.comparing(SewageDataDto::getCocaineConcentration), + SewageDataDto::getCocaineConcentration, + "可卡因"); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "可卡因 ", + cocaineAbuseCurrentSituation, + false, + 2); + + /* 原文 + * 摇头丸(MDMA)在本次监测中均未检出,说明不存在摇头丸的明显滥用。 + */ + String mdmaAbuseCurrentSituation = getDrugAbuseCurrentSituation( + yearMonth, + sewageDataDtos, + allTaskProvinceDrugConsumptionList, + sewagePlantNum, + sewageDataDto -> sewageDataDto.getMdmaConcentration() != 0 && sewageDataDto.getMdaConcentration() != 0, + Comparator.comparing(SewageDataDto::getMdmaConcentration), + SewageDataDto::getMdmaConcentration, + "摇头丸(MDMA)"); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "摇头丸(MDMA) ", + mdmaAbuseCurrentSituation, + false, + 2); + + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "芬太尼 ", + "在本次监测中均未检出,说明不存在芬太尼的明显滥用。", + false, + 2); + + if (dto.getGenerateEtomidateTable()) { + // 判断是否要生成依托咪酯的滥用现状 + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.LEFT, + "依托咪酯 ", + getEtomidateAbuseSCurrentSituation(yearMonth, sewageDataDtos), + false, + 2); + } + + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.CENTER, + "表1 陕西省各行政区主要毒品总消费量表 ", + "", + false, + 0); + // 陕西省各行政区主要毒品总消费量表 + List nameList = new ArrayList<>(Arrays.asList("海洛因", "冰毒", "氯胺酮", "MDMA", "可卡因", "芬太尼", "综合")); + TableCreateUtils.fetchRegionalDrugConsumptionTable(doc, regionalDrugConsumptionDTOList.size() + 2,15, nameList, regionalDrugConsumptionDTOList); + + // 柱状图 + BarLineChartForm chartForm1 = getServiceAreaDrugConsumeBarLineChartForm(doc, regionalDrugConsumptionDTOList, pieChartForm, cityNameList); + WordUtils.createBarLineCharts(doc, chartForm1, "图2 陕西省各行政区毒品千人均消费量",true); + + // 折线柱状图 todo + doc.createParagraph().createRun().addBreak(); + BarLineChartForm chartForm = generateDrugConsumePerThousandTrendChartData( + taskStartDateList, + pieChartForm.getXData(), + allTaskProvinceDrugConsumptionList); + WordUtils.createBarLineCharts(doc, chartForm, "图3 陕西省毒品千人均消费量变化趋势",true); + // 生成对这几个任务中陕西省的毒品千人均消费量变化趋势进行描述 + String drugConsumePerThousandTrendDescribe = getDrugConsumePerThousandTrendDescribe(allTaskProvinceDrugConsumptionList, taskInfoList); + // 判断当前任务前面是否存在任务 + TaskInfo taskInfo1 = taskIdByOrderStartTimeLimit4.get(0) == null ? taskInfo : taskIdByOrderStartTimeLimit4.get(0); + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, + "陕西省" + taskInfo1.getTaskStartDate().format(chineseYearDoubleMonthFormatter ) + + "至" + yearMonth +"综合千人均消费量变化趋势如图3所示。" + + drugConsumePerThousandTrendDescribe, + false, 2); + // 生成全省海洛因的消费量变化趋势描述 + String heroinProvinceAbuseTendDescribe = analysisHeroinProvinceAbuseTendDescribe(allTaskProvinceDrugConsumptionList, taskStartDateChinaFormatList); + /* 原文 + * 全省海洛因千人均消费量与综合千人均消费量变化趋势一致。 + * 2023年2月(18毫克/千人/天)与2022年3月(24.5毫克/千人/天)相比,同比下降36%, + * 与2022年12月(46.5毫克/千人/天)相比,环比下降47%,海洛因滥用趋势逐渐下降。 + */ + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, + "全省海洛因千人均消费量与综合千人均消费量变化趋势一致。" + heroinProvinceAbuseTendDescribe, + false, 2); + + /* 原文 + * 全省冰毒千人均消费量2023年2月(2.5毫克/千人/天)与2022年3月(3毫克/千人/天)相比,同比下降16.6%, + * 与2022年12月(1.1毫克/千人/天)相比,环比增加127%。全省冰毒滥用明显增加。 + */ + String methamphetamineProvinceAbuseTendDescribe = analysisMethamphetamineProvinceAbuseTendDescribe(allTaskProvinceDrugConsumptionList, taskStartDateChinaFormatList); + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, + methamphetamineProvinceAbuseTendDescribe, + false, 2); + + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.CENTER, + "表2 陕西省各污水厂服务区及各行政区毒品千人均消费量表 ", + "", + false, + 0); + + // 表2 陕西省各污水厂服务区及各行政区毒品千人均消费量表 + generateServiceAreaDrugConsumptionPerThousandTable(sewageDataGroupByMap, regionalDrugConsumptionDTOMap, doc); + + // 空两行,模仿得到的模板格式 + doc.createParagraph(); + doc.createParagraph(); + WordUtils.createParagraph(doc, ParagraphAlignment.LEFT, "注:1.因西安和铜川各行政区之间无独立污水处理厂,因此除西安和铜川外按照污水处理厂计算千人均消费量量,其余地市按照区县计算。", false, 2); + WordUtils.createParagraphCustomTab(doc, ParagraphAlignment.LEFT, "2.不合格样品:定义为检测出该样品中可替宁浓度低于500 ng/L。", false, 2, 2); + if (dto.getGenerateEtomidateTable()) { + doc.createParagraph().createRun().addBreak(BreakType.PAGE); // 创建新的一页 + TableCreateUtils.subsection(doc, TableCreateUtils.SUBSECTIONONE); + WordUtils.createParagraphAndBold(doc, + ParagraphAlignment.CENTER, + "表3 陕西省第"+ yearMonth +"份各行政区污水厂检出依托咪酯统计表", + "", + false, + 0); + List headerList = new ArrayList<>(Arrays.asList("行政区", "污水厂数量", "污水样品数量", "污水厂检出数量", "样品检出数量", "样品检出百分比", "污水厂检出百分比", "依托咪酯检出污水厂名称")); + List> tableDataList = new ArrayList<>(); + tableDataList.add(headerList); + // 组装依托咪酯统计数据 + getEtomidateDetectedStatisticalData(sewageDataGroupByMap, tableDataList); + TableCreateUtils.fetchEtomidateDetectedStatisticalTable(doc, tableDataList.size(), headerList.size(), tableDataList); + WordUtils.createParagraph(doc, + ParagraphAlignment.LEFT, + "注:榆林、杨凌送样时未建立依托咪酯检测方法,故未检。", + false, + 2); + TableCreateUtils.subsection(doc, TableCreateUtils.SUBSECTIONTWO); + + } + // 三、各区域情况 +// doc.createParagraph().createRun().addBreak(BreakType.PAGE); + WordUtils.createParagraphTitle(doc, "三、各区域情况", false, 2); + WordUtils.createParagraphAndBothSidesBold(doc, + ParagraphAlignment.LEFT, + "(详细数据见表1)", + "根据" + yearMonth + "监测结果分析,陕西省各行政区和各监测污水厂服务片区的常规毒品滥用情况分析如下", + ":", + false, + 2); + WordUtils.createParagraphAndMiddleBold( + doc, + ParagraphAlignment.LEFT, + "从", + "综合总消费量", + "(冰毒、K粉、海洛因、可卡因、摇头丸和芬太尼五种毒品折算总量,反映某区域内全体人口的毒品滥用总量)分析。", + false, + 2); + + // 对当前季度任务的各行政区的综合总消费量进行降序排序 + List tcRegionalDrugConsumptionDTOS = getRegionalDrugConsumptionDTOSSortedDesc(regionalDrugConsumptionDTOList, true, true); + // 根据得到的降序数组进行描述 + String combinedTotalConsumptionDescribe = compareEachCityCombinedTotalConsumptionDescribe(tcRegionalDrugConsumptionDTOS); + /** + * 按行政区,西安市的综合总消费量最高为178.1克/天,占全省监测区域消费总量的54.8%; + * 其次是咸阳市,综合总消费量为33.6克/天,分别占全省监测区域消费总量的10.3%; + * 位居第三、第四、第五位的是榆林市、渭南市和宝鸡市,综合总消费量分别为31.4克/天、27.1克/天和24.9克/天, + * 占全省监测区域消费总量的9.6%、8.3%和7.6%;其余五个行政区综合总消费量均低于20克/天,占比均低于6%。 + */ + WordUtils.createParagraph( + doc, + ParagraphAlignment.LEFT, + combinedTotalConsumptionDescribe, + true, + 2); + // 如图所示各行政区毒品滥用总量排序(即综合总消费量排序):西安市>咸阳市>榆林市>渭南市>宝鸡市>延安市>汉中市>安康市>商洛市>铜川市>杨凌区。 + String combinedTotalConsumptionSortedDescStr = getCombinedTotalConsumptionSortedDesc(tcRegionalDrugConsumptionDTOS); + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.LEFT, + "如图所示各行政区毒品滥用总量排序(即综合总消费量排序):", + combinedTotalConsumptionSortedDescStr, + true, + 2); + + // 折线图 各行政区毒品总消费量变化趋势 + WordUtils.createBarLineCharts(doc, + getRendsInTotalDrugConsumptionInEachAdministrativeRegion( + allMergeMegionalDrugConsumptionDTOList, + regionalDrugConsumptionDTOList, + taskStartDateList, + cityNameList), + "", + false); + + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "图4 各行政区毒品总消费量变化趋势", + "", + false, + 0); + // todo 这里的文字描述不太好生, 暂时不做 + WordUtils.createHighLightParagraph(doc, + ParagraphAlignment.LEFT, + "如图4所示,"+ + taskStartDateChinaFormatList.get(0) + + "至" + + taskStartDateChinaFormatList.get(taskStartDateChinaFormatList.size() - 1) + + "各市毒品消费总量变化趋势基本一致," + + "2022年3月至2022年9月各市毒品消费总量呈现下降趋势,至2022年12月呈现上升趋势,2023年2月出现明显下降。其中西安变化趋势最为明显," + + "2023年2月与2022年3月相比,西安总消费量同比下降16.2%,与2022年12月相比,西安总费量环比下降70%。", + false, + 2); + + WordUtils.createParagraphAndMiddleBold( + doc, + ParagraphAlignment.LEFT, + "综合千人均消费量", + "从", + "(冰毒、K粉、海洛因、可卡因、摇头丸和芬太尼五种毒品千人均消费量的折算总量," + + "反映单位人口的毒品滥用量)分析。", + false, + 2); + + // 对当前季度任务的各行政区的综合总消费量进行降序排序 + List pccRegionalDrugConsumptionDTOS = getRegionalDrugConsumptionDTOSSortedDesc(regionalDrugConsumptionDTOList, false, true); + String combinedThousandPerConsumptionCompareDescribe = getCombinedThousandPerConsumptionCompareDescribe(pccRegionalDrugConsumptionDTOS, allProvince); + /** + * 全省各行政区千人均变化趋势如图2所示,全省平均千人均消费量为20.5毫克/千人/天, + * 咸阳市的综合千人均消费量最高,为63.9毫克/千人/天,是全省平均水平的3.1倍; + * 其次是汉中市和宝鸡市,综合千人均消费量为38毫克/千人/天和31.9毫克/千人/天; + * 位居第四的是商洛市,综合千人均消费量分别为为27.4毫克/千人/天; + * 位居第五至十一位的分别是杨凌区、安康市、西安市、渭南市、延安市、铜川市和榆林市, + * 分别为27.5毫克/千人/天、22.3毫克/千人/天、20.9毫克/千人/天、20.5毫克/千人/天、19.3毫克/千人/天、16.4毫克/千人/天和13.9毫克/千人/天 + */ + WordUtils.createParagraph(doc, + ParagraphAlignment.LEFT, + combinedThousandPerConsumptionCompareDescribe, + false, + 2); + + // 对当前季度任务的各行政区的综合总消费量进行降序排序(全省的也包含在排序的数组里) + List pccRegionalDrugConsumptionDTOS1 = getRegionalDrugConsumptionDTOSSortedDesc(regionalDrugConsumptionDTOList, false, false); + String combinedThousandPerConsumptionSortedDesc = getCombinedThousandPerConsumptionSortedDesc(pccRegionalDrugConsumptionDTOS1); + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.LEFT, + "各行政区毒品滥用水平排序(即综合千人均消费量排序):", + combinedThousandPerConsumptionSortedDesc, + false, + 2); + + // 折线图 各行政区毒品千人均消费量变化趋势 + WordUtils.createBarLineCharts(doc, getTrendsInPerCapitaDrugConsumptionEachAdministrativeRegion(allMergeMegionalDrugConsumptionDTOList, regionalDrugConsumptionDTOList, taskStartDateList, cityNameList), "",false); + + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "图5 各行政区毒品千人均消费量变化趋势", + "", + false, + 0); + + WordUtils.createHighLightParagraph(doc, + ParagraphAlignment.LEFT, + "如图5所示,2023年2月全省千人均消费量(除汉中市和咸阳市外)整体变化趋势与全省总消费量变化趋势保持一致。" + + "2022年3月至2022年9月各市千人均消费量呈现下降趋势,至2022年12月呈现上升趋势,2023年2月出现明显下降," + + "其中西安市和汉中市变化最为明显。汉中市2022年3月至2022年6月有所下降," + + "后3个月基本保持平稳。咸阳市2022年3月至2022年9月有所下降,其后2个月保持上升趋势。" + + "各市具体增长率/下降率见下表。", + false, + 2); + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "表3 陕西省各污水厂服务区及各行政区毒品千人均消费量表", + "", + false, + 0); + + // 表3 陕西省各污水厂服务区及各行政区毒品千人均消费量表 + List> cityDrugConsumptionGrowthRatesData = fetchCityDrugConsumptionGrowthRatesData(allMergeMegionalDrugConsumptionDTOList, regionalDrugConsumptionDTOList, taskInfoList, cityNameList); + TableCreateUtils.fetchCityDrugConsumptionGrowthRatesTable(doc, 3, 11, cityNameList, cityDrugConsumptionGrowthRatesData); + + WordUtils.createParagraphAndBothSidesBold( + doc, + ParagraphAlignment.LEFT, + "生活污水处理厂水样中“人口标记物”可替宁浓度过低或过高,会被公安部禁毒情报技术中心判定为", + "另有一点需要再次说明:", + "数据不合格,", + false, + 2); + + WordUtils.createParagraph(doc, + ParagraphAlignment.LEFT, + "影响陕西省的检测数据质量。请各市禁毒部门除关注毒品消费量数据之外," + + "重点寻找部分污水处理厂水样中可替宁浓度异常的原因(公安部禁毒情报技术中心给出的经验值范围:500~5000纳克/升)。" + + "对于可替宁浓度持续低于经验值的区县,建议在条件允许的情况下,申请连续采样送检,以供陕西分中心技术人员判断原因。", + false, + 2); + + // 换页 + doc.createParagraph().createRun().addBreak(BreakType.PAGE); + WordUtils.createParagraphTitle(doc, "四、2023年2月陕西省毒品滥用情况分析", false, 2); + WordUtils.createParagraphTitle(doc, "1、冰毒(甲基苯丙胺)", false, 3); + + List tableName2List = new ArrayList<>(Arrays.asList("污水处理厂名称","甲基苯丙胺(ng/L)")); + // 对数据进行排序 + List> sortSewageDataDtos = getSortSewageDataDtos(sewageDataDtoLists, + Comparator.comparing(SewageDataDto::getMethamphetamineConcentration).reversed()); + List> cityDrugAbuseConditionAnalysisData = fetchCityDrugAbuseConditionAnalysisData( + sortSewageDataDtos, + SewageDataDto::getMethamphetamineConcentration, + 10); + // 描述 冰毒(甲基苯丙胺) 的排名情况 + String describeMethamphetamineConcentrationRank = getDescribeMethamphetamineConcentrationRank(sortSewageDataDtos.get(sortSewageDataDtos.size()-1)); + WordUtils.createParagraph(doc, + ParagraphAlignment.LEFT, + yearMonth + "份," + + describeMethamphetamineConcentrationRank, + false, + 2); + + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "表4 陕西省污水处理厂冰毒浓度排名表", + "", + false, + 0); + + int analysisTableCols = taskStartDateChinaFormatList.size() * 2 + 1; + TableCreateUtils.fetchCityDrugAbuseConditionAnalysisTable(doc, 12, analysisTableCols, taskStartDateChinaFormatList, tableName2List, cityDrugAbuseConditionAnalysisData); + + WordUtils.createParagraphTitle(doc, "2、吗啡", false, 3); + + // 对数据进行排序 + List> sortSewageDataDtos1 = getSortSewageDataDtos(sewageDataDtoLists, + Comparator.comparing(SewageDataDto::getMorphineConcentration).reversed()); + List> cityDrugAbuseConditionAnalysisData1 = fetchCityDrugAbuseConditionAnalysisData( + sortSewageDataDtos1, + SewageDataDto::getMorphineConcentration, + 15); // 吗啡是列表前15名的污水厂 + + WordUtils.createParagraph(doc, + ParagraphAlignment.LEFT, + yearMonth + "份吗啡对全省毒品消费总量贡献较大," + getDescribeMorphineConcentrationRank(sortSewageDataDtos1.get(sortSewageDataDtos1.size() - 1)), + false, + 2); + + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "表5 陕西省污水处理厂吗啡检测情况", + "", + false, + 0); + + List tableName4List = new ArrayList<>(Arrays.asList("污水处理厂名称","吗啡(ng/L)")); + + TableCreateUtils.fetchCityDrugAbuseConditionAnalysisTable(doc, 17, analysisTableCols, taskStartDateChinaFormatList, tableName4List,cityDrugAbuseConditionAnalysisData1); + + WordUtils.createParagraphAndBold(doc, ParagraphAlignment.LEFT, "注:", "100 ng/L为公安部禁毒情报技术中心定义的警戒值。", false, 2); + + TableCreateUtils.subsection(doc, TableCreateUtils.SUBSECTIONONE); + WordUtils.createParagraphAndBold( + doc, + ParagraphAlignment.CENTER, + "附表:陕西省各污水厂监测点主要毒品及其代谢物每日浓度表", + "", + false, + 0); + List tableName5List = getDailyDrugAndMetaboliteConcentrationName(reportConfigDTOSFilterHeroin, dto.getPopulationMarkers()); +// List tableName5List = new ArrayList<>(Arrays.asList("可替宁","可待因","MDA","MDMA","可卡因","苯甲酰爱康宁","吗啡","O6-单乙酰吗啡","甲基苯丙胺","苯丙胺","氯胺酮","去甲氯胺酮","芬太尼")); + Map>> map = generateDailyDrugAndMetaboliteConcentrationData(sewageDataGroupByMap, tableName5List); + // 加2 的原因是有两行表头 + TableCreateUtils.fetchDailyDrugAndMetaboliteConcentrationTable(doc, sewageDataDtos.size() + 2, 17, tableName5List, map); + TableCreateUtils.subsection(doc, TableCreateUtils.SUBSECTIONTWO); + // 因为设置横向后,多出了一页空白页,直接删除最后一页 +// int pages = doc.getBodyElements().size(); +// doc.removeBodyElement(pages - 1); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + doc.write(outputStream); + doc.close(); + String fileSaveMinioPath = OSSDirectoryConstants.DOCUMENT_SEWAGE_REPORTS_DIRECTORY + "/" + yearMonth + "/" + taskInfo.getId() + "/" + yearMonth + "份"+ province +"污水专项检测毒品分析报告.docx"; +// WordUtils.saveAs(doc, "污水报告测试-111.docx", "C:\\Users\\27109\\Desktop\\DesktopFiles\\PersonalFile\\workFile\\LianChuang\\task\\污水报告\\"); + ossFile.fileSave(fileSaveMinioPath, new ByteArrayInputStream(outputStream.toByteArray())); + return fileSaveMinioPath; + } + + /** + * 获取附表:陕西省各污水厂监测点主要毒品及其代谢物每日浓度表中的毒品名称 + * @param commonDrugAndMetabolites + * @param populationMarkers + * @return + */ + private List getDailyDrugAndMetaboliteConcentrationName(List commonDrugAndMetabolites, List populationMarkers) { + List dailyDrugAndMetaboliteConcentrationName = populationMarkers.stream().map(ReportConfigDTO::getDictLabel).collect(Collectors.toList()); + dailyDrugAndMetaboliteConcentrationName.addAll(commonDrugAndMetabolites.stream().map(ReportConfigDTO::getDictLabel).collect(Collectors.toList())); + return dailyDrugAndMetaboliteConcentrationName; + } + + /** + * 生成每常见毒品及代谢物的描述 + * @param reportConfigDTOSFilterHeroin + * @return + */ + private String getCommonDrugMetabolites(List reportConfigDTOSFilterHeroin) { + StringBuilder stringBuilder = new StringBuilder(); + Map> reportConfigGroupMap = reportConfigDTOSFilterHeroin.stream().collect(Collectors.groupingBy(ReportConfigDTO::getDictType)); + reportConfigGroupMap.forEach((dictType, reportConfigs) -> { + Map> reportConfigsByType = reportConfigs.stream().collect(Collectors.groupingBy(ReportConfigDTO::getType)); + List commonDrugs = reportConfigsByType.getOrDefault("1", Collections.emptyList()); + List metabolites = reportConfigsByType.getOrDefault("2", Collections.emptyList()); + // 常见毒品和代谢物都不可能为空 + if (CollUtil.isNotEmpty(commonDrugs)) { + stringBuilder.append(commonDrugs.get(0).getDictLabel()); + if (CollUtil.isNotEmpty(metabolites)) { + String metaboliteLabels = metabolites.stream() + .map(configDTO -> configDTO.getDictLabel() + configDTO.getRemark()) + .collect(Collectors.joining("、")); + stringBuilder.append("、").append(metaboliteLabels); + } + stringBuilder.append(";"); + } else { + String metaboliteLabels = metabolites.stream() + .map(configDTO -> configDTO.getDictLabel() + configDTO.getRemark()) + .collect(Collectors.joining("、")); + stringBuilder.append(metaboliteLabels).append(";"); + } + }); + String resultStr = stringBuilder.toString(); + if (StrUtil.isNotBlank(resultStr)) { + return resultStr.substring(0, resultStr.length() - 1) + "。"; + } + return ""; + } + + /** + * 生成人口标记物的描述 + * @param reportConfigDTOS + * @return + */ + private String getPopulationMarking(List reportConfigDTOS) { + StringBuilder stringBuilder = new StringBuilder(); + Map> reportConfigGroupMap = reportConfigDTOS.stream().collect(Collectors.groupingBy(ReportConfigDTO::getDictType)); + reportConfigGroupMap.forEach((dictType, reportConfigs) -> { + Map> reportConfigsByType = reportConfigs.stream().collect(Collectors.groupingBy(ReportConfigDTO::getType)); + List commonDrugs = reportConfigsByType.getOrDefault("1", Collections.emptyList()); + List metabolites = reportConfigsByType.getOrDefault("2", Collections.emptyList()); + // 常见毒品和代谢物都不可能为空 + if (CollUtil.isNotEmpty(commonDrugs)) { + stringBuilder.append(commonDrugs.get(0).getDictLabel()).append(commonDrugs.get(0).getRemark()); + if (CollUtil.isNotEmpty(metabolites)) { + String metaboliteLabels = metabolites.stream() + .map(configDTO -> configDTO.getDictLabel() + configDTO.getRemark()) + .collect(Collectors.joining("、")); + stringBuilder.append("、").append(metaboliteLabels); + } + stringBuilder.append(";"); + } else { + String metaboliteLabels = metabolites.stream() + .map(configDTO -> configDTO.getDictLabel() + configDTO.getRemark()) + .collect(Collectors.joining("、")); + stringBuilder.append(metaboliteLabels).append(";"); + } + }); + String resultStr = stringBuilder.toString(); + if (StrUtil.isNotBlank(resultStr)) { + return resultStr.substring(0, resultStr.length() - 1) + "。"; + } + return ""; + } + + /** + * 组装生成依托咪酯的统计数据 + * @param sewageDataGroupByMap + * @param tableDataList + */ + private void getEtomidateDetectedStatisticalData(Map> sewageDataGroupByMap, List> tableDataList) { +// int materialSize = sewageDataDtos.size(); // 污水样品的总数量 +// int plantSize = sewagePlantNum.size(); + sewageDataGroupByMap.forEach((k,v) -> { + int materialSize = v.size(); // 污水样品的总数量 + Set sewagePlantNum = v.stream().map(sewageDataDto -> StrUtil.split(sewageDataDto.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + int plantSize = sewagePlantNum.size(); + List subDataList = new ArrayList<>(); + subDataList.add(k); // 行政区名称 + subDataList.add(plantSize);// 污水厂数量 + subDataList.add(materialSize); // 污水样品数量 + // 检出依托咪酯的污水厂 + List detectedEtomidateList = v.stream().filter(sewageDataDto -> sewageDataDto.getEtomidateConcentration() != 0).collect(Collectors.toList()); + Set sewagePlantNameList = detectedEtomidateList.stream().map(sewageDataDto -> StrUtil.split(sewageDataDto.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + int detectedEtomidatePlantSize = sewagePlantNameList.size(); + int detectedEtomidateMaterialSize = detectedEtomidateList.size(); + subDataList.add(detectedEtomidatePlantSize);// 污水厂检出数量 + subDataList.add(detectedEtomidateMaterialSize); // 样品检出数量 + subDataList.add(Math.ceil(detectedEtomidateMaterialSize / (double) materialSize * 100) + "%"); // 样品检出百分比 + subDataList.add(Math.ceil(detectedEtomidatePlantSize / (double) plantSize * 100) + "%"); // 污水厂检出百分比 + subDataList.add(sewagePlantNameList.stream().collect(Collectors.joining(","))); + tableDataList.add(subDataList); + }); + } + + /** + * 生成相关依托咪酯相关的滥用现状 + * @param yearMonth + * @param sewageDataDtos + * @return + */ + private String getEtomidateAbuseSCurrentSituation(String yearMonth, List sewageDataDtos) { + StringBuilder stringBuilder = new StringBuilder(); + List sewageDataDtosDetectedEtomidate = sewageDataDtos.stream().filter(o -> o.getEtomidateConcentration() != 0).collect(Collectors.toList()); + Set sewagePlantNum = sewageDataDtosDetectedEtomidate.stream().map(o -> StrUtil.split(o.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + + stringBuilder + .append(yearMonth) + .append("检测的全省污水中依托咪酯含量,发现全省有") + .append(sewagePlantNum.size()) + .append("家污水厂共") + .append(sewageDataDtosDetectedEtomidate.size()) + .append("份污水样品存在依托咪酯检出,详情见表3。"); + + return stringBuilder.toString(); + } + + /** + * 生成氯胺酮/可卡因/摇头丸的滥用现状描述 + * + * @param yearMonth + * @param sewageDataDtos + * @param provinceDataList + * @param sewagePlantNum + * @param predicate 筛选的函数式条件 + * @param comparator 排序的函数式条件 + * @param drugName 毒品名称 + * @return + */ + private String getDrugAbuseCurrentSituation(String yearMonth, + List sewageDataDtos, + List provinceDataList, + Set sewagePlantNum, + Predicate predicate, + Comparator comparator, + Function function, + String drugName) { + StringBuilder stringBuilder = new StringBuilder(); + // 筛选出氯胺酮浓度不为0的检材 + List sewageDataDtosByDetected = sewageDataDtos.stream().filter(predicate).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(sewageDataDtosByDetected)) { + if (sewageDataDtosByDetected.size() == 1) { + SewageDataDto sewageDataDto = sewageDataDtosByDetected.get(0); + stringBuilder.append("本次监测中,在") + .append(sewageDataDto.getCityName()) + .append(StrUtil.split(sewageDataDto.getSampleName(), "-").get(0)) + .append("中有") + .append(keep1DecimalPlace.format(function.apply(sewageDataDto))) + .append("ng/L的"+drugName+"检出,其他地市均未检出,说明全省范围内无明显滥用,需长期关注,掌握变化趋势。"); + } else { + // 列表不为空 + // 计算有多少个污水厂检出 + Set detectedKetaminePlant = sewageDataDtosByDetected.stream().map(o -> StrUtil.split(o.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + List detectedCity = new ArrayList<>(sewageDataDtosByDetected.stream().map(SewageDataDto::getCityName).collect(Collectors.toSet())); + List sewageDataDtosByDetectedKetamineSorted = sewageDataDtosByDetected.stream().sorted(comparator).collect(Collectors.toList()); + int lastYear = Year.now().minusYears(1).getValue(); + stringBuilder + .append(yearMonth) + .append("在") + .append(keep1DecimalPlace.format( + detectedKetaminePlant.size() / (double) sewagePlantNum.size() * 100)) + .append("%") + .append("的污水处理厂均有") + .append(drugName) + .append("检出,与") + .append(lastYear) + .append("相比,") + .append(yearMonth) + .append("份") + .append(drugName) + .append("滥用"); + RegionalDrugConsumptionDTO yearOnYear = provinceDataList.get(0); + RegionalDrugConsumptionDTO dto = provinceDataList.get(provinceDataList.size() - 1); + double yoyKetamineCon = Double.parseDouble(yearOnYear.getTcK()); + double ketamineCon = Double.parseDouble(dto.getTcK()); + if (yoyKetamineCon > ketamineCon) { + stringBuilder.append("逐渐下降,"); + } else if (yoyKetamineCon < ketamineCon) { + stringBuilder.append("明显增加,"); + } else { + stringBuilder.append("程度没有变化,"); + } + + int citySize = detectedCity.size(); + for (String city : detectedCity) { + int indexOf = detectedCity.indexOf(city); + if (indexOf == 0) { + stringBuilder.append(city); + } else if (indexOf == citySize - 1 && citySize >= 2) { + stringBuilder.append("和").append(city); + } else { + stringBuilder.append("、").append(city); + } + } + stringBuilder + .append(citySize) + .append("个地市(") + .append(detectedKetaminePlant.size()) + .append("个污水处理厂)中均有检出,") + .append(drugName) + .append("浓度范围为") + .append(keep1DecimalPlace.format(function.apply(sewageDataDtosByDetectedKetamineSorted + .get(0) + ) + ) + ) + .append("~") + .append(keep1DecimalPlace.format(function.apply(sewageDataDtosByDetectedKetamineSorted + .get(sewageDataDtosByDetectedKetamineSorted.size() - 1) + ) + ) + ) + .append(" ng/L,后续检测中可持续关注。"); + } + } else { + stringBuilder.append("在本次监测中均未检出,说明不存在").append(drugName).append("的明显滥用。"); + } + return stringBuilder.toString(); + } + + /** + * 生成海洛因的滥用现状 + * + * @param yearMonth + * @param sewageDataDtos + * @param regionalDrugConsumptionDTOMap + * @param allProvince + * @param sewagePlantNum + * @return + */ + private String getHeroinAbuseCurrentSituation(String yearMonth, List sewageDataDtos, Map regionalDrugConsumptionDTOMap, RegionalDrugConsumptionDTO allProvince, Set sewagePlantNum) { + StringBuilder stringBuilder = new StringBuilder(); + List sewageDataDtosByMorphine = sewageDataDtos.stream().filter(o -> o.getMorphineConcentration() != 0).collect(Collectors.toList()); + Set detectedMorphineNum = sewageDataDtosByMorphine.stream().map(o -> StrUtil.split(o.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + double pccHeroinProvince = Double.parseDouble(allProvince.getPccHeroin()); + double tcHeroinProvince = Double.parseDouble(allProvince.getTcHeroin()); + if (pccHeroinProvince != 0 && tcHeroinProvince != 0) { + stringBuilder + .append(yearMonth) + .append("在") + .append(keep1DecimalPlace.format( + detectedMorphineNum.size() / (double) sewagePlantNum.size() * 100)) + .append("%的污水处理厂均有吗啡检出(海洛因的代谢物)。") + .append("陕西省海洛因的千人均消费量") + .append(allProvince.getPccHeroin()) + .append("毫克/千人/天,核算海洛因的总消费量为") + .append(allProvince.getTcHeroin()) + .append("克/天。特别指出,根据污水中的吗啡和可待因的浓度计算海洛因消费量时,粗略扣除了合法药物、医用吗啡以及磷酸可待因代谢吗啡的干扰,但未充分考虑干扰的区域性和季节性差异,因而存在一定误差,结果仅供参考。"); + } else { + stringBuilder.append("在本次监测中均未检出,说明不存在海洛因的明显滥用。"); + } + + return stringBuilder.toString(); + } + + /** + * 生成冰毒的滥用现状描述 + * @param yearMonth + * @param sewageDataDtos + * @param regionalDrugConsumptionDTOMap + * @param allProvince + * @return + */ + private String getMethamphetamineAbuseCurrentSituation(String yearMonth, List sewageDataDtos, Map regionalDrugConsumptionDTOMap, RegionalDrugConsumptionDTO allProvince, Set sewagePlantNum) { + StringBuilder stringBuilder = new StringBuilder(); + // 筛选检出冰毒的污水厂 + List sewageDataDtosByDetectedMa = sewageDataDtos.stream().filter(o -> o.getPccMa() != 0).collect(Collectors.toList()); + if (CollUtil.isNotEmpty(sewageDataDtosByDetectedMa)) { + // 计算出检测冰毒的污水厂比例 + Set detectedMaSewagePlantNum = sewageDataDtosByDetectedMa.stream().map(o -> StrUtil.split(o.getSampleName(), "-").get(0)).collect(Collectors.toSet()); + RegionalDrugConsumptionDTO dto = regionalDrugConsumptionDTOMap.get("西安市"); + double maPercent = Double.parseDouble(dto.getTcMa()) / Double.parseDouble(allProvince.getTcMa()); + stringBuilder + .append(yearMonth) + .append("份在") + .append(keep1DecimalPlace.format( + detectedMaSewagePlantNum.size() / (double) sewagePlantNum.size() * 100) + ) + .append("%的污水厂有冰毒及其代谢物检出。") + .append("全省冰毒的千人均消费量为") + .append(allProvince.getPccMa()) + .append("毫克/千人/天,核算陕西省冰毒的总消费量为") + .append(allProvince.getTcMa()) + .append("克/天。").append("西安冰毒总消费量为") + .append(dto.getTcMa()) + .append("克/天,占全省总消费量的") + .append(keep1DecimalPlace.format(maPercent)) + .append("%"); + } else { + stringBuilder.append("在本次监测中均未检出,说明不存在冰毒的明显滥用。"); + } + + return stringBuilder.toString(); + } + + /** + * 全省冰毒千人均消费量 描述 + * @param allTaskProvinceDrugConsumptionList + * @param taskStartDateChinaFormatList + * @return + */ + private String analysisMethamphetamineProvinceAbuseTendDescribe(List allTaskProvinceDrugConsumptionList, List taskStartDateChinaFormatList) { + StringBuilder stringBuilder = new StringBuilder(); + int size = allTaskProvinceDrugConsumptionList.size(); + if (size < 2) { + return ""; + } + RegionalDrugConsumptionDTO nowTaskData = allTaskProvinceDrugConsumptionList.get(size - 1); + double nowTaskMaData = Double.parseDouble(nowTaskData.getPccMa()); + boolean yearDecline = false; // 标记同比是否下降, true 是在下降, false 不是 + boolean monthDecline = false; // 标记环比是否下降, true 是在下降, false 不是 + for (int i = 0; i < size - 1; i++) { + RegionalDrugConsumptionDTO dto = allTaskProvinceDrugConsumptionList.get(i); + double oldTaskMaData = Double.parseDouble(dto.getPccMa()); + double abs = Math.abs((nowTaskMaData - oldTaskMaData) / oldTaskMaData * 100); + switch (i) { + case 0: { + stringBuilder + .append("全省冰毒千人均消费量") + .append(taskStartDateChinaFormatList.get(size - 1)) + .append("(") + .append(nowTaskMaData) + .append("毫克/千人/天)") + .append("与") + .append(taskStartDateChinaFormatList.get(i)) + .append("(") + .append(oldTaskMaData) + .append("毫克/千人/天)相比,"); + if (size == 2) { + stringBuilder.append("环比"); + } else { + stringBuilder.append("同比"); + } + if (oldTaskMaData > nowTaskMaData) { + yearDecline = true; + stringBuilder.append("下降"); + } else { + yearDecline = false; + stringBuilder.append("增加"); + } + stringBuilder.append(keep1DecimalPlace.format(abs)).append("%"); + if (size == 2) { + stringBuilder.append("全省冰毒滥用趋势"); + if (yearDecline) { + stringBuilder.append("逐渐下降"); + } else { + stringBuilder.append("明显增加"); + } + stringBuilder.append("。"); + } else { + stringBuilder.append(","); + } + break; + } + default: { + if (i == size - 2) { + stringBuilder + .append("与") + .append(taskStartDateChinaFormatList.get(i)) + .append("(") + .append(oldTaskMaData) + .append("毫克/千人/天)相比,") + .append("环比"); + if (oldTaskMaData > nowTaskMaData) { + monthDecline = true; + stringBuilder.append("下降"); + } else { + monthDecline = false; + stringBuilder.append("增加"); + } + stringBuilder + .append(keep1DecimalPlace.format( + abs + ) + ) + .append("%,"); + if(yearDecline && monthDecline || monthDecline) { + stringBuilder.append("全省冰毒滥用趋势逐渐下降。"); + } else if (yearDecline) { + stringBuilder.append("全省冰毒滥用趋势明显增加。"); + } + } + } + } + } + return stringBuilder.toString(); + } + + /** + * 生成全省海洛因的消费量变化趋势描述 + * + * @param allTaskProvinceDrugConsumptionList + * @param taskStartDateChinaFormatList + * @return + */ + private String analysisHeroinProvinceAbuseTendDescribe(List allTaskProvinceDrugConsumptionList, List taskStartDateChinaFormatList) { + + StringBuilder stringBuilder = new StringBuilder(); + int size = allTaskProvinceDrugConsumptionList.size(); + if (size < 2) { + return ""; + } + RegionalDrugConsumptionDTO nowTaskData = allTaskProvinceDrugConsumptionList.get(size - 1); + double nowTaskHeroinData = Double.parseDouble(nowTaskData.getPccHeroin()); + boolean yearDecline = false; // 标记同比是否下降, true 是在下降, false 不是 + boolean monthDecline = false; // 标记环比是否下降, true 是在下降, false 不是 + for (int i = 0; i < size - 1; i++) { + RegionalDrugConsumptionDTO dto = allTaskProvinceDrugConsumptionList.get(i); + double oldTaskHeroinData = Double.parseDouble(dto.getPccHeroin()); + double abs = Math.abs((nowTaskHeroinData - oldTaskHeroinData) / oldTaskHeroinData * 100); + switch (i) { + case 0: { + stringBuilder + .append(taskStartDateChinaFormatList.get(size - 1)) + .append("(") + .append(nowTaskHeroinData) + .append("毫克/千人/天)") + .append("与") + .append(taskStartDateChinaFormatList.get(i)) + .append("(") + .append(oldTaskHeroinData) + .append("毫克/千人/天)相比,"); + if (size == 2) { + stringBuilder.append("环比"); + } else { + stringBuilder.append("同比"); + } + if (oldTaskHeroinData > nowTaskHeroinData) { + yearDecline = true; + stringBuilder.append("下降"); + } else { + yearDecline = false; + stringBuilder.append("增加"); + } + stringBuilder.append(keep1DecimalPlace.format(abs)).append("%"); + if (size == 2) { + stringBuilder.append("海洛因滥用趋势"); + if (yearDecline) { + stringBuilder.append("逐渐下降"); + } else { + stringBuilder.append("明显增加"); + } + stringBuilder.append("。"); + } else { + stringBuilder.append(","); + } + break; + } + default: { + if (i == size - 2) { + stringBuilder + .append("与") + .append(taskStartDateChinaFormatList.get(i)) + .append("(") + .append(oldTaskHeroinData) + .append("毫克/千人/天)相比,") + .append("环比"); + if (oldTaskHeroinData > nowTaskHeroinData) { + monthDecline = true; + stringBuilder.append("下降"); + } else { + monthDecline = false; + stringBuilder.append("增加"); + } + stringBuilder + .append(keep1DecimalPlace.format( + abs + ) + ) + .append("%,"); + if(yearDecline && monthDecline || monthDecline) { + stringBuilder.append("海洛因滥用趋势逐渐下降。"); + } else if (yearDecline) { + stringBuilder.append("海洛因滥用趋势明显增加。"); + } + } + } + } + } + return stringBuilder.toString(); + } + + /** + * 各行政区毒品滥用水平排序(即综合千人均消费量排序) + * @param pccRegionalDrugConsumptionDTOS1 + * @return + */ + private String getCombinedThousandPerConsumptionSortedDesc(List pccRegionalDrugConsumptionDTOS1) { + StringBuilder stringBuilder = new StringBuilder(); + for (RegionalDrugConsumptionDTO regionalDrugConsumptionDTO : pccRegionalDrugConsumptionDTOS1) { + if (pccRegionalDrugConsumptionDTOS1.indexOf(regionalDrugConsumptionDTO) == 0) { + stringBuilder.append(regionalDrugConsumptionDTO.getRegional()); + } else { + if (regionalDrugConsumptionDTO.getRegional().contains("全省平均")) { + stringBuilder.append("≧"); + } else { + stringBuilder.append(">"); + } + stringBuilder.append(regionalDrugConsumptionDTO.getRegional()); + } + } + stringBuilder.append("。"); + return stringBuilder.toString(); + } + + /** + * 全省各行政区 综合千人均消费量 排名描述 + * + * @param pccRegionalDrugConsumptionDTOS + * @param allProvince 当前季度全省的消费量统计 + * @return + */ + private String getCombinedThousandPerConsumptionCompareDescribe(List pccRegionalDrugConsumptionDTOS, RegionalDrugConsumptionDTO allProvince) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder + .append("全省各行政区千人均变化趋势如图2所示,全省平均千人均消费量为") + .append(allProvince.getPccTotal()).append("毫克/千人/天,"); + + int size = pccRegionalDrugConsumptionDTOS.size(); + for (int i = 0; i < size && i < 5; i++) { // 只用循环5次 + RegionalDrugConsumptionDTO dto = pccRegionalDrugConsumptionDTOS.get(i); + double pccTotal = Double.parseDouble(dto.getPccTotal()); + switch (i) { + case 0: { + stringBuilder + .append(dto.getRegional()) + .append("的综合千人均消费量最高,为") + .append(dto.getPccTotal()) + .append("毫克/千人/天,是全省平均水平的") + .append( + keep1DecimalPlace.format( + pccTotal / Double.parseDouble(allProvince.getPccTotal()))) + .append("倍;"); + break; + } + case 1: { + stringBuilder.append("其次是").append(dto.getRegional()); + if (size >= 3) { + stringBuilder.append("和").append(pccRegionalDrugConsumptionDTOS.get(i + 1).getRegional()); + } + stringBuilder.append(",综合千人均消费量为").append(dto.getPccTotal()).append("毫克/千人/天"); + if (size >= 3) { + stringBuilder.append("和").append(pccRegionalDrugConsumptionDTOS.get(i + 1).getPccTotal()).append("毫克/千人/天"); + } + stringBuilder.append(";"); + break; + } + case 3: { + stringBuilder + .append("位居第四的是") + .append(dto.getRegional()) + .append(",综合千人均消费量分别为") + .append(dto.getPccTotal()) + .append("毫克/千人/天;"); + break; + } + case 4: { + stringBuilder.append("位居第五"); + if (size > 5) { + stringBuilder.append("至").append(NumberTransferHanZi.getHanZiNameByNumber(size)).append("位的分别是"); + } else { + stringBuilder.append("位的是"); + } + stringBuilder.append(dto.getRegional()); + for (int j = 5; j < size; j++) { + RegionalDrugConsumptionDTO consumptionDTO = pccRegionalDrugConsumptionDTOS.get(j); + if (pccRegionalDrugConsumptionDTOS.indexOf(consumptionDTO) == (size - 1)) { + stringBuilder.append("和").append(consumptionDTO.getRegional()); + } else { + stringBuilder.append("、").append(consumptionDTO.getRegional()); + } + } + stringBuilder.append(",综合千人均消费量分别为").append(dto.getPccTotal()).append("毫克/千人/天"); + for (int j = 5; j < size; j++) { + RegionalDrugConsumptionDTO consumptionDTO = pccRegionalDrugConsumptionDTOS.get(j); + if (pccRegionalDrugConsumptionDTOS.indexOf(consumptionDTO) == (size - 1)) { + stringBuilder.append("和").append(consumptionDTO.getPccTotal()).append("毫克/千人/天"); + } else { + stringBuilder.append("、").append(consumptionDTO.getPccTotal()).append("毫克/千人/天"); + } + } + stringBuilder.append("。"); + } + } + } + + return stringBuilder.toString(); + } + + /*** + * 各行政区毒品滥用总量排序(即综合总消费量排序) + * @param regionalDrugConsumptionDTOS + * @return + */ + private String getCombinedTotalConsumptionSortedDesc(List regionalDrugConsumptionDTOS) { + StringBuilder stringBuilder = new StringBuilder(); + for (RegionalDrugConsumptionDTO regionalDrugConsumptionDTO : regionalDrugConsumptionDTOS) { + stringBuilder.append(regionalDrugConsumptionDTO.getRegional()); + if (regionalDrugConsumptionDTOS.indexOf(regionalDrugConsumptionDTO) == (regionalDrugConsumptionDTOS.size() - 1)) { + stringBuilder.append("。"); + } else { + stringBuilder.append(">"); + } + } + return stringBuilder.toString(); + } + + /** + * 各行政区中的综合总消费量比较和描述 + * @param regionalDrugConsumptionDTOS + * @return + */ + private String compareEachCityCombinedTotalConsumptionDescribe(List regionalDrugConsumptionDTOS) { + + StringBuilder stringBuilder = new StringBuilder(); + double sum = regionalDrugConsumptionDTOS.stream().mapToDouble(o -> Double.parseDouble(o.getTcTotal())).sum(); + int size = regionalDrugConsumptionDTOS.size(); + for (int i = 0; i < size && i < 6; i++) { + RegionalDrugConsumptionDTO dto = regionalDrugConsumptionDTOS.get(i); + double v = Double.parseDouble(dto.getTcTotal()); // 当前地区的综合消费量 + switch (i) { + case 0: { + stringBuilder + .append("按行政区,") + .append(dto.getRegional()) + .append("的综合总消费量最高为") + .append(dto.getTcTotal()) + .append("克/天,占全省监测区域消费总量的") + .append(keep1DecimalPlace.format(v / sum * 100)) + .append("%;"); + break; + } + case 1: { + stringBuilder + .append("其次是") + .append(dto.getRegional()) + .append(",综合总消费量为") + .append(dto.getTcTotal()) + .append("克/天,") + .append("分别占全省监测区域消费总量的") + .append(keep1DecimalPlace.format(v / sum * 100)) + .append("%;"); + break; + } + case 2: { + stringBuilder.append("位居第三"); + if (size >= 4) { + // 判断当前季度任务下送检的样品地市是否超过 + stringBuilder.append("、第四"); + } + if (size >= 5) { + stringBuilder.append("、第五"); + } + stringBuilder.append("的是").append(dto.getRegional()); + if (size >= 4) { + stringBuilder.append("、").append(regionalDrugConsumptionDTOS.get(i + 1).getRegional()); + } + if (size >= 5) { + stringBuilder.append("、").append(regionalDrugConsumptionDTOS.get(i + 2).getRegional()); + } + + stringBuilder.append(",综合总消费量分别为").append(dto.getTcTotal()).append("克/天"); + if (size >= 4) { + stringBuilder.append("、").append(regionalDrugConsumptionDTOS.get(i + 1).getTcTotal()).append("克/天"); + } + if (size >= 5) { + stringBuilder.append("、").append(regionalDrugConsumptionDTOS.get(i + 2).getTcTotal()).append("克/天"); + } + + stringBuilder + .append(",占全省监测区域消费总量的") + .append(keep1DecimalPlace.format(v / sum * 100)) + .append("%"); + if (size >= 4) { + stringBuilder.append("、") + .append(keep1DecimalPlace.format( + Double.parseDouble(regionalDrugConsumptionDTOS.get(i + 1).getTcTotal()) / sum * 100)) + .append("%"); + } + if (size >= 5) { + stringBuilder.append("、") + .append(keep1DecimalPlace.format( + Double.parseDouble(regionalDrugConsumptionDTOS.get(i + 2).getTcTotal()) / sum * 100)) + .append("%"); + } + stringBuilder.append(";"); + break; + } + case 5: { + stringBuilder + .append("其余") + .append(size - i) + .append("个行政区综合总消费量均低于") + .append(Math.ceil(v)) + .append("克/天,") + .append("占比均低于") + .append(Math.ceil(v / sum * 100)) + .append("%"); + break; + } + } + } + stringBuilder.append("。"); + return stringBuilder.toString(); + } + + /** + * 根据flag决定时根据综合总消费量进行排序还是综合千人均消费量排序 + * @param regionalDrugConsumptionDTOList + * @param flag true -> 综合总消费量 false 综合千人均消费量 + * @param remove 是否移除最后一个全省的消费量 + * @return + */ + private static List getRegionalDrugConsumptionDTOSSortedDesc(List regionalDrugConsumptionDTOList, boolean flag, boolean remove) { + List regionalDrugConsumptionDTOS = new ArrayList<>(regionalDrugConsumptionDTOList); + if (remove) { + // 对综合总消费量排序时要排除全省的 + regionalDrugConsumptionDTOS.remove(regionalDrugConsumptionDTOS.size() - 1); + } + Collections.sort(regionalDrugConsumptionDTOS, new Comparator() { + @Override + public int compare(RegionalDrugConsumptionDTO o1, RegionalDrugConsumptionDTO o2) { + Double o1V = Double.parseDouble(flag ? o1.getTcTotal() : o1.getPccTotal()); + Double o2V = Double.parseDouble(flag ? o2.getTcTotal() : o2.getPccTotal()); + return o2V.compareTo(o1V); + } + }); + return regionalDrugConsumptionDTOS; + } + + /** + * 描述 冰毒(甲基苯丙胺) 在 陕西省污水处理厂冰毒浓度排名 + * @param sewageDataDtos + * @return + */ + private String getDescribeMethamphetamineConcentrationRank(List sewageDataDtos) { + + String resultStr = ""; + for (int i = 0; i < sewageDataDtos.size() && i < 3; i++) { + SewageDataDto sewageDataDto = sewageDataDtos.get(i); + String sewagePlantName = StrUtil.split(sewageDataDto.getSampleName(), "-").get(0); + Double methamphetamineConcentration = sewageDataDto.getMethamphetamineConcentration(); + switch (i) { + case 0: { + resultStr = resultStr + "陕西省的甲基苯丙胺浓度范围为0(表示未检出,下同)~"+ + keep1DecimalPlace.format(methamphetamineConcentration) +"ng/L。" + "各污水厂检测数据中,浓度最高的" + + sewagePlantName + + "," + "甲基苯丙胺含量为"+ + keep1DecimalPlace.format(methamphetamineConcentration) +" ng/L;"; + break; + } + case 1: { + resultStr = resultStr + + "排名第二的是" + + sewagePlantName + "," + + "甲基苯丙胺含量为"+ + keep1DecimalPlace.format(methamphetamineConcentration) +" ng/L;"; + break; + } + case 2: { + resultStr = resultStr + + "排名第三的是" + + sewagePlantName + "," + + "甲基苯丙胺含量为"+ + keep1DecimalPlace.format(methamphetamineConcentration) +" ng/L。"; + break; + } + } + + } + return resultStr; + } + + /** + * 描述 吗啡 在 陕西省污水处理厂冰毒浓度排名 + * @param sewageDataDtos + * @return + */ + private String getDescribeMorphineConcentrationRank(List sewageDataDtos) { + // 筛选大于100ng/L的数量 + long count = sewageDataDtos.stream().filter(o -> o.getMorphineConcentration() > 100).count(); + String resultStr = ""; + for (int i = 0; i < sewageDataDtos.size() && i < 3; i++) { + SewageDataDto sewageDataDto = sewageDataDtos.get(i); + String sewagePlantName = StrUtil.split(sewageDataDto.getSampleName(), "-").get(0); + Double morphineConcentration = sewageDataDto.getMorphineConcentration(); + switch (i) { + case 0: { + resultStr = resultStr + + "吗啡日浓度范围为0(表示未检出,下同)~"+ + keep1DecimalPlace.format(morphineConcentration) +"ng/L。" + "其中全省" + + (count == 0 ? "没有" : ("有" + count + "个")) + + "污水处理厂的吗啡浓度高于100 ng/L。" + + "表5列出了吗啡浓度排名前15的污水处理厂。" + "浓度最高的是" + + sewagePlantName + + "," + "吗啡浓度为"+ + keep1DecimalPlace.format(morphineConcentration) +" ng/L;"; + break; + } + case 1: { + resultStr = resultStr + + "排名第二的是" + + sewagePlantName + "," + + "吗啡浓度为"+ + keep1DecimalPlace.format(morphineConcentration) +" ng/L;"; + break; + } + case 2: { + resultStr = resultStr + + "排名第三的是" + + sewagePlantName + + "吗啡浓度为"+ + keep1DecimalPlace.format(morphineConcentration) +" ng/L。"; + break; + } + } + } + return resultStr; + } + + /** + * 组装陕西省毒品滥用情况分析 - 各污水厂毒品浓度排名表 + * @param sortSewageDataDtos + * @param mapper + * @param cols 表格的行数 + * @return + */ + private List> fetchCityDrugAbuseConditionAnalysisData(List> sortSewageDataDtos, Function mapper, Integer cols) { + List> list = new ArrayList<>(); +// List> sortSewageDataDtos = getSortSewageDataDtos(sewageDataDtoLists, sort); + // 11 是表格的列数, + for (int i = 0; i < cols; i++) { + List subList = new ArrayList<>(); + // 添加数据 + subList.add(i + 1); + list.add(subList); + } + for (int i = 0; i < sortSewageDataDtos.size(); i++) { + List sewageDataDtos = sortSewageDataDtos.get(i); + List concentrationList = sewageDataDtos.stream().map(mapper::apply).collect(Collectors.toList()); + for (int j = 0; j < cols; j++) { + List subList = null; + + subList = list.get(j); + if (j < sewageDataDtos.size()) { + SewageDataDto sewageDataDto = sewageDataDtos.get(j); + subList.add(StrUtil.split(sewageDataDto.getSampleName(), "-").get(0)); + subList.add(keep1DecimalPlace.format(concentrationList.get(j))); + } else { + subList.add(""); + subList.add(""); + } + } + } + + return list; + } + + /** + * 根据检材检测出的毒品浓度进行排序 + * @param sewageDataDtoLists + * @param sort + * @return + */ + private static List> getSortSewageDataDtos(List> sewageDataDtoLists, Comparator sort) { + List> sortSewageDataDtos = new ArrayList<>(); + // 进行排序-升序 + for (List sewageDataDtoList : sewageDataDtoLists) { + List sewageDataDtos = sewageDataDtoList.stream().sorted(sort).collect(Collectors.toList()); + sortSewageDataDtos.add(sewageDataDtos); + } + return sortSewageDataDtos; + } + + /** + * 获取一年内的任务检材数据 + * @param taskInfoList + * @param dto + * @return + */ + private List> getSewageTaskDataForAYear(List taskInfoList, ExportSewageAnalystReportsDTO dto) { + List> resultList = new ArrayList<>(); + for (int i = 0; i < taskInfoList.size() - 1; i++) { + TaskInfo taskInfo = taskInfoList.get(i); + // feign 接口调用获取 污水检材 + List data = getSewageJobIdentificationMaterialVOS(dto, taskInfo); + // 获取每个样品的数据 + List sewageDataDtos = taskInfoService.processSewageDataDtos(dto.getDailySmokingPerCapita(), data); + resultList.add(sewageDataDtos); + } + return resultList; + } + + /** + * 组装 表3 陕西省各污水厂服务区及各行政区毒品千人均消费量表 的数据 + * + * @param allMergeMegionalDrugConsumptionDTOList 之前季度的消费量数据 + * @param regionalDrugConsumptionDTOList 当前季度的消费数据 + * @param taskInfoList 任务列表, 目的是取同期的月份, 上期的月份, 本期的月份 + * @param cityNameList + * @return + */ + private List> fetchCityDrugConsumptionGrowthRatesData(List> allMergeMegionalDrugConsumptionDTOList, List regionalDrugConsumptionDTOList, List taskInfoList, List cityNameList) { + // 取上期的数据, 取0的原因是在计算时任务列表的顺序是升序的, 所有第一个元素就是上期的数据, 同理最后一个则是同期的数据 + List regionalDrugConsumptionDTOList_LastYear = allMergeMegionalDrugConsumptionDTOList.get(0); + List regionalDrugConsumptionDTOList_Last = allMergeMegionalDrugConsumptionDTOList.get(allMergeMegionalDrugConsumptionDTOList.size() - 1); + + // 上期数据 + List lastList = compareDiffQuarterCityDrugConsumptionGrowthRatesData( + regionalDrugConsumptionDTOList_Last, + regionalDrugConsumptionDTOList, + taskInfoList.get(taskInfoList.size() - 2), + cityNameList, true); + // 同期数据 + List lastYearList = compareDiffQuarterCityDrugConsumptionGrowthRatesData( + regionalDrugConsumptionDTOList_LastYear, + regionalDrugConsumptionDTOList, + taskInfoList.get(0), + cityNameList, + false); + + return new ArrayList<>(Arrays.asList(lastYearList, lastList)); + } + + /** + * 比较两个不同季度的消费量数据 + * @param sourceList 本期的数据 + * @param compareList 上期或者同期数据 + * @param taskInfo 比较的任务信息 + * @param cityNameList + * @param isMonthToMonth 是否是环比 + * @return + */ + private List compareDiffQuarterCityDrugConsumptionGrowthRatesData(List compareList, + List sourceList, + TaskInfo taskInfo, + List cityNameList, + boolean isMonthToMonth) { + // 先把两个列表转出map, 城市名是key + Map sourceMap = sourceList.stream().collect(Collectors.toMap(RegionalDrugConsumptionDTO::getRegional, Function.identity())); + Map compareMap = compareList.stream().collect(Collectors.toMap(RegionalDrugConsumptionDTO::getRegional, Function.identity())); + // 存数据的列表 + List dataList = new ArrayList<>(); + dataList.add("与" + taskInfo.getTaskStartDate().format(chineseYearSingleMonthFormatter) + (isMonthToMonth ? "环比" : "同比"));// 比较的任务月份 + + for (String cityName : cityNameList) { + RegionalDrugConsumptionDTO source = sourceMap.get(cityName); + RegionalDrugConsumptionDTO compare = compareMap.get(cityName); + if (source != null && compare != null) { + double compareV = Double.parseDouble(compare.getPccTotal()); + double sourceV = Double.parseDouble(source.getPccTotal()); + double rate = (sourceV - compareV) / compareV * 100; + dataList.add(keep1DecimalPlace.format(rate) + "%"); + } else { + // 默认添加空字符串 + dataList.add(""); + } + } + + return dataList; + } + + /** + * 根据得到的各个季度任务的全省毒品消费量值 去 描述 陕西省毒品千人均消费量变化趋势 + * 在这里说明一下本期,同期和上期之间的关系 + * 1 本期 指的是当前季度 + * 2 上期 是 当前季度的上一个季度 + * 3 同期指的是去年的同一季度 + * @param allTaskProvinceDrugConsumptionList + * @param taskInfoList 已经根据任务开始时间进行升序排序的列表 + * @return + */ + private String getDrugConsumePerThousandTrendDescribe(List allTaskProvinceDrugConsumptionList, List taskInfoList) { + String resultStr = ""; + boolean turnPoint = false; // 上升是true 下降是false + int size = allTaskProvinceDrugConsumptionList.size(); + if (size < 4) { + return resultStr; + } + for (int i = 0; i < size; i++) { + RegionalDrugConsumptionDTO dto = allTaskProvinceDrugConsumptionList.get(i); + switch (i) { + case 0: { + if (Double.parseDouble(dto.getPccTotal()) > Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal())) { + resultStr = resultStr + "全省千人均消费量自" + + taskInfoList.get(0).getTaskStartDate().format(chineseYearSingleMonthFormatter) + + "以来呈下降趋势,"; + turnPoint = false; + } else { + resultStr = resultStr + "全省千人均消费量自" + + taskInfoList.get(0).getTaskStartDate().format(chineseYearSingleMonthFormatter) + + "以来呈上升趋势,"; + turnPoint = true; + } + break; + } + case 1: { + if (turnPoint && (Double.parseDouble(dto.getPccTotal()) > Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal())) ) { + // 如果之前是上升,现在 是下降则出现转折点 + resultStr = resultStr + "于" + taskInfoList.get(1).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "开始下降,"; + turnPoint = false; + } else if (!turnPoint && (Double.parseDouble(dto.getPccTotal()) < Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal()))) { + // 如果之前是下降,现在 是上升则出现转折点 + resultStr = resultStr + "于" + taskInfoList.get(1).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "开始上升,"; + turnPoint = true; + } + break; + } + case 2: { + if (turnPoint && (Double.parseDouble(dto.getPccTotal()) > Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal())) ) { + // 如果之前是上升,现在 是下降则出现转折点 + resultStr = resultStr + taskInfoList.get(2).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "下降,"; + turnPoint = false; + } else if (!turnPoint && (Double.parseDouble(dto.getPccTotal()) < Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal()))) { + // 如果之前是下降,现在 是上升则出现转折点 + resultStr = resultStr + taskInfoList.get(2).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "上升,"; + turnPoint = true; + } + break; + } + case 3: { + if (turnPoint && (Double.parseDouble(dto.getPccTotal()) > Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal())) ) { + // 如果之前是上升,现在 是下降则出现转折点 + resultStr = resultStr + "至" + taskInfoList.get(4).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "开始下降,"; + turnPoint = false; + } else if (!turnPoint && (Double.parseDouble(dto.getPccTotal()) < Double.parseDouble(allTaskProvinceDrugConsumptionList.get(i + 1).getPccTotal()))) { + // 如果之前是下降,现在 是上升则出现转折点 + resultStr = resultStr + "至" + taskInfoList.get(4).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "开始上升,"; + turnPoint = true; + } + break; + } + } + } + if (size > 3) { + + RegionalDrugConsumptionDTO dto1 = allTaskProvinceDrugConsumptionList.get(0); + RegionalDrugConsumptionDTO dto2 = allTaskProvinceDrugConsumptionList.get(size -2); + RegionalDrugConsumptionDTO dto3 = allTaskProvinceDrugConsumptionList.get(size -1); + resultStr = resultStr + taskInfoList.get(4).getTaskStartDate().format(chineseYearSingleMonthFormatter) + + "与" + + taskInfoList.get(0).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "相比,"; + // 同比 (本期-同期) / 同期 * 100% + double v1 = Double.parseDouble(dto1.getPccTotal()); // 同期数据 + double v2 = Double.parseDouble(dto2.getPccTotal()); // 上期期数据 + double v3 = Double.parseDouble(dto3.getPccTotal()); // 本期期期数据 + double yearOnYear = (v3 - v1) / v1 * 100; // 同比 + double monthOnMonth = (v3 - v2) / v2 * 100; // 环比, (本期-上期) / 上期 * 100% + + if (v3 < v1) { + // 小于0 证明下降了 + resultStr = resultStr + "同比下降了" + keep1DecimalPlace.format(Math.abs(yearOnYear)) + "%,"; + } else { + resultStr = resultStr + "同比上升了" + keep1DecimalPlace.format(Math.abs(yearOnYear)) + "%,"; + } + + // 环比 + resultStr = resultStr + "与" + taskInfoList.get(3).getTaskStartDate().format(chineseYearSingleMonthFormatter) + "相比,"; + if (v3 < v2) { + // 小于0 证明下降了 + resultStr = resultStr + "环比下降了" + keep1DecimalPlace.format(Math.abs(monthOnMonth)) + "%。"; + } else { + resultStr = resultStr + "环比上升了" + keep1DecimalPlace.format(Math.abs(monthOnMonth)) + "%。"; + } + } + return resultStr; + } + + /** + * 获取 前面四个季度的毒品消费量数据,也不定是4个 + * @param sewageDataDtoLists + * @param taskIdByOrderStartTimeLimit4 + * @return + */ + private List> getAllMergeBeforeMegionalDrugConsumptionDTOList(List> sewageDataDtoLists, List taskIdByOrderStartTimeLimit4) { + List> allMergeMegionalDrugConsumptionDTOList = new ArrayList<>(); + // 因为目前只获取之前4个任务的信息,所以列表的长度为4 + if (CollUtil.isNotEmpty(taskIdByOrderStartTimeLimit4)) { + for (int i = 0; i < taskIdByOrderStartTimeLimit4.size() - 1; i++) { // 这里之所以减一的原因是 参数任务列表中最后一个这里不用求 + List beforeDrugConsumptionDTOList = fetchRegionalDrugConsumption(getSewageDataGroupByCityNameMap(sewageDataDtoLists.get(i))); + allMergeMegionalDrugConsumptionDTOList.add(beforeDrugConsumptionDTOList); + } + } + return allMergeMegionalDrugConsumptionDTOList; + } + + /** + * 获取 陕西省毒品千人均消费量变化趋势 执行图的x轴名称 + * + * @param taskInfoList + * @return + */ + private List getTaskStartDateList(List taskInfoList, DateTimeFormatter dateTimeFormatter) { + List xAxisNameList = taskInfoList + .stream() + .map(o -> o.getTaskStartDate().format(dateTimeFormatter)) // 在获取任务的开始年月 + .collect(Collectors.toList()); + + return xAxisNameList; + } + + /** + * 对任务进行开始时间的升序排序 + * @param taskIdByOrderStartTimeLimit4 + * @param taskInfo + * @return + */ + private List getTaskInfos(List taskIdByOrderStartTimeLimit4, TaskInfo taskInfo) { + List tempList = new ArrayList<>(taskIdByOrderStartTimeLimit4); + tempList.add(taskInfo); + List taskInfoList = tempList + .stream() + .sorted(Comparator.comparing(TaskInfo::getTaskStartDate)) // 根据任务开始时间进行排序 + .collect(Collectors.toList()); + return taskInfoList; + } + + /** + * 根据任务查询污水检材,筛选出某个省份的已经受理了的检材 + * @param dto + * @param taskInfo + * @return + */ + private List getSewageJobIdentificationMaterialVOS(ExportSewageAnalystReportsDTO dto, TaskInfo taskInfo) { + R> voListByJobIdR = remoteSewageJobIdentificationMaterialService.getSewageJobIdentificationMaterialVOListByJobId(taskInfo.getOriginalId()); + if (voListByJobIdR.getCode() == CommonConstants.FAIL) { + log.error("根据任务id 获取检材失败!"); + throw new RuntimeException("根据任务id 获取检材失败!"); + } + List data = voListByJobIdR + .getData() + .stream() + .filter(vo -> + vo.getProvinceName() + .equals(dto.getProvinceName()) && vo.getAcceptTime() != null) // 根据省编码筛选 + .collect(Collectors.toList()); + return data; + } + + /** + * 根据当前任务去比较之前四个任务的数据 + * + * @param taskStartDateList 要比较的毒品消费量数据 + * @param legendNameList 要比较的毒品消费量数据 + * @param regionalDrugConsumptionDTOList 保存着全省毒品消费量数据 + * @return + */ + private BarLineChartForm generateDrugConsumePerThousandTrendChartData(List taskStartDateList, + List legendNameList, + List regionalDrugConsumptionDTOList) { + + List yData = new ArrayList<>(); + for (String drugName : legendNameList) { + List thousandPerCapitaConsumptionList = getThousandPerCapitaConsumptionByDrug(regionalDrugConsumptionDTOList, drugName, false); + AxisYVal axisYVal = new AxisYVal(); + axisYVal.setTitle(drugName); + axisYVal.setVal(thousandPerCapitaConsumptionList.toArray(new Double[]{})); + yData.add(axisYVal); + } + // 折线数据组装 + List pccTotals = regionalDrugConsumptionDTOList.stream() + .map(o -> Double.parseDouble(o.getPccTotal())) + .collect(Collectors.toList()); + AxisYVal zx = new AxisYVal(); + zx.setTitle("综合"); + // 这里的值不能跌倒过来 + zx.setVal(pccTotals.toArray(new Double[]{})); + List yLintData = Collections.singletonList(zx); // 使用不可变列表 + + BarLineChartForm chartForm = new BarLineChartForm(); + chartForm.setTitle(""); + chartForm.setXTitle(""); + chartForm.setYTitle("千人均消费量(毫克/千人/天)"); + chartForm.setXData(taskStartDateList); + chartForm.setYBarData(yData); + chartForm.setYLineData(yLintData); + return chartForm; + } + + /** + * 取出各行政区主要毒品总消费量表 数据DTO 列表中的全省数据 + * + * @param regionalDrugConsumptionDTOList + * @param list + * @param allProvince 当前报告中的全省毒品消费量 + */ + private void extractedProvinceDrugConsumeData(List> regionalDrugConsumptionDTOList, List list, RegionalDrugConsumptionDTO allProvince) { + for (int i = 0; i < regionalDrugConsumptionDTOList.size(); i++) { + List regionalDrugConsumptionDTOSubList = regionalDrugConsumptionDTOList.get(i); + list.add(regionalDrugConsumptionDTOSubList.get(regionalDrugConsumptionDTOSubList.size()-1)); + } + list.add(allProvince); + } + + /** + * 循环生成陕西省各污水厂服务区及各行政区毒品千人均消费量表 + * @param sewageDataGroupByMap + * @param regionalDrugConsumptionDTOMap + * @param doc + */ + private void generateServiceAreaDrugConsumptionPerThousandTable(Map> sewageDataGroupByMap, Map regionalDrugConsumptionDTOMap, XWPFDocument doc) { + List nameList1 = new ArrayList<>(Arrays.asList("海洛因", "冰毒", "氯胺酮", "MDMA", "可卡因", "芬太尼", "综合折算")); + + for (String cityName : sewageDataGroupByMap.keySet()) { + + Map>> dataMap = new HashMap<>(); + + // 取这个市的所有污水检材 + List sewageDataDtos = sewageDataGroupByMap.get(cityName); + Map> sewageDataGroupByAreaName = null; + if (cityName.equals("西安市") || cityName.equals("铜川市")) { + // 根据检材的名称分组,因为检材名称的组成是 污水厂名称 + "-" +节假日或工作日样本组成, 所以这里通过 - 分隔 取第一个元素 + sewageDataGroupByAreaName = sewageDataDtos.stream().collect(Collectors.groupingBy(o -> StrUtil.split(o.getSampleName(), "-").get(0))); + } else { + sewageDataGroupByAreaName = sewageDataDtos.stream().collect(Collectors.groupingBy(SewageDataDto::getDistrictName)); + } + List> list = new ArrayList<>(); + for (String areaName : sewageDataGroupByAreaName.keySet()) { + List sewageDataDtosByAreaName = sewageDataGroupByAreaName.get(areaName); + // 总测算人口 + double estimatedPopulationSum = sewageDataDtosByAreaName.stream().mapToDouble(SewageDataDto::getEstimatedPopulation).sum(); + // 这里变量名取错了,这里的变量名的意思是 每个区县的千人均消费量,以tc开头 + Double tcHeroinSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccHeroin() * item.getEstimatedPopulation()).sum() / estimatedPopulationSum; + Double tcMaSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccMa() * item.getEstimatedPopulation()).sum() /estimatedPopulationSum; + Double tcKSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccK() * item.getEstimatedPopulation()).sum() / estimatedPopulationSum; + Double tcMdmaSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccMdma() * item.getEstimatedPopulation()).sum() /estimatedPopulationSum; + Double tcCocSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccCoc() * item.getEstimatedPopulation()).sum() / estimatedPopulationSum; + Double tcFenSum = sewageDataDtosByAreaName.stream().mapToDouble(item -> item.getPccFen() * item.getEstimatedPopulation()).sum() / estimatedPopulationSum; + // 对计算出来的数据进行NAN判断处理 + ValidDrugConsumptionResult result = getValidDrugConsumptionResult(tcHeroinSum, tcMaSum, tcKSum, tcMdmaSum, tcCocSum, tcFenSum); + Double tcTotal = result.tcKSum + result.tcMaSum + result.tcHeroinSum + result.tcMdmaSum + result.tcCocSum; + List rowDataList = new ArrayList<>(); + rowDataList.add(areaName); // 区县 + for (String name : nameList1) { + if (name.equals("海洛因")) { + rowDataList.add(keep1DecimalPlace.format(result.tcHeroinSum)); + } else if (name.equals("冰毒")) { + rowDataList.add(keep1DecimalPlace.format(result.tcMaSum)); + } else if (name.equals("氯胺酮")) { + rowDataList.add(keep1DecimalPlace.format(result.tcKSum)); + } else if (name.equals("MDMA")) { + rowDataList.add(keep1DecimalPlace.format(result.tcMdmaSum)); + } else if (name.equals("可卡因")) { + rowDataList.add(keep1DecimalPlace.format(result.tcCocSum)); + } else if (name.equals("芬太尼")) { + rowDataList.add(keep1DecimalPlace.format(result.tcFenSum)); + } else if (name.equals("综合折算")) { + rowDataList.add(keep1DecimalPlace.format(tcTotal)); + } + } + // 样品中可替宁浓度低于500 ng/L 为 不合格样品 + boolean exist = whetExistsUnqualifiedSamples(sewageDataDtosByAreaName); + rowDataList.add(exist ? "存在不合格样品" : ""); + list.add(rowDataList); + } + // 添加地区平均 + List lastRowDataList = new ArrayList<>(); + RegionalDrugConsumptionDTO regionalDrugConsumptionDTO = regionalDrugConsumptionDTOMap.get(cityName); + lastRowDataList.add("地区平均"); + for (String name : nameList1) { + if (name.equals("海洛因")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccHeroin()); + } else if (name.equals("冰毒")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccMa()); + } else if (name.equals("氯胺酮")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccK()); + } else if (name.equals("MDMA")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccMdma()); + } else if (name.equals("可卡因")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccCoc()); + } else if (name.equals("芬太尼")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccFen()); + } else if (name.equals("综合折算")) { + lastRowDataList.add(regionalDrugConsumptionDTO.getPccTotal()); + } + } + list.add(lastRowDataList); + dataMap.put(cityName, list); // 行政区城市名 + // 加2 的原因是有两行表头 + TableCreateUtils.fetchServiceAreaDrugConsumptionPerThousandTable(doc,list.size() + 2, 10, nameList1, dataMap); + doc.createParagraph(); + doc.createParagraph(); + } + } + + /** + * 判断是否存在不合格样品 + * 不合格样品:定义为检测出该样品中可替宁浓度低于500 ng/L。 + * @param sewageDataDtosByAreaName + * @return + */ + private boolean whetExistsUnqualifiedSamples(List sewageDataDtosByAreaName) { + + for (SewageDataDto sewageDataDto : sewageDataDtosByAreaName) { + if (sewageDataDto.getCotinineConcentration() < 500) { + return true; + } + } + return false; + } + + /** + * 图2 陕西省各行政区毒品千人均消费量 柱状图 + * + * @param doc + * @param regionalDrugConsumptionDTOList + * @param pieChartForm + * @param cityNameList + * @return + */ + private BarLineChartForm getServiceAreaDrugConsumeBarLineChartForm(XWPFDocument doc, List regionalDrugConsumptionDTOList, PieChartForm pieChartForm, List cityNameList) { + List list = new ArrayList<>(regionalDrugConsumptionDTOList); // new 一个新的列表操作 + + for (int i = 0; i < 2; i++) { // 空两行 + doc.createParagraph().createRun().addBreak(); + } + List xData = new ArrayList<>(); + List yData = new ArrayList<>(); +// for (int i = 0; i < regionalDrugConsumptionDTOList.size() - 1; i++) { // 不去最后一个的原因是,最后一个元素计算的是全省的 +// RegionalDrugConsumptionDTO dto = regionalDrugConsumptionDTOList.get(i); +// xData.add(dto.getRegional()); +// } + for (int i = 0; i < cityNameList.size(); i++) { + String cityName = cityNameList.get(i); + if (i < regionalDrugConsumptionDTOList.size() - 1) { // 不取最后一个的原因是,最后一个元素计算的是全省的 + RegionalDrugConsumptionDTO dto = regionalDrugConsumptionDTOList.get(i); + xData.add(dto.getRegional()); + } else if (!xData.contains(cityName)){ + xData.add(cityName); + RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO(); + dto.setRegional(cityName); + dto.setPccHeroin("0"); + dto.setPccFen("0"); + dto.setPccMa("0"); + dto.setPccMdma("0"); + dto.setPccK("0"); + dto.setPccCoc("0"); + list.add(dto); + } + } + for (String drugName : pieChartForm.getXData()) { + List thousandPerCapitaConsumptionList = getThousandPerCapitaConsumptionByDrug(list, drugName, true); + AxisYVal axisYVal = new AxisYVal(); + axisYVal.setTitle(drugName); + axisYVal.setVal(thousandPerCapitaConsumptionList.toArray(new Double[]{})); + yData.add(axisYVal); + } + + BarLineChartForm chartForm1 = new BarLineChartForm(); + chartForm1.setTitle(""); + chartForm1.setXTitle(""); + chartForm1.setYTitle("千人均消费量(毫克/千人/天)"); + // new ArrayList<>(Arrays.asList("西安市", "咸阳市", "宝鸡市", "渭南市", "铜川市", "榆林市", "延安市", "汉中市", "商洛市", "安康市", "杨凌区")) + chartForm1.setXData(xData); + chartForm1.setYBarData(yData); + chartForm1.setYLineData(null); + return chartForm1; + } + + /** + * 根据毒品的名称获取对应各行政区的千人均消费量列表 + * @param regionalDrugConsumptionDTOList + * @param drugName + * @param isRemoveLastElement 是否移除最后一个元素 + * @return + */ + private List getThousandPerCapitaConsumptionByDrug(List regionalDrugConsumptionDTOList, String drugName, boolean isRemoveLastElement) { + List thousandPerCapitaConsumptionList = new ArrayList<>(); + List list = new ArrayList<>(regionalDrugConsumptionDTOList); // 因为参数是引用类型,直接移除会影响其他地方的调用,这里通过新new 一个实例来操作 + if (isRemoveLastElement) { + // 因为最后一个是全省的所以移除 + list.remove(list.size() -1); + } + if (drugName.equals("冰毒")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccMa())).collect(Collectors.toList()); + } else if (drugName.equals("海洛因")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccHeroin())).collect(Collectors.toList()); + } else if (drugName.equals("氯胺酮")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccK())).collect(Collectors.toList()); + } else if (drugName.equals("摇头丸(MDMA)")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccMdma())).collect(Collectors.toList()); + } else if (drugName.equals("可卡因")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccCoc())).collect(Collectors.toList()); + } else if (drugName.equals("芬太尼")) { + thousandPerCapitaConsumptionList = list.stream().map(o -> Double.parseDouble(o.getPccFen())).collect(Collectors.toList()); + } + return thousandPerCapitaConsumptionList; + } + + /** + * 全省监测区域 内容生成 + * @param inspectResultAnalysisMap 在生成检测结果分析时计算的百分比 + * @param allProvince + * @return + */ + private String getProvinceMonitorsDrugConsumeContent(Map inspectResultAnalysisMap, RegionalDrugConsumptionDTO allProvince) { + String provinceMonitorsDrugConsumeContent = ""; + for (String key : inspectResultAnalysisMap.keySet()) { + if (key.equals("resultAnalysis")) { + continue; + } + String consumption = getConsumption(allProvince, key); + String percent = keep1DecimalPlace.format((Double) inspectResultAnalysisMap.get(key) * 100d); + provinceMonitorsDrugConsumeContent = StrUtil.isNotBlank(provinceMonitorsDrugConsumeContent) + ? provinceMonitorsDrugConsumeContent + key + "消费量为" + consumption + "克/天,占比" + percent + "%;" + : "全省监测区域内," + key + "消费量为" + consumption + "克/天,占比" + percent + "%;" ; + } + // 删除最后一个;,替换成 。 + return provinceMonitorsDrugConsumeContent.substring(0, provinceMonitorsDrugConsumeContent.length()-1) + "(受合法药物干扰,存在一定误差,仅供参考)。"; + } + + /** + * 获取不同毒品的消费量 + * @param allProvince + * @param key + * @return + */ + private String getConsumption(RegionalDrugConsumptionDTO allProvince, String key) { + String consumption = ""; + if (key.equals("冰毒")) { + consumption = allProvince.getTcMa(); + } else if (key.equals("海洛因")) { + consumption = allProvince.getTcHeroin(); + } else if (key.equals("氯胺酮")) { + consumption = allProvince.getTcK(); + } else if (key.equals("摇头丸(MDMA)")) { + consumption = allProvince.getTcMdma(); + } else if (key.equals("可卡因")) { + consumption = allProvince.getTcCoc(); + } else if (key.equals("芬太尼")) { + consumption = allProvince.getTcFen(); + } + return consumption; + } + + /** + * 根据饼图数据生成检测结果分析 + * + * @param pieChartForm + * @param allProvince + * @return + */ + private Map getInspectResultAnalysis(PieChartForm pieChartForm, RegionalDrugConsumptionDTO allProvince) { + + + List drugNameList = pieChartForm.getXData(); // 毒品名称列表 + Double[] numbers = (Double[]) pieChartForm.getYData().getVal(); // 饼图各毒品的消费量 + boolean flagMaster = false; // 标记是否存在大于10%的毒品,默认没有 + // 求数组的和 + Double sum = calculateArraySum(numbers); + Map map = new HashMap<>(); + for (int i = 0; i < numbers.length; i++) { + double percent = numbers[i] / sum; + if (percent > 0.1) { + flagMaster = true; + } + map.put(drugNameList.get(i), percent); + } + + // 拼接检出的字符串 + String detectedDrug = ""; + if (drugNameList.size() > 0) { + detectedDrug = getDetectedDrugStr(numbers, flagMaster, drugNameList, map); + } + + // 未检出的 + String noDetected = getNoDetectedStr(allProvince); + + map.put("resultAnalysis", detectedDrug + noDetected); + return map; + } + + /** + * 获取检出的毒品字符串 + * + * @param numbers + * @param drugNameList + * @param map + * @return + */ + private String getDetectedDrugStr(Double[] numbers, boolean flagMaster, List drugNameList, Map map) { + + String detectedDrug = ""; + if (flagMaster) { + String masterStr = ""; // 主要毒品 + String secondStr = ""; // 其次 + for (String key : map.keySet()) { + Double v = (Double) map.get(key); + if (v > 0.1) { + masterStr = StrUtil.isNotBlank(masterStr) ? masterStr + "、" + key : "陕西省存在滥用的主要毒品为" + key; + } else { + secondStr = StrUtil.isNotBlank(secondStr) ? secondStr + "、" + key : "其次为" + key; + } + } + // 因为flag 为true 那么肯定是有大于0.1的 + detectedDrug = masterStr + (StrUtil.isBlank(secondStr) ? "。" : "," + secondStr + "。"); + } else { + detectedDrug = "陕西省存在滥用的毒品为" + drugNameList.stream().collect(Collectors.joining("、")) + "。"; + } + + return detectedDrug; + } + + /** + * 获取结果分析中未检出的字符串 + * @param allProvince + * @return + */ + private String getNoDetectedStr(RegionalDrugConsumptionDTO allProvince) { + String noDetected = ""; + if (Double.parseDouble(allProvince.getTcHeroin()) == 0) { + noDetected = noDetected + "海洛因"; + } + // 冰毒 + if (Double.parseDouble(allProvince.getTcMa()) == 0) { + noDetected = StrUtil.isNotBlank(noDetected) ? noDetected + "、冰毒" : "冰毒"; + } + // 氯胺酮 + if (Double.parseDouble(allProvince.getTcK()) == 0) { + noDetected = StrUtil.isNotBlank(noDetected) ? noDetected + "、氯胺酮" : "氯胺酮"; + } + // 摇头丸 + if (Double.parseDouble(allProvince.getTcMdma()) == 0) { + noDetected = StrUtil.isNotBlank(noDetected) ? noDetected + "、摇头丸" : "摇头丸"; + } + // 可卡因 + if (Double.parseDouble(allProvince.getTcCoc()) == 0) { + noDetected = StrUtil.isNotBlank(noDetected) ? noDetected + "、可卡因" : "可卡因"; + } + // 芬太尼 + if (Double.parseDouble(allProvince.getTcFen()) == 0) { + noDetected = StrUtil.isNotBlank(noDetected) ? noDetected + "、芬太尼" : "芬太尼"; + } + // 如果确实有未检出的,则拼接 均未检出,暂未发现明显滥用。 + if (StrUtil.isNotBlank(noDetected)) { + noDetected = noDetected + "均未检出,暂未发现明显滥用。"; + } + return noDetected; + } + + /** + * 数组求和 + * @param numbers + * @return + */ + private Double calculateArraySum(Number[] numbers) { + Double sum = 0d; + for (Number number : numbers) { + sum = sum + (Double) number; + } + return sum; + } + + /** + * 获取文件模板样式路径 + * + * @return + * @throws UnsupportedEncodingException + */ + private ByteArrayInputStream getTemplateStyleFilePath() throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); +// ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/" + "templateStyles.docx", bos); + String path = null; + try { +// path = new ClassPathResource("template\\templateStyles.docx").getPath(); + ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/" + "templateStyles.docx", bos); + } catch (Exception e) { + log.error("文件名为 {} 的模板路径获取失败!", "template\\templateStyles.docx"); + e.printStackTrace(); + } +// String filePath = URLDecoder.decode(path, "UTF-8"); + return new ByteArrayInputStream(bos.toByteArray()); + } + + /** + * 生成文档首页 + * @param doc + * @param yearMonth 报告的月份 + * @param organization 国家毒品实验室陕西分中心 + * @param generateDate 生成日期 + * @param province 省份 + */ + private void generateHomePage(XWPFDocument doc, String yearMonth, String organization, String generateDate, String province) { + // 空三行 + for (int i = 0; i < 3; i++) { + doc.createParagraph().createRun().addBreak(); + } + WordUtils.createDocHomePage(doc, yearMonth + province + "污水样品毒品监测分析报告", "",16, 24); + WordUtils.createDocHomePage(doc, organization, "",0, 18); + WordUtils.createDocHomePage(doc, generateDate, "",0, 18); + } + + /** + * 各污水厂监测点主要毒品及其代谢物每日浓度表 的 数据组装 + * @param sewageDataGroupByMap + * @param tableName5List + * @return + */ + private Map>> generateDailyDrugAndMetaboliteConcentrationData(Map> sewageDataGroupByMap, List tableName5List) { + Map>> dataMap = new HashMap<>(); + Map> drugConcentrationMap = new HashMap<>(); + drugConcentrationMap.put("可替宁", SewageDataDto::getCotinineConcentration); + drugConcentrationMap.put("可待因", SewageDataDto::getCodeineConcentration); + drugConcentrationMap.put("MDA", SewageDataDto::getMdaConcentration); + drugConcentrationMap.put("MDMA", SewageDataDto::getMdmaConcentration); + drugConcentrationMap.put("可卡因", SewageDataDto::getCocaineConcentration); + drugConcentrationMap.put("苯甲酰爱康宁", SewageDataDto::getBenzoylecgonineConcentration); + drugConcentrationMap.put("吗啡", SewageDataDto::getMorphineConcentration); + drugConcentrationMap.put("O6-单乙酰吗啡", SewageDataDto::getAcetylmorphineConcentration); + drugConcentrationMap.put("甲基苯丙胺", SewageDataDto::getMethamphetamineConcentration); + drugConcentrationMap.put("苯丙胺", SewageDataDto::getAmphetamineConcentration); + drugConcentrationMap.put("氯胺酮", SewageDataDto::getKetamineConcentration); + drugConcentrationMap.put("去甲氯胺酮", SewageDataDto::getNorketamineConcentration); + drugConcentrationMap.put("芬太尼", SewageDataDto::getFenConcentration); + sewageDataGroupByMap.forEach((k,v) -> { + List dataList = new ArrayList(); + for (SewageDataDto sewageDataDto : v) { + ArrayList subDataList = new ArrayList<>(); + // 根据检材的名称分组,因为检材名称的组成是 污水厂名称 + "-" +节假日或工作日样本组成, 所以这里通过 - 分隔 取第一个元素 + subDataList.add(StrUtil.split(sewageDataDto.getSampleName(), "-").get(0));// 污水厂名称 + subDataList.add(sewageDataDto.getCollectTime().format(DateTimeFormatter.ofPattern("yyyy-M-d"))); + for (String name : tableName5List) { + Function concentrationGetterFunction = drugConcentrationMap.get(name); + if (concentrationGetterFunction != null) { + subDataList.add(keep1DecimalPlace.format(concentrationGetterFunction.apply(sewageDataDto))); + } else { + // 或者添加null,表示该数据不存在 + } + } + subDataList.add("备注"); + dataList.add(subDataList); + } + dataMap.put(k, dataList); + }); + + return dataMap; + } + + /** + * 各行政区毒品总消费量变化趋势 折线图 + * + * @param allMergeMegionalDrugConsumptionDTOList + * @param regionalDrugConsumptionDTOList + * @param taskStartDateList + * @param cityNameList + * @return + */ + private BarLineChartForm getRendsInTotalDrugConsumptionInEachAdministrativeRegion(List> allMergeMegionalDrugConsumptionDTOList, List regionalDrugConsumptionDTOList, List taskStartDateList, List cityNameList) { + + List yLintData1 = getAxisYValsByLiineChart(allMergeMegionalDrugConsumptionDTOList, regionalDrugConsumptionDTOList, cityNameList,true); + + BarLineChartForm lineChartForm = new BarLineChartForm(); + lineChartForm.setTitle(""); + lineChartForm.setXTitle(""); + lineChartForm.setYTitle("总消费量(克/天)"); + lineChartForm.setXData(taskStartDateList); + lineChartForm.setYBarData(null); + lineChartForm.setYLineData(yLintData1); + return lineChartForm; + } + + /** + * 获取折线图的数据 + * @param allMergeMegionalDrugConsumptionDTOList + * @param regionalDrugConsumptionDTOList + * @param cityNameList + * @param flag 取值是综合总消费量还是千人均总消费量 + * @return + */ + private static List getAxisYValsByLiineChart(List> allMergeMegionalDrugConsumptionDTOList, List regionalDrugConsumptionDTOList, List cityNameList, boolean flag) { + List> list = new ArrayList<>(allMergeMegionalDrugConsumptionDTOList); + list.add(regionalDrugConsumptionDTOList); + + List> mapList = list.stream().map(item -> { + return item.stream().collect(Collectors.toMap(RegionalDrugConsumptionDTO::getRegional, Function.identity())); + }).collect(Collectors.toList()); + + List yLintData1 = new ArrayList<>(); + for (String cityName : cityNameList) { + AxisYVal axisYVal = new AxisYVal(); + axisYVal.setTitle(cityName); + Double[] doubles = new Double[list.size()]; + for (int i = 0; i < mapList.size(); i++) { + Map map = mapList.get(i); + if (map.containsKey(cityName)) { + RegionalDrugConsumptionDTO dto = map.get(cityName); + doubles[i] = Double.valueOf(flag ? dto.getTcTotal() : dto.getPccTotal()); + } else { + doubles[i] = 0d; + } + } + axisYVal.setVal(doubles); + yLintData1.add(axisYVal); + } + return yLintData1; + } + + /** + * 图5 各行政区毒品千人均消费量变化趋势 + * @param allMergeMegionalDrugConsumptionDTOList + * @param regionalDrugConsumptionDTOList + * @param taskStartDateList + * @param cityNameList + * @return + */ + private BarLineChartForm getTrendsInPerCapitaDrugConsumptionEachAdministrativeRegion(List> allMergeMegionalDrugConsumptionDTOList, List regionalDrugConsumptionDTOList, List taskStartDateList, List cityNameList) { + + List yLintData1 = getAxisYValsByLiineChart(allMergeMegionalDrugConsumptionDTOList, regionalDrugConsumptionDTOList, cityNameList, false); + + BarLineChartForm lineChartForm = new BarLineChartForm(); + lineChartForm.setTitle(""); + lineChartForm.setXTitle(""); + lineChartForm.setYTitle("千人均消费量/(毫克/千人/天)"); + lineChartForm.setXData(taskStartDateList); + lineChartForm.setYBarData(null); + lineChartForm.setYLineData(yLintData1); + return lineChartForm; + } + + /** + * 获取陕西省各行政区主要毒品总消费量表数据 列表 + * @param sewageDataGroupByMap + * @return + */ + private List fetchRegionalDrugConsumption(Map> sewageDataGroupByMap) { + + List regionalDrugConsumptionDTOS = new ArrayList<>(); + + sewageDataGroupByMap.forEach((k,v) -> { + RegionalDrugConsumptionDTO dto = getRegionalDrugConsumptionDTO(v); + regionalDrugConsumptionDTOS.add(dto); + }); + // 全省平均/总计 计算方式目前还不清楚 + regionalDrugConsumptionDTOS.add(getAllProvinceAvgAndSumDataDTO(regionalDrugConsumptionDTOS)); + + return regionalDrugConsumptionDTOS; + } + + /** + * 根据污水检材 去计算污水毒品千人均消费量,然后根据城市名称进行分组 + * @param sewageDataDtos + * @return + */ + private Map> getSewageDataGroupByCityNameMap(List sewageDataDtos) { + // 根据市级编码 分组 + Map> sewageDataGroupByMap = sewageDataDtos + .stream() + .collect(Collectors + .groupingBy(SewageDataDto::getCityName)); + return sewageDataGroupByMap; + } + + /** + * 获取全省各种毒品的千人均消费量平均值和总消费量 + * @param regionalDrugConsumptionDTOS + * @return + */ + private RegionalDrugConsumptionDTO getAllProvinceAvgAndSumDataDTO(List regionalDrugConsumptionDTOS) { + // 这部分是先计算全省各毒品平均消耗量 + double allProvinceHeroinAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccHeroin())); + double allProvinceCocAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccCoc())); + double allProvinceKAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccK())); + double allProvinceMaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMa())); + double allProvinceMdmaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMdma())); + double allProvinceFenAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccFen())); + double allProvincePccTotalAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccTotal())); + // 全省各毒品的总消耗量 + double allProvinceHeroinTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcHeroin())); + double allProvinceMaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMa())); + double allProvinceKTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcK())); + double allProvinceMdmaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMdma())); + double allProvinceCocTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcCoc())); + double allProvinceFenTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcFen())); + double allProvinceTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcTotal())); + + RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO(); + dto.setRegional("全省平均/总计"); + // 平均 + dto.setPccHeroin(keep1DecimalPlace.format(allProvinceHeroinAvg)); + dto.setPccMdma(keep1DecimalPlace.format(allProvinceMdmaAvg)); + dto.setPccK(keep1DecimalPlace.format(allProvinceKAvg)); + dto.setPccMa(keep1DecimalPlace.format(allProvinceMaAvg)); + dto.setPccCoc(keep1DecimalPlace.format(allProvinceCocAvg)); + dto.setPccFen(keep1DecimalPlace.format(allProvinceFenAvg)); + dto.setPccTotal(keep1DecimalPlace.format(allProvincePccTotalAvg)); + + // 总计 + dto.setTcHeroin(keep1DecimalPlace.format(allProvinceHeroinTotalSum)); + dto.setTcMdma(keep1DecimalPlace.format(allProvinceMdmaTotalSum)); + dto.setTcCoc(keep1DecimalPlace.format(allProvinceCocTotalSum)); + dto.setTcMa(keep1DecimalPlace.format(allProvinceMaTotalSum)); + dto.setTcK(keep1DecimalPlace.format(allProvinceKTotalSum)); + dto.setTcFen(keep1DecimalPlace.format(allProvinceFenTotalSum)); + dto.setTcTotal(keep1DecimalPlace.format(allProvinceTotalSum)); + + return dto; + } + + /** + * 全省各毒品平均消耗量 + * @param regionalDrugConsumptionDTOS + * @param mapper + * @return + */ + private double calculateAverage(List regionalDrugConsumptionDTOS, Function mapper) { + return regionalDrugConsumptionDTOS.stream() + .mapToDouble(mapper::apply) + .average() + .orElse(0.0); + } + + /** + * 全省各毒品总消耗量 + * @param regionalDrugConsumptionDTOS + * @param mapper + * @return + */ + private double calculateConsumeSum(List regionalDrugConsumptionDTOS, Function mapper) { + return regionalDrugConsumptionDTOS.stream().mapToDouble(mapper::apply).sum(); + } + + /** + * 获取各行政区主要毒品总消费量 数据传输对象 + * @param v + * @return + */ + private RegionalDrugConsumptionDTO getRegionalDrugConsumptionDTO(List v) { + // 对小数进行保留1位小数的操作 + DecimalFormat df = new DecimalFormat("#.##"); + + RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO(); + SewageDataDto sewageDataDto = v.get(0); + dto.setRegional(sewageDataDto.getCityName()); // 城市名称 + // 总测算人口 +// double estimatedPopulationSum = v.stream().mapToDouble(SewageDataDto::getEstimatedPopulation).sum(); +// // 各类毒品的总消耗量 +// Double tcHeroinSum = v.stream().mapToDouble(item -> item.getPccHeroin() * item.getEstimatedPopulation()).sum() ; +// Double tcMaSum = v.stream().mapToDouble(item -> item.getPccMa() * item.getEstimatedPopulation()).sum(); +// Double tcKSum = v.stream().mapToDouble(item -> item.getPccK() * item.getEstimatedPopulation()).sum(); +// Double tcMdmaSum = v.stream().mapToDouble(item -> item.getPccMdma() * item.getEstimatedPopulation()).sum(); +// Double tcCocSum = v.stream().mapToDouble(item -> item.getPccCoc() * item.getEstimatedPopulation()).sum(); +// Double tcFenSum = v.stream().mapToDouble(item -> item.getPccFen() * item.getEstimatedPopulation()).sum(); + // 总测算人口及各毒品消耗量的统计 + double estimatedPopulationSum = 0; + double tcHeroinSum = 0, tcMaSum = 0, tcKSum = 0, tcMdmaSum = 0, tcCocSum = 0, tcFenSum = 0; + for (SewageDataDto item : v) { + estimatedPopulationSum += item.getEstimatedPopulation(); + tcHeroinSum += item.getPccHeroin() * item.getEstimatedPopulation(); + tcMaSum += item.getPccMa() * item.getEstimatedPopulation(); + tcKSum += item.getPccK() * item.getEstimatedPopulation(); + tcMdmaSum += item.getPccMdma() * item.getEstimatedPopulation(); + tcCocSum += item.getPccCoc() * item.getEstimatedPopulation(); + tcFenSum += item.getPccFen() * item.getEstimatedPopulation(); + } + // 对计算出来的数据进行NAN判断处理 + // 对计算出来的数据进行NAN判断处理 + ValidDrugConsumptionResult result = getValidDrugConsumptionResult(tcHeroinSum, tcMaSum, tcKSum, tcMdmaSum, tcCocSum, tcFenSum); + Double tcTotal = result.tcKSum + result.tcMaSum + result.tcHeroinSum + result.tcMdmaSum + result.tcCocSum; + // 总消费量(克/天), 因为算出来的单位是毫克,所以这里需要除以1000, 综合 + dto.setTcTotal(df.format(tcTotal / 1000)); + dto.setTcHeroin(df.format(result.tcHeroinSum / 1000)); + dto.setTcMa(df.format(result.tcMaSum / 1000)); + dto.setTcK(df.format(result.tcKSum / 1000)); + dto.setTcMdma(df.format(result.tcMdmaSum / 1000)); + dto.setTcCoc(df.format(result.tcCocSum / 1000)); + dto.setTcFen(df.format(result.tcFenSum / 1000)); + + // 千人均消费量(毫克/千人/天) + double pccHeroin = estimatedPopulationSum == 0.0 ? 0 : result.tcHeroinSum / estimatedPopulationSum; + double pccK = estimatedPopulationSum == 0.0 ? 0 : result.tcKSum / estimatedPopulationSum; + double pccCoc = estimatedPopulationSum == 0.0 ? 0 : result.tcCocSum / estimatedPopulationSum; + double pccMa = estimatedPopulationSum == 0.0 ? 0 : result.tcMaSum / estimatedPopulationSum; + double pccMdma = estimatedPopulationSum == 0.0 ? 0 : result.tcMdmaSum / estimatedPopulationSum; + double pccFen = estimatedPopulationSum == 0.0 ? 0 : result.tcFenSum / estimatedPopulationSum; + double pccTotal = estimatedPopulationSum == 0.0 ? 0 : pccCoc + pccHeroin + pccFen + pccMa + pccMdma; + dto.setPccHeroin(df.format(pccHeroin)); + dto.setPccK(df.format(pccK)); + dto.setPccCoc(df.format(pccCoc)); + dto.setPccMa(df.format(pccMa)); + dto.setPccMdma(df.format(pccMdma)); + dto.setPccFen(df.format(pccFen)); + dto.setPccTotal(df.format(pccTotal)); + return dto; + } + + /** + * 图1 陕西省常见毒品消费结构图 + * @param dto 陕西省各行政区主要毒品总消费量表数据 中计算全省的dto + * @return + */ + private PieChartForm generateCommonDrugConsumeStructureChart(RegionalDrugConsumptionDTO dto) { + // 取列表最后一个,最后一个是计算全省的 + List xDataSet = new ArrayList<>(); // 饼图图例名称 + AxisYVal val3 = new AxisYVal(); // 创建封装饼图数据的类 + val3.setTitle(""); + List dataList = new ArrayList<>(); + + // 封装转换与添加逻辑,减少重复代码 + addIfNotZero("海洛因", dto.getTcHeroin(), xDataSet, dataList); + addIfNotZero("冰毒", dto.getTcMa(), xDataSet, dataList); + addIfNotZero("氯胺酮", dto.getTcK(), xDataSet, dataList); + addIfNotZero("摇头丸(MDMA)", dto.getTcMdma(), xDataSet, dataList); + addIfNotZero("可卡因", dto.getTcCoc(), xDataSet, dataList); + addIfNotZero("芬太尼", dto.getTcFen(), xDataSet, dataList); + + val3.setVal(dataList.toArray(new Double[]{})); + + //拼图 + PieChartForm pieChartFrom = new PieChartForm(); + pieChartFrom.setTitle(""); + pieChartFrom.setXData(new ArrayList<>(xDataSet)); + pieChartFrom.setYData(val3); + + return pieChartFrom; + } + + // 辅助方法,用于简化主方法中的逻辑, 减少不必要的Double.parseDouble调用,提高了代码的执行效率 + private void addIfNotZero(String drugName, String valueStr, List xDataSet, List dataList) { + double value = Double.parseDouble(valueStr); + if (value != 0) { + xDataSet.add(drugName); + dataList.add(value); + } + } + + /** + * 判断各类毒品消费量是不是NAN + * @param tcHeroinSum + * @param tcMaSum + * @param tcKSum + * @param tcMdmaSum + * @param tcCocSum + * @param tcFenSum + * @return + */ + private static ValidDrugConsumptionResult getValidDrugConsumptionResult(Double tcHeroinSum, Double tcMaSum, Double tcKSum, Double tcMdmaSum, Double tcCocSum, Double tcFenSum) { + tcHeroinSum = tcHeroinSum.toString().equals("NaN") ? 0 : tcHeroinSum; + tcMaSum = tcMaSum.toString().equals("NaN") ? 0 : tcMaSum; + tcKSum = tcKSum.toString().equals("NaN") ? 0 : tcKSum; + tcMdmaSum = tcMdmaSum.toString().equals("NaN") ? 0 : tcMdmaSum; + tcCocSum = tcCocSum.toString().equals("NaN") ? 0 : tcCocSum; + tcFenSum = tcFenSum.toString().equals("NaN") ? 0 : tcFenSum; + ValidDrugConsumptionResult result = new ValidDrugConsumptionResult(tcHeroinSum, tcMaSum, tcKSum, tcMdmaSum, tcCocSum, tcFenSum); + return result; + } + + /** + * 封装处理数据计算结果是nan的毒品消费量数据的 静态内部类 + */ + private static class ValidDrugConsumptionResult { + public final Double tcHeroinSum; + public final Double tcMaSum; + public final Double tcKSum; + public final Double tcMdmaSum; + public final Double tcCocSum; + public final Double tcFenSum; + + public ValidDrugConsumptionResult(Double tcHeroinSum, Double tcMaSum, Double tcKSum, Double tcMdmaSum, Double tcCocSum, Double tcFenSum) { + this.tcHeroinSum = tcHeroinSum; + this.tcMaSum = tcMaSum; + this.tcKSum = tcKSum; + this.tcMdmaSum = tcMdmaSum; + this.tcCocSum = tcCocSum; + this.tcFenSum = tcFenSum; + } + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TaskInfoServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TaskInfoServiceImpl.java new file mode 100644 index 0000000..0f54248 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TaskInfoServiceImpl.java @@ -0,0 +1,1489 @@ +package digital.laboratory.platform.inspection.service.impl; +/* + *@title TaskInfoServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/8 11:10 + */ + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.deepoove.poi.data.ChartSingleSeriesRenderData; +import com.deepoove.poi.data.Charts; +import digital.laboratory.platform.api.dto.UploadHairJobDTO; +import digital.laboratory.platform.api.dto.UploadSewageJobDTO; +import digital.laboratory.platform.api.entity.UploadHairJobDetailLite; +import digital.laboratory.platform.api.entity.UploadSewageJobDetailLite; +import digital.laboratory.platform.api.feign.RemoteUploadService; +import digital.laboratory.platform.common.core.constant.CommonConstants; +import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.feign.RemoteGenerateWordService; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.BusinessType; +import digital.laboratory.platform.inspection.constant.SewageReportColumn; +import digital.laboratory.platform.inspection.dto.*; +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspection.entity.TaskInfo; +import digital.laboratory.platform.inspection.mapper.TaskInfoMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspetion.api.entity.MaterialDto; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.sewage.feign.RemoteSewageJobIdentificationMaterialService; +import digital.laboratory.platform.sewage.vo.SewageJobIdentificationMaterialVO; +import digital.laboratory.platform.sys.feign.RemoteDictionaryService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.lang.StringUtils; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import javax.annotation.Resource; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +@Slf4j +@SuppressWarnings("all") +public class TaskInfoServiceImpl extends ServiceImpl implements TaskInfoService { + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private AssignmentInfoService assignmentInfoService; + + @Resource + private TestRecordSampleDataService testRecordSampleDataService; + + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService; + + @Resource + private TestRecordSampleDataMapper testRecordSampleDataMapper; + + @Resource + private RemoteUploadService remoteUploadService; + + @Resource + private RemoteDictionaryService remoteDictionaryService; + + @Resource + private RemoteGenerateWordService remoteGenerateWordService; + + @Resource + private RemoteSewageJobIdentificationMaterialService remoteSewageJobIdentificationMaterialService; + + @Resource + private TestRecordInstrumentConditionService testRecordInstrumentConditionService; + + @Resource + private OssFile ossFile; + + /** + * 根据目标任务的开始时间进行排序 取4个任务的id + * + * @param targetTask + * @return + */ + @Override + public List getTaskIdByOrderStartTimeLimit4(TaskInfo targetTask) { + List list = this.list(Wrappers.lambdaQuery() + .ne(TaskInfo::getOriginalId, "") + .isNotNull(TaskInfo::getOriginalId) + .lt(TaskInfo::getTaskStartDate, targetTask.getTaskStartDate()) + .orderByDesc(TaskInfo::getTaskStartDate) + .last("limit 4") + ); + + return list; + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public TaskInfo addTaskInfo(TaskInfoDto taskInfo) { + String businessType = taskInfo.getBusinessType(); + if (businessType.equals("污水任务鉴定")) { + taskInfo.setBusinessType("20002"); + } else { + taskInfo.setBusinessType("20001"); + } + String originalId = taskInfo.getOriginalId(); + //判断是否是从其他系统读取过来的数据 + if (StringUtils.isNotBlank(originalId)) { + TaskInfo info = this.getOne(Wrappers.lambdaQuery().eq(TaskInfo::getOriginalId, originalId)); + //判断是否已经添加至本系统 + if (ObjectUtils.isNotNull(info)) { + int index = 0; + //已经添加过来了,update即可 + taskInfo.setId(info.getId()); + List materialList = taskInfo.getMaterialList(); + String distributionSituation = info.getDistributionSituation(); + + //获取检材信息 + if (materialList != null && materialList.size() > 0) { + List oldSampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, info.getId())); + List newSampleInfoList = new ArrayList<>(); + List oldSampleNoList = new ArrayList<>(); + //获取已读取的检材信息 + if (oldSampleInfoList != null && oldSampleInfoList.size() > 0) { + oldSampleInfoList.forEach(item -> oldSampleNoList.add(item.getAcceptNo())); + } + //去重处理 + if (oldSampleNoList.size() > 0) { + for (MaterialDto material : materialList) { + if (taskInfo.getBusinessType().equals("20001")) { + material.setImNo(material.getSampleCode()); + } + if (!oldSampleNoList.contains(material.getImNo())) { + SampleInfo sampleInfo = new SampleInfo(); + sampleInfoService.copy(sampleInfo, material, 1); + sampleInfo.setBusinessType(taskInfo.getBusinessType()); + sampleInfo.setBusinessId(taskInfo.getId()); + newSampleInfoList.add(sampleInfo); + index = index + 1; + } + } + } else { + for (MaterialDto material : materialList) { + SampleInfo sampleInfo = new SampleInfo(); + sampleInfoService.copy(sampleInfo, material, 1); + sampleInfo.setBusinessType(taskInfo.getBusinessType()); + sampleInfo.setBusinessId(taskInfo.getId()); + newSampleInfoList.add(sampleInfo); + } + } + sampleInfoService.saveBatch(newSampleInfoList); + } + //修改检材总数 + if (StringUtils.isNotBlank(distributionSituation)) { + int prefix = 0; + int suffix = 0; + String[] split = distributionSituation.split("/"); + prefix = Integer.parseInt(split[0]); + suffix = Integer.parseInt(split[1]); + taskInfo.setDistributionSituation(prefix + "/" + (suffix + index)); + } + this.updateById(taskInfo); + return taskInfo; + } else { + taskInfo.setId(IdWorker.get32UUID().toUpperCase()); + List materialList = taskInfo.getMaterialList(); + if (materialList != null && materialList.size() > 0) { + List newSampleInfoList = new ArrayList<>(); + for (MaterialDto material : materialList) { + if (taskInfo.getBusinessType().equals("20001")) { + material.setImNo(material.getSampleCode()); + } + SampleInfo sampleInfo = new SampleInfo(); + sampleInfoService.copy(sampleInfo, material, 1); + sampleInfo.setBusinessType(taskInfo.getBusinessType()); + sampleInfo.setBusinessId(taskInfo.getId()); + newSampleInfoList.add(sampleInfo); + } + sampleInfoService.saveBatch(newSampleInfoList); + } + this.save(taskInfo); + return taskInfo; + } + + } + if (StringUtils.isBlank(taskInfo.getId())) { + taskInfo.setId(IdWorker.get32UUID()); + log.info("保存对象entrustInfo的ID为空,由系统生成一个给它使用 {}", taskInfo.getId()); + } + boolean ret = this.save(taskInfo); + if (ret) { + log.info("{} 保存成功", taskInfo); + return taskInfo; + } else { + log.info("{} 保存失败", taskInfo); + return null; + } + } + + + @Override + public TaskInfo updateTaskInfo(TaskInfo taskInfo) { +// if (taskInfo.getSource() == 0) { +// log.info("数据是其他系统推送录入的,不能修改"); +// return null; +// } + if (CollUtil.isNotEmpty(taskInfo.getCompoundsJsonArray())) { + taskInfo.setCompounds(taskInfo.getCompoundsJsonArray().toJSONString()); + } + boolean ret = this.updateById(taskInfo); + if (ret) { + return taskInfo; + } else { + return null; + } + } + + @Override + public Boolean deleteTaskInfo(String id) { + List assignmentInfos = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, id)); + if (assignmentInfos.size() > 0) { + throw new RuntimeException(String.format("当前业务已被分配,无法删除!")); + } + return this.removeById(id); + } + + @Override + public IPage getTaskPageList(Page page, TaskInfo taskInfo, String keywords) { + IPage ret = this.page(page, Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(keywords), TaskInfo::getTaskName, keywords) + .orderByDesc(TaskInfo::getCreateTime)); + List records = ret.getRecords(); + for (TaskInfo info : records) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + if (info.getBusinessType().equals("20001")) { + info.setBusinessTypeName("毛发任务"); + } else { + info.setBusinessTypeName("污水任务"); + } + } + return ret; + } + + @Override + public List getTaskList(TaskInfo taskInfo, String keywords) { + List retList = this.list(Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(keywords), TaskInfo::getTaskName, keywords) + .eq(StringUtils.isNotBlank(taskInfo.getId()), TaskInfo::getId, taskInfo.getId()) + .orderByDesc(TaskInfo::getCreateTime)); + for (TaskInfo info : retList) { + List list = assignmentInfoService.list(Wrappers.lambdaQuery().eq(AssignmentInfo::getBusinessId, info.getId())); + if (list.size() > 0) { + info.setIsDistribution(true); + } else { + info.setIsDistribution(false); + } + if (info.getBusinessType().equals("20001")) { + info.setBusinessTypeName("毛发任务"); + } else { + info.setBusinessTypeName("污水任务"); + } + } + return retList; + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(TaskInfo::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + @Override + public void createUploadItem(List sampleNos) { + List taskTestDataDTOList = testRecordSampleDataMapper. + queryWaitApproveTaskTestDataList(Wrappers.query() + .in("ss.sample_no", sampleNos)); + // 获取当前数据的业务类型 毛发还是污水 + String businessType = taskTestDataDTOList.get(0).getBusinessType(); + //获取对应样本溶液编号的实验数据,按检材编号进行分组 + Map> map = taskTestDataDTOList + .stream().collect(Collectors.groupingBy(item -> item.getAcceptNo())); + + if (businessType.equals(BusinessType.BOINT_JOB.getBusinessType())) { + getUploadHairJobDTOS(map); + } else { + getUploadSewageJobDTOS(map); + } + + } + + /** + * 导出污水专项检测毒品分析报告 + * + * @param dto + * @return + */ + @Override + public R exportSewageAnalystReports(ExportSewageAnalystReportsDTO dto) { + + +// String yearMonth = dto.getMonth().format(DateTimeFormatter.ofPattern("yyyy年MM月")); + // 目前字典中的单位名称不统一,这里暂时写死,后期在改 + String organization = "国家毒品实验室陕西分中心"; + String generateDate = LocalDate.now().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日")); + String province = dto.getProvinceName(); + R> voListByJobIdR = remoteSewageJobIdentificationMaterialService.getSewageJobIdentificationMaterialVOListByJobId(dto.getJobId()); + if (voListByJobIdR.getCode() == CommonConstants.FAIL) { + log.error("根据任务id 获取检材失败!"); + return R.failed("根据任务id 获取检材失败!"); + } + List data = voListByJobIdR + .getData() + .stream() + .filter(vo -> + vo.getProvinceName() + .equals(dto.getProvinceName()) && vo.getAcceptTime() != null) // 根据省编码筛选 + .collect(Collectors.toList()); + // 使用stream 流进行排序 + List dateSortedByAcceptTime = data.stream() + .sorted((d1, d2) -> d1.getAcceptTime().compareTo(d2.getAcceptTime())) + .collect(Collectors.toList()); + List dateSortedByCollectTime = data.stream() + .sorted((d1, d2) -> d1.getCollectTime().compareTo(d2.getCollectTime())) + .collect(Collectors.toList()); + String collectDate1 = dateSortedByAcceptTime.get(0).getAcceptTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日")); + String collectDate2 = dateSortedByAcceptTime.get(dateSortedByAcceptTime.size() - 1).getAcceptTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日")); + + String samplingDate1 = dateSortedByCollectTime.get(0).getCollectTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日")); + String samplingDate2 = dateSortedByCollectTime.get(dateSortedByCollectTime.size() - 1).getCollectTime().format(DateTimeFormatter.ofPattern("YYYY年MM月dd日")); + int materialNum = data.size(); // 本次样本数量 + + // 常见的毒品及其代谢物 (先取检验鉴定中的样本表的目标物)和 TODO 人口标记物 还不知道怎么查 + List noList = data.stream().map(SewageJobIdentificationMaterialVO::getImNo).collect(Collectors.toList()); + // 查询检验鉴定的样本表 + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().in(SampleInfo::getAcceptNo, noList)); + // 取所有的筛查物 列表 +// Set targetObjectSet = new HashSet<>(); +// for (SampleInfo sampleInfo : sampleInfoList) { +// // 获取这个检材的筛查物列表 +// List targetObjectList = sampleInfo.getTargetObject(); +// for (TargetObject targetObject : targetObjectList) { +// targetObjectSet.add(targetObject.getName()); +// } +// } + String commonDrugAndMetabolite = "甲基苯丙胺、苯丙胺(甲基苯丙胺代谢物);" + + "氯胺酮、去甲氯胺酮(氯胺酮代谢物);" + + "吗啡(海洛因二级代谢产物)、O6-单乙酰吗啡(海洛因一级代谢产物);" + + "可待因;" + + "可卡因、苯甲酰爱康宁(可卡因代谢物);" + + "3,4-亚甲基二氧甲基苯丙胺(摇头丸MDMA)、3,4-亚甲基二氧基苯丙胺(摇头丸代谢物);" + + "芬太尼。"; + String populationMarkers = "可替宁(烟草代谢物)"; + + // 查询检验数据 + List dataSolutionSampleDTOS = testRecordSampleDataMapper.queryDataSolutionSampleDTOList(Wrappers.query() + .in("si.id", sampleInfoList.stream().map(SampleInfo::getId).collect(Collectors.toList()))); + // 筛选出未检出的列表 + List undetectedList = dataSolutionSampleDTOS + .stream() + .filter(o -> o.getIsDetected() == 0) + .collect(Collectors.toList()); + // 筛选出检出的列表 + List detectedList = dataSolutionSampleDTOS + .stream() + .filter(o -> o.getIsDetected() == 1) + .collect(Collectors.toList()); + // 在根据检出的列表进行分类 + Map> groupByCompoundNameMap = detectedList + .stream() + .collect(Collectors.groupingBy(DataSolutionSampleDTO::getCompoundName)); + StringBuilder inspectResultAnalysis = new StringBuilder(); // 报告的检测结果分析 +// String commonDrugConsumeStructureChartInputStream = generateCommonDrugConsumeStructureChart(detectedList, groupByCompoundNameMap, inspectResultAnalysis); + // 把未检出的数据也拼凑到结果分析中 + inspectResultAnalysis + .append( + undetectedList + .stream() + .map(DataSolutionSampleDTO::getCompoundName) + .collect(Collectors.joining("、")) + ) + .append("均未检出,暂未发现明显滥用。"); + + // 获取陕西省各行政区主要毒品总消费量表数据 + List regionalDrugConsumptionDTOList = fetchRegionalDrugConsumption(data); + // 陕西省各行政区毒品千人均消费量统计图 输入流 +// ByteArrayInputStream drugConsumePerThousandPeopleByRegionChartInputStream = generateDrugConsumePerThousandPeopleByRegionChart(regionalDrugConsumptionDTOList, groupByCompoundNameMap.keySet()); + // 陕西省毒品千人均消费量变化趋势 统计图 输入流 +// generateDrugConsumePerThousandTrendChart(); + + Map docMap = new HashMap<>(); + docMap.put("yearMonth", null); + docMap.put("organization", organization); + docMap.put("generateDate", generateDate); + docMap.put("province", province); + docMap.put("collectDate1", collectDate1); + docMap.put("collectDate2", collectDate2); + docMap.put("samplingDate1", samplingDate1); + docMap.put("samplingDate2", samplingDate2); + docMap.put("materialNum", materialNum); + docMap.put("commonDrugAndMetabolite", commonDrugAndMetabolite); + docMap.put("populationMarkers", populationMarkers); + ChartSingleSeriesRenderData chartSingleSeriesRenderData = Charts + .ofSingleSeries("", new String[]{"海洛因", "冰毒", "氯胺酮", "可卡因"}) + .series("", new Number[]{76, 12, 2, 10}) + .create(); + docMap.put("demo", chartSingleSeriesRenderData); + +// docMap.put("commonDrugConsumeStructure", chartSingleSeriesRenderData); +// try { +// ChartSingleSeriesRenderData chartSingleSeriesRenderData = Charts.ofPie("", new String[]{"海洛因", "冰毒", "氯胺酮", "可卡因"}) +// .series("", new Number[]{76, 12, 2, 10}).create(); +// docMap.put("commonDrugConsumeStructure", chartSingleSeriesRenderData); +// docMap.put("commonDrugConsumeStructure", +// new ImageEntity(commonDrugConsumeStructureChartInputStream, 450, 265)); + +// } catch (Exception e) { +// e.printStackTrace(); +// log.error(e.getMessage()); +// } + docMap.put("abuseContent", inspectResultAnalysis.toString()); + docMap.put("regionalDrugConsumptionDTOList", regionalDrugConsumptionDTOList); + + String templatePath = OSSDirectoryConstants.DOCUMENT_SEWAGE_REPORTS_DIRECTORY + "/" + dto.getJobId() + "/" + "污水样品毒品检测分析报告-"; + String templateName = "污水样品毒品检测分析报告模板.docx"; + String fileType = ".docx"; + String originalFilename = "污水样品毒品检测分析报告-"; + List listNameCollection = new ArrayList<>(); + listNameCollection.add("abuseStatusList"); + listNameCollection.add("regionalDrugConsumptionDTOList"); + R r = remoteGenerateWordService.generateWord(templateName, originalFilename, templatePath, fileType, null, listNameCollection, false, docMap); + + return null; + } + + + /** + * 获取陕西省各行政区主要毒品总消费量表数据 列表 + * + * @param data + * @return + */ + private List fetchRegionalDrugConsumption(List data) { + + List regionalDrugConsumptionDTOS = new ArrayList<>(); + + List sewageDataDtos = processSewageDataDtos(5.19, data); + // 根据市级编码 分组 + Map> sewageDataGroupByMap = sewageDataDtos + .stream() + .collect(Collectors + .groupingBy(SewageDataDto::getCityName)); + + sewageDataGroupByMap.forEach((k, v) -> { + RegionalDrugConsumptionDTO dto = getRegionalDrugConsumptionDTO(v); + regionalDrugConsumptionDTOS.add(dto); + }); + // TODO 全省平均/总计 计算方式目前还不清楚 + regionalDrugConsumptionDTOS.add(getAllProvinceAvgAndSumDataDTO(regionalDrugConsumptionDTOS)); + + return regionalDrugConsumptionDTOS; + } + + /** + * 获取全省各种毒品的千人均消费量平均值和总消费量 + * + * @param regionalDrugConsumptionDTOS + * @return + */ + private RegionalDrugConsumptionDTO getAllProvinceAvgAndSumDataDTO(List regionalDrugConsumptionDTOS) { + // 这部分是先计算全省各毒品平均消耗量 + double allProvinceHeroinAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccHeroin())); + double allProvinceCocAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccCoc())); + double allProvinceKAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccK())); + double allProvinceMaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMa())); + double allProvinceMdmaAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccMdma())); + double allProvincePccTotalAvg = calculateAverage(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getPccTotal())); + // 全省各毒品的总消耗量 + double allProvinceHeroinTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcHeroin())); + double allProvinceMaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMa())); + double allProvinceKTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcK())); + double allProvinceMdmaTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcMdma())); + double allProvinceCocTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcCoc())); + double allProvinceTotalSum = calculateConsumeSum(regionalDrugConsumptionDTOS, regionalDrugConsumptionDTO -> Double.parseDouble(regionalDrugConsumptionDTO.getTcTotal())); + + // 对小数进行保留1位小数的操作 + DecimalFormat df = new DecimalFormat("#.#"); + RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO(); + dto.setRegional("全省平均/总计"); + // 平均 + dto.setPccHeroin(df.format(allProvinceHeroinAvg)); + dto.setPccMdma(df.format(allProvinceMdmaAvg)); + dto.setPccK(df.format(allProvinceKAvg)); + dto.setPccMa(df.format(allProvinceMaAvg)); + dto.setPccCoc(df.format(allProvinceCocAvg)); + dto.setPccTotal(df.format(allProvincePccTotalAvg)); + + // 总计 + dto.setTcHeroin(df.format(allProvinceHeroinTotalSum)); + dto.setTcMdma(df.format(allProvinceMdmaTotalSum)); + dto.setTcCoc(df.format(allProvinceCocTotalSum)); + dto.setTcMa(df.format(allProvinceMaTotalSum)); + dto.setTcK(df.format(allProvinceKTotalSum)); + dto.setTcTotal(df.format(allProvinceTotalSum)); + + return dto; + } + + /** + * 全省各毒品平均消耗量 + * + * @param regionalDrugConsumptionDTOS + * @param mapper + * @return + */ + private double calculateAverage(List regionalDrugConsumptionDTOS, Function mapper) { + return regionalDrugConsumptionDTOS.stream() + .mapToDouble(mapper::apply) + .average() + .orElse(0.0); + } + + /** + * 全省各毒品总消耗量 + * + * @param regionalDrugConsumptionDTOS + * @param mapper + * @return + */ + private double calculateConsumeSum(List regionalDrugConsumptionDTOS, Function mapper) { + return regionalDrugConsumptionDTOS.stream().mapToDouble(mapper::apply).sum(); + } + + /** + * 获取各行政区主要毒品总消费量 数据传输对象 + * + * @param v + * @return + */ + private RegionalDrugConsumptionDTO getRegionalDrugConsumptionDTO(List v) { + // 对小数进行保留1位小数的操作 + DecimalFormat df = new DecimalFormat("#.#"); + + RegionalDrugConsumptionDTO dto = new RegionalDrugConsumptionDTO(); + SewageDataDto sewageDataDto = v.get(0); + dto.setRegional(sewageDataDto.getCityName()); // 城市名称 + // 总测算人口 + double estimatedPopulationSum = v.stream().mapToDouble(SewageDataDto::getEstimatedPopulation).sum(); + // 各类毒品的总消耗量 + double pccHeroinSum = v.stream().mapToDouble(SewageDataDto::getPccHeroin).sum(); + double pccMaSum = v.stream().mapToDouble(SewageDataDto::getPccMa).sum(); + double pccKSum = v.stream().mapToDouble(SewageDataDto::getPccK).sum(); + double pccMdmaSum = v.stream().mapToDouble(SewageDataDto::getPccMdma).sum(); + double pccCocSum = v.stream().mapToDouble(SewageDataDto::getPccCoc).sum(); + double tcTotal = pccKSum + pccMaSum + pccHeroinSum + pccMdmaSum + pccCocSum; + // 总消费量(克/天), 因为算出来的单位是毫克,所以这里需要除以1000, 综合 + dto.setTcTotal(df.format(tcTotal / 1000)); + dto.setTcHeroin(df.format(pccHeroinSum / 1000)); + dto.setTcMa(df.format(pccMaSum / 1000)); + dto.setTcK(df.format(pccKSum / 1000)); + dto.setTcMdma(df.format(pccMdmaSum / 1000)); + dto.setTcCoc(df.format(pccCocSum / 1000)); + + // 千人均消费量(毫克/千人/天) + double pccHeroin = pccHeroinSum / estimatedPopulationSum; + double pccK = pccKSum / estimatedPopulationSum; + double pccCoc = pccCocSum / estimatedPopulationSum; + double pccMa = pccMaSum / estimatedPopulationSum; + double pccMdma = pccMdmaSum / estimatedPopulationSum; + double pccTotal = pccCoc + pccHeroin + pccCoc + pccMa + pccMdma; + dto.setPccHeroin(df.format(pccHeroin)); + dto.setPccK(df.format(pccK)); + dto.setPccCoc(df.format(pccCoc)); + dto.setPccMa(df.format(pccMa)); + dto.setPccMdma(df.format(pccMdma)); + dto.setPccTotal(df.format(pccTotal)); + return dto; + } + +// /** +// * 生成常用毒品消费结构图, 返回其输入流 +// * +// * @param detectedList +// * @param groupByCompoundNameMap +// * @param inspectResultAnalysis 通过引用来获取值 +// * @return +// */ +// private String generateCommonDrugConsumeStructureChart(List detectedList, +// Map> groupByCompoundNameMap, +// StringBuilder inspectResultAnalysis) { +// String masterDrug = ""; // 主要毒品 +// String secondlyDrug = ""; // 其次毒品 +// +// int size = detectedList.size(); +// // 图例名称 +// List legendList = new ArrayList<>(groupByCompoundNameMap.keySet()); +// List dataList = new ArrayList<>(); +// // 图表背景 +// List colorList = randomGetColorList(legendList.size()); +// // 偏离百分比数据 +// List explodePercentList = new ArrayList<>(); +// for (String key : legendList) { +// List dataSolutionSampleDTOS = groupByCompoundNameMap.get(key); +// // 对小数进行保留两位小数的操作 +// DecimalFormat df = new DecimalFormat("#.##"); +// double percent = (dataSolutionSampleDTOS.size() / (double) size) * 100; +// dataList.add(df.format(percent)); +// // 设置偏离百分比 +// explodePercentList.add(0.01); +// // 大于10%的为主要毒品 +// if (percent > 10) { +// if (StrUtil.isNotBlank(masterDrug)) { +// masterDrug = "主要毒品为" + key; +// } else { +// masterDrug = masterDrug + "、" + key; +// } +// } else { +// if (StrUtil.isNotBlank(secondlyDrug)) { +// secondlyDrug = "其次为" + key; +// } else { +// secondlyDrug = secondlyDrug + "、" + key; +// } +// } +// } +// +// // 合成最终的检测结果分析 +// inspectResultAnalysis +// .append(masterDrug) +// .append(",") +// .append(secondlyDrug) +// .append("。"); +// +// // 创建输出流 +// ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); +// JFreeChart chart = null; +// try { +//// GeneratePieChartUtil.createPieChart( +//// byteArrayOutputStream, +//// "", +//// legendList, +//// dataList, +//// 450, +//// 265, +//// JFreeChartUtil.createChartTheme("宋体"), +//// colorList, +//// explodePercentList); +// chart = GeneratePieChartUtil.createPieChart( +// "", +// legendList, +// dataList, +// JFreeChartUtil.createChartTheme("宋体"), +// colorList, +// explodePercentList); +// File dirFile = new File(ResourceUtils.getURL("classpath:").getPath() + +// "chart/" + +// LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")) + "/"); +// if (!dirFile.exists()) { +// dirFile.mkdirs(); +// } +// String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒")) + "-饼图" + ".png"; +// File file = new File(dirFile.getPath() + "/" + fileName); +// if (file.exists()) { +// file.delete(); +// } +// ChartUtils.saveChartAsPNG(file, chart, 800, 600); +// return dirFile.getPath() + "/" + fileName; +// } catch (Exception e) { +// e.printStackTrace(); +// log.error(e.getMessage()); +// } +// return null; +//// return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); +//// return byteArrayOutputStream.toByteArray(); +// } + + /** + * 获取不同颜色的颜色列表 + * + * @param count + * @return + */ + private List randomGetColorList(int count) { + Random random = new Random(); + + Set colors = new HashSet<>(); + + while (colors.size() < count) { + int red = random.nextInt(256); + int green = random.nextInt(256); + int blue = random.nextInt(256); + + java.awt.Color color = new java.awt.Color(red, green, blue); + colors.add(color); + } + + log.info("获取的颜色RGB: " + colors.toString()); + return new ArrayList<>(colors); + } + + /** + * 推送毛发任务检验数据到上传系统 + * + * @param map + * @return + */ + private List getUploadHairJobDTOS(Map> map) { + List uploadHairJobDTOList = new ArrayList<>(); + map.forEach((k, v) -> { + UploadHairJobDTO uploadHairJobDTO = new UploadHairJobDTO(); + TaskTestDataDTO taskTestDataDTO = v.get(0); + uploadHairJobDTO.setResultId(taskTestDataDTO.getSampleDataId()); + uploadHairJobDTO.setExperimentId(taskTestDataDTO.getTestId()); + uploadHairJobDTO.setSampleId(taskTestDataDTO.getMaterialId()); + uploadHairJobDTO.setAnalysisTime(LocalDateTimeUtil.format(taskTestDataDTO.getCreateTime(), "yyyy-MM-dd")); + uploadHairJobDTO.setSampleCode(taskTestDataDTO.getAcceptNo()); // 样品编号 + uploadHairJobDTO.setEquipmentVendor("三重四极杆液质联用仪"); + uploadHairJobDTO.setEquipmentBrand("Waters TQ-S Micro"); + uploadHairJobDTO.setOrganizationName("国家毒品实验室陕西分中心"); + List uploadHairJobDetailLiteList = new ArrayList<>(); + // 取出每个检材中检测到的化合物浓度 + for (TaskTestDataDTO testDataDTO : v) { + UploadHairJobDetailLite uploadHairJobDetailLite = getUploadHairJobDetailLite(testDataDTO); + uploadHairJobDetailLiteList.add(uploadHairJobDetailLite); + } + uploadHairJobDTO.setDetails(uploadHairJobDetailLiteList); + + uploadHairJobDTOList.add(uploadHairJobDTO); + }); + + R hairJobUploadItem = remoteUploadService.createHairJobUploadItem(uploadHairJobDTOList); + if (hairJobUploadItem.getCode() == CommonConstants.FAIL) { + log.error("数据推送到上传系统失败!"); + throw new RuntimeException("数据推送到上传系统失败!"); + } + + return uploadHairJobDTOList; + } + + /** + * 生成毛发任务详细数据 + * + * @param testDataDTO + * @return + */ + private UploadHairJobDetailLite getUploadHairJobDetailLite(TaskTestDataDTO testDataDTO) { + UploadHairJobDetailLite uploadHairJobDetailLite = new UploadHairJobDetailLite(); + uploadHairJobDetailLite.setCompound(testDataDTO.getCompoundName()); + uploadHairJobDetailLite.setConcentration(testDataDTO.getSampleConcentration()); + // 检出限和定量限暂时设置 + uploadHairJobDetailLite.setExistLimit(0.01); + uploadHairJobDetailLite.setLowerLimit(0.02); + uploadHairJobDetailLite.setStatus(testDataDTO.getIsDetected() == 1 ? "detected" : "noDetected"); + return uploadHairJobDetailLite; + } + + /** + * 推送污水的检验数据到上传系统 + * + * @param map + * @return + */ + private List getUploadSewageJobDTOS(Map> map) { + List uploadSewageJobDTOS = new ArrayList<>(); + Set keySet = map.keySet(); + for (String acceptNo : keySet) { + UploadSewageJobDTO uploadSewageJobDTO = new UploadSewageJobDTO(); + uploadSewageJobDTO.setSampleCode(acceptNo); + ArrayList uploadSewageJobDetailLites = new ArrayList<>(); + List taskTestDataDTOS = map.get(acceptNo); + TaskTestDataDTO dataDTO = taskTestDataDTOS.get(0); + uploadSewageJobDTO.setResultId(taskTestDataDTOS.get(0).getSampleDataId()); + uploadSewageJobDTO.setExperimentId(taskTestDataDTOS.get(0).getTestId()); + uploadSewageJobDTO.setAnalysisTime(LocalDateTimeUtil.format(dataDTO.getCreateTime(), "yyyy-MM-dd")); + uploadSewageJobDTO.setEquipmentVendor("三重四极杆液质联用仪"); + uploadSewageJobDTO.setEquipmentBrand("Waters TQ-S Micro"); + uploadSewageJobDTO.setOrganizationName("国家毒品实验室陕西分中心"); + //获得化合物的Map,用来存储大数据平台需要的化合物信息 + Map compoundMap = this.getSewageCompoundMap(); + Set compoundKeySet = compoundMap.keySet(); + List compoundList = new ArrayList<>(compoundKeySet); + //组装上传数据的内容 + for (TaskTestDataDTO taskTestDataDTO : taskTestDataDTOS) { + String compoundName = taskTestDataDTO.getCompoundName().toLowerCase(); + //如果检验数据属于大数据平台要求上传的数据,那么就将检验出来的浓度赋值过去 + if (compoundKeySet.contains(compoundName)) { + compoundMap.put(compoundName, taskTestDataDTO.getSampleConcentration()); + } + } + //根据大数据平台要求的化合物来封装数据对象 + for (String compoundName : compoundList) { + UploadSewageJobDetailLite uploadSewageJobDetailLite = new UploadSewageJobDetailLite(); + uploadSewageJobDetailLite.setCompound(compoundName); + uploadSewageJobDetailLite.setConcentration(compoundMap.get(compoundName)); + uploadSewageJobDetailLites.add(uploadSewageJobDetailLite); + } + uploadSewageJobDTO.setDetails(uploadSewageJobDetailLites); + uploadSewageJobDTOS.add(uploadSewageJobDTO); + } + remoteUploadService.createUploadItem(uploadSewageJobDTOS); + return uploadSewageJobDTOS; + } + + //获得大数据平台要求的污水数据的化合物Map + public Map getSewageCompoundMap() { + Map map = new HashMap<>(); + map.put("cot", 0.0); + map.put("cod", 0.0); + map.put("mda", 0.0); + map.put("mdma", 0.0); + map.put("coc", 0.0); + map.put("bze", 0.0); + map.put("mor", 0.0); + map.put("o6", 0.0); + map.put("ma", 0.0); + map.put("am", 0.0); + map.put("k", 0.0); + map.put("nk", 0.0); + map.put("thc", 0.0); + return map; + } + + @Override + public List createSewageReportData(String taskId, Double dailySmokingPerCapita) { + TaskInfo taskInfo = this.getById(taskId); + String originalId = taskInfo.getOriginalId(); + if (!StringUtils.isNotBlank(originalId)) { + throw new RuntimeException("当前任务不是污水系统推送任务,无法生成报表!"); + } + R> r = remoteSewageJobIdentificationMaterialService.getSewageJobIdentificationMaterialVOListByJobId(originalId); + List voList = r.getData(); + + List sewageDataDtos = processSewageDataDtos(dailySmokingPerCapita, voList); + return sewageDataDtos; + } + + /** + * 根据污水任务检材列表和人均日吸烟 处理报表数据,最后返回数据列表 + * + * @param dailySmokingPerCapita + * @param voList + * @return + */ + @Override + public List processSewageDataDtos(Double dailySmokingPerCapita, List voList) { + List numList = new ArrayList<>(); + voList.forEach(item -> numList.add(item.getImNo())); + //获得任务中进行实验检材的检出数据 + List taskTestDataDTOList = testRecordSampleDataMapper. + queryWaitApproveTaskTestDataList(Wrappers.query() + .in("ss.sample_no", numList)); + + Map> map = taskTestDataDTOList.stream().collect(Collectors.groupingBy(item -> item.getAcceptNo()));//按照检材编号生成的Map + Set keySet = map.keySet(); + List sewageDataDtos = new ArrayList<>(); + //遍历每个检材,为检材添加化合物检测信息 + for (String key : keySet) { + SewageDataDto sewageDataDto = new SewageDataDto(); + for (SewageJobIdentificationMaterialVO vo : voList) { + if (vo.getImNo().equals(key)) { + BeanUtils.copyProperties(vo, sewageDataDto); + sewageDataDto.setDailySmokingPerCapita(dailySmokingPerCapita); + } + } + + List taskTestDataDTOS = map.get(key);//同一编号的一组化合物数据 + HashMap compoundMap = new HashMap<>(); + taskTestDataDTOS.forEach(item -> { + compoundMap.put(item.getCompoundName().toLowerCase(), item.getSampleConcentration()); + });//把化合物的名称与浓度封装到map中 + sewageDataDto.setCotinineConcentration(compoundMap.get("cot") != null ? compoundMap.get("cot") : 0d);//可替宁 + sewageDataDto.setCodeineConcentration(compoundMap.get("codeine") != null ? compoundMap.get("codeine") : 0d);//可待因 + sewageDataDto.setMdaConcentration(compoundMap.get("mda") != null ? compoundMap.get("mda") : 0d);//mad + sewageDataDto.setMdmaConcentration(compoundMap.get("mdma") != null ? compoundMap.get("mdma") : 0d);//mdma + sewageDataDto.setCocaineConcentration(compoundMap.get("cocaine") != null ? compoundMap.get("cocaine") : 0d);//可卡因 + sewageDataDto.setBenzoylecgonineConcentration(compoundMap.get("benzoylecgonine") != null ? compoundMap.get("benzoylecgonine") : 0d);//苯甲酰爱康宁 + sewageDataDto.setMorphineConcentration(compoundMap.get("morphine") != null ? compoundMap.get("morphine") : 0d);//吗啡 + sewageDataDto.setAcetylmorphineConcentration(compoundMap.get("6-acetylmorphine") != null ? compoundMap.get("6-acetylmorphine") : 0d);//O6-单乙酰吗啡 + sewageDataDto.setMethamphetamineConcentration(compoundMap.get("methamphetamine") != null ? compoundMap.get("methamphetamine") : 0d);//甲基苯丙胺 + sewageDataDto.setAmphetamineConcentration(compoundMap.get("amphetamine") != null ? compoundMap.get("amphetamine") : 0d);//苯丙胺 + sewageDataDto.setKetamineConcentration(compoundMap.get("ketamine") != null ? compoundMap.get("ketamine") : 0d);//氯胺酮 + sewageDataDto.setNorketamineConcentration(compoundMap.get("norketamine") != null ? compoundMap.get("norketamine") : 0d);//去甲氯胺酮 + sewageDataDto.setThcConcentration(compoundMap.get("thc") != null ? compoundMap.get("thc") : 0d);//四氢大麻酸 + sewageDataDto.setFenConcentration(compoundMap.get("fentanyl") != null ? compoundMap.get("fentanyl") : 0d);//芬太尼 + sewageDataDto.setEtomidateConcentration(compoundMap.get("etomidate") != null ? compoundMap.get("etomidate") : 0d);//依托咪酯 + +// for (TaskTestDataDTO taskTestDataDTO : taskTestDataDTOS) { +// switch (taskTestDataDTO.getCompoundName().toLowerCase()) { +// case "cot": +// case "cotinine": { +// sewageDataDto.setCotinineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "codeine": { +// sewageDataDto.setCodeineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "mda": { +// sewageDataDto.setMdaConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "mdma": { +// sewageDataDto.setMdmaConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "cocaine": { +// sewageDataDto.setCocaineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "benzoylecgonine": { +// sewageDataDto.setBenzoylecgonineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "morphine": { +// sewageDataDto.setMorphineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "6-acetylmorphine": { +// sewageDataDto.setAcetylmorphineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "methamphetamine": { +// sewageDataDto.setMethamphetamineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "amphetamine": { +// sewageDataDto.setAmphetamineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "ketamine": { +// sewageDataDto.setKetamineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "norketamine": { +// sewageDataDto.setNorketamineConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "thc": { +// sewageDataDto.setThcConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "fentanyl": { +// sewageDataDto.setFenConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// case "etomidate": { +// sewageDataDto.setEtomidateConcentration(taskTestDataDTO.getSampleConcentration()); +// break; +// } +// } +// } + calculatedConsumption(sewageDataDto, dailySmokingPerCapita); + sewageDataDtos.add(sewageDataDto); + } + return sewageDataDtos; + } + + /** + * 把计算消费量的方法封装一下,此时sewageDataDto中已经保存了检验鉴定系统检出的化合物数据,此方法是用来计算消费量的 + * + * @param sewageDataDto + * @param dailySmokingPerCapita + */ + public void calculatedConsumption(SewageDataDto sewageDataDto, Double dailySmokingPerCapita) { + Double dailyFlow = sewageDataDto.getDailyFlow(); // 当前检材对应的日流 + sewageDataDto.setCotinineExcretion(dailySmokingPerCapita * 0.14 * 1000);//可替宁排泄量 + sewageDataDto.setEstimatedPopulation(sewageDataDto.getCotinineConcentration() * dailyFlow * 10 * sewageDataDto.getDomesticSewageProportion() / 100 / sewageDataDto.getCotinineExcretion());//测算人口 + + Double estimatedPopulation = sewageDataDto.getEstimatedPopulation(); // 当前检材对应的测算人口数量, 后面需要频繁使用到这个值,防止后面频繁调用get消耗时间这里提前存在一个变量里 + Double norketamineConcentration = sewageDataDto.getNorketamineConcentration(); // 去甲氯胺酮的浓度 + Double methamphetamineConcentration = sewageDataDto.getMethamphetamineConcentration(); // 甲基苯丙胺浓度 + Double morphineConcentration = sewageDataDto.getMorphineConcentration(); // 吗啡浓度 + Double amphetamineConcentration = sewageDataDto.getAmphetamineConcentration(); // 苯丙胺浓度 + Double ketamineConcentration = sewageDataDto.getKetamineConcentration(); // 氯胺酮浓度 + Double codeineConcentration = sewageDataDto.getCodeineConcentration(); // 可待因 浓度 + Double thcConcentration = sewageDataDto.getThcConcentration(); // 四氢大麻粉浓度 + Double mdmaConcentration = sewageDataDto.getMdmaConcentration(); // 摇头丸mdma浓度 + Double benzoylecgonineConcentration = sewageDataDto.getBenzoylecgonineConcentration(); // 苯甲酰爱康宁 浓度 + + sewageDataDto.setMorphineLoad(morphineConcentration == 0.0 ? 0 : morphineConcentration * dailyFlow * 10 / estimatedPopulation);//吗啡负荷量(mg/千人﹒天) + sewageDataDto.setCodeineLoad(codeineConcentration == 0.0 ? 0 : codeineConcentration * dailyFlow * 10 / estimatedPopulation);//可待因负荷量(mg/千人﹒天) + sewageDataDto.setCodeineIsConvertedToMorphineLoad(sewageDataDto.getCodeineLoad() * 0.065 / (0.3 * 1.05));//可待因转化为吗啡负荷量(mg/千人﹒天) + sewageDataDto.setMedicalMorphineLoad(1.0);//医用吗啡负荷量(mg/千人﹒天) + + if (amphetamineConcentration == 0.0) { + sewageDataDto.setMA_AM(0.0);//MA/AM + } else { + sewageDataDto.setMA_AM(methamphetamineConcentration / amphetamineConcentration);//MA/AM + } + if (norketamineConcentration == 0.0) { + sewageDataDto.setK_NK(0.0);//K/NK 除数为0了,我们直接把结果赋为0 + } else { + sewageDataDto.setK_NK(ketamineConcentration / norketamineConcentration);//K/NK + } + sewageDataDto.setPccHeroin((sewageDataDto.getMorphineLoad() - sewageDataDto.getCodeineIsConvertedToMorphineLoad() - sewageDataDto.getMedicalMorphineLoad()) * 3.07);//人均消耗量(mg/千人﹒天)Heroin + + if (amphetamineConcentration == 0.0 || (amphetamineConcentration != 0.0 && sewageDataDto.getMA_AM() <= 20)) { + sewageDataDto.setPccMa(methamphetamineConcentration == 0.0 ? 0 : methamphetamineConcentration * dailyFlow * 10 * 2.33 / estimatedPopulation);//人均消耗量(mg/千人﹒天)MA + } else { + sewageDataDto.setPccMa(amphetamineConcentration == 0.0 ? 0 : amphetamineConcentration * dailyFlow * 10 * 46.6 / estimatedPopulation);//人均消耗量(mg/千人﹒天)MA + } + if (norketamineConcentration == 0.0 || (norketamineConcentration != 0.0 && sewageDataDto.getK_NK() <= 6)) { + sewageDataDto.setPccK(ketamineConcentration == 0 ? 0 : ketamineConcentration * dailyFlow * 10 * 5 / estimatedPopulation);//人均消耗量(mg/千人﹒天)K + } else { + sewageDataDto.setPccK(norketamineConcentration == 0 ? 0 : norketamineConcentration * dailyFlow * 10 * 26.6 / estimatedPopulation);//人均消耗量(mg/千人﹒天)K + } + sewageDataDto.setPccFen(0d); + sewageDataDto.setTcFen(0d); + + sewageDataDto.setPccK(ketamineConcentration == 0.0 ? 0 : ketamineConcentration * dailyFlow * 10 * 5 / estimatedPopulation);//人均消耗量(mg/千人﹒天)K + sewageDataDto.setPccMdma(mdmaConcentration == 0.0 ? 0 : mdmaConcentration * dailyFlow * 10 * 4.44 / estimatedPopulation);//人均消耗量(mg/千人﹒天)MDMA + sewageDataDto.setPccCoc(benzoylecgonineConcentration == 0.0 ? 0 : benzoylecgonineConcentration * dailyFlow * 10 * 2.33 / estimatedPopulation);//人均消耗量(mg/千人﹒天)COC + sewageDataDto.setPccThc(thcConcentration == 0.0 ? 0 : thcConcentration * dailyFlow * 10 * 152 / estimatedPopulation);//人均消耗量(mg/千人﹒天)THC + // 在这里对计算结果为非数值的数据,防止对后续的使用造成影响 + processNaNAndInfinityData(sewageDataDto); + sewageDataDto.setTcHeroin(sewageDataDto.getPccHeroin() * estimatedPopulation);//总消耗量Heroin + sewageDataDto.setTcMa(sewageDataDto.getPccMa() * estimatedPopulation);//总消耗量MA + sewageDataDto.setTcK(sewageDataDto.getPccK() * estimatedPopulation);//总消耗量K + sewageDataDto.setTcMdma(sewageDataDto.getPccMdma() * estimatedPopulation);//总消耗量MDMA + sewageDataDto.setTcCoc(sewageDataDto.getPccCoc() * estimatedPopulation);//总消耗量COC + sewageDataDto.setTcThc(sewageDataDto.getPccThc() * estimatedPopulation);//总消耗量THC + } + + /** + * 在这里对计算结果为非数值的数据,防止对后续的使用造成影响 Double.isFinite() 这个的方法作用是判断当前数字是不是在规定的有限数值范围内,是返回true, 不是返回false + * + * @param sewageDataDto + */ + private void processNaNAndInfinityData(SewageDataDto sewageDataDto) { + if (!Double.isFinite(sewageDataDto.getPccCoc()) || sewageDataDto.getPccCoc() < 0d) { + sewageDataDto.setPccCoc(0d); + } + if (!Double.isFinite(sewageDataDto.getPccHeroin()) || sewageDataDto.getPccHeroin() < 0d) { + sewageDataDto.setPccHeroin(0d); + } + if (!Double.isFinite(sewageDataDto.getPccK()) || sewageDataDto.getPccK() < 0d) { + sewageDataDto.setPccK(0d); + } + if (!Double.isFinite(sewageDataDto.getPccMdma()) || sewageDataDto.getPccMdma() < 0d) { + sewageDataDto.setPccMdma(0d); + } + if (!Double.isFinite(sewageDataDto.getPccCoc()) || sewageDataDto.getPccCoc() < 0d) { + sewageDataDto.setPccMa(0d); + } + if (!Double.isFinite(sewageDataDto.getPccThc()) || sewageDataDto.getPccThc() < 0d) { + sewageDataDto.setPccThc(0d); + } + if (!Double.isFinite(sewageDataDto.getPccFen()) || sewageDataDto.getPccFen() < 0d) { + sewageDataDto.setPccFen(0d); + } + } + + @Override + public String createSewageReportExcel(List sewageDataDtos, String id) throws IOException { + String temporarilyPath = "C:\\tmp\\upload\\";//用来临时存储生成的文件,用于OSS上传,待OSS上传成功后将这个路径下的文件删除 + HSSFWorkbook workbook = new HSSFWorkbook(); + HSSFCellStyle redCellStyle = workbook.createCellStyle();//表头样式 + HSSFCellStyle cellStyle = workbook.createCellStyle();//表格样式 + HSSFCellStyle redBackdropStyle = workbook.createCellStyle();//红色背景样式 + HSSFCellStyle pinkBackgroundStyle = workbook.createCellStyle();//粉色背景样式 + + HSSFFont redBackdropFont = workbook.createFont(); + HSSFFont font = workbook.createFont(); + HSSFFont redFont = workbook.createFont(); + + redFont.setFontHeightInPoints((short) 9); + redFont.setFontName("黑体"); + redFont.setColor(IndexedColors.RED.getIndex()); + redBackdropFont.setFontHeightInPoints((short) 9); + redBackdropFont.setFontName("黑体"); + redBackdropFont.setColor(IndexedColors.MAROON.getIndex()); + font.setFontName("黑体"); + font.setFontHeightInPoints((short) 9); + //红色背景填充 + redBackdropStyle.setFillForegroundColor(IndexedColors.CORAL.getIndex());//填充颜色 + redBackdropStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);//填充类型 + redBackdropStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中 + redBackdropStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中 + //粉色背景填充 + pinkBackgroundStyle.setFillForegroundColor(IndexedColors.TAN.getIndex()); + pinkBackgroundStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + pinkBackgroundStyle.setAlignment(HorizontalAlignment.CENTER); + pinkBackgroundStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + redCellStyle.setAlignment(HorizontalAlignment.CENTER); + redCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + cellStyle.setAlignment(HorizontalAlignment.CENTER); + cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); + + cellStyle.setFont(font); + redCellStyle.setFont(redFont); + redBackdropStyle.setFont(redBackdropFont); + pinkBackgroundStyle.setFont(font); + + + Map> map = sewageDataDtos.stream().collect(Collectors.groupingBy(item -> item.getCityName()));//按市名称进行分组 + Set cityNameList = map.keySet(); + + //组装每个市检材的数据 + for (String cityName : cityNameList) { + List sewageDataDtoList = map.get(cityName); + Collections.sort(sewageDataDtoList, new Comparator() { + @Override + public int compare(SewageDataDto o1, SewageDataDto o2) { + return o1.getImNo().compareTo(o2.getImNo()); + } + }); + //工作表名称 + HSSFSheet sheet = workbook.createSheet(sewageDataDtoList.get(0).getJobYear() + "-" + sewageDataDtoList.get(0).getJobSeason() + "-" + cityName.substring(0, cityName.length() - 1)); + for (int i = 0; i < 49; i++) { + sheet.setColumnWidth(i, 5000); + } + //给特殊的单元格设置长一点的宽度 + sheet.setColumnWidth(1, 10000); + sheet.setColumnWidth(10, 5800); + sheet.setColumnWidth(26, 5500); + sheet.setColumnWidth(27, 5800); + sheet.setColumnWidth(28, 6500); + sheet.setColumnWidth(29, 6500); + sheet.setColumnWidth(33, 5500); + sheet.setColumnWidth(50, 3500); + + //获得表头数据 + List columns = Arrays.asList(SewageReportColumn.values()); + + //开始构建表头 + HSSFRow row0 = sheet.createRow(0);//创建第一行 + row0.setHeight((short) 1200); + for (int i = 0; i < columns.size(); i++) { + HSSFCell cell = row0.createCell(i); + //有些列字体颜色会有变化,且会有背景填充,这边将逻辑写在枚举类中,用于传入单独的style样式 + SewageReportColumn sewageReportColumn = columns.get(i); + if (sewageReportColumn.getBackgroundColor().equals("red")) { + cell.setCellStyle(redBackdropStyle); + } else if (sewageReportColumn.getBackgroundColor().equals("pink")) { + cell.setCellStyle(pinkBackgroundStyle); + } else if (sewageReportColumn.getFontColor().equals("red") && sewageReportColumn.getBackgroundColor().equals("")) { + cell.setCellStyle(redCellStyle); + } else { + cell.setCellStyle(cellStyle); + } + cell.setCellValue(sewageReportColumn.getColumnName()); + } + //总消耗量与总测算人口 + double sumEstimatedPopulation = 0; + double sumHeroin = 0; + double sumMa = 0; + double sumK = 0; + double sumMDMA = 0; + double sumCoc = 0; + double sumThc = 0; + + for (int i = 0; i < sewageDataDtoList.size() + 1; i++) { + //构建最后两行中的消费量总量和人均量消费量数据 + if (i == sewageDataDtoList.size()) { + HSSFRow lastTwoRow = sheet.createRow(i + 1); + HSSFRow lastOneRow = sheet.createRow(i + 2); + lastTwoRow.setHeight((short) 300); + lastOneRow.setHeight((short) 300); + + HSSFCell lastTwoRowCell42 = lastTwoRow.createCell(42); + lastTwoRowCell42.setCellValue("总和"); + lastTwoRowCell42.setCellStyle(cellStyle); + + HSSFCell twoRowCell11 = lastTwoRow.createCell(11); + twoRowCell11.setCellValue(String.format("%.2f", sumEstimatedPopulation)); + twoRowCell11.setCellStyle(cellStyle); + + HSSFCell lastRowCell = lastOneRow.createCell(42); + lastRowCell.setCellValue("人均消耗量"); + lastRowCell.setCellStyle(pinkBackgroundStyle); + + HSSFCell lastRowCell50 = lastOneRow.createCell(50); + lastRowCell50.setCellValue("人均总消耗量"); + lastRowCell50.setCellStyle(pinkBackgroundStyle); + + HSSFCell lastTwoRowCell43 = lastTwoRow.createCell(43); + lastTwoRowCell43.setCellValue(String.format("%.1f", sumHeroin)); + lastTwoRowCell43.setCellStyle(cellStyle); + + HSSFCell lastTwoRowCell44 = lastTwoRow.createCell(44); + lastTwoRowCell44.setCellValue(String.format("%.1f", sumMa)); + lastTwoRowCell44.setCellStyle(cellStyle); + + HSSFCell lastTwoRowCell45 = lastTwoRow.createCell(45); + lastTwoRowCell45.setCellValue(String.format("%.1f", sumK)); + lastTwoRowCell45.setCellStyle(cellStyle); + + HSSFCell lastTwoRowCell46 = lastTwoRow.createCell(46); + lastTwoRowCell46.setCellValue(String.format("%.1f", sumMDMA)); + lastTwoRowCell46.setCellStyle(cellStyle); + + HSSFCell lastTwoRowCell47 = lastTwoRow.createCell(47); + lastTwoRowCell47.setCellValue(String.format("%.1f", sumCoc)); + lastTwoRowCell47.setCellStyle(cellStyle); + + HSSFCell lastTwoRowCell48 = lastTwoRow.createCell(48); + lastTwoRowCell48.setCellValue(String.format("%.1f", sumThc)); + lastTwoRowCell48.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell43 = lastOneRow.createCell(43); + lastOneRowCell43.setCellValue(String.format("%.1f", (sumHeroin / sumEstimatedPopulation))); + lastOneRowCell43.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell44 = lastOneRow.createCell(44); + lastOneRowCell44.setCellValue(String.format("%.1f", (sumMa / sumEstimatedPopulation))); + lastOneRowCell44.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell45 = lastOneRow.createCell(45); + lastOneRowCell45.setCellValue(String.format("%.1f", (sumK / sumEstimatedPopulation))); + lastOneRowCell45.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell46 = lastOneRow.createCell(46); + lastOneRowCell46.setCellValue(String.format("%.1f", (sumMDMA / sumEstimatedPopulation))); + lastOneRowCell46.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell47 = lastOneRow.createCell(47); + lastOneRowCell47.setCellValue(String.format("%.1f", (sumCoc / sumEstimatedPopulation))); + lastOneRowCell47.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell48 = lastOneRow.createCell(48); + lastOneRowCell48.setCellValue(String.format("%.1f", (sumThc / sumEstimatedPopulation))); + lastOneRowCell48.setCellStyle(cellStyle); + + HSSFCell lastOneRowCell51 = lastOneRow.createCell(51); + lastOneRowCell51.setCellValue(String.format("%.2f", sumHeroin / sumEstimatedPopulation + sumCoc / sumEstimatedPopulation + sumK / sumEstimatedPopulation * 0.1 + sumMa / sumEstimatedPopulation + sumMDMA / sumEstimatedPopulation * 0.5 + sumThc / sumEstimatedPopulation)); + lastOneRowCell51.setCellStyle(cellStyle); + break; + } + + //构建检材数据 + SewageDataDto sewageDataDto = sewageDataDtoList.get(i); + HSSFRow rowi = sheet.createRow(i + 1); + rowi.setHeight((short) 300); + + HSSFCell celli0 = rowi.createCell(0); + celli0.setCellValue(sewageDataDto.getImNo()); + celli0.setCellStyle(cellStyle); + + HSSFCell celli1 = rowi.createCell(1); + celli1.setCellValue(sewageDataDto.getSampleName()); + celli1.setCellStyle(cellStyle); + + HSSFCell celli2 = rowi.createCell(2); + celli2.setCellValue(sewageDataDto.getProvinceName()); + celli2.setCellStyle(cellStyle); + + HSSFCell celli3 = rowi.createCell(3); + celli3.setCellValue(sewageDataDto.getCityName()); + celli3.setCellStyle(cellStyle); + + HSSFCell celli4 = rowi.createCell(4); + celli4.setCellValue(sewageDataDto.getDistrictName()); + celli4.setCellStyle(cellStyle); + + HSSFCell celli5 = rowi.createCell(5); + celli5.setCellValue(LocalDateTimeUtil.format(sewageDataDto.getCollectTime(), "yyyy/MM/dd")); + celli5.setCellStyle(cellStyle); + + HSSFCell celli6 = rowi.createCell(6); + celli6.setCellValue(sewageDataDto.getServicePopulation()); + celli6.setCellStyle(cellStyle); + + HSSFCell celli7 = rowi.createCell(7); + celli7.setCellValue(sewageDataDto.getDomesticSewageProportion() + "%"); + celli7.setCellStyle(cellStyle); + + HSSFCell celli8 = rowi.createCell(8); + celli8.setCellValue(sewageDataDto.getDailyFlow()); + celli8.setCellStyle(cellStyle); + + HSSFCell celli9 = rowi.createCell(9); + celli9.setCellValue(sewageDataDto.getDailySmokingPerCapita()); + celli9.setCellStyle(cellStyle); + + HSSFCell celli10 = rowi.createCell(10); + celli10.setCellValue(sewageDataDto.getCotinineExcretion()); + celli10.setCellStyle(cellStyle); + + HSSFCell celli11 = rowi.createCell(11); + celli11.setCellValue(String.format("%.2f", sewageDataDto.getEstimatedPopulation())); + celli11.setCellStyle(cellStyle); + sumEstimatedPopulation += sewageDataDto.getEstimatedPopulation(); + + HSSFCell celli12 = rowi.createCell(12); + celli12.setCellStyle(cellStyle); + celli12.setCellValue(String.format("%.1f", sewageDataDto.getCotinineConcentration())); + + HSSFCell celli13 = rowi.createCell(13); + celli13.setCellStyle(cellStyle); + celli13.setCellValue(sewageDataDto.getCodeineConcentration()); + + HSSFCell celli14 = rowi.createCell(14); + celli14.setCellStyle(cellStyle); + celli14.setCellValue(String.format("%.1f", sewageDataDto.getMdaConcentration())); + + HSSFCell celli15 = rowi.createCell(15); + celli15.setCellStyle(cellStyle); + celli15.setCellValue(String.format("%.1f", sewageDataDto.getMdmaConcentration())); + + HSSFCell celli16 = rowi.createCell(16); + celli16.setCellStyle(cellStyle); + celli16.setCellValue(String.format("%.1f", sewageDataDto.getCocaineConcentration())); + + HSSFCell celli17 = rowi.createCell(17); + celli17.setCellStyle(cellStyle); + celli17.setCellValue(String.format("%.1f", sewageDataDto.getBenzoylecgonineConcentration())); + + HSSFCell celli18 = rowi.createCell(18); + celli18.setCellStyle(cellStyle); + celli18.setCellValue(String.format("%.1f", sewageDataDto.getMorphineConcentration())); + + HSSFCell celli19 = rowi.createCell(19); + celli19.setCellStyle(cellStyle); + celli19.setCellValue(String.format("%.1f", sewageDataDto.getAcetylmorphineConcentration())); + + HSSFCell celli20 = rowi.createCell(20); + celli20.setCellStyle(cellStyle); + celli20.setCellValue(String.format("%.1f", sewageDataDto.getMethamphetamineConcentration())); + + HSSFCell celli21 = rowi.createCell(21); + celli21.setCellStyle(cellStyle); + celli21.setCellValue(String.format("%.1f", sewageDataDto.getAmphetamineConcentration())); + + HSSFCell celli22 = rowi.createCell(22); + celli22.setCellStyle(cellStyle); + celli22.setCellValue(String.format("%.1f", sewageDataDto.getKetamineConcentration())); + + HSSFCell celli23 = rowi.createCell(23); + celli23.setCellStyle(cellStyle); + celli23.setCellValue(String.format("%.1f", sewageDataDto.getNorketamineConcentration())); + + HSSFCell celli24 = rowi.createCell(24); + celli24.setCellStyle(cellStyle); + celli24.setCellValue(String.format("%.1f", sewageDataDto.getThcConcentration())); + + HSSFCell celli25 = rowi.createCell(25); + celli25.setCellStyle(cellStyle); + celli25.setCellValue(""); + + + HSSFCell celli26 = rowi.createCell(26); + celli26.setCellStyle(cellStyle); + celli26.setCellValue(String.format("%.1f", sewageDataDto.getMorphineLoad())); + + HSSFCell celli27 = rowi.createCell(27); + celli27.setCellStyle(cellStyle); + celli27.setCellValue(String.format("%.1f", sewageDataDto.getCodeineLoad())); + + HSSFCell celli28 = rowi.createCell(28); + celli28.setCellStyle(cellStyle); + celli28.setCellValue(String.format("%.1f", sewageDataDto.getCodeineIsConvertedToMorphineLoad())); + + HSSFCell celli29 = rowi.createCell(29); + celli29.setCellValue(sewageDataDto.getMedicalMorphineLoad()); + celli29.setCellStyle(cellStyle); + + HSSFCell celli30 = rowi.createCell(30); + celli30.setCellStyle(cellStyle); + celli30.setCellValue(String.format("%.1f", sewageDataDto.getMA_AM())); + + HSSFCell celli31 = rowi.createCell(31); + celli31.setCellStyle(cellStyle); + celli31.setCellValue(String.format("%.1f", sewageDataDto.getK_NK())); + + HSSFCell celli32 = rowi.createCell(32); + celli32.setCellValue(""); + HSSFCell celli33 = rowi.createCell(33); + celli33.setCellValue(""); + + HSSFCell celli34 = rowi.createCell(34); + celli34.setCellStyle(cellStyle); + celli34.setCellValue(String.format("%.1f", sewageDataDto.getPccHeroin())); + + HSSFCell celli35 = rowi.createCell(35); + celli35.setCellStyle(pinkBackgroundStyle); + celli35.setCellValue(String.format("%.1f", sewageDataDto.getPccMa())); + + HSSFCell celli36 = rowi.createCell(36); + celli36.setCellStyle(cellStyle); + celli36.setCellValue(String.format("%.1f", sewageDataDto.getPccK())); + + HSSFCell celli37 = rowi.createCell(37); + celli37.setCellStyle(cellStyle); + celli37.setCellValue(String.format("%.1f", sewageDataDto.getPccMdma())); + + HSSFCell celli38 = rowi.createCell(38); + celli38.setCellStyle(cellStyle); + celli38.setCellValue(String.format("%.1f", sewageDataDto.getPccCoc())); + + HSSFCell celli39 = rowi.createCell(39); + celli39.setCellStyle(cellStyle); + celli39.setCellValue(String.format("%.1f", sewageDataDto.getPccThc())); + + HSSFCell celli40 = rowi.createCell(40); + celli40.setCellValue(""); + HSSFCell celli41 = rowi.createCell(41); + celli41.setCellValue(""); + HSSFCell celli42 = rowi.createCell(42); + celli42.setCellValue(""); + + HSSFCell celli43 = rowi.createCell(43); + celli43.setCellStyle(cellStyle); + celli43.setCellValue(String.format("%.1f", sewageDataDto.getTcHeroin())); + sumHeroin += sewageDataDto.getTcHeroin(); + + HSSFCell celli44 = rowi.createCell(44); + celli44.setCellStyle(cellStyle); + celli44.setCellValue(String.format("%.1f", sewageDataDto.getTcMa())); + sumMa += sewageDataDto.getTcMa(); + + HSSFCell celli45 = rowi.createCell(45); + celli45.setCellStyle(cellStyle); + celli45.setCellValue(String.format("%.1f", sewageDataDto.getTcK())); + sumK += sewageDataDto.getTcK(); + + HSSFCell celli46 = rowi.createCell(46); + celli46.setCellStyle(cellStyle); + celli46.setCellValue(String.format("%.1f", sewageDataDto.getTcMdma())); + sumMDMA += sewageDataDto.getTcMdma(); + + HSSFCell celli47 = rowi.createCell(47); + celli47.setCellStyle(cellStyle); + celli47.setCellValue(String.format("%.1f", sewageDataDto.getTcCoc())); + sumCoc += sewageDataDto.getTcCoc(); + + HSSFCell celli48 = rowi.createCell(48); + celli48.setCellStyle(cellStyle); + celli48.setCellValue(String.format("%.1f", sewageDataDto.getTcThc())); + sumThc += sewageDataDto.getTcThc(); + } + } + String fileName = sewageDataDtos.get(0).getJobYear() + "年" + sewageDataDtos.get(0).getJobSeason() + "月污水" + "消费量报表.xls"; + FileOutputStream fileOutputStream = new FileOutputStream(temporarilyPath + fileName); + workbook.write(fileOutputStream); + fileOutputStream.close(); + File file = new File(temporarilyPath, fileName); + FileItem fileItem = testRecordInstrumentConditionService.getMultipartFile(file, file.getName()); + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + String ossPath = "document/sewageReport/" + id; + boolean ret = ossFile.fileUpload(multipartFile, "document/sewageReport/" + id); + if (ret) { + Files.delete(Paths.get(temporarilyPath, fileName)); + } + workbook.close(); + return ossPath + "/" + fileName; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentConditionServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentConditionServiceImpl.java new file mode 100644 index 0000000..45836b9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentConditionServiceImpl.java @@ -0,0 +1,433 @@ +package digital.laboratory.platform.inspection.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.deepoove.poi.xwpf.NiceXWPFDocument; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.TestRecordFileUrl; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordInstrumentCondition; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordInstrumentConditionMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.commons.CommonsMultipartFile; + +import javax.annotation.Resource; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +@Service +@SuppressWarnings("all") +public class TestRecordInstrumentConditionServiceImpl extends ServiceImpl implements TestRecordInstrumentConditionService { + + @Resource + private TestRecordService testRecordService; + @Resource + private TestRecordMapper testRecordMapper; + @Resource + private TestTemplateService testTemplateService; + @Resource + private TestTemplateMapper testTemplateMapper; + @Resource + private SampleInfoService sampleInfoService; + @Resource + private OssFile ossFile; + @Resource + private EntrustInfoService entrustInfoService; + private final String fileName = "仪器条件.docx"; + + /** + * 新增实验仪器条件 + * + * @param testRecordInstrumentCondition + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public TestRecordInstrumentCondition addInstrumentCondition(TestRecordInstrumentCondition testRecordInstrumentCondition) { + testRecordInstrumentCondition.setId(IdWorker.get32UUID().toUpperCase()); + boolean ret = testRecordService.updateTestRecordArgument(testRecordInstrumentCondition.getTestId(), testRecordInstrumentCondition.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION.getType(), 1); + return this.save(testRecordInstrumentCondition) && ret ? testRecordInstrumentCondition : null; + } + + /** + * 删除仪器条件 + * + * @param id + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean delInstrumentCondition(String id) { + Integer opCode = -1;//表示从实验中删除 + TestRecordInstrumentCondition instrumentCondition = this.getById(id); + List testRecordList = testRecordMapper.getTestRecordMapList(new LambdaQueryWrapper()); + boolean ret = testRecordService.updateTestRecordArgument(instrumentCondition.getTestId(), instrumentCondition.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION.getType(), opCode); + return this.removeById(id) && ret; + } + + /** + * 向实验添加仪器条件 + * + * @param testRecordInstrumentCondition + * @return + */ + @Override + public TestRecordInstrumentCondition updateInstrumentCondition(TestRecordInstrumentCondition testRecordInstrumentCondition) { + return this.updateById(testRecordInstrumentCondition) ? testRecordInstrumentCondition : null; + } + + /** + * 通过实验ID获取这个实验的仪器条件 + * + * @param testId + * @return + */ + @Override + public TestRecordInstrumentCondition getInstrumentConditionByTestId(String testId) { + return baseMapper.getTestRecordInstrumentConditionVoMapByTestId(testId); + } + + /** + * 为模板添加或移除仪器条件 + * + * @param testRecordArgumentDto + * @return + */ + @Override + public boolean useInstrumentConditionToTemplate(TestRecordArgumentDto testRecordArgumentDto) { + return testTemplateService.updateTestTemplate(testRecordArgumentDto.getTemplateId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION.getType(), testRecordArgumentDto.getOpCode()); + } + + /** + * 复制仪器条件 + * + * @param idList 仪器条件ID集合 + * @param testId + * @return + */ + @Override + public List copyCondition(List idList, String testId) { + ArrayList newIdList = new ArrayList<>(); + ArrayList instrumentConditions = new ArrayList<>(); + List list = this.list(new LambdaQueryWrapper().in(TestRecordInstrumentCondition::getId, idList)); + for (TestRecordInstrumentCondition testRecordInstrumentConditionVo : list) { + TestRecordInstrumentCondition newTestRecordInstrumentCondition = new TestRecordInstrumentCondition(); + newTestRecordInstrumentCondition.setConditionData(testRecordInstrumentConditionVo.getConditionData()); + newTestRecordInstrumentCondition.setBusinessFlag(testRecordInstrumentConditionVo.getBusinessFlag()); + newTestRecordInstrumentCondition.setTestId(testId); + newTestRecordInstrumentCondition.setId(IdWorker.get32UUID().toUpperCase()); + newIdList.add(newTestRecordInstrumentCondition.getId()); + instrumentConditions.add(newTestRecordInstrumentCondition); + } + this.saveBatch(instrumentConditions); + return newIdList; + } + + /** + * 判断这个实验是否生成了仪器条件 + * + * @param testId + * @return + */ + @Override + public String generatedOrNot(String testId) { + String path = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId; + List fileList = ossFile.fileList(path); + for (String name : fileList) { + if (name.equals(fileName)) { + return path + "/" + fileName; + } + } + return null; + } + + /** + * 为实验生成仪器条件模板 + * + * @param testId + * @param type 1:生物样本仪器条件 -1 :缴获物仪器条件 + * @return + * @throws Exception + */ + @Override + public boolean createConditionWordByTest(String testId) throws Exception { + TestRecordVo vo = testRecordMapper.getTestRecordMapById(testId); + String businessType = vo.getBusinessType(); + if (!StringUtils.isNotBlank(businessType)) { + throw new RuntimeException(String.format("当前还未选择样本,无法确定实验类型,请添加样本后再进行创建!")); + } + if (!businessType.startsWith("1")) { + throw new RuntimeException(String.format("任务或筛查无需创建仪器条件!")); + } + String url = ""; + if (businessType.equals("10002")) {//type = 1 代表是生物样本类型的仪器条件 + url = TestRecordFileUrl.TEST_RECORD_BIOLOGICAL_SAMPLE_INSTRUMENT_CONDITION_TEMPLATE.getFileUrl(); + } else { + url = TestRecordFileUrl.TEST_RECORD_SEIZURE_INSTRUMENT_CONDITION_TEMPLATE.getFileUrl(); + } + String filePath = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + fileName; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + ossFile.fileGet(url, bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + boolean ret = ossFile.fileSave(filePath, bis); + bos.close(); + bis.close(); + return ret; + } + + /** + * 为模板生成仪器条件模板 + * + * @param testId + * @param type 1:生物样本仪器条件 -1 :缴获物仪器条件 + * @return + * @throws Exception + */ + @Override + public boolean createConditionWordByTemplate(String templateId) throws Exception { + String url = ""; + TestTemplateVo vo = testTemplateMapper.getTestTemplateMapById(templateId); + if (vo.getBusinessType().equals("10002")) {//代表是生物样本类型的仪器条件 + url = TestRecordFileUrl.TEST_RECORD_BIOLOGICAL_SAMPLE_INSTRUMENT_CONDITION_TEMPLATE.getFileUrl(); + } else { + url = TestRecordFileUrl.TEST_RECORD_SEIZURE_INSTRUMENT_CONDITION_TEMPLATE.getFileUrl(); + } + String filePath = TestRecordFileUrl.TEST_TEMPLATE_CATALOGUE.getFileUrl() + "/" + templateId + "/" + fileName; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + ossFile.fileGet(url, bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + boolean ret = ossFile.fileSave(filePath, bis); + //创建好后将仪器条件类型存储在实验里面 + bos.close(); + bis.close(); + return ret; + } + +// /** +// * 判断是否能够选择这个类型的仪器条件模板 +// * +// * @param testId +// * @param type : 1:生物样本仪器条件 -1 :缴获物仪器条件 +// */ +// public void comparisonTypeForTest(String testId, Integer type) { +// TestRecordVo vo = testRecordMapper.getTestRecordMapById(testId); +// String businessType = vo.getBusinessType(); +// if (StringUtils.isNotBlank(businessType)) { +// if (!businessType.startsWith("1")) { +// throw new RuntimeException(String.format("任务或筛查无需创建仪器条件!!!")); +// } +// if (businessType.equals("10001") && type != -1) { +// throw new RuntimeException(String.format("当前选择的仪器条件模板类别与实验类型不匹配!!!")); +// } +// if (businessType.equals("10002") && type != 1) { +// throw new RuntimeException(String.format("当前选择的仪器条件模板类别与实验类型不匹配!!!")); +// } +// } +// } + + /** + * 获取实验仪器条件的类别 + * + * @param testId + * @return + */ + public Integer getConditionFileType(String testId) { + TestRecordVo vo = testRecordMapper.getTestRecordMapById(testId); + List deviceUseCondition = vo.getDeviceUseCondition(); + if (deviceUseCondition != null && deviceUseCondition.size() > 0) { + return Integer.parseInt(deviceUseCondition.get(0)); + + } + return null; + } + /** + * 为模板创建仪器条件word + * + * @param templateId + * @param testId + * @throws Exception + */ + @Override + public void copyConditionWord(String templateId, String testId) throws Exception { + // TODO:要先判断是否已经存在仪器条件模板 + List fileNameList = ossFile.fileList(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId); + boolean ret = fileNameList.contains(fileName); + if (ret) { + String filePath = TestRecordFileUrl.TEST_TEMPLATE_CATALOGUE.getFileUrl() + "/" + templateId + "/" + fileName; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ossFile.fileGet(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + fileName, bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + ossFile.fileSave(filePath, bis); + bos.close(); + bis.close(); + } + } + + /** + * 将仪器条件内容合并至检验记录中 + * + * @param testId + * @throws Exception + */ + @Override + public boolean mergeFile(String testId) throws Exception { + String businessType = testRecordMapper.getTestRecordMapById(testId).getBusinessType(); + if (StringUtils.isNotBlank(businessType) && businessType.equals("10002")) { + return this.mergeBiologicalSampleFile(testId); + } else if (StringUtils.isNotBlank(businessType) && businessType.equals("10001")) { + return this.mergeSeizureFile(testId); + } + return false; + } + + /** + * 合并生物样本仪器条件与检验记录 + * + * @param testId + * @throws Exception + */ + public boolean mergeBiologicalSampleFile(String testId) throws Exception { + String filePath = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + fileName;//生物样本仪器条件 + ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); + ossFile.fileGet(filePath, bos1); + byte[] templateArray1 = bos1.toByteArray(); + ByteArrayInputStream bis1 = new ByteArrayInputStream(templateArray1); + NiceXWPFDocument sourceDoc = new NiceXWPFDocument(bis1); + bos1.write(bis1); + + //获取仪器条件表格 + XWPFTable table = sourceDoc.getTables().get(0); + + String templatePath = TestRecordFileUrl.TEST_RECORD_BIOLOGICAL_SAMPLE_TEMPLATE.getFileUrl();//生物样本检验记录模板 + ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); + ossFile.fileGet(templatePath, bos2); + byte[] templateArray2 = bos2.toByteArray(); + ByteArrayInputStream bis2 = new ByteArrayInputStream(templateArray2); + NiceXWPFDocument targetDoc = new NiceXWPFDocument(bis2); + + int insertPosition = 1;//替换到第2个段落的表格 + + //替换表格 + targetDoc.setTable(insertPosition, table); + +// //删除空白行 +// for (int i = targetDoc.getParagraphs().size() - 1; i >= 0; i--) { +// XWPFParagraph paragraph = targetDoc.getParagraphs().get(i); +// if (paragraph.getRuns().isEmpty() || paragraph.getText().trim().isEmpty()) { +// targetDoc.removeBodyElement(targetDoc.getPosOfParagraph(paragraph)); +// } +// } + String temporaryfileName = "生物样本检验记录.docx"; + String temporaryPath = TestRecordFileUrl.TEMPORARY_PATH.getFileUrl() + "/" + temporaryfileName;//临时存储 + FileOutputStream fileOutputStream = new FileOutputStream(temporaryPath); + targetDoc.write(fileOutputStream); + fileOutputStream.close(); + File file = new File(temporaryPath); + FileItem fileItem = this.getMultipartFile(file, file.getName()); + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + String ossPath = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId; + boolean ret = ossFile.fileUpload(multipartFile, ossPath); + if (ret) { + Files.delete(Paths.get(temporaryPath)); + } + return ret; + } + + /** + * 合并缴获物仪器条件与检验记录 + * + * @param testId + * @throws Exception + */ + public boolean mergeSeizureFile(String testId) throws Exception { + + String filePath = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + fileName;// + ByteArrayOutputStream bos1 = new ByteArrayOutputStream(); + ossFile.fileGet(filePath, bos1); + byte[] templateArray1 = bos1.toByteArray(); + ByteArrayInputStream bis1 = new ByteArrayInputStream(templateArray1); + NiceXWPFDocument sourceDoc = new NiceXWPFDocument(bis1); + bos1.write(bis1); + + //获取仪器条件表格 + XWPFTable table = sourceDoc.getTables().get(0); + + //todo:缴获物检验记录模板 + String templatePath = TestRecordFileUrl.TEST_RECORD_SEIZURE_TEMPLATE.getFileUrl(); + ByteArrayOutputStream bos2 = new ByteArrayOutputStream(); + ossFile.fileGet(templatePath, bos2); + byte[] templateArray2 = bos2.toByteArray(); + ByteArrayInputStream bis2 = new ByteArrayInputStream(templateArray2); + NiceXWPFDocument targetDoc = new NiceXWPFDocument(bis2); + + bis2.close(); + bos2.close(); + bis1.close(); + bos1.close(); + + int insertPosition = 5;//替换第五个表格之后的表格 + + //替换表格 + targetDoc.setTable(insertPosition, table); + + String temporaryfileName = "缴获物检验记录.docx"; + String temporaryPath = TestRecordFileUrl.TEMPORARY_PATH.getFileUrl() + temporaryfileName;//临时存储 + FileOutputStream fileOutputStream = new FileOutputStream(temporaryPath); + targetDoc.write(fileOutputStream); + fileOutputStream.close(); + File file = new File(temporaryPath); + FileItem fileItem = this.getMultipartFile(file, file.getName()); + FileInputStream fileInputStream = new FileInputStream(TestRecordFileUrl.TEMPORARY_PATH.getFileUrl() + temporaryfileName); + MultipartFile multipartFile = new CommonsMultipartFile(fileItem); + String ossPath = TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + temporaryfileName; + boolean ret = ossFile.fileSave(ossPath, fileInputStream); + if (ret) { + Files.delete(Paths.get(temporaryPath)); + } + return ret; + } + + //todo:一个文件类型转换的封装方法 + @Override + public FileItem getMultipartFile(File file, String fieldName) { + FileItemFactory factory = new DiskFileItemFactory(16, null); + FileItem item = factory.createItem(fieldName, "text/plain", true, file.getName()); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + try { + FileInputStream fis = new FileInputStream(file); + OutputStream os = item.getOutputStream(); + while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + return item; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentServiceImpl.java new file mode 100644 index 0000000..be49d33 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordInstrumentServiceImpl.java @@ -0,0 +1,220 @@ +package digital.laboratory.platform.inspection.service.impl; +/* + *@title TestRecordInstrumentServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 14:51 + */ + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordInstrument; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordInstrumentMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.TestRecordInstrumentService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.service.TestTemplateService; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +@Slf4j +public class TestRecordInstrumentServiceImpl extends ServiceImpl implements TestRecordInstrumentService { + + @Resource + private TestRecordService testRecordService; + + @Resource + private TestRecordMapper testRecordMapper; + + @Resource + private TestTemplateMapper testTemplateMapper; + + @Resource + private TestTemplateService testTemplateService; + + @Override + public TestRecordInstrument addTestRecordInstrument(TestRecordInstrument testRecordInstrument) { + if (StringUtils.isBlank(testRecordInstrument.getId())) { + testRecordInstrument.setId(IdWorker.get32UUID()); + log.info("保存对象testRecordInstrument的ID为空,由系统生成一个给它使用 {}", testRecordInstrument.getId()); + } + boolean ret = this.save(testRecordInstrument); + if (ret) { + log.info("{} 保存成功", testRecordInstrument); + return testRecordInstrument; + } else { + log.info("{} 保存失败", testRecordInstrument); + return null; + } + } + + @Override + public TestRecordInstrument updateTestRecordInstrument(TestRecordInstrument testRecordInstrument) { + if (testRecordInstrument.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + return null; + } + boolean ret = this.updateById(testRecordInstrument); + if (ret) { + return testRecordInstrument; + } else { + return null; + } + } + + /** + * 通过ID删除仪器设备 + * @param id + * @return + */ + @Override + public Boolean deleteTestRecordInstrument(String id) { + List testRecordMapList = testRecordMapper.getTestRecordMapList(new LambdaQueryWrapper()); + testRecordMapList.forEach(item -> { + if (item.getDeviceIdList() != null && item.getDeviceIdList().size() > 0 && item.getDeviceIdList().contains(id)) { + throw new RuntimeException(String.format("该设备已绑定编号为%s的实验,无法删除!", item.getTestSerialNumber())); + } + }); + List testTemplateMapList = testTemplateMapper.getTestTemplateMapList(new LambdaQueryWrapper()); + testTemplateMapList.forEach(item -> { + if (item.getDeviceIdList() != null && item.getDeviceIdList().size() > 0 && item.getDeviceIdList().contains(id)) { + throw new RuntimeException(String.format("该设备已绑定ID为%s的实验,无法删除!", item.getId())); + } + }); + return this.removeById(id); + } + + /** + * 分页查询 + * + * @param opCode 通过Opcode区分仪器条件列表 1:查询所有的仪器设备(这个实验绑定的除外) 2:查询这个实验下绑定的仪器设备 + * @param keywords 模糊查询参数 + */ + @Override + public IPage getTestRecordInstrumentPageList(Page page, String testId, String keywords, Integer opCode) { + TestRecordVo testRecordVo = testRecordMapper.getTestRecordMapById(testId); + List deviceIdList = testRecordVo.getDeviceIdList(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.and(StringUtils.isNotBlank(keywords), qw -> qw + .like(TestRecordInstrument::getInstrumentNumber, keywords) + .or() + .like(TestRecordInstrument::getInstrumentProvider, keywords) + .or() + .like(TestRecordInstrument::getInstrumentName, keywords) + .or() + .like(TestRecordInstrument::getInstrumentTypeNo, keywords)); + if (opCode == 1) { + if (deviceIdList != null && deviceIdList.size() > 0) { + wrapper.notIn(TestRecordInstrument::getId, deviceIdList); + } + wrapper.orderByDesc(TestRecordInstrument::getCreateTime); + } else {//这是为了查询时不报错,加入了空字符串 + if (deviceIdList == null || deviceIdList.size() == 0) { + deviceIdList = new ArrayList(); + deviceIdList.add(""); + } + wrapper.in(TestRecordInstrument::getId, deviceIdList) + .orderByDesc(TestRecordInstrument::getUpdateTime); + } + return this.page(page, wrapper); + } + + /** + * 列表查询 + * + * @param opCode 通过Opcode区分仪器条件列表 1:查询所有的仪器设备(这个实验绑定的除外) 2:查询这个实验下绑定的仪器设备 + * @param keywords 模糊查询参数 + */ + @Override + public IPage getTemplateInstrumentPageList(Page page, String templateId, String keywords, Integer opCode) { + TestTemplateVo testTemplateVo = testTemplateMapper.getTestTemplateMapById(templateId); + List deviceIdList = testTemplateVo.getDeviceIdList(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.and(StringUtils.isNotBlank(keywords), qw -> qw + .like(TestRecordInstrument::getInstrumentNumber, keywords) + .or() + .like(TestRecordInstrument::getInstrumentProvider, keywords) + .or() + .like(TestRecordInstrument::getInstrumentName, keywords) + .or() + .like(TestRecordInstrument::getInstrumentTypeNo, keywords)); + if (opCode == 1) { + if (deviceIdList != null && deviceIdList.size() > 0) { + wrapper.notIn(TestRecordInstrument::getId, deviceIdList); + } + wrapper.orderByDesc(TestRecordInstrument::getCreateTime); + } else {//这是为了查询时不报错,加入了空字符串 + if (deviceIdList == null || deviceIdList.size() == 0) { + deviceIdList = new ArrayList(); + deviceIdList.add(""); + } + wrapper.in(TestRecordInstrument::getId, deviceIdList) + .orderByDesc(TestRecordInstrument::getUpdateTime); + } + return this.page(page, wrapper); + } + + @Override + public List getTestRecordInstrumentList(TestRecordInstrument testRecordInstrument) { + List retList = this.list(Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(testRecordInstrument.getInstrumentName()), TestRecordInstrument::getInstrumentName, testRecordInstrument.getInstrumentName())); + return retList; + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(TestRecordInstrument::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + /** + * 添加或移除实验中的仪器设备 + * @param testRecordArgumentDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean useTestRecordInstrument(TestRecordArgumentDto testRecordArgumentDto) { + TestRecordInstrument testRecordInstrument = this.getById(testRecordArgumentDto.getArgumentId()); + testRecordInstrument.setUpdateTime(LocalDateTime.now());//这里修改是为了查询实验中已添加的列表可以按照添加顺序进行排序 + return this.updateById(testRecordInstrument) && testRecordService.updateTestRecordArgument(testRecordArgumentDto.getTestRecordId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType(), testRecordArgumentDto.getOpCode()); + } + + /** + * 添加或移除模板中的仪器设备 + * @param testRecordArgumentDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean useTemplateInstrument(TestRecordArgumentDto testRecordArgumentDto) { + TestRecordInstrument testRecordInstrument = this.getById(testRecordArgumentDto.getArgumentId()); + testRecordInstrument.setUpdateTime(LocalDateTime.now());//这里修改是为了查询实验中已添加的列表可以按照添加顺序进行排序 + boolean ret = testTemplateService.updateTestTemplate(testRecordArgumentDto.getTemplateId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType(), testRecordArgumentDto.getOpCode()); + return this.updateById(testRecordInstrument) && ret; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordMethodServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordMethodServiceImpl.java new file mode 100644 index 0000000..2a36ad5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordMethodServiceImpl.java @@ -0,0 +1,149 @@ +package digital.laboratory.platform.inspection.service.impl; +/* + *@title TestRecordMethodServiceImpl + *@description + *@author xy + *@version 1.0 + *@create 2023/12/19 14:51 + */ + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordMethodMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.TestRecordMethodService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.service.TestTemplateService; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; + +@Service +@Slf4j +public class TestRecordMethodServiceImpl extends ServiceImpl implements TestRecordMethodService { + + @Resource + private TestRecordService testRecordService; + + @Resource + private TestRecordMapper testRecordMapper; + + @Resource + private TestTemplateMapper testTemplateMapper; + + @Resource + private TestTemplateService testTemplateService; + + @Override + public TestRecordMethod addTestRecordMethod(TestRecordMethod testRecordMethod) { + if (StringUtils.isBlank(testRecordMethod.getId())) { + testRecordMethod.setId(IdWorker.get32UUID()); + log.info("保存对象testRecordMethod的ID为空,由系统生成一个给它使用 {}", testRecordMethod.getId()); + } + boolean ret = this.save(testRecordMethod); + if (ret) { + log.info("{} 保存成功", testRecordMethod); + return testRecordMethod; + } else { + log.info("{} 保存失败", testRecordMethod); + return null; + } + } + + @Override + public TestRecordMethod updateTestRecordMethod(TestRecordMethod testRecordMethod) { + if (testRecordMethod.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + return null; + } + boolean ret = this.updateById(testRecordMethod); + if (ret) { + return testRecordMethod; + } else { + return null; + } + } + + /** + * 删除方法 + * @param id + * @return + */ + + @Override + public Boolean deleteTestRecordMethod(String id) { + List testRecordList = testRecordMapper.getTestRecordMapList(new LambdaQueryWrapper<>()); + testRecordList.forEach(item -> { + if (item.getTestMethodList() != null && item.getTestMethodList().size() > 0 && item.getTestMethodList().contains(id)) { + throw new RuntimeException(String.format("当前方法已绑定编号为%s的实验,无法删除!", item.getTestSerialNumber())); + } + }); + List testTemplateMapList = testTemplateMapper.getTestTemplateMapList(new LambdaQueryWrapper()); + testTemplateMapList.forEach(item -> { + if (item.getTestMethods() != null && item.getTestMethods().size() > 0 && item.getTestMethods().contains(id)) { + throw new RuntimeException(String.format("当前方法已绑定ID为%s的模板,无法删除!", item.getId())); + } + }); + this.list(Wrappers.lambdaQuery()); + return this.removeById(id); + } + + @Override + public IPage getTestRecordMethodPageList(Page page, TestRecordMethod testRecordMethod) { + IPage ret = this.pageMaps(page, Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(testRecordMethod.getMethodName()), TestRecordMethod::getMethodName, testRecordMethod.getMethodName())); + return ret; + } + + @Override + public List getTestRecordMethodList(TestRecordMethod testRecordMethod) { + List retList = this.list(Wrappers.lambdaQuery() + .like(StringUtils.isNotBlank(testRecordMethod.getMethodName()), TestRecordMethod::getMethodName, testRecordMethod.getMethodName()) + .orderByDesc(TestRecordMethod::getCreateTime)); + return retList; + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(TestRecordMethod::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + /** + * 向实验添加或移除方法 + * @param testRecordArgumentDto + * @return + */ + @Override + public boolean useTestRecordMethod(TestRecordArgumentDto testRecordArgumentDto) { + return testRecordService.updateTestRecordArgument(testRecordArgumentDto.getTestRecordId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_METHOD.getType(), testRecordArgumentDto.getOpCode()); + } + + /** + * 向模板添加或移除方法 + * @param testRecordArgumentDto + * @return + */ + @Override + public boolean useTemplateMethod(TestRecordArgumentDto testRecordArgumentDto) { + return testTemplateService.updateTestTemplate(testRecordArgumentDto.getTemplateId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_METHOD.getType(), testRecordArgumentDto.getOpCode()); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordReagentServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordReagentServiceImpl.java new file mode 100644 index 0000000..df22b8c --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordReagentServiceImpl.java @@ -0,0 +1,264 @@ +package digital.laboratory.platform.inspection.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto; +import digital.laboratory.platform.inspection.entity.TestRecordReagent; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordReagentMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.TestRecordReagentService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.service.TestTemplateService; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title TestRecordReagentServiceImpl + * @description + * @create 2023/12/20 11:15 + */ +@Service +@Slf4j +public class TestRecordReagentServiceImpl extends ServiceImpl implements TestRecordReagentService { + + @Resource + private TestRecordService testRecordService; + @Resource + private TestRecordMapper testRecordMapper; + + @Resource + private TestTemplateService testTemplateService; + @Resource + private TestTemplateMapper testTemplateMapper; + + @Override + public TestRecordReagent addTestRecordReagent(TestRecordReagent testRecordReagent) { + if (StringUtils.isBlank(testRecordReagent.getId())) { + testRecordReagent.setId(IdWorker.get32UUID()); + log.info("保存对象testRecordReagent的ID为空,由系统生成一个给它使用 {}", testRecordReagent.getId()); + } + if (!testRecordReagent.getCategory().equals("试剂")){ + testRecordReagent.setPurityGrade("/"); + } + boolean ret = this.save(testRecordReagent); + if (ret) { + log.info("{} 保存成功", testRecordReagent); + return testRecordReagent; + } else { + log.info("{} 保存失败", testRecordReagent); + return null; + } + } + + @Override + public TestRecordReagent updateTestRecordReagent(TestRecordReagent testRecordReagent) { + if (testRecordReagent.getSource() == 0) { + log.info("数据是其他系统推送录入的,不能修改"); + return null; + } + boolean ret = this.updateById(testRecordReagent); + if (ret) { + return testRecordReagent; + } else { + return null; + } + } + + /** + * 删除试剂耗材 + * @param id + * @return + */ + @Override + public Boolean deleteTestRecordReagent(String id) { + TestRecordReagent recordReagent = this.getById(id); + List recordMapList = testRecordMapper.getTestRecordMapList(new LambdaQueryWrapper()); + List testTemplateMapList = testTemplateMapper.getTestTemplateMapList(new LambdaQueryWrapper()); + recordMapList.forEach(item -> { + if (item.getReagentConsumablesList() != null && item.getReagentConsumablesList().size() > 0 && item.getReagentConsumablesList().contains(recordReagent.getId())) { + throw new RuntimeException(String.format("该试剂耗材/标准物质已绑定编号为%s的实验,无法删除!", item.getTestSerialNumber())); + } + }); + testTemplateMapList.forEach(item -> { + if (item.getReagentConsumables() != null && item.getReagentConsumables().size() > 0 && item.getReagentConsumables().contains(recordReagent.getId())) { + throw new RuntimeException(String.format("该试剂耗材/标准物质已绑定ID为%s的模板,无法删除!", item.getId())); + } + }); + return this.removeById(id); + } + + /** + * 实验分页查询 + * @param page + * @param testId + * @param keywords 标准物质编号、名称查询参数 + * @param category 类别查询参数 + * @param opCode 1:查询所有的试剂耗材 -1:查询这个实验下的试剂耗材 + * @return + */ + @Override + public IPage getTestRecordReagentPageList(Page page, String testId, String keywords, String category, Integer opCode) { + ArrayList categoryList = new ArrayList<>(); + if (category.equals("试剂耗材")) { + categoryList.add("试剂"); + categoryList.add("耗材"); + } else { + categoryList.add("标准物质"); + categoryList.add("标准储备溶液"); + } + TestRecordVo testRecordVo = testRecordMapper.getTestRecordMapById(testId); + List reagentConsumablesList = testRecordVo.getReagentConsumablesList(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.and(StringUtils.isNotBlank(keywords), qw -> qw + .like(TestRecordReagent::getNumber, keywords) + .or() + .like(TestRecordReagent::getReagentConsumableName, keywords)) + .in(TestRecordReagent::getCategory, categoryList); + if (opCode == 1) { + queryWrapper.orderByDesc(TestRecordReagent::getCreateTime); + if (reagentConsumablesList != null && reagentConsumablesList.size() > 0) { + queryWrapper.notIn(TestRecordReagent::getId, reagentConsumablesList); + } + } else { + if (reagentConsumablesList == null || reagentConsumablesList.size() == 0) { + //下面两步是为了能使参数正常查询 + reagentConsumablesList = new ArrayList<>(); + reagentConsumablesList.add(""); + } + queryWrapper.in(TestRecordReagent::getId, reagentConsumablesList) + .orderByDesc(TestRecordReagent::getUpdateTime); + } + //给了实验ID,查询这个实验下的试剂耗材、标准物质 + return this.page(page, queryWrapper); + } + + /** + * 模板分页查询 + * @param page + * @param testId + * @param keywords 标准物质编号、名称查询参数 + * @param category 类别查询参数 + * @param opCode 1:查询所有的试剂耗材 -1:查询这个模板下的试剂耗材 + * @return + */ + @Override + public IPage getTestTemplateReagentPageList(Page page, String templateId, String keywords, String category, Integer opCode) { + ArrayList categoryList = new ArrayList<>(); + if (category.equals("试剂耗材")) { + categoryList.add("试剂"); + categoryList.add("耗材"); + } else { + categoryList.add("标准物质"); + categoryList.add("标准储备溶液"); + } + TestTemplateVo templateVo = testTemplateMapper.getTestTemplateMapById(templateId); + List reagentConsumablesList = templateVo.getReagentConsumables(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.and(StringUtils.isNotBlank(keywords), qw -> qw + .like(TestRecordReagent::getNumber, keywords) + .or() + .like(TestRecordReagent::getReagentConsumableName, keywords)) + .in(TestRecordReagent::getCategory, categoryList); + if (opCode == 1) {//查询所有的试剂耗材、标准物质(去重处理) + queryWrapper.orderByDesc(TestRecordReagent::getCreateTime); + if (reagentConsumablesList != null && reagentConsumablesList.size() > 0) { + queryWrapper.notIn(TestRecordReagent::getId, reagentConsumablesList); + } + } else {//查询这个模板中绑定的试剂耗材 + if (reagentConsumablesList == null || reagentConsumablesList.size() == 0) { + //下面两步是为了能使参数正常查询 + reagentConsumablesList = new ArrayList<>(); + reagentConsumablesList.add(""); + } + queryWrapper.in(TestRecordReagent::getId, reagentConsumablesList) + .orderByDesc(TestRecordReagent::getUpdateTime); + } + return this.page(page, queryWrapper); + } + + /** + * 实验列表查询 + * @param testId + * @param category 类别查询参数 + * @return + */ + @Override + public List getTestRecordReagentList(String testId, String category) { + ArrayList categoryList = new ArrayList<>(); + if (category.equals("试剂耗材")) { + categoryList.add("试剂"); + categoryList.add("耗材"); + } else { + categoryList.add("标准物质"); + categoryList.add("标准储备溶液"); + } + TestRecordVo testRecordVo = testRecordMapper.getTestRecordMapById(testId); + List reagentConsumablesList = testRecordVo.getReagentConsumablesList(); + if (reagentConsumablesList == null || reagentConsumablesList.size() == 0) { + //下面两步是为了能使参数正常查询 + reagentConsumablesList = new ArrayList<>(); + reagentConsumablesList.add(""); + } + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper + .in(TestRecordReagent::getCategory, categoryList).in(TestRecordReagent::getId, reagentConsumablesList) + .orderByDesc(TestRecordReagent::getUpdateTime); + //给了实验ID,查询这个实验下的试剂耗材、标准物质 + return this.list(queryWrapper); + } + + @Override + public Boolean checkExist(String id) { + List retList = this.list(Wrappers.lambdaQuery() + .eq(TestRecordReagent::getId, id)); + if (retList.size() > 0) { + return true; + } else { + return false; + } + } + + /** + * 向实验添加或移除试剂耗材 + * @param testRecordArgumentDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean useTestRecordReagent(TestRecordArgumentDto testRecordArgumentDto) { + TestRecordReagent testRecordReagent = this.getById(testRecordArgumentDto.getArgumentId()); + testRecordReagent.setUpdateTime(LocalDateTime.now()); + return this.updateById(testRecordReagent) && testRecordService.updateTestRecordArgument(testRecordArgumentDto.getTestRecordId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_REAGENT.getType(), testRecordArgumentDto.getOpCode()); + } + + /** + * 向模板添加或移除试剂耗材 + * @param testRecordArgumentDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean useTestTemplateReagent(TestRecordArgumentDto testRecordArgumentDto) { + TestRecordReagent testRecordReagent = this.getById(testRecordArgumentDto.getArgumentId()); + testRecordReagent.setUpdateTime(LocalDateTime.now()); + boolean ret = testTemplateService.updateTestTemplate(testRecordArgumentDto.getTemplateId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_REAGENT.getType(), testRecordArgumentDto.getOpCode()); + return this.updateById(testRecordReagent) && ret; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java new file mode 100644 index 0000000..7dd80ce --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleDataServiceImpl.java @@ -0,0 +1,1915 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.common.collect.Lists; +import digital.laboratory.platform.common.core.constant.CommonConstants; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.comservice.entity.DlpDictData; +import digital.laboratory.platform.comservice.feign.RemoteDictDataService; +import digital.laboratory.platform.inspection.constant.*; +import digital.laboratory.platform.inspection.dto.*; +import digital.laboratory.platform.inspection.entity.*; +import digital.laboratory.platform.inspection.event.AuditDataExecutionEvent; +import digital.laboratory.platform.inspection.event.FinishTestExecutionEvent; +import digital.laboratory.platform.inspection.mapper.SampleInjectorMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct; +import digital.laboratory.platform.inspection.vo.ESTBusinessInfoVO; +import digital.laboratory.platform.inspection.vo.ResultConcentrationVO; +import digital.laboratory.platform.inspection.vo.TestResultBusinessVO; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * @author xy + * @version 1.0 + * @title TestRecordSampleDataServiceImpl + * @description 检验数据实现类 + * @create 2024/1/30 11:07 + */ +@Service +@Slf4j +public class TestRecordSampleDataServiceImpl extends ServiceImpl implements TestRecordSampleDataService { + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService; + + @Resource + private TestRecordStandardSolutionService testRecordStandardSolutionService; + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private SampleInjectorMapper sampleInjectorMapper; + + @Resource + private TestRecordSampleDataMapper testRecordSampleDataMapper; + + @Resource + private TestRecordService testRecordService; + + @Resource + private EntrustInfoService entrustInfoService; + + @Resource + private TaskInfoService taskInfoService; + + @Resource + private ApplicationContext applicationContext; + + /** + * 校验实验状态是否完成,完成则提升不能修改数据 + * + * @param testId 实验id + */ + @Override + public void validateTestStatus(String testId) { + // 校验实验状态是否完成 + if (testRecordService + .count(Wrappers.lambdaQuery() + .eq(TestRecord::getId, testId) + .ge(TestRecord::getStatus, 5)) + > 0) { + // 大于0 说明该实验已经完成 + throw new RuntimeException("该实验已经完成,禁止修改原始数据!"); + } + } + + + @Override + public Boolean saveTestData(List testRecordSampleDataList) { + return super.saveBatch(testRecordSampleDataList); + } + + //获取检验记录中的样品信息数据 + @Override + public List getNPSSampleTestDataByTestId(String testId) { + List list = this.list(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + List retList = new ArrayList<>(); + for (TestRecordSampleData testRecordSampleData : list) { +// NPSCaseTestDataDto npsCaseTestDataDto = testRecordSampleDataToPSCaseTestDataDto(testRecordSampleData); + NPSCaseTestDataDto npsCaseTestDataDto = testRecordSampleDataToPSCaseTestDataDto(testRecordSampleData, NPSCaseTestDataDto.class); + retList.add(npsCaseTestDataDto); + } + return retList; + } + + /** + * TestRecordSampleDataMapper + * 根据业务id获取检验数据 + * + * @param businessId 业务id + * @return + */ + @Override + public List getSampleTestDataByBusiness(String businessId) { + // 先根据业务id查询委托、筛查、任务表中有没有这个id + List estBusinessInfoVOS = testRecordSampleDataMapper.queryESTBusinessInfoList(Wrappers.query().eq("T.id", businessId)); + if (CollUtil.isEmpty(estBusinessInfoVOS)) { + return null; + } + // 根据业务id查询样品信息 + List sampleInfoIds = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId)) + .stream().map(SampleInfo::getId).collect(Collectors.toList()); + TestRecord testRecord = null; + for (String sampleInfoId : sampleInfoIds) { + TestRecord testRecord1 = testRecordService.getOne(Wrappers.lambdaQuery().like(TestRecord::getSampleTestList, sampleInfoId)); + if (testRecord1 != null) { + testRecord = testRecord1; + break; + } + } + if (testRecord == null) { + throw new RuntimeException(String.format("没有查询到委托对应的试实验信息!")); + } + // 根据检材id 查询溶液编号 + Set testRecordSampleSolutionsNoList = testRecordSampleSolutionService.list(Wrappers.lambdaQuery() + .in(TestRecordSampleSolution::getMaterialId, sampleInfoIds)) + .stream() + .map(TestRecordSampleSolution::getSampleNo) + .collect(Collectors.toSet()); + + List testRecordSampleDataList = this.list(Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getTestId, testRecord.getId()) + .last("ORDER BY SUBSTRING_INDEX(name, '-', -1) + 0")).stream().filter(item -> { +// int size = testRecordSampleSolutionsNoList.size(); + // 这里判断了如果不是检材也返回true,是检材的话判断是不是这个业务id下的检材,根据编号判断 + if (!item.getSampleType().equals(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE) || + (item.getSampleType().equals(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE) + && testRecordSampleSolutionsNoList.contains(item.getSampleNo()) + )) { + return true; + } else { + return false; + } + }).collect(Collectors.toList()); + ESTBusinessInfoVO estBusinessInfoVO = estBusinessInfoVOS.get(0); + // 封装的结果集 + List retList = new ArrayList<>(); + if (estBusinessInfoVO.getBusinessType().equals(BusinessType.BOINT_CASE.getBusinessType())) { + extractedSampleTestData(testRecordSampleDataList, retList, HairSewageDataDto.class); + } else if (estBusinessInfoVO.getBusinessType().equals(BusinessType.NPS_CASE.getBusinessType()) || estBusinessInfoVO.getBusinessType().equals(BusinessType.SCREENING_EVENT.getBusinessType())) { + extractedSampleTestData(testRecordSampleDataList, retList, NPSCaseTestDataDto.class); + } else { + extractedSampleTestData(testRecordSampleDataList, retList, HairSewageDataDto.class); + } +// List collect = TypeCasting(retList); + return typeCasting(retList); + } + + /** + * 毛发案件检验数据读取处理保存到数据库 + * + * @param hairCompoundDataMap + * @param testId + * @return + */ + @Override + public Boolean saveTestDataHairCase(Map> hairCompoundDataMap, String testId) { + try { + buildSampleDataFromHairCase(hairCompoundDataMap, testId);//构造实验数据 + testRecordService.update(Wrappers.lambdaUpdate().eq(TestRecord::getId, testId).set(TestRecord::getStatus, 2)); + return true; + } catch (Exception err) { + log.info("程序执行异常{}", err.getMessage()); + err.printStackTrace(); + return false; + } + } + + /** + * 根据实验id获取不同类型的数据 + * + * @param testId + * @param type + * @return + */ + @Override + public List getSampleTestDataByTestId(String testId, String type) { + List list = this.list(Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getTestId, testId) + .last("ORDER BY SUBSTRING_INDEX(name, '-', -1) + 0")); + List retList = new ArrayList<>(); + switch (BusinessType.getBusinessTypeByType(type)) { + case SCREENING_EVENT: + case NPS_CASE: + // NPS的数据分析 + extractedSampleTestData(list, retList, NPSCaseTestDataDto.class); + break; + case BOINT_CASE: + extractedSampleTestData(list, retList, HairSewageDataDto.class); + break; + } + + // z最后转换类型 +// TypeCasting(retList); + return typeCasting(retList); + } + + /** + * 分页查询 根据实验id获取不同类型的数据 + * + * @param pageDTO + * @return + */ + @Override + public Page getSampleTestDataByTestIdPage(AnalysisTestResultPageDTO pageDTO) { + Page page = this.page(new Page<>(pageDTO.getCurrent(), pageDTO.getSize()), Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getTestId, pageDTO.getTestId()) + .orderByDesc(TestRecordSampleData::getCompoundName) + .orderByDesc(TestRecordSampleData::getSampleNo)); + List retList = new ArrayList<>(); + switch (BusinessType.getBusinessTypeByType(pageDTO.getType())) { + case NPS_CASE: + // NPS的数据分析 + extractedSampleTestData(page.getRecords(), retList, NPSCaseTestDataDto.class); + case BOINT_CASE: + extractedSampleTestData(page.getRecords(), retList, HairSewageDataDto.class); + } + Page resultPage = new Page<>(); + BeanUtils.copyProperties(page, resultPage, "records"); + // z最后转换类型 +// TypeCasting(retList); + resultPage.setRecords(retList); + return resultPage; + } + + /** + * 分页查询 获取审核的任务检验数据 + * + * @param pageDTO + * @return + */ + @Override + public Map queryWaitApproveTaskTestDataPage(TaskTestDataPageDTO pageDTO) { + QueryWrapper queryWrapper = generateTaskTestDataQW(pageDTO); + // 获取所有的任务数据 + List taskTestDataDTOList = baseMapper.queryWaitApproveTaskTestDataList(queryWrapper); + + // 根据检材编号进行分组, 使用LinkedHashMap的原因是保证顺序不乱 + LinkedHashMap> dataGroupBySampleNoMap = taskTestDataDTOList + .stream() + .collect(Collectors.groupingBy(TaskTestDataDTO::getSampleNo, LinkedHashMap::new, Collectors.toList())); + + Map map = new HashMap<>(); + + JSONArray headerArray = generateHeaderArray(dataGroupBySampleNoMap); + JSONArray dataArray = generateDataArray(dataGroupBySampleNoMap); + /*// 标记表头是否添加完成 + AtomicReference finish = new AtomicReference<>(false); // 为了能在lambda中使用 + dataGroupBySampleNoMap.forEach((k, v) -> { + // 组装列表数据 + JSONObject dataObject = new JSONObject(); + dataObject.put("sampleNo", k); + int size = v.size(); // 防止频繁调用方法 + for (int i = 0; i < size; i++) { + TaskTestDataDTO taskTestDataDTO = v.get(i); + String compoundKey = "compound" + (i + 1); + if (!finish.get()) { + // 组装自定义列表头部 + JSONObject object = new JSONObject(); + if (i == 0) { + JSONObject sampleNoObject = new JSONObject(); + sampleNoObject.put(TestRecordSampleDataConstant.LABEL, "溶液编号"); + sampleNoObject.put(TestRecordSampleDataConstant.PROP, "sampleNo"); + sampleNoObject.put("fixed", true); + JSONObject name = new JSONObject(); + name.put(TestRecordSampleDataConstant.PROP, "taskName"); + name.put(TestRecordSampleDataConstant.LABEL, "案件/任务名称"); + JSONObject business = new JSONObject(); + business.put(TestRecordSampleDataConstant.PROP, "businessTypeName"); + business.put(TestRecordSampleDataConstant.LABEL, "业务类型"); + JSONObject status = new JSONObject(); + status.put(TestRecordSampleDataConstant.PROP, "statusName"); + status.put(TestRecordSampleDataConstant.LABEL, "状态"); + + headerArray.add(name); + headerArray.add(business); + headerArray.add(status); + headerArray.add(sampleNoObject); + } + object.put(TestRecordSampleDataConstant.PROP, compoundKey); + object.put(TestRecordSampleDataConstant.LABEL, "化合物" + (i + 1) + "(" + taskTestDataDTO.getCompoundName() + ")"); + headerArray.add(object); + } + // 把化合物组装导对象里 + dataObject.put("taskName", taskTestDataDTO.getTaskName()); + dataObject.put("businessTypeName", BusinessType.getBusinessTypeName(taskTestDataDTO.getBusinessType())); + dataObject.put("status", taskTestDataDTO.getStatus()); + dataObject.put("statusName", TaskTestDataStatus.getStatusNameByCode(taskTestDataDTO.getStatus())); + dataObject.put(compoundKey, taskTestDataDTO.getSampleConcentration()); + if (i == size - 1) { + finish.set(true); + } + } + dataArray.add(dataObject); + }); +*/ + // 手动分页 + map.put("header", headerArray); + map.put("page", getPageData(dataArray, pageDTO.getCurrent(), pageDTO.getSize())); + return map; + } + + + /** + * 毛发、污水任务检验数据导入并保存到数据库 + * + * @param hairSewageCompoundDataMap + * @param testId + * @param fileTypeCode + * @return + */ + @Override + public Boolean saveTestDataHairSewageTask(Map> hairSewageCompoundDataMap, String testId, String fileTypeCode) { + List testRecordSampleDataList_All = new Vector<>(); + + hairSewageCompoundDataMap.forEach((k, v) -> { + v.parallelStream().forEach(hairsSewageCompoundData -> { + String idName = hairsSewageCompoundData.getIdName(); + HairSewageDataDto hairSewageDataDto = new HairSewageDataDto(); + hairSewageDataDto.setSampleNo(idName); // 样本编号 + hairSewageDataDto.setSampleName(hairsSewageCompoundData.getSampleName()); // 样本名称 + hairSewageDataDto.setTestId(testId); // 实验id + hairSewageDataDto.setBusinessType(fileTypeCode); + // 设置对应的元素数据 + hairSewageDataDto.setTestSampleDataList(Lists.newArrayList(hairsSewageCompoundData)); + hairSewageDataDto.setCompoundName(k); // 化合物名称 + completeHairDataInfo(hairsSewageCompoundData, hairSewageDataDto); + hairSewageDataDto.setTargetConcentration(hairsSewageCompoundData.getConcentration()); + if (hairsSewageCompoundData.getRatioFlag().equals("NO")) { + hairSewageDataDto.setIsDetected(1); + } else { + hairSewageDataDto.setIsDetected(0); + } + if (idName.startsWith(StdSolutionNum.QC_SOLUTION.getPrefix())) { + hairSewageDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_QC); + } else if (idName.startsWith(StdSolutionNum.MIXED_SOLUTION.getPrefix()) || idName.startsWith(StdSolutionNum.SIMPLE_SOLUTION.getPrefix())) { + hairSewageDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_STD); + } else { + hairSewageDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE); + } + testRecordSampleDataList_All.add(hairSewageDataDto);//所有的样本的数据 + }); + }); + + List testRecordSampleDataAnalyteList = genPersistenceSampleData(testRecordSampleDataList_All); + // 批量保存到数据库 + if (super.saveBatch(testRecordSampleDataAnalyteList)) { + return testRecordService.update(Wrappers.lambdaUpdate().eq(TestRecord::getId, testId).set(TestRecord::getStatus, 2)); + } + return false; + } + + /** + * 实验结果查询中分页查询 + * + * @param testResultBusinessVOPage + * @param dto + * @return + */ + @Override + public IPage queryTestResultPage(Page testResultBusinessVOPage, QueryTestResultPageDTO dto, Object... arg) { + DLPUser dlpUsers = (DLPUser) arg[0]; + IPage testResultBusinessVOIPage = new Page<>(); + /** 1 查询当前用户做了哪些实验 + * 2 取出实验中关联的检材id + * 3 根据检材id 取查询检材 + * 4 根据检材提取出对应的业务id + * 5 最后通过业务id 进行分页查询 + */ + List testRecordList = testRecordService.list(Wrappers.lambdaQuery() + .eq(TestRecord::getTestUserId, dlpUsers.getId()) + .eq(TestRecord::getStatus, 5)); + List sampleTestListAll = new ArrayList<>(); + testRecordList.forEach(o -> sampleTestListAll.addAll(o.getSampleTestList())); // 合并所有的检材id + + Set businessIdList = new HashSet<>(); + if (CollUtil.isNotEmpty(sampleTestListAll)) { + businessIdList = sampleInfoService.list(Wrappers.lambdaQuery().in(SampleInfo::getId, sampleTestListAll)).stream().map(SampleInfo::getBusinessId).collect(Collectors.toSet()); + } else { + return testResultBusinessVOIPage; + } + // 查询所有污水报告配置信息不为空的的任务信息 + Map taskInfoMap = taskInfoService.list(Wrappers.lambdaQuery().isNotNull(TaskInfo::getReportConfig).ne(TaskInfo::getReportConfig, "")).stream().collect(Collectors.toMap(TaskInfo::getId, Function.identity())); + QueryWrapper queryWrapper = generateQueryWrapperByDTO(dto, businessIdList); + testResultBusinessVOIPage = baseMapper.queryTestResultTaskPage(testResultBusinessVOPage, queryWrapper); + testResultBusinessVOIPage.getRecords().parallelStream().forEach(item -> { + item.setBusinessTypeName(BusinessType.getBusinessTypeName(item.getBusinessType())); + if (taskInfoMap.containsKey(item.getId())) { + item.setReportConfig(taskInfoMap.get(item.getId()).getReportConfig()); + } + if (StrUtil.isNotBlank(item.getCompounds())) { + item.setCompoundsJsonArray(JSONArray.parseArray(item.getCompounds())); + } + }); + return testResultBusinessVOIPage; + } + + /** + * 修改导入的实验数据 + * + * @param dto + * @return + */ + @Override + public JSONObject updateEntrustTestData(UpdateEntrustTestDataDTO dto) { + JSONObject dtoParam = dto.getParam(); + TestRecordSampleData oldInfo = this.getById(dtoParam.getString("testSampleDataId")); // 取实验数据id + // 取出老数据,进行更改 + JSONObject oldObject = new JSONObject(); + if (oldInfo != null) { + oldObject = JSONObject.parseObject(oldInfo.getDataResultJson()); + dtoParam.put("testSampleDataList", oldObject.get("testSampleDataList")); + } else { + dtoParam.put("testSampleDataList", new JSONArray()); + } + dtoParam.put("businessType", dto.getType()); + // 根据类型去判断当前是nps还是毛发 + boolean saved = false; // 标记保存是否成功 + if (dto.getType().equals(BusinessType.NPS_CASE.getBusinessType()) + || dto.getType().equals(BusinessType.SCREENING_EVENT.getBusinessType())) { + // 设置nps中的testSampleDataList 为空, 因为这里的数据不能修改 + /*dtoParam.put("testSampleDataList", null);*/ + NPSCaseTestDataDto param = JSONObject.toJavaObject(dtoParam, NPSCaseTestDataDto.class); + + saved = saveOrUpdateTestData( + oldInfo, + param.getCompoundName(), + JSONUtil.toJsonStr(param), + param.getSampleNo(), + param.getTestId(), + param.getSampleName(), + param.getCompoundCnName()); + + } else if (dto.getType().equals(BusinessType.BOINT_CASE.getBusinessType())) { + HairSewageDataDto param = JSONObject.toJavaObject(dtoParam, HairSewageDataDto.class); + saved = saveOrUpdateTestData( + oldInfo, + param.getCompoundName(), + JSONUtil.toJsonStr(param), + param.getSampleNo(), + param.getTestId(), + param.getSampleName(), + param.getCompoundCnName()); + } + // 根据成功标识返回 + if (saved) { + // 保存成功, 返回成功的json对象 + return dtoParam; + } else { + // 保存失败, 返回之前的json对象 + return oldObject; + } + } + + /** + * 获取任务实验结果数据 + * + * @param testId + * @return + */ + @Override + public Map queryTaskTestResult(String testId) { + // 查询初2这个实验id下的实验数据,然后根据检材编号进行分组 + Map> dataGroupBySampleNoMap = this + .list(Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getTestId, testId) + // 对名称进行排序,因为字符串的排序中 22 < 3,所以需要转换进行怕排序 + .last("ORDER BY SUBSTRING_INDEX(name, '-', -1) + 0")) + .stream() + .collect(Collectors.groupingBy(TestRecordSampleData::getSampleNo, LinkedHashMap::new, Collectors.toList())); + if (CollUtil.isEmpty(dataGroupBySampleNoMap)) { + return null; + } + Map map = new HashMap<>(); + + JSONArray headerArray = new JSONArray(); + JSONArray dataArray = new JSONArray(); + // 标记表头是否添加完成 + AtomicReference finish = new AtomicReference<>(false); // 为了能在lambda中使用 + dataGroupBySampleNoMap.forEach((k, v) -> { + // 组装列表数据 + JSONObject dataObject = new JSONObject(); + dataObject.put("sampleNo", k); + int size = v.size(); // 防止频繁调用方法 + for (int i = 0; i < size; i++) { + TestRecordSampleData testRecordSampleData = v.get(i); + String compoundKey = "compound" + (i + 1); + if (!finish.get()) { + if (i == 0) { + headerArray.add(createHeaderObject("sampleNo", "溶液编号", false)); + } + headerArray.add(createHeaderObject(compoundKey, "化合物" + "(" + testRecordSampleData.getCompoundName() + ")", false)); + } + // 把化合物组装导对象里 + dataObject.put(compoundKey, testRecordSampleData.getSampleConcentration()); + if (i == size - 1) { + finish.set(true); + } + } + dataArray.add(dataObject); + }); + map.put("header", headerArray); + map.put("data", dataArray); + return map; + } + + /** + * 根据业务id获取任务实验结果数据 + * + * @param businessId + * @return + */ + @Override + public Map queryTaskTestResultByBusiness(String businessId) { + // 获取业务信息 + List testResultBusinessVOS = baseMapper.queryTestResultTaskList(Wrappers.query().eq("T.id", businessId)); + if (CollUtil.isEmpty(testResultBusinessVOS)) { + throw new RuntimeException(String.format("业务id 为 %s 的数据在系统查询不到!", businessId)); + } + TestResultBusinessVO testResultBusinessVO = testResultBusinessVOS.get(0); + JSONArray compoundsJsonArray = JSONArray.parseArray(testResultBusinessVO.getCompounds()); // 获取头数组 + + /** + * 1 根据业务id查询到所有的检材 + * 2 通过查询到的检材id 关联查询到溶液 + * 3 通过溶液编号查询实验数据 + */ + List testDataListByBusiness = baseMapper + .getTestDataListByBusiness(Wrappers.query().eq("si.business_id", businessId) + .orderByDesc("si.accept_no")) + .stream() + .filter(item -> StrUtil.isNotBlank(item.getSampleDataId()) && StrUtil.isNotBlank(item.getCompoundName())) // 筛选 检验数据不为空的检材数据 + .collect(Collectors.toList()); + // 根据化合物进行分组 + Map> dataGroupByCompoundMap = testDataListByBusiness.stream() + .collect(Collectors.groupingBy(DataSolutionSampleDTO::getSampleNo, LinkedHashMap::new, Collectors.toList())); + + Map map = new HashMap<>(); + + JSONArray headerArray = new JSONArray(); + JSONArray dataArray = new JSONArray(); + // 标记表头是否添加完成 + AtomicReference finish = new AtomicReference<>(false); // 为了能在lambda中使用 + dataGroupByCompoundMap.forEach((k, v) -> { + + Map dataSolutionSampleDTOMap = v.stream() + .collect(Collectors + .toMap(DataSolutionSampleDTO::getCompoundName, Function.identity(), (v1, v2) -> v2)); // 化合物相同则后面的覆盖前面的值 + // 组装列表数据 + JSONObject dataObject = new JSONObject(); + dataObject.put("sampleNo", k); + int size = compoundsJsonArray.size(); // 防止频繁调用方法 + for (int i = 0; i < size; i++) { + JSONObject headerObject = compoundsJsonArray.getJSONObject(i); + String dictValue = headerObject.getString("dictValue"); + String dictLabel = headerObject.getString("dictLabel").substring(0, 3);//把化合物后缀取消,例如化合物1 + + // 第一次循环时添加头部信息 + if (!finish.get()) { + if (i == 0) { + headerArray.add(createHeaderObject("sampleNo", "溶液编号", false)); + } + headerArray.add(createHeaderObject(dictValue, dictLabel + "(" + dictValue + ")", false)); + } + // 设置标记,避免多次执行上面的代码 + if (i == size - 1) { + finish.set(true); + } + DataSolutionSampleDTO dto = dataSolutionSampleDTOMap.get(dictValue); + // 显示的数据 +// if (dto != null) { + // 把化合物组装导对象里 + dataObject.put(dictValue, dto != null ? dto.getSampleConcentration() : 0); +// } + } + dataArray.add(dataObject); + }); + map.put("header", headerArray); + map.put("data", dataArray); + return map; + } + + /** + * 保存实验数据的定量结果 + * + * @param dto + * @return + */ + @Override + public boolean saveQuantitativeResults(SaveQuantitativeResultsDTO dto) { + TestRecordSampleData testRecordSampleData = this.getOne(Wrappers.lambdaQuery() + .eq(TestRecordSampleData::getCompoundName, dto.getCompoundName()) + .eq(StrUtil.isNotBlank(dto.getSampleName()), TestRecordSampleData::getName, dto.getSampleName()) + .eq(StrUtil.isNotBlank(dto.getSampleNo()), TestRecordSampleData::getSampleNo, dto.getSampleNo()) + ); + if (testRecordSampleData == null) { + throw new RuntimeException(String.format("定量结果保存失败!%s 和 化合物 %s 对应数据不存在!", + StrUtil.isNotBlank(dto.getSampleName()) ? "上样编号 " + dto.getSampleName() : "检材编号 " + dto.getSampleNo(), dto.getCompoundName())); + } + validateTestStatus(testRecordSampleData.getTestId()); + JSONObject jsonObject = JSONObject.parseObject(testRecordSampleData.getDataResultJson()); + jsonObject.put("quantitativeResults", dto.getQuantitativeResults()); + return this.update(Wrappers.lambdaUpdate() + .eq(TestRecordSampleData::getId, testRecordSampleData.getId()) + .set(TestRecordSampleData::getDataResultJson, jsonObject.toJSONString())); + } + + + /** + * 删除实验数据的定量结果 + * + * @param testSampleDataId + * @return + */ + @Override + public boolean deleteQuantitativeResults(String testSampleDataId) { + TestRecordSampleData testRecordSampleData = this.getById(testSampleDataId); + if (testRecordSampleData == null) { + throw new RuntimeException(String.format("id 为 %s 的检验数据在系统中查询不到!", testSampleDataId)); + } + validateTestStatus(testRecordSampleData.getTestId()); + JSONObject jsonObject = JSONObject.parseObject(testRecordSampleData.getDataResultJson()); + jsonObject.put("quantitativeResults", null); + return this.update(Wrappers.lambdaUpdate() + .eq(TestRecordSampleData::getId, testRecordSampleData.getId()) + .set(TestRecordSampleData::getDataResultJson, jsonObject.toJSONString())); + } + + /** + * 标记该流程是否开始实验 + * + * @param testId + * @return + */ + @Override + public boolean whetherSave(String testId) { + long count = this.count(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + return count > 0; + } + + /** + * 根据实验id生成定性结果 + * + * @param businessId + * @return 从1号和2号检材中均检出合成大麻素类物质 MDMB-4E-PINACA, + * 未检出四氢大麻酚和 ADB-BUTINACA4F-MDMB-BUTICA、AMB-FUBICA、ADB-4E-PINACA、4F-MDMB-BUTINACA、SF-EDMB-PICA、 + * SF-ADB、SF-MPP-PICA4F-ABUTINACA、EDMB-PINACA、SCIAPINACA、4CN-CUMYL-BUTINACA、FUB-144。 + */ + @Override + public String generateQualitativeResults(String businessId) { + + List dataSolutionSampleDTOS = baseMapper.queryDataSolutionSampleDTOList(Wrappers.query() + .eq("si.business_id", businessId) + .last("ORDER BY SUBSTRING_INDEX(rs.name, '-', -1) + 0")); + Map> dataMap = dataSolutionSampleDTOS + .stream() + .collect( + Collectors.groupingBy( + item -> StrUtil.join("_", item.getCompoundName(), item.getIsDetected()), + LinkedHashMap::new, + Collectors.toList() + ) + ); + + StringBuilder stringBuilder = new StringBuilder(); +// AtomicInteger index = new AtomicInteger(1); // 在lambda里进行递增 + if (dataMap.size() == 1) { + dataMap.forEach((key, value) -> { + DataSolutionSampleDTO first = value.get(0); + stringBuilder + .append("\t") +// .append(index.getAndIncrement()) +// .append("、") + .append(first.getOrderNo()).append("号"); + if (value.size() > 1) { + stringBuilder.append("至").append(value.get(value.size() - 1).getOrderNo()).append("号"); + } + stringBuilder.append("检材") + .append(first.getIsDetected() == 1 ? TestRecordSampleDataConstant.CHECK_OUT : TestRecordSampleDataConstant.NOT_CHECK_OUT) + .append(first.getCompoundName()) + .append("\n"); + }); + } else { + dataMap.forEach((key, value) -> { + DataSolutionSampleDTO first = value.get(0); + stringBuilder + .append("\t") +// .append(index.getAndIncrement()) +// .append("、") + .append(value.stream().map(item -> item.getOrderNo() + "号检材").collect(Collectors.joining("、"))); + stringBuilder.append(first.getIsDetected() == 1 ? TestRecordSampleDataConstant.CHECK_OUT : TestRecordSampleDataConstant.NOT_CHECK_OUT) + .append(first.getCompoundName()) + .append("。\n"); + }); + } + +// dataMap.forEach((k, v) -> { +// Map> groupByCompoundMap = v.stream().collect(Collectors.groupingBy(DataSolutionSampleDTO::getCompoundName)); +// stringBuilder.append("\t").append(index.getAndIncrement()).append("、从").append(v.get(0).getSampleName() + "(" + v.get(0).getSampleNo() + ")"); +// String checkOutResult = ""; +// String notCheckOutResult = ""; +// Set keySet = groupByCompoundMap.keySet(); +// for (String key : keySet) { +// List dtoS1 = groupByCompoundMap.get(key); +// boolean detected = true; +// /// 下面先判断是否检出 +// if (dtoS1.size() > 1) { +// Set isDetected = dtoS1.stream().map(DataSolutionSampleDTO::getIsDetected).collect(Collectors.toSet()); +// // 如果set的长度大于1 则证明其中有的检出,有的未检出, 或者其中值有0 +// if (isDetected.size() > 1 || isDetected.contains(0)) { +// detected = false; +// } +// } else { +// // 不等于1 未检出 +// detected = dtoS1.get(0).getIsDetected() == 1; +// } +// // 拼接结果 +// if (detected) { +// if (StrUtil.isBlank(checkOutResult)) { +// checkOutResult = TestRecordSampleDataConstant.CHECK_OUT + key; +// } else { +// checkOutResult = checkOutResult + "、" + key; +// } +// +// } else { +// if (StrUtil.isBlank(notCheckOutResult)) { +// notCheckOutResult = TestRecordSampleDataConstant.NOT_CHECK_OUT + key; +// } else { +// notCheckOutResult = notCheckOutResult + "、" + key; +// } +// } +// } +// if (StrUtil.isNotBlank(checkOutResult) && StrUtil.isNotBlank(notCheckOutResult)) { +// stringBuilder.append(checkOutResult + ","); +// stringBuilder.append(notCheckOutResult + "。"); +// } else if (StrUtil.isNotBlank(checkOutResult)) { +// stringBuilder.append(checkOutResult + "。"); +// } else { +// stringBuilder.append(notCheckOutResult + "。"); +// } +// stringBuilder.append("\n"); +// }); + + return stringBuilder.toString(); + } +// 之前生成定性结果的代码 + // Map> isDetectedMap = v.stream().collect(Collectors.groupingBy(DataSolutionSampleDTO::getIsDetected)); +// List checkOutList = isDetectedMap.get(1); +// List notCheckOutList = isDetectedMap.get(0); +//// String result = "从" + v.get(0).getSampleName(); +// stringBuilder.append("\t"); +// stringBuilder.append(index.getAndIncrement() + "、从" + v.get(0).getSampleName()); +// if (CollUtil.isNotEmpty(checkOutList)) { +// String result = TestRecordSampleDataConstant.CHECK_OUT + +// StrUtil.join("、", checkOutList.stream().map(DataSolutionSampleDTO::getCompoundName).collect(Collectors.toList())) + ","; +// stringBuilder.append(result); +// } +// if (CollUtil.isNotEmpty(notCheckOutList)) { +// String result = TestRecordSampleDataConstant.NOT_CHECK_OUT + +// StrUtil.join("、", notCheckOutList.stream().map(DataSolutionSampleDTO::getCompoundName).collect(Collectors.toList())) + "。"; +// stringBuilder.append(result); +// } + + /** + * 完成实验 + * + * @param testId + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R finishTest(String testId) { + TestRecord testRecord = testRecordService.getById(testId); + if (testRecord == null) { + return R.failed(String.format("id 为 %s 的数据不存在!", testId)); + } + // 更新实验状态 + if (testRecordService.update(Wrappers.lambdaUpdate() + .eq(TestRecord::getId, testId) + .set(TestRecord::getStatus, 5) + .set(TestRecord::getTestEndDate, LocalDate.now()))) { + // 获取业务id + List dataSolutionSampleDTOS = baseMapper.queryDataSolutionSampleDTOList(Wrappers.query() + .in("si.id", testRecord.getSampleTestList())); + if (CollUtil.isEmpty(dataSolutionSampleDTOS)) { + throw new RuntimeException("检验数据和检材不匹配!"); + } + Set businessIdSet = dataSolutionSampleDTOS.stream().map(DataSolutionSampleDTO::getBusinessId).collect(Collectors.toSet()); + // 获取业务信息 + List testResultBusinessVOS = baseMapper.queryTestResultTaskList(Wrappers.query().in("T.id", businessIdSet)); + // 进行分组 + Map> testResultBusinessVOTypeMap = testResultBusinessVOS.stream().collect(Collectors.groupingBy(TestResultBusinessVO::getType)); + testResultBusinessVOTypeMap.forEach((k, v) -> { + if (k == 10000 && CollUtil.isNotEmpty(v)) { + List entrustIds = v.stream().map(TestResultBusinessVO::getId).collect(Collectors.toList()); + if (!entrustInfoService.update(Wrappers.lambdaUpdate() + .in(EntrustInfo::getId, entrustIds).set(EntrustInfo::getStatus, 3))) { + throw new RuntimeException("委托状态更新失败!"); + } + } + }); + } else { + throw new RuntimeException("实验状态更新失败!"); + } + // 发布事件 + applicationContext.publishEvent(new FinishTestExecutionEvent(this)); + return R.ok("完成实验成功!"); + } + + /** + * 审核审批数据 + * + * @param auditDataDTO + * @param httpServletRequest + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R auditTaskTestData(AuditDataDTO auditDataDTO, HttpServletRequest httpServletRequest) { + // 标记操作是否成功 + boolean success = true; + try { + // 获取参数中所有编号的检验数据 + Map> testRecordSampleDataMap = this.list(Wrappers.lambdaQuery() + .in(TestRecordSampleData::getSampleNo, auditDataDTO.getSampleNoList())) + .stream() + .collect(Collectors.groupingBy(TestRecordSampleData::getSampleNo)); + // 对执行数据进行校验 + testRecordSampleDataMap.forEach((k, v) -> { + TestRecordSampleData testRecordSampleData = v.get(0); + if (auditDataDTO.getOpCode().equals(TaskTestDataStatus.REVIEWED.getCode())) { + if (testRecordSampleData.getStatus() > TaskTestDataStatus.REVIEWED.getCode()) { + throw new RuntimeException(String.format("编号为 %s 的数据已经审核过,不能重复审核!", k)); + } + } else if (auditDataDTO.getOpCode().equals(TaskTestDataStatus.APPROVED.getCode())) { + if (testRecordSampleData.getStatus() > TaskTestDataStatus.APPROVED.getCode()) { + throw new RuntimeException(String.format("编号为 %s 的数据已经审批过,不能重复审批!", k)); + } + } + }); + + switch (TaskTestDataStatus.getEnumByCode(auditDataDTO.getOpCode())) { +// case REJECT: +// success = this.update(Wrappers.lambdaUpdate() +// .in(TestRecordSampleData::getSampleNo, auditDataDTO.getSampleNoList()) +// .set(TestRecordSampleData::getStatus, TaskTestDataStatus.REJECT.getCode())); +// break; + case REVIEWED: + success = this.update(Wrappers.lambdaUpdate() + .in(TestRecordSampleData::getSampleNo, auditDataDTO.getSampleNoList()) + .set(TestRecordSampleData::getStatus, TaskTestDataStatus.REVIEWED.getCode())); + + break; + case APPROVED: + success = this.update(Wrappers.lambdaUpdate() + .in(TestRecordSampleData::getSampleNo, auditDataDTO.getSampleNoList()) + .set(TestRecordSampleData::getStatus, TaskTestDataStatus.APPROVED.getCode())); + List sampleNoList = auditDataDTO.getSampleNoList(); +// taskInfoService.createUploadItem(sampleNoList); + applicationContext.publishEvent(new AuditDataExecutionEvent(this, sampleNoList)); + break; + + } + } catch (Exception e) { + e.printStackTrace(); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + } + if (success) { + return R.ok(true, "操作成功"); + } else { + return R.failed(false, "操作失败!"); + } + } + + //获取标准品样品信息数据 + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean saveTestDataFromNps(List npsDataFileStructList, String testId) { +// try { + List testRecordSampleDataList = buildSampleDataFromNps(npsDataFileStructList, testId);//构造实验数据 + testRecordService.update(Wrappers.lambdaUpdate().eq(TestRecord::getId, testId).set(TestRecord::getStatus, 2)); + return true; +// } catch (Exception err) { +// log.info("程序执行异常{}", err.getMessage()); +// err.printStackTrace(); +// return false; +// } + } + + + /** + * 更新或者保存实验数据 + * + * @param oldInfo 未更新前的数据 + * @param compoundName + * @param jsonStr DTO 转 json String + * @param sampleNo + * @param testId + * @param sampleName + * @return + */ + private boolean saveOrUpdateTestData(TestRecordSampleData oldInfo, + String compoundName, + String jsonStr, + String sampleNo, + String testId, String sampleName, String compoundCnName) { +// TestRecordSampleData one = this.getById(testSampleDataId); + if (oldInfo != null) { + return this.update(Wrappers.lambdaUpdate() + .eq(TestRecordSampleData::getId, oldInfo.getId()) + .set(!oldInfo.getCompoundName().equals(compoundName), TestRecordSampleData::getCompoundName, compoundName) + .set(sampleName != null && !sampleName.equals(oldInfo.getName()), TestRecordSampleData::getName, sampleName) + .set(TestRecordSampleData::getDataResultJson, jsonStr) + .set(StringUtils.isNotBlank(compoundCnName), TestRecordSampleData::getCompoundCnName, compoundCnName)); + } else { + TestRecordSampleData testRecordSampleData = new TestRecordSampleData(); + testRecordSampleData.setId(IdWorker.get32UUID()); + testRecordSampleData.setSampleNo(sampleNo); + testRecordSampleData.setCompoundName(compoundName); + testRecordSampleData.setTestId(testId); + testRecordSampleData.setDataResultJson(jsonStr); + if (sampleNo.startsWith(StdSolutionNum.QC_SOLUTION.getPrefix())) { + testRecordSampleData.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_QC); + } else if (sampleNo.startsWith(StdSolutionNum.MIXED_SOLUTION.getPrefix()) || sampleNo.startsWith(StdSolutionNum.SIMPLE_SOLUTION.getPrefix())) { + testRecordSampleData.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_STD); + } else { + testRecordSampleData.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE); + } + return this.save(testRecordSampleData); + } + } + + /** + * 毛发案件检验数据持久化到数据库 + * + * @param hairCompoundDataMap + * @param testId + * @return + */ + private List buildSampleDataFromHairCase(Map> hairCompoundDataMap, String testId) { + List testRecordSampleDataList_All = new Vector<>(); + List testRecordSampleDataList_Std = new Vector<>();//如果筛查物是多个,就可能出现多个标准品的数据 + List testRecordSampleDataList_Analyte = new Vector<>();//检材样品的数据 + + hairCompoundDataMap.forEach((k, v) -> { + v.parallelStream().forEach(hairCompoundData -> { + String sampleName = hairCompoundData.getSampleName(); + String idName = hairCompoundData.getIdName(); + HairSewageDataDto hairSewageDataDto = new HairSewageDataDto(); + hairSewageDataDto.setSampleNo(idName); // 样本编号 + hairSewageDataDto.setSampleName(sampleName); // 样本名称 + hairSewageDataDto.setTestId(testId); // 实验id + // 设置对应的元素数据 + hairSewageDataDto.setTestSampleDataList(Lists.newArrayList(hairCompoundData)); + hairSewageDataDto.setCompoundName(k); // 化合物名称 + + hairSewageDataDto.setBusinessType(BusinessType.BOINT_CASE.getBusinessType()); + completeHairDataInfo(hairCompoundData, hairSewageDataDto); + if (idName.contains(TestRecordSampleDataConstant.SAMPLE_TYPE_STD)) { + hairSewageDataDto.setRtTimeError(-999); // 标准溶液的相对误差为 / + hairSewageDataDto.setRtTimeWithinError(TestRecordSampleDataConstant.IS); + hairSewageDataDto.setIonAbundanceRatioWithinError(-999); // 离子丰度比相对误差 + hairSewageDataDto.setWhetherCheckOut(TestRecordSampleDataConstant.IS); + hairSewageDataDto.setStdRtTime(hairSewageDataDto.getTargetRtTime()); + hairSewageDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_STD); + testRecordSampleDataList_Std.add(hairSewageDataDto);//放标准品的列表 + } else { + hairSewageDataDto.setSampleType( + idName.startsWith(TestRecordSampleDataConstant.SAMPLE_TYPE_QC) ? + TestRecordSampleDataConstant.SAMPLE_TYPE_QC : TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE); +// hairSewageDataDto.setTargetRtTime(rtTime); // 目标物保留时间 + testRecordSampleDataList_Analyte.add(hairSewageDataDto);//放被分析物 + } + testRecordSampleDataList_All.add(hairSewageDataDto);//所有的样本的数据 + }); + }); + // 计算相对误差喝离子丰度比相对误差,并判断是否符合 + settingHairCaseStdConcentration(testRecordSampleDataList_Std, testId); + settingHairCaseRelativeErrorAnalyte(testRecordSampleDataList_Std, testRecordSampleDataList_Analyte, testId); + + // 组装数据持久化到数据库 + List testRecordSampleDataStdList = genPersistenceSampleData(testRecordSampleDataList_Std); + List testRecordSampleDataAnalyteList = genPersistenceSampleData(testRecordSampleDataList_Analyte); + // 合并数组 + List mergeList = new ArrayList<>(); + mergeList.addAll(testRecordSampleDataStdList); + mergeList.addAll(testRecordSampleDataAnalyteList); + // 批量保存到数据库 + this.saveBatch(mergeList); + return mergeList; + } + + /** + * 补全毛发检验数据信息 + * + * @param hairCompoundData + * @param hairSewageDataDto + */ + private void completeHairDataInfo(HairSewageCompoundData hairCompoundData, HairSewageDataDto hairSewageDataDto) { + hairSewageDataDto.setQualitativeIonPairUp(hairCompoundData.getQuanTrace()); // 定性离子对 + hairSewageDataDto.setQualitativeIonPairDown(hairCompoundData.getTrace1()); + hairSewageDataDto.setPeakAreaUp(hairCompoundData.getArea() == null ? -999 : hairCompoundData.getArea()); // 峰面积 + hairSewageDataDto.setPeakAreaDown(hairCompoundData.getArea1() == null ? -999 : hairCompoundData.getArea1()); + + // 封装定性离子对和峰面积 + Map upMap = new HashMap<>(); + upMap.put("qualitativeIonPair", hairSewageDataDto.getQualitativeIonPairUp()); + upMap.put("peakArea", hairSewageDataDto.getPeakAreaUp()); + Map downMap = new HashMap<>(); + downMap.put("qualitativeIonPair", hairSewageDataDto.getQualitativeIonPairDown()); + downMap.put("peakArea", hairSewageDataDto.getPeakAreaDown()); + hairSewageDataDto.setMaps(Lists.newArrayList(upMap, downMap)); + // 离子丰度比 + if (hairCompoundData.getRatioActual() == null) { + if (hairCompoundData.getArea() != null && hairCompoundData.getArea1() != null) { + hairSewageDataDto.setIonAbundanceRatio(hairCompoundData.getArea1() / hairCompoundData.getArea()); + } else { + hairSewageDataDto.setIonAbundanceRatio(-999); + } + } else { + hairSewageDataDto.setIonAbundanceRatio(hairCompoundData.getRatioActual()); + } + Double rtTime = hairCompoundData.getRtTime() == null ? -999 : hairCompoundData.getRtTime(); // 取文件的保留时间 + hairSewageDataDto.setTargetRtTime(rtTime); // 目标物保留时间, 标准物质的保留时间同时存在 TargetRtTime 和 StdRtTime + } + +// /** +// * 生成持久化到数据库的实体类 +// * @param hairCaseDataDtoList +// * @return +// */ +// private List generateTestRecordSampleData(List hairCaseDataDtoList) { +// +// List persistenceSampleDataList = new ArrayList<>(); +// hairCaseDataDtoList.forEach(item->{ +// TestRecordSampleData testRecordSampleData = new TestRecordSampleData(); +// testRecordSampleData.setId(IdWorker.get32UUID()); +// testRecordSampleData.setTestId(item.getTestId()); +// testRecordSampleData.setSampleNo(item.getSampleNo()); +// testRecordSampleData.setSampleConcentration(item.getTargetConcentration()); +// testRecordSampleData.setStdConcentration(item.getStdConcentration()); +// testRecordSampleData.setCompoundName(item.getCompoundName()); +// testRecordSampleData.setTargetRtTime(item.getTargetRtTime());//检材保留时间 +// testRecordSampleData.setStdRtTime(item.getStdRtTime());//标准品保留时间 +// testRecordSampleData.setRtTimeWithinError(item.getRtTimeWithinError()); +// String dataJsonStr=JSONUtil.toJsonStr(item.getTestSampleDataList()); +// String dataResultJsonStr=JSONUtil.toJsonStr(item); +// testRecordSampleData.setDataJson(dataJsonStr); +// testRecordSampleData.setDataResultJson(dataResultJsonStr); +// persistenceSampleDataList.add(testRecordSampleData); +// }); +// return persistenceSampleDataList; +// } + + /** + * 计算相对误差喝离子丰度比相对误差,并判断是否符合 + * + * @param testRecordSampleDataListStd + * @param testRecordSampleDataListAnalyte + * @param testId + * @return + */ + private List settingHairCaseRelativeErrorAnalyte(List testRecordSampleDataListStd, + List testRecordSampleDataListAnalyte, String testId) { + + List resultConcentrationVOList = sampleInjectorMapper.queryResultConcentrationList( + Wrappers.query().eq("T.test_id", testId)); + Map stdMap = testRecordSampleDataListStd.stream() + .collect(Collectors.toMap(HairSewageDataDto::getCompoundName, Function.identity())); + + testRecordSampleDataListAnalyte.parallelStream().forEach(hairSewageDataDto -> { + List testRecordSampleSolutionlist = resultConcentrationVOList.stream() + .filter(item -> item.getNumber().equals(hairSewageDataDto.getSampleNo())).collect(Collectors.toList()); + /// 设置目标物浓度 + if (CollUtil.isNotEmpty(testRecordSampleSolutionlist)) { + hairSewageDataDto.setStdConcentration(testRecordSampleSolutionlist.get(0).getResultConcentration()); + } else { + log.info("没有找到该样本溶液,检验的化合物 {} 样本编号 {}", hairSewageDataDto.getCompoundName(), hairSewageDataDto.getSampleNo()); + hairSewageDataDto.setStdConcentration("/"); + } + + // 设置标准物质浓度 + HairSewageDataDto hairSewageDataDtoStd = stdMap.get(hairSewageDataDto.getCompoundName()); // 获取化合物下的标准物质信息 + if (hairSewageDataDtoStd != null) { +// hairSewageDataDto.setConcentration(hairSewageDataDtoStd.getStdConcentration()); +// hairSewageDataDto.setStdRtTime(hairSewageDataDtoStd.getStdRtTime()); + // 计算相对误差 (目标物保留时间 - 标准物保留时间) / 标准物质保留时间 * 100 + calculateHairCaseRtTimeError(hairSewageDataDto, hairSewageDataDtoStd); + // 计算离子丰度比 相对偏差 (目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100 + calculateHairCaseIonAbundanceRatioWithinError(hairSewageDataDto, hairSewageDataDtoStd); + } +// else { +// log.info("没有找到该标准溶液,化合物 {} 样本ID {}", hairSewageDataDto.getCompoundName(), hairSewageDataDto.getSampleNo()); +// hairSewageDataDto.setStdConcentration("-1"); +// hairSewageDataDto.setStdRtTime(-999); +// } + }); + return testRecordSampleDataListAnalyte; + } + + /** + * 计算离子丰度比 相对偏差 (目标物离子丰度比 - 标准物离子丰度比) / 标准物质离子丰度比 * 100 + * + * @param hairSewageDataDto + * @param hairSewageDataDtoStd + */ + private void calculateHairCaseIonAbundanceRatioWithinError(HairSewageDataDto hairSewageDataDto, HairSewageDataDto hairSewageDataDtoStd) { + if (hairSewageDataDto.getIonAbundanceRatio() != -999) { + double ionAbundanceRatioWithinError = getHairCaseIonAbundanceRatioWithinError(hairSewageDataDto, hairSewageDataDtoStd); + hairSewageDataDto.setIonAbundanceRatioWithinError(ionAbundanceRatioWithinError); + double stdIonAbundanceRatio = hairSewageDataDtoStd.getIonAbundanceRatio(); + // 判断是否在离子丰度比允许的最大偏差范围 + if (stdIonAbundanceRatio > TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_1) { + + setHairCaseWhetherCheckOut( + hairSewageDataDto, + TestRecordSampleDataConstant.HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_1, + TestRecordSampleDataConstant.HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_1); + + } else if (stdIonAbundanceRatio > TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_2 + && stdIonAbundanceRatio <= TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_1) { + + setHairCaseWhetherCheckOut( + hairSewageDataDto, + TestRecordSampleDataConstant.HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_2, + TestRecordSampleDataConstant.HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_2); + + } else if (stdIonAbundanceRatio > TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_3 + && stdIonAbundanceRatio <= TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_2) { + + setHairCaseWhetherCheckOut( + hairSewageDataDto, + TestRecordSampleDataConstant.HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_3, + TestRecordSampleDataConstant.HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_3); + } else if (stdIonAbundanceRatio <= TestRecordSampleDataConstant.HAIR_CASE_ION_ABUNDANCE_RATIO_3) { + setHairCaseWhetherCheckOut( + hairSewageDataDto, + TestRecordSampleDataConstant.HAIR_CASE_POSITIVE_MAX_ALLOW_ERROR_4, + TestRecordSampleDataConstant.HAIR_CASE_NEGATIVE_MAX_ALLOW_ERROR_4); + } + } else { + hairSewageDataDto.setIonAbundanceRatioWithinError(-999); + hairSewageDataDto.setWhetherCheckOut("/"); + } + } + + /** + * 计算离子丰度比相对误差 + * + * @param hairSewageDataDto + * @param hairSewageDataDtoStd + * @return + */ + private double getHairCaseIonAbundanceRatioWithinError(HairSewageDataDto hairSewageDataDto, HairSewageDataDto hairSewageDataDtoStd) { + return (hairSewageDataDto.getIonAbundanceRatio() - hairSewageDataDtoStd.getIonAbundanceRatio()) / hairSewageDataDtoStd.getIonAbundanceRatio() * 100; + } + + /** + * 根据计算出来的离子丰度比误差来判断是否检出 + * + * @param hairSewageDataDto + * @param positive + * @param negative + */ + private void setHairCaseWhetherCheckOut(HairSewageDataDto hairSewageDataDto, double positive, double negative) { + if (hairSewageDataDto.getIonAbundanceRatioWithinError() < positive + && hairSewageDataDto.getIonAbundanceRatioWithinError() > negative) { + hairSewageDataDto.setWhetherCheckOut(TestRecordSampleDataConstant.IS); + hairSewageDataDto.setIsDetected(1); + } else { + hairSewageDataDto.setWhetherCheckOut(TestRecordSampleDataConstant.NO); + hairSewageDataDto.setIsDetected(0); + } + } + + /** + * 计算相对误差 (目标物保留时间 - 标准物保留时间) / 标准物质保留时间 * 100 + * + * @param hairSewageDataDto + * @param hairSewageDataDtoStd + */ + private void calculateHairCaseRtTimeError(HairSewageDataDto hairSewageDataDto, HairSewageDataDto hairSewageDataDtoStd) { + if (hairSewageDataDto.getTargetRtTime() != -999) { + // 计算保留时间的相对误差 + double rtTimeError = getHairCaseRtTimeError(hairSewageDataDto, hairSewageDataDtoStd); + hairSewageDataDto.setRtTimeError(rtTimeError); + // 判断保留时间相对误差是否符合误差范围 + setHairCaseRtTimeWithinError(hairSewageDataDto); + } else { + hairSewageDataDto.setRtTimeError(-999); + hairSewageDataDto.setRtTimeWithinError("/"); + } + } + + /** + * 计算保留时间的相对误差 + * + * @param hairSewageDataDto 目标物信息 + * @param hairSewageDataDtoStd 标准物信息 + * @return + */ + private double getHairCaseRtTimeError(HairSewageDataDto hairSewageDataDto, HairSewageDataDto hairSewageDataDtoStd) { + return (hairSewageDataDto.getTargetRtTime() - hairSewageDataDtoStd.getStdRtTime()) / hairSewageDataDtoStd.getStdRtTime() * 100; + } + + /** + * 判断保留时间相对误差是否符合误差范围 + * + * @param hairSewageDataDto + */ + private void setHairCaseRtTimeWithinError(HairSewageDataDto hairSewageDataDto) { + if (hairSewageDataDto.getRtTimeError() > TestRecordSampleDataConstant.HAIR_CASE_NEGATIVE_RT_ERROR + && hairSewageDataDto.getRtTimeError() < TestRecordSampleDataConstant.HAIR_CASE_POSITIVE_RT_ERROR) { + hairSewageDataDto.setRtTimeWithinError(TestRecordSampleDataConstant.IS); + } else { + hairSewageDataDto.setRtTimeWithinError(TestRecordSampleDataConstant.NO); + } + } + + /** + * 设置标准物的溶液浓度 + * + * @param testRecordSampleDataListStd + * @param testId + * @return + */ + private List settingHairCaseStdConcentration(List testRecordSampleDataListStd, String testId) { + List testRecordStandardSolutionList = testRecordStandardSolutionService.list( + Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getTestId, testId)); + // 根据编号转map 方便获取 + Map testRecordStandardSolutionMap = testRecordStandardSolutionList + .stream() + .collect(Collectors.toMap(TestRecordStandardSolution::getNumber, Function.identity())); + for (HairSewageDataDto hairSewageDataDto : testRecordSampleDataListStd) { + //设置标准品的浓度 + TestRecordStandardSolution testRecordStandardSolution = testRecordStandardSolutionMap.get(hairSewageDataDto.getSampleNo()); + if (ObjectUtil.isNotEmpty(testRecordStandardSolution)) { + hairSewageDataDto.setStdConcentration(testRecordStandardSolution.getResultConcentration());//设置标准品的浓度 + } else { + log.info("没有找到该标准溶液,实验ID {} {}", hairSewageDataDto.getCompoundName(), hairSewageDataDto.getSampleNo()); + hairSewageDataDto.setStdConcentration("/"); + } + } + return testRecordSampleDataListStd; + } + + /** + * 构建数据库持久化对象 + * + * @param npsDataFileStructList + * @param testId + * @return + */ + private List buildSampleDataFromNps(List npsDataFileStructList, String testId) { + List testRecordSampleDataList_All = new ArrayList<>(); + List testRecordSampleDataList_Std = new ArrayList<>();//如果筛查物是多个,就可能出现多个标准品的数据 + List testRecordSampleDataList_Analyte = new ArrayList<>();//检材样品的数据 + + //一批文件中含有多个样本,将一个样本的检验数据封装到一个NPSCaseTestDataDto对象中 + //查出这批实验中的标准品数据,并将NPSDataFileStruct 转化为NPSCaseTestDataDto对象 + npsDataFileStructList.forEach(item -> { + String sampleNo = item.getSi_SampleId(); + String sampleType = item.getSi_SampleType(); + //离子丰度比数据 + NPSCaseTestDataDto npsCaseTestDataDto = getNpsCaseTestDataDto(testId, item, sampleNo); + if (sampleType.equals(TestRecordSampleDataConstant.SAMPLE_TYPE_STD)) { + testRecordSampleDataList_Std.add(npsCaseTestDataDto);//放标准品的列表 + } else { + testRecordSampleDataList_Analyte.add(npsCaseTestDataDto);//放被分析物 + } + testRecordSampleDataList_All.add(npsCaseTestDataDto);//所有的样本的数据 + }); + //设置计算保留时间和丰度比 + settingAbundanceRatioStd(testRecordSampleDataList_Std, testId); + settingAbundanceRatioAnalyte(testRecordSampleDataList_Analyte, testRecordSampleDataList_Std, testId); + //构造持久化到数据库的对象 + List testRecordSampleDataList_std = genPersistenceSampleData(testRecordSampleDataList_Std); + List testRecordSampleDataList_analyte = genPersistenceSampleData(testRecordSampleDataList_Analyte); + this.saveBatch(testRecordSampleDataList_std); + this.saveBatch(testRecordSampleDataList_analyte); + List retList = new ArrayList<>(); + retList.addAll(testRecordSampleDataList_std); + retList.addAll(testRecordSampleDataList_analyte); + return retList; + } + + /** + * 生成npsDTO + * + * @param testId + * @param item + * @param sampleNo + * @return + */ + private NPSCaseTestDataDto getNpsCaseTestDataDto(String testId, NPSDataFileStruct item, String sampleNo) { + List testDetailDataList = item.getChildDataList(); + NPSCaseTestDataDto npsCaseTestDataDto = new NPSCaseTestDataDto(); + npsCaseTestDataDto.setSampleName(item.getSi_SampleName()); + npsCaseTestDataDto.setSampleNo(sampleNo); + npsCaseTestDataDto.setTestId(testId); + npsCaseTestDataDto.setTestSampleDataList(testDetailDataList); + npsCaseTestDataDto.setCompoundName(testDetailDataList.get(0).getName()); + npsCaseTestDataDto.setBusinessType(BusinessType.NPS_CASE.getBusinessType()); // 设置业务类型 + return npsCaseTestDataDto; + } + + /** + * 构造持久化到数据库的对象 + * 使用了通配符 来接收不同类型的数据对象,并通过 instanceof 关键字进行类型判断以获取对应的属性值。 + * 这样可以避免重复的代码逻辑,提高代码的可维护性和复用性 + * + * @param npsCaseTestDataDtoList + * @return + */ + private List genPersistenceSampleData(List npsCaseTestDataDtoList) { + List persistenceSampleDataList = Collections.synchronizedList(new ArrayList<>()); + npsCaseTestDataDtoList.parallelStream().forEach(item -> { + + TestRecordSampleData testRecordSampleData = new TestRecordSampleData(); + testRecordSampleData.setId(IdWorker.get32UUID()); + testRecordSampleData.setTestId(item.getTestId()); +// testRecordSampleData.setSampleNo(item.getSampleId()); + if (item instanceof HairSewageDataDto) { + testRecordSampleData.setName(((HairSewageDataDto) item).getSampleName()); + testRecordSampleData.setSampleNo(((HairSewageDataDto) item).getSampleNo()); + } else if (item instanceof NPSCaseTestDataDto) { + NPSCaseTestDataDto npsCaseTestDataDto = (NPSCaseTestDataDto) item; + testRecordSampleData.setName(npsCaseTestDataDto.getSampleName()); + testRecordSampleData.setSampleNo(npsCaseTestDataDto.getSampleNo()); + } + testRecordSampleData.setSampleConcentration(item.getTargetConcentration()); + testRecordSampleData.setStdConcentration(item.getStdConcentration()); + testRecordSampleData.setTargetRtTime(item.getTargetRtTime());//检材保留时间 + testRecordSampleData.setStdRtTime(item.getStdRtTime());//标准品保留时间 + testRecordSampleData.setCompoundName(item.getCompoundName()); + testRecordSampleData.setRtTimeWithinError(item.getRtTimeWithinError()); + testRecordSampleData.setIsDetected(item.getIsDetected()); + testRecordSampleData.setSampleType(item.getSampleType()); + String dataJsonStr = null; + String dataResultJsonStr = null; + try { + dataJsonStr = JSON.toJSONString(item.getTestSampleDataList()); + } catch (Exception e) { + log.error("错误位置详细信息 ============== {}", item.getTestSampleDataList()); + e.printStackTrace(); + } + try { + dataResultJsonStr = JSON.toJSONString(item); + } catch (Exception e) { + log.error("错误位置详细信息 ============== {}", item); + e.printStackTrace(); + } + testRecordSampleData.setDataJson(dataJsonStr); + testRecordSampleData.setDataResultJson(dataResultJsonStr); + persistenceSampleDataList.add(testRecordSampleData); + }); + return persistenceSampleDataList; + } + + //计算标准品的丰度比 + private List settingAbundanceRatioStd(List testRecordSampleDataListStd, String testId) { + // + if (CollUtil.isEmpty(testRecordSampleDataListStd)) { + throw new RuntimeException("未检测到数据文件中的标准品溶液!"); + } +// Optional testId = testRecordSampleDataListStd.stream().map(item -> item.getTestId()).findFirst(); + List testRecordStandardSolutionList = testRecordStandardSolutionService.list( + Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getTestId, testId)); + + for (NPSCaseTestDataDto npsCaseTestDataDto : testRecordSampleDataListStd) { + //设置标准品的浓度 + List testRecordStandardSolution = testRecordStandardSolutionList.stream() + .filter(item -> item.getNumber().equals(npsCaseTestDataDto.getSampleNo())).collect(Collectors.toList()); + if (testRecordStandardSolution.size() > 0) { + npsCaseTestDataDto.setStdConcentration(testRecordStandardSolution.get(0).getResultConcentration());//设置标准品的浓度 + } else { + log.info("没有找到该标准溶液,实验ID {} {}", npsCaseTestDataDto.getCompoundName(), npsCaseTestDataDto.getSampleNo()); + npsCaseTestDataDto.setStdConcentration("/"); + } + + //根据化合物名称查出谁是基峰 + List testSampleDataList = npsCaseTestDataDto.getTestSampleDataList(); + NPSTestDetailDataStruct npsTestDetailDataStruct_Base = getBasePeakMass(testSampleDataList); + if (npsTestDetailDataStruct_Base == null) { + throw new RuntimeException("在系统中没有找到对应的化合物基峰!"); + } + double sumRetTime = 0; + for (NPSTestDetailDataStruct npsTestDetailDataStruct : testSampleDataList) { + //求保留时间 + sumRetTime = sumRetTime + npsTestDetailDataStruct.getRetTime(); + if (!npsTestDetailDataStruct.getId().equals(npsTestDetailDataStruct_Base.getId())) { + //计算丰度比 + double mzValue = npsTestDetailDataStruct.getArea() / npsTestDetailDataStruct_Base.getArea() * 100; + npsTestDetailDataStruct.setAbundanceRatio(mzValue); + } else { + npsTestDetailDataStruct.setAbundanceRatio(-999); + npsTestDetailDataStruct.setIsBasePeak(1); + } + + } + double sampleRetTime = sumRetTime / testSampleDataList.size(); + npsCaseTestDataDto.setStdRtTime(sampleRetTime);//设置样品的保留时间 + npsCaseTestDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_STD); + + } + return testRecordSampleDataListStd; + } + + /** + * 计算待测样品的保留时间和丰度比 + * + * @param testRecordSampleDataList + * @param testId + */ + private List settingAbundanceRatioAnalyte(List testRecordSampleDataList, List testRecordSampleDataList_std, String testId) { + //因为要读样本的浓度,所以我们把该实验下所有样本信息拿过来 +// Optional testId = testRecordSampleDataList.stream().map(item -> item.getTestId()).findFirst(); + List sampleSolutionlist = testRecordSampleSolutionService.list(Wrappers.lambdaQuery() + .eq(TestRecordSampleSolution::getTestId, testId)); + + for (NPSCaseTestDataDto npsCaseTestDataDto : testRecordSampleDataList) { + + List testRecordSampleSolutionlist = sampleSolutionlist.stream() + .filter(item -> item.getSampleNo().equals(npsCaseTestDataDto.getSampleNo())).collect(Collectors.toList()); + if (testRecordSampleSolutionlist.size() > 0) { + npsCaseTestDataDto.setTargetConcentration(testRecordSampleSolutionlist.get(0).getResultConcentration());//设置标准品的浓度 + } else { + log.info("没有找到该样本溶液,检验的化合物 {} 样本编号 {}", npsCaseTestDataDto.getCompoundName(), npsCaseTestDataDto.getSampleNo()); + npsCaseTestDataDto.setTargetConcentration("/"); + } + //设置标准物质的浓度 + List stdSolution = testRecordSampleDataList_std.stream() + .filter(item -> item.getCompoundName().equals(npsCaseTestDataDto.getCompoundName())) + .collect(Collectors.toList()); + if (stdSolution.size() > 0) { + npsCaseTestDataDto.setStdConcentration(stdSolution.get(0).getStdConcentration()); + } else { + log.info("没有找到该标准溶液,化合物 {} 样本ID {}", npsCaseTestDataDto.getCompoundName(), npsCaseTestDataDto.getSampleNo()); + npsCaseTestDataDto.setStdConcentration("/"); + } + // 取出这个子列表 + List testSampleDataList = npsCaseTestDataDto.getTestSampleDataList(); + List notIdentifiedList = testSampleDataList.stream().filter(o -> o.isNotIdentified()).collect(Collectors.toList()); + if (CollUtil.isEmpty(notIdentifiedList)) { // 没有未检出的数据 + //根据化合物名称查出谁是基峰 + NPSTestDetailDataStruct npsTestDetailDataStruct_Base = getBasePeakMass(testSampleDataList); + double sumRetTime = 0; + //定义1个List来保存除基峰之外的其他碎片峰 + List otherList = new ArrayList<>(); + for (NPSTestDetailDataStruct npsTestDetailDataStruct : testSampleDataList) { + //求保留时间 + sumRetTime = sumRetTime + npsTestDetailDataStruct.getRetTime(); + if (!npsTestDetailDataStruct.getId().equals(npsTestDetailDataStruct_Base.getId())) { + //计算丰度比 + double mzValue = npsTestDetailDataStruct.getArea() / npsTestDetailDataStruct_Base.getArea() * 100; + npsTestDetailDataStruct.setAbundanceRatio(mzValue); + //设置误差范围,基峰不用设置误差范围 + double errorRange = getErrorRange(mzValue); + npsTestDetailDataStruct.setErrorRange(errorRange); + //设置标准品的丰度比 + double stdCorrespondingAbundanceRatio = getStdCorrespondingAbundanceRatio(npsTestDetailDataStruct.getMass(), + npsTestDetailDataStruct.getName(), testRecordSampleDataList_std); + npsTestDetailDataStruct.setAbundanceRatio_std(stdCorrespondingAbundanceRatio); + //设置偏差,公式是 样品-标准品/标准品 + double abundanceRatioErrorValue = getAbundanceRatioErrorValue(npsTestDetailDataStruct.getAbundanceRatio(), + npsTestDetailDataStruct.getAbundanceRatio_std()); + npsTestDetailDataStruct.setAbundanceRatioError(abundanceRatioErrorValue); + //设置是否在误差范围内 + String withinErrorText = getWithinErrorText(npsTestDetailDataStruct.getAbundanceRatioError(), npsTestDetailDataStruct.getErrorRange()); + npsTestDetailDataStruct.setWithinError(withinErrorText); + otherList.add(npsTestDetailDataStruct); + } else { + npsTestDetailDataStruct.setAbundanceRatio(-999);//设置检材丰度比 + npsTestDetailDataStruct.setAbundanceRatio_std(-999);//设置标准物质丰度比 + npsTestDetailDataStruct.setErrorRange(-999);//设置丰度比偏差 + npsTestDetailDataStruct.setAbundanceRatioError(-999);//设置偏差范围 + npsTestDetailDataStruct.setWithinError("/");//设置是否在误差范围内 + npsTestDetailDataStruct.setIsBasePeak(1);//设置他是基峰 + } + + } + double sampleRetTime = sumRetTime / testSampleDataList.size(); + npsCaseTestDataDto.setTargetRtTime(sampleRetTime);//设置样品的保留时间 + //设置标准品的保留时间 + double stdRtTime = findStdRtTime(npsCaseTestDataDto.getTestSampleDataList().get(0).getName(), testRecordSampleDataList_std); + npsCaseTestDataDto.setStdRtTime(stdRtTime); + //设置保留时间偏差是否在范围 ±1 范围内 公式是 (Rt样品-标品)/标品 *100% + double tmp1 = (sampleRetTime - stdRtTime) / stdRtTime; + tmp1 = Math.abs(tmp1) * 100; + npsCaseTestDataDto.setRtTimeError(tmp1); + String rtWithinErrorText = getRtWithinErrorText(tmp1, 1); + npsCaseTestDataDto.setRtTimeWithinError(rtWithinErrorText); + //设置碎片峰的结果,条件是 除了基峰外的所有特征碎片都满足 离子丰度误差,才算是检出条件之一 + int isOk = checkOtherFragmentResult(otherList); + npsCaseTestDataDto.setIsDetected(isOk);//1是检出,0是未检出 + npsCaseTestDataDto.setWhetherCheckOut(isOk == 1 ? + TestRecordSampleDataConstant.CHECK_OUT + npsCaseTestDataDto.getCompoundName() : + TestRecordSampleDataConstant.NOT_CHECK_OUT + npsCaseTestDataDto.getCompoundName()); + npsCaseTestDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE); + } else { + npsCaseTestDataDto.setTargetRtTime(-999);//设置样品的保留时间 + npsCaseTestDataDto.setStdRtTime(-999); + npsCaseTestDataDto.setRtTimeError(-999); + npsCaseTestDataDto.setRtTimeWithinError("/"); + npsCaseTestDataDto.setIsDetected(0);//1是检出,0是未检出 + npsCaseTestDataDto.setWhetherCheckOut(TestRecordSampleDataConstant.NOT_CHECK_OUT + npsCaseTestDataDto.getCompoundName()); + npsCaseTestDataDto.setSampleType(TestRecordSampleDataConstant.SAMPLE_TYPE_ANALYTE); + } + } + return testRecordSampleDataList; + } + + @Resource + private RemoteDictDataService remoteDictDataService; + /** + * 根据化合物名称找出基峰的对应的数据 + * + * @param testSampleDataList + * @return 如果没找到 返回null + */ + private NPSTestDetailDataStruct getBasePeakMass(List testSampleDataList) { + NPSTestDetailDataStruct npsTestDetailDataStruct_Base = null; + R> r = remoteDictDataService.getDictDataListByDictType(TestRecordSampleDataConstant.COMPOUND_BASIC_PEAK); + if (r.getCode() == CommonConstants.FAIL) { + log.error(LocalDateTime.now() + "从字典中获取化合物基峰数据失败!"); + throw new RuntimeException(LocalDateTime.now() + "从字典中获取化合物基峰数据失败!"); + } + Map compoundBasicPeak = r.getData(); // 这里我们需要注意的是化合物基峰的值我们存储在备注里 + for (NPSTestDetailDataStruct npsTestDetailDataStruct : testSampleDataList) { + String compoundName = npsTestDetailDataStruct.getName();//化合物名称 + double massValue = compoundBasicPeak.containsKey(compoundName) ? Double.parseDouble(compoundBasicPeak.get(compoundName).getRemark()) : 0; + if (Double.parseDouble(npsTestDetailDataStruct.getMass()) == massValue) { + npsTestDetailDataStruct_Base = npsTestDetailDataStruct; + log.info("找到化合物 {} 的基峰质荷比(mz)是 {}", compoundName, npsTestDetailDataStruct_Base); + break; + } + } + return npsTestDetailDataStruct_Base; + } + + //设置是否在误差范围内 + private String getWithinErrorText(double actualValue, double expectedValue) { + if (actualValue < expectedValue) { + return TestRecordSampleDataConstant.IS; + } else { + return TestRecordSampleDataConstant.NO; + } + } + + //判断保留时间范围是否符合 + private String getRtWithinErrorText(double targetRtErr, double errorRange) { + if (targetRtErr < errorRange) { + return TestRecordSampleDataConstant.IS; + } else { + return TestRecordSampleDataConstant.NO; + } + + } + + //查找标准品的保留时间 + private double findStdRtTime(String compoundName, List testRecordSampleDataList_std) { + List retStd = testRecordSampleDataList_std.stream() + .filter(item -> item.getCompoundName() + .equals(compoundName)).collect(Collectors.toList()); + + if (retStd.size() > 0) { + return retStd.get(0).getStdRtTime(); + } else { + log.info("没有找到化合物是{}的标准溶液,请核查参数是否准确", compoundName); + return -1; + } + } + + /** + * 计算丰度比偏差 + * + * @param sampleAbundanceRatio + * @param sampleAbundanceRatio_std + * @return + */ + private double getAbundanceRatioErrorValue(double sampleAbundanceRatio, double sampleAbundanceRatio_std) { + double diffValue = sampleAbundanceRatio - sampleAbundanceRatio_std; + double abundanceRatioErrorValue = Math.abs(diffValue) / sampleAbundanceRatio_std * 100; + return abundanceRatioErrorValue; + } + + /** + * 获取碎片的丰度比偏差范围 + * + * @param abundanceRatio + * @return + */ + private double getErrorRange(double abundanceRatio) { + double retValue = 0; + if (abundanceRatio > 0.5) { + retValue = 10; + } else if (abundanceRatio > 0.2) { + retValue = 15; + } else if (abundanceRatio > 0.1) { + retValue = 20; + } else { + retValue = 50; + } + return retValue; + } + + private double getStdCorrespondingAbundanceRatio(String massValue, String compoundName, List testRecordSampleDataList_std) { + double retValue = 0; + //根据化合物名称找出对应的标准品 + List std = testRecordSampleDataList_std.stream() + .filter(item -> item.getCompoundName().equals(compoundName)).collect(Collectors.toList()); + NPSCaseTestDataDto std_NPSCaseTestDataDto = null; + for (NPSCaseTestDataDto item : testRecordSampleDataList_std) { + if (item.getCompoundName().equals(compoundName)) { + std_NPSCaseTestDataDto = item; + break; + } + } + for (NPSTestDetailDataStruct npsTestDetailDataStruct : std_NPSCaseTestDataDto.getTestSampleDataList()) { + if (Double.parseDouble(npsTestDetailDataStruct.getMass()) == Double.parseDouble(massValue)) { + retValue = npsTestDetailDataStruct.getAbundanceRatio(); + } + } + return retValue; + } + + //TestRecordSampleData 与NPSCaseTestDataDto的转换 + private NPSCaseTestDataDto testRecordSampleDataToPSCaseTestDataDto(TestRecordSampleData testRecordSampleData) { + JSONObject jsonObject = (JSONObject) JSONObject.parse(testRecordSampleData.getDataResultJson()); + NPSCaseTestDataDto npsCaseTestDataDto = JSONObject.toJavaObject(jsonObject, NPSCaseTestDataDto.class); + return npsCaseTestDataDto; + } + + private int checkOtherFragmentResult(List npsTestDetailDataStructList) { + int ret = 1; + + for (NPSTestDetailDataStruct npsTestDetailDataStruct : npsTestDetailDataStructList) { + if (npsTestDetailDataStruct.getWithinError().equals(TestRecordSampleDataConstant.NO)) { + ret = 0; + } + } + return ret; + } + + /** + * 封装根据类的类型去组装数据 + * + * @param list + * @param retList + * @param clazz + * @param + */ + private void extractedSampleTestData(List list, List retList, Class clazz) { + for (TestRecordSampleData testRecordSampleData : list) { + retList.add(testRecordSampleDataToPSCaseTestDataDto(testRecordSampleData, clazz)); + } + } + + /** + * 获取TestRecordSampleData中的dataResultJson 转换成指定的对象 + * + * @param testRecordSampleData + * @param clazz + * @param + * @return + */ + private T testRecordSampleDataToPSCaseTestDataDto(TestRecordSampleData testRecordSampleData, Class clazz) { + JSONObject jsonObject = (JSONObject) JSONObject.parse(testRecordSampleData.getDataResultJson()); + jsonObject.put("testSampleDataId", testRecordSampleData.getId()); + // 对小数进行保留两位小数的操作 + DecimalFormat df = new DecimalFormat("#.##"); + jsonObject.put("rtTimeError", df.format(jsonObject.getDouble("rtTimeError"))); + jsonObject.put("compoundCnName", testRecordSampleData.getCompoundCnName()); + return JSONObject.toJavaObject(jsonObject, clazz); + } + + /** + * 检验数据类型转换 + * + * @param retList + * @return + */ + private List typeCasting(List retList) { + List collect = retList.stream().map(item -> { + if (item instanceof HairSewageDataDto) { + return (HairSewageDataDto) item; + } else if (item instanceof NPSCaseTestDataDto) { + return (NPSCaseTestDataDto) item; + } else { + // todo 待处理的任务dto + return item; + } + }).collect(Collectors.toList()); + return collect; + } + + /** + * 生成审核任务列表的头部名称json数组 + * + * @param dataGroupBySampleNoMap + * @return + */ + private JSONArray generateHeaderArray(LinkedHashMap> dataGroupBySampleNoMap) { + JSONArray headerArray = new JSONArray(); + AtomicBoolean finish = new AtomicBoolean(false); + + dataGroupBySampleNoMap.forEach((sampleNo, dataList) -> { + if (!finish.get()) { + headerArray.add(createHeaderObject("sampleNo", "溶液编号", true)); + headerArray.add(createHeaderObject("taskName", "案件/任务名称", false)); + headerArray.add(createHeaderObject("businessTypeName", "业务类型", false)); + headerArray.add(createHeaderObject("statusName", "状态", false)); + + IntStream.range(0, dataList.size()) + .forEach(i -> headerArray + .add(createHeaderObject( + "compound" + (i + 1), + "化合物" + "(" + dataList.get(i).getCompoundName() + ")", + false))); + finish.set(true); + } + }); + + return headerArray; + } + + /** + * 创建列表头名称json + * + * @param prop + * @param label + * @param fixed + * @return + */ + private JSONObject createHeaderObject(String prop, String label, boolean fixed) { + JSONObject object = new JSONObject(); + object.put(TestRecordSampleDataConstant.PROP, prop); + object.put(TestRecordSampleDataConstant.LABEL, label); + if (fixed) { + object.put("fixed", true); + } + return object; + } + + /** + * 组装具体的检验数据 + * + * @param dataGroupBySampleNoMap + * @return + */ + private JSONArray generateDataArray(LinkedHashMap> dataGroupBySampleNoMap) { + JSONArray dataArray = new JSONArray(); + + dataGroupBySampleNoMap.forEach((sampleNo, dataList) -> { + JSONObject dataObject = new JSONObject(); + dataObject.put("sampleNo", sampleNo); + + dataList.forEach(taskTestDataDTO -> { + dataObject.put("taskName", taskTestDataDTO.getTaskName()); + dataObject.put("businessTypeName", BusinessType.getBusinessTypeName(taskTestDataDTO.getBusinessType())); + dataObject.put("status", taskTestDataDTO.getStatus()); + dataObject.put("statusName", TaskTestDataStatus.getStatusNameByCode(taskTestDataDTO.getStatus())); + IntStream.range(0, dataList.size()) + .forEach(i -> dataObject.put("compound" + (i + 1), dataList.get(i).getSampleConcentration())); + }); + + dataArray.add(dataObject); + }); + + return dataArray; + } + + + /** + * 手动分页方法 + * + * @param dataList + * @param current + * @param size + * @return + */ + private Page getPageData(JSONArray dataList, int current, int size) { + int fromIndex = (current - 1) * size; + if (fromIndex >= dataList.size()) { + return new Page<>(); // 如果起始索引超出数据范围,返回空page + } + int toIndex = Math.min(fromIndex + size, dataList.size()); + Page page = new Page<>(); + page.setCurrent(current); + page.setSize(size); + page.setRecords(dataList.subList(fromIndex, toIndex)); + page.setTotal(dataList.size()); + return page; + } + + /** + * 生成查询条件 + * + * @param pageDTO + * @return + */ + private QueryWrapper generateTaskTestDataQW(TaskTestDataPageDTO pageDTO) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByDesc("ti.create_time").orderByDesc("ss.sample_no"); + queryWrapper.and(StrUtil.isNotBlank(pageDTO.getKeyword()), + wrapper -> + wrapper + .like("ti.task_name", pageDTO.getKeyword()) + .or() + .like("si.sample_name", pageDTO.getKeyword()) + .or() + .like("ss.sample_no", pageDTO.getKeyword())); + queryWrapper.eq(StrUtil.isNotBlank(pageDTO.getBusinessType()), "ti.business_type", pageDTO.getBusinessType()); + if (pageDTO.getStatus().equals(TaskTestDataStatus.REVIEWED.getCode())) { + // 任务审核列表,查询待审核的数据返回 + queryWrapper.eq("rs.status", TaskTestDataStatus.WAIT_REVIEW.getCode()); + } else if (pageDTO.getStatus().equals(TaskTestDataStatus.APPROVED.getCode())) { + // 任务审批列表,查询待审批的数据返回 + queryWrapper.eq("rs.status", TaskTestDataStatus.REVIEWED.getCode()); + } + return queryWrapper; + } + + /** + * 生成查询条件 + * + * @param dto + * @param businessIdList + * @return + */ + private QueryWrapper generateQueryWrapperByDTO(QueryTestResultPageDTO dto, Set businessIdList) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + // 获取查询的关键字字段 + String keyword = dto.getKeyword(); + queryWrapper.in("T.id", businessIdList); + queryWrapper.eq("T.type", dto.getType()); + queryWrapper.ge("T.status", 3); + // 如果创建人不为空,则查询该创建人的任务 + queryWrapper.eq(StrUtil.isNotBlank(dto.getCreateBy()), "T.create_by", dto.getCreateBy()) + .and(StrUtil.isNotBlank(keyword), wrapper -> + wrapper.like("T.case_name", keyword)); + // 时间范围查询,包含开始时间和结束时间 + queryWrapper.ge(dto.getStartTime() != null, "T.create_time", dto.getStartTime()) + .le(dto.getEndTime() != null, "T.create_time", dto.getEndTime()); + // 根据创建时间进行排序 + if (dto.getType().equals(20000)) { + queryWrapper.orderByDesc("T.task_start_date"); + } else { + queryWrapper.orderByDesc("T.create_time"); + } + return queryWrapper; + } + + /** + * 拼接定性结果,检出或未检出的字符串 + * + * @param existingResult + * @param newResult + * @return + */ + private String appendCheckOutResult(String existingResult, String newResult) { + return StrUtil.isBlank(existingResult) ? newResult : existingResult + "、" + newResult; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleSolutionServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleSolutionServiceImpl.java new file mode 100644 index 0000000..101a787 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordSampleSolutionServiceImpl.java @@ -0,0 +1,371 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.dto.TestRecordSampleSolutionDto; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import digital.laboratory.platform.inspection.entity.SampleInjector; +import digital.laboratory.platform.inspection.entity.TestRecordSampleSolution; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordSampleSolutionMapper; +import digital.laboratory.platform.inspection.service.SampleInfoService; +import digital.laboratory.platform.inspection.service.SampleInjectorService; +import digital.laboratory.platform.inspection.service.TestRecordSampleSolutionService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.sys.feign.RemoteBalanceRMaterialService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@SuppressWarnings("all") +public class TestRecordSampleSolutionServiceImpl extends ServiceImpl implements TestRecordSampleSolutionService { + + @Resource + private RemoteBalanceRMaterialService remoteBalanceRMaterialService; + + @Resource + private TestRecordService testRecordService; + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private TestRecordMapper testRecordMapper; + + @Resource + private SampleInjectorService sampleInjectorService; + + /** + * 新增样本溶液 + * + * @param testRecordSampleSolutionDto + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public TestRecordSampleSolution addTestRecordSampleSolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + TestRecordSampleSolution testRecordSampleSolution = new TestRecordSampleSolution(); + BeanUtils.copyProperties(testRecordSampleSolutionDto, testRecordSampleSolution); + SampleInfo sampleInfo = sampleInfoService.getById(testRecordSampleSolutionDto.getMaterialId()); + testRecordSampleSolution.setSampleShape(sampleInfo.getForm()); + testRecordSampleSolution.setId(IdWorker.get32UUID().toUpperCase()); + testRecordSampleSolution.setSampleNo(this.createSampleNo(testRecordSampleSolutionDto.getMaterialId(), testRecordSampleSolutionDto.getTestId()));//获取编号 +// SampleInfo sampleInfo = sampleInfoService.getOne(Wrappers.lambdaQuery().eq(SampleInfo::getAcceptNo, testRecordSampleSolutionDto.getSampleNo())); +// if (sampleInfo == null) { +// throw new RuntimeException(String.format("没有找到编号为%s的样本!", testRecordSampleSolutionDto.getSampleNo())); +// } + //计算浓度 + testRecordSampleSolution = this.calculatedConcentration(testRecordSampleSolution); + Integer opCode = 1;//代表是向实验添加溶液 + boolean ret = testRecordService.updateTestRecordArgument(testRecordSampleSolution.getTestId(), testRecordSampleSolution.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_SAMPLE_SOLUTION.getType(), opCode); + return this.save(testRecordSampleSolution) && ret ? testRecordSampleSolution : null; + } + + /** + * 创建编号 + * + * @param testRecordSampleSolutionDto + * @return + */ + public String createSampleNo(String materialId, String testId) { + SampleInfo sampleInfo = sampleInfoService.getById(materialId); + String acceptNo = sampleInfo.getAcceptNo(); + + //根据这个样本在实验中创建为溶液的次数来生成后缀,以便能自动匹配称量数据 + List list = this.list(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getMaterialId, materialId)); + + if (list == null || list.size() == 0) { + return acceptNo; + } else if (list != null && list.size() == 1) { + //判断是否已上样 + this.isLoadSample(acceptNo, testId); + //选中同一样本创建第二个溶液时,要将第一个溶液的编号后缀修改为-1 + TestRecordSampleSolution testRecordSampleSolution = list.get(0); + testRecordSampleSolution.setSampleNo(acceptNo + "-1"); + this.updateById(testRecordSampleSolution); + return acceptNo + "-2"; + } else { + return acceptNo + "-" + (list.size() + 1); + } + + } + + /** + * 删除样本溶液 + * + * @param id + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean delTestRecordSampleSolution(String id) { + TestRecordSampleSolution oldTestRecordSampleSolution = this.getOne(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getId, id)); + Integer opCode = -1;//代表向实验删除这个溶液 + if (oldTestRecordSampleSolution == null) { + throw new RuntimeException(String.format("没有找到ID为%s的样本溶液!", id)); + } + this.isLoadSample(oldTestRecordSampleSolution.getSampleNo(), oldTestRecordSampleSolution.getTestId()); + List list = this.list(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getMaterialId, oldTestRecordSampleSolution.getMaterialId())); + if (list.size() == 2) { + list.remove(oldTestRecordSampleSolution); + TestRecordSampleSolution testRecordSampleSolution = list.get(0); + String sampleNo = testRecordSampleSolution.getSampleNo(); + this.isLoadSample(sampleNo, testRecordSampleSolution.getTestId()); + int lastInde = sampleNo.lastIndexOf("-"); + String newSampleNo = sampleNo.substring(0, lastInde); + testRecordSampleSolution.setSampleNo(newSampleNo); + this.updateById(testRecordSampleSolution); + } + boolean ret = testRecordService.updateTestRecordArgument(oldTestRecordSampleSolution.getTestId(), oldTestRecordSampleSolution.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_SAMPLE_SOLUTION.getType(), opCode); + return this.removeById(id) && ret; + } + + /** + * 修改样本溶液 + * + * @param testRecordSampleSolutionDto + * @return + */ + @Override + public TestRecordSampleSolution updateTestRecordSampleSolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + TestRecordSampleSolution oldTestRecordSampleSolution = this.getOne(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getId, testRecordSampleSolutionDto.getId())); + if (oldTestRecordSampleSolution == null) { + throw new RuntimeException(String.format("没有找到ID为%s的样本溶液!", testRecordSampleSolutionDto.getId())); + } + BeanUtils.copyProperties(testRecordSampleSolutionDto, oldTestRecordSampleSolution); + //计算浓度 + oldTestRecordSampleSolution = this.calculatedConcentration(oldTestRecordSampleSolution); + return this.updateById(oldTestRecordSampleSolution) ? oldTestRecordSampleSolution : null; + } + + /** + * 计算浓度 + * + * @param testRecordSampleSolution + * @return + */ + public TestRecordSampleSolution calculatedConcentration(TestRecordSampleSolution testRecordSampleSolution) { + //计算原始浓度 + if (StrUtil.isNotBlank(testRecordSampleSolution.getWeighingValue())) { + BigDecimal weighingValue = new BigDecimal(testRecordSampleSolution.getWeighingValue()); + BigDecimal constantVolume = new BigDecimal(testRecordSampleSolution.getConstantVolume()); + BigDecimal originalConcentration = weighingValue.divide(constantVolume, 2, RoundingMode.HALF_UP); + testRecordSampleSolution.setOriginalConcentration(originalConcentration.toString()); + } + + //计算结果浓度 + if (StrUtil.isNotBlank(testRecordSampleSolution.getOriginalConcentration()) && StrUtil.isNotBlank(testRecordSampleSolution.getDilutionFactor()) && !testRecordSampleSolution.getDilutionFactor().equals("/")) { + BigDecimal originalConcentration = new BigDecimal(testRecordSampleSolution.getOriginalConcentration()); + BigDecimal dilutionFactor = new BigDecimal(testRecordSampleSolution.getDilutionFactor()); + BigDecimal resultConcentration = originalConcentration.divide(dilutionFactor, 2, RoundingMode.HALF_UP); + testRecordSampleSolution.setResultConcentration(resultConcentration.toString()); + } + return testRecordSampleSolution; + } + + /** + * 列表查询 + * + * @param testId + * @param keywords 样本编号模糊查询 + * @return + */ + @Override + public List getSolutionList(String testId, String keywords) { + return this.list(Wrappers.lambdaQuery() + .eq(TestRecordSampleSolution::getTestId, testId) + .like(StrUtil.isNotBlank(keywords), TestRecordSampleSolution::getSampleNo, keywords) + .orderByAsc(TestRecordSampleSolution::getSampleNo)); + } + + /** + * 分页查询 + * + * @param testId + * @param page + * @param keywords 样本编号模糊查询 + * @return + */ + @Override + public IPage getSolutionPage(Page page, String testId, String keywords) { + return this.page(page, Wrappers.lambdaQuery() + .eq(TestRecordSampleSolution::getTestId, testId) + .like(StrUtil.isNotBlank(keywords), TestRecordSampleSolution::getSampleNo, keywords) + .orderByAsc(TestRecordSampleSolution::getSampleNo)); + } + + /** + * ] + * 匹配称量数据 + * + * @param id + * @return + */ + @Override + public List matchingWeighing(String id) { + List testRecordSampleSolutionList = this.list(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getTestId, id)); + if (testRecordSampleSolutionList.size() == 0) { + throw new RuntimeException(String.format("没有找到ID为%s的实验!", id)); + } + Map> map = testRecordSampleSolutionList.stream().collect(Collectors.groupingBy(item -> item.getMaterialId())); + + List sampleSolutions = new ArrayList<>(); + Set keySet = map.keySet(); + + List idList = new ArrayList<>(); + for (String key : keySet) { + List solutionList = map.get(key); + if (solutionList.size() == 1) { + TestRecordSampleSolution solution = solutionList.get(0); + idList.add(solution.getId()); + } + sampleSolutions.addAll(solutionList); + } + + //如果匹配到了称量质量,那么就自动去计算浓度 + for (TestRecordSampleSolution testRecordSampleSolution : sampleSolutions) { + String weighingNum = ""; + if (idList.contains(testRecordSampleSolution.getId())) { + weighingNum = testRecordSampleSolution.getSampleNo() + "-1"; + } else { + weighingNum = testRecordSampleSolution.getSampleNo(); + } + R data = remoteBalanceRMaterialService.getWeightForNumber(weighingNum); + BigDecimal weighing = data.getData(); + if (weighing.compareTo(BigDecimal.ZERO) != 0) { + //计算原始浓度 + testRecordSampleSolution.setWeighingValue(weighing.toString()); + BigDecimal constantVolume = new BigDecimal(testRecordSampleSolution.getConstantVolume()); + BigDecimal originalConcentration = weighing.divide(constantVolume, 2, RoundingMode.HALF_UP); + testRecordSampleSolution.setOriginalConcentration(originalConcentration.toString()); + //计算结果浓度 + if (StrUtil.isNotBlank(testRecordSampleSolution.getDilutionFactor())) { + BigDecimal dilutionFactor = new BigDecimal(testRecordSampleSolution.getDilutionFactor()); + BigDecimal resultConcentration = originalConcentration.divide(dilutionFactor, 2, RoundingMode.HALF_UP); + testRecordSampleSolution.setResultConcentration(resultConcentration.toString()); + } else { + testRecordSampleSolution.setResultConcentration(originalConcentration.toString()); + } + } + } + return this.updateBatchById(testRecordSampleSolutionList) ? testRecordSampleSolutionList : null; + } + + /** + * 为任务创建所有检材对应的样本溶液 + * + * @param testId + * @return + */ + @Override + public boolean createTaskSamSol(String testId) { + TestRecordVo vo = testRecordMapper.getTestRecordMapById(testId); + if (StringUtils.isNotBlank(vo.getBusinessType()) && !vo.getBusinessType().startsWith("2")) { + return true; + } + List sampleSolutionList = new ArrayList<>(); + List sampleTestList = vo.getSampleTestList(); + this.remove(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getTestId, testId)); + if (sampleTestList != null && sampleTestList.size() > 0) { + List solutions = new ArrayList<>(); + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().in(SampleInfo::getId, sampleTestList)); + for (SampleInfo sampleInfo : sampleInfoList) { + TestRecordSampleSolution testRecordSampleSolution = new TestRecordSampleSolution(); + testRecordSampleSolution.setId(IdWorker.get32UUID().toUpperCase()); + testRecordSampleSolution.setSampleNo(sampleInfo.getAcceptNo()); + testRecordSampleSolution.setMaterialId(sampleInfo.getId()); + testRecordSampleSolution.setTestId(vo.getId()); + testRecordSampleSolution.setSampleShape("/"); + testRecordSampleSolution.setDilutionName("/"); + testRecordSampleSolution.setConstantVolume("0.0"); + testRecordSampleSolution.setDilutionFactor("0"); + testRecordSampleSolution.setOriginalConcentration("/"); + testRecordSampleSolution.setResultConcentration("/"); + testRecordSampleSolution.setWeighingValue("/"); + solutions.add(testRecordSampleSolution); + sampleSolutionList.add(testRecordSampleSolution.getId()); + } + vo.setSampleSolution(sampleSolutionList); + testRecordService.updateById(vo); + return this.saveBatch(solutions); + } else return true; + } + + /* + * 复制样品溶液 + * + * @param testRecordSampleSolutionDto + * @return + */ + @Override + public List copySolution(TestRecordSampleSolutionDto testRecordSampleSolutionDto) { + TestRecordSampleSolution sampleSolution = this.getById(testRecordSampleSolutionDto.getId()); + List materialIdList = testRecordSampleSolutionDto.getMaterialIdList(); + ArrayList testRecordSampleSolutions = new ArrayList<>(); + TestRecordVo vo = testRecordMapper.getTestRecordMapById(sampleSolution.getTestId()); + List solutionIdList = new ArrayList<>(); + for (String id : materialIdList) { + SampleInfo sampleInfo = sampleInfoService.getById(id); + String acceptNo = sampleInfo.getAcceptNo(); + String sampleNo = this.createSampleNo(id, testRecordSampleSolutionDto.getTestId()); + TestRecordSampleSolution testRecordSampleSolution = new TestRecordSampleSolution(); + BeanUtils.copyProperties(sampleSolution, testRecordSampleSolution); + testRecordSampleSolution.setCreateBy(null); + testRecordSampleSolution.setUpdateBy(null); + testRecordSampleSolution.setCreateTime(null); + testRecordSampleSolution.setUpdateTime(null); + testRecordSampleSolution.setId(IdWorker.get32UUID().toUpperCase()); + testRecordSampleSolution.setSampleNo(sampleNo); + testRecordSampleSolution.setMaterialId(id); + testRecordSampleSolution.setSampleShape(sampleInfo.getForm()); + testRecordSampleSolutions.add(testRecordSampleSolution); + solutionIdList.add(testRecordSampleSolution.getId()); + } + List voSampleSolution = vo.getSampleSolution(); + voSampleSolution.addAll(solutionIdList); + vo.setSampleSolution(voSampleSolution); + if (this.saveBatch(testRecordSampleSolutions) && testRecordService.updateById(vo)) { + return testRecordSampleSolutions; + } else return null; + } + + @Override + public void isLoadSample(String acceptNo, String testId) { + SampleInjector sampleInjector = sampleInjectorService.getOne(Wrappers.lambdaQuery().eq(SampleInjector::getTestId, testId)); + if (sampleInjector == null) { + return; + } + String injectorInfo = sampleInjector.getInjectorInfo(); + if (injectorInfo == null) { + return; + } + JSONArray jsonArray = JSON.parseArray(injectorInfo); + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + if (jsonObject.getString("sampleNo").equals(acceptNo)) { + throw new RuntimeException(String.format("编号为:%s的溶液已存在上样记录,请先修改上样记录后再进行操作!", acceptNo)); + } + } + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java new file mode 100644 index 0000000..f545294 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordServiceImpl.java @@ -0,0 +1,1529 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.file.FileNameUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy; +import com.deepoove.poi.util.TableTools; +import com.deepoove.poi.xwpf.NiceXWPFDocument; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.BusinessType; +import digital.laboratory.platform.inspection.constant.TestRecordFileUrl; +import digital.laboratory.platform.inspection.constant.TestRecordSampleDataConstant; +import digital.laboratory.platform.inspection.dto.*; +import digital.laboratory.platform.inspection.entity.*; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.*; +import digital.laboratory.platform.inspection.utils.PageUtils; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct; +import digital.laboratory.platform.inspection.vo.ProcedureVo; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import digital.laboratory.platform.inspetion.api.entity.EntrustInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.poi.xwpf.usermodel.*; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.ByteArrayInputStream; +import java.text.DecimalFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +@SuppressWarnings("all") +public class TestRecordServiceImpl extends ServiceImpl implements TestRecordService { + + @Resource + private SampleInfoService sampleInfoService; + + @Resource + private TestRecordMethodService testRecordMethodService; + + @Resource + private TestTemplateMapper testTemplateMapper; + + @Resource + private TestRecordInstrumentConditionService testRecordInstrumentConditionService; + + @Resource + private TestRecordReagentService testRecordReagentService; + + @Resource + private TestRecordInstrumentService testRecordInstrumentService; + + @Resource + private TestRecordStandardSolutionService testRecordStandardSolutionService; + + @Resource + private TestRecordSampleSolutionService testRecordSampleSolutionService; + + @Resource + private TestRecordSampleDataService testRecordSampleDataService; + + + @Resource + private OssFile ossFile; + @Resource + private EntrustInfoService entrustInfoService; + + @Resource + private SampleInjectorService sampleInjectorService; + + @Resource + private TestRecordSampleDataMapper testRecordSampleDataMapper; + + /** + * 创建一个实验 + * + * @param testRecord + * @param dlpUser 用户信息 + * @return + * @throws Exception + */ + @Transactional(rollbackFor = Exception.class) + @Override + public TestRecord createTestInstance(TestRecordDto testRecord, DLPUser dlpUser) throws Exception { + testRecord.setId(IdWorker.get32UUID().toUpperCase()); + List sampleInfos = new ArrayList<>(); + testRecord.setStatus(0); + // 设置开始时间 + testRecord.setTestStartDate(LocalDate.now()); + //通过样本ID创建实验 + if (testRecord.getSampleTestList() != null && testRecord.getSampleTestList().size() > 0) { + for (String sampleId : testRecord.getSampleTestList()) { + SampleInfo sampleInfo = sampleInfoService.getById(sampleId); + if (sampleInfo == null) { + throw new RuntimeException(String.format("没有找到ID为%s的样本!", sampleId)); + } + sampleInfo.setStatus(2); + sampleInfos.add(sampleInfo); + } + this.judgmentSampleType(sampleInfos);//判断是否有不同类型的检材 + testRecord.setId(IdWorker.get32UUID().toUpperCase()); + testRecord.setTestUserId(dlpUser.getId()); + testRecord.setTestSerialNumber(this.createTestNumber()); + testRecord.setBusinessType(sampleInfos.get(0).getBusinessType()); + + sampleInfoService.updateBatchById(sampleInfos);//更新检材状态 + return this.save(testRecord) ? testRecord : null; + + //通过业务ID创建实验 + } else if (testRecord.getBusinessDtoList() != null && testRecord.getBusinessDtoList().size() > 0) { + List businessDtoList = testRecord.getBusinessDtoList(); + this.judgmentBusinessType(businessDtoList);//判断是否有不同类型的业务 + businessDtoList.forEach(item -> { + List infos = sampleInfoService.getSampleInfoListForBusiness(item.getBusinessId(), dlpUser.getId()); + String businessType = item.getBusinessType(); + //如果是委托,需要更新一下委托的状态 + if (businessType.startsWith("1")) { + entrustInfoService.update(Wrappers.lambdaUpdate() + .eq(EntrustInfo::getId, item.getBusinessId()) + .set(EntrustInfo::getStatus, 1)); + } + sampleInfos.addAll(infos); + + }); + List sampleIdList = new ArrayList<>(); + if (sampleInfos.size() > 0) { + for (SampleInfo sampleInfo : sampleInfos) { + sampleIdList.add(sampleInfo.getId()); + sampleInfo.setStatus(2); + } + sampleInfoService.updateBatchById(sampleInfos); + } + testRecord.setTestUserId(dlpUser.getId()); + testRecord.setTestSerialNumber(this.createTestNumber()); + testRecord.setSampleTestList(sampleIdList); + testRecord.setBusinessType(testRecord.getBusinessDtoList().get(0).getBusinessType()); + + return this.save(testRecord) ? testRecord : null; + //创建空实验 + } else { + testRecord.setId(IdWorker.get32UUID().toUpperCase()); + testRecord.setTestUserId(dlpUser.getId()); + testRecord.setTestSerialNumber(this.createTestNumber()); + return this.save(testRecord) ? testRecord : null; + } + } + + /** + * 判断是否有不同类型的业务 + * + * @param businessDtoList : 业务集合 + */ + public void judgmentBusinessType(List businessDtoList) { + Map> map = businessDtoList.stream().collect(Collectors.groupingBy(item -> item.getBusinessType())); + if (map.keySet().size() > 1) { + throw new RuntimeException(String.format("实验创建失败,请选择相同类型的业务进行实验!")); + } + if (businessDtoList.get(0).getBusinessType().startsWith("1")) { + businessDtoList.forEach(item -> { + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, item.getBusinessId())); + EntrustInfo entrustInfo = entrustInfoService.getById(item.getBusinessId()); + sampleInfoList.forEach(obj -> { + TestRecord record = this.getOne(Wrappers.lambdaQuery().like(TestRecord::getSampleTestList, obj.getId())); + if (record != null) { + throw new RuntimeException(String.format("%s中的其余检材已进行了编号为" + record.getTestSerialNumber() + "的实验,无法继续选择该委托!" + record.getId(), entrustInfo.getCaseName())); + } + }); + }); + } + } + + /** + * 判断是否有不同类型的检材 + * + * @param sampleInfoList : 检材集合 + */ + public void judgmentSampleType(List sampleInfoList) { + Map> map = sampleInfoList.stream().collect(Collectors.groupingBy(item -> item.getBusinessType())); + if (map.keySet().size() > 1) { + throw new RuntimeException(String.format("实验创建失败,请选择相同类型的检材进行实验!")); + } + String businessType = ""; + if (sampleInfoList.get(0).getBusinessType().startsWith("1")) { + Map> map1 = sampleInfoList.stream().collect(Collectors.groupingBy(item -> item.getBusinessId())); + Set keySet = map1.keySet(); + keySet.forEach(item -> { + EntrustInfo entrustInfo = entrustInfoService.getById(item); + List list = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, item)); + List list1 = map1.get(item); + if (list.size() != list1.size()) { + throw new RuntimeException(String.format("没有选择完%s下的所有检材!", entrustInfo.getCaseName())); + } + }); + } + } + + /** + * 使用模板 + * + * @param testRecord : 实验对象 + * @param templateId : 模板Id + */ + public void copyFromTemplate(TestRecord testRecord, String templateId) throws Exception { + //将模板内容赋值给实验 + TestTemplateVo testTemplateVo = testTemplateMapper.getTestTemplateMapById(templateId); + if (testTemplateVo.getUseCount() == null || testTemplateVo.getUseCount() == 0) { + testTemplateVo.setUseCount(1); + } else { + testTemplateVo.setUseCount(testTemplateVo.getUseCount() + 1); + } + //复制方法 + if (testTemplateVo.getTestMethods() != null && testTemplateVo.getTestMethods().size() > 0) { + testRecord.setTestMethodList(testTemplateVo.getTestMethods()); + } + //复制仪器设备 + if (testTemplateVo.getDeviceIdList() != null && testTemplateVo.getDeviceIdList().size() > 0) { + testRecord.setDeviceIdList(testTemplateVo.getDeviceIdList()); + } + //复制仪器设备条件 + if (testTemplateVo.getDeviceUseCondition() != null && testTemplateVo.getDeviceUseCondition().size() > 0) { + List idList = testRecordInstrumentConditionService.copyCondition(testTemplateVo.getDeviceUseCondition(), testRecord.getId()); + testRecord.setDeviceUseCondition(idList); + } + //复制试剂耗材 + if (testTemplateVo.getReagentConsumables() != null && testTemplateVo.getReagentConsumables().size() > 0) { + testRecord.setReagentConsumablesList(testTemplateVo.getReagentConsumables()); + } + //复制仪器条件Word + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ossFile.fileGet(TestRecordFileUrl.TEST_TEMPLATE_CATALOGUE.getFileUrl() + "/" + templateId + "/" + "仪器条件.docx", bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + ossFile.fileSave(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testRecord.getId() + "/" + "仪器条件.docx", bis); + testRecord.setTemplateName(testTemplateVo.getName()); + testTemplateMapper.updateById(testTemplateVo); + this.updateById(testRecord); + } + + /** + * 添加实验处理步骤 + * + * @param testRecord + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public TestRecord updateTestInstance(TestRecord testRecord) { + TestRecord record = this.getById(testRecord.getId()); + //样本溶液处理步骤 + if (StrUtil.isNotBlank(testRecord.getSampleSolutionProcessing())) { + record.setSampleSolutionProcessing(testRecord.getSampleSolutionProcessing()); + } else { + record.setSampleSolutionProcessing(""); + } + //标准溶液处理步骤 + if (StrUtil.isNotBlank(testRecord.getStandardSolutionProcessing())) { + record.setStandardSolutionProcessing(testRecord.getStandardSolutionProcessing()); + } else { + record.setStandardSolutionProcessing(""); + } + if (StringUtils.isNotBlank(testRecord.getTestProcessDes())) { + record.setTestProcessDes(testRecord.getTestProcessDes()); + } + return this.updateById(record) ? record : null; + } + + /** + * 通过实验ID查看实验 + * + * @param id + * @param dlpUser 用户信息 + * @return + */ + @Override + public TestRecordVo getTestRecord(String id, DLPUser dlpUser) { + TestRecordVo testRecordVo = baseMapper.getTestRecordMapById(id); + if (testRecordVo.getTestMethodList() != null && testRecordVo.getTestMethodList().size() > 0) { + this.getTestMethodName(testRecordVo); + } + if (StringUtils.isNotBlank(testRecordVo.getBusinessType())) { + testRecordVo.setBusinessTypeName(BusinessType.getBusinessTypeName(testRecordVo.getBusinessType())); + } + //需要判断这个实验是否由操作者创建的 + return testRecordVo.getTestUserId().equals(dlpUser.getId()) ? testRecordVo : null; + } + + /** + * 获取实验的方法名集合 + * + * @param testRecordVo + */ + public void getTestMethodName(TestRecordVo testRecordVo) { + List testMethodName = new ArrayList(); + List list = testRecordMethodService.list(Wrappers.lambdaQuery().in(TestRecordMethod::getId, testRecordVo.getTestMethodList())); + if (list.size() > 0) { + for (TestRecordMethod testRecordMethod : list) { + testMethodName.add(testRecordMethod.getMethodName()); + } + } + testRecordVo.setTestMethodName(testMethodName); + } + + /** + * 分页查询实验 + * + * @param page + * @param dlpUser :实验创建者 + * @param startTime :时间范围查询 + * @param endTime :时间范围查询 + * @param businessType + */ + @Override + public IPage getTestRecordPageList(Page page, DLPUser dlpUser, LocalDateTime startTime, LocalDateTime endTime, String businessType) { + IPage testRecordMapPage = baseMapper.getTestRecordMapPage(page, Wrappers.lambdaQuery() + .eq(TestRecord::getTestUserId, dlpUser.getId()) + .ge(startTime != null, TestRecord::getCreateTime, startTime) + .le(endTime != null, TestRecord::getCreateTime, endTime) + .eq(StrUtil.isNotBlank(businessType), TestRecord::getBusinessType, businessType) + .orderByDesc(TestRecord::getCreateTime)); + for (TestRecordVo testRecordVo : testRecordMapPage.getRecords()) { + if (testRecordVo.getTestMethodList() != null && testRecordVo.getTestMethodList().size() > 0) { + this.getTestMethodName(testRecordVo); + } + if (StringUtils.isNotBlank(testRecordVo.getBusinessType())) { + testRecordVo.setBusinessTypeName(BusinessType.getBusinessTypeName(testRecordVo.getBusinessType())); + } + } + return testRecordMapPage; + } + + /** + * 列表查询实验 + * + * @param dlpUser 用户信息 + */ + @Override + public List getTestRecordList(DLPUser dlpUser) { + List testRecordMapList = baseMapper.getTestRecordMapList(Wrappers.lambdaQuery() + .eq(TestRecord::getTestUserId, dlpUser.getId()) + .orderByDesc(TestRecord::getCreateTime)); + for (TestRecordVo testRecordVo : testRecordMapList) { + if (StringUtils.isNotBlank(testRecordVo.getBusinessType())) { + testRecordVo.setBusinessTypeName(BusinessType.getBusinessTypeName(testRecordVo.getBusinessType())); + } + if (testRecordVo.getTestMethodList() != null && testRecordVo.getTestMethodList().size() > 0) { + this.getTestMethodName(testRecordVo); + } + } + return testRecordMapList; + } + + /** + * 编号生成规则 + * + * @return + */ + public String createTestNumber() { + String number = "SXT"; + LocalDateTime localDateTime = LocalDateTime.now(); + number = number + LocalDateTimeUtil.format(localDateTime, "yyyyMMdd"); + List list = this.list(Wrappers.lambdaQuery().likeRight(TestRecord::getTestSerialNumber, number)); + if (list.size() == 0) { + number = number + "001"; + return number; + } else { + //保留三位小数 + number = number + String.format("%03d", list.size() + 1); + return number; + } + } + + /** + * 为实验添加或移除内容 + * + * @param testId 实验Id + * @param testRecordArgumentId 参数Id + * @param argument 参数类型 + * @param opCode 判断是添加还是删除 1 :添加 -1 :删除 + * @return + */ + @Override//opCode: + public boolean updateTestRecordArgument(String testId, String testRecordArgumentId, String argument, Integer opCode) { + TestRecord testRecord = baseMapper.getTestRecordMapById(testId); + List argumentIdList = new ArrayList<>(); + if (testRecord == null) { + throw new RuntimeException(String.format("没有找到ID为%s的实验", testId)); + } + + //添加或移除仪器设备 + if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType())) { + if (testRecord.getDeviceIdList() != null && testRecord.getDeviceIdList().size() > 0) { + argumentIdList = testRecord.getDeviceIdList(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setDeviceIdList(argumentIdList); + + //添加或移除仪器条件 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION.getType())) { + if (testRecord.getDeviceUseCondition() != null && testRecord.getDeviceUseCondition().size() > 0) { + argumentIdList = testRecord.getDeviceUseCondition(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setDeviceUseCondition(argumentIdList); + + + //添加或移除方法 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_METHOD.getType())) { + if (testRecord.getTestMethodList() != null && testRecord.getTestMethodList().size() > 0) { + argumentIdList = testRecord.getTestMethodList(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setTestMethodList(argumentIdList); + + //添加或移除试剂耗材 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_REAGENT.getType())) { + if (testRecord.getReagentConsumablesList() != null && testRecord.getReagentConsumablesList().size() > 0) { + argumentIdList = testRecord.getReagentConsumablesList(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setReagentConsumablesList(argumentIdList); + + //添加或移除样本溶液 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_SAMPLE_SOLUTION.getType())) { + if (testRecord.getSampleSolution() != null && testRecord.getSampleSolution().size() > 0) { + argumentIdList = testRecord.getSampleSolution(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setSampleSolution(argumentIdList); + + //添加或移除标准溶液 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_STANDARD_SOLUTION.getType())) { + if (testRecord.getStandardSolution() != null && testRecord.getStandardSolution().size() > 0) { + argumentIdList = testRecord.getStandardSolution(); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setStandardSolution(argumentIdList); + + //添加或移除样本 + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_SAMPLE_DATA.getType())) { + String businessType; + SampleInfo sampleInfo = sampleInfoService.getById(testRecordArgumentId); + businessType = sampleInfo.getBusinessType(); + //判断与实验的业务类型是否相同 + if (StringUtils.isNotBlank(testRecord.getBusinessType()) && !testRecord.getBusinessType().equals(businessType)) { + throw new RuntimeException(String.format("添加失败,请添加%s类型的样本!", BusinessType.getBusinessTypeName(testRecord.getBusinessType()))); + } + if (testRecord.getSampleTestList() != null && testRecord.getSampleTestList().size() > 0) { + //如果该实验已存在样本了,添加样本时就要判断是否为同一类型 + businessType = sampleInfoService.getById(testRecord.getSampleTestList().get(0)).getBusinessType(); + if (!businessType.equals(sampleInfo.getBusinessType())) { + throw new RuntimeException(String.format("添加失败,请添加相同类型的样本!")); + } + //添加检材时,需判是否已经存在其他实验选择了该检材相关的委托下其余的检材 + if (businessType.startsWith("1") && opCode == 1) { + this.addOrRemoveSample(sampleInfo.getBusinessId(), testId); + } + argumentIdList = testRecord.getSampleTestList(); + } else { + businessType = sampleInfo.getBusinessType(); + //添加检材时,需判是否已经存在其他实验选择了该检材相关的委托下其余的检材 + if (businessType.startsWith("1") && opCode == 1) { + this.addOrRemoveSample(sampleInfo.getBusinessId(), testId); + } + //如果是第一次添加检材,那么就给这个实验赋予这个检材的业务类型 + testRecord.setBusinessType(sampleInfo.getBusinessType()); + } + this.updateArgument(argumentIdList, opCode, testRecordArgumentId); + testRecord.setSampleTestList(argumentIdList); + } + return this.updateById(testRecord); + } + + /** + * 添加检材时,需判是否已经存在其他实验选择了该检材相关的委托下其余的检材 + * + * @param businessId + * @param testId + */ + public void addOrRemoveSample(String businessId, String testId) { + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId)); + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + sampleInfoList.forEach(item -> { + TestRecord record = this.getOne(Wrappers.lambdaQuery().like(TestRecord::getSampleTestList, item.getId())); + if (record != null && (!record.getId().equals(testId))) { + throw new RuntimeException(String.format("委托" + entrustInfo.getCaseName() + "中的其余检材已进行了编号为%s的实验,无法选择该检材!", record.getTestSerialNumber())); + } + }); + } + + /** + * 判断有没有向实验重复添加或者添加了无效的参数 + * + * @param argumentIdList 已添加的参数集合 + * @param opCode 1:添加 -1 移除 + * @param testRecordArgumentId 参数ID + */ + public void updateArgument(List argumentIdList, Integer opCode, String testRecordArgumentId) { + if (opCode == 1) { + if (argumentIdList.size() > 0 && argumentIdList.contains(testRecordArgumentId)) { + throw new RuntimeException(String.format("当前内容已添加至实验,请勿重复添加!")); + } + argumentIdList.add(testRecordArgumentId); + } else if (opCode == -1 && argumentIdList.contains(testRecordArgumentId)) { + boolean ret = argumentIdList.remove(testRecordArgumentId); + if (!ret) { + throw new RuntimeException(String.format("在实验中没有找到ID为%s的内容!", testRecordArgumentId)); + } + } + } + + /** + * 使用模板 + * + * @param testId + * @param templateId + * @return + * @throws Exception + */ + @Override + public TestRecord useTemplate(String testId, String templateId) throws Exception { + TestRecord testRecord = this.getById(testId); + this.copyFromTemplate(testRecord, templateId); + return testRecord; + } + + + /** + * 实验中不同流程的完成程度(只要在某个流程添加了数据,就传给前端true) + * + * @param testId + * @return + */ + @Override + public ProcedureVo getProcedure(String testId) { + TestRecordVo testRecordVo = baseMapper.getTestRecordMapById(testId); + ProcedureVo procedureVo = new ProcedureVo(); + if (StringUtils.isNotBlank(testRecordInstrumentConditionService.generatedOrNot(testId))) { + procedureVo.setSetInstrumentConditions(true); + } else { + procedureVo.setSetInstrumentConditions(false); + } + + if (testRecordVo.getTestMethodList() != null && testRecordVo.getTestMethodList().size() > 0) { + procedureVo.setTestRecordMethod(true); + } else { + procedureVo.setTestRecordMethod(false); + } + if (testRecordVo.getDeviceIdList() != null && testRecordVo.getDeviceIdList().size() > 0) { + procedureVo.setTestRecordInstrument(true); + } else { + procedureVo.setTestRecordInstrument(false); + } + if (testRecordVo.getReagentConsumablesList() != null && testRecordVo.getReagentConsumablesList().size() > 0) { + List testRecordReagentList = testRecordReagentService.list(Wrappers.lambdaQuery() + .in(TestRecordReagent::getCategory, "试剂", "耗材") + .in(TestRecordReagent::getId, testRecordVo.getReagentConsumablesList())); + + List testRecordStandardSubstanceList = testRecordReagentService.list(Wrappers.lambdaQuery() + .notIn(TestRecordReagent::getCategory, "试剂", "耗材") + .in(TestRecordReagent::getId, testRecordVo.getReagentConsumablesList())); + if (testRecordReagentList.size() > 0) { + procedureVo.setTestRecordReagentConsumables(true); + } else { + procedureVo.setTestRecordReagentConsumables(false); + } + if (testRecordStandardSubstanceList.size() > 0) { + procedureVo.setTestRecordStandardSubstance(true); + } else { + procedureVo.setTestRecordStandardSubstance(false); + } + } + procedureVo.setTestRecordReagentConsumables(true); + if (testRecordVo.getStandardSolution() != null && testRecordVo.getStandardSolution().size() > 0 && testRecordVo.getSampleSolution() != null && testRecordVo.getSampleSolution().size() > 0) { + procedureVo.setPretreatment(true); + } else { + procedureVo.setPretreatment(false); + } + if (testRecordVo.getSampleTestList() != null && testRecordVo.getSampleTestList().size() > 0) { + procedureVo.setSampleInfo(true); + } else { + procedureVo.setSampleInfo(false); + } + procedureVo.setEmbarkation(true); + procedureVo.setResultAnalysis(testRecordSampleDataService.whetherSave(testId)); + return procedureVo; + } + + /** + * 获取打印数据 + * + * @param businessId + * @return + */ + @Override + public Map getPrintData(String businessId) throws Exception { + //这个委托下检材信息 + List sampleInfos = sampleInfoService.list(Wrappers.lambdaQuery().eq(SampleInfo::getBusinessId, businessId)); + ArrayList sampleNoList = new ArrayList<>(); + ArrayList sampleIdList = new ArrayList<>(); + sampleInfos.forEach(item -> { + sampleNoList.add(item.getAcceptNo()); + sampleIdList.add(item.getId()); + }); + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + String businessType = entrustInfo.getBusinessType(); + TestRecord vo = new TestRecord(); + + //查询实验 + for (String sampleId : sampleIdList) { + TestRecord testRecord = this.getOne(Wrappers.lambdaQuery().like(TestRecord::getSampleTestList, sampleId)); + if (testRecord != null) { + vo = testRecord; + break; + } + } + testRecordInstrumentConditionService.mergeFile(vo.getId()); + HashMap data = new HashMap<>(); + //构建检验记录的参数 + data.put("acceptNo", entrustInfo.getAcceptNo()); + if (vo.getTestMethodList() != null && vo.getTestMethodList().size() > 0) { + List testRecordMethods = testRecordMethodService.list(Wrappers.lambdaQuery().in(TestRecordMethod::getId, vo.getTestMethodList())); + if (BusinessType.NPS_CASE.getBusinessType().equals(businessType)) { + String method = ""; + for (TestRecordMethod testRecordMethod : testRecordMethods) { + if (method.equals("")) { + method = "☑ " + testRecordMethod.getMethodName(); + } else { + method = method + "\n" + "☑ " + testRecordMethod.getMethodName(); + } + } + method = method + "\n" + "□ " + "其他"; + data.put("method", method); + } + data.put("testRecordMethods", testRecordMethods); + } + if (vo.getDeviceIdList() != null && vo.getDeviceIdList().size() > 0) { + List testRecordInstruments = testRecordInstrumentService.list(Wrappers.lambdaQuery().in(TestRecordInstrument::getId, vo.getDeviceIdList())); + data.put("testRecordInstruments", testRecordInstruments); + } + if (vo.getStandardSolution() != null && vo.getStandardSolution().size() > 0) { + List testRecordStandardSolutions = testRecordStandardSolutionService.list(Wrappers.lambdaQuery().in(TestRecordStandardSolution::getId, vo.getStandardSolution()).eq(TestRecordStandardSolution::getSolutionType, "STD")); + testRecordStandardSolutions.forEach(item -> { + item.setExpirationDatePrint(item.getExpirationDate().getYear() + "-" + item.getExpirationDate().getMonthValue() + "-" + item.getExpirationDate().getDayOfMonth()); + item.setMadeDatePrint(item.getMadeDate().getYear() + "-" + item.getMadeDate().getMonthValue() + "-" + item.getMadeDate().getDayOfMonth()); + }); + data.put("testRecordStandardSolutions", testRecordStandardSolutions); + } + if (vo.getSampleSolution() != null && vo.getSampleSolution().size() > 0) { + List testRecordSampleSolutions = testRecordSampleSolutionService.list(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getTestId, vo.getId()).in(TestRecordSampleSolution::getMaterialId, sampleIdList).orderByAsc(TestRecordSampleSolution::getSampleNo)); + Collections.sort(testRecordSampleSolutions, new Comparator() { + @Override + public int compare(TestRecordSampleSolution o1, TestRecordSampleSolution o2) { + Integer o1No = Integer.parseInt(o1.getSampleNo().substring(o1.getSampleNo().lastIndexOf("-") + 1)); + Integer o2No = Integer.parseInt(o2.getSampleNo().substring(o2.getSampleNo().lastIndexOf("-") + 1)); + return Integer.compare(o1No, o2No); + } + }); + for (int i = 0; i < testRecordSampleSolutions.size(); i++) { + testRecordSampleSolutions.get(i).setPrintSampleName(i + 1 + "号检材"); + } + data.put("testRecordSampleSolutions", testRecordSampleSolutions); + } + //缴获物检验记录数据 + if (BusinessType.NPS_CASE.getBusinessType().equals(businessType)) { + List npsCaseTestDataDtos = new ArrayList<>(); + List stdDataList = new ArrayList<>(); + List npsCaseTestDataDtoList = (List) testRecordSampleDataService.getSampleTestDataByBusiness(entrustInfo.getId()); + //判断是标准溶液数据还是样本的数据 + for (NPSCaseTestDataDto npsCaseTestDataDto : npsCaseTestDataDtoList) { + if (TestRecordSampleDataConstant.SAMPLE_TYPE_STD.equals(npsCaseTestDataDto.getSampleType())) { + stdDataList.add(npsCaseTestDataDto); + data.put("stdDataList", stdDataList); + } else { + npsCaseTestDataDtos.add(npsCaseTestDataDto); + data.put("npsCaseTestDataDtos", npsCaseTestDataDtos); + } + } + //生物样本检验记录数据 + } else { + //鉴定过程 + List appraisalProcessDtoList = new ArrayList<>(); + if (StringUtils.isNotBlank(vo.getStandardSolutionProcessing())) { + appraisalProcessDtoList.add(new AppraisalProcessDto(vo.getStandardSolutionProcessing())); + + } + if (StringUtils.isNotBlank(vo.getSampleSolutionProcessing())) { + appraisalProcessDtoList.add(new AppraisalProcessDto(vo.getSampleSolutionProcessing())); + } + + if (StringUtils.isNotBlank(vo.getTestProcessDes())) { + appraisalProcessDtoList.add(new AppraisalProcessDto(vo.getTestProcessDes())); + } + data.put("appraisalProcessDtoList", appraisalProcessDtoList); + + List hairSewageDataDtoList = new ArrayList<>(); + List hairSewageDataDtos = new ArrayList<>(); + List list = (List) testRecordSampleDataService.getSampleTestDataByBusiness(entrustInfo.getId()); + Map> map = list.stream().collect(Collectors.groupingBy(item -> item.getSampleType())); + List bls = testRecordStandardSolutionService.list(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, vo.getId()).eq(TestRecordStandardSolution::getSolutionType, "BLS")); + List blk = testRecordStandardSolutionService.list(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, vo.getId()).eq(TestRecordStandardSolution::getSolutionType, "BLK")); + Set keySet = map.keySet(); + + keySet.forEach(key -> { + if (key.equals("STD")) { + hairSewageDataDtoList.addAll(map.get(key)); + data.put("STDIndex", map.get(key).size()); + } + }); + keySet.forEach(key -> { + if (key.equals("QC")) { + hairSewageDataDtoList.addAll(map.get(key)); + data.put("QCIndex", map.get(key).size()); + } + }); + //根据选取的溶液创建数据 + if (blk != null && blk.size() > 0) { + //创建空白溶剂 + for (TestRecordStandardSolution testRecordStandardSolution : blk) { + HairSewageDataDto hairSewageDataDto = new HairSewageDataDto(); + hairSewageDataDto.setSampleNo(testRecordStandardSolution.getNumber()); + hairSewageDataDto.setSampleType("空白溶剂"); + hairSewageDataDto.setTmpPeakAreaUp("/"); + hairSewageDataDto.setTmpIonAbundanceRatio("/"); + hairSewageDataDto.setTmpTargetRtTime("/"); + hairSewageDataDto.setTmpRtTimeError("/"); + hairSewageDataDto.setCompoundName("/"); + hairSewageDataDto.setTmpPeakAreaDown("/"); + hairSewageDataDto.setTmpIonAbundanceRatioWithinError("/"); + hairSewageDataDto.setRtTimeWithinError("/"); + hairSewageDataDto.setQualitativeIonPairUp("/"); + hairSewageDataDto.setQualitativeIonPairDown("/"); + hairSewageDataDto.setWhetherCheckOut("/"); + hairSewageDataDtoList.add(hairSewageDataDto); + data.put("BLKIndex", blk.size()); + } + } + if (bls != null && blk.size() > 0) { + //创建空白样品 + for (TestRecordStandardSolution testRecordStandardSolution : bls) { + HairSewageDataDto hairSewageDataDto = new HairSewageDataDto(); + hairSewageDataDto.setSampleNo(testRecordStandardSolution.getNumber()); + hairSewageDataDto.setSampleType("空白样品"); + hairSewageDataDto.setTmpPeakAreaUp("/"); + hairSewageDataDto.setTmpIonAbundanceRatio("/"); + hairSewageDataDto.setTmpTargetRtTime("/"); + hairSewageDataDto.setTmpRtTimeError("/"); + hairSewageDataDto.setTmpPeakAreaDown("/"); + hairSewageDataDto.setCompoundName("/"); + hairSewageDataDto.setTmpIonAbundanceRatioWithinError("/"); + hairSewageDataDto.setRtTimeWithinError("/"); + hairSewageDataDto.setQualitativeIonPairUp("/"); + hairSewageDataDto.setQualitativeIonPairDown("/"); + hairSewageDataDto.setWhetherCheckOut("/"); + hairSewageDataDtoList.add(hairSewageDataDto); + data.put("BLSIndex", bls.size()); + } + } + keySet.forEach(key -> { + if (key.equals("Analyte")) { + ArrayList hairSewageDataDtos2 = new ArrayList<>(); + List hairSewageDataDtos1 = map.get(key); + //按照化合物进行分组 + Map> map2 = hairSewageDataDtos1.stream().collect(Collectors.groupingBy(item -> item.getCompoundName())); + Set keySet2 = map2.keySet(); + for (String compoundName : keySet2) { + List hairSewageDataDtos4 = map2.get(compoundName); + //分组来组装数据,因为生物样本的数据会有两条溶液编号一样的结果数据,我们需要对数据进行加工,在溶液编号后面加上-1和-2 + Map> map1 = hairSewageDataDtos4.stream().collect(Collectors.groupingBy(item -> item.getSampleNo())); + Set keySet1 = map1.keySet(); + List list1 = new ArrayList<>(keySet1); + Integer x = 0; + //对溶液数据进行排序 + Collections.sort(list1, new Comparator() { + @Override + public int compare(String o1, String o2) { + int num1 = Integer.parseInt(o1.substring(o1.lastIndexOf("-") + 1)); + int num2 = Integer.parseInt(o2.substring(o2.lastIndexOf("-") + 1)); + return Integer.compare(num1, num2); + } + }); + for (String key1 : list1) { + List hairSewageDataDtos3 = map1.get(key1); + Collections.sort(hairSewageDataDtos3, new Comparator() { + @Override + public int compare(HairSewageDataDto o1, HairSewageDataDto o2) { + return o1.getSampleName().compareTo(o2.getSampleName()); + } + }); + if (hairSewageDataDtos3.size() != 1) { + for (int i = 0; i < hairSewageDataDtos3.size(); i++) { + HairSewageDataDto hairSewageDataDto = hairSewageDataDtos3.get(i); + hairSewageDataDto.setSampleNo(hairSewageDataDto.getSampleNo() + "-" + (i + 1)); + hairSewageDataDtos2.add(hairSewageDataDto); + } + } else { + hairSewageDataDtos2.add(hairSewageDataDtos3.get(0)); + } +// if (dto1.getWhetherCheckOut().equals("是") && dot2.getWhetherCheckOut().equals("是")) { +// } + } + } + hairSewageDataDtoList.addAll(hairSewageDataDtos2); + } + }); + //处理数据类型格式转化问题 + hairSewageDataDtoList.forEach(item -> { + switch (item.getSampleType()) { + case "STD": + item.setSampleType("标准溶液"); + break; + case "QC": + item.setSampleType("质控样品"); + break; + case "Analyte": + item.setSampleType(item.getSampleNo()); + break; + } + if (!item.getSampleType().startsWith("空")) { + if (item.getTargetRtTime() == -999.0 || item.getTargetRtTime() == 0.00) { + item.setTmpTargetRtTime("/"); + } else { + item.setTmpTargetRtTime(String.format("%.02f", item.getTargetRtTime())); + } + if (item.getRtTimeError() == -999.0 || item.getRtTimeError() == -100 || item.getRtTimeError() == 0.00) { + item.setTmpRtTimeError("/"); + } else { + item.setTmpRtTimeError(String.format("%.02f", item.getRtTimeError())); + } + if (item.getIonAbundanceRatioWithinError() == -999.0 || item.getIonAbundanceRatioWithinError() == -100) { + item.setTmpIonAbundanceRatioWithinError("/"); + } else { + item.setTmpIonAbundanceRatioWithinError(String.format("%.02f", item.getIonAbundanceRatioWithinError())); + } + if (item.getPeakAreaUp() == 0.00) { + item.setTmpPeakAreaUp("/"); + } else { + item.setTmpPeakAreaUp(String.format("%.02f", item.getPeakAreaUp())); + } + + if (item.getPeakAreaDown() == 0.00) { + item.setTmpPeakAreaDown("/"); + } else { + item.setTmpPeakAreaDown(String.format("%.02f", item.getPeakAreaDown())); + } + if (item.getIonAbundanceRatio() == 0.00) { + item.setTmpIonAbundanceRatio("/"); + } else { + item.setTmpIonAbundanceRatio(String.format("%.02f", item.getIonAbundanceRatio())); + } + } + + HairSewageDataDto hairSewageDataDto = new HairSewageDataDto(); + BeanUtils.copyProperties(item, hairSewageDataDto); + if (item.getQualitativeIonPairDown() != null) { + hairSewageDataDto.setQualitativeIonPairUp(item.getQualitativeIonPairDown()); + hairSewageDataDto.setQualitativeIonPairUp(item.getQualitativeIonPairDown()); + } + if (item.getPeakAreaDown() != 0.0) { + hairSewageDataDto.setTmpPeakAreaUp(String.format("%.02f", item.getPeakAreaDown())); + } + hairSewageDataDtos.add(item); + hairSewageDataDtos.add(hairSewageDataDto); + }); + data.put("hairSewageDataDtos", hairSewageDataDtos); + String results = testRecordSampleDataService.generateQualitativeResults(businessId); + data.put("results", results); + } + data.put("createTime", LocalDateTimeUtil.format(entrustInfo.getAcceptDate(), "yyyy年MM月dd日")); + data.put("vo", vo); + return data; + } + + /** + * 创建生物样本检验记录 + * + * @param businessId + * @return + * @throws Exception + */ + @Override + public boolean createInspectionRecordByBiological(String businessId) throws Exception { + Map data = this.getPrintData(businessId); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + TestRecord vo = (TestRecord) data.get("vo"); + ossFile.fileGet(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + vo.getId() + "/" + "生物样本检验记录.docx", bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + bos.close(); + + LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); + Configure config = Configure.builder(). + bind("testRecordMethods", policy) + .bind("testRecordInstruments", policy) + .bind("testRecordStandardSolutions", policy) + .bind("testRecordSampleSolutions", policy) + .bind("hairSewageDataDtos", policy) + .bind("appraisalProcessDtoList", policy) + .build(); + XWPFTemplate template = XWPFTemplate.compile(bis, config).render( + new HashMap() {{ + put("testRecordMethods", data.get("testRecordMethods")); + put("testRecordInstruments", data.get("testRecordInstruments")); + put("testRecordStandardSolutions", data.get("testRecordStandardSolutions")); + put("testRecordSampleSolutions", data.get("testRecordSampleSolutions")); + put("createTime", data.get("createTime")); + put("acceptNo", data.get("acceptNo")); + put("hairSewageDataDtos", data.get("hairSewageDataDtos")); + put("results", data.get("results")); + put("appraisalProcessDtoList", data.get("appraisalProcessDtoList")); + }} + ); + NiceXWPFDocument document = template.getXWPFDocument(); + XWPFTable table = document.getTables().get(3); + List hairSewageDataDtos = (List) data.get("hairSewageDataDtos"); + int size = hairSewageDataDtos.size() / 2; + int mergeIndex = 2; + //合并单元格 + for (int i = 0; i < size; i++) { + TableTools.mergeCellsVertically(table, 0, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 1, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 2, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 3, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 4, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 7, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 8, mergeIndex, mergeIndex + 1); + TableTools.mergeCellsVertically(table, 9, mergeIndex, mergeIndex + 1); + mergeIndex += 2; + } + int stdIndex = (int) data.get("STDIndex") * 2; + int qcIndex = (int) data.get("QCIndex") * 2; + System.out.println(stdIndex); + //根据标准溶液和质控溶液的数量来确定合并多少行 + TableTools.mergeCellsVertically(table, 0, 2, stdIndex + 1); + TableTools.mergeCellsVertically(table, 0, stdIndex + 2, stdIndex + 2 + qcIndex - 1); + List paragraphs = document.getParagraphs(); + for (int i = 0; i < paragraphs.size(); i++) { + XWPFParagraph paragraph = paragraphs.get(i); + + // 检查段落内容是否为空 + if (paragraph.getParagraphText().trim().isEmpty()) { + // 删除空白段落 + document.removeBodyElement(document.getPosOfParagraph(paragraph)); + i--; // 更新索引以考虑删除的段落 + } + } + + bis.close(); + ByteArrayOutputStream fosWord = new ByteArrayOutputStream(); + template.write(fosWord); + template.close(); + ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray()); + fosWord.close(); + document.close(); + return ossFile.fileSave(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + businessId + "/" + "生物样本检验记录.docx", fisWord); + } + + /** + * 创建缴获物检验记录 + * + * @param businessId + * @return + * @throws Exception + */ + public boolean createInspectionRecordBySeizure(String businessId) throws Exception { + Map data = this.getPrintData(businessId); + String fileName = "缴获物检验记录.docx"; + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + TestRecord vo = (TestRecord) data.get("vo"); + ossFile.fileGet(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + vo.getId() + "/" + fileName, bos); + byte[] templateArray = bos.toByteArray(); + ByteArrayInputStream bis = new ByteArrayInputStream(templateArray); + bos.close(); + + List npsCaseTestDataDtos = (List) data.get("npsCaseTestDataDtos"); + if (npsCaseTestDataDtos != null && npsCaseTestDataDtos.size() != 0) { + List sampleDataList = new ArrayList<>(); + Collections.sort(npsCaseTestDataDtos, new Comparator() { + @Override + public int compare(NPSCaseTestDataDto o1, NPSCaseTestDataDto o2) { + return o1.getSampleNo().compareTo(o2.getSampleNo()); + } + }); + for (NPSCaseTestDataDto npsCaseTestDataDto : npsCaseTestDataDtos) { + List testSampleDataList = npsCaseTestDataDto.getTestSampleDataList(); + for (NPSTestDetailDataStruct npsTestDetailDataStruct : testSampleDataList) { + NPSCaseTestSampleData sampleData = new NPSCaseTestSampleData(); + this.disposalData(npsCaseTestDataDto, npsTestDetailDataStruct, sampleData); + sampleDataList.add(sampleData); + } + } + data.put("sampleDataList", sampleDataList); + } + + LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(); + Configure config = Configure.builder() + .bind("testRecordMethods", policy) + .bind("testRecordInstruments", policy) + .bind("testRecordStandardSolutions", policy) + .bind("testRecordSampleSolutions", policy) + .bind("npsCaseTestDataDtoList", policy) + .bind("sampleDataList", policy) + .build(); + XWPFTemplate template = XWPFTemplate.compile(bis, config).render( + new HashMap() {{ + put("testRecordMethods", data.get("testRecordMethods")); + put("testRecordInstruments", data.get("testRecordInstruments")); + put("testRecordStandardSolutions", data.get("testRecordStandardSolutions")); + put("testRecordSampleSolutions", data.get("testRecordSampleSolutions")); + put("createTime", data.get("createTime")); + put("acceptNo", data.get("acceptNo")); + put("method", data.get("method")); + put("sampleDataList", data.get("sampleDataList")); + }} + ); + bis.close(); + ByteArrayOutputStream fosWord = new ByteArrayOutputStream(); + NiceXWPFDocument xwpfDocument = template.getXWPFDocument(); + List stdDataList = (List) data.get("stdDataList"); + if (stdDataList != null && stdDataList.size() != 0) { + //创建标准溶液的数据表格 + XWPFTable stdTable = xwpfDocument.createTable(stdDataList.size() * 6, 4); + int index = 0; + for (int i = 0; i < stdDataList.size(); i++) { + NPSCaseTestDataDto npsCaseTestDataDto = stdDataList.get(i); + XWPFTableRow row1 = stdTable.getRow(index); + row1.getCell(0).setText(npsCaseTestDataDto.getCompoundName()); + row1.getCell(1).setText(npsCaseTestDataDto.getStdConcentration()); + row1.getCell(2).setText("保留时间"); + row1.getCell(3).setText(String.valueOf(npsCaseTestDataDto.getStdRtTime())); + XWPFTableRow row2 = stdTable.getRow(index + 1); + row2.getCell(0).setText("m/z"); + row2.getCell(1).setText("S/N"); + row2.getCell(2).setText("峰面积"); + row2.getCell(3).setText("丰度比"); + List testSampdleDataList = npsCaseTestDataDto.getTestSampleDataList(); + for (int j = 0; j < testSampdleDataList.size(); j++) { + NPSTestDetailDataStruct struct = testSampdleDataList.get(j); + XWPFTableRow row3 = stdTable.getRow(index + 2 + j); + //判断是不是基峰 + if (struct.getIsBasePeak() == 1) { + row3.getCell(0).setText(String.valueOf((int) Double.parseDouble(struct.getMass())) + "*"); + } else { + row3.getCell(0).setText(String.valueOf((int) Double.parseDouble(struct.getMass()))); + } + row3.getCell(1).setText(String.format("%.02f", struct.getSn())); + row3.getCell(2).setText(String.valueOf((int) struct.getArea())); + if (Double.compare(struct.getAbundanceRatio(), -999) == 0) { + row3.getCell(3).setText("/"); + } else { + row3.getCell(3).setText(String.format("%.02f", struct.getAbundanceRatio()) + "%"); + } + } + index = index + 6; + } + //设置文本居中 + for (XWPFTableRow row : stdTable.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + for (XWPFParagraph paragraph : cell.getParagraphs()) { + paragraph.setAlignment(ParagraphAlignment.CENTER); + } + } + } + List rows = stdTable.getRows(); +// 设置宽度 + for (XWPFTableRow row : rows) { + for (int i = 0; i < 4; i++) { + row.getCell(i).setWidth("4200"); + } + } + xwpfDocument.setTable(6, stdTable); + //因为上面的方法会默认在word最后添加这个表格,所以我们要删除掉这个表格 + List tables = xwpfDocument.getTables(); + XWPFTable table = tables.get(tables.size() - 1); + xwpfDocument.removeBodyElement(xwpfDocument.getBodyElements().indexOf(table)); + } + + XWPFTable sampleDataTable = xwpfDocument.getTables().get(7); + XWPFTable resultTable = xwpfDocument.getTables().get(8); + + //设置需要合并的单元格 + int mergeIndex = 1; + for (int i = 0; i < npsCaseTestDataDtos.size(); i++) { + TableTools.mergeCellsVertically(sampleDataTable, 0, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(sampleDataTable, 1, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(sampleDataTable, 2, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 0, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 1, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 2, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 3, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 4, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 5, mergeIndex, mergeIndex + 3); + TableTools.mergeCellsVertically(resultTable, 12, mergeIndex, mergeIndex + 3); + mergeIndex = mergeIndex + 4; + } + template.write(fosWord); + template.close(); + ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray()); + fosWord.close(); + return ossFile.fileSave(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + businessId + "/" + fileName, fisWord); + } + + /** + * 处理打印数据 + * + * @param caseTest 仪器导出数据 + * @param dataStruct 仪器导出数据 + * @param sampleData 样本数据 + */ + public void disposalData(NPSCaseTestDataDto caseTest, NPSTestDetailDataStruct dataStruct, NPSCaseTestSampleData sampleData) { + DecimalFormat format = new DecimalFormat("#.00"); + sampleData.setStdConcentration(caseTest.getStdConcentration()); + sampleData.setRtTimeWithinError(caseTest.getRtTimeWithinError()); + sampleData.setSampleNo(caseTest.getSampleNo()); + sampleData.setTargetConcentration(caseTest.getTargetConcentration()); + + if (Double.compare(caseTest.getStdRtTime(), -999) == 0) { + sampleData.setStdRtTime("/"); + } else { + sampleData.setStdRtTime(String.format("%.02f", caseTest.getStdRtTime()) + "%"); + } + + if (Double.compare(caseTest.getRtTimeError(), -999) == 0) { + sampleData.setRtTimeError("/"); + } else { + sampleData.setRtTimeError(String.format("%.02f", caseTest.getRtTimeError()) + "%"); + } + + if (Double.compare(caseTest.getTargetRtTime(), -999) == 0) { + sampleData.setTargetRtTime("/"); + } else { + sampleData.setTargetRtTime(String.format("%.02f", caseTest.getTargetRtTime()) + "%"); + } + + //判断是不是基峰 + if (dataStruct.getIsBasePeak() == 1) { + sampleData.setMass(String.valueOf((int) Double.parseDouble(dataStruct.getMass())) + "*"); + } else { + sampleData.setMass(String.valueOf((int) Double.parseDouble(dataStruct.getMass()))); + } + + if (Double.compare(dataStruct.getAbundanceRatio(), -999) == 0) { + sampleData.setAbundanceRatio("/"); + } else { + sampleData.setAbundanceRatio(String.format("%.02f", dataStruct.getAbundanceRatio()) + "%"); + } + + if (Double.compare(dataStruct.getAbundanceRatio_std(), -999) == 0) { + sampleData.setAbundanceRatio_std("/"); + } else { + sampleData.setAbundanceRatio_std(String.format("%.02f", dataStruct.getAbundanceRatio_std()) + "%"); + } + + if (Double.compare(dataStruct.getAbundanceRatioError(), -999) == 0) { + sampleData.setAbundanceRatioError("/"); + } else { + sampleData.setAbundanceRatioError(String.format("%.02f", dataStruct.getAbundanceRatioError()) + "%"); + } + + if (Double.compare(dataStruct.getErrorRange(), -999) == 0) { + sampleData.setErrorRange("/"); + } else { + sampleData.setErrorRange("±" + (int) dataStruct.getErrorRange() + "%"); + } + + if (caseTest.getIsDetected() == 0) { + sampleData.setCompoundName("未检出" + caseTest.getCompoundName()); + } else if (caseTest.getIsDetected() == 1) { + sampleData.setCompoundName("检出" + caseTest.getCompoundName()); + } + sampleData.setWithinError(dataStruct.getWithinError()); + sampleData.setArea(String.valueOf((int) dataStruct.getArea())); + sampleData.setSn(String.format("%.02f", dataStruct.getSn())); + } + + /** + * 创建检验记录 + * + * @param businessId + * @param type + * @return + * @throws Exception + */ + @Override + public boolean createInspectionRecord(String businessId) throws Exception { + EntrustInfo entrustInfo = entrustInfoService.getById(businessId); + /** + * @apiNote invivo 生物样本 + * @apiNote inVitro 缴获物 + */ + if (entrustInfo.getBusinessType().equals(BusinessType.BOINT_CASE.getBusinessType())) { + return this.createInspectionRecordByBiological(businessId); + } else { + return this.createInspectionRecordBySeizure(businessId); + } + } + + /** + * 删除实验 + * + * @param testId + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean delTestRecord(String testId) { + TestRecordVo vo = baseMapper.getTestRecordMapById(testId); + if (vo.getStatus() >= 5) { + throw new RuntimeException(String.format("该实验已上机,无法删除!")); + } + List sampleTestList = vo.getSampleTestList(); + if (sampleTestList != null && sampleTestList.size() > 0) { + List sampleInfoList = sampleInfoService.list(Wrappers.lambdaQuery().in(SampleInfo::getId, sampleTestList)); + sampleInfoList.forEach(sampleInfo -> sampleInfo.setStatus(1)); + sampleInfoService.updateBatchById(sampleInfoList); + } + testRecordSampleSolutionService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getTestId, testId)); + testRecordStandardSolutionService.remove(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, testId)); + + //文件集合:包括仪器条件、检验记录 + List fileNameList = ossFile.fileList(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId); + if (fileNameList != null && fileNameList.size() > 0) { + fileNameList.forEach(fileName -> { + try { + ossFile.fileDelete(TestRecordFileUrl.TEST_RECORD_CATALOGUE.getFileUrl() + "/" + testId + "/" + fileName); + } catch (Exception e) { + // 处理异常,可以记录日志或者回滚事务 + throw new RuntimeException("Failed to delete file: " + fileName, e); + } + }); + } + testRecordSampleDataService.remove(Wrappers.lambdaQuery().eq(TestRecordSampleData::getTestId, testId)); + sampleInjectorService.remove(Wrappers.lambdaQuery().eq(SampleInjector::getTestId, testId)); + return this.removeById(vo); + } + + /** + * 获取实验中所有的溶液列表 + * + * @param page + * @param testId + * @return + */ + @Override + public Page getResultSolutionPage(Page page, String testId) { + TestRecordVo vo = baseMapper.getTestRecordMapById(testId); + List standardSolutions = testRecordStandardSolutionService.list(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, testId).orderByAsc(TestRecordStandardSolution::getNumber)); + List sampleSolutions = testRecordSampleSolutionService.list(Wrappers.lambdaQuery().eq(TestRecordSampleSolution::getTestId, testId).orderByAsc(TestRecordSampleSolution::getSampleNo)); + List list = new ArrayList<>(); + + if (standardSolutions != null && standardSolutions.size() > 0) { + standardSolutions.forEach(item -> { + list.add(item.getNumber()); + }); + } + if (sampleSolutions != null && sampleSolutions.size() > 0) { + sampleSolutions.forEach(item -> { + list.add(item.getSampleNo()); + }); + } + return new PageUtils().getPages(page.getCurrent(), page.getSize(), list); + } + + /** + * 上传实验图谱 + * + * @param testId + * @param files + * @return + */ + @Override + public R uploadTestAtlas(String testId, MultipartFile file) throws Exception { + TestRecord testRecord = this.getById(testId); + if (testRecord == null) { + throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId)); + } + // 取已上传过的实验图谱 + JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas()); + // 获取文件名list + List fileNameList = new ArrayList<>(); + for (int i = 0; i < testAtlas.size(); i++) { + JSONObject jsonObject = testAtlas.getJSONObject(i); + fileNameList.add(jsonObject.getString("fileName")); + } + // 拼接上传的路径,以实验id为文件夹 + String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId(); + + // 生成一个文件id + String fileId = IdWorker.getIdStr(); + boolean upload = ossFile.fileUpload(file, commonPath); + String fileName = FileNameUtil.getName(file.getOriginalFilename()); + String type = file.getContentType(); + if (!upload) { + // 上传失败 + Map resultData = new HashMap<>(); + resultData.put("fileName", fileName); + resultData.put("path", commonPath); + return R.failed(resultData, "上传实验图谱删除失败"); + } + if (testAtlas.size() > 0) { + // 删除之前上传的 + JSONObject oldObject = testAtlas.getJSONObject(0); + ossFile.fileDelete(oldObject.getString("path")); + testAtlas = new JSONArray(); + } + JSONObject jsonObject = new JSONObject(); + jsonObject.put("fileId", fileId); + jsonObject.put("fileName", fileName); + jsonObject.put("type", type); + jsonObject.put("path", commonPath + "/" + fileName); + testAtlas.add(jsonObject); + + testRecord.setTestAtlas(testAtlas.toJSONString()); + if (this.updateById(testRecord)) { + return R.ok("上传实验图谱成功!"); + } else { + return R.failed("上传实验图谱失败!"); + } + } + + /** + * 上传实验图谱 + * + * @param testId + * @param files + * @return + */ + @Override + public R uploadTestAtlasBatch(String testId, List files) { + TestRecord testRecord = this.getById(testId); + if (testRecord == null) { + throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId)); + } + // 取已上传过的实验图谱 + JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas()); + // 获取文件名list + List fileNameList = new ArrayList<>(); + for (int i = 0; i < testAtlas.size(); i++) { + JSONObject jsonObject = testAtlas.getJSONObject(i); + fileNameList.add(jsonObject.getString("fileName")); + } + // 拼接上传的路径,以实验id为文件夹 + String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId(); + // 这里遍历要上传的文件 + for (MultipartFile file : files) { + // 获取id来防止因为文件名重复导致的问题 + String fileId = IdWorker.getIdStr(); + /*String filePath = commonPath + "/" + fileId + "/";*/ + boolean upload = ossFile.fileUpload(file, commonPath); + String fileName = FileNameUtil.getName(file.getOriginalFilename()); + String type = file.getContentType(); + if (!upload) { + // 上传失败 + Map resultData = new HashMap<>(); + resultData.put("fileName", fileName); + resultData.put("path", commonPath); + return R.failed(resultData, "上传实验图谱删除失败"); + } + if (fileNameList.contains(fileName)) { + // 文件名存在则不用在添加一个json对象 + continue; + } + JSONObject jsonObject = new JSONObject(); + jsonObject.put("fileId", fileId); + jsonObject.put("fileName", fileName); + jsonObject.put("type", type); + jsonObject.put("path", commonPath + "/" + fileName); + testAtlas.add(jsonObject); + } + testRecord.setTestAtlas(testAtlas.toJSONString()); + if (this.updateById(testRecord)) { + return R.ok("上传实验图谱成功!"); + } else { + return R.failed("上传实验图谱失败!"); + } + } + + /** + * 获取该实验id的实验图谱 + * + * @param testId + * @return + */ + @Override + public R getTestAtlasList(String testId) { + TestRecord testRecord = this.getById(testId); + if (testRecord == null) { + throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId)); + } + if (StrUtil.isBlank(testRecord.getTestAtlas())) { + return R.ok(); + } + + return R.ok(JSONArray.parseArray(testRecord.getTestAtlas()), "获取实验图谱列表成功!"); + } + + /** + * 删除实验图谱 + * + * @param dto + * @return + */ + @Override + public R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception { + TestRecord testRecord = this.getById(dto.getTestId()); + if (testRecord == null) { + throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", dto.getTestId())); + } + JSONArray array = JSONArray.parseArray(testRecord.getTestAtlas()); + if (CollUtil.isEmpty(array)) { + throw new RuntimeException("该实验的图谱为空!"); + } + // 获取删除的fileid + List fileIds = dto.getFileIds(); + JSONArray newArray = new JSONArray(); + int size = array.size(); + for (int i = 0; i < size; i++) { + JSONObject jsonObject = array.getJSONObject(i); + String fileId = jsonObject.getString("fileId"); + if (fileIds.contains(fileId)) { + ossFile.fileDelete(jsonObject.getString("path")); + } else { + // 不是删除的,就添加到新的数组 + newArray.add(jsonObject); + } + } + + // 更新 + testRecord.setTestAtlas(newArray.toJSONString()); + if (this.updateById(testRecord)) { + return R.ok(true, "实验图谱删除成功!"); + } else { + return R.ok(false, "实验图谱删除失败!"); + } + } + + /** + * 根据业务id获取实验图谱 + * + * @param businessId + * @return + */ + @Override + public R getTestAtlasListByBusinessId(String businessId) { + /** + * 先根据业务id 查询出检材id + */ + List testDataListByBusiness = testRecordSampleDataMapper + .queryDataSolutionSampleDTOList(Wrappers.query().eq("si.business_id", businessId)); + if (CollUtil.isEmpty(testDataListByBusiness)) { + return R.ok(); + } + // 2 根据查询出来的结果,取出实验id + List testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList()); + // 3 根据实验id 获取实验信息 + List testRecordList = this.list(Wrappers.lambdaQuery() + .in(TestRecord::getId, testIdList) + .orderByDesc(TestRecord::getUpdateTime)); + // 最终返回的结果数组 + JSONArray resultArray = new JSONArray(); + for (TestRecord testRecord : testRecordList) { + if (StrUtil.isNotBlank(testRecord.getTestAtlas())) { + resultArray.addAll(JSONArray.parseArray(testRecord.getTestAtlas())); + } + } + return R.ok(resultArray, "根据业务id获取列表成功!"); + } + + /** + * 根据业务id获取实验信息 + * + * @param businessIds + * @return + */ + @Override + public R> queryTestRecordInfoByBusinessId(List businessIds) { + List dataSolutionSampleDTOS = testRecordSampleDataMapper + .queryDataSolutionSampleDTOList(Wrappers.query() + .in("si.business_id", businessIds)); + Set testIdSet = dataSolutionSampleDTOS + .stream() + .map(DataSolutionSampleDTO::getTestId) + .collect(Collectors.toSet()); + // 以实验id为key + Map dataSolutionSampleDTOMap = dataSolutionSampleDTOS + .stream() + .collect( + Collectors + .toMap( + DataSolutionSampleDTO::getTestId, + Function.identity(), + (v1, v2) -> v2 + ) + ); + List testRecordMapList = baseMapper.getTestRecordMapList(Wrappers.lambdaQuery().in(TestRecord::getId, testIdSet)); + // 业务id为key + Map map = new HashMap<>(); + for (TestRecordVo testRecordVo : testRecordMapList) { + DataSolutionSampleDTO dataSolutionSampleDTO = dataSolutionSampleDTOMap.get(testRecordVo.getId()); + map.put(dataSolutionSampleDTO.getBusinessId(), testRecordVo); + } + return R.ok(map); + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordStandardSolutionServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordStandardSolutionServiceImpl.java new file mode 100644 index 0000000..95fccf8 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestRecordStandardSolutionServiceImpl.java @@ -0,0 +1,423 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.common.core.util.R; +import digital.laboratory.platform.inspection.constant.StdSolutionNum; +import digital.laboratory.platform.inspection.constant.TestRecordSampleDataConstant; +import digital.laboratory.platform.inspection.dto.TestRecordStandardSolutionDto; +import digital.laboratory.platform.inspetion.api.entity.TestRecord; +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordStandardSolutionMapper; +import digital.laboratory.platform.inspection.service.TestRecordReagentService; +import digital.laboratory.platform.inspection.service.TestRecordService; +import digital.laboratory.platform.inspection.service.TestRecordStandardSolutionService; +import digital.laboratory.platform.sys.feign.RemoteBalanceRMaterialService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +@SuppressWarnings("all") +public class TestRecordStandardSolutionServiceImpl extends ServiceImpl implements TestRecordStandardSolutionService { + @Resource + private RemoteBalanceRMaterialService remoteBalanceRMaterialService; + + @Resource + private TestRecordService testRecordService; + + @Resource + private TestRecordReagentService testRecordReagentService; + + /** + * 创建标准溶液。 + *

+ * 此方法接收一个包含标准溶液信息的数据传输对象(DTO),并将其转换为实体对象进行保存。 + * 同时,根据输入数据计算浓度,并将该标准溶液与相应的实验记录绑定。 + * + * @param testRecordStandardSolutionDto 包含标准溶液信息的数据传输对象 + * @return 成功保存的标准溶液实体对象,如果保存失败则返回null + */ + @Override + @Transactional(rollbackFor = Exception.class) // 确保事务管理,发生异常时回滚 + public TestRecordStandardSolution addTestRecordStandardSolution(TestRecordStandardSolutionDto testRecordStandardSolutionDto) { + + Integer opCode = 1; // 操作码,用于标识操作类型 + + TestRecordStandardSolution testRecordStandardSolution = new TestRecordStandardSolution(); + + // 将DTO中的属性复制到实体对象中 + BeanUtils.copyProperties(testRecordStandardSolutionDto, testRecordStandardSolution); + + String standardName = ""; + + // 设置标准物质数量,默认为1,表示单个标准物质溶液 + testRecordStandardSolution.setStandardSubstanceCount(1); + + // 生成标准溶液编号 + testRecordStandardSolution.setNumber(this.createNumber(testRecordStandardSolution)); + + // 生成唯一ID + testRecordStandardSolution.setId(IdWorker.get32UUID().toUpperCase()); + + // 设置有效期为制备日期后7天 + testRecordStandardSolution.setExpirationDate(testRecordStandardSolutionDto.getMadeDate().plusDays(7)); + + // 设置溶液类型为标准工作溶液(STD) + testRecordStandardSolution.setSolutionType(TestRecordSampleDataConstant.SAMPLE_TYPE_STD); + + // 如果提供了称取质量/移取体积,则计算浓度;否则假设用户已填写好浓度 + if (StringUtils.isNotBlank(testRecordStandardSolution.getWeighingMoving())) { + testRecordStandardSolution = this.calculatedConcentration(testRecordStandardSolution); + } else { + testRecordStandardSolution.setWeighingMoving(testRecordStandardSolution.getResultConcentration()); + testRecordStandardSolution.setDilutionFactor("1"); + testRecordStandardSolution.setOriginalConcentration(testRecordStandardSolution.getResultConcentration()); + testRecordStandardSolution.setConstantVolume("1"); + } + + // 命名溶液名称 + testRecordStandardSolution.setStandardName(testRecordStandardSolutionDto.getStandardName() + + testRecordStandardSolution.getDilutionName() + "溶液"); + + // 将该标准溶液与对应的实验记录进行绑定 + boolean ret = testRecordService.updateTestRecordArgument( + testRecordStandardSolution.getTestId(), + testRecordStandardSolution.getId(), + TestRecordArgumentType.TEST_RECORD_ARGUMENT_STANDARD_SOLUTION.getType(), + opCode + ); + + // 保存标准溶液实体对象,并检查是否成功保存以及是否成功更新实验记录参数 + return this.save(testRecordStandardSolution) && ret ? testRecordStandardSolution : null; + } + + /** + * 生成空白溶液。 + *

+ * 根据提供的实验ID和类型(空白溶剂或空白样品),创建并保存一个空白溶液记录。 + * 编号生成规则基于当前日期和已有溶液的数量进行编号。 + * + * @param testId 实验ID + * @param type 类型标识,1表示空白溶剂,-1表示空白样品 + * @return 成功保存的标准溶液实体对象,如果保存失败则返回null + */ + @Override + public TestRecordStandardSolution addBlankSolution(String testId, Integer type) { + // 创建新的标准溶液实体对象 + TestRecordStandardSolution solution = new TestRecordStandardSolution(); + + // 设置标准物质数量为0,表示空白溶液 + solution.setStandardSubstanceCount(0); + + // 设置实验ID + solution.setTestId(testId); + + // 设置溶液类型和名称 + String solutionType; + String standardName; + String prefix; + if (type == 1) { // 空白溶剂 + solutionType = "BLK"; // 溶液类型:空白溶剂 + standardName = "空白溶剂"; // 名称:空白溶剂 + prefix = StdSolutionNum.BLANK_SOLUTION.getPrefix(); // 前缀用于生成编号 + } else { // 空白样品 + solutionType = "BLS"; // 溶液类型:空白样品 + standardName = "空白样品"; // 名称:空白样品 + prefix = StdSolutionNum.BLANK_SAMPLE_SOLUTION.getPrefix(); // 前缀用于生成编号 + } + solution.setStandardName(standardName); // 设置标准溶液名称 + solution.setSolutionType(solutionType); // 设置溶液类型 + + // 查询已有的溶液列表以生成编号 + List solutionList = this.list( + Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getSolutionType, solutionType) // 过滤条件:溶液类型 + .eq(TestRecordStandardSolution::getTestId, testId) // 过滤条件:实验ID + ); + + // 生成编号 + String suffix = solutionList == null || solutionList.isEmpty() ? "01" : String.format("%02d", solutionList.size() + 1); + String number = prefix + "-" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd") + "-" + suffix; + solution.setNumber(number); // 设置生成的编号 + + // 设置其他属性 + solution.setResultConcentration("/"); // 结果浓度默认值 + solution.setMadeDate(LocalDateTime.now()); // 制备日期设置为当前时间 + solution.setOriginalConcentration("/"); // 原始浓度默认值 + solution.setWeighingMoving("0"); // 称取质量/移取体积默认值 + solution.setConstantVolume("0"); // 定容体积默认值 + solution.setDilutionFactor("0"); // 稀释倍数默认值 + solution.setDilutionName("/"); // 稀释物质名称默认值 + solution.setExpirationDate(LocalDateTime.now()); // 有效期设置为当前时间 + solution.setId(IdWorker.get32UUID().toUpperCase()); // 设置唯一ID + solution.setResultConcentrationUnit("/"); //设置单位 + + // 更新实验记录参数,将该标准溶液与对应的实验记录进行绑定 + boolean ret = testRecordService.updateTestRecordArgument( + solution.getTestId(), + solution.getId(), + TestRecordArgumentType.TEST_RECORD_ARGUMENT_STANDARD_SOLUTION.getType(), + 1 + ); + + // 保存标准溶液实体对象,并检查是否成功保存以及是否成功更新实验记录参数 + return this.save(solution) && ret ? solution : null; + } + + /** + * 根据标准溶液种数创建质控溶液。 + * + * @param testId 实验ID + * @return 成功保存的质控溶液列表,如果保存失败则返回null + */ + @Override + public List createQualityControlSol(String testId) { + // 获取实验记录 + TestRecord record = testRecordService.getById(testId); + + // 查询所有非空白和非质控的标准溶液 + List standardSolutions = this.list( + Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getSolutionType, "STD") + .eq(TestRecordStandardSolution::getTestId, testId) + ); + + // 检查是否有标准溶液 + if (standardSolutions.isEmpty()) { + throw new RuntimeException("请先添加至少一瓶标准溶液后再进行添加质控溶液!"); + } + + // 计算所有标准溶液中的标准物质数量总和 + + int totalSubstanceCount = standardSolutions.size(); + + // 清除现有的质控溶液 + + List qcList = this.list( + Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getStandardSubstanceCount, 0) + .eq(TestRecordStandardSolution::getTestId, testId) + .likeRight(TestRecordStandardSolution::getNumber, TestRecordSampleDataConstant.SAMPLE_TYPE_QC) + ); + + // 删除现有质控溶液 + if (!qcList.isEmpty()) { + this.remove(Wrappers.lambdaQuery() + .eq(TestRecordStandardSolution::getStandardSubstanceCount, 0) + .eq(TestRecordStandardSolution::getTestId, testId) + .likeRight(TestRecordStandardSolution::getNumber, TestRecordSampleDataConstant.SAMPLE_TYPE_QC)); + + // 更新实验记录中的标准溶液列表,移除旧的质控溶液ID + List standardSolutionIds = record.getStandardSolution(); + for (TestRecordStandardSolution qcSolution : qcList) { + standardSolutionIds.remove(qcSolution.getId()); + } + } + + // 创建新的质控溶液 + List qcSolutions = new ArrayList<>(); + for (int i = 0; i < totalSubstanceCount; i++) { + TestRecordStandardSolution qcSolution = new TestRecordStandardSolution(); + qcSolution.setStandardSubstanceCount(0); // 设置标准物质数量为0 + qcSolution.setTestId(testId); // 设置实验ID + qcSolution.setStandardName("标准添加样品"); // 设置名称为“标准添加样品” + String suffix = String.format("%02d", i + 1); // 生成编号后缀 + String number = StdSolutionNum.QC_SOLUTION.getPrefix() + "-" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd") + "-" + suffix; // 生成编号 + qcSolution.setNumber(number); // 设置编号 + qcSolution.setResultConcentration("/"); // 设置结果浓度默认值 + qcSolution.setMadeDate(LocalDateTime.now()); // 设置制备日期为当前时间 + qcSolution.setOriginalConcentration("/"); // 设置原始浓度默认值 + qcSolution.setWeighingMoving("0"); // 设置称取质量/移取体积默认值 + qcSolution.setConstantVolume("0"); // 设置定容体积默认值 + qcSolution.setDilutionFactor("0"); // 设置稀释倍数默认值 + qcSolution.setDilutionName("/"); // 设置稀释物质名称默认值 + qcSolution.setExpirationDate(LocalDateTime.now()); // 设置有效期为当前时间 + qcSolution.setId(IdWorker.get32UUID().toUpperCase()); // 设置唯一ID + qcSolution.setSolutionType(TestRecordSampleDataConstant.SAMPLE_TYPE_QC); // 设置溶液类型为质控溶液 + qcSolution.setResultConcentrationUnit("/"); // 设置单位 + qcSolutions.add(qcSolution); // 添加到质控溶液列表中 + } + + + // 更新实验记录中的标准溶液列表,添加新的质控溶液ID + List standardSolutionIds = record.getStandardSolution(); + for (TestRecordStandardSolution qcSolution : qcSolutions) { + standardSolutionIds.add(qcSolution.getId()); // 添加新的质控溶液ID + } + record.setStandardSolution(standardSolutionIds); // 更新实验记录中的标准溶液列表 + testRecordService.updateById(record); // 更新实验记录 + // 批量保存新创建的质控溶液 + return this.saveBatch(qcSolutions) ? qcSolutions : null; + } + + + /** + * 创建标准溶液编号 + * + * @param standardSubstanceNumList + * @param orderNum 溶液编号后缀,用来匹配称量系统那边的称量编号 + * @return + */ + public String createNumber(TestRecordStandardSolution solution) { + String number = ""; + String englishName = solution.getEnglishName(); + String date = LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMdd"); + return englishName + "-" + date; + } + + /** + * 删除标准溶液 + * + * @param id + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean delTestRecordStandardSolution(String id) { + Integer opCode = -1; + TestRecordStandardSolution testRecordStandardSolution = this.getById(id); + if (testRecordStandardSolution == null) { + throw new RuntimeException(String.format("没有找到ID为%s的标准溶液", id)); + } + boolean ret = testRecordService.updateTestRecordArgument(testRecordStandardSolution.getTestId(), testRecordStandardSolution.getId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_STANDARD_SOLUTION.getType(), opCode); + return this.removeById(id) && ret; + } + + /** + * 修改标准溶液 + * + * @param testRecordStandardSolution + * @return + */ + @Override + public TestRecordStandardSolution updateTestRecordStandardSolution(TestRecordStandardSolutionDto testRecordStandardSolutionDto) { + TestRecordStandardSolution oldTestRecordStandardSolution = this.getOne(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getId, testRecordStandardSolutionDto.getId())); + if (oldTestRecordStandardSolution == null) { + throw new RuntimeException(String.format("没有找到ID为%s的标准溶液", testRecordStandardSolutionDto.getId())); + } + TestRecordStandardSolution solution = new TestRecordStandardSolution(); + BeanUtils.copyProperties(testRecordStandardSolutionDto, solution); + solution.setNumber(this.createNumber(solution)); + solution.setExpirationDate(solution.getMadeDate().plusDays(7)); + + // 如果提供了称取质量/移取体积,则计算浓度;否则假设用户已填写好浓度 +// if (!testRecordStandardSolutionDto.getWeighingMoving().isEmpty()) { +// solution = this.calculatedConcentration(solution); +// } else { + solution.setWeighingMoving(solution.getResultConcentration()); + solution.setDilutionFactor("1"); + solution.setOriginalConcentration(solution.getResultConcentration()); + solution.setConstantVolume("1"); +// } + return this.updateById(solution) ? solution : null; + } + + /** + * 计算溶液浓度 + * + * @param testRecordStandardSolution + * @return + */ + public TestRecordStandardSolution calculatedConcentration(TestRecordStandardSolution testRecordStandardSolution) { + //计算原始浓度 + if (StrUtil.isNotBlank(testRecordStandardSolution.getWeighingMoving())) { + BigDecimal weighingValue = new BigDecimal(testRecordStandardSolution.getWeighingMoving()); + BigDecimal constantVolume = new BigDecimal(testRecordStandardSolution.getConstantVolume()); + BigDecimal originalConcentration = weighingValue.divide(constantVolume, 2, RoundingMode.HALF_UP); + testRecordStandardSolution.setOriginalConcentration(originalConcentration.toString()); + } + //计算结果浓度 + if (StrUtil.isNotBlank(testRecordStandardSolution.getOriginalConcentration()) && StrUtil.isNotBlank(testRecordStandardSolution.getDilutionFactor())) { + BigDecimal originalConcentration = new BigDecimal(testRecordStandardSolution.getOriginalConcentration()); + BigDecimal dilutionFactor = new BigDecimal(testRecordStandardSolution.getDilutionFactor()); + BigDecimal resultConcentration = originalConcentration.divide(dilutionFactor, 2, RoundingMode.HALF_UP); + testRecordStandardSolution.setResultConcentration(resultConcentration.toString()); + } + return testRecordStandardSolution; + } + + /** + * 通过实验ID分页查询 + * + * @param page + * @param testId + * @return + */ + @Override + public IPage getTestRecordStandardSolutionPage(Page page, String testId, String keywords) { + return baseMapper.getTestRecordStandardSolutionMapPage(page, testId); + } + + /** + * 通过实验ID列表查询 + * + * @param testId + * @param keywords + * @return + */ + @Override + public List getTestRecordStandardSolutionList(String testId, String keywords) { + return baseMapper.getTestRecordStandardSolutionMapList(testId); + } + + /** + * 匹配称量数据 + * + * @param id + * @return + */ + @Override + public List matchingWeighing(String id) { + List testRecordStandardSolutionList = this.list(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, id)); + if (testRecordStandardSolutionList == null || testRecordStandardSolutionList.size() == 0) { + throw new RuntimeException(String.format("没有找到ID为%s的实验具有相关的标准溶液信息!", id)); + } + + //如果匹配到了称量质量,那么就自动去计算浓度 + for (TestRecordStandardSolution testRecordStandardSolution : testRecordStandardSolutionList) { + String standardSolutionNumber = testRecordStandardSolution.getNumber(); + String number = standardSolutionNumber.substring(4); + R data = remoteBalanceRMaterialService.getWeightForNumber(number); + BigDecimal weighing = data.getData(); + if (weighing.compareTo(BigDecimal.ZERO) != 0) { + testRecordStandardSolution.setWeighingMoving(weighing.toString()); + BigDecimal constantVolume = new BigDecimal(testRecordStandardSolution.getConstantVolume()); + BigDecimal originalConcentration = weighing.divide(constantVolume, 2, RoundingMode.HALF_UP); + testRecordStandardSolution.setOriginalConcentration(originalConcentration.toString()); + + if (StrUtil.isNotBlank(testRecordStandardSolution.getDilutionFactor())) { + BigDecimal dilutionFactor = new BigDecimal(testRecordStandardSolution.getDilutionFactor()); + BigDecimal resultConcentration = originalConcentration.divide(dilutionFactor, 2, RoundingMode.HALF_UP); + testRecordStandardSolution.setResultConcentration(resultConcentration.toString()); + } else { + testRecordStandardSolution.setResultConcentration(originalConcentration.toString()); + } + } + } + return this.updateBatchById(testRecordStandardSolutionList) ? testRecordStandardSolutionList : null; + } + + @Override + public boolean detection(String testId) { + List stdList = this.list(Wrappers.lambdaQuery().eq(TestRecordStandardSolution::getTestId, testId).eq(TestRecordStandardSolution::getSolutionType, TestRecordSampleDataConstant.SAMPLE_TYPE_STD)); + if (stdList == null || stdList.size() < 1) { + return false; + } else return true; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestTemplateServiceImpl.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestTemplateServiceImpl.java new file mode 100644 index 0000000..8fc00a7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/service/impl/TestTemplateServiceImpl.java @@ -0,0 +1,278 @@ +package digital.laboratory.platform.inspection.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.laboratory.platform.common.mybatis.security.service.DLPUser; +import digital.laboratory.platform.common.oss.service.OssFile; +import digital.laboratory.platform.inspection.constant.TestRecordFileUrl; +import digital.laboratory.platform.inspection.entity.TestRecordMethod; +import digital.laboratory.platform.inspection.entity.TestTemplate; +import digital.laboratory.platform.inspection.constant.TestRecordArgumentType; +import digital.laboratory.platform.inspection.mapper.TestRecordMapper; +import digital.laboratory.platform.inspection.mapper.TestTemplateMapper; +import digital.laboratory.platform.inspection.service.TestRecordInstrumentConditionService; +import digital.laboratory.platform.inspection.service.TestRecordMethodService; +import digital.laboratory.platform.inspection.service.TestTemplateService; +import digital.laboratory.platform.inspetion.api.vo.TestRecordVo; +import digital.laboratory.platform.inspection.vo.TestTemplateVo; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Service +public class TestTemplateServiceImpl extends ServiceImpl implements TestTemplateService { + @Resource + private TestRecordMapper testRecordMapper; + @Resource + private TestTemplateMapper testTemplateMapper; + @Resource + private TestRecordMethodService testRecordMethodService; + + @Resource + private TestRecordInstrumentConditionService testRecordInstrumentConditionService; + + @Resource + private OssFile ossFile; + + /** + * 将实验设置为模板 + * @param testTemplate + * @param testId + * @param dlpUser + * @return + * @throws Exception + */ + @Override + public TestTemplate createTemplate(TestTemplate testTemplate, String testId, DLPUser dlpUser) throws Exception { + TestRecordVo testRecord = testRecordMapper.getTestRecordMapById(testId); + if (testRecord.getDeviceIdList() != null && testRecord.getDeviceIdList().size() > 0) { + testTemplate.setDeviceIdList(testRecord.getDeviceIdList()); + } + if (testRecord.getTestMethodList() != null && testRecord.getTestMethodList().size() > 0) { + testTemplate.setTestMethods(testRecord.getTestMethodList()); + } + if (testRecord.getReagentConsumablesList() != null && testRecord.getReagentConsumablesList().size() > 0) { + testTemplate.setReagentConsumables(testRecord.getReagentConsumablesList()); + } + if (testRecord.getDeviceUseCondition() != null && testRecord.getDeviceUseCondition().size() > 0) { + testTemplate.setDeviceUseCondition(testRecord.getDeviceUseCondition()); + } + testTemplate.setAuthor(dlpUser.getId()); + testTemplate.setStatus(0); + testTemplate.setCreateDate(LocalDateTime.now()); + testTemplate.setUseCount(0); + testTemplate.setId(IdWorker.get32UUID().toUpperCase()); + //创建仪器条件 + testRecordInstrumentConditionService.copyConditionWord(testTemplate.getId(), testId); + return this.save(testTemplate) ? testTemplate : null; + } + + /** + * 修改模板 + * @param testTemplate + * @return + */ + @Override + public TestTemplate editTemplate(TestTemplate testTemplate) { + if (testTemplate.getStatus() != 0) { + throw new RuntimeException(String.format("当前模板仍处于发布状态,请先停用后再进行编辑!")); + } + return this.updateById(testTemplate) ? testTemplate : null; + } + + /** + * 删除模板 支持批量 + * @param idList + * @param dlpUser + * @return + */ + @Override + public boolean delTemplate(List idList, DLPUser dlpUser) { + List list = this.list(Wrappers.lambdaQuery().in(TestTemplate::getId, idList)); + for (TestTemplate testTemplate : list) { + if (!testTemplate.getAuthor().equals(dlpUser.getId())) { + throw new RuntimeException(String.format("这个模板不是你创建的,无法删除!")); + } + if (testTemplate.getStatus() != 0) { + throw new RuntimeException(String.format("请先停用模板后再进行删除!")); + } + } + return this.removeBatchByIds(list); + } + + /** + * 向模板添加或移除参数 + * @param templateId 模板ID + * @param argumentId 物品ID + * @param argument 物品类型 + * @param opCode 添加还是移除 + * @return + */ + @Override + public boolean updateTestTemplate(String templateId, String argumentId, String argument, Integer opCode) { + TestTemplateVo templateVo = baseMapper.getTestTemplateMapById(templateId); + if (templateVo.getStatus() != 0) { + throw new RuntimeException(String.format("当前模板仍处于发布状态,请先停用后再进行编辑!")); + } + ArrayList argumentIdList = new ArrayList<>(); + if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType())) { + if (templateVo.getDeviceIdList() != null && templateVo.getDeviceIdList().size() > 0) { + argumentIdList.addAll(templateVo.getDeviceIdList()); + } + this.updateArgument(argumentIdList, opCode, argumentId); + templateVo.setDeviceIdList(argumentIdList); + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT_CONDITION.getType())) { + if (templateVo.getDeviceUseCondition() != null && templateVo.getDeviceUseCondition().size() > 0) { + argumentIdList.addAll(templateVo.getDeviceUseCondition()); + } + this.updateArgument(argumentIdList, opCode, argumentId); + templateVo.setDeviceUseCondition(argumentIdList); + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_METHOD.getType())) { + if (templateVo.getTestMethods() != null && templateVo.getTestMethods().size() > 0) { + argumentIdList.addAll(templateVo.getTestMethods()); + } + this.updateArgument(argumentIdList, opCode, argumentId); + templateVo.setTestMethods(argumentIdList); + } else if (argument.equals(TestRecordArgumentType.TEST_RECORD_ARGUMENT_REAGENT.getType())) { + if (templateVo.getReagentConsumables() != null && templateVo.getReagentConsumables().size() > 0) { + argumentIdList.addAll(templateVo.getReagentConsumables()); + } + this.updateArgument(argumentIdList, opCode, argumentId); + templateVo.setReagentConsumables(argumentIdList); + } else { + throw new RuntimeException(String.format("没有传入正常的argument!")); + } + return this.updateById(templateVo); + } + + /** + * 判断添加物品的参数是否正确 + * @param argumentIdList + * @param opCode + * @param argumentId + */ + public void updateArgument(List argumentIdList, Integer opCode, String argumentId) { + if (opCode == 1) { + if (argumentIdList.size() > 0 && argumentIdList.contains(argumentId)) { + throw new RuntimeException(String.format("当前内容已添加至模板,请勿重复添加!")); + } + argumentIdList.add(argumentId); + } else if (opCode == -1 && argumentIdList.contains(argumentId)) { + boolean ret = argumentIdList.remove(argumentId); + if (!ret) { + throw new RuntimeException(String.format("在模板中没有找到ID为%s的内容!", argumentId)); + } + } + } + + /** + * 发布模板 + * @param id + * @return + */ + @Override + public TestTemplateVo publishTemplate(String id) { + TestTemplateVo templateVo = testTemplateMapper.getTestTemplateMapById(id); + templateVo.setPublishDate(LocalDateTime.now()); + if (templateVo.getStatus() != 0) { + throw new RuntimeException(String.format("当前模板不处在未发布的状态,无法进行发布!")); + } + templateVo.setStatus(1); + return this.updateById(templateVo) ? templateVo : null; + } + + /** + * 停用模板 + * @param id + * @return + */ + @Override + public TestTemplateVo blockTemplate(String id) { + TestTemplateVo templateVo = testTemplateMapper.getTestTemplateMapById(id); + templateVo.setStatus(0); + return this.updateById(templateVo) ? templateVo : null; + } + + /** + * 通过ID查询模板 + * @param id + * @return + */ + @Override + public TestTemplateVo getTemplateById(String id) { + TestTemplateVo templateVo = baseMapper.getTestTemplateMapById(id); + this.getMethodName(templateVo); + List fileNameList = ossFile.fileList(TestRecordFileUrl.TEST_TEMPLATE_CATALOGUE.getFileUrl() + "/" + templateVo.getId()); + if (fileNameList != null && fileNameList.size() > 0) { + boolean ret = fileNameList.contains("仪器条件.docx"); + if (ret) { + templateVo.setInstrumentConditionFileName("仪器条件.docx"); + templateVo.setInstrumentConditionUrl(TestRecordFileUrl.TEST_TEMPLATE_CATALOGUE.getFileUrl() + "/" + templateVo.getId() + "/" + "仪器条件.docx"); + } + } + return templateVo; + } + + /** + * @param opCode 1:查询所有发布的公有模板 -1:查询自己发布的所有模板 + * @param dlpUser 用户信息 + * @param keywords 查询参数:模板名称 + * */ + @Override + public IPage getTemplateVoPage(Page page, Integer opCode, DLPUser dlpUser, String keywords) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + //查询所有公有且已发布的模板(去掉自己发布的) + if (opCode == 1) { + wrapper.ne(TestTemplate::getAuthor, dlpUser.getId()) + .eq(TestTemplate::getStatus, 1) + .eq(TestTemplate::isNature, true) + .like(StrUtil.isNotBlank(keywords), TestTemplate::getName, keywords) + .orderByDesc(TestTemplate::getCreateDate); + IPage iPage = baseMapper.getTestTemplateMapPage(page, wrapper); + return iPage; + //查询所有自己发布的模板 + } else { + wrapper.eq(TestTemplate::getAuthor, dlpUser.getId()) + .like(StrUtil.isNotBlank(keywords), TestTemplate::getName, keywords) + .orderByDesc(TestTemplate::getCreateDate); + IPage iPage = baseMapper.getTestTemplateMapPage(page, wrapper); + return iPage; + } + } + + /** + * 获取模板中的方法名集合 + * @param testTemplate + */ + public void getMethodName(TestTemplateVo testTemplate) { + if (testTemplate.getTestMethods() != null && testTemplate.getTestMethods().size() > 0) { + ArrayList nameList = new ArrayList<>(); + List list = testRecordMethodService.list(Wrappers.lambdaQuery().in(TestRecordMethod::getId, testTemplate.getTestMethods())); + list.forEach(item -> nameList.add(item.getMethodName())); + testTemplate.setTestMethodName(nameList); + } + } + + /** + * 列表查询模板信息(创建实验时) + * @param dlpUser + * @return + */ + @Override + public List getTemplateVoList(DLPUser dlpUser) { + return baseMapper.getTestTemplateMapList(Wrappers.lambdaQuery() + .and(wrapper -> wrapper.eq(TestTemplate::getAuthor, dlpUser.getId()) + .or() + .eq(TestTemplate::isNature, true)) + .eq(TestTemplate::getStatus, 1) + .orderByDesc(TestTemplate::getCreateDate)); + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/PageUtils.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/PageUtils.java new file mode 100644 index 0000000..c580d94 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/PageUtils.java @@ -0,0 +1,52 @@ +package digital.laboratory.platform.inspection.utils; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.ArrayList; +import java.util.List; + +public class PageUtils { + + /** + * 分页函数 + * + * @param currentPage 当前页数 + * @param pageSize 每一页的数据条数 + * @param list 要进行分页的数据列表 + * @return 当前页要展示的数据 + * @author yhh + */ + public Page getPages(long currentPage, long pageSize, List list) { + Page page = new Page(); + if (list == null) { + return null; + } + int size = list.size(); + + if (pageSize > size) { + pageSize = size; + } + if (pageSize != 0) { + // 求出最大页数,防止currentPage越界 + long maxPage = size % pageSize == 0 ? size / pageSize : size / pageSize + 1; + + if (currentPage > maxPage) { + currentPage = maxPage; + } + } + // 当前页第一条数据的下标 + long x = currentPage > 1 ? (currentPage - 1) * pageSize : 0; + + int curIdx = (int) x; + + List pageList = new ArrayList(); + + // 将当前页的数据放进pageList + for (int i = 0; i < pageSize && curIdx + i < size; i++) { + pageList.add(list.get(curIdx + i)); + } + page.setCurrent(currentPage).setSize(pageSize).setTotal(list.size()).setRecords(pageList); + return page; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TestDataFileUtil.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TestDataFileUtil.java new file mode 100644 index 0000000..03f9043 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TestDataFileUtil.java @@ -0,0 +1,63 @@ +package digital.laboratory.platform.inspection.utils; + +import digital.laboratory.platform.inspection.utils.datafile.HairDataFileUtil; +import digital.laboratory.platform.inspection.utils.datafile.NPSDataFileUtil; +import digital.laboratory.platform.inspection.utils.datafile.SewageDataFileUtil; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title TestDataFileUtil 实验数据文件解析工具类 + * @description + * @create 2024/1/8 16:05 + */ + +public class TestDataFileUtil { + private static String getFileText(MultipartFile file) throws Exception{ + String charset = TextEncodeUtil.checkFileCharset(file);//查看文件流的编码格式 + String fileText = TextEncodeUtil.formatStream(file, charset);//将其转化为一个字符文本 + return fileText; + } + /** + * 解析毛发实验数据文件 毛发任务数据,污水任务数据 + * @param file + * @param code 1 调用毛发的方法 2 调用污水的方法 + * @return + * @throws Exception + */ + public static Map> analysisWtsDataFile(MultipartFile file, Integer code) throws Exception{ + String fileText=getFileText(file); + Map> retMap = null; + if (code == 1) { + retMap=HairDataFileUtil.readDataFromText(fileText); + } else if (code == 2) { + retMap = SewageDataFileUtil.readDataFromText(fileText); + } else { + throw new RuntimeException("code 的值不合法!"); + } + return retMap; + } + /** + * 解析NPS案件的实验数据文件 + * @param file 实验数据文件 + * @throws Exception + */ + public static List analysisNpsDataFile(MultipartFile file) throws Exception{ + String fileText=getFileText(file); + //NPS数据文件解析 + List fileStructList= NPSDataFileUtil.readDataFromText(fileText); + return fileStructList; + } + //解析冰毒,海洛因实验数据文件 + + + + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TextEncodeUtil.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TextEncodeUtil.java new file mode 100644 index 0000000..96d0a92 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/TextEncodeUtil.java @@ -0,0 +1,144 @@ +package digital.laboratory.platform.inspection.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +/** + * @author xy + * @version 1.0 + * @title TextEncodeUtil 文本文件编码工具类 + * @description + * @create 2024/1/8 16:20 + */ + +public class TextEncodeUtil { + + /** + * 检查文件的字符集 + * + * @param inputStream + * @return + * UTF-8 表示是 UTF-8 格式 + * UTF-16 表示是 UTF-16 格式 + * GBK 表示是 GBK 格式 + */ + public static String checkFileCharset(MultipartFile file) throws IOException { + byte[] bytes = new byte[256]; + InputStream inputStream=file.getInputStream(); + int n = inputStream.read(bytes); + inputStream.close(); + if (n<=2) { + return "GBK"; + } + if (bytes[0]==-17 && bytes[1]==-69 && bytes[2]==-65) { + return "UTF-8"; + } + + ENCODE_TYPE encodeType =detectEncodeType(bytes); + if (encodeType ==ENCODE_TYPE.UTF8) + return "UTF-8"; + else + + return "GBK"; + } + public static String formatStream(MultipartFile file, String charset) throws IOException { + + InputStream inputStream=file.getInputStream(); + Reader reader = new InputStreamReader(inputStream, charset); + StringBuilder sbText = new StringBuilder(); + char[] buffer = new char[1024]; + int n; + while ((n = reader.read(buffer)) != -1) { + sbText.append(buffer, 0, n); + } + inputStream.close(); + return sbText.toString(); + } + public enum ENCODE_TYPE { + UNKNOW, + ANSI, + UTF8, + UTF16_big_endian, + UTF16_little_endian + } + public static ENCODE_TYPE detectEncodeType(byte[] inputBuffer /*, int bufLen*/) { + ENCODE_TYPE filetype = ENCODE_TYPE.ANSI; + + if (Byte.toUnsignedInt(inputBuffer[0]) == 0xFF + && Byte.toUnsignedInt(inputBuffer[1]) == 0xFE) //fffe,小头,windows默认 + filetype = ENCODE_TYPE.UTF16_little_endian; + else if (Byte.toUnsignedInt(inputBuffer[0]) == 0xFE + && Byte.toUnsignedInt(inputBuffer[1]) == 0xFF) + filetype = ENCODE_TYPE.UTF16_big_endian; + else { + if (validUtf8(inputBuffer)) { + filetype = ENCODE_TYPE.UTF8; + } + } + return filetype; + } + static final int MASK1 = 1 << 7; + static final int MASK2 = (1 << 7) + (1 << 6); + + public static boolean validUtf8(byte[] data) { + int m = data.length; + int index = 0; + while (index < m) { + int num = Byte.toUnsignedInt(data[index]); + int n = getBytes(num); + if (n < 0 || index + n > m) { + return false; + } + for (int i = 1; i < n; i++) { + if (!isValid(Byte.toUnsignedInt(data[index + i]))) { + return false; + } + } + index += n; + } + return true; + } + + public static boolean validUtf8(int[] data) { + int m = data.length; + int index = 0; + while (index < m) { + int num = data[index]; + int n = getBytes(num); + if (n < 0 || index + n > m) { + return false; + } + for (int i = 1; i < n; i++) { + if (!isValid(data[index + i])) { + return false; + } + } + index += n; + } + return true; + } + + public static int getBytes(int num) { + if ((num & MASK1) == 0) { + return 1; + } + int n = 0; + int mask = MASK1; + while ((num & mask) != 0) { + n++; + if (n > 4) { + return -1; + } + mask >>= 1; + } + return n >= 2 ? n : -1; + } + + public static boolean isValid(int num) { + return (num & MASK2) == MASK1; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/HairDataFileUtil.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/HairDataFileUtil.java new file mode 100644 index 0000000..c9bd2c5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/HairDataFileUtil.java @@ -0,0 +1,92 @@ +package digital.laboratory.platform.inspection.utils.datafile; + +import cn.hutool.core.util.StrUtil; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.util.*; + +/** + * @author xy + * @version 1.0 + * @title HairDataFileUtil 毛发数据的文件解析工具类 + * @description + * @create 2024/1/29 14:37 + */ +@Slf4j +public class HairDataFileUtil { + public static Map> readDataFromText(String dataText) throws Exception{ + ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(dataText.getBytes()); + BufferedReader reader = new BufferedReader(new InputStreamReader(tInputStringStream)); + String currentLineContent="";//当前行 + int sampleCount=0; + Map> retMap=new HashMap<>();//某种化合物的 10个样本的该化合物含量数据 + HairSewageCompoundData hairSewageCompoundData =null; + List hairSewageCompoundDataList =null; + String compoundName=""; + List fieldList = null; + boolean clearTab = true; + while ((currentLineContent = reader.readLine()) != null) { + if(StrUtil.isBlank(currentLineContent)) continue;//如果该行是空行,直接跳到下一行 + String[] arrayLineTemp = currentLineContent.split("\t",-1); + String[] arrayLine = null; + if (clearTab || arrayLineTemp[0].startsWith("Compound")) { + arrayLine = Arrays.stream(arrayLineTemp).filter(s -> StrUtil.isNotBlank(s)).toArray(String[]::new); + } else { + arrayLine = arrayLineTemp; + } + if(arrayLine.length==1){ + //说明这一行就是一个标题 + //arrayLine[0].indexOf("Compound")!=-1&&arrayLine[0].indexOf(":")!=-1 + if(arrayLine[0].startsWith("Compound")){ + //如果条件成立,就是化合物名称 + compoundName=arrayLine[0].split(":")[1].trim(); + // 标识后面的不用在去清除制表符\t + clearTab = false; + //hairSewageCompoundData=new HairSewageCompoundData(); + hairSewageCompoundDataList = new ArrayList<>(); + //hairSewageCompoundData.setCompoundName(compoundName); + //hairSewageCompoundDataList.add(hairSewageCompoundData); + //retMap.put(compoundName,hairSewageCompoundDataList); + sampleCount=0; + } + }else if(arrayLine.length>1){ + //说明现在是某种化合物数据了 + if(arrayLine[2].equals("Name")){ + //说明是表头行 + fieldList= Arrays.asList(arrayLine); + //hairSewageCompoundData.setFieldList(fieldList); + }else{ + sampleCount++; + //说明是数据行 + hairSewageCompoundData =new HairSewageCompoundData(); + + hairSewageCompoundData.setCompoundName(compoundName); + hairSewageCompoundData.setFieldList(fieldList); // 表头 + hairSewageCompoundData.setIndexNo(Integer.parseInt(arrayLine[1]));// + hairSewageCompoundData.setSampleName(arrayLine[2]); + hairSewageCompoundData.setIdName(arrayLine[3]); + hairSewageCompoundData.setRtTime(StrUtil.isBlank(arrayLine[4])?0:Double.parseDouble(arrayLine[4])); + hairSewageCompoundData.setQuanTrace(arrayLine[5]); + hairSewageCompoundData.setArea(StrUtil.isBlank(arrayLine[6])?0:Double.parseDouble(arrayLine[6])); + hairSewageCompoundData.setTrace1(arrayLine[7]); + hairSewageCompoundData.setArea1(StrUtil.isBlank(arrayLine[8])?0:Double.parseDouble(arrayLine[8])); + hairSewageCompoundData.setRatioActual(StrUtil.isBlank(arrayLine[9])?0:Double.parseDouble(arrayLine[9])); + hairSewageCompoundData.setRatioPred(StrUtil.isBlank(arrayLine[10])?0:Double.parseDouble(arrayLine[10])); + hairSewageCompoundData.setRatioFlag(arrayLine[11]); + hairSewageCompoundData.setPrimaryFlags(arrayLine[13]); + hairSewageCompoundData.setConcentration(arrayLine[14]); + + hairSewageCompoundDataList.add(hairSewageCompoundData); + retMap.put(compoundName, hairSewageCompoundDataList); + } + + } + } + log.info("此次一共解析出{}种化合物,包含{}个检材样本",retMap.size(),sampleCount); + return retMap; + } +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/NPSDataFileUtil.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/NPSDataFileUtil.java new file mode 100644 index 0000000..0d191f3 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/NPSDataFileUtil.java @@ -0,0 +1,235 @@ +package digital.laboratory.platform.inspection.utils.datafile; + +import cn.hutool.core.util.StrUtil; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSDataFileStruct; +import digital.laboratory.platform.inspection.utils.datafile.nps.NPSTestDetailDataStruct; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title NPSDataFile 文件是按 [ ] 分成不同的小节,我们只需要找到对应的小节进行数据读取即可 + * @description + * @create 2024/1/9 11:59 + */ +@Slf4j +public class NPSDataFileUtil { + //文件是按[]分成各小节,不同小节的解析不方式不同 + public static List readDataFromText(String dataText) throws Exception{ + ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(dataText.getBytes()); + BufferedReader reader = new BufferedReader(new InputStreamReader(tInputStringStream)); + String currentLineContent="";//当前行 + String currentSectionContent="";//当前节点的内容 + int currentSectionIndex=0;//当前节点的序号 + List materialDataList=new ArrayList<>(); + NPSDataFileStruct npsDataFileStruct=null;//一个NPSDataFileStruct 对象代表一个检材样本 + //文件中,可能存在多个样本,因此应该生成多个对象 + while ((currentLineContent = reader.readLine()) != null) { + if(StrUtil.isBlank(currentLineContent)) continue; + String[] arrayLine = currentLineContent.split("\t"); + //如果当前行是以 [ 开始,以 ] 结束 + if (StrUtil.startWith(arrayLine[0], "[") && StrUtil.endWith(arrayLine[0], "]")) { + // 开始新的 secion + String tmp1= StrUtil.removePrefix(arrayLine[0], "[");//去掉左边中括号 + String tmp2= StrUtil.removeSuffix(tmp1, "]");//去掉右边中括号 + currentSectionContent=tmp2; + npsDataFileStruct=handleSectionTitle(currentSectionContent,npsDataFileStruct); + currentSectionIndex=npsDataFileStruct.getCurrentSection(); + if(currentSectionIndex==1){ + materialDataList.add(npsDataFileStruct); + } + }else if(arrayLine.length>1){ + //如果不是空行且不是以 [ 开始,以 ] 结束,我们就解析数据 + //当然前提是知道他是哪个节点的数据,不同节点的数据,解析需求是不相同的。 + if(currentSectionIndex!=-1){ + handleSectionContent(currentSectionIndex,arrayLine,npsDataFileStruct); + }else{ + System.out.println("对不起,未知的节点数据,请联系开发人员"); + } + } + } + //输出结果 + log.info("此次一共解析样本{}条",materialDataList.size()); + log.info("解析内容如下:{}",materialDataList); + return materialDataList; + } + private static NPSDataFileStruct handleSectionTitle(String lineSectionName, NPSDataFileStruct _npsDataFileStruct){ + //无论是一个检材还是几个检材,肯定先执行到的是header section + if (StrUtil.equalsIgnoreCase(lineSectionName, "Header")) { + _npsDataFileStruct=new NPSDataFileStruct(); + _npsDataFileStruct.setCurrentSection(1); + return _npsDataFileStruct; + } + if (StrUtil.equalsIgnoreCase(lineSectionName, "File Information")) { + _npsDataFileStruct.setCurrentSection(2); + return _npsDataFileStruct; + } + if (StrUtil.equalsIgnoreCase(lineSectionName, "Sample Information")) { + _npsDataFileStruct.setCurrentSection(3); + return _npsDataFileStruct; + } + if (StrUtil.equalsIgnoreCase(lineSectionName, "Original Files")) { + _npsDataFileStruct.setCurrentSection(4); + return _npsDataFileStruct; + } + if (StrUtil.equalsIgnoreCase(lineSectionName, "File Description")) { + _npsDataFileStruct.setCurrentSection(5); + return _npsDataFileStruct; + } + if (StrUtil.equalsIgnoreCase(lineSectionName, "MS Quantitative Results")) { + _npsDataFileStruct.setCurrentSection(6); + return _npsDataFileStruct; + } + _npsDataFileStruct.setCurrentSection(-1); + return _npsDataFileStruct; + } + + /** + * 处理不同节点的数据 + * @param sectionNo + * @param arrayLine + * @param _npsDataFileStruct + */ + private static void handleSectionContent(int sectionNo,String[] arrayLine,NPSDataFileStruct _npsDataFileStruct){ + + switch (sectionNo){ + case 1: + { + //如果是1,则表明是新的一份检材数据的开始 + if (StrUtil.equalsIgnoreCase(arrayLine[0], "Data File Name")) { + _npsDataFileStruct.setHeader_DataFileName((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Output Date")) { + _npsDataFileStruct.setHeader_OutputDate((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Output Time")) { + _npsDataFileStruct.setHeader_OutputTime((arrayLine.length > 1) ? arrayLine[1] : ""); + } + } + break; + case 2:{ + if (StrUtil.equalsIgnoreCase(arrayLine[0], "Type")) { + _npsDataFileStruct.setFi_FileType((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Generated")) { + _npsDataFileStruct.setFi_FileGenerated((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Generated by")) { + _npsDataFileStruct.setFi_FileGeneratedBy((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Modified")) { + _npsDataFileStruct.setFi_FileModified((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Modified by")) { + _npsDataFileStruct.setFi_FileModifiedBy((arrayLine.length > 1) ? arrayLine[1] : ""); + } + } + break; + case 3:{ + if (StrUtil.equalsIgnoreCase(arrayLine[0], "Operator Name")) { + _npsDataFileStruct.setSi_SampleOperatorName((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Analyzed")) { + _npsDataFileStruct.setSi_SampleAnalyzed((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Type")) { + _npsDataFileStruct.setSi_SampleType((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Level")) { + _npsDataFileStruct.setSi_SampleLevel((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Sample Name")) { + _npsDataFileStruct.setSi_SampleName(arrayLine[1]); + }else if(StrUtil.equalsIgnoreCase(arrayLine[0], "Sample ID")) { + _npsDataFileStruct.setSi_SampleId((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Dilution Factor")) { + _npsDataFileStruct.setSi_SampleDilutionFactor((arrayLine.length > 1) ? arrayLine[1] : ""); + } + } + break; + case 4:{ + if (StrUtil.equalsIgnoreCase(arrayLine[0], "Data File")) { + _npsDataFileStruct.setOf_DataFile((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Method File")) { + _npsDataFileStruct.setOf_MethodFile((arrayLine.length > 1) ? arrayLine[1] : ""); + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Batch File")) { + _npsDataFileStruct.setOf_BatchFile((arrayLine.length > 1) ? arrayLine[1] : ""); + }else if (StrUtil.equalsIgnoreCase(arrayLine[0], "Tuning File")) { + _npsDataFileStruct.setOf_TuningFile((arrayLine.length > 1) ? arrayLine[1] : ""); + } + } + break; + case 5: + { + System.out.println("这个节点没有数据"); + } + break; + case 6: + { + int dataNum = 0; + //如果是该节下面的第一行,则表示的是数据条数 + if (StrUtil.equalsIgnoreCase(arrayLine[0], "# of IDs")) { + if (arrayLine.length > 1) { + dataNum = Integer.parseInt(arrayLine[1]); + _npsDataFileStruct.setMqr_DataCount(dataNum); + } + } + else if (StrUtil.equalsIgnoreCase(arrayLine[0], "ID#")) { + // 如果第一个值是“ID#”,那么这行就是表数据的表头 + //_npsDataFileStruct.getMqrDataMap(). + List dataHeaderFieldList=Arrays.asList(arrayLine); + _npsDataFileStruct.setMqrDataHeaderList(dataHeaderFieldList); + } + else { + NPSTestDetailDataStruct dataObj=generateQuantitativeObj(arrayLine); + _npsDataFileStruct.getChildDataList().add(dataObj); + } + } + break; + } + + } + //构建定量结果表对象 + private static NPSTestDetailDataStruct generateQuantitativeObj(String[] rowData){ + NPSTestDetailDataStruct npsDataFileStructChild=new NPSTestDetailDataStruct(); + npsDataFileStructChild.setId(rowData[0]); + npsDataFileStructChild.setName(rowData[1]); + npsDataFileStructChild.setType(rowData[2]); + npsDataFileStructChild.setMass(rowData[4]); + if (rowData[5].equals("Not Identified")) { + // 如果文件中存在这个信息,则证明这条数据是未检出的, 下面的值都默认设置为0 + npsDataFileStructChild.setNotIdentified(true); + npsDataFileStructChild.setRetTime(-999); + npsDataFileStructChild.setStartTime(-999); + npsDataFileStructChild.setEndTime(-999); + npsDataFileStructChild.setArea(-999); + npsDataFileStructChild.setStdRetTime(-999); + npsDataFileStructChild.setSn(-999); + npsDataFileStructChild.setAbundanceRatio(-999);//设置检材丰度比 + npsDataFileStructChild.setAbundanceRatio_std(-999);//设置标准物质丰度比 + npsDataFileStructChild.setErrorRange(-999);//设置丰度比偏差 + npsDataFileStructChild.setAbundanceRatioError(-999);//设置偏差范围 + npsDataFileStructChild.setWithinError("/");//设置是否在误差范围内 + npsDataFileStructChild.setIsBasePeak(1);//设置他是基峰 + } else { + npsDataFileStructChild.setRetTime(Double.parseDouble(rowData[5])); + npsDataFileStructChild.setStartTime(Double.parseDouble(rowData[6])); + npsDataFileStructChild.setEndTime(Double.parseDouble(rowData[7])); + npsDataFileStructChild.setArea(Double.parseDouble(rowData[9])); + npsDataFileStructChild.setStdRetTime(Double.parseDouble(rowData[14])); + npsDataFileStructChild.setSn(Double.parseDouble(rowData[52])); + } + + return npsDataFileStructChild; + } + //构建定性结果表对象 + private void generateQualitativeObj(){ + + } + //构造定性结果表 +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/SewageDataFileUtil.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/SewageDataFileUtil.java new file mode 100644 index 0000000..fda310b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/SewageDataFileUtil.java @@ -0,0 +1,157 @@ +package digital.laboratory.platform.inspection.utils.datafile; + +import cn.hutool.core.util.StrUtil; +import com.alibaba.druid.sql.visitor.functions.If; +import digital.laboratory.platform.inspection.utils.datafile.hair.HairSewageCompoundData; +import lombok.extern.slf4j.Slf4j; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author xy + * @version 1.0 + * @title HairDataFileUtil 毛发数据的文件解析工具类 + * @description + * @create 2024/1/29 14:37 + */ +@Slf4j +public class SewageDataFileUtil { + public static Map> readDataFromText(String dataText) throws Exception { + ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(dataText.getBytes()); + BufferedReader reader = new BufferedReader(new InputStreamReader(tInputStringStream)); + String currentLineContent = "";//当前行 + int sampleCount = 0; + Map> retMap = new HashMap<>();//某种化合物的 10个样本的该化合物含量数据 + + String compoundName = ""; + List fieldList = null; + boolean clearTab = true; + ArrayList sewageCompoundDataList = new ArrayList<>(); + while ((currentLineContent = reader.readLine()) != null) { + //如果该行是空行,直接跳到下一行 + if (StrUtil.isBlank(currentLineContent)) { + continue; + } + String[] arrayLine = currentLineContent.split("\t", -1); + if (arrayLine[0].equals("Index")) { + fieldList = Arrays.asList(arrayLine); + continue; + } + if (arrayLine[4].endsWith("2")) { + continue; + } + List hairSewageCompoundDataList = new ArrayList<>(); + + HairSewageCompoundData hairSewageCompoundData = new HairSewageCompoundData(); + hairSewageCompoundData.setCompoundName(arrayLine[3]); + hairSewageCompoundData.setFieldList(fieldList); // 表头 + hairSewageCompoundData.setIndexNo(Integer.parseInt(arrayLine[0]));// + hairSewageCompoundData.setSampleName(arrayLine[1]); + hairSewageCompoundData.setIdName(arrayLine[1]); + try { + hairSewageCompoundData.setRtTime(StrUtil.isBlank(arrayLine[11]) ? 0 : Double.parseDouble(arrayLine[11])); // 保留时间 + } catch (Exception e) { + hairSewageCompoundData.setRtTime(0.0); // 保留时间 + } + try { + hairSewageCompoundData.setArea1(StrUtil.isBlank(arrayLine[10]) ? 0 : Double.parseDouble(arrayLine[10])); + } catch (Exception e) { + hairSewageCompoundData.setArea1(0.0); + } + try { + hairSewageCompoundData.setArea(StrUtil.isBlank(arrayLine[9]) ? 0 : Double.parseDouble(arrayLine[9])); + } catch (Exception e) { + hairSewageCompoundData.setArea(0.0); + } + try { + hairSewageCompoundData.setRatioActual(StrUtil.isBlank(arrayLine[15]) ? 0 : Double.parseDouble(arrayLine[15])); + } catch (Exception e) { + hairSewageCompoundData.setRatioActual(0.0); + } + hairSewageCompoundData.setRatioPred(0.0); + try { + // 浓度的数组下标是13 + hairSewageCompoundData.setConcentration(String.valueOf(Double.parseDouble(arrayLine[13]))); + } catch (Exception e) { + hairSewageCompoundData.setConcentration("0"); + } + hairSewageCompoundData.setTrace1(""); + hairSewageCompoundData.setQuanTrace(""); + hairSewageCompoundData.setPrimaryFlags(""); + hairSewageCompoundData.setRatioFlag(""); + hairSewageCompoundDataList.add(hairSewageCompoundData); + sewageCompoundDataList.addAll(hairSewageCompoundDataList); +// if (retMap.containsKey(hairSewageCompoundData.getCompoundName())) { +// List sewageCompoundDataList = retMap.get(hairSewageCompoundData.getCompoundName()); +// sewageCompoundDataList.add(hairSewageCompoundData); +// retMap.put(hairSewageCompoundData.getCompoundName(), sewageCompoundDataList); +// }else { +// retMap.put(hairSewageCompoundData.getCompoundName(), hairSewageCompoundDataList); +// } +// String[] arrayLineTemp = currentLineContent.split("\t",-1); +// String[] arrayLine = null; +// if (clearTab || arrayLineTemp[0].startsWith("Compound")) { +// arrayLine = Arrays.stream(arrayLineTemp).filter(s -> StrUtil.isNotBlank(s)).toArray(String[]::new); +// } else { +// arrayLine = arrayLineTemp; +// } +// if(arrayLine.length==1){ +// //说明这一行就是一个标题 +// //arrayLine[0].indexOf("Compound")!=-1&&arrayLine[0].indexOf(":")!=-1 +// if(arrayLine[0].startsWith("Compound")){ +// //如果条件成立,就是化合物名称 +// compoundName=arrayLine[0].split(":")[1].trim(); +// // 标识后面的不用在去清除制表符\t +// clearTab = false; +// hairSewageCompoundDataList = new ArrayList<>(); +// +// sampleCount=0; +// } +// }else if(arrayLine.length>1){ +// //说明现在是某种化合物数据了 +// if(arrayLine[2].equals("Name")){ +// //说明是表头行 +// fieldList= Arrays.asList(arrayLine); +// //hairSewageCompoundData.setFieldList(fieldList); +// }else{ +// sampleCount++; +// //说明是数据行 +// hairSewageCompoundData =new HairSewageCompoundData(); +// +// hairSewageCompoundData.setCompoundName(compoundName); +// hairSewageCompoundData.setFieldList(fieldList); // 表头 +// hairSewageCompoundData.setIndexNo(Integer.parseInt(arrayLine[1]));// +// hairSewageCompoundData.setSampleName(arrayLine[2]); +// hairSewageCompoundData.setIdName(arrayLine[3]); +// hairSewageCompoundData.setRtTime(StrUtil.isBlank(arrayLine[4])?0:Double.parseDouble(arrayLine[4])); // 保留时间 +// hairSewageCompoundData.setArea1(StrUtil.isBlank(arrayLine[5])?0:Double.parseDouble(arrayLine[5])); +// hairSewageCompoundData.setArea(StrUtil.isBlank(arrayLine[6])?0:Double.parseDouble(arrayLine[6])); +// hairSewageCompoundData.setRatioActual(StrUtil.isBlank(arrayLine[7])?0:Double.parseDouble(arrayLine[7])); +// hairSewageCompoundData.setRatioPred(StrUtil.isBlank(arrayLine[8])?0:Double.parseDouble(arrayLine[8])); +// hairSewageCompoundData.setConcentration(arrayLine[10]); // 溶液浓度 +// hairSewageCompoundData.setTrace1(arrayLine[13]); +// hairSewageCompoundData.setQuanTrace(arrayLine[14]); +// hairSewageCompoundData.setPrimaryFlags(arrayLine[15]); +// hairSewageCompoundData.setRatioFlag(arrayLine[16]); +// +// hairSewageCompoundDataList.add(hairSewageCompoundData); +// retMap.put(compoundName, hairSewageCompoundDataList); +// } +// +// } + } + Map> map = updateInfo(sewageCompoundDataList); + log.info("此次一共解析出{}种化合物,包含{}个检材样本", map.size(), sampleCount); + return map; + } + + public static Map> updateInfo(List hairSewageCompoundDataList) { + Map> map = hairSewageCompoundDataList.stream().collect(Collectors.groupingBy(item -> item.getCompoundName())); + return map; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairDataStruct.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairDataStruct.java new file mode 100644 index 0000000..95f7fed --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairDataStruct.java @@ -0,0 +1,20 @@ +package digital.laboratory.platform.inspection.utils.datafile.hair; + +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title HairDataStruct 毛发案件检验数据的数据结构 + * @description + * @create 2024/1/29 12:05 + * 毛发案件的检验结果数据,每行的数据用 /t分割 + * + */ + +public class HairDataStruct { + private String fileIdentifier;//文件标识 用于标识是那种格式的文件 + private String printDate;//打印时间 + private Map> hairCompoundDataList;//化合物数据列表 +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairSewageCompoundData.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairSewageCompoundData.java new file mode 100644 index 0000000..5a7cb84 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/hair/HairSewageCompoundData.java @@ -0,0 +1,35 @@ +package digital.laboratory.platform.inspection.utils.datafile.hair; + +import lombok.Data; + +import java.util.List; + +/** + * @author xy + * @version 1.0 + * @title HairSewageCompoundData 毛发化合物数据,这个相当于是每个检材的某一种化合物的数据情况 + * 比如:MDMB-4en-PINACA 这个化合物,每种检材检出的情况 + * @description + * @create 2024/1/29 14:18 + */ +@Data +public class HairSewageCompoundData { + private List fieldList; + private String compoundName; + private Integer indexNo;//序号 + private String sampleName;// 样本名称 + private String idName;// + private Double rtTime;//保留时间 + private String quanTrace;// + private Double area;//峰面积 + private String trace1; + private Double area1; + private Double ratioActual;//实际丰度比 + private Double ratioPred;//预计丰度比 + private String ratioFlag; + private String primaryFlags; + private String concentration;//溶液浓度 ng/mL + + //离子丰度比偏差范围 + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSDataFileStruct.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSDataFileStruct.java new file mode 100644 index 0000000..68be469 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSDataFileStruct.java @@ -0,0 +1,55 @@ +package digital.laboratory.platform.inspection.utils.datafile.nps; + +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author xy + * @version 1.0 + * @title NPSDataFileStruct NPS 数据文件结构 + * @description + * @create 2024/1/24 10:44 + */ +@Data +public class NPSDataFileStruct { + //Header部份的属性 + private String header_DataFileName; + private String header_OutputDate; + private String header_OutputTime; + //File Information 部份的属性 + private String fi_FileType; + private String fi_FileGenerated; + private String fi_FileGeneratedBy; + private String fi_FileModified; + private String fi_FileModifiedBy; + //Sample Information 部份的属性 + private String si_SampleOperatorName; + private String si_SampleAnalyzed; + private String si_SampleType; + private String si_SampleLevel; + private String si_SampleName; + private String si_SampleId; + private String si_SampleDilutionFactor; + //Original Files 部份的属性 + private String of_DataFile; + private String of_MethodFile; + private String of_BatchFile; + private String of_TuningFile; + //MS Quantitative Results 部份的属性 + private Integer mqr_Index=0; + private Integer mqr_DataCount; + private List mqrDataHeaderList; + private Map mqrDataMap; + private List childDataList=new ArrayList<>(); + private int currentSection;//当前节点 的索引号 index + + public void calcMqrIndex(){ + this.mqr_Index=this.mqr_Index+1; + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSTestDetailDataStruct.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSTestDetailDataStruct.java new file mode 100644 index 0000000..037b389 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/datafile/nps/NPSTestDetailDataStruct.java @@ -0,0 +1,32 @@ +package digital.laboratory.platform.inspection.utils.datafile.nps; + +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title NPS详细数据结构 + * @description + * @create 2024/1/24 11:08 + */ +@Data +public class NPSTestDetailDataStruct{ + private String id; + private String name; + private String type; + private String mass;//mz 质荷比 + private double retTime;//保留时间 + private double startTime; + private double endTime; + private double area;//峰面积 + private double stdRetTime; + private double sn; + private double abundanceRatio;//丰度比,如果是基峰,我们设置为1,丰度比的公式为自己的峰面积/基峰峰面积 + private double abundanceRatio_std;// 标准物质的丰度比 + private double abundanceRatioError;//丰度比偏差,如果是基峰不需要比,公式是 (自己的丰度比-标准品的MZ对应丰度比)/标准品的MZ对应丰度比 + private double errorRange;//误差范围 + private String withinError ;//丰度比偏差是否在误差范围内 + private int isBasePeak;//是否是基峰,0 不是基峰 1 是基峰 + private boolean notIdentified = false; // 标记从文件中读取的数据是不是有not identified, 默认 false 没有 + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/AxisYVal.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/AxisYVal.java new file mode 100644 index 0000000..a32222b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/AxisYVal.java @@ -0,0 +1,30 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import lombok.Getter; +import lombok.Setter; +import org.apache.poi.xddf.usermodel.XDDFColor; + +/** + * Y周坐标值 + * + * @author liuxn + * @date 2022/10/27 + */ +@Setter +@Getter +public class AxisYVal { + + /** + * Y轴数据、与X轴数据数量保持一致 + */ + private Number[] val; + /** + * Y轴数据 图例 + */ + private String title; + /** + * Y 周颜色 + */ + private XDDFColor color; + // todo 其他属性配置 +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/BarLineChartForm.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/BarLineChartForm.java new file mode 100644 index 0000000..c500f68 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/BarLineChartForm.java @@ -0,0 +1,31 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 柱状+折线 + * + * @author liuxn + * @date 2022/10/27 + */ +@Setter +@Getter +public class BarLineChartForm extends ChartForm { + + /** + * X轴数据 + */ + private List xData; + /** + * 柱状数据 支持多组 + */ + private List yBarData; + /** + * 折线数据 支持多组 + */ + private List yLineData; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/ChartForm.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/ChartForm.java new file mode 100644 index 0000000..510da08 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/ChartForm.java @@ -0,0 +1,27 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import lombok.Getter; +import lombok.Setter; + +/** + * 图表属性 + * + * @author liuxn + * @date 2022/10/27 + */ +@Setter +@Getter +public class ChartForm { + /** + * 图表标题 + */ + private String title; + /** + * X轴标题 + */ + private String xTitle; + /** + * Y轴标题 + */ + private String yTitle; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/PieChartForm.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/PieChartForm.java new file mode 100644 index 0000000..6a4d423 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/PieChartForm.java @@ -0,0 +1,27 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 饼状图 + * + * @author liuxn + * @date 2022/10/27 + */ +@Setter +@Getter +public class PieChartForm extends ChartForm { + /** + * X轴 图例 + */ + private List xData; + + /** + * 饼状数据 + */ + private AxisYVal yData; + +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableCreateUtils.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableCreateUtils.java new file mode 100644 index 0000000..a413ad5 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableCreateUtils.java @@ -0,0 +1,675 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import cn.hutool.core.collection.CollUtil; +import com.deepoove.poi.util.TableTools; +import digital.laboratory.platform.inspection.dto.RegionalDrugConsumptionDTO; +import org.apache.poi.xwpf.usermodel.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; + +import java.math.BigInteger; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** +* date: 2024/4/26 14:04 +* @author: Chen +* @since JDK 1.8 +* Description: 污水样本分析报告各类表格生成工具类, 设置word纸张方向api +*/ +public class TableCreateUtils { + + public static final String SUBSECTIONONE = "v"; + + public static final String SUBSECTIONTWO = "landscape"; // 纸张方向为横向 + + /** + * 分段 + * @param xwpfDocument 要生成的word文档对象 + * @param result SUBSECTIONONE / SUBSECTIONTWO + */ + public static void subsection(XWPFDocument xwpfDocument, String result) { + CTDocument1 doc = xwpfDocument.getDocument(); + CTBody body = doc.getBody(); + CTP ctp = body.addNewP(); + CTPPr ctpPr = ctp.addNewPPr(); + CTSectPr ctSectPr = ctpPr.addNewSectPr(); + changeOrientation(ctSectPr, result); + } + + /** + * 陕西省各行政区主要毒品总消费量表 + * @param document 生成表格的文档对象 + * @param rows 表格的行数 + * @param cols 表格的列数 + * @param nameList 表格的表头名称 + * @param dataList 表格数据列表 + */ + public static void fetchRegionalDrugConsumptionTable(XWPFDocument document, int rows, int cols, List nameList, List dataList) { + + // 创建一个rows行cols列的表格 + XWPFTable table = getXwpfTable(document, rows, cols); + + // 给表格设置边框 + setTableBorderAttributes(table); + + // 遍历表格设置属性 + List tableRowList = table.getRows(); + setTableCellAttribute(tableRowList); + // 合并单元格 + int mergeCount = tableRowList.get(0).getTableCells().size() / 2; + TableTools.mergeCellsHorizonal(table, 0, 1, mergeCount); + TableTools.mergeCellsHorizonal(table, 0, 2, mergeCount + 1); + + //垂直合并第一列 + TableTools.mergeCellsVertically(table, 0, 0, 1); + // 填充表格数据 + for (XWPFTableRow tableRow : table.getRows()) { + switch (table.getRows().indexOf(tableRow)) { + case 0: + tableRow.getCell(0).setText("行政区"); + tableRow.getCell(1).setText("千人均消费量(毫克/千人/天)"); + tableRow.getCell(2).setText("总消费量(克/天)"); + break; + case 1: + int size = tableRow.getTableCells().size(); + for (int i = 1; i < size; i++) { + // 因为第一列的单元格被合并了,所以从第二个开始 + tableRow.getCell(i).setText(nameList.get((i - 1) % nameList.size())); + } + break; + } + } + // 填充数据 + for (int i = 0; i < dataList.size(); i++) { + RegionalDrugConsumptionDTO dto = dataList.get(i); + XWPFTableRow tableRow = table.getRow(i + 2); + tableRow.getCell(0).setText(dto.getRegional()); + // 千人均消费量(毫克/千人/天) + tableRow.getCell(1).setText(dto.getPccHeroin()); + tableRow.getCell(2).setText(dto.getPccMa()); + tableRow.getCell(3).setText(dto.getPccK()); + tableRow.getCell(4).setText(dto.getPccMdma()); + tableRow.getCell(5).setText(dto.getPccCoc()); + tableRow.getCell(6).setText(dto.getPccFen()); + tableRow.getCell(7).setText(dto.getPccTotal()); + + // 总消费量(克/天) + tableRow.getCell(8).setText(dto.getTcHeroin()); + tableRow.getCell(9).setText(dto.getTcMa()); + tableRow.getCell(10).setText(dto.getTcK()); + tableRow.getCell(11).setText(dto.getTcMdma()); + tableRow.getCell(12).setText(dto.getTcCoc()); + tableRow.getCell(13).setText(dto.getTcFen()); + tableRow.getCell(14).setText(dto.getTcTotal()); + + } + } + + /** + * 陕西省各污水厂服务区及各行政区毒品千人均消费量表 + * @param document 生成表格的文档对象 + * @param rows 表格的行数 + * @param cols 表格的列数 + * @param nameList 表格的表头名称 + * @param dataMap 表格数据列表 第一个元素是 行政区 2 区县 + */ + public static void fetchServiceAreaDrugConsumptionPerThousandTable(XWPFDocument document, int rows, int cols, List nameList, Map>> dataMap) { + + // 创建一个一行两列 + XWPFTable table = document.createTable(rows, cols); +// table.setWidth("100%"); + // 创建表格后,添加grid 网格,grid 规定了表格每一列的宽度,对后面合并单元格有作用 + CTTblGrid grid = table.getCTTbl().addNewTblGrid(); + // grid 的宽度单位是 twips, twip 是 point 的 1/20。一英寸有 1440 twips, 一英寸 2.54厘米, + // 假设我们的表格第一列 4cm,第二列 8cm,那么需要先除以 2.54 得到英寸再乘以 1440 得到 twips。 + for (int i = 0; i < cols; i++) { + if (i == 1) { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (3 / 2.54 * 1440))); + } else { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (1.5 / 2.54 * 1440))); + } + } + + // 给表格设置边框 + setTableBorderAttributes(table); + List tableRows = table.getRows(); // 或row元素 + for (XWPFTableRow tableRow : tableRows) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRows.indexOf(tableRow); + int indexOfCell = tableRow.getTableCells().indexOf(tableCell); + if (indexOf == 1 || indexOf == 0) { + tableCell.getCTTc().addNewTcPr().addNewTcBorders(); + tableCell.setColor("b5d9fc"); // 填充单元格颜色 91,155,213 5b9bd5 b5d9fc + } + if (indexOfCell == 1) { + tableCell.setWidth(Long.toString((long) (3 / 2.54 * 1440))); + } else { + tableCell.setWidth(Long.toString((long) (1.5 / 2.54 * 1440))); + } + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); + } + } + + // 先垂直合并第9列 0,1单元格, 因为先操作水平合并后,表格结构发生改变不好操作 + TableTools.mergeCellsVertically(table, cols -1, 0, 1); + // 水平合并 第一行 2到8列 + TableTools.mergeCellsHorizonal(table, 0, 2, 8); + //垂直合并第一列 + TableTools.mergeCellsVertically(table, 0, 0, 1); + // 垂直合并第二列 0,1单元格 + TableTools.mergeCellsVertically(table, 1, 0, 1); + // 垂直合并剩下的第一列 1 到最后一行 + TableTools.mergeCellsVertically(table, 0, 2, tableRows.size() - 1); + + for (XWPFTableRow tableRow : tableRows) { + switch (tableRows.indexOf(tableRow)) { + case 0: + tableRow.getCell(0).setText("行政区"); + tableRow.getCell(1).setText("区/县"); + tableRow.getCell(2).setText("千人均消费量(毫克/千人/天)"); + tableRow.getCell(3).setText("备注"); + break; + case 1: + int size = tableRow.getTableCells().size(); + for (int i = 2; i < size -1; i++) { + // 因为第一列的单元格被合并了,所以从第二个开始 + tableRow.getCell(i).setText(nameList.get((i -2) % nameList.size())); + } + break; + } + } + // 填充表格数据 + dataMap.forEach((k,v) -> { + // 前两行是表头,所以从第三行开始 + tableRows.get(2).getCell(0).setText(k); + for (int i = 0; i < v.size(); i++) { + List rowDataList = v.get(i); + XWPFTableRow xwpfTableRow = tableRows.get(i + 2); + for (int j = 0; j < rowDataList.size(); j++) { + xwpfTableRow.getCell(j + 1).setText(rowDataList.get(j).toString()); + } + } + }); + + } + + /** + * 陕西省各市毒品千人均消费量具体增长率/下降率表 + * @param document + * @param rows + * @param cols + * @param cityNameList + * @param dataList + */ + public static void fetchCityDrugConsumptionGrowthRatesTable(XWPFDocument document, int rows, int cols, List cityNameList, List> dataList) { + + // 创建一个一行两列 + XWPFTable table = getXwpfTable(document, rows, cols); + + // 给表格设置边框 + setTableBorderAttributes(table); + List tableRows = table.getRows(); // 或row元素 + for (XWPFTableRow tableRow : tableRows) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRows.indexOf(tableRow); + if (indexOf == 0) { + tableCell.setColor("bdd7ee"); // 填充单元格颜色 + } + if (indexOf == 0 && tableRow.getTableCells().indexOf(tableCell) == 0) { + tableCell.setText("行政区"); + for (XWPFParagraph row1Cell1Paragraph : tableCell.getParagraphs()) { + row1Cell1Paragraph.setAlignment(ParagraphAlignment.CENTER); + row1Cell1Paragraph.setVerticalAlignment(TextAlignment.TOP); + } + XWPFParagraph xwpfParagraph = tableCell.addParagraph(); + xwpfParagraph.createRun().addBreak(); + xwpfParagraph.createRun().addBreak(); + xwpfParagraph.createRun().setText("增长/下降"); + xwpfParagraph.setAlignment(ParagraphAlignment.CENTER); + xwpfParagraph.setVerticalAlignment(TextAlignment.BOTTOM); + + // 设置对角线 + CTTcPr tcPr = tableCell.getCTTc().getTcPr(); + CTTcBorders ctTcBorders = tcPr.isSetTcBorders() ? tcPr.getTcBorders() : tcPr.addNewTcBorders(); + CTBorder ctBorder = ctTcBorders.isSetTl2Br() ? ctTcBorders.getTl2Br() : ctTcBorders.addNewTl2Br(); + ctBorder.setVal(STBorder.SINGLE); + ctBorder.setSz(BigInteger.valueOf(4)); + ctBorder.setSpace(BigInteger.valueOf(0)); + ctBorder.setColor("auto"); + tableCell.setWidth(Long.toString((long) (5 / 2.54 * 1440))); + } else { + tableCell.setWidth(Long.toString((long) (2 / 2.54 * 1440))); + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); + } + } + } + for (XWPFTableRow row : tableRows) { + int indexOfRow = tableRows.indexOf(row); + switch (indexOfRow) { + case 0: + for (int i = 1; i < row.getTableCells().size(); i++) { + XWPFTableCell cell = row.getCell(i); + cell.setText(cityNameList.get(i - 1)); + } + break; + default: + // 填充表格数据 + XWPFTableRow xwpfTableRow = tableRows.get(indexOfRow); + List list = dataList.get(indexOfRow - 1); + for (int i = 0; i < xwpfTableRow.getTableCells().size(); i++) { + xwpfTableRow.getCell(i).setText(list.get(i).toString()); + } + break; + } + } + + } + + + /** + * xxxx年mm月陕西省毒品滥用情况分析中各类毒品表生成 + * 表4 陕西省污水处理厂冰毒浓度排名表 + * 表5 陕西省污水处理厂吗啡检测情况 + * @param document + * @param rows + * @param cols + * @param tableName1List + * @param tableName2List + * @param dataList + */ + public static void fetchCityDrugAbuseConditionAnalysisTable(XWPFDocument document, int rows, int cols, + List tableName1List, List tableName2List, List> dataList) { + // 创建一个一行两列 + XWPFTable table = document.createTable(rows, cols); +// table.setWidth("100%"); + // 创建表格后,添加grid 网格,grid 规定了表格每一列的宽度,对后面合并单元格有作用 + CTTblGrid grid = table.getCTTbl().addNewTblGrid(); + // grid 的宽度单位是 twips, twip 是 point 的 1/20。一英寸有 1440 twips, 一英寸 2.54厘米, + // 假设我们的表格第一列 4cm,第二列 8cm,那么需要先除以 2.54 得到英寸再乘以 1440 得到 twips。 + for (int i = 0; i < cols; i++) { + if (i % 2 == 1) { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (4 / 2.54 * 1440))); + } else { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (2 / 2.54 * 1440))); + } + } + // 给表格设置边框 + setTableBorderAttributes(table); + + List tableRows = table.getRows(); + + for (XWPFTableRow tableRow : tableRows) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRows.indexOf(tableRow); + int indexOfCell = tableRow.getTableCells().indexOf(tableCell); + if (indexOf == 1 || indexOf == 0) { + tableCell.setColor("bdd7ee"); // 填充单元格颜色 + } + if (indexOfCell % 2 == 1) { + tableCell.setWidth(Long.toString((long) (4 / 2.54 * 1440))); + } else { + tableCell.setWidth(Long.toString((long) (2 / 2.54 * 1440))); + } + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); + } + } + +// for (String colName : tableName1List) { +// 潜在的逻辑错误:如果tableName1List中有重复的元素,那么indexOf将总是返回第一次出现的索引,这可能导致某些合并操作被错误地重复执行,而不是针对每个唯一的索引执行一次。 +// int indexOf = tableName1List.indexOf(colName); +// switch (indexOf) { +// case 0: { +// TableTools.mergeCellsHorizonal(table, 0, 1, 2); +// break; +// } +// case 1: { +// TableTools.mergeCellsHorizonal(table, 0, 2, 3); +// break; +// } +// case 2: { +// TableTools.mergeCellsHorizonal(table, 0, 3, 4); +// break; +// } +// case 3: { +// TableTools.mergeCellsHorizonal(table, 0, 4, 5); +// break; +// } +// case 4: { +// TableTools.mergeCellsHorizonal(table, 0, 5, 6); +// break; +// } +// } +// } + // 根据tableName1List的大小合并表头单元格 + for (int i = 0; i < tableName1List.size(); i++) { + TableTools.mergeCellsHorizonal(table, 0, i + 1, i + 2); + } +// TableTools.mergeCellsHorizonal(table, 0, 1, 2); +// TableTools.mergeCellsHorizonal(table, 0, 2, 3); +// TableTools.mergeCellsHorizonal(table, 0, 3, 4); +// TableTools.mergeCellsHorizonal(table, 0, 4, 5); +// TableTools.mergeCellsHorizonal(table, 0, 5, 6); + + //垂直合并第一列 + TableTools.mergeCellsVertically(table, 0, 0, 1); + + for (XWPFTableRow tableRow : tableRows) { + int indexOfRow = tableRows.indexOf(tableRow); + switch (indexOfRow) { + case 0: + tableRow.getCell(0).setText("序号"); + List tableCells = tableRow.getTableCells(); + for (int i = 1; i < tableCells.size() && i <= tableName1List.size(); i++) { + tableRow.getCell(i).setText(tableName1List.get(i -1)); + } + break; + case 1: + int size = tableRow.getTableCells().size(); + for (int i = 1; i < size; i++) { + // 因为第一列的单元格被合并了,所以从第二个开始 + tableRow.getCell(i).setText(tableName2List.get((i -1) % tableName2List.size())); + } + break; + default: + // 数据填充 + if (CollUtil.isNotEmpty(dataList)) { + XWPFTableRow xwpfTableRow = tableRows.get(indexOfRow); + List list = dataList.get(indexOfRow - 2); + for (int i = 0; i < xwpfTableRow.getTableCells().size() && i < list.size(); i++) { + xwpfTableRow.getCell(i).setText(list.get(i).toString()); + } + } + break; + } + } + } + + /** + * 附表:陕西省各污水厂监测点主要毒品及其代谢物每日浓度表 + * @param document + * @param rows + * @param cols + * @param tableName2List + * @param dataMap + */ + public static void fetchDailyDrugAndMetaboliteConcentrationTable(XWPFDocument document, int rows, int cols, + List tableName2List, Map>> dataMap) { + + XWPFTable table = document.createTable(rows, cols); +// table.setWidth("100%"); + // 创建表格后,添加grid 网格,grid 规定了表格每一列的宽度,对后面合并单元格有作用 + CTTblGrid grid = table.getCTTbl().addNewTblGrid(); + // grid 的宽度单位是 twips, twip 是 point 的 1/20。一英寸有 1440 twips, 一英寸 2.54厘米, + // 假设我们的表格第一列 4cm,第二列 8cm,那么需要先除以 2.54 得到英寸再乘以 1440 得到 twips。 + for (int i = 0; i < table.getRows().get(0).getTableCells().size(); i++) { + if (i == 1) { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (4 / 2.54 * 1440))); + } else { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (2 / 2.54 * 1440))); + } + } + // 设置表格边框属性 + setTableBorderAttributes(table); + + List tableRows = table.getRows(); + for (XWPFTableRow tableRow : tableRows) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRows.indexOf(tableRow); + int indexOfCell = tableRow.getTableCells().indexOf(tableCell); + if (indexOf == 1 || indexOf == 0) { + tableCell.setColor("5b9bd5"); // 填充单元格颜色 + } + if (indexOfCell == 1) { + // 第二列因为是污水厂,所以调大点 + tableCell.setWidth(Long.toString((long) (4 / 2.54 * 1440))); + } else { + tableCell.setWidth(Long.toString((long) (2 / 2.54 * 1440))); + } + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + XWPFParagraph xwpfParagraph = tableCell.getParagraphs().get(0); + xwpfParagraph.setAlignment(ParagraphAlignment.CENTER); + + } + } + + //垂直合并第一列 + TableTools.mergeCellsVertically(table, 0, 0, 1); + TableTools.mergeCellsVertically(table, 1, 0, 1); + TableTools.mergeCellsVertically(table, 2, 0, 1); + TableTools.mergeCellsVertically(table, 16, 0, 1); + // 水平合并 ,这里的代码顺序不能变更,会影响代码的执行 + TableTools.mergeCellsHorizonal(table, 0, 3, 17-2); + // 合并单元格并填充数据 + mergeTableCellAndFillData(dataMap, table); + +// List tableName2List = new ArrayList<>(Arrays.asList("可替宁","可待因","MDA","MDMA","可卡因","苯甲酰爱康宁","吗啡","O6-单乙酰吗啡","甲基苯丙胺","苯丙胺","氯胺酮","去甲氯胺酮","芬太尼")); + for (XWPFTableRow tableRow : table.getRows()) { + switch (table.getRows().indexOf(tableRow)) { + case 0: + tableRow.getCell(0).setText("行政区"); + tableRow.getCell(1).setText("污水处理厂"); + tableRow.getCell(2).setText("采样时间"); + tableRow.getCell(3).setText("浓度(纳克/升)"); + tableRow.getCell(4).setText(""); + break; + case 1: + int size = tableRow.getTableCells().size(); + for (int i = 3; i < size-1; i++) { + // 因为第一列的单元格被合并了,所以从第二个开始 + tableRow.getCell(i).setText(tableName2List.get((i -3) % tableName2List.size())); + } + break; + } + } + + } + + /** + * 表3 陕西省第二季度各行政区污水厂检出依托咪酯统计表 + * @param document 生成表格的文档对象 + * @param rows 表格的行数 + * @param cols 表格的列数 + * @param tableDataList 表格数据列表 + */ + public static void fetchEtomidateDetectedStatisticalTable(XWPFDocument document, int rows, int cols, List> tableDataList) { + XWPFTable table = document.createTable(rows, cols); +// table.setWidth("100%"); + // 创建表格后,添加grid 网格,grid 规定了表格每一列的宽度,对后面合并单元格有作用 + CTTblGrid grid = table.getCTTbl().addNewTblGrid(); + // grid 的宽度单位是 twips, twip 是 point 的 1/20。一英寸有 1440 twips, 一英寸 2.54厘米, + // 假设我们的表格第一列 4cm,第二列 8cm,那么需要先除以 2.54 得到英寸再乘以 1440 得到 twips。 + for (int i = 0; i < 8; i++) { + if (i == 7) { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (10 / 2.54 * 1440))); + } else { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (2 / 2.54 * 1440))); + } + } + + // 给表格设置边框 + setTableBorderAttributes(table); + + List tableRows = table.getRows(); + for (XWPFTableRow tableRow : tableRows) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRows.indexOf(tableRow); + int indexOfCell = tableRow.getTableCells().indexOf(tableCell); + if (indexOf == 0) { + tableCell.setColor("bdd7ee"); // 填充单元格颜色 + } + if (indexOfCell != 7) { + tableCell.setWidth(Long.toString((long) (3 / 2.54 * 1440))); + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); + } else { + tableCell.setWidth(Long.toString((long) (12 / 2.54 * 1440))); + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.BOTH); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.LEFT); + } + } + } + + for (int i = 0; i < tableRows.size(); i++) { + List tableCells = tableRows.get(i).getTableCells(); + List list = tableDataList.get(i); + for (int j = 0; j < tableCells.size(); j++) { + tableCells.get(j).setText(list.get(j).toString()); + } + } + } + + + /** + * 创建word表格 + * @param document + * @param rows + * @param cols + * @return + */ + private static XWPFTable getXwpfTable(XWPFDocument document, int rows, int cols) { + // 创建一个一行两列 + XWPFTable table = document.createTable(rows, cols); +// table.setWidth("100%"); + // 创建表格后,添加grid 网格,grid 规定了表格每一列的宽度,对后面合并单元格有作用 + CTTblGrid grid = table.getCTTbl().addNewTblGrid(); + // grid 的宽度单位是 twips, twip 是 point 的 1/20。一英寸有 1440 twips, 一英寸 2.54厘米, + // 假设我们的表格第一列 4cm,第二列 8cm,那么需要先除以 2.54 得到英寸再乘以 1440 得到 twips。 + for (int i = 0; i < cols; i++) { + grid.addNewGridCol().setW(BigInteger.valueOf((long) (2 / 2.54 * 1440))); + } + return table; + } + + /** + * 根据市的数据量合并单元格和填充数据 + * @param dataMap + * @param table + */ + private static void mergeTableCellAndFillData(Map>> dataMap, XWPFTable table) { + // 根据数据合并单元格 + AtomicInteger fromRow = new AtomicInteger(2);// 数据开始插入行,比如说表格有0,1两行表头,所以从 第三行 2表头开始 + // 合并单元格 数据填充 + dataMap.forEach((k, v) -> { + int toRow = fromRow.get() + v.size(); + if (toRow == table.getRows().size()) { + // 如果是最后一次数据合并,则 -1 + toRow = toRow -1; // 防止下标越界, + } + if (v.size() != 1) { + // 只有当数据量大于1时才需要合并第一列的单元格 + TableTools.mergeCellsVertically(table, 0, fromRow.get(), toRow); + } + XWPFTableRow tableRow = table.getRow(fromRow.get()); + tableRow.getCell(0).setText(k); + Map>> groupBySewagePlant = new HashMap<>(); + for (List list : v) { + if (groupBySewagePlant.containsKey(list.get(0).toString())) { + groupBySewagePlant.get(list.get(0)).add(list); + } else { + groupBySewagePlant.put(list.get(0).toString(), new ArrayList<>(Arrays.asList(list))); + } + } + // 取分好类的数据 + List keyList = new ArrayList<>(groupBySewagePlant.keySet()); + int startRow = fromRow.get(); + for (String s : keyList) { + List> dataMapBySewagePlantList = groupBySewagePlant.get(s); + if (dataMapBySewagePlantList.size() == 2) { + TableTools.mergeCellsVertically(table, 1, startRow, startRow + 1); + + for (int count = 0; count < dataMapBySewagePlantList.size(); count++) { + List list = dataMapBySewagePlantList.get(count); + + XWPFTableRow tableDataRow = table.getRow(startRow + count); + if (count == 0) { + tableDataRow.getCell(1).setText(s.toString()); + } + // 从2开始的原因是 第一个 是行政区, 第二个是污水厂 + for (int cellIndex = 2; cellIndex < tableDataRow.getTableCells().size(); cellIndex++) { + tableDataRow.getCell(cellIndex).setText(list.get(cellIndex - 1).toString()); + } + } + + startRow = startRow + 2; + } else { + XWPFTableRow tableDataRow = table.getRow(startRow); + List list = dataMapBySewagePlantList.get(0); + // 从2开始的原因是 第一个 是行政区, 第二个是污水厂 + for (int cellIndex = 1; cellIndex < tableDataRow.getTableCells().size(); cellIndex++) { + tableDataRow.getCell(cellIndex).setText(list.get(cellIndex - 1).toString()); + } + startRow++; + } + } + fromRow.getAndAdd(v.size()); + }); + } + + + /** + * 设置表格边框属性 + * @param table + */ + private static void setTableBorderAttributes(XWPFTable table) { + table.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + table.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + table.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + table.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + table.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + table.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000"); + } + + /** + * 设置纸张方向 + * @param section + * @param orientation 字符串方向 + */ + private static void changeOrientation(CTSectPr section, String orientation) { + CTPageSz pageSize = section.isSetPgSz() ? section.getPgSz() : section.addNewPgSz(); + // 设置页边距 + CTPageMar ctPageMar = section.isSetPgMar() ? section.getPgMar() : section.addNewPgMar(); + if (orientation.equals(SUBSECTIONTWO)) { + pageSize.setOrient(STPageOrientation.LANDSCAPE); + pageSize.setW(BigInteger.valueOf(842 * 20)); + pageSize.setH(BigInteger.valueOf(595 * 20)); + // 设置页边距 +// CTPageMar ctPageMar = section.isSetPgMar() ? section.getPgMar() : section.addNewPgMar(); + ctPageMar.setLeft(new BigInteger((28 * 20) + "")); + ctPageMar.setTop(new BigInteger((28 * 20) + "")); + ctPageMar.setRight(new BigInteger((28 * 20) + "")); + ctPageMar.setBottom(new BigInteger((28 * 20) + "")); + } else { + pageSize.setOrient(STPageOrientation.PORTRAIT); + pageSize.setH(BigInteger.valueOf(842 * 20)); + pageSize.setW(BigInteger.valueOf(595 * 20)); + // 设置页边距 为 上 1.28厘米 左 右 下都是2.4厘米 1 厘米等于28磅 +// CTPageMar ctPageMar = section.isSetPgMar() ? section.getPgMar() : section.addNewPgMar(); +// ctPageMar.setLeft(new BigInteger((67 * 20) + "")); +// ctPageMar.setTop(new BigInteger((36 * 20) + "")); +// ctPageMar.setRight(new BigInteger((67 * 20) + "")); +// ctPageMar.setBottom(new BigInteger((67 * 20) + "")); + } + } + + /** + * 根据表格的所有行遍历单元格设置单元格属性 + * @param tableRowList + */ + private static void setTableCellAttribute(List tableRowList) { + for (XWPFTableRow tableRow : tableRowList) { + for (XWPFTableCell tableCell : tableRow.getTableCells()) { + int indexOf = tableRowList.indexOf(tableRow); + if (indexOf == 1 || indexOf == 0) { + tableCell.setColor("bdd7ee"); // 填充单元格颜色 + } + tableCell.setWidth(Long.toString((long) (2 / 2.54 * 1440))); + tableCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + tableCell.getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER); + } + } + } + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableForm.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableForm.java new file mode 100644 index 0000000..e3f2fd7 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/TableForm.java @@ -0,0 +1,40 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * 表格数据 + * + * @author liuxn + * @date 2022/10/27 + */ +@Setter +@Getter +public class TableForm { + //表头数据 + private List headerList; + + //表头数据 + private List header2List; + /** + * 表格数据 + */ + private List> rowDataList; + + //todo 表格其他属性 + + @Setter + @Getter + public static class CellData { + //单元格值 + private String val; + // todo 其他单元格属性 + + public CellData(String val) { + this.val = val; + } + } +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/WordUtils.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/WordUtils.java new file mode 100644 index 0000000..a8b2ce0 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/utils/sewagereport/WordUtils.java @@ -0,0 +1,917 @@ +package digital.laboratory.platform.inspection.utils.sewagereport; + +import cn.hutool.core.util.StrUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.util.Units; +import org.apache.poi.xddf.usermodel.chart.*; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xwpf.usermodel.*; +import org.apache.xmlbeans.XmlException; +import org.openxmlformats.schemas.drawingml.x2006.chart.CTDLbls; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.math.BigInteger; +import java.net.URLEncoder; +import java.util.List; + +/** +* date: 2024/4/26 11:58 +* @author: Chen +* @since JDK 1.8 +* Description: 封装的一下poi接口,有生成图表的接口, 创建标题的接口, 创建段落的 +*/ +@Slf4j +public class WordUtils { + + + /** + * 设置模板样式, 比如标题 + * @param document + * @param templateStylePath + */ + public static void setDocumentStyle(XWPFDocument document, String templateStylePath) { + // word整体样式 + // 读取模板文档 + XWPFDocument template = null; + // 获得模板文档的整体样式 + CTStyles wordStyles = null; + try { + template = new XWPFDocument(new FileInputStream(templateStylePath)); + wordStyles = template.getStyle(); + } catch (XmlException e) { + e.printStackTrace(); + log.error("模板样式读取失败!"); + } catch (IOException e) { + e.printStackTrace(); + log.error("模板样式读取失败!"); + } + // 获取新建文档对象的样式 + XWPFStyles newStyles = document.createStyles(); + // 关键行// 修改设置文档样式为静态块中读取到的样式 + newStyles.setStyles(wordStyles); + } + + /** + * 设置模板样式, 比如标题 + * @param document + * @param inputStream + */ + public static void setDocumentStyle(XWPFDocument document, InputStream inputStream) { + // word整体样式 + // 读取模板文档 + XWPFDocument template = null; + // 获得模板文档的整体样式 + CTStyles wordStyles = null; + try { +// OPCPackage open = OPCPackage.open(inputStream); + template = new XWPFDocument(inputStream); + wordStyles = template.getStyle(); + } catch (XmlException e) { + e.printStackTrace(); + log.error("模板样式读取失败!"); + } catch (IOException e) { + e.printStackTrace(); + log.error("模板样式读取失败!"); + } + // 获取新建文档对象的样式 + XWPFStyles newStyles = document.createStyles(); + // 关键行// 修改设置文档样式为静态块中读取到的样式 + newStyles.setStyles(wordStyles); + } + + /** + * 创建文件首页内容 + * @param document + * @param docTitle + * @param fontFamily 字体 + * @param breakSize 换行行数 + * @param fontSize 字体大小 + */ + public static void createDocHomePage(XWPFDocument document, String docTitle, String fontFamily,int breakSize, int fontSize) { + //新建一个标题段落对象(就是一段文字) + XWPFParagraph titleParagraph = document.createParagraph(); + //样式居中 + titleParagraph.setAlignment(ParagraphAlignment.CENTER); + //创建文本对象 + XWPFRun titleFun = titleParagraph.createRun(); + //设置标题的名字 + titleFun.setText(docTitle); + if (StrUtil.isNotBlank(fontFamily)) { + titleFun.setFontFamily(fontFamily); + } + //加粗 + titleFun.setBold(true); + //设置颜色 + titleFun.setColor("000000"); + //字体大小 + titleFun.setFontSize(fontSize); + for (int i = 0; i < breakSize; i++) { + //换行 + titleFun.addBreak(); + } + } + + + /** + * 创建文件标题 + * + * @param document 文档 + * @param docTitle 完档标题 + */ + public static void createDocTitle(XWPFDocument document, String docTitle, boolean isBreak) { + //新建一个标题段落对象(就是一段文字) + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setStyle("1"); + //样式居中 + titleParagraph.setAlignment(ParagraphAlignment.CENTER); + //创建文本对象 + XWPFRun titleFun = titleParagraph.createRun(); + //设置标题的名字 + titleFun.setText(docTitle); + //加粗 + titleFun.setBold(true); + //设置颜色 + titleFun.setColor("000000"); + //字体大小 + titleFun.setFontSize(16); + if (isBreak) { + //换行 + titleFun.addBreak(); + } + } + + /*** + * 创建段落标题 , 无标题设置 + * @param document 文档 + * @param parTitle 段落标题 + * @param isBreak 是否换行 + */ + public static void createParagraphTitle(XWPFDocument document, String parTitle, boolean isBreak) { + XWPFParagraph titleParagraph = document.createParagraph(); + + setParagraphTitleProperty(parTitle, isBreak, titleParagraph); + } + + + /*** + * 创建段落标题 有标题设置 + * @param document 文档 + * @param parTitle 段落标题 + * @param isBreak 是否换行 + * @param styleLevel 标题等级 + */ + public static void createParagraphTitle(XWPFDocument document, String parTitle, boolean isBreak, Integer styleLevel) { + XWPFParagraph titleParagraph = document.createParagraph(); + // 设置标题等级 + titleParagraph.setStyle(styleLevel.toString()); + + setParagraphTitleProperty(parTitle, isBreak, titleParagraph); + } + + /** + * 创建word文档段落, 可以选择设置tab的数量 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraph 内容 + * @param isBreak 是否换行 + * @param tabCount 需要tab的数量 + */ + public static void createParagraphCustomTab(XWPFDocument document, ParagraphAlignment align, String paragraph, boolean isBreak, int firstLintIndent, int tabCount) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + XWPFRun titleFun = titleParagraph.createRun(); + titleFun.setFontSize(12); + for (int i = 0; i < tabCount; i++) { + titleFun.addTab(); + } + titleFun.setFontFamily("宋体"); + titleFun.setText(paragraph); + titleFun.setColor("000000"); + titleParagraph.setFirstLineIndent(firstLintIndent); + // 设置段落行距 + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + titleFun.addBreak(); + } + } + + /** + * 创建word文档段落 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraph 内容 + * @param isBreak 是否换行 + */ + public static void createParagraph(XWPFDocument document, ParagraphAlignment align, String paragraph, boolean isBreak, int firstLintIndent) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + XWPFRun titleFun = titleParagraph.createRun(); + titleFun.setFontSize(12); + + titleFun.addTab(); + + titleFun.setFontFamily("宋体"); + titleFun.setText(paragraph); + titleFun.setColor("000000"); + titleParagraph.setFirstLineIndent(firstLintIndent); + // 设置段落行距 + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + titleFun.addBreak(); + } + } + + /** + * 创建word文档高亮段落 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraph 内容 + * @param isBreak 是否换行 + */ + public static void createHighLightParagraph(XWPFDocument document, ParagraphAlignment align, String paragraph, boolean isBreak, int firstLintIndent) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + XWPFRun titleFun = titleParagraph.createRun(); + highLight(titleParagraph, titleFun); + titleFun.setFontSize(12); + + titleFun.addTab(); + + titleFun.setFontFamily("宋体"); + titleFun.setText(paragraph); + titleFun.setColor("000000"); + titleParagraph.setFirstLineIndent(firstLintIndent); + // 设置段落行距 + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + titleFun.addBreak(); + } + } + + /** + * 设置高亮属性 + * @param p + * @param run + */ + private static void highLight(XWPFParagraph p, XWPFRun run) { + CTRPr pRpr; + if (run.getCTR() != null) { + pRpr = run.getCTR().getRPr(); + if (pRpr == null) { + pRpr = run.getCTR().addNewRPr(); + } + } else { + pRpr = p.getCTP().addNewR().addNewRPr(); + } + CTHighlight highlight = pRpr.addNewHighlight(); + highlight.setVal(STHighlightColor.RED); + } + + + /** + * 设置段落行距 + * @param paragraph + */ + public static void setSingleLineSpacing(XWPFParagraph paragraph) { + CTP ctp = paragraph.getCTP(); + CTPPr ppr = ctp.isSetPPr() ? ctp.getPPr() : ctp.addNewPPr(); + CTSpacing spacing = ppr.isSetSpacing()? ppr.getSpacing() : ppr.addNewSpacing(); + spacing.setAfter(BigInteger.valueOf(10)); + spacing.setBefore(BigInteger.valueOf(0)); + //注意设置行距类型为 EXACT + spacing.setLineRule(STLineSpacingRule.EXACT); + //1磅数是20 + spacing.setLine(BigInteger.valueOf(480)); + + + } + + /** + * 创建word文档段落, 一部分加粗加粗, 一部分正常 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraphBold 要加粗的内容 + * @param paragraph 不加粗的内容 + * @param isBreak 是否换行 + */ + public static void createParagraphAndBold(XWPFDocument document, ParagraphAlignment align, String paragraphBold, String paragraph, boolean isBreak, int firstLintIndent) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + XWPFRun titleFun = titleParagraph.createRun(); + /** + * + 字体大小 磅值 + 五号 9pt + 小四 12pt + 四号 14pt + 三号 16pt + 小二 18pt + 二号 22pt + 一号 26pt + 小初 36pt + + */ + titleFun.setFontSize(12); // 小四 + titleFun.addTab(); + titleFun.setFontFamily("宋体"); + titleFun.setBold(true); + titleFun.setText(paragraphBold); + titleFun.setColor("000000"); + + XWPFRun xwpfRun = titleParagraph.createRun(); + xwpfRun.setFontSize(12); // 小四 +// xwpfRun.addTab(); + xwpfRun.setFontFamily("宋体"); + xwpfRun.setText(paragraph); + xwpfRun.setColor("000000"); + + titleParagraph.setFirstLineIndent(firstLintIndent); + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + xwpfRun.addBreak(); + } + } + + /** + * 创建word文档段落, 两边是不加粗的内容,中间是需要加粗 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraphBold 要加粗的内容 + * @param paragraph1 不加粗的内容1 + * @param paragraph2 不加粗的内容2 + * @param isBreak 是否换行 + */ + public static void createParagraphAndMiddleBold(XWPFDocument document, ParagraphAlignment align, String paragraphBold, String paragraph1, String paragraph2,boolean isBreak, int firstLintIndent) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + titleParagraph.setFirstLineIndent(firstLintIndent); + // 第一部分 不加粗内容 + XWPFRun xwpfRun1 = titleParagraph.createRun(); + xwpfRun1.addTab(); + xwpfRun1.setFontSize(12); // 小四 + xwpfRun1.setFontFamily("宋体"); + xwpfRun1.setText(paragraph1); + xwpfRun1.setColor("000000"); + + // 中间加粗的内容 + XWPFRun titleFun = titleParagraph.createRun(); + /** + * + 字体大小 磅值 + 五号 9pt + 小四 12pt + 四号 14pt + 三号 16pt + 小二 18pt + 二号 22pt + 一号 26pt + 小初 36pt + */ + titleFun.setFontSize(12); // 小四 + titleFun.setFontFamily("宋体"); + titleFun.setBold(true); + titleFun.setText(paragraphBold); + titleFun.setColor("000000"); + // 第二部分不加粗的内容 + XWPFRun xwpfRun = titleParagraph.createRun(); + xwpfRun.setFontSize(12); // 小四 + xwpfRun.setFontFamily("宋体"); + xwpfRun.setText(paragraph2); + xwpfRun.setColor("000000"); + + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + titleParagraph.createRun().addBreak(); + } + } + + /** + * 创建word文档段落, 两边是加粗的内容,中间是不需要加粗 + * + * @param document 文档 + * @param align ParagraphAlignment.LEFT 居左 + * @param paragraph 不要加粗的内容 + * @param paragraphBold1 加粗的内容1 + * @param paragraphBold2 加粗的内容2 + * @param isBreak 是否换行 + */ + public static void createParagraphAndBothSidesBold(XWPFDocument document, ParagraphAlignment align, String paragraph, String paragraphBold1, String paragraphBold2,boolean isBreak, int firstLintIndent) { + XWPFParagraph titleParagraph = document.createParagraph(); + titleParagraph.setAlignment(align); + titleParagraph.setFirstLineIndent(firstLintIndent); + // 第一部分 加粗内容 + XWPFRun xwpfRun = titleParagraph.createRun(); + xwpfRun.setFontSize(12); // 小四 + xwpfRun.setFontFamily("宋体"); + xwpfRun.addTab(); + xwpfRun.setBold(true); + xwpfRun.setText(paragraphBold1); + xwpfRun.setColor("000000"); + + // 中间不加粗的内容 + XWPFRun titleFun = titleParagraph.createRun(); + /** + * + 字体大小 磅值 + 五号 9pt + 小四 12pt + 四号 14pt + 三号 16pt + 小二 18pt + 二号 22pt + 一号 26pt + 小初 36pt + */ + titleFun.setFontSize(12); // 小四 + titleFun.setFontFamily("宋体"); + titleFun.setText(paragraph); + titleFun.setColor("000000"); + // 第二部分加粗的内容 + XWPFRun xwpfRun2 = titleParagraph.createRun(); + xwpfRun2.setFontSize(12); // 小四 + xwpfRun2.setFontFamily("宋体"); + xwpfRun2.setBold(true); + xwpfRun2.setText(paragraphBold2); + xwpfRun2.setColor("000000"); + + setSingleLineSpacing(titleParagraph); + //换行 + if (isBreak) { + titleParagraph.createRun().addBreak(); + } + } + + /** + * 创建饼图 + * + * @param document 文档 + * @param from 数据 + * @throws Exception + */ + public static void createPieChart(XWPFDocument document, PieChartForm from, String content) throws Exception { + XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER); + + // 设置图例位置:上下左右 + XDDFChartLegend legend = chart.getOrAddLegend(); + legend.setPosition(LegendPosition.BOTTOM); + legend.setOverlay(false); + chart.setTitleText(from.getTitle()); + chart.setTitleOverlay(false); + int numOfPoints = from.getXData().size(); + String[] categories = from.getXData().toArray(new String[]{}); + XDDFDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories); + String range = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + AxisYVal yData = from.getYData(); + XDDFNumericalDataSource source = XDDFDataSourcesFactory.fromArray(yData.getVal(), range); + XDDFPieChartData pieChart = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null); + pieChart.setVaryColors(true); + XDDFPieChartData.Series series = (XDDFPieChartData.Series) pieChart.addSeries(categoriesData, source); + series.setTitle(yData.getTitle(), setTitleInDataSheet(chart, yData.getTitle(), 0)); + // 设置数据标签显示占比 + series.setShowLeaderLines(true); + CTDLbls dLbls = series.getCTPieSer().getDLbls(); + setCTDlbls(dLbls, false, false,false,false); + chart.plot(pieChart); + setChartFontProperty(document, content); + } + + /** + * 创建表格 + * + * @param document 文档 + * @param from 表格数据 + */ + public static void createTable(XWPFDocument document, TableForm from) { + log.info(">> 开始生成表格"); + XWPFTable table = document.createTable(); + List headerList = from.getHeaderList(); + //创建表头 + XWPFTableRow headerRow = getTableRow(table, 0); + for (int i = 0; i < headerList.size(); i++) { + TableForm.CellData cellData = headerList.get(i); + XWPFTableCell cell = getTableRowCell(headerRow, i); + cell.setText(cellData.getVal()); + } + //表格数据 + List> rowDataList = from.getRowDataList(); + for (int i = 0; i < rowDataList.size(); i++) { + int rowIndex = i + 1; + List cellData = rowDataList.get(i); + XWPFTableRow row = getTableRow(table, rowIndex); + for (int x = 0; x < cellData.size(); x++) { + TableForm.CellData cellD = cellData.get(x); + XWPFTableCell cell = getTableRowCell(row, x); + cell.setText(cellD.getVal()); + } + } + log.info(">> 生成表格 完成"); + + } + + /** + * 生成图表 柱状图+折线+ 柱状折线组合 + * + * @param document 文档 + * @param chartForm 数据 + * @param content 图表名称 + * @param isShowLineVal 折线上是否显示数据 + * @throws Exception + */ + public static void createBarLineCharts(XWPFDocument document, BarLineChartForm chartForm, String content, boolean isShowLineVal) throws Exception { + if (chartForm == null) { + throw new IllegalArgumentException("数据为空"); + } + List xData = chartForm.getXData(); + if (xData == null) { + throw new IllegalArgumentException("X轴数据为空"); + } + List yBarData = chartForm.getYBarData(); + List yLintData = chartForm.getYLineData(); + if (yBarData == null && yLintData == null) { + throw new IllegalArgumentException("柱状数据、折线数据为空"); + } + XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER); + // 设置图例位置:上下左右 + XDDFChartLegend legend = chart.getOrAddLegend(); + legend.setPosition(LegendPosition.TOP); + legend.setOverlay(false); + // 设置标题 + chart.setTitleText(chartForm.getTitle()); + //标题覆盖 + chart.setTitleOverlay(false); + int numOfPoints = xData.size(); + //初始化X轴数据 + String[] categories = xData.toArray(new String[]{}); + String cat = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + XDDFDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories, cat, 0); + //初始化X轴 + XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + bottomAxis.setTitle(chartForm.getXTitle()); + //初始化Y周 + XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); + leftAxis.setTitle(chartForm.getYTitle()); + leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); + leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); + int barSize = 0; + if (yBarData != null) { + log.info(">> 开始生成柱状图 "); + // 创建柱状图的类型 + barSize = yBarData.size(); + XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); + barChart.setBarDirection(BarDirection.COL); + for (int i = 0; i < yBarData.size(); i++) { + setBarProperty(yBarData, chart, numOfPoints, categoriesData, barChart, i); + } + if (yBarData.size() > 1) { + barChart.setBarGrouping(BarGrouping.STACKED); +// barChart.setOverlap((byte)-100);// 满值叠加柱子才不会错位 +// barChart.setGapWidth(500); + // 堆叠柱状图,必须设置为100 不然会柱状图会错位 + chart.getCTChart().getPlotArea().getBarChartArray(0).addNewOverlap().setVal((byte) 100); + } + chart.plot(barChart); + log.info(">> 生成柱状图 完毕 "); + } + + //********************* 折线图 ************************************************* + if (yLintData != null) { + log.info(">> 开始生成折线图 "); + XDDFLineChartData lineChart = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis); + lineChart.setVaryColors(false); + for (int i = 0; i < yLintData.size(); i++) { + int collIndex = i + 1 + barSize; + String range = chart.formatRange(new CellRangeAddress(1, numOfPoints, collIndex, collIndex)); + AxisYVal yVal = yLintData.get(i); + Number[] number = yVal.getVal(); + XDDFNumericalDataSource source = XDDFDataSourcesFactory.fromArray(number, range); + XDDFLineChartData.Series series = (XDDFLineChartData.Series) lineChart.addSeries(categoriesData, source); + series.setTitle(yVal.getTitle(), setTitleInDataSheet(chart, yVal.getTitle(), collIndex)); + series.setMarkerStyle(MarkerStyle.STAR); + series.setMarkerSize((short) 6); + series.setSmooth(Boolean.FALSE); + series.setShowLeaderLines(true); + CTDLbls dLbls = series.getCTLineSer().getDLbls(); + // 控制系列名称是否显示 + setCTDlbls(dLbls,false, isShowLineVal, false, false); + } + + chart.plot(lineChart); + log.info(">> 生成折线图 完毕"); + } + setChartFontProperty(document, content); + } + + /** + * 生成横向柱状图 + * + * @param document word文档 + * @param chartForm 图表数据 + * @throws Exception + */ + public static void createBarCharts(XWPFDocument document, BarLineChartForm chartForm) throws Exception { + if (chartForm == null) { + throw new IllegalArgumentException("数据为空"); + } + List xData = chartForm.getXData(); + if (xData == null) { + throw new IllegalArgumentException("X轴数据为空"); + } + List yBarData = chartForm.getYBarData(); + List yLintData = chartForm.getYLineData(); + if (yBarData == null && yLintData == null) { + throw new IllegalArgumentException("柱状数据、折线数据为空"); + } + XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER); + // 设置图例位置:上下左右 + XDDFChartLegend legend = chart.getOrAddLegend(); + legend.setPosition(LegendPosition.TOP); + legend.setOverlay(false); + // 设置标题 + chart.setTitleText(chartForm.getTitle()); + //标题覆盖 + chart.setTitleOverlay(false); + int numOfPoints = xData.size(); + //初始化X轴数据 + String[] categories = xData.toArray(new String[]{}); + String cat = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0)); + XDDFDataSource categoriesData = XDDFDataSourcesFactory.fromArray(categories, cat, 0); + //初始化X轴 + XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM); + bottomAxis.setTitle(chartForm.getXTitle()); + //初始化Y周 + XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT); + leftAxis.setTitle(chartForm.getYTitle()); + leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); + leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN); + log.info(">> 开始生成柱状图 "); + // 创建柱状图的类型 + XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis); + barChart.setBarDirection(BarDirection.BAR); + for (int i = 0; i < yBarData.size(); i++) { + setBarProperty(yBarData, chart, numOfPoints, categoriesData, barChart, i); + break; + } + if (yBarData.size() > 1) { + barChart.setBarGrouping(BarGrouping.CLUSTERED); + chart.getCTChart().getPlotArea().getBarChartArray(0).addNewOverlap().setVal((byte) 0); + } + chart.plot(barChart); + log.info(">> 生成柱状图 完毕 "); + + + } + + /** + * 浏览器下载 + * + * @param document 文档 + * @param fileName 文件名 + * @throws IOException + */ + public static void save(XWPFDocument document, String fileName) throws IOException { + ServletOutputStream out = null; + try { + if (document == null || fileName == null) { + throw new IllegalArgumentException("参数不能为空"); + } + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + if (requestAttributes != null) { + ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes; + HttpServletResponse response = servletRequestAttributes.getResponse(); + response.setContentType("application/octet-stream"); + out = response.getOutputStream(); + String encodedFileName; + try { + encodedFileName = URLEncoder.encode(fileName, "UTF-8"); + } catch (UnsupportedEncodingException var20) { + throw new RuntimeException(var20); + } + response.setHeader("Content-Disposition", "attachment;fileName=" + encodedFileName); + document.write(out); + return; + } + log.warn("非web请求,无法操作。"); + } finally { + if (document != null) { + try { + document.close(); + } catch (Exception var19) { + } + } + if (out != null) { + try { + out.close(); + } catch (Exception var18) { + } + } + } + } + + /** + * 另存为 + * + * @param document 文档 + * @param fileName 文件名 + * @param path 文件存储目录 + * @throws IOException + */ + public static void saveAs(XWPFDocument document, String fileName, String path) throws IOException { + FileOutputStream out = null; + try { + if (document == null || fileName == null || path == null) { + throw new IllegalArgumentException("参数不能为空"); + } + File file = new File(path+fileName); + String saveAsPath = file.getCanonicalPath(); + out = new FileOutputStream(file); + log.info("开始另存为word文件[" + saveAsPath + "]", "1"); + document.write(out); + document.close(); + log.info("成功另存为excel文件[" + saveAsPath + "]", "1"); + return; + } finally { + if (document != null) { + try { + document.close(); + } catch (Exception var19) { + } + } + if (out != null) { + try { + out.close(); + } catch (Exception var18) { + } + } + } + } + + ////////// 图表的设置 + + /** + * 为图表设置标题 + * @param chart + * @param title + * @param column + * @return + * @throws Exception + */ + private static CellReference setTitleInDataSheet(XWPFChart chart, String title, int column) throws Exception { + XSSFWorkbook workbook = chart.getWorkbook(); + XSSFSheet sheet = workbook.getSheetAt(0); + XSSFRow row = sheet.getRow(0); + if (row == null) { + row = sheet.createRow(0); + } + XSSFCell cell = row.getCell(column); + if (cell == null) { + cell = row.createCell(column); + } + cell.setCellValue(title); + return new CellReference(sheet.getSheetName(), 0, column, true, true); + } + + /** + * 设置柱状图中柱状的属性 + * @param yBarData + * @param chart + * @param numOfPoints + * @param categoriesData + * @param barChart + * @param i + * @throws Exception + */ + private static void setBarProperty(List yBarData, XWPFChart chart, int numOfPoints, XDDFDataSource categoriesData, XDDFBarChartData barChart, int i) throws Exception { + int collIndex = i + 1; + String range = chart.formatRange(new CellRangeAddress(1, numOfPoints, collIndex, collIndex)); + AxisYVal yVal = yBarData.get(i); + Number[] number = yVal.getVal(); + XDDFNumericalDataSource source = XDDFDataSourcesFactory.fromArray(number, range); + XDDFBarChartData.Series series = (XDDFBarChartData.Series) barChart.addSeries(categoriesData, source); + series.setTitle(yVal.getTitle(), setTitleInDataSheet(chart, yVal.getTitle(), collIndex)); + } + + /** + * 设置图表字体属性 + * @param document + * @param content + */ + private static void setChartFontProperty(XWPFDocument document, String content) { + XWPFParagraph paragraph = document.createParagraph(); + paragraph.setAlignment(ParagraphAlignment.CENTER); + XWPFRun xwpfRun = paragraph.createRun(); + xwpfRun.setFontSize(10); + xwpfRun.setBold(true); + xwpfRun.setFontFamily("宋体"); + xwpfRun.setText(content); + xwpfRun.setColor("000000"); + } + + /** + * 设置图表的属性显示 + * @param dLbls + * @param showSerName 控制系列名称是否显示 + * @param showVal 控制值是否显示 + * @param showCatName 控制分类名称显示 + * @param showLegendKey 控制图例标识 + */ + private static void setCTDlbls(CTDLbls dLbls, boolean showSerName, boolean showVal, boolean showCatName, boolean showLegendKey) { + // 控制系列名称是否显示 + if (dLbls.isSetShowSerName()) { + dLbls.getShowSerName().setVal(showSerName); + } else { + dLbls.addNewShowSerName().setVal(showSerName); + } + // 控制值是否显示 + if (dLbls.isSetShowVal()) { + dLbls.getShowVal().setVal(showVal); + } else { + dLbls.addNewShowVal().setVal(showVal); + } + // 控制分类名称显示 + if (dLbls.isSetShowCatName()) { + dLbls.getShowCatName().setVal(showCatName); + } else { + dLbls.addNewShowCatName().setVal(showCatName); + } + // 控制图例标识 + if (dLbls.isSetShowLegendKey()) { + dLbls.getShowLegendKey().setVal(showLegendKey); + } else { + dLbls.addNewShowLegendKey().setVal(showLegendKey); + } + } + + ///////////////////////// 段落的设置 + /** + * 设置标题属性 + * @param parTitle + * @param isBreak + * @param titleParagraph + */ + private static void setParagraphTitleProperty(String parTitle, boolean isBreak, XWPFParagraph titleParagraph) { + XWPFRun titleFun = titleParagraph.createRun(); + titleFun.setFontFamily("宋体"); + titleParagraph.setAlignment(ParagraphAlignment.LEFT); + titleFun.setText(parTitle); + titleFun.setColor("000000"); + titleFun.setFontSize(14); + titleFun.setBold(true); + //换行 + if (isBreak) { + titleFun.addBreak(); + } + } + + + /////////// 表格的设置 + /** + * 创建单元格 + * @param row + * @param index + * @return + */ + private static XWPFTableCell getTableRowCell(XWPFTableRow row, int index) { + XWPFTableCell cell = row.getCell(index); + if (cell != null) { + return cell; + } + return row.createCell(); + } + + /** + * 创建表格行 + * @param table + * @param index + * @return + */ + private static XWPFTableRow getTableRow(XWPFTable table, int index) { + XWPFTableRow row = table.getRow(index); + if (row != null) { + return row; + } + return table.createRow(); + } +} \ No newline at end of file diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/AssignmentInfoVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/AssignmentInfoVo.java new file mode 100644 index 0000000..2211151 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/AssignmentInfoVo.java @@ -0,0 +1,14 @@ +package digital.laboratory.platform.inspection.vo; + +import digital.laboratory.platform.inspection.entity.AssignmentInfo; +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import lombok.Data; + +import java.util.List; + +@Data +public class AssignmentInfoVo extends AssignmentInfo { + private List sampleInfoList; + private Integer sampleCount; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ESTBusinessInfoVO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ESTBusinessInfoVO.java new file mode 100644 index 0000000..5218ed4 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ESTBusinessInfoVO.java @@ -0,0 +1,23 @@ +package digital.laboratory.platform.inspection.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 接收通过业务id查询委托表、筛查表、任务表中得到的信息 + */ +@Data +@ApiModel(value = "ESTBusinessInfoVO", description = "接收通过业务id查询委托表、筛查表、任务表中得到的信息") +public class ESTBusinessInfoVO { + + @ApiModelProperty("业务id") + private String id; + + @ApiModelProperty("检材类别(缴获物和生物样本), invivo 生物样本 | inVitro 缴获物") + private String materialType; + + @ApiModelProperty("业务类型") + private String businessType; + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ProcedureVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ProcedureVo.java new file mode 100644 index 0000000..5ad83cc --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ProcedureVo.java @@ -0,0 +1,34 @@ +package digital.laboratory.platform.inspection.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class ProcedureVo { + @ApiModelProperty(value = "实验方法") + private boolean testRecordMethod; + + @ApiModelProperty(value = "实验试剂耗材") + private boolean testRecordReagentConsumables; + + @ApiModelProperty(value = "实验标准物质") + private boolean testRecordStandardSubstance; + + @ApiModelProperty(value = "实验仪器设备") + private boolean testRecordInstrument; + + @ApiModelProperty(value = "实验检材") + private boolean sampleInfo; + + @ApiModelProperty(value = "实验前处理") + private boolean pretreatment; + @ApiModelProperty(value = "实验仪器条件") + private boolean setInstrumentConditions; + + @ApiModelProperty(value = "上机") + private boolean embarkation; + @ApiModelProperty(value = "结果分析") + private boolean resultAnalysis; + + +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ResultConcentrationVO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ResultConcentrationVO.java new file mode 100644 index 0000000..c6ebdbd --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/ResultConcentrationVO.java @@ -0,0 +1,22 @@ +package digital.laboratory.platform.inspection.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel(value = "TestRecordSolutionVO", description = "上机步骤中回显检材物列表的VO") +public class ResultConcentrationVO { + + @ApiModelProperty("样本溶液id或者标准溶液id") + private String id; + + @ApiModelProperty("溶液编号") + private String number; + + @ApiModelProperty("检验ID") + private String testId; + + @ApiModelProperty("溶液的结果浓度") + private String resultConcentration; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/SampleInfoVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/SampleInfoVo.java new file mode 100644 index 0000000..3c6d3b6 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/SampleInfoVo.java @@ -0,0 +1,9 @@ +package digital.laboratory.platform.inspection.vo; + +import digital.laboratory.platform.inspetion.api.entity.SampleInfo; +import lombok.Data; + +@Data +public class SampleInfoVo extends SampleInfo { + public String businessTypeName; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordInstrumentConditionVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordInstrumentConditionVo.java new file mode 100644 index 0000000..4145ce4 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordInstrumentConditionVo.java @@ -0,0 +1,9 @@ +package digital.laboratory.platform.inspection.vo; + +import digital.laboratory.platform.inspection.entity.TestRecordInstrumentCondition; + +public class TestRecordInstrumentConditionVo extends TestRecordInstrumentCondition { + + private String testSerialNumber; + private String testUserName; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSolutionVO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSolutionVO.java new file mode 100644 index 0000000..2635b2d --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordSolutionVO.java @@ -0,0 +1,33 @@ +package digital.laboratory.platform.inspection.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.models.auth.In; +import lombok.Data; +import springfox.documentation.service.ApiListing; + +@Data +@ApiModel(value = "TestRecordSolutionVO", description = "上机步骤中回显检材物列表的VO") +public class TestRecordSolutionVO { + + @ApiModelProperty("样本溶液id或者标准溶液id") + private String id; + + @ApiModelProperty("溶液编号") + private String number; + + @ApiModelProperty("溶液类型名称") + private String typeName; + + @ApiModelProperty("进样次数") + private Integer injectorCount = 1; + + @ApiModelProperty("架号") + private String frameNumber; + + @ApiModelProperty("检验ID") + private String testId; + + @ApiModelProperty("进样盘号位置") + private String injectorLocation; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordStandardSolutionVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordStandardSolutionVo.java new file mode 100644 index 0000000..3592b9e --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestRecordStandardSolutionVo.java @@ -0,0 +1,10 @@ +package digital.laboratory.platform.inspection.vo; + +import digital.laboratory.platform.inspection.entity.TestRecordStandardSolution; +import lombok.Data; + +@Data +public class TestRecordStandardSolutionVo extends TestRecordStandardSolution { + + private Integer orderNum; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestResultBusinessVO.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestResultBusinessVO.java new file mode 100644 index 0000000..ff33c4c --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestResultBusinessVO.java @@ -0,0 +1,65 @@ +package digital.laboratory.platform.inspection.vo; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.annotation.JSONField; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; +import digital.laboratory.platform.inspection.dto.ReportConfigDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 实验结果查询中分页查询, 接收委托表、筛查表、任务表中得到的信息VO + */ +@Data +@TableName(autoResultMap = true) +@ApiModel(value = "TestResultBusinessVO", description = "实验结果查询中分页查询, 接收委托表、筛查表、任务表中得到的信息VO") +public class TestResultBusinessVO { + + @ApiModelProperty("业务id") + private String id; + + @ApiModelProperty("检材类别(缴获物和生物样本), invivo 生物样本 | inVitro 缴获物, 只存在在委托表里, 其他表为空(筛查表,任务表)") + private String materialType; + + @ApiModelProperty("业务类型") + private String businessType; + + @ApiModelProperty("业务类型名称") + private String businessTypeName; + + @ApiModelProperty("案件名称或者任务名称") + private String caseName; + + @ApiModelProperty("类型,1 委托、2 筛查、 3 任务") + private Integer type; + + @ApiModelProperty("录入时间") + @JSONField(format = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createTime; + + @ApiModelProperty("录入人") + private String createBy; + + @ApiModelProperty("化合物字段") + private String compounds;//[{"compound1":"aaaa","english":"ab-fui"}] + + @ApiModelProperty("生成报告配置") + @TableField(value = "report_config", typeHandler = FastjsonTypeHandler.class) + private JSONArray reportConfig;// + + @ApiModelProperty("化合物字段转json数组") + private JSONArray compoundsJsonArray; + + @ApiModelProperty("业务状态, 0:未分配\n" + + "1:已分配\n" + + "2:实验中\n" + + "3:检验完成\n" + + "4:鉴定完毕") + private Integer status = 3; +} diff --git a/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestTemplateVo.java b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestTemplateVo.java new file mode 100644 index 0000000..59a2d68 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/java/digital/laboratory/platform/inspection/vo/TestTemplateVo.java @@ -0,0 +1,17 @@ +package digital.laboratory.platform.inspection.vo; + +import digital.laboratory.platform.inspection.entity.TestTemplate; +import lombok.Data; + +import java.util.List; + +@Data +public class TestTemplateVo extends TestTemplate { + + private String authorName; + private List testMethodName; + + private String instrumentConditionUrl; + + private String instrumentConditionFileName; +} diff --git a/dlp-drugtesting-biz/src/main/resources/banner.txt b/dlp-drugtesting-biz/src/main/resources/banner.txt new file mode 100644 index 0000000..5627c50 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/banner.txt @@ -0,0 +1,13 @@ +${AnsiColor.BRIGHT_GREEN} + _ _ _ _ _ _ + __| | |_ __ __| |_ __ _ _ __ _| |_ ___ ___| |_(_)_ __ __ _ + / _` | | '_ \ _____ / _` | '__| | | |/ _` | __/ _ \/ __| __| | '_ \ / _` | +| (_| | | |_) |_____| (_| | | | |_| | (_| | || __/\__ \ |_| | | | | (_| | + \__,_|_| .__/ \__,_|_| \__,_|\__, |\__\___||___/\__|_|_| |_|\__, | + |_| |___/ |___/ +检验鉴定系统(Dlp-drugTesting) + +版本: ${version} +创建: ${timestamp} + +${AnsiColor.DEFAULT} diff --git a/dlp-drugtesting-biz/src/main/resources/bootstrap.yml b/dlp-drugtesting-biz/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..aa71aa9 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/bootstrap.yml @@ -0,0 +1,56 @@ +logging: + level: + digital.laboratory.platform.camera.mapper: debug +server: + port: 5240 +mybatis: + mapper-locations: classpath*:mapper/*.xml + +spring: + application: + name: @artifactId@ + cloud: + nacos: + discovery: + server-addr: ${NACOS_HOST:dlp-nacos}:${NACOS_PORT:8848} + config: + server-addr: ${spring.cloud.nacos.discovery.server-addr} + file-extension: yml + shared-configs: + - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} + profiles: + active: @profiles.active@ + datasource: + type: com.zaxxer.hikari.HikariDataSource + driver-class-name: com.mysql.cj.jdbc.Driver + username: dlp + password: 7990016 + url: jdbc:mysql://dlp-mysql:3306/dlp_inspection_system?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true +# hikari: +# # 指定 Hikari 连接池的最大连接数为 30。这个配置项表示连接池中允许的最大连接数,超过这个数量的连接请求将被阻塞 +# maximum-pool-size: 30 +# data-source-properties: +# # 开启 MySQL JDBC 驱动的批处理功能。设置为 true 可以让 MySQL 驱动在批量操作时使用 rewriteBatchedStatements 特性,提高批量插入的效率。 +# rewriteBatchedStatements: true +# # 启用服务器端预处理语句。设置为 true 时,将使用 MySQL 服务器端的预处理语句功能,可提高性能。 +# useServerPrepStmts: true +# # 启用预处理语句缓存。设置为 true 时,将启用预处理语句缓存功能,可以提高 SQL 语句的执行效率。 +# cachePrepStmts: true +# # 使用本地会话状态。设置为 true 时,将使用本地会话状态来执行 SQL 语句,可能会提高性能。 +# useLocalSessionState: true + servlet: + multipart: + # 默认最大上传文件大小为1M, 单个文件大小 + max-file-size: 20MB + # 默认最大请求大小为10M, 总上传的数据大小 + max-request-size: 50MB + location: /tmp/upload +mybatis-plus: + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + +oss: + endpoint: http://dlp-minio:9000 + accessKey: dlp + secretKey: 87990016 + bucket-name: dlpfiles diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/SampleInfoMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/SampleInfoMapper.xml new file mode 100644 index 0000000..06374ea --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/SampleInfoMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/SampleInjectorMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/SampleInjectorMapper.xml new file mode 100644 index 0000000..a22cd8b --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/SampleInjectorMapper.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + SELECT T.id, + T.number, + T.test_id, + T.result_concentration + FROM (SELECT id, sample_no AS number, test_id, result_concentration + FROM b_test_record_sample_solution + UNION ALL + SELECT id, number, test_id, result_concentration + FROM b_test_record_standard_solution) T + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordInstrumentConditionMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordInstrumentConditionMapper.xml new file mode 100644 index 0000000..c3b1e4a --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordInstrumentConditionMapper.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + select ic.*, (select t.test_serial_number from b_test_record t where t.id = ic.test_id) as test_serial_number + from b_test_record_use_condition ic + order by create_time desc + + + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordMapper.xml new file mode 100644 index 0000000..b552352 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select t.*, + (select u.name from dlp_base.sys_user u where u.user_id = t.test_user_id) as test_user_name + from b_test_record t + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataMapper.xml new file mode 100644 index 0000000..6d923b6 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordSampleDataMapper.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + SELECT T.id, + T.material_type, + T.business_type, + T.case_name, + T.type, + T.compounds, + T.report_config, + T.create_time, + T.create_by, + T.status, + T.task_start_date + FROM (SELECT id, material_type, case_name, business_type, "" AS compounds, "" AS report_config, 10000 AS type, create_time, create_by, status, "" AS task_start_date + FROM b_entrustinfo + UNION ALL + SELECT id, "" AS material_type, case_name, business_type, "" AS compounds, "" AS report_config,30000 AS type, create_time, create_by, 3 AS status, "" AS task_start_date + FROM b_case_screen + UNION ALL + SELECT id, "" AS material_type, task_name AS case_name, business_type, compounds, report_config, 20000 AS type, create_time, create_by, 3 AS status, task_start_date + FROM b_taskinfo) T + + + + + + + + + + + + + + SELECT + rs.id AS sample_data_id, -- 检验数据id + rs.data_result_json, -- 数据json + rs.compound_name, -- 化合物名称 + rs.is_detected, -- 是否检出 + rs.test_id, -- 实验id + rs.name, -- name + ss.sample_no, -- 溶液编号 + si.id AS material_id, -- 检材id + si.sample_name, -- 检材名称 + si.business_id, -- 业务id,可能是委托、任务、筛查 + si.order_no -- 委托中检材的序号 + FROM + `b_test_record_sampledata` rs + LEFT JOIN `b_test_record_sample_solution` ss ON rs.sample_no = ss.sample_no + LEFT JOIN `b_sampleinfo` si ON si.id = ss.material_id OR rs.sample_no = si.accept_no -- 如果溶液关联id 不存在则通过检材受理编号关联 + + + + + + + SELECT + rs.id AS sample_data_id, -- 检验数据id + rs.data_result_json, -- 数据json + rs.compound_name, -- 化合物名称 + rs.is_detected, -- 是否检出 + rs.test_id, -- 实验id + si.accept_no AS sample_no, -- 检材受理编号 + si.id AS material_id, -- 检材id + si.sample_name, -- 检材名称 + rs.sample_concentration, -- 对应的检材化合物浓度 + si.business_id -- 业务id,可能是委托、任务、筛查 + FROM + `b_sampleinfo` si + LEFT JOIN `b_test_record_sampledata` rs ON rs.sample_no = si.accept_no + + + + + + + SELECT + rs.id AS sample_data_id,-- 检验数据id + rs.data_result_json,-- 数据json + rs.compound_name,-- 化合物名称 + rs.is_detected,-- 是否检出 + rs.test_id,-- 实验id + rs.status, -- 任务数据的审核状态 + rs.sample_concentration, -- 对应的检材化合物浓度 + ss.sample_no,-- 溶液编号 + si.id AS material_id,-- 检材id + si.accept_no, -- 检材编号 + si.sample_name,-- 检材名称 + si.business_id, -- 业务id,可能是委托、任务、筛查 + ti.task_name, + ti.business_type, + ti.create_time + FROM + `b_test_record_sampledata` rs + LEFT JOIN `b_test_record_sample_solution` ss ON rs.sample_no = ss.sample_no + LEFT JOIN `b_sampleinfo` si ON si.id = ss.material_id + JOIN b_taskinfo ti ON si.business_id = ti.Id + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordStandardSolutionMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordStandardSolutionMapper.xml new file mode 100644 index 0000000..191ceea --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/TestRecordStandardSolutionMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT ts.*, RIGHT (ts.number, 1) as order_num + FROM b_test_record_standard_solution ts + where test_id = #{testId} + order by ts.number asc + + + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/mapper/TestTemplateMapper.xml b/dlp-drugtesting-biz/src/main/resources/mapper/TestTemplateMapper.xml new file mode 100644 index 0000000..5bf7278 --- /dev/null +++ b/dlp-drugtesting-biz/src/main/resources/mapper/TestTemplateMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select t.*, + (select u.name from dlp_base.sys_user u where u.user_id = t.author) as author_name + from b_test_template t + + + + + + diff --git a/dlp-drugtesting-biz/src/main/resources/template/templateStyles.docx b/dlp-drugtesting-biz/src/main/resources/template/templateStyles.docx new file mode 100644 index 0000000000000000000000000000000000000000..38648aa423b87b4c7c17de03c45fa2e6601b4e3b GIT binary patch literal 12878 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�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 literal 0 HcmV?d00001 diff --git a/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/JFreeChartTest.java b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/JFreeChartTest.java new file mode 100644 index 0000000..8cd5ddc --- /dev/null +++ b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/JFreeChartTest.java @@ -0,0 +1,424 @@ +//package digital.laboratory.platform.inspection.test; +// +//import com.google.common.collect.Lists; +//import digital.laboratory.platform.inspection.utils.jfreechart.GenerateChartUtil; +//import digital.laboratory.platform.inspection.utils.jfreechart.GeneratePieChartUtil; +//import digital.laboratory.platform.inspection.utils.jfreechart.JFreeChartUtil; +//import org.jfree.chart.ChartFactory; +//import org.jfree.chart.ChartPanel; +//import org.jfree.chart.ChartUtils; +//import org.jfree.chart.JFreeChart; +//import org.jfree.chart.axis.*; +//import org.jfree.chart.labels.ItemLabelAnchor; +//import org.jfree.chart.labels.ItemLabelPosition; +//import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; +//import org.jfree.chart.labels.StandardCategoryToolTipGenerator; +//import org.jfree.chart.plot.CategoryPlot; +//import org.jfree.chart.plot.DatasetRenderingOrder; +//import org.jfree.chart.plot.PlotOrientation; +//import org.jfree.chart.renderer.category.LineAndShapeRenderer; +//import org.jfree.chart.renderer.category.StackedBarRenderer; +//import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +//import org.jfree.chart.ui.TextAnchor; +//import org.jfree.data.category.CategoryDataset; +//import org.jfree.data.category.DefaultCategoryDataset; +//import org.jfree.data.xy.XYSeries; +//import org.jfree.data.xy.XYSeriesCollection; +//import org.junit.jupiter.api.Test; +//import org.springframework.test.context.TestPropertySource; +// +//import javax.swing.*; +//import java.awt.*; +//import java.awt.geom.Ellipse2D; +//import java.awt.geom.Line2D; +//import java.awt.geom.Rectangle2D; +//import java.awt.image.BufferedImage; +//import java.io.File; +//import java.io.IOException; +//import java.text.NumberFormat; +//import java.time.LocalDate; +//import java.time.format.DateTimeFormatter; +//import java.util.*; +//import java.util.List; +// +//public class JFreeChartTest { +// +// // 图片存放地址 +// String filePath = "F:\\ProjectFile\\WorkFile\\LianChuang\\project\\DLP\\dlp-drugtesting\\dlp-drugtesting-biz\\src\\test\\resources\\image" + "\\" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); +// +// @Test +// void testPie() throws Exception { +// // 图例名称 +// List list = Lists.newArrayList("海洛因", "冰毒", "氯胺酮"); +// // 数据比例列表 +// List dataList = Lists.newArrayList(86, 12, 2); +// // 图表背景 +// List colorList = Lists.newArrayList(new Color(11, 144, 232), new Color(232, 188, 11), new Color(161, 84, 234)); +// // 偏离百分比数据 +// List explodePercentList = Lists.newArrayList(0.01, 0.01, 0.01); +// JFreeChart chart = GeneratePieChartUtil.createPieChart("", list, dataList, JFreeChartUtil.createChartTheme("宋体"), +// colorList, explodePercentList); +// +// File file = new File(filePath); +// if (!file.exists()) { +// file.mkdirs(); +// } +// String fileName = System.currentTimeMillis() + "测试图片" + ".jpeg"; +// File file1 = new File(file.getPath() + "/" + fileName); +// +// try { +// if(file1.exists()) { +// file1.delete(); +// } +// ChartUtils.saveChartAsJPEG(file1, chart, 800, 600); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// /** +// * 层叠柱状图 +// */ +// @Test +// public void stackedBarChart() throws Exception { +// //x轴名称列表 +// List xAxisNameList = new ArrayList<>(Arrays.asList("西安市", "咸阳市", "宝鸡市", "渭南市", "铜川市", "榆林市", "延安市", "汉中市", "商洛市", "安康市", "杨凌区")); +// //图例名称列表 +// List legendNameList = new ArrayList<>(Arrays.asList("海洛因", "冰毒", "氯胺酮")); +// //数据列表 +// List> dataList = new ArrayList<>(); +// dataList.add(new ArrayList<>(Arrays.asList(17.0, 60.9, 31.2, 19.5, 15.6, 13.6, 19.0, 32.4, 26.8, 21.8, 54.7))); +// dataList.add(new ArrayList<>(Arrays.asList(3.8, 3.1, 0.7, 1.0, 0.7, 0.3, 0.4, 5.6, 0.5, 0.5, 1.0))); +// dataList.add(new ArrayList<>(Arrays.asList(0.6, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0., 0.0))); +// +// // 图表背景 +// List colorList = Lists.newArrayList(new Color(72, 161, 250), new Color(255, 192, 0), new Color(152, 102, 202)); +// +// // 返回outputStream +// //GenerateChartUtil.createStackedBarChart(response.getOutputStream(), "各级变化图", legendNameList, xAxisNameList +// // , dataList, JFreeChartUtil.createChartTheme("宋体"), "y轴", "x轴", 600, 400); +// +// // 返回JFreeChart +// JFreeChart chart = GenerateChartUtil.createStackedBarChart("", legendNameList, xAxisNameList +// , dataList, colorList, JFreeChartUtil.createChartTheme("宋体"), "千人均消费量(毫克/千人/天)", "城市名"); +// //在D盘目录下生成图片 +// File p = new File(filePath); +// if (!p.exists()) { +// p.mkdirs(); +// } +// String imageName = System.currentTimeMillis() + "_层叠柱状图" + ".jpeg"; +// File file = new File(p.getPath() + "/" + imageName); +// try { +// if(file.exists()) { +// file.delete(); +// } +// ChartUtils.saveChartAsJPEG(file, chart, 1200, 1000); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// /** +// * 生成折线图 +// */ +// @Test +// public void lineChart() throws Exception { +// +// //x轴名称列表 +// List xAxisNameList = new ArrayList<>(Arrays.asList("2022-03", "2022-06", "2022-09", "2022-12", "2023-02")); +// //图例名称列表 +// List legendNameList = new ArrayList<>(Arrays.asList("综合")); +// //数据列表 +// List> dataList = new ArrayList<>(); +// dataList.add(new ArrayList<>(Arrays.asList(27.5, 22.7, 13.2, 47.6, 20.5))); +// //x轴名称列表 +// /*List xAxisNameList = new ArrayList<>(Arrays.asList("一级", "二级", "三级", "四级", "五级")); +// //图例名称列表 +// List legendNameList = new ArrayList<>(Arrays.asList("李四", "张三","王五")); +// //数据列表 +// List> dataList = new ArrayList<>(); +// dataList.add(new ArrayList<>(Arrays.asList(1, 3, 5, 6, 2))); +// dataList.add(new ArrayList<>(Arrays.asList(2, 1, 3, 4, 5))); +// dataList.add(new ArrayList<>(Arrays.asList(5, 8, 4, 6, 4)));*/ +// +// // 返回outputStream +// //GenerateChartUtil.createLineChart(response.getOutputStream(), "各级变化图", legendNameList, xAxisNameList +// // , dataList, JFreeChartUtil.createChartTheme("宋体"), "y轴", "x轴", 600, 400); +// +// JFreeChart chart = GenerateChartUtil.createLineChart("各级变化图", legendNameList, xAxisNameList +// , dataList, JFreeChartUtil.createChartTheme("宋体"), "y轴", "x轴"); +// //在D盘目录下生成图片 +// File p = new File(filePath); +// if (!p.exists()) { +// p.mkdirs(); +// } +// String imageName = System.currentTimeMillis() + "_折线图" + ".jpeg"; +// File file = new File(p.getPath() + "/" + imageName); +// try { +// if(file.exists()) { +// file.delete(); +// } +// ChartUtils.saveChartAsJPEG(file, chart, 800, 600); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// /** +// * 生成综合图表 -- 折线层叠图 +// */ +// @Test +// void combinedChartExample() throws Exception { +// +// //x轴名称列表 +// List xAxisNameList = new ArrayList<>(Arrays.asList("2022-03", "2022-06", "2022-09", "2022-12", "2023-02")); +// //图例名称列表 +// List legendNameList = new ArrayList<>(Arrays.asList("海洛因", "冰毒", "氯胺酮")); +// // 图表背景 +// List colorList = Lists.newArrayList(new Color(72, 161, 250), new Color(221, 61, 61), new Color(146, 210, 80)); // , new Color(152,102,202)); +// +// //数据列表 +// List> dataList = new ArrayList<>(); +// dataList.add(new ArrayList<>(Arrays.asList(24.5, 19.5, 12.1, 46.5, 18))); +// dataList.add(new ArrayList<>(Arrays.asList(3, 3.3, 1.1, 1.1, 2.5))); +// dataList.add(new ArrayList<>(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.3))); +// +// JFreeChart stackedBarChart = GenerateChartUtil.createStackedBarChart("", legendNameList, xAxisNameList +// , dataList, colorList, JFreeChartUtil.createChartTheme("宋体"), "千人均消费量(毫克/千人/天)", ""); +// +// // 折线图 +// //图例名称列表 +// List legendNameList2 = new ArrayList<>(Arrays.asList("综合")); +// //数据列表 +// List dataList2 = new ArrayList<>(Arrays.asList(27.5, 22.7, 13.2, 47.6, 20.5)); +// +// +// CategoryDataset dataset2 = createDataset2(xAxisNameList, legendNameList2, dataList2); +// +// // 获取图表绘图区域对象 +// CategoryPlot plot = stackedBarChart.getCategoryPlot(); +//// plot.setBackgroundPaint(new Color(0xEE, 0xEE, 0xFF)); +//// plot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_RIGHT); +// +// +// // 将折线图添加到层叠柱状图上 +// plot.setDataset(1, dataset2); +// plot.mapDatasetToRangeAxis(1, 1); +// +// final CategoryAxis domainAxis = plot.getDomainAxis(); +// domainAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD); +// final ValueAxis axis2 = new NumberAxis("综合千人均消费量(毫克/千人/天)"); +// axis2.setLabelFont(new Font("新宋体", Font.BOLD, 20)); +// plot.setRangeAxis(1, axis2); +// +// final LineAndShapeRenderer renderer2 = getLineAndShapeRenderer(); +// plot.setRenderer(1, renderer2); +// plot.setDatasetRenderingOrder(DatasetRenderingOrder.REVERSE); +// +// //在D盘目录下生成图片 +// File p = new File(filePath); +// if (!p.exists()) { +// p.mkdirs(); +// } +// String imageName = System.currentTimeMillis() + "_组合图" + ".jpeg"; +// File file = new File(p.getPath() + "/" + imageName); +// try { +// if(file.exists()) { +// file.delete(); +// } +// ChartUtils.saveChartAsJPEG(file, stackedBarChart, 1200, 1000); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// private static LineAndShapeRenderer getLineAndShapeRenderer() { +// final LineAndShapeRenderer renderer2 = new LineAndShapeRenderer(); //setToolTipGenerator +// renderer2.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator()); +// /// 数据标签的设置 +// renderer2.setDefaultItemLabelsVisible(true); +// renderer2.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator(StandardCategoryItemLabelGenerator.DEFAULT_LABEL_FORMAT_STRING, +// NumberFormat.getInstance())); +// renderer2.setDefaultItemLabelFont(new Font("SansSerif", Font.PLAIN, 20)); // 数据标签的字体大小 +// // 位置 +// renderer2.setDefaultPositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.BOTTOM_CENTER)); +// renderer2.setSeriesStroke(0, new BasicStroke(5.0f)); // 设置第一条折线的宽度为2.0 +// // 设置第一条折线的折线点大小 +// renderer2.setSeriesShapesVisible(0, true); // 设置显示折现点 +// renderer2.setSeriesShape(0, new Ellipse2D.Double(-15.0, -15.0, 15.0, 15.0)); // 设置折线点的大小 +// // 设置折线的颜色 +// renderer2.setSeriesPaint(0, new Color(152,102,202)); +// renderer2.setLegendShape(0, new Rectangle2D.Double(0, 0, 60.0, 20.0)); // 设置图例项的大小 +// return renderer2; +// } +// +// @Test +// void combinedChartExample2() throws Exception { +// // 获取柱状图数据 +// List xAxisNameList = Arrays.asList("2022-03", "2022-06", "2022-09", "2022-12", "2023-02"); +// List legendNameList = Arrays.asList("海洛因", "冰毒", "氯胺酮", "综合"); +// List colorList = Arrays.asList(new Color(146, 210, 80), new Color(221, 61, 61), new Color(72, 161, 250), new Color(152, 102, 202)); +// List> dataList = new ArrayList<>(); +// dataList.add(Arrays.asList(24.5, 19.5, 12.1, 46.5, 18.0)); +// dataList.add(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.0)); +// dataList.add(Arrays.asList(3.0, 3.3, 1.1, 1.1, 2.5)); +// +// JFreeChart stackedBarChart = GenerateChartUtil.createStackedBarChart("", legendNameList, xAxisNameList, dataList, colorList, JFreeChartUtil.createChartTheme("宋体"), "千人均消费量(毫克/千人/天)", ""); +// +// // 折线图数据 +// List> dataList2 = new ArrayList<>(); +// dataList2.add(Arrays.asList(27.5, 22.7, 13.2, 47.6, 20.5)); +// +// JFreeChart lineChart = GenerateChartUtil.createLineChart("", legendNameList, xAxisNameList, dataList2, JFreeChartUtil.createChartTheme("宋体"), "千人均消费量(毫克/千人/天)", ""); +// +// // 创建组合图表 +// /*CategoryPlot plot = stackedBarChart.getCategoryPlot(); +// plot.setDataset(1, lineChart.getCategoryPlot().getDataset()); +// plot.mapDatasetToRangeAxis(1, 1); +// +// LineAndShapeRenderer lineRenderer = new LineAndShapeRenderer(); +// plot.setRenderer(1, lineRenderer);*/ +// +// // 在指定目录下生成图片 +// File p = new File(filePath); +// if (!p.exists()) { +// p.mkdirs(); +// } +// String imageName = System.currentTimeMillis() + "_组合图" + ".jpeg"; +// File file = new File(p.getPath() + "/" + imageName); +// try { +// if (file.exists()) { +// file.delete(); +// } +// ChartUtils.saveChartAsJPEG(file, stackedBarChart, 1200, 1000); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// +// private CategoryDataset createDataset2(List xAxisNameList, List legendNameList, List dataList) { +// +// // row keys... +// final String series1 = "Fourth"; +// +// // column keys... +// final String category1 = "Category 1"; +// final String category2 = "Category 2"; +// final String category3 = "Category 3"; +// final String category4 = "Category 4"; +// final String category5 = "Category 5"; +// final String category6 = "Category 6"; +// final String category7 = "Category 7"; +// final String category8 = "Category 8"; +// +// // create the dataset... +// final DefaultCategoryDataset dataset = new DefaultCategoryDataset(); +// for (int i = 0; i < dataList.size(); i++) { +// dataset.addValue(dataList.get(i), legendNameList.get(0), xAxisNameList.get(i)); +// } +//// dataset.addValue(15.0, series1, category1); +//// dataset.addValue(24.0, series1, category2); +//// dataset.addValue(31.0, series1, category3); +//// dataset.addValue(25.0, series1, category4); +//// dataset.addValue(56.0, series1, category5); +//// dataset.addValue(37.0, series1, category6); +//// dataset.addValue(77.0, series1, category7); +//// dataset.addValue(18.0, series1, category8); +// +// return dataset; +// +// } +// @Test +// void testFHTOJT() { +// // 创建层叠柱状图数据集 +// DefaultCategoryDataset barDataset = new DefaultCategoryDataset(); +// barDataset.addValue(24.5, "海洛因", "2022-03"); +// barDataset.addValue(19.5, "海洛因", "2022-06"); +// barDataset.addValue(12.1, "海洛因", "2022-09"); +// barDataset.addValue(46.5, "海洛因", "2022-12"); +// barDataset.addValue(18.0, "海洛因", "2023-02"); +// +// barDataset.addValue(0.0, "冰毒", "2022-03"); +// barDataset.addValue(0.0, "冰毒", "2022-06"); +// barDataset.addValue(0.0, "冰毒", "2022-09"); +// barDataset.addValue(0.0, "冰毒", "2022-12"); +// barDataset.addValue(0.3, "冰毒", "2023-02"); +// +// barDataset.addValue(3.0, "氯胺酮", "2022-03"); +// barDataset.addValue(3.3, "氯胺酮", "2022-06"); +// barDataset.addValue(1.1, "氯胺酮", "2022-09"); +// barDataset.addValue(1.1, "氯胺酮", "2022-12"); +// barDataset.addValue(2.5, "氯胺酮", "2023-02"); +// +// // 创建折线图数据集 +// DefaultCategoryDataset lineDataset = new DefaultCategoryDataset(); +// lineDataset.addValue(27.5, "综合", "2022-03"); +// lineDataset.addValue(22.7, "综合", "2022-06"); +// lineDataset.addValue(13.2, "综合", "2022-09"); +// lineDataset.addValue(47.6, "综合", "2022-12"); +// lineDataset.addValue(20.5, "综合", "2023-02"); +// +// // 创建层叠柱状图 +// JFreeChart barChart = ChartFactory.createStackedBarChart( +// "千人均消费量(毫克/千人/天)", +// "时间", +// "消费量", +// barDataset, +// PlotOrientation.VERTICAL, +// true, +// true, +// false +// ); +// +// // 创建折线图 +// JFreeChart lineChart = ChartFactory.createLineChart( +// "", +// "时间", +// "消费量", +// lineDataset, +// PlotOrientation.VERTICAL, +// true, +// true, +// false +// ); +// +// // 将折线图数据集和渲染器添加到层叠柱状图中 +// CategoryPlot plot = barChart.getCategoryPlot(); +// plot.setDataset(1, lineChart.getCategoryPlot().getDataset()); +// plot.mapDatasetToRangeAxis(1, 1); +// +// LineAndShapeRenderer lineRenderer = new LineAndShapeRenderer(); +// plot.setRenderer(1, lineRenderer); +// +// // 保存图表为 JPEG 文件 +// File file = new File(filePath + "\\"+ "CombinedChart.jpeg"); +// try { +// ChartUtils.saveChartAsJPEG(file, barChart, 1200, 1000); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// +// @Test +// void randomGetColor() { +// Random random = new Random(); +// +// Set colors = new HashSet<>(); +// int count = 10; // 生成 10 种不同的颜色 +// +// while (colors.size() < count) { +// int red = random.nextInt(256); +// int green = random.nextInt(256); +// int blue = random.nextInt(256); +// +// Color color = new Color(red, green, blue); +// colors.add(color); +// } +// +// for (Color color : colors) { +// System.out.println("RGB: " + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue()); +// } +// } +// +//} diff --git a/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/LcTest.java b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/LcTest.java new file mode 100644 index 0000000..997eccf --- /dev/null +++ b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/LcTest.java @@ -0,0 +1,58 @@ +package digital.laboratory.platform.inspection.test; +/** + @title LcTest + @description + @author xy + @version 1.0 + @create 2023/12/14 17:10 + */ + +import digital.laboratory.platform.inspection.test.entity.UserInfo; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +public class LcTest { + @Test + void test1(){ + boolean t1=false; + String t2=""; + t2=t1 ? "123":"234"; + System.out.println(t2); + } + @Test + void test2(){ + List testList1=new ArrayList<>(); + testList1.add("11"); + testList1.add("12"); + testList1.add("13"); + String tmp=getListFisrt(testList1); + System.out.println("输出的数据"+tmp); + } + @Test + void test3(){ + for (MyEnumTest value : MyEnumTest.values()) { + System.out.println(value.getTypeName()+" 是 "+value.getTypeDes()); + } + } + @Test + void test4(){ + UserInfo userInfo=new UserInfo(); + userInfo.setUserName("张三"); + userInfo.setId("1111"); + UserInfo userInfo1=setOtherProperty(userInfo); + System.out.println("用户的属性如下:"+userInfo1.getUserName()+"//"+userInfo1.getId()+"//"+userInfo1.getSex()+"//"+userInfo1.getAge()); + } + private UserInfo setOtherProperty(UserInfo userInfo){ + userInfo.setSex("男人"); + userInfo.setAge(39); + return userInfo; + } + private T getListFisrt(List data) { + if (data == null || data.size() == 0) { + return null; + } + return data.get(0); + } +} diff --git a/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/MyEnumTest.java b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/MyEnumTest.java new file mode 100644 index 0000000..41712c2 --- /dev/null +++ b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/MyEnumTest.java @@ -0,0 +1,30 @@ +package digital.laboratory.platform.inspection.test; + +import lombok.Data; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * @author xy + * @version 1.0 + * @title MyEnumTest + * @description + * @create 2024/1/8 16:44 + */ +public enum MyEnumTest{ + SMALL("小杯","小孩子喝"), MEDIUM("中杯","中孩子喝"), LARGE("大杯","大孩子喝"); + private final String typeName; + private final String typeDes; + MyEnumTest(String _typeName,String _typeDes){ + this.typeName=_typeName; + this.typeDes=_typeDes; + } + + public String getTypeDes() { + return typeDes; + } + + public String getTypeName() { + return typeName; + } +} diff --git a/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/entity/UserInfo.java b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/entity/UserInfo.java new file mode 100644 index 0000000..321dcb5 --- /dev/null +++ b/dlp-drugtesting-biz/src/test/java/digital/laboratory/platform/inspection/test/entity/UserInfo.java @@ -0,0 +1,18 @@ +package digital.laboratory.platform.inspection.test.entity; + +import lombok.Data; + +/** + * @author xy + * @version 1.0 + * @title UserInfo + * @description + * @create 2024/2/20 9:44 + */ +@Data +public class UserInfo { + private String id; + private String userName; + private int age; + private String sex; +} diff --git a/doc/检验鉴定系统 -- 数据文件解析方式.md b/doc/检验鉴定系统 -- 数据文件解析方式.md new file mode 100644 index 0000000..3c67c67 --- /dev/null +++ b/doc/检验鉴定系统 -- 数据文件解析方式.md @@ -0,0 +1,138 @@ +# 检验鉴定系统 -- 数据文件解析方式 + +## 20240415 + +### 毛发案件 + +#### 使用的仪器 + +**沃特斯** + +#### 源文件表头意思 + + # Name ID RT Quan Trace Area 1?Trace 1?Area + 1?Ratio (Actual) 1?Ratio (Pred) 1?Ratio Flag %Dev + Primary Flags ng/mL Std. Conc 2?Trace 2?Area + 2?Ratio (Actual) 2?Ratio (Pred) 2?Ratio Flag + +**Name** -> 数据流水号,目前也存储在数据库表`b_test_record_sampledata.name` ,存储该字段的原因是因为在实验中一个检材可能取两次数据,方便生成检验记录表时,给检材加标识 `-1、-2` 等 + +**ID** -> 这个字段可能有检材、标准品、空白溶液等。标准品在文件中的标识是 `STD`、检材的标识是系统中检材的受理编号、质控溶液的标识 `QC` 、空白溶液的是 `BLK`、 `ACN` 是用来清洗针管等 + +**RT** -> 数据文件中保留时间字段 + +**Quan Trace 和 1?Trace** -> 定性离子对 + +**Area 和 1?Area** -> 峰面积 + +**1?Ratio (Actual)** -> 离子丰度比,其计算公式是 `1?Area` / `Area` + +**1?Ratio (Pred)** -> 对比的标准品离子丰度比 + +**1?Ratio Flag** -> 标记是否检出, YES 未检出 NO检出 + +**ng/mL** -> 检材或者标准品浓度 + +余下的字段目前未用到 + + + +### NPS案件 + +#### 使用的仪器 + +**岛津** + +#### 源文件字段意思 + +``` +[Header] +Data File Name D:\20231019山西临猗\2023-76-4_8.qgd +Output Date 2023/10/27 +Output Time 9:39:02 + +[File Information] +Type 数据文件 +Generated 2023/10/24 18:45:06 +Generated by Admin +Modified 2023/10/27 9:39:02 +Modified by Admin + +[Sample Information] +Operator Name Admin +Analyzed 2023/10/24 18:52:13 +Type 未知物 +Level 1 +Sample Name 4号毒品疑似物 +Sample ID 2023-0072-1 +ISTD Amount 1 1 +ISTD Amount 2 1 +ISTD Amount 3 1 +ISTD Amount 4 1 +ISTD Amount 5 1 +ISTD Amount 6 1 +ISTD Amount 7 1 +ISTD Amount 8 1 +ISTD Amount 9 1 +ISTD Amount 10 1 +ISTD Amount 11 1 +ISTD Amount 12 1 +ISTD Amount 13 1 +ISTD Amount 14 1 +ISTD Amount 15 1 +ISTD Amount 16 1 +ISTD Amount 17 1 +ISTD Amount 18 1 +ISTD Amount 19 1 +ISTD Amount 20 1 +ISTD Amount 21 1 +ISTD Amount 22 1 +ISTD Amount 23 1 +ISTD Amount 24 1 +ISTD Amount 25 1 +ISTD Amount 26 1 +ISTD Amount 27 1 +ISTD Amount 28 1 +ISTD Amount 29 1 +ISTD Amount 30 1 +ISTD Amount 31 1 +ISTD Amount 32 1 +Sample Amount 1 +Dilution Factor 1 +Vial# 5 +Injection Volume 1 +Injection Count 1 +Bar Code + +[Original Files] +Data File D:\20231019山西临猗\2023-76-4_8.qgd +Method File D:\20231019山西临猗\海洛因方法+数据处理.qgm +Batch File D:\20231019山西临猗\2023-1026-test.qgb +Report Format File +Tuning File C:\GCMSsolution\System\Tune1\20231024-N-#1.qgt + +[File Description] + + +[MS Quantitative Results] +# of IDs 4 +ID# Name Type ISTD Group# Mass Ret.Time Start Time End Time A/H Area Height Conc. Mode Peak# Std.Ret.Time Calibration Curve 3rd 2nd 1st Constant Ref.Ion Area Ref.Ion Height Ref.Ion Set Ratio Ref.Ion Ratio Recovery SI Ref.Ion1 m/z Ref.Ion1 Area Ref.Ion1 Height Ref.Ion1 Set Ratio Ref.Ion1 Ratio Ref.Ion2 m/z Ref.Ion2 Area Ref.Ion2 Height Ref.Ion2 Set Ratio Ref.Ion2 Ratio Ref.Ion3 m/z Ref.Ion3 Area Ref.Ion3 Height Ref.Ion3 Set Ratio Ref.Ion3 Ratio Ref.Ion4 m/z Ref.Ion4 Area Ref.Ion4 Height Ref.Ion4 Set Ratio Ref.Ion4 Ratio Ref.Ion5 m/z Ref.Ion5 Area Ref.Ion5 Height Ref.Ion5 Set Ratio Ref.Ion5 Ratio Ret. Index S/N Unit Description Threshold Tailing Ref.Ion1 S/N Ref.Ion2 S/N Ref.Ion3 S/N Ref.Ion4 S/N Ref.Ion5 S/N ISTD Name ISTD Area ISTD Height ISTD Ret.Time Noise +1 Heroin 目标物 1 327.00 10.727 10.640 10.950 1.970 142994 72693 0.00000 Auto 4 10.695 线性 0 0 0 0 0 0 0 0.00 0.00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 521.57 ppm 0.00000 1.126 139.374 +2 Heroin 目标物 1 369.00 10.726 10.680 11.170 1.950 93699 48039 0.00000 Auto 9 10.695 线性 0 0 0 0 0 0 0 0.00 0.00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1010.38 ppm 0.00000 1.119 47.545 +3 Heroin 目标物 1 310.00 10.665 10.630 10.675 2.200 130 59 0.00000 Auto 13 10.695 线性 0 0 0 0 0 0 0 0.00 0.00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.32 ppm 0.00000 -- 44.735 +4 Heroin 目标物 1 268.00 10.727 10.640 11.085 1.960 93834 47994 0.00000 Auto 18 10.695 线性 0 0 0 0 0 0 0 0.00 0.00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 648.39 ppm 0.00000 1.115 74.020 + +[MC Peak Table] +``` + + + +**Type** -> 表明是标准品还是要检测的样品,    `未知物` 待检测的样品,`Standard` 标准品 + +**Sample Name** -> 检材样品的名称 + +**Sample ID** -> 检材样品的编号 + +**Name** -> 所要检测的化合物名称 + +**Mass** ->本次检测的质荷比 diff --git a/doc/污水检验鉴定系统文档.docx b/doc/污水检验鉴定系统文档.docx new file mode 100644 index 0000000000000000000000000000000000000000..8651e3d91ae4fe7426f756f7794948735c8a7a30 GIT binary patch literal 857237 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

5-jcR-!x; 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�Ga0hxRTr8AtcRm&^VHiCf$~I_l@{} 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⪻Vu}e{_BKY;PdbhKFyq&k)`CgCf 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

}wLL*W)tbLY%?pAkXa4 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�_UyE3n8sL6JMK3+J=dM8kwqlJ!Xu?4 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≦ZRqhOt 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

!Ns$qX%7;H^lb^LtrCaY5A;T8Zi;ps}F{p^&sH zWo5*h>(N;8X9RA21ISZ?m$j=Sb1*cYSnwp7abUxGZ_q$c#;P%4-Q^Z?XZqKGcJeTT z_1;(k^HZjEd9LfPKMPV4!O50Ja-7D}Cj+M{PpuO`SyKHSq*lhFZ`#re5mYG@LSt8i zzep_escX44ZACSQ`%W3dDO-V>%EPIiJrX4LFkvy>Ub8fnTs`jC~AHbbwX?eKAF>Zq#lVC0^YReZttItkBre%OO;PRpQC zuzzkP*RY|p6u16HOkJQ1Th+K%bv%*g`N(#YGu<`;aKyM;_1*JV(Z&%PA`MWYcT}}} z0i`hvQ~#ICzhbzV(Kd~z*2uBB6t;cDyM1;@dkZ1l_&d?;hhE!5HV#iOtC;Vhr}g&X zLd4C4G+)78+~8{thMo z1622Yf2i4hzkSdR$8b+vtF$ z^|zXrwuiv|QB&a})0Nd>*G1H)UL|P;!<{E()iRy7pQ6e1>ChD{9YB10^v}qxk6x)B z_uAd#mm?Nct<+cIFGQ{$X{}B^IPIdPlN?1+B#ueXt(Vz zrA?oE;`m}#>!jK0=^qz3$!*)m*1t9+JQrE%5s)jwWE2)06Mx=Bi8t>_5IBWI+nc*t z;l*vMj`}A&%ZceXz*0-8TaPv(Y}qG5giMF&f#Ok{&H~5^$^%=;#pIEl7j#m^jz~RC zhCd83-n8hAzEinRtPbednzjiSaH~}@cd|RE3)L#M)4R|1Dw$14o9{@yAty>x)0+eR z$X|NjW4^q4rv&JYq;+Y-qp1fwNIX&9Slf}%=cdiCF2I+P9Hg8)WFVM9B?+OLn&okM zawx><8#vN#Q+_Xg();)RosRlygy<`l>~1QMd;>VRRI{T+Fg4s0IEPIBOArW=boONPa+|0qDEl%#G>Zi5)LML-j0Qc-G*s;g(q58e#7uZJ^qRY9m&N$3AJ!TE}~*H+Dgjt#+pK3H1)|I%>+MGn#hpd zS}-|9gI31d;<3gOKunm5N%1@iXh_Sls=0&IAs^vDpJfJPzg{&6j(gFCK2S4)8pyR& zjAJ8o{j?PmXp#5-FpV11xgOabsP~xMyf4pTgXp4~66n+reGe4LHEsY61=LSaC{!bA8su(q=e@8ncpt*j|-bZFVq zDr3diE(lr{KW(|%dCo!o2HHfgwBkvb;p#V=MqA!1xx6hT`|m1Za-7S-jfxTgiX!Ok zBQsW`+uPhnb=mVhkRdFsfIv>|HzooqNJ>MLgSIDkCO-Pa(XROC$RPws-Ip6XH%*~+ zn^imrb}m`n7q5C}jMCVYOMcF4`ucsw?x_^m~4n)cGDh;Cx;ibE-KZWNG z%XlnB>8uG%3gJF1OpTdBrP~X_3y&KxZ-apz816_OX?LqmKNdocRlZtEA*LMj^DOzi ziR@N+s=XpeBoK0L653>M#tir%tbbC<(j2r0eX`bWZDPHGKd-{>%7k8b^@K{J<1Y65 zZ(xeQSI#ABOipgi%wfm7sx?H%XV`fUqyeOnaWHR z4K&3RX76E^bCet?33d8J06E2kUa-WQ%k#ZK%cLvro@;gdZqj#&CJh9^T*Tlb>13FV zT8S{XBG(`eDuug)$xodB@p;KzvxyPH_i?ukSZDo+oC{eue8r?h5EC%LeBeM*G0D9yL+g{YZi8SNZ|P2Y$tBGt;Y%2A2hNz6m0+ePIIt3l z<30(b0jN%(%XWQtX5_}t1%V{84t?}2G2XT|W1#Ubj4$OHL-RW8u}}z76bCPam8tqt zmrngsb0*Y@H)m26tnC%01Asxz^04a`$zY0((91q>Q6nL+pX_|`ISCJV7M|;jw?<*5 z$VI3;zSQR$1hi%N1Q!}+vOQKYo_%(V|3{m7U~V-rvM^ui?DrO83WUMm z&gdcR+4V1+HtaTo!-s!RWv_P+_tq80R!^xbf?qY8)H_hgxdeyzylk2&w0y&@W0WH6;pxuWWUq5b6;EfJB zY>dZ;vgHf|B)UREjgE?&yCu5L7FlQzMNu-oWQ8(W*LVQG}Jz~fJ7$re{vdkb$*5L`8tB|eG3rMFV&eCFP{pPtT@>HkY|Mu z9J>i{0_!;dZGC?z&|Y5aF<#wAAHpVcaj`@FSk^RY)9A{jD3wZ$zfEav@E0KNx%UkQ zeXX%UUPTgC+Z>4=m`K@ZC>TC~1HoP*C%S5$m*`i;_8*xwrF>`cqb~8cD~N$EvTOF{ zPkWf#QU_>re6@;N`t$auUBE{c^l5Fo%XCGTJiv*xN9dLkxARfw$WyjlN4c%SMwWTP zw`9`>EA+IcNTR)<1nE8W$7ma0Mt&5bk=Fr0j_j!qGO%w#&%ONax{B2?$#`3X1Ah+T zKg5&d*cQ+32+lf79+^dLdL(ZxqdAwRTPb}V{>vZX>*O8gbspLCHg#ZX7}P~Q)@i~^ zd_7uIDv0)Z_(?aSU>r!1J^W=zsN577XrdA~|LJuw3586UV@5f-ua#as>LCyx3*#)v z<-6t$j;()aLu)7`=?D`?P@gQlypGP`12c3xfmj%y31;MD1>)5nTt5Enr&I=17EW2c zHp*Ja&ghtA-Iok)o}@mczM2w22(sv|)E~^E6^NuDCB(x$xUiC#aJVoZTQ{Pfw*Ozf@eNqpBm@!q`Te6hxU;oN>xNV{vRci_#zR7Csn^@{!o=*7_b zhV_mom(G@HH!2XMtNn9?H=uPg?l^30iOBG~Ocj)+cXz!UrR`Bbm@)p6#GWm3Ep8Ot zfbBAGVWrS#o{Gzue)n&g zkqBp;0=wIIJF!u~G7r579;w7SLWkc|LapU*rnjV$sI<3ok$`rG1^-upLQndKXV*~m zQ-XR~0X#o)f?Y2<&*BKk)_Zx5|Sx1MA&)cz6F26MHxhT@U3oF9)gX2+;685@deYnt11Qv&o*b-t}AsJLbxa z7G7}mYf!jKI7+hYJB(3Br@*!~|MaHliy>3L7M>#VL?04p7G+dd*_L!9KP7Y3++OwC z&l$xrA{IO9d8v#50foC=Bd)rDaWHLC$&h=AoxaxF!|1g^wrS+Y38{L==tQ?yW{AO%MT zgV{EOvXFe6d1+VpqPPf50cBYrb&VD-xGlYjSQ=JEDovX+xfK zu)2VfK`NJA#jIW_WzHrhJ0I-_(7jhasJkN}E5bt|4=` zB{=bJlvehJ;YSzxQn@^2TWXguK6S=ZhB&iXCm2i9`zwh<&vmf~%P+t76_%S>=q zk^G63qu-y&$4o{=&svNNNIi@tLKa?<-Sp+M&{?$Er{!#=a9I^StYHl?$rC77Wr?72 zX@iGY%nvW7oAWVFrA{X&gyZo$O!$xYwVS_frkYsLSk8r zD}Yw6Q{7Vb(ihTG8D*=>d(CD``wH=H>Oq~gC^g^NCF>i7bx|KDSlF0!vyu)xzu(`_ zrnYgOFaB0@FwCiL&u(Z(B`Nbv$%117Da}IWm^7)>j+)|^WeCeNHpl$Vql0pPL+Sm* z=Eieq)u6Spbh+FkoCYQZXT8~$b=Xrh!LFuF&P+VpTSS8MR zOe;B#ZO6(lIsIKGV%h3Y?Z~1V!|_R==Abs z0sOng&FC7xf1(%G=(M|gsskeUu^qn&WlhlhE6J`E($#<0%iE_i#eb-XO^O43_ zlEqyeG}Nf8>rO5vH{xp!l@aGnWZIIKcoyzCTVqY1`!=e?6sFoKs}UQIpwK5yb!2U- zluO|)9US%y9!^cIU+x}fbP9}$R&A8~6Z{Y@(@K3`AsjT+h1KXY4e3;d7yfJs)#p0v zSmt8gw{um!vDG~Be_-=!`G<$L{+<~zo<*sV1@ny0Rp9Pxc}(T~4+1TC@gRoj$%tre z%k_s8s`mzLaXH#&;<8pl!)A->^r~}#QF zLJM3NVu!xJyU8gmf5mIMK)DD431`T3t_)%3BKjO?w}K{Me?!lcm+q2jx$52;+XW}f zl=U^VcUq1M?-It{H}(#uLjZIw@!SgnAsI`E2r1F+m>WF(Nf*E>7=CS8Ea$~N zjxKFQFz^-%H1*7Mz7lVpO(&PSKRz%g-jg1fTlZQ+9wd&2X`Wdaff5kMo3tmFI|%~A zR?N2@V6(CPU0$kiCg%oM5ov%T?~WS27|+<(CS$)vUwt zvodsR7YNW_xFRnrSvDUFUD>4zU@~83g1_@v;>Z^}By=|TwTM}Y=K5o=ZvXB3D37=v z6b08Ss_~|#1%Kl6Y?RbvCxp<;jWZtEcq<$4v74y1{(%L2W3S%Zlbx4Yw;*=Cr(J+S zluZz4Xk<9PzZk$`V|}wM^%G`)DW|7SH}kAt4_fx_YeYs9`46{%3m8j+_^WaC7xw&4 zmlKmG6)7MUd=9)V z{QG=GP+Pb1Fc%sdS~7oC^Y;Bd+}}b%5dM_HdRErQ?eqJIu?Gd-81r{4POwMrzO9+7 z6ds>$ct+Gwnan&mjLS2W_v1(s10J0>Ww_lSPX}NF8DF1Jw-k`^Y z#9-v8G38X+!0tp;-u)QRvHFWM+~F%oFp`#lfE}aesxx4GaEx ztQ`%0hj}6Oa=GonjE0m4#Y#M??=!OcYH?$rk}3EVGWE6%1QaKC8d#*2y=aep0BDoE zW!de4f@Cj6o~nH)e%=PGMYpb?44_o(&{XWo6vOQvBi7NQ+Wt7sTD>f!_m5=x7vO7G z{I#ESy{6s8hIgmO_+w=EwdU;VU|pGQ73JT;&|5{G-IC{iV7~<$>3bJEV+47QKrhX! zFM&f2I2=0@Kc7$Dq65<@P6Pc}0p z1VAFzyNWUojtRx_c)RJl3Cg=n`g%O49FeuloAqv|KW3zzJ8?6r4VOSe=ogRyRIa1S z`Tx{o&N}@+dQ7esED)g8HHQ)x+*audTkps%1KAjtY;(&=YI+uD=Ls=gW*YKoNJ0wH zWr{DE16?@)8LH!{PuBypKLhQA%y$J0F?DW?H3*W8EvnPwAoz|ZM?0I zE}0vyu8<^+Qm;#!Vhd$jDx;;LMaM$gC-V3E%+Vdy``>y-&y)LERBwI$mRSZnz5S+! z!MPgrk;+xzYrkNr!~_~llZza+6cT1Aal32@J!Z#lEqJM{0Y zAs<3N$=!vS)dr1F4)%RP8>gfdp&@NlN4&TX6hvR&NYBkFuAO@RL9|11fE6u6Zft}_hp2r=0MQzplI@g(Rq9Rcg)xw*2f_5{jMqe=Mpo;bUA^z5J}4=lqoKf zU&^=AA0qq_x-|F!e1P2>`-pIs31kj?8 zXF3FVlNozUP%p4lAu}gGq?&mI!wBoIZe9|C!zBqBmm+Sm!4v-NNQeV(vk)va4zLNn zgApF@f_eyby6JiySJ%Jvj(ch;Jr27>p>GR+bmD>h*j`d4U3nr%&pP70IJ7pazZ@GB(V4VEYO_iH>WdW~lngh%G{8624YS72~-R7}V8zs21Ee}Gd z@$yFAoahl=$y&`l0`F$)+6AOE_{Hw8h|20&G5NI`LGX6(@$ANLH|QpH34vH3<79J> z|IM$dBvH_Nd+~#Wl2v3H3c8h_HSAGps4P1{ zlvJQ|6E}u-LXUfHlJckS1l0tJ!%|CfW3M2riuWQ6@0q5C9=FG=8w-ca=KgWnacPh? zLqCe+V&o4Ey#XNeP*{Z*2PtOL8Ic=wrGYsLnYjnibYf|t7y*})T8)D~c!sDtEQ%N+ z69`J_Ph2lH5DwpWu7hxfs2^WtqR5R(wO9xXz2fg=E2pS*p(@z9)10(9F>a5c+ejP}Y%J7M8lsP#>s98nR6fEW+dE zF#QsP;;LQ!CpRr9!=7(uI0;3cNHreUb2--04oi3t@KmRjlgunPLLM%6(*;XR{Z_6x zaD3;|y>>F#723F|T@@kpp5XY%0i<6i2;h z(mrx}8swDuopGD(olHl2yjDGc+Z0AhqB$N0gN((8wB50wtMv0{9MwAu%ytlKE~MIMKtc!YQa-J zX?fMp^tctRjYgk_^!3ZPp@d{wIBs1a)n*|QreTHg?pN4t15(<;+y-gtv;P*KsPt6l z&gx1>>f*ea?8Dw7=g&1M2MA1036t&3&ShtonYWN`@}F073`KbizWd!sHtB;%3pA&t zaLOgP3at^$n_-I>#^_T(fk%T5E{M|WhIQ>W)*408_38rB&nyE~QIZyWC%cPXDqf5` z)&w7_2NrwPx9yURX!+&(82<|}IiD@vlsgbhDA0S7C^Q}lnlmS&8yt!LOWomt7o-9# zP@n|Qu@?B@MxWmC1OsmGAZ5mEFW!mZd0OYMH>Sl+wUCIDvHdIA8I_*_Y5MGq2B85Q z?}bWe{|=zpop<_Iz1|9y5zd#=F?NAL=<$T_j=go4Zg2HoDlat;WR49ZC(_EJ&q4xg z57Oso5mP0`S|W%#$ALTQ;LXl^LEMArOuJ~hfg$1YBVjvUp@Yee}y6yVl{EF@1E zLpcBaI{jf-(>AXP-bqx3;c!;9kxrgkC4}BK;eC;W9we^+SAp8S?BBQ7deD1`n$Yv; z|IdoFSHao&Hzm<{XwdtQgs6;24wu?ocZlrO);dV&lMDt_vDqGuRxiWi} zVjD&mMC<8=sB1TewyX`{H%Z=Jz5mI6 zgX#G$z&(fu=JEYbY6=E8>IDeApP*lZ0mqaaWZ>8h>HYo`M^{G|rt?~;ybg;Og>o&%#OUqof?Ywm2D8W5qW|8n zjXa_ji*c-ujTM|}4MB0yvRqXU%=O7F6bs)VSn92I?OrJ-#NG5 zt5@f}y7yL{`v=wRp5EQPyH~IETfbg=H|Khi;18=3v-BlIcmNcv(aBSNuOm-%RL9sj zI@|@2^Yd_kE~ynI3V^OhtL_gDXLqA8sw+iQWJyF`Rt;;$6u@?X)zYFy$=D9|$Gli0wp?M^UKx?JH ziKgJaN&34a3FW0HL7-nO-hCkf3dcGvSyq0v*24`c20PolD7Pw3(7EDlpdl@Qw|u_=m_{5`i7Zr!1pxQ7vln)kD#s&64i1_|4YRh zfuvkqftjqh`M|X!1TQh>DX3JjzU#O9GTbeOBLQX`7CBuG9>4ag*&ef#uFt$rBL{Od z6 z)(*;3L(GMDj+_TlmfUpMju+5(9Ev}U_F{Rs&7QYKG4=FHA04h}1*nZDfW9)daUmmL zRJeH%V9RI%Vi3m%s?k(T0Dvdg=h&5{-A|wE2id^WTSm|b>*FE9`(k#$6HMSDg?y5k zeZP$ZM6{xUx&7^DCU+-ma0T3u1k{4YS*#Ak-R6a#H}9ueTNI_|t-o}*r&kLTWt}Co zxh1~u^E4dS1f3(I5FzC9d>xd!QsgHa&1-K^w92{&`cM+*cB-y(?=VRxGz~Tg5R{Ie?z7#?%n3zULF)*W)g#*`jvStVN?J|=u>Gq-|-_pfC!iag(suKQvc0bOnF zFMhIoIOdZ2<%f`WHHM&YXY;k|-YrLX=VQ~k3>yr!%`<9CyN-DnCjEN&SZYCh0L@Cm zYz?nv0lqaV`3=VNfkp7bQ&X2%*_T?)rxln9Ld3$Vj2<~OV}uNR{F`Di%cATk$5T%_ zy{i*d5BpJz47$wE-4BlchN;q;BlVuqRW^PedREeQ#gd@$EQfdO78zAztW2{!-* zojxZ7`AWNbC#cXh)S7vz>NauE@xwS{Fd?^ce=B==i{ z-(9m>=8KLgA|SqlqoK@ek*2G2SI-(pVcTe2If z*r#>{^vdxtnV%7NAR96&juyDC*-<}oqf*;EeB_A!V7uVaov#zgz#93Zjb&*ebJF)F zZa0%0&C=FXU`fBrW%r>0DE#ug-2cUp(D17T_D}DikT-!o(;aQ|KC%Z0PoR%oG}`vz zo*GR=1X;+y_I6W`VWzAEv()Gj4?~=!oxHe>Zcv15$C`M;5~l8k@CALtcCjtx_~$8> zEykML?wJXl79vH5Rl+^1sXpHxnFQiluNnZQ8hsJzT4r18#o=gM%}t7uH7!t!HLLBm zqyySgOp$fXPuz;qAxmD17`Z>^#ke>hj*tJeaRoNKS1_{rxvp19b72;1rv8OFqSmS(1>tM`A8 z{|>{NZ3#~Q282wfg)LpJ+v;bi$kQ^jPrxthx0`Nsj0Yp`RmNpG{?&qXCHTe6X#ts$k z))BRIW3nnXE6|X zfPn$aCg?5M+;WOYho6f3_D z;$P!@deZ}K)@8zc66MeQa(lDmji-F}^3Sy|iuMpTTdl|_O1CP5txlA!Ln|#wbB`^9 zln%sMOGwEk!Ywzk9?q6I5A#RVf@N{o;lBU8{p+|M8YBVx+v4yLT_3OBcUY~0b&i1-X0Ynj;`>?JxzjGj`{|Nlx|YUlg8;1^7h+nW6vMX#e>!+ zdMshzR-SYMillYY$39V#ra7NwYY`p2w3p2OMnVFJh`8s^_UJ~7Sj@g)J8g`f{4P6` zSO1{FuB9Wu&>ZYg?V3}6MmwNMzZ#&DR!2u)Udc`ZN}fh2!XIB?q4HFRaCiBf+tO%! z`#^2)Q;)CcEYZrx&w0|U{RJ!-A^DDAN%)RJ7e`IQe*>wFIF47x&NLh?+tXgGYW;b4 zoVMgz>jUuRc}vaJ`yfFr`lIvcGIaFDs3bko8LZ@FTr9c4#XDdVp~~Zj>7^Op>ynN= z@NQ%2$6m7=I@PBNYsb@R`0;mxj+Hx#{AZN}GBgXj$R{;T2$T#bRAdPcn>rPM-k>C# zey6qK^N*}dtep@=Yi%m=ghSzYX&t5_>0-fe*`%*p1#5 z1b0g6TZ&KIx>Q4gZZ46=Z893><;l7ouSy{TaT8>iT_!XF=M-@w4e{Pe$*h->`IPcJJyS5sqC2m5U}A zRLuRg{9bW5$2G6(g09)&kc5Rci{?c%#}C4sLES_1^DfDsN7&-X(jA~%-wx_^(~%jN zB}MkaUb_aIxh@vba83~f%ChlM^UO%;tm(-m$1S1e+eJOQ4nS54hpXvX$M$q?Jqk*E zVIHd}{~B@AtLHk&|KH}|TI!Phk^j@YV(g4`%`j&kMp7W(8a`P^mqAi^_FOT3XVWqD z(*&(V$vK1M;4$3k`2!ljgbfWaDns-AQ}l->VNUjru5M~pCVCp))cMTG=bPtbN7s!S zBRLPb>uL-ueTzU5@%x^xY;J?-gV^c4 z=ObY?Q*`DdXu({2y$UUy@zyOqpkZ7Cl}O`W_?`^hQLPgG)}v_NGqf8OCVh5dudinHYV9L<*Ov{2N$9*CC9+z<;U)@}{OBnK ziNb8NKd=B&6zJ;b%|SSM1C=Y!vUx7gQty37>!KLFAJV_j5xkoU0mKDt#_`dl$5NRk+BL1 zJls3Fvg&S$Z{tYQ@~Ew8gS|j(g>JFKK-{_$&9}X2^6S{7)pjBVvZOdYgT$+Pj=g+9 zTK_8Dyx*8Xg56a*jt2WN4(vCCkra=!y-VS%rOd3?f(a}B`Hg}E^&weyL2(De3rZ+% z2EvA|-eZ*Lv%MK2UEPmU5pn@bcc*A$H4{3wI3|A65>`JEK%a$8MoYKp8|9O#yEd@a2GhcYY5F;gwhX>ez8-?0Kg%ujGF@2 zYVn#`4I>#TZ`NkNByfdM)h*!H|2wMzMy6I5^EaEy)HapXESUzGf)1YMCp*y5t2D4| zYCumIPWGE8lC?K4zIhMC@3`W|&Ws8ZL-q3>7RS&{wF^a{NV8k4bK--Po12{hA19~vx%S>hppIRH0i?6%hz8~&p z1x)#sJe|J*dyzbego(6k9scFQ(3WINckZ3#$O$5`_i)&`H9-$wG5cNv5v!0Y5{7bYzbz)3lVhP%Q6D)g@scj$%Lb z4ANI`BudC?IpKSfmua3rT>q{yFDE!2TrQL7rqZnE(7XvPzm>9W;S(Yo?mGZ~3+1RD zAU{5?ta|o@G|>3vu&G`XmK?$9Kl5a!Qsy~7kjt(QBbPkjd{3$ATv1FO&V=!&iVQ1X z>qHn{3V6u;mp?6S(LmLrx%{Uc9;hbAQPQp1?nYAfVee4Kh47lQ*gf9d_suPcM7B2E zTns0b9A;j*_SGBYxpPw>_+;5CeNlGvZfP=J|_5!v^zbErAt+kP0P^+ zW$$d*8P$T)Sg29NdEQzSi_G zX4+TN7|QVdPW{FP=t2L&m#R#Y%mmYY-j!vgL{xu5-(EUz%<3=Z1P2ju^!!$)JD$}% zlOkB^WOp?4fq_2%Gkh$mfbHTyW|v(1EeoYrDp=Hz4swh7YF`ci+wALqaL!*^u7CgO zJC@NYv*pc`#ku^5@il>q3Rs-AjI>&~PyB@w_h{NEd-u|Kn7U#D*=SJvvud%A4(aF5 z{2W$D@>U&AUVe;K4wm_Ee^0V^g`Xb6=-@wnHb1W}bsqF=8&V#67F{A7zPh>TXt?w- z7JE1!qhk1tiI;fhvbxBS6|Q!llXD(J6%V8tP@6VqQ*RXatXW5*$%ki~cOuk~iwCl| z7gxExaj3jqcZxOO>v$|umN+imKc%)ZcRuoS-ed0G$uRC+ii?H?k z&?Eut$ys8#DN;h<2(BZ_{Xxbua&e@7V%}uKyDOJ8!IsXhZil^qh5%Y35g|Qc9|wQ$ z$KGI7S!VAxA-U;Be>vbhTc~a+L zvN`1i)m=ygzY++WW4AU61^A%WJVia*sVENy|14A-Jr$Z`yR*Qj$G+Ti%MG;~w~qXdsN2NqZ{O5zGm=ymVB-rt9*tgg%x zx&7xxltx`}5qs)x`J+7VJmeSkUHZ%$F>=-6v2t-vaQ;HNXoNuF@H+-}UBn zu9&qYs?wAtuAGi(Y)2ng%CbD0YK1?8*3K;#o1S#^h5;bF5R+sYNunp6*M#vwE9_3W z+A$N~T$5QY!Y$?ddyOc&`IU}6*tvWd84J6?qmR4m)nvLWIo{eGCfWbD$K7RM*FW#3 z)$Q@TVOX;JThq3x7C%rk^+%BNFNKvdwif*Ap0f0~*4aSx0|YOyX=Z8D zy{eZB_>D28x(y%dS;F+Bvx||M3be;NVzMkoSOnzzlmW=eOwZ9g+$ewq0c+?X^`OoF z;ib#!f`jI7d_h2)i|0bsLku!fGCh%4CyS8PIXUxc5jEMYv_;2GwX)f*BIz@A{dUVtkjlXS8KV~V|mppH1Iv2l+knhg#_1j&1TC$f~$LA-rq8miWje(%bVPE6L zH&N4*jg#NYXLi;*V=Z_ioK5c5UXG>MdKi3e^9G=9!JM+Hz(p84gN=<#nBM9_P~3LO zh89G0cBi|(KWm4U-Ku+RJ4DsMu4Wn;>R?PlkNo`&auvjZixTC*X3 zv9_DHr+V5R<GinCJlfEwPcZ0XgXceb0`y7m<& z(qk=@N*D$mz}u^>!@ju=XjGrrx5ZIZ=s1mh#aClWiOPQ!CZ4&ct%p$#fw}D`0t`?tLai_3FIfQT(seKT-xWTeh-Ng$WVm+|GWDoDLNmu!j% zV2wqea2h9A6-Xr+{51vro~y-&j$?+~>I9glls*Z3ag{v?SVZR-F+Vdlfxpvn#7oc} z|J)-u45-;|(*(4Jek}E!aWFPX&$<}X?ks><K$c~#&c>0RtDZ09^3{4frI_d>lnV<~ zZhRG5J_JLU!OjiwHU?v3>AGuchCDHU_?4Jh=k01JD_1+eYi4J5cbj!1FH*VcsrB5r z4P6J>-?Em5SOd|Y^`_4i2Do}M?7b+n7ypzVsGIKhb7@tLxnQ_43k6Zy=#((*s_7$h z3N(jbfv$DfufLF$4)}}4SIF}iMA(lIa%!g@U2$VsOtE0v3CSOG_V}`+?D4)jnTB^x zfc33lw`$|YnQ|)%av!iu+1AX;foQ5Yrx4~J2qU&zbT;NCH7&MaBEH*hsV6gfqN@Eh z*b4@G=)_u{eP1`r+u{D__rwjWaM|GC-rBy#z5g$6saG8az^G@Q3>c;HgDW}`{7-@o zT3uK7Tr@4L4z# zkJ?AM%Y#k+(>tvP23=)n#5)<-R>+S?7Xd$IXuJtTyP6+XEH{~FO@wVt@LgxnFAi95 zCf|e~A#4rzoPX=Z$7Kw5Q^tiA@}P%$f2ws_W~Cr74EhLf2Fr@g;zg;d=~;MNVZ05y zglm_e|2GKXsi>nn=N&Ag0RI1EP{RL4=!5<9Y4_ty>1!{4*j?=ULHAySt;p(Ob`8ME zzU-6n540!)r=49~X}VTFiO+B!e&)}|Uh+JL9%?{^%n01CMd$7A=NXY0aLC$U)Wl_| zuBZQ@^(a+KH7i@wT!cY^H~q-wFBnm@9gh%Lfy7cGi3Co;fki7|^Zb*GN_@YX(M{BZ zaq>yq7yfrO4>~%63od)s7@;u*KJsYu#*f-+$0!fvpk!A3q__d#j55f=OpTZ6%-KvLNXIGgn9;ricp}io-G-dc+@&#@^Rr zvvO{AJW1AMyUS_xzc0VlfKCQA_pFn;mPy{4`qxD`>^b8H_T9Bl4YN`Lr(1Gs2n_7LB<|B!g3;6nc;sCu+cpHTKva6%%VwYGbqewcqH*LlAN+j_iZHa6=Z8}@8pU3Ue_PZ z(pWlPWa!B1gfUjQ2JUYx?6z-IeZm1XKBPue7&=1~cbb}e5~nl@iLj%24EK)|t@`eT z166Y8WfFvE*9G3Eu!CjY@&ADv2ync6VI^QxPTt#B%wSj-*z-E8r2NDOg$!_fFj&?8 z+kol5)bKFz4DPF64fO3}DPY3YHHM2^&w4{3H$>JN=4lIHj{GPT1Hz_lj9na^FEp|5Yt`N~ongpEOS=}V=AR}#!p@(Ud)N3?H$D(ibnu`{*nve| zA=%c0v1z9v)v9lNbWfJP$e>es7zt^EL28CFPbc`~mO3kkF&@b_(exj< z(xUYT^4c3jD)F9rtap|Ewm@+S%fsKUbzVSWK7c#Nf=J5lJP&hM84R@u>NiYd^ z?&p5atlyztS}>MS;-JAuzx!ujSo-;b?1i8SBWzZRFh|njGCI{^xQ28`O32C; zl$`odXyWwzJl|QnL4Zx_XKLB#7B*tnfH&L@h({tDh&wbKR>MHpauofFJ)9NEfB{Fj z5%mJKf7$bU>c%f{qx^W!Fz3)V91ra8zl?w5{5SrMM|`;JzleWZgoFD>|KIqxW~!({SR?HpF{AwC6eQZ4&yw7CtH~;{glnxjv7Eh%%4}{GhwBAu$uP%H218F-l<2_=!o> zi`5RTLyz*i>Qy~vkeVil3o3AbeWuI--uI+||$PpDq zf4tSY&7r#;WRac_w!ivw+$nhV=N3V1G0Vs8CT-8-`!4Uq)gOn|oEt~u z74`ju3A_F=Oa6a8L2BZ4Yvgq^-KX6gs`bs{pLUZm0MPAB5I`&^h@N!!^1LVwLhxi;#aEc8VlcOD+KxrMm=)e z!M}0#!u?#v>c6`*KKoA({i=QW!iiGw(9WQ6*NpPFbi(IA&hS#fWp6yo@cA<3<+8#r z&o4(b8LsD@%YcqrHnD(Xulvrl(VMX{MNgWUO!B3vw5pmu(r;!!mCMGBUj1=kelx~M{pwzOUxKKsQg%#4S-gZe6J6)-%ciQn*A-ITA zI~|KFA*VO=J)DRCP=-B-pO5cuT8j73SSn6;bRX|pP>>2@#pVR>BXJlcC|BGV3oyrf8y0G@>kfTxDLX3^MnU$>VhDzxCN6h^eJ31F{1_j(Q6*i?vK6PK zm{W>#Ne!p3l%pV~_gaLunt!r3T{agcoPzq~mn+T_PX{^A^t%y1b{07)csDUM%zqs6 zARUYpq?^${X9nAIRMWMh`aBHEj_AZ}i((kd2E(Xf3xLKxXtT>9o+v1WtTfxUc zPdj3KI{aRqdDq-c930O5kw|5DwBY{Pr{%iK{N5hJR7uMI!aT?S$J@8aD$A9F->Zzq zqY;&tDx-!|GyQ$)Ale#V#5LE%=eKczl)JqSD?L;a6mVYNrw1iD)t&8UASmdz>&yqb zy#72_wRO;s)Jujz3fG5|`3YA2gco#}HYZcq2i%cy z+lwLc$os+`!~~0(`cd(5kyp=fXnUI~n;v!zcQK`)2{}D@1N%2rBESzDmi};8M~FLv ziB&{Igk)oDYba7WOdX4IlqYC(b#ptPb={Wl27Rk%fEAUj08>uS&-1|K(X0E`D>dsi zAUmwA%|~l%JPRNKU7Gm#9H3$h%Y?&`O3*l4X}cPQDUdaHPgl$q)LnpL4()_mrj#%NweG_d@J{>i=D}#cn<9utkVy zfw!+t=N$@e993eotuiIO_=frD07OMN@I40CtBdx(WJAid8e7yP$mt$k@*dR!ds>JY zhV-gstt^d!y#o+5q6LvBP)p_AVZsp+PxV~+lo<1NjV(Dm*rKml{Q!Cl2Z5cVLemSv94f2u&OtN zOJSwm$Nb^5=f!NtH1S%yPY4v>m9UUzr-zop6KLwQ9D(tC2dk_AKy~EUdQK0yWCcBJ zhar{NueU*dk47jB$26m-_#H<1-9xGa%pvz1{CXt$4!EXHGQ4Hv>PT2ssMoD`Hv{PS zq!$L>kYO07`RAnD!}Q@G%CGx&Uali-|H+<5{sq}N{Bk;UU3G88LZUdw_j1PmY2UhP z#rOb-!;(hj%Tm(=BDSRBqc|4o@XR5Y$}(mhZuo484`L9>*HaInlYjFC{ooTL-QXP7UCdfrZmSHd?-3S-B`raUR72tPY%9-3 zR}xp>W`&aPJ*%JWHOnyTSdmeUokTrdRF5I(u|-7ayx$yl4&1)nS#;&gNT|bS7T?c$ zZIsh=FKD-Z7bQwhF}K|}yfK(hn+g1$qL&$MbT5t3g1g-sP@HK<2b0Ac`v2@e+@R?8 z)2NH`6m8y@g8SqJS#S7_Wc$bc8{TBYGw=ma#NZjs%Y!)DL^;jy7(#kCPYDRMxQ#}* z2A9Y+_R?Zh%a%L>AIA<5(2y3o#Uv%OCVYSNV8qh=q*NlgA5Qv(yA71VP#5#4MlZ={ zz!|LpDy$pYvJ;)YY$}PgX=p!3DD8qz?Qv&HlLMPKtS5wv?uPE4TN+Vvo~l>{C+QWo zyf@U!qh8`tPGRD=H;=?B;_`Rt8Se}H-lzzKGKNNkVy{BtL-kJ?FBy#6BiKc6)5%oD zpT&=>Vv=Wyoghg72y!gVs`w!+yaseLHHrirnjT74cSrkaOZ;qW_RzEG_Y~gv8+O32 zz*x_E-ECRJYgvl}T0iLyvV@oje!V+WiLD%8&#e>@&)uTc>Eky2=L39@un2t1zYUiM zN_bA9h`Vm@SEs=i+^?11`TJueEvRm%80b)!U11~fSQjN7P20E2da%J+QWDA6TaFK} z0+cF0Om*&jfG3PKbv;9r;~5Z|{g5}sO!UlHsT-e^;dHNs^0JXqvYw=Or9FMO1?`_D z>IR;B?DzMR`BZ6SlXYvfH3A%ZG$wCG+a&~~8(iHqLu#Vp*0>W2M5+GC>E60{_?L+hm$quM{rEyH(z{5BsI2pA6=_HC7gUk8S z(os7wTn1ZqnWr@FL*BXbXtF5Pky3=*)9_2&(1@lfb&lsE$}(Rq^U`YI@owhMfM#ka zkCi0itEw*(BY!m_|F5LZ?A18*Npd#DX6ez7HzkgPO!0TkJ!$%o{NKU-fEMNj;OB<2 z3MNs*)VPsIJZN`%zu}+1uXV)&lkP;*x9A7459CS2!5C4LNM=N-p*w4__t>zk$CQ#&kIZQz#m2AvJ8VTHV-si^OA_CKAC zml`w1$fNNQT8x&)HufHyW$tAfO>RU=ve}yhnqyMeiZ*3@n}!#6U2OC={$6o?Je; zNL@}d>f2A{aHDFc*ReG&$E1(k;#6@+f%u^*wWTp#$gEI+PKnz%Zw1d+^Co&|4mZ@n z2p`I$_W}DF*bk@q@qOLr%8^K;b0Ug_2iNpR;ttoi55+F5XoJD+qAJTX$Mn2&VoPOM zv}TRxR}DZ!>?M89>1dh*-HVPDS+38&q((MtN-ukT_2*Ff=PO47K549!%hJ$b;yB9{ zno$>TBs=StFVQxr;?r5p>GE6+b9s&Uy2d(l$1~gEgAlx=iSzyH8MFq=e@Hy&SBF`M zYmK$M$FbKtiji&Y;|D>BGE^I`WM*m^7tWTa=L9ri)p(@~Y3q?BE_|#*M9Dc`gAI-k zxvF{8TU$R>1Iihs?&(yn4V@`T(B`F#8-b&o#*s@Ui}I|gLIZ6_MSznw<&EfuE(j>e zVoIJLR_om@GoV{~sDRD+tBLmMpcbKvlnjwOvo#OCAGNmCoF3S(In zjh2j+&8WwvEPVv;J`dt^wr+1K3Z0TpuvnT)2!`F^fl zKt`&3(%)n@09cad5dJgsv!~8jwq6;!Q>j$_&|DAj`&nqRtDnz8;gki6IxgFx7On?V zr4I6~M0xRq?+DFSa%p|lx)tm0+_qY~&K1{}`8VOLIP)ueh4$WboQ_?#7Qv z;u;t+kyoD?7JuSVidi~j&99yAjE%luFkVz@W2X4DJWZl{b!1F$Ih|T5ZK|Z7TiOP> z+vV51(F!>$0a?~-P&N-cZo>5|F ze;i8boP7Kp;_wZJ4xk&CJBe;Etu5kn(nrw+nvDT%3l%#Nzp?~mQ+b;UZQ*B@R*if#sH5!*zq&$wW7uL=f5Fn$cDD#w;<` zsY)O2u|eU(s8r&BFRrJb`^yaE<%A5cyR+kD2KK%UPzJm2fi~j3mbI?FX=9_pqUJ0O zaW(qL_b9$z|DG7jvs$ACWk*`fIJ`QBx7*mu#0)5F%u`yVUjR6s=yO3QMJLKC8MR#k zbU<$76mNXrw>RiXmH0lmyqUu+*9Km3^(`y9#$v#s4$4=Q?Dz0=P{Lbnzj!wWWRzQf zq2aty(f(T4V^Re=QgXyx=xKLoYGh`z!l~9oGHaGv`75%9^~u!7|1=Lc~) zaN696xIUjMSewoYCt4k;O^q^b+hU`m0cgR89a_s%y=p?kviEGBvYZDlEY|^ptNpGc zMj{ULi*meWiByNa%D62AsTJ7*RWcmP1%`q?4zul{tT%N9Y{3Tkz`8ujtsg`mQF4AP ze76|^nCHcuQWNRCdWVJUCx7cld7^he`d#0&zOg}jmWD%{WZNmqRMZYdq{1sC9Mykl zpef|(i!L?*ai~~cIESgg&CnZCBkXZAf70Q9erd+wt&n{=tY#}>EWX?5#sE0#8J=!# zC{^IoCQ01+==g&(i0o+1$hLMzoZMKo-sU4Cqlx9_k>9;qen7{|LEe$G2(>^f^!EX9 z89eT5wzXsxUgF#8F46?i!alR}x)7LBLldDoQ)6tVqjcR6w=^#-RcKWv*;bD-jp+zF z8(PcT6DRNCKz8cCNs*1HjPllnu6NB$6w!e^Uog&A%Gc0ATo(^j&ow8SG~d70$7pNd z+od#Xe75a5Im~@OA1YUGaL0Z^l6?G8wfYT3xgviY+LP16_lxJU?#FAT`QWFY@BbN? z1^;X|Sw5uDEg}iEh26Swm}@g1%1KQ3$ajM-=Y~cvSMiD1Qq0*oadAOYL!PlgPTfGn zX@94`2IZ%TK0FZ%5s4uCp}H;! zhUGTk@bn2FX<)V;l=slSLqvwnyb8L~&DTBiE%5T`jfX(xHFF!Qejdtv-UmI56!hiz zq{4vTsTdTpixEmk=7j_f|I83oIbEn;^NE4Zwjx)cerpxmhq@!Ca)@H@76#7Tj4~1r zxh3Be+2X28#|NHb0!bUss9J8(xnQsQ4)quG{Z@R1ExA1x(qREvdL2IaaBvix;Me?p ztbgE!NDBCg=cL2d+gv+5fq!5UFl3jI2lF+m6&TBE?=Q5!5naDR85UA%bT{!=m?S+e zVnJ39FTn{1$G`JJ=Xj=YG3fGQr(k?F2mdc-`p>czFa@M1C`)`C_^RMSozCeTYjOTX zN={If&2O}b6fpP}o9>EQakX2vOa#~*eT8+V;<19D59oI|F-fInRDjnKGp@^HkZQTcz(My%@qI!jP%$#C5V^*r#4_y0IUr6Awek3~TuWy!!Y0-_d zTHYoI*BIju<{=+P@@7cHS1^47QS=4@`6@;#9bU{GXeoSQ^6Uh~ePMC6( zleGoe*S=(Z6vz^=PIAoov#v}ji*)-d3_NLObsxpQfk<%w={8GU?AV;}NJGj$AgNUD z57mR$P{K8i3xv&|4B7Gq@e!8t%+;Cx$4xqUaJHZG@lI1QswB8OX&HoxQw~-^3wI6|nMk8nCtC&O@qH{X`$=+xZl6uRw@pHML-Tt$@ zlvuiuGQKgUWVxOd~>al1Kc-VcvUDR$3^24XbZ z5y`_uZ0GiKm<#Ll$k?|}Y3wRNzg%;~mx|=$*8Jb)t43w$EZ@Z*osG=L5UPf}GI(q- z0~8F5j=saS%i4TkruPe}LRAOtLf8Q->}zhm#(M<){6CahLiSi8Zlj z#e>cx7Zs8f6<7gt;`RbJ4k1X%(KhHf))k2V4gbhnf08^fOdS_j*K*|Xt$Z<$(;?mT$Iie{K`#{7rGT2QzH*0$v#lTddpxRFD+_O_{Qtxl0a z0n)A7S}U-wmwveJ>D}DC)35%woc*Wh6-53p0-M2{B0uTE*~Q5>Pqd+zB;@7;i{7zi z@#Xg9PS(OMEefm!`6^h>d@>If)>sxv+n0;R^A+s$I%U>1TFyov*JnCdJ~~+mT|Q>4 z@g9*z^0qgg?WJi5Q-0b`vh@|}WwHpc(s92Elz@s4NEowpuS2AOapf$Nznt?xj5jf1 zCk8m#ave$#A=d*&W>%rcMSplK?j}KbNy(t>f&fX$G3F}WQrIjMv(9Mc*wf^TPkb{R zRQeumW3sv8iPEVEBDvcwupG7^6`Yonlw8i{?=-V6lb;oIwzHY}9R!c%YPZhi;#RyT zs-gv!0u15xWwt3kuthV8OOin4AOmdLAVz{1rH!I;Zlz+L+NIOuS zLpS0z7?LbC!8*GD$Y$%<4OK4{;9OLKtW%%(8v9aQXPuIc@i$F2CEN({u5s6G9Tq9X zD6Tx^3Tk_+A3xe#EqAIjsR27r{s4 zvYeZ8Y?s`leVdW4t7CsG!V7RWB~tOYplRxljnFAa7TBPvD_@h9_QO8pre~h9Sm(*d z-N3Q6OrbR_sAkVMJ|;voWSl8VCK0mS>oI#^M3k8Ye~KtAYZH|e!dWQwv#=_Ho|f*6 zT<;M1R0VYG#zenLyFfEzH9y7Fhyi)Nfd0WAd+81J`cfQn7D+_o6?k~QO2R9ISKVY$ ze4@{4V&v}E8nC+h{S6n8jDK#yvGl^0f&#Yqn8WONPw^r>dDdGNs1E1?E!@)4OFdb+ zi-eq$vJWhigIHr*FX#Hj7ruephLHYXeSsbIrm+wHvNs|*_NSiN)@Qjrtkl_yENXBa zNQx|nfOWd-r2vnX;H*2D5iIVfRl+s*g3{$s*8qfgk7l3ACku4x!lff&2w#jl?LeCA z?t|F#r`2Dqi748n$q_Zk!meF~x_dxTTkb6!!siLeoJmX3Fj?hYW5nUcf{p0+qiPz} zWH(m}x5@`MLySE8T2?Q z@$GnFi`ksw^0f1WCcka?qIm5$XhRFcseO1{RCW=A(OrvYHYD3ocDw1#+JPEb|h zHo|-t0Pc&9T;dYAh(ervU-U;_{-Hq^{J2(uYp?%0E0-6gpm&{kjM zLuzk|x2DnlgrGtYfu3@(qLtJFFLWcRaaU3Q;56@0hHD)~VPx{CG0keAbVFYCsduDx z0Ysvc?%J*eUV;&V>M(Y2%I@bOzr5pzM3_>pwh0QeXqg?zBb*zK^!h{snhH5FKF*&A zrlB2g;nDcQg6MtP%24DY#l}dxLyQ!;Q!?JNeNsbtTI|V_1DP<0Q3{2gsjqg$5*)!} ztylXh=&BUOv0$w3I?a9cF?pA;BQ}GmfEw?;Qltrf3BQ+?;GG7W>4?#+HJLJRdu(L zq><<8#xzA=2JIDk@TpV?v#MU(!iT9qA?PlQAamZ3s6!5Zd)5vvt#`Akf=`daE}@&U zA0%M`Y#(Q?7_=?$$Mue5yPY95V3#Mny@*LI( ze4*A%`c73nK=r~wbjyFqvlFrgfd3otPX{Rdi%l?Ik*HP_!c%x9M>All)5#>al=+=0o@<836kr$rF_0AWx7fIE-VXIY) z3J$YU^Pff*RL%f0*7b+eC>p*&BiB^^kfYFE_jCQFZ|A~bsjli4CzdAQJ?>FgR_s9H zU&I5#V{Mex8?`it)O}@9NL&Mm!kUdE2#+KB&CMelfp`kEaka!TR997^J7-tJP>v&u zKYD^eFh2-h?T~#w_v15c_lF6OC`Mi0ww;v(EiyW}2p`Ye?!(9K?>##E=PJe-qV>x8 zg~CfIFpaNR+xMGQy^`9(gnPScWm_>LodLs}K2s9yNUP~;dk!zp*KhGTIK6Iw;BEjh%G>nzS-rxb8iZr60~{P zLq|1`y8e<%lAk^xhA86ou_IA}%)lNDI^AocOvt*Z z-J~1wgl>_!mm@pL>j032uK~wDt+V&tV6Fm|mVaIsY z<8&&^{9srD$E(O6t0?;FRjF-<;V|?%w;}6ZBonsvDYu=FkfknT1Qt%URJ;al<%an?+V^W>2 z@Z3h8?eK3$SosJ%@pli~rw82SqSBQ8>=w`QJ8v5`y_t(?RK*C$TVT0%QTT0QQN1`a zFO)-fwK%c{Wrn>`EzuFl1_+o?V-8z%?^E-dliBbTNeCRR3v_VCwkv(v5mXIso;4^j zr;CU17_ts4F&sPmx!}3F3^`!QjDqu%`+m)sI(!A=y&t%Ew$;(&l09;!zN)~RDjqw7 z)V{#hyqXUI%kifS9z)G?yR$XkN>+^u*DMuRPzMZ`02JeLoM76*q z4fR$oy*;~$oxJg|3S&y1aZ|ro-;tlD7+)!aL4B58M9zQNdZ~z@ZL&IUruAl zLc_NyREnjF4VfnJZ0A)k%0K%jhofXSubQAZ#+~ECQkzB}TxQ-LJreN#Y9d*t45R7} z{?f(bchm?ss?WjmsbXUz?bt7CaA||Wkt!t*(i3@moGAVxajM=oJ~?<7ID4n!WlOxo z_WjKrTGOYKh3A4zz-B0;wtP9)A|unrBj$3F&(yxaz)jJzY3Asx<^ga_V0OIxfxTwY)A(^H&E5E4L(p; z7U?}nps4iEk0F0HSdLcls(5FW8zFmwKM4oeB@%Q>3k~L|w$1u<63Ya%{JL#H}$^Da5FVy5R#@4{T9F`Fw+PQ6NR(%DFJjU1c@lITpc*K}x|Ec=1L zSH=8M50_i%u*Pa&T~T#t2mrYo>t|gMhfsA9q9YlCbg<*g4oj=JHo|or2U-^2T87!FzLQv*3xn242&spy^k} zS?Ur86V@;l@dp!WmEqP%r*oNMAo}ZWa}9SycR zlDt;&^f)z{VenFLoh7cuNU`}A{uP>Bh0_iA!5fN% zX(+BrX&zT8MoT@zQz$7UO*;0{PljhN<4IB))6il!Y2lM;%S>$^^|7ufNuQ7j0MJFj z6-*M}{wK(PA5MxbC7NSRok5QY=$PWvX6f-uFy^c*E6t^B`E_|X+L71Z;n2s=8<~B6 z!)G6uN|%Qu?N8sd_I4ZMi{Bj@;_}q1d3D_3U5J$L zcD8|e`hK25VY|z8tvx5^yhuDDtUjmFMM>N>LK86hPHuSsF5WS2dl5IU7N+oq%6509 zV98#+TG(~{tiOm_M)WVpCf?_GfG3-n@u=bXe9^tX%aHdSiiJ%hv4if2$&#R{39s;K zgzd^}t1iNvu0$+v9A~p63+g)A%5K8lk2_tY`WqKY>0V=m5 z$u;xHlB$6xASzp+W7Nac(|6sV?J%0K=~H&eRL(d~iJB1@}}aUJ2Dn27OsD7__*9!#Yk}x(c~T z{#9hZfaZ+BeP94%BslAdDDY-2 zN5zqt@Q}=zYlaF+j$f*@+vH^^imKgKFS|DOml?^MSz=TW|LGjpC>Hl&H!K%975R$D zdyoT=MZlkXYR5S9+Zo|mof$D!#W92l1&3ce@a_Go0bh`5e2vplM2oMLIC>vr`kWjS z6pF(J4ivPx3JQd$*$1dT0wI=&z871MI&9cyV=fDW+vqg0LV7?{(qQNfQpii}kQq^^ zeZwI;DEh(={(->Y=p_berp&J;B)$HzVA^RxLU;M@Mr?J1zv*j)nCi`d9TUi5_*^J} zA9{P^U9gaXinyMr{5_nc${@mo_VV0{;^^}#<^dSPm%za-623(w&hYj~_`q5+=+Fs% z(&$AQ|DCzyDXkb5NVSO|M3PC`4m&(?lNQA}hU`Q%#3(8X_p2QfcpY+pAqfg22iEA-(2xXb@10@A{<=;p9tdyPDUKfOlue6S&K zP31n*eGkXsS6hdrHCRN{(9MDRNydefw3XYuxdw|W_c)feq2IDGDwZHE>^bp_JFD7r9y21ATH(1bk(cCd$@7SM+rG2N%0e zbOB?@X#rRG$b60%rP-g>75C?lx9@SJw$1JH=yZKgmdVLZxNtKdI7!g`&YF4(F82os zP1<{Cj4%ekaed=3c)A+jIIZ#!M}Oi5{xW4`Rg76Em}ZYh z14Q5pNT+(!5HcuQk@ZkX1<^`Jd&ITD3{948>@cGuCvBRd+qX%A zq#l}o{!TzQ_&2`EJZ&YM2O<~HB>NVOlf5QWZf^ThLE+!>&(kDGcP*JEum~_^NC396 z+VvOJ$A0VH?<}PJy8+kE1S&~y+oZR8|Jcnx-RZn@T$k7wliNk=QJ=y{ z1^>d7dN`f7foWM$x!+wp|HZVH+R)D|h?^@MG8Dv5|+a3I5*Q)na0rEKW}eN5Y< z&H_#Lzwn=fOwJ!m2aSkW$mZY%+^1@mn?l4m{~N;@+>Fko(BWVNtX46~*Vt>G;`_1- ziNd$n&h)>~sw32yghbl-{GH6WUU7v>g1othBCNVm^Sf&Eo>L&Pd&dKU$X4F@tNWV(~n}n!4 z^K7HSfr;S-EfrPsx4|K&5>p9b<_YdSz+Lg!f z=dXAv;`Ilh}^YH!qG%26$TK&*V3R@!+VsIDXBfDn{%USS;e) z(SEu2hL$P)ZpHKHdj++tYo+a>Gf!kGzcET2OeI3juUB_}_$##45!_j+F-QqERc6Ig zd#~Q?8SP-{Im-NwxET_a6IIo3TWpcB|Ff(*Aat7c1W*c9699ehp)uZgbT?*FGM(l) zrY@?oygT5tc*AVfL3BWXVe@^8oNI6k*XC*JIpIq@fS)ujxR*Rvdf%wWyU7N-^EWJu z+{ZL2I-aLksZ=R^E=bN~eUG{4C~8*u-s?M)ZhoJ0mE{`?Q6dq^Q|XXE4X0JFo+?lC z+L=Wem2F~TZ$sJC+m(U_fmPCXBYI4OOiV4rUPdnmgXTOQNIPYx6Jv2Tr)#NYJm=rv zHl8MPYRGwJrKix>{|>oVslQ7G8i)3R2lXljp66HOg`}fG^g^ZfM2a>C~=|rdfxFG z%iGTaENsFEVKQ^2dDbm!B3>E2cmb*4_fO2lffxur`N|s7wja1mO@6eX7yTMwGn|44 z4@(hh+HHrVss-Mzjz~;@E&oez6j@zQiI?3mwnlrklC;`qq+M26_H8MMvd8??{->fX z#?&sdnhM8I)g5g8Ij*=G$Xat(mERGc+kCm|0~~SakuwI$cb00-i1z%34lSbymIs0K z1T|^BCNA+{nW-p61NT%-6chpBQUrw+him#zkTrD#a{PLLL7ke32H2;!;+RPm0NH`C zL{kFSxxk~W7Zz6KC^KuZILvi%Wmo0(P+743JC#v9F5NdIjH!S!boECx)yA$1o?QHR z#W(-LOp4z@W~@U1WfQ_farKnGrNq_CwA)r+u?4WQq6@*P>gh47hyUSk5N?9aNJR2Q zKr3RQ_3gR9VIAAfe>{>_*Bt5{K`78TSicGL8TpT|Do0`$<>|2+`4LE~=>1}GZ;H9X+|cx!#03qO6ti4(k${_bPnnt3G@ z=yo@w5<4|CB+@QAdn6}-lFD*^+PL!}fW6!6mri&yow+X}Kx^1X&7LNfLa#YkLY~v) z-H|?#(ozQ_tKC%xZa-Bx+LGP`yA+hoG683LZ7H#PplY~x%zhX#s7$I9E!WZj7%JUn zdk;A-lWm?b><4erDMn} z1zLD z%Hk(`>sW`TM7UNJhUeI^s3EFMt}A^W1`@)CB~$hINi}voaoSV5xnM`mbYyh_xObGt zrid(U!-I^c$TPAAMBYl(?Tz_R^&ocqHrXltN>+~Hh3}hQ$AUgN9bTkrmqfT`f^o1k z64kKwg9hO2#rBPhFQ?IicXczaFJ)8tT?;Sqt(wHcy64&W&@CAwR1Gc(=b-ImuYqvi z#()mj8N1YwQ-wWhMA9pkc$qxB7gjAOJc9TOm0h}^QGIqKKa{-1-Yx5=Gl*QwD7T2} z^(kF0sm{v#L~lya;O$0ta1iZj^IqmSr}r}&hnM$iXPl>%B}up5h~=C8&~|{$>@bXI zWY(yWB)KP1P;m-6|8{Zs>H0_&)*fXArsY(T+z9pCzL4rmw2jRTeDzA!(_$80;p6L? zALWwEiq#n6e*Hr#mRQ&X*l-wopl2!pIikEpDps|N; zoQ|`om&>S#_&}jvyO*~`z5yrt*T=qUga&`a(=l?hl)K)v#`n^T9ndmUi|P5)MOg_% z43-D-g&YdSFGE6a04uWivz~^{w;bL5&KNhibz3U$7U;v0*y~4f3^q(5*5b+ z!36+=2DoE$^(r#RmID6#%Jedx4+R_rWfBc6#KlN;_Xz;`FSw+4I&NM-MmDksumxY1 z@4kP{ctzjpS8<~~^JACT$@v8(&lS`*A;UdG(w4t}HegK!Rjhm<+Z2kJ=|ljc5IiJo zYL5+cYsFhTp-qw9LGr4k&9~4;wLb8o!xZeUWN(Y{y^(! zyOCMxzI7Mf9gAGapIlHs{l5eYRC?#qjl2RRTfht5w2)#Uu2=IfWZ@jq<$poJs&!CF z)WM9WZ5)D1$-E8bRy#JcLIl51blUxeM5R^C4*)u_@D(9djb24MODBGDdXSkKq2>r} zS6@LEuJK`UUWt)zBwtXa-Q7YIH4Cn)54X|(W_cWG^}oCRRW0>PyVL)n+>aA`(8~V_ zH&}Z(8T)P>_6lql^4a$KI0$uV(3SSCrp{B^3Nxa zbMs2&pp8=|HxtmjV%8e!=7g=O#D+tqrjpMW$~EcI9S%S84eNN}MXP{VfqEAbP2FyE zASUTc+*I3(mpL@P_t2kQg4xcqcj$1Vkv`p$r4B`_!12JRbW|D^N}a56(Bn$)#{;dntx@*Ek1y@b7yxMIDW^ zBW8HNq9hnG1`)-ilwBhC+5BeZm4l<>ZEIj|tiSsFn<{tg*ek&LazFkRW3sX~98#bd?liwQ9li7fs`RX*62)ztkT$ys;Zf8}(1mZqE%Trg`(BW8$*dCKL)DMSo z>bT}e_5W-%WaEYJE%-;&{Z1;6Ibvct_u5d&*0H6lQY-tTTx(nLO{Sh#*dgIf=zxc4 zsymaq$Rtu;T4OjFB0`}<+R3C1S!x;qwVt7i;C*lNbQ~oaoq<=d%ZU)TgbCmVe{&*y zc=GP~_R=J@7|i~Bz6pg36BgBAIDbO24--B*l2A}JH^z*fRL+nD6pc=dS$I6HUwNOttB4jhIti?ezB+v z_vn|w-@V@nKE#XJvX+E(2`(-klJ-nZd2S6F91;8~*@PV;c}j(Y z2Ay-t3TJ>VK*CMkHcj*{vic=YIW~9|!okSIO!HwupJYT3GVr z(kmVzp!ZvlU@Z`WWSh`K?3(l~poyi17NBBR$-IQV-e|(ii2bSN1tr@tqfhF74e{xo ze2_j`96}**neHCLz{nyDZIOg=fg8vHR@5>ny2C+XBs!(SZ)QioO(TvzqKK~^t>zVy zza5j`X}T~`i+lI07mOGF<~-LKsq_VvMp#sh@{+9fm`iz@4JLt#&B_Iio#H)knw$(v^YTUe+6}a zFQT`O3p^ZUuD46*b}&x7wON69^{N666tw4O94N1yyeI+fr_Qp7G{JEOv{xSRCX?Gv zqy7IKMf<^n63DR5;BgB_@a1lt_;DMqS78<4K!I#2cHsnX{S1dZyl*ncUw-VpO#7^f zzFaqM6}?8Wf=H^FPM?&!Y$bEiyG_)93zCyBaGrd#%Ci}4p}@!g$95B;4uZuEM<7r+ z@b`b+ZUX$e-2^~ozWDr~+f6{N1D)pl?{*Up#mRts`TuvjiKA5yPXgy=!LxB!GtNc1 zDR5f7TwGxwg`AEyVgcu`DF-GAQAWfNcTwmXT|T;R_bTW6cO}8(*oG$4;NT6rtLPQt!CUkKi{6nQ`M!(O`X`pUSD`$!KAG&rYtV5 zE}Cb$b&Q8>X_@=WCmRj{&i4o4z$p?41keNo0`7K$LlGiG69^$0I7Di~*X~G#+X)J%t6*PA^9FG*o7=cN+!19(GX#jn z`&y)Z-(MQ`ThSq!p^Srilm%HJ-}hHxOxX|{5StX{$ow5fP6EwRmb^El6)*YWW?s6` z^$S}~NWPzkB~euRkBM1jC3ne3zfTzoKAX7&^Ca~sRAWwX9mMMAj^lfM)(<?uj~CjEg{J-JHRr`S-%mPi z#llD@=u;A)R9x90vbYa0c^6KKFy>150V!L!ODvqQ``9Ag8x7gv7U_orBUpYUaVF+VNQ*kLLv~4%}IIozN-q(z(j|km#Gu6wz<#KCYsn>6_`~#A8XDYXg7+KO-chL!9wl{H z9m!B!VLAU$q}T<1QneB`SvEbZ4L74m1lGvZ(PCYQ3?B}btZyUqD1Mrf0$r&94`0{U z?Cd7l;%h8bH|gF+Ts#aEq%hQoX4=QlPhCGR?*_k3-ce9~@`4JrXv@Fh(nVFT%V&m? z5CyaxQ%OjIK!2_yQE}D?ZU*l`i-7rcINmf8$jQltn8y?RHr2vQP}XA^JMsGh@_{{s zuNzEi8+86`CB~#u(Ia0}XxB$PUq%vS{mgJG;FLvl$i*67aLSMpV|+AuaWvk$py7Sb zkXo(jveF?)KR@ycZ*rrNukkezYUcTP>UJ(!UQ*KR-xFf>V*bn@Q^Uaq)g>( zw#|p5uS)DnU zgXp`kV?kM&>-buaBfa^~-kyu=O@w#QoJRalL%e*;39+M3fe@IM1T_*APEF1_P~YLv zHzjPk(I?oOW~0&(aG6JDZe~eq;ZbZ{-1A-t`(RL?78Zy0Pk{q<& z__@GXNVA3CgISPxUntRe1epplp;O@hjlVKU2~leBZv1CNC|()+w_}dbDM=wXC$<(5 zMMGUgSNK$49sg?YBe?*r-?8$g(sSW@He7j1*m)N;)A7D!~QE(Uv*&;A!vVi0L2JV&{dj2jv%R zEFTZXL(UQCa5JL5&8O+9g1?uPd^Qr@^Y4*04zw64rfqrRQS|+R!3K6i$gxh9@tO~u za3Up(f#~@q;a(4|3u#k!tI;KSRbUvxDmA^KOuh&mfT{uiBVPYGe2crq-K0|6&v`HJ z4LmY1x(QFeS1(j~7kOLVdO)!wYX}v?;zNRTWf>++s7Uh_C%I+W+|Qx$86X;cgES?? zP#8nu8%gEN<|Z5mMMf_%AzK)}DOL#JW=vP#1`;HO?+lw>x}%83CBzqE)XXRR2@@0- zP7V=51w{)dks&GD(NE=@rZRJnz4uqOb}Qrf5T!O`YDC?=pDs^DroKXkmpU!wSM%$9 zS~q&?bMZ_wx-gD^MQ&(_IEmP0Ec+C8lDP%iYhwI2%%3D0K@S<28QtLnplFmFa`%WU z$yh%TQBjc+q#Em*5VD`EHF3sH0*hM2_}vqR*=@2=875!857)#@f$oic5C%~ssj<8> z**>m(MHJtQi)l9xD`X_2dGLhQNEilMh(X|iJ5HZED(=7u*R$YSzgn`R`@^22UL<_^OPUm$Ym22~saP4e`sG~H; zz45F&D$Kv6lbOEByBL(zgHiFKUgV74|3y*2j4U$53?dDvY-N|jePp2Gp)8T{e+OUE zkPS%$3!-Kb-zzaRISY3zhbX$&Mnqkv;;|G%BCPm?hk=pt2?8*cS;-|tXd=OCzw2WH<><}QP;p^V`Qqdw<3PU-R z6LXU=S6VyKRWk}xK!fqx%cZH9c?6Y$XnQv8C}IaI#i>5lPP-9603*TXiM9Z*eFkTe zf?`yX;vNq+mwF#pE7EU5wBKo&ZN~x_ERMR-EI+IlRWN; zUa#GY?>aUAmVBFpbo57}BTz;26mnK?Vmmwf6{LH>JyygdF!?4DVyQE@k><(q%+LV@ zZGSL%>E1-7pbKNBR^~d)Qff=P)RFRtS*8x}IJ^r&5SoVmDBcYV`Hl7;WWKh7Kc!FpM5e9L+VZ{ZtV-NLospfFw{FD;s;D|8l|OvRpaAZ(IS z=!+kdFJ+0EOyv_Lp@6JjSN!5YfGDR8nHuy7GxZ+c+BX#9`QAJLk%hW-*!A{z>HIpbPAGCYHX5vK7w(1t2080RC2VT5M(OVit_Zxb{qa=$*mkZv#!=+ z;bxF;A%bKNZX?nQMg|Rp9Gon)@sC^yp``G!X-O+z-(~3_XmFlzZ=S zvHN_%jGhX|Ei}ARgbEu|(4+2gi_^?=RCzk>^~R#wg_Sy;pJs-YWg|15x80_BoBEi4 ze4mXcx04y0A9^+sF`|?cA6_EHw235?{Hc~>Kfo9lpZGCCN(i17oCK~j7VJr-RjB3D z8d`UKNHT~(it;7p&Y;K-po%UKnB)ONwPj1RL@X;310qEQSa!{EMMM3xcw}jl=O&ed zQdX;lh!&@KPl@(34%6OeXcJhOK}aj7OC=i`9X?x&4=*FWN6n<6@BQOT6;#CR1{O;o zI(jq#4TpuNyf8*V@Rb|3@N~ZAnF_!7^|iXJ$%KjdGO1|T*j zypqA_HL=8`AEot20;yO~$Xdd%h2iCV=cnh)BkALmu6<9|S}!h5Q~rPu)GYsix61pU;AG-b0>VWlyk#V5e@uA3 z53u_nJ-`ftmz#GIK_pt6$Y;<0(fnimrC#Njvz#rFERH=rC3K9EB4C$QZcb83JEcKH z2cpFEh&hSo_*R5Zdi*TM^p8+dIitloLBu^*YP31i?ztXYJU3Vx<=9V!5(Hm)yyL?bVQHs!#lTF zOp=1ObAxC99BvHYWvcm9^Yz`!j$ou~SEyxo$kXut&d8M3B3S{|S4p_5I4>Vs2%oo$}?U7+=dE57?=+Olm+pW`qr z39*Kr4Mc$#xH3N=+Bj;wzv8D#3+8h8SSTQ*1%X_xUA!svYXVVBm^{bVTyjIn*ya%_ zU;j-Ng;iOAT#}lq3w(Vh3x_xT&M0|rKbj)FN)+SIo~SCVlVS)W%eQ~y-B{$BSi zvuQF$Bn66Oo}W4 z(tboudX8MNg4;&4t@K55h4RAp7diJE8yR^9e;Ziq`RsN+@qJ}7OU1|j)+^g~o%MMf zUFWr2$E4BW;VU98Pp7tdMn9=&;NU%cF}HBdSD_vkM;4({OZxmRg|B zT5ysT92ypO!d7P3xjgxE0~)thaau?g@oR_J)<_OZe-FOL6x7}o@qy3qqHc*_|9szy zKIw4MekF&=Z66s*oKaQU{XlmX1^X$iAYy$X$~y7m@!^jU?od6s+mn}Y7p)AhP;xV$ zBR2bK*7r1iGCe`Outl^ND0gh=edGFsx;mg6gTNs?k&{oCc~-C|I&8njK0DJ4_G2MU zzJv7rqyYvSbYgKb`0Gd<7h^uY_N}xcIKe{Q@a+jGj%oAojKZRlTcTnEh9r)8bo_i8-2R(Rma{T}* zz079;3Y753I0EDA!Pv)-!%MB%icfjxU$wPp1vHRY0f-s>$7*NjnqU>K3ZKaC#6EE? z{$KegeNMYZJXf0Dc145q0(aqf&enP5oiM7}@AM_i*J1V;(s|fj&1#tX(^j3!Pp4+h zk41f=g*d@;Zc|SacCJg7t(PY-K%GD)K#hd+_vTb)J7+14A#bE2bCL!wL z$01)23*wL+?#c7{Q8Y%(N;mU{rRLx>pAO+@Mk7Jbk?>5z$HnwsnZ?4cdf!En?i_$lIuVhi&y*R)82V4hHJLGw+mjRF8Y7J%R&H8<*yr|p z9RXXZiGm@pc7c(^;tC5o;!UlcAn2lhafzJJohzOQwf(v~rbcnU&<{&5yH!HY;BgS5 zBe5Xl^{#Md^PbZ8vubgBh**vEcofW8Nl~>6JI_NdOHD$x#&rFaIK5${f2xRtEg0Nr zWvgHM^D_=IEsqA}(aR$RFmzWOkVVf%(r)(=`7Wri6F0oDG}QuQJ-^h!N|d|-X1@#q zo`>pfbh<*Qu1FDDq*3ZT1pJI1b;DR@!}8eQ*SSdvI}09fFU&~LyA7^CnsPhT1~EV? zE&hI43}r_;?|c67u+9?>!)Cv^vY(EV2&7uSCft)zEcjJwqTBw>lS#i+Oop>zHmBfS zqn>Zro&*{!use}{rVZhnwkk*@84w9NzKE;K>x?3`nKjlMJoe++1#~;X&1~|Ok+CQw z^j(GyqT}YAge2~IJ+eys7carxQIM~BnbP!E4@Pkv+pU9HnkhB4u?OCVGkNkg4UEs5 zxvAXR{h(`kCWOUhS^-ZehuX6Y!L9D*1-t%ehotXi_RBE0i)EAPPn?3l4m%%!ZpcGW z#;2D-yr3RzJ>HkA+yn-@qAb^Dys9_WS~Mt_bbnC=_Baxr&SFGEL?NaBuYDZ{2>kBqC}iUpmUX(ZALu*NJW=; zI1~4&t^8`Okw=5}ZXM4B@^`FAhL=A(n+>5s6LLSKKayT27TP-cu|#F5mahAyc0K}3 z_n1fda7blo_qc7uT=|Qe!dA$7%T~#3&v`Cg{nb|N-Q+Ht)%Q~!Hq9sD*D>ez8DBvA z_fb!j!Qe)zEG{OPr%}Tg&2`+aO^d4)`NcvKyR*;0!Qx51Tmf7_9!})7${nQdG9&O2 zoO6o_Q`%vwhUMK!-Xi*a32nU#ndcQQ3|fBGk9dVXA^W{@EoB&TsaSu35zhe&&tJ%u zN`w0syI{z@{RgQ+j(WKm(bZJmaJiZqDKPN%u*MZHmpDR!-&6KB?hvX+!ZsbKsojz(PXX_HP4D zCwy^8uMm|i^-S|W87ozr|HWn)|0N#~Q~ipq{-=CYh>`!mU9IEgr@?&^rGMBbgbH90 zfLa8mSusFOa;(IhQ2xW6>bDb`Svf=6`N!ko`i$}aP+V^4*F51@2njsz#4;WLGxyV9 zKMjy=Kb!mq4cf5cNAd#j?e)4v?tfuKrRv(hU~*tArjvuM`O|zbQ_9V{&sy2D=J)*a zPvUC^>sIe+hxn~eob()Zf4-Ib-2U>g)Fnr`>gCvz*SOXFDTjJC9!Gj;ouMBR9ORSHMB-f>pXd zS6ntj&Kq+eZh-QOY*a_DGqhMnkEa-UijHy}hh{Ram%V=LvHpF6l+oEVbL@cHoi5nV=@Y52+F|t5(r0~fiv~@Kb6$b-xc<3Xqd|6* z9$Jxo*}THlfLV8aW_D%nVPtoee9ZOWackOKe(`$FufF1M-<*WcbhB)nSP`C{VGk-b zdl=ILtMI@5h6`kQL<6i2IbFYYxwtK-2X&c>{Tlt;evURzc+HE7Bj7p6w;q3VOM9Ha z0CI=Qk>slV^uc~;KKZqkX))dZ9Wep;VKZ)yWjQe7x?zyj&*8V)6B81@d zEo{)YhCh(}HIkd2a1o~5-u<`r@~$T7vA?`3^#VE_po%q0(Ks8g)JLyP7rXV;P9RCf zf5X-{o5BRq>hRn{pfI!X(7o;AeOO9lpi!6825!(al~GqQ_fhhjmoD?Ujdg4HWA>do zaKp(^N&Ib3oo>u!^!&FEj3qX#;b=bz4ll@%zBVZSkkX=&xmv?}9Ys&GpJ33_54*^I zJ$4VPN!4)=xW^RYH;7%cU+Np1D_(!yUCT-xYKW|DPU-2+)W_&7Y<}xCWG|#u5Fg;` z{^SpSTwb$r8j+7c|Nh)|`1sAK6ZE&!Y;rm54P}ZvKYv_cHZfrSl-0zE&X^qQHP(jb z2a)G~6BAyZU8k34y}TTuK8@914`pb4O4`X2TTGL&G~xM4Rz!U-5$j9s!ap;tZf}=cTAl9qeA#)pZRZ|v>x1yBSI)Po5>i|rk47oAFfh?^#JEHjvj_IN z7TY#t^tS!G!i$LyC2Omx+xFvG+tya^E>f{@c2dp6!}k9U=-7ud$_rJPF!pQK{_Qz- zl&+Cn-A0+;C;@7QEtR3qq8NV=WUxtFfj;x6Z8D)OU2Wsb?bBYucxvYS(xPA;&Ahjo z67pwQOPokiCKsM|lA%l&!a&vpCj!&x+ilM*UCIA@Qj>Cv%*gGfOzp7|5 zTCAkBe3%Ik(-;WxI`JpP_TuphKk+SH43=Rx>uIa#*gERiN-0$yE^eLTRpaM&zO?;O z(DT}DeOQ{&rmEs)%E(M=$V2&C(&XU*l3SggMutY^Ggx+!7@7F$M&s0`Vr{kb#Ph{% zhs~4Q$D^p^#BM$&^7#TMsTXov$kXzRc4#hJrSy1u0a(s5i1(%=J@fAG>=}`5w`SUN z^$9NsRG$;LiFaBo`M2A$6cQlsOk*VRMq&nCf0F9?^EwJbsAx&Em$%JnBjWq^t>zr| zv;6-v35y}XBVbO2ujZJ3fnjau`ztAeTzIYU(`|8ibI6mU(ZAV}Mp_ur0^L7pCZ2Vt zV2`!3!xa6WZB7;zKV`QPcPJK;!^uVWmuR42Nf~?&J^xP$rpmSZS^v>KBH9lb)II;^ zWg2NAp=k&V!WLT7(ua&FUqY}i}#Zvf$%>PaMCQ3a*Ft8W9z|G47#^NfmK-u=>9U!8gZK~if9M7p+5%tI&8GNh>O?>4|JrV%T0ErC zfwaMHB}LlR&D6Ct2}h?KEQcpGJ@Qv>@n13RsZI#oiF5Rpwl<7G;(H<<4YyJC1s|Ug zq*R7xQ0@P!X?%a<&xDgk2^gmP-$Wq0Sx%fJyF4Ki7|2!Y|0zWxx+Xb~aK<=|nkYsd zbCSP0xaccs0u|jjzc610&>bB6wq9G>>DyGcH60PQu!S%iIR=990L4N0Y;fWRe9$hS zF_reOl9tEEZ+x7Z7u^6WJuqbd7Zr&AUcqWgcBXbGz{m`uxGmpF!2Ty3DxgWUE_3`)f6bkDEnh@-LYp0XQBlNk7Hl{0Zn4EIs^t0~w?9Jp1i6>$` zfi06BB^jmjGIs_mft-1RNQ1b^Hbh?bo=u|fVKc`^o<7ardsW-@E9`^pB#AYuPIdqx!1I#t@5sj z@G+9{BqZaL@gNfh`2vI@ZsBNXmp#lB8FoC9kkEc4by4d&w}^M{plF(Q{L8jnW$90l zNp|Pnvrc(%04MbeT<5zT&+xu`$j(N?wb*CB2;gu{e zJ~dm97!zI>xvqP(JM;c-V^`^TkaI!4O)S!u0i5S3X=^nS)v&ppH4T%@X#!1GyZK|ua+8>Q>nyM%XiEN{04_385NoIV>1E9`47 zh5E8 zT=wdXewN3nKM1J5bCwZAxe3yDgAlU#9R|85y8HIs{tZz##w5kw06rQ{ zAtJdEz8O3yz}GHb{om)|d0>}&@7$St=6ufQ%-k95nAZ!sxMN|(h$<<; z>Io`9FH71SkyS>$?|GgrP-GiuU;n+>`g~%YvyQHOq~3&`ca!fIItu>I8P|yB&*F7# z==zx#`X`6`O5bZ?RakZ)dw~IC>nQQp!1TI0@4O&;T?uT1tE*3InTzx~jVf0N2lnK8 z(g;3EpFOmW9nFqh2^daTQf@NYh|l00I!iBDwmulGn9@Sa4SN3&&z1vma>@0`5!B~? zlnw28E(3~!(UVSOX8-poa9(((d#h_F_waGq0BCP(^4UVo))QGHLKJDA74Nqu?clnb zrN68krARb(4zDu^vJoSk^4>_j^#$B_kGa3E-m=KQWD9p0xw|cJLtU3*Dp_;g!FXR7 zRl552QzO^qyrqLJUIfRebFxpC+;JOF^B$oF!iRg0wc+{#F+UBNHaxeTXiff}o1tqw zt@>Bo#xOtj2h1)ezajJ7#d z#4HoUM2XC-1TNN7#BMsh2yWv5n?7@vepzI(R<#fSh>Q2-@s)m1s|Gef*@6xEA|!73 zusP^LJMtcR8+`uYJm$H&N0rehIEfI9eMvfub~!!~&c~s_@%;;9!|mHf<}k)^yWMPN z`t0ySiTN~6Aop0~AM5{EGz#Ne7SP8FKi%eEpS;ztHbu#Z*6>VRw07Nz%NtGv`uRU* ziEr4Tb7ECEDs7>(5Dnx%D>L=82@81NCo-27@a7ht3*e2$b;$uBwKXpzELejM*un7H zf~v0gL(|@*$%5p0(E6~1fRpyke3XEo(#vx~qxJdo{a(Ic==ibae; zT~E%e42gw!oJSU2n?QM95%3T_MDD@5YuNP{)+_PtwqUA)0c47orS;X{F&%%&6*m*3aK=RX&q`O#5j{vr`%Ek!o+TKjIH6zt6rHVi9MjwBLC zi}m;y6~YJ3C?sbe&glDi&nCV90^R%?{Nx0H>?6hKX5bpUUxAs{L&&e=aSt!DpYh$I zwU+FXfN58)2ff*p1C!CEHH#iOnY;*TS!IKK`MS>D#S;_NANV=lqq3+m`C=x(Pt%v( znI&mCj@b)i#YAPael{gPqU+pQJ9b{|&I=v3pc>hgR0u$90m{+d2RPD!Z}PFWSv z2%20vypf!3N#b>RXDYmG#6yoAl8iEFi#dM*!xXY)rtYiSDQDU1BW&1t$iCMa>%h|QMnTogZuvRgN8F91-Fush^@W_T+SeQCmu`;F zy54;a0CQ{93EV8BQ57djf%?~h3eC6C1-KnbjcerXR>uxA+}x7AZigJdTZq2}|NJ97od7(G zJMgW+4@axf$K0&*>=J#A7y@2%^-8nJ11RwjHPL;1Q=*hRi$Is$5_y9(9jLSSOV*cH zz%CPi5#0&@l>cH2ZgYB`)PT;C*6(Jt@;~=wwt#`{80d_~cGNAh{d7i{PSjr1zw>_` znga4vr(t5|c|G=}*{wC~!zF!1sX=)C83FwV8_4alONk~w-3``Cqh=4#-0#Hw8RC7} z%pCGbI07^IC2XPSDVuSl4v<2;xhWHHpc<@GR)A&lP?&VNcG$KlstEz-jBG*!%73x| zhVp7n??Wg!1};9w%i5yFRO?@ie9C3jm;mTC<9rp>PfHOEkRdygxth5eeM5bd3dvuT zUP@q7^nR~sVh9(wDs{gRVk+nt=h3Zw`pM^nVC+eGbT^~?y-#pmtqlaU5Ueo(dXiAB zozfMDacIUsamBL#P3)?p-uG38?8_VQ)wj9nid<1Jz^5!KWbd4*-g#Bcva+uG(Y@>& zv*TFfE`GMYap2=m+|^9@=-tO#e^FYPj2H}r#Hox-*_Tva{g|d?nj9hl++3FaPCr9kfXK8`umJ zI4tHcKr8#~51>3eu4P^*{R!Ii(Ks_Lx|=G-T^2sLSb-lYFKEdG$VrLgwKm~qvxF75 zE=mxFNTwHae?>R1vv0f_nvEsEocK2c#>tKD#-@u079W{+idcDwDg3FMDWHcE0>lf9 zXETLsG;o6R_L&)jMp^KF$WFR;xc>En<4RC~8F$$w!14K7hBas!*Qq|!*>p0-ah7j^ z>OkrvdCaG6=?gS_1fBBIG+Kz*>l6E~oAedG!{<)Q&UXRf^m1lZAN78iE;6ajf9fZF zApZu&Cp4}z2Dm1j5ePRA12h>l6|Mk?k12H31TJ&)l1ih^W)NoJS-GIf-qRvaTp@}_iY8z)m7orD(+ta9 za;zc#+=RYyS!Y%Ijav;kWr7}M=-Pnp6K#F3|ENV+b_u=<#*C@dFT+%QCFVX-v3pe^4lMdn4Ygn1|79H&N?ge~aMCh?9EweBn0m`xrWF-GBVBRUj7oA{^hJLqME&i1 zJR5nNYmccSyC*3r~EKmDVB(|89pcc`SN6Fx{AYe`N`p30(Cz5?@XQ zpIF;FY9$%9`1bp-j?SL%P)uWsdTtbjw=>5z&u@5xzHJ-*xZ5pc4iNaCUo<^KT)_`B z=N=OP8O*r436nkF&NmP4RBH=XH*(BQF4CA3AG_w`|BdieOcvw!)B`!gPS+u6Ms<_E zzaPry+C$oAmc2RnX8ho6&p#p8od*kEeWTt7kdtz=n3={CQLnp@dSb2i`g%h}pCh!9 z(cv@fG^78Su<0RX&6M#wIYL#n_w=L@%^TS*Rb~O2W06bUC?#zA&KWHMQyGK{PiM== zOK56ZbEXE-f8=u^a!WtgJ!U+#jPj<APb03GGp9Tz|@aMXtO7)Kac{e{3@W)leADlJl znVLZ86wcCm4PyN3ZfS&{ki0Dp7Jvd4-h~2?QO@0HYu9x$>NHG0R?!qZs*4%@uE~9s z8gJ;bULE|;9@)KJyg%cijPKiWEgMK(Ztu)(uy?X|%r)W>VjXl~$k1rU3T9Sw1-(t@ zTi_fjHZffyFq8N_pi7U-W=mz?ynA1rYyUMU5$5TyytJmnAl+BHc^zjK1elvG9(`x( z|M?ZKoYfmh3;^z0sVY{WMc!p&qe0QaP3t*Up+&Ww`FGYvu-5>sUTa|9B+qR>$V0QUT_eK;nBm{5_bhmbj<{2n7)dBxO3vMuwc;Acc0GR zj?;R&Pvutg<|)9Fa@+X=6;|d?@OW-(wz!7#J)NBZS2&*=)o*=XP0%Tt0P+8Z{TuSb zQ+z|!diF`9YyD(j7A3@P`~aAP-w(hCh%9;M^G6fkpX1JCQ65r1ozi2bJ7-Xi$#ilqo9_{bRQ+8heW3=&(s-I5ea-rzkX$|n5(%8o=(c&!k}?ab8cR9#Y)qgFu)xdKmBRC z>p31R^$~E%lHvxpqNPGMU_?yK&ivhfv#edueCxW`lCQWwDp|K|yMF)lGGeogiX;QO zurY}Q!W_lO9OyF<0|ic1{oUS--_8Bw>$Onir2d(M#(4Dq%`Z}wD7Ds?dM;|Okf!$a zpjWhJUpf*_>0A77j6?OSO-r3YhLB$NAMT>BVYJL27ws~NTbIVZ8G(ZFhz|c};wA@k z$2xQJ|HzPLw5xruS!^?)GCS}`fq72#-$3dYYZ3{u33X?7>agN|IjIb0tiR#KHZ2Oj zXk9T(!X$_OH@e0^%f05>Ti}K+R_v}`ii-%$zC)Blr{VT;r+G(CD9=rUjM$aUf{l1Gt9TIEephj_RC-1{jpxf8{*D(4 zdLVtj;VI?-#qTOwK_D@Wtv#~pW^Ywx=pA4APX2zI$y48aw|iLkJua=75@q$woT^Xn1A!tnuK%VixN1R*>iOIJ znl~&5sItGw236wFulALC`^8Jz-*qLrwf=JzIz`Hl=X_)z%D~cd^13%{@^tdU#M%773Wi&Q;BvY-b=Ny%yr_c2=lep1bwx z%lN=aqJML%JQaqjpy zr+rzhe`v2i&5^D5T~9^DTiH_zbmSWza`i?7$27cmD+_AiM$?hC-*jgQkg5YW*6pwF zBT)ZNEgg8aqIR$GK~^XnUoI_)D6&;Xm>ib5SvFTF{+OZnq0J9 zYCv?4A&k*;t09`%I$k*~_{fyr)K|D`d|-!-dSjPL4-0HCOACgXS^AJ0~! zB6fKk>KQdPJv|*&lS=I1`cct?!}`%r`JBO1 z5cbm2H!Fs)jc1XD<%}I!r}huhJDzSkn)5g$>Z?_bEB+I)EAX2Wq#99tvYddbpFe&* ziI(T8`!%rQqOXH1(Xr%_)+&jNLt>Ao0cprFsdUHgj3fIL`Bp>HC ze|z^P9CH|$0%kyss}3KCj&}8X-y<43j|0rwV!iuuyaF(u!-Am!Y+u4oKIIkKY4*uu zq?!1B-}YK0WzA?udw#y75lm!VIUOp9hxU?J>3gD{hEEG7E7>)b;m?|KC=^yw;-sX* z99*0_Jw1K>@X!{frmI(WWu5sm*6w)!_=RkDBxxoN4{slbdhfae#S?%u0gIyE-U)zv z54k>8mDc0|KgA7Itf^d-MV~(-coep_?sRtjo=}dl?DA{z(-_c^&fQmq6HFyUF>-6A zT7siXA>h9g6I#NsKN)qEJvhd`2^@DB`~^oho-@Sv#kwYE`M-%gvi?$`yWh2j@&0(p zhKrstKIGYoz|Bkb8a-T3ZvmkH$->9a!5(@JI|3FANJvNqeJu!=Xdy4)IB@^FC{3Gr zG5*D+1v08^B$5fw;;6SI=)X>aK^39fRUP2wcLhLCD*-lhz{UZFHC&5;oZ4ywwg$GQC5ftMgvw`v+DJ*S z{X~}az;~kFpmLq-g0sbr%yWC@6rCLq3CHKN;@kmjMu7p^99^7i>-r-#UM2by+$ zDjI z66F+#mKOs&Y2b&yNYlwI{cE@Rh&4bY-X7MQ)^}+(8~H5ee9)kEq{Gfr)W;R!8i$t+ zy~XzEIk@t6Yy12pMvZ%TeB`mG8yJ`~b6|6F3i-memb{-;D=0C=6CZsK1OX^TDD^;fUNtV{>w`#K z004L9|MV?4&0O;ZoJ`|WGZgv=6S)FJJbL@t!A&+PSpD8ob$!z zp3DV^&|{!oiPcR>S_3x^&qARjy#MoUKzr!pt6#Z>^PhB71CMyLf;NlEK!6wua$mal zJJvn$?)a?>1|A-u0sz<|OioUgPeKca_Nw(7HHItoq5ItcSRj1txag=MpD#xJR?w>M zOMqBt?`TuYqIc*d_%Bv3)L)U1vO=P?s`LX7*m7$`13!zMmKlj2o$QyFl|jds_dUw$ ziS{dEu9)Wmrdkm77(BO7IGPgGv=~(D@YhWl0BTn5ThgBYx!DczTjtI*_foX7jJS58 z7z&8SJj2d_Twg>a-+fpw<9*Q)O&@@}fAJway#G8;)Tqnr`J{33NU5Wvej=BX1L`sn za|I{;$Djvfq|=o_-Sd!gqvYzKBi0&=X}pDO1Fs{rsj}aEjavWu2(Qy}o#pVB8B2qx zX#VG#s@4jWaMbP(jK{~v!1Gqj)SO+WT;gbK0Q@E&f@0&NQBw5qVr&8erZW38UlEk{ z5MUSX6m+fdcW16`hJ<_&Cd<|(kxsEUi~gItwPqsw^dM86Ag;YW9&pe=Vtt`3Bhp%p z2?>TWI>>r9h@|s7){f4UI7#vG;(#Zl#dCrit=j}7vIJWucj|7OJ-E_FlbaTqj(*W` z?o%nd00_KUf`_x0l#a)Hdm7E2@U!1%DYp|+slr}Wv<)Ll9RX6Y8J#<-lr~xd>8ZoKNlc+{-oKDEx5RNduuTDcu|APPP1%OD-W@~*^Tw)2=Y%T zj|Lb$_y#0z2M{1ZDd72t4RAt z626mqiv9}y=7#}RcCEEQfWm^PRRB)9@tQiZt6}+o_<1#AMRaCv@8lBBszPbhDZ&U4 zV9&{k@5S)`)*vcGUfA%YPt;dUO${rUYgGSs`+9$1;5?S>`4rFvx(8(v%RrRVNVoww zGN-0aIzYIhmqCBwR=kspSGW~;if2}#GnGLFfku*3ivxfZ?*ND_)2XGl-2`lk!WAyM z@`cO<5DWb{FZW)J&5#jwckULt8O$t>?c>vg{SAAEo0^bpnPoOZhmsfZWu6Mi^#1S) z!}a$n#y2NsCHDcSKR@($)yk9c!Ah@P%4t;|9odW;ewLNpwQ~d=4X|=N4|9#qPbdtg zu|3`;9W-j4cw6?=8&=P}>zq8eDy0@xY-#oL^}R3t*stLStFUiu0kbX~eHo!pYiRHQ zn6Lb=ga|1qIuN?1oQ{6RAO6(R-}Ht7dfiq6E3(J7?pETOemgnEymg7iwxV2Eq~BQ? zw6p{RonKtc3q9Q3skOAkZS5%6(r*9WrUU8w)}0&yF%+Irt?ik5rDE`ikU~1c{mw(a zoq1Tb9WzBrOUDPKGk5&?^XKDZ%APN;lyhwqr|0L3fu0Rzl@}Kew5BFE>Tp~cu?<%S zR~`c4T+Ere|2~Vim7Dx!AJYtM+1>%087*U1rk>2@ql&7kBaXiY?)2Z9j&_rv#QY;q z7N3gsKv2D9N;?n%SxD9QOjthzUC27#uHgjfYwtoTDoUNKODjsP9UZTG3oh;hUaSBM zbhVxj3?AWuO$Gd99ZbprwpxKguIKHlmbF&?0zu~cim2UD*3{oTRZTKo@yY>7xPQAb zH7+)4rQjhT{AzMZmmbE6jPjKU@80S*IWKL1nb{~FM9#hL0dRC<1|fZ3?Es(V$%hdG z$=r2LYX$SlqM-wol$`|>>^ueE&>GiTtw)<1n05$)Wa+6!MH3FDiL^LAR_N5r)XvFl zRSALXJr-6nGBS?(JXmb5P9zjU_NYT0# zdc3xWdHDSz;7|S#@Q9%7*+6*{YDZ$}Y)s9^1nadaWGLePD8)fcZy{A&GbaGbw~=s@ zwPL0YOHSYf<`;=mA{ZJ=S?%V0b_6`m>sA$`o zS;Zm7AOJx`Y+2*;^NyoIeQ1AyJfN5x?h7YkFGV!wFsDL~~_@@M_U#@#>iP?5yJo|L$D)wgDo}uv(VT{$Vx$x#s3f zWo!+|uoM-CLH^;Q@qL97%8;ZK4fglbhVRU_ZoC|BkKCsJ`UCQ5fJe*!ti8IN@bnH- zCYRgA++Tz;zWQ&8ywEX_dI3_!(IPyB9}wBnQ{c{>3x}oa{Ts^LC!j$m2i2K85Eeal ztN^QEq9+y;O7zq8t`10pO{QwKvp-I%%mb`E5C@5(0DEeG?@pIbUXtZAWuDQl%#PR>7x9Tkqn5=L@J&0e$!^8zCiu{pmCcug!J z*2K+>O#kB>CxRq>6)w2_&MpHt_$w$FS>F-eL^+pBkm~cy!QCH4zS8;@Lc*>1$C>!a z$1}F7!#y{Prga5)^#-7T!Ef)JL-@3}^mwoA~*owKV7?A#>qO~)% za@tfNQTg)DJ1o!U)VChtClrd6KU|p}s{PmLB;eSy6(+De-4F+qR#|ye%sthqChG&s z)?lo%^($5yM#IGf;JlYX35G$b2?ro-tDdbI%`dZ&$?p&ev&v{r&IqdYYlQ=mf53!A zOx$Gbo-I*ghS}IO-H*?Fu>wSMM;q<5hRK{9weDQu3BmF{<+yEi1*R98;&%f zzivAxpGxjAb}!*bU0sC~kl22&c6g`9OrT2THDQ`j@k?IynWf$sVgvxJZHDoL84w~t zEkmEX_Ip$S%2iM=Y(ADr6To~@--rF(seg_;T-0$}C~*X=2^r{FI9p%!vSW}|+P;^~ z2kp6n>0cQ#DaHKD31ZZ@@iQwmGuaUMiLPJden@r0*8snA<>dK@A_fMsK)4Wyfq?!EH{Qldo-TM5F zO!Wo1Y0ylyuw3^fW%P^%RAN5lQQ*4p zWh$ANh;SC|{q~OXcizgH%1V)iBPGMvPCM2+rZ|h0y);$a!X`^TUS9Fsii8Phh)Daa zCs&qO`G7bq4RO-=xuG4oz9$VQeM!MTIU7*XCs>ZKIu5<<%D8Ue+V8aSO#m|MC|w4R z?R+Ry%wtQY*~5@54=dL?~A=VQgR_u+BNhSI^13__FuEROypABLU}T z>Vq7p%ebb#o*=kygZb@crLMcUv~=^pM?lEqblmUTX*PQBxK+>8TaR^TWX#{@Z~_pm zmsbF3zbg=#R3Owa3Az~O`z;IGhdNa+*B+ncF2ch{=a44W_D3=^GAi4=-4tS440Jzz z;%WQ@MOFzl0@9K*99Av%=lhxVbHK|hD%PUVnhXY-TJy8L#D3mEodSFL%1qw-#hXQ# zCt!I3#p*dd{sNpim}&1h*dg%4l_~}*BC&ycKBlKub<1DD+gc&3{yD>Hrhfd5GEKJJ zmaEj<=k>i?%Oi|3w&GM*AZIxBx}W0Ixq_6FGFKUTtTi}PFZ*A_#=X9O42++N$#3R7 zSj18!cWgWu;@Up;tqweC553sVK{W<`=c{Z2U$!g}Fuoy_$iSCD#>Yj>klQPgpeYL5 z4#}x}nsgsF@3?SZI6ZWWA!7Skf?3g)Aky=0apE!Xd2s*}x^m`qXEb{ox!?%vZ70+H z>AVJ{sen7FrY%?UzL0RM{>W>4XN%|RXZfxJ^{WicO$GiUm|0ZeO0#75_-V^MlED*u z3equ<9gckiV%D0o`Mewjh6c{BFdQJ2*v|*7E{`Qbqxh<08+%6t&S~un=M6l_Tnx17 z@bGYKlm?f?xwU?h9JSj-F?2wgEMjb8DP|4J@BE@3qGM0~(8O z#osJ3`zZZ4#r@+LwmV=w9aI}q2dAc{CMM#0kW5TYlINaj0N_Z;l&ODPJ;UW;`+2{# z6wz*~)=*@h^^G>*3)6w`&$8{nNUMCK!thM191WbZ#pZxZTmRf)yg9N>w2;sLJcu!> z^D^)Gm936DI=+9sJYKZHFgr}Oqx_$1R#@)_kZKGOyF0f^b;TR4o@AR4w^oA-h|&Vg zE9mh_1{Co48F*ikNyYl5m^_;TU&0FzuqwfjiusS7ub*v5IPoBMk*}kj)vZa(lIpdp znipNxX9vi1$WhpcrgEgA7Raltr#h9!Z}&(@1aUE6N0=})YY0fWoc%mrHk|tYBagbH z$vZfSk(O%mA6{Ut*BvGdFW9sAfpN~Vsa$HL1{eS*U?z>}#hcxdXCCe9mx*L-{ zi)Z(hD(p9z>x)GVm2j@*B>DQba4=$K`EUj7yGDo8(RhZGFVM>C>gM(W)$HbY={7UV z>4wT&_d8!&{U$P%!_%yqWrxT{tmMlPq8)Z}Q6F_HqMZrTD)@*k7?~a96qpB_aKoyq&5w+0}Xnya}#T*YZ|oXY%q9b?zm*Y6g?-$RlW@D?TTWxzAq0%*;Nkod~3o?0WKQyMdmO^+hz3 zt%z?na{P{8szsiw$@z?8$F!e-ovnMZAlk9+>Hm;rKPw#;V7dTa@!7U7=rYDN zeAPXOR9b=q0Jal%=Pk!?{Iuv?7x}1Aa4P*ZJ ztG}l`AhpYWKe_+q-H582&IG8)^{K6SsJ=aLNmumUONI6Rz!n7}aQky-J`VVvpN zd7L)OW59>CAfs7<64Gl6P2Q`XG)i(t${^DX2eZAF#67~vZl`aO%FO26sH!mtxi5+|;bd{inHGKedAp)Ucj(865Xz4cjDqZOgef1}_p}E(To7ja zxiGrtt_ZKgSf-pVSW?Xmr|G&q14FO&6MgjMY(pmTaD&~085Zf-OiAm0^~R##QVPK+ zcj-ZT6Dp4!E=6`+;mAQ~78|lSZkUjO7g4C`;`n*`+3W?%aXS`dW-ZEsorON9ivTB| znrgId*YsrUBy*NSZ4Iirz>YSRmU- zov8e^TkFEd&K4-YTPFX)G{xyzI135djX-LBX4s^8aw`9EhG;9r_c4qRYw_7dwSiJO zTx9X4OkimPAS%0$s(1g0Y08N5!D*T0afv>Vy!QXh%6!E=xXAd<<*L*T#L&zC7-L4$ z%GY$uRAuD0$YbgM=zxzr_5nA2RUmHTm#Kn9xJq7&W7h7)+i@Z@o^1riw+HR)Dt(+e8hV8&U0H8$O?M5T$CblcJyZu` zND~dX$YY;zqoin~ehsB^ZBnoQvW!8|bZv0QY?`J7iQ_6320WeVR(c;%rC)%2uWZHw zA0G}}6PpH@N2VST;FC6gFfbbgY+ZT&jB%R>pPsoS9E&hkO-p@~Xt1Zv#TMt>zZ-M_ zJCmcu^xBpq8l$|$FOx*+uVb>z7*2Hy(ih17hDc4{bP)C~)Z;$!aYbO*i)Nk>Sj5@< z{fET_w$Ie)jVABE(AT6OI)vJ(w!;ZX&`2M7$QkR)9O|3*XnCKNk(}mTZ@x-$a#YL2G#DCcLd=WgI)n~Fr)Q@=gHD( zy)|ne@J}3gyXzRWThYw6U9Jf6gyjqueaLPe$=8%S6yKtPD4P$117G(=#W6ZcG>G}{ z+rq!}nmRen0WS)@CM6>zo@lICOt0*B((QnnK(&8S;wv{#+M=MPvuP?gye5RpT#}2d z^MX<|ioxtZ>Qw~G8H9o-e@2LOBk6BD((95mf5gmdnlyg@dasrG%Qc88;mdV3E%im7>xevka?zU6xh(;|_V>T$z|ov} zHJHBQJkK%x2(ldL!O)3s=aTfJH27vG7ie0@=Tk1JIBU=Xg$A(0+Jqvv@x@-dEx_wM}A4Hb$HhOX-q1$xKhR)ad2DvTW}+ z@T0C8q-S_Is#!FA4 zpuMkix2u()A}5eh)g_8?_3yq0H4a2{y&L~n_6Te>isi^29wHV@eqYYj0qHzJLExa( z#}n8!X_S@o$&b}Mu}chzH4ji7l*|_S#E;b$JBs?t@0!OLDt__kvvxchx`->Qg_IOV zv@@9TaTA%(yiAKUY5bI~?B--)L)e1 zr=m-qqq`(I8$A~q;c_is3Rld!H&Hc2bAu5}tS0<$7MOzT^8BP;{r=dA<}_8x8_=Nm zraAy);v}49*7Ao54C|sX>j_1~uh8h3G?MC(5+>;|W!-k+u%U~@Z^tAtVu zFt30fSx(zcs_Xn_pCxiyPot38&f|01>Bz3L!PzQJB@csJx02iGmT@9V6T;&Hmd~$x1p;fy% zAE+|EheE1ERQ&)YpRY<9`}wbnD%Xa_Bei$`bdJnNMqwzfwC~{}Ru@C1hc@)LfQIRd zkdWG$)T6uzNSMzA0UIJ3}d2PqZjMoiwlYq(pt0BdB61Z3Qe5@MBih@>V|xnehBw!#Tt$@RuijjJOHL)NbHlus z3H#EUW#&DPGIHPK33G(%R%&{G;jd+?0HMWg*fOe1#lDIUpp%e^Z>p>tzs#kx0#3SZ z4+%y5@hPgksp6?o0l=%f+(*WTEAdy`W}`H63u5J(X^As^XatN4T(wQ^iNAiWeJ5Vq zh(V)taX>bL3lf22voaL?xfgk!)~p)LB9~D#YOs2~vXBrk&X8m}&)N&|R{bW+;(T3> zx<~@33Xp{Q=TBvkQg2iHi}tqwN$6h@l8IZe#QPUNg8VOR3_zQ5`2O*84dq z(BYJ<`gquud7_B-_{~26Rd)UGx#sb|FuJ{iURwiljP!FO?fdryJL!0#!bOx7zw8^5 zQ^=yD2gBDrx06klTAAar?=Q|%4guaQj9g*7`Zh@yoM~!P8?xbTMGYXBcI1-W@zGvxb(Ml0gfR(Q!2D8{TJ8eBRM*r`yHB81~0wv&~&8Tr=07pcu(u(*}*x(9$ z+W9Bs2?zit(6L6J7@+zZfj`||%TxT*~q(ljG9hPskV0jy&ZC;eaP*_m~pgx#q| zvb&n1yzSKN;v)dC5K!Z}e0m4;7^R^uUAi9HvWvK(_}8-m2z!E&9NE-g8qoV_K7PJK zdS|#40!vLXeZqdY6FMf3yUoV+AZj(U`L3#^{z=24V1iEk=V|%e{r{f};KKisk`g~W zSDDyJ$1c9erzV|^wpNb5w#Y#|%4j3<4>5@CGiVJG!+7E)jF7^~pYI8&CCiM)VI%_s0zH=c>{$ z0E0j2Hs9OKhy@v_ez3#&5uP{e6Ukr@nVvUI3AA`DJtO*_;Ek8sr>{P03GR3zer7ia zw|C7QgS=82DN+AU=KxOENGXHLj!CE-w)L1oKTT#)&r@Y>98&XjDqJ{<)a>9Qwzf2P z@S^z)V-$#t`#iaR$OfLSJ7e@Eug!6FXBt{Qrp*xo9#9_7w_A6YnF$fdlxc1H(j-5? zuVdEHmrYLZtA2F0Vm$?b_D`oNaRG2IoLyhzM*Sk6ag+dNAATzNP&gbuWeU|@ociyi zH{LeKdr{d&biQJCIA4H=%);9b-3qJ5K>!0CGCzR$t5IXfTIeldQyK+cr%t+M; zU!M~NJ{bWS7m1j}dUHKS6c&|_x7)+C4p(v6RK7nHFt(g<$aU*(&yIvVa|DuB|H?^u z&$m;|ADO0Ywt|nvpq*a^(1AYF+`1*>?(f!NA>Xh>ITznsAa#aJ{!0PDd4EOkz%v z2g!%8|4AtP=ROr{Mn;rL#y>c7^J`zN$)17O^_xiY)T;t5Qcg`91Og9&pC0ehbhFt% zQtVGFs9HN|0QV^Mw%w&(%-dFJuq`Lmhay<&ZCun#Qe9+3d zs~N@cZ|wa(Dd8YIdEwl{J!S?QC0sV~K+0`J=!XmGn6pW@#_{w|Wy$^f0$4>>=5LZQ ztx#~p%GCL@c2(G*a}D~8M)mg$l}cW`G%mg8C5=H()v9!nkg0ss&@)&p6*3y69B1q` zwhRa(YG+nQ{fj<(kV$WS_v`>$!RgJ_4TsW);q#lD{^`Y6$AX?L2@af(x*8VyM5U`Y zj5*4vdB+s4Z19M*w2!5gFxY0o8Vo=V04K@hDk<7jd6E69!kIMC>CKIckGFgBy!c{$ z>&pf<{HSh8KT=lKtNTQnQ1}IY){^v}t(*#7on|0E&iCx)m^@?uFgnogQrPLk3GEV< zjBKS2*~NDE^r%v~9nBDUJjIb^0!Dqh!xjAXAG*V1?9Bj+udJ->ZS=)tofTkbd;gya zO=J<|w1M^rm#zQuGFaim2iNAWz}B`eP%D*)$+*1xla$*omf=Wfms$`>rezTmpbHrq zo;NkkGQ?0>)U`lFcqY}YxxPK5Zn53~M#5lit$ zUSG!a)l<7~K!0qTL}-4uw(8wZ5o?9;+6_I37LOQzQlwgJ@G_wL=A3uNrOnR4h9wH`MVRwq|8j#q(Qi> ztk8+6mFgOZx6cWd(yos`&9r#~<{11jKGx%~Mix2iJBhk6N9S34bNhMQ6FIp;3fC@g%(}Z;_AW-AG>@U;2ZBNQcS^5@<7WCXCsh)D1s5r+M8vl^kVu}cS_2ux4at#mj$?hcUv^~L3aoVP!AizFRumZ>Y` z_?uqz=`kv0IY0a=`{1R_pZRU}F#pn6qY?PItgtun{}P{l!E~Q4{^)+cp4?V(`u}+P z3aF^M@9jZRBqSuI6$PZbLjqztweW1hJwhp=5! zHg2^dxCtA|AfLy{Rexdth#R;1+@WOaP3NAuaM)k5KldL>AKM&##(&cxe|GQcM}QM{T3z;Z>z#-h`VsL0z=l$2U+nlgP(__Ws7M}u^((>-Pp)`harS+WiYf}bcA zcSwdjNSyBfRC1b^sf5SILabJB`&L>0J^-duj80);e|=ns*hA&Glg>Wc2&Em$+Zf$S(Nvp=`SUb&GLiNBdFBp?#t-R-A@nD4 z^K+>W@ENy zexhl;;PQBF58(T^2?D50Ea3q%+< zA2U@YiDFg*Pz&^S-N2joZPOVwbp)v(uv4}x>sgIoG|zh5famNO&A?}%eEB@6L(EHO zcxIMK6b^U4$r3f5zXX$(_$kRnfSaa#&}J+>sIrij2Fvz!QS~qMO;sf;YFb*(!~r$W zGA6kJzjvQTS+wwqul?doR7okKrDG~p16gbpJI8}d7krG>huvDkFpct zXLh#W{gPB;)szYrS* zMWT+~$?xtt0o>cgP z+Irv!0f^4Vy5T4N7SLuD7p{A*Sd20vS{nFmbm1P!i^44=u>IrXZ25U4r885=XJ8S; zGrY)277zmBU|A<2yMp!0nVA_of8Dmn$8gFwC}VY)f$jGo&iUw%i5*AdSx&{NOu<-@ zi*D?(FVojTcnS-h1#$zTfmDRV_M$b9f zoXFh?5`KJ_xBA6A5ag^U&i{tE=M-(TZEf)&hVIfd9&VP}yGP3ZC{ekz`k+orTdzz7 zpx$4sXXj_%F<#D)y?0YOyA)*PZK#)~tdOD#?XUP7+aA&VwXZKfqwKM2!bi$jH`m@z zloh=ec%fWhNA}2?z{waqqpvVNmmA_Ff#?43oWenls?2fDHp&&WQb1lgmrR4Duph z$IPUgQ;^fO=j9@oXQmV7lFqlIpxRl@t|`wK+q+9WI~VV6H3J~DU7ZE6CN3?M zt&X6qnOUQpM<^sB95J)}^-nh-%w8RWGZTqX_PlYJ0SNz`Rj8eH5%FVVO7J{3J(SQtf2 zAK64F6Hxm#c2s5`OY`i#OyurCc=#tgnD*7^5`dkZ*FWW`9n>@v)S#)+87L@rBf*eX zy|QP*YY>sw_}?=dXQ)9GF%fYh(Ch;0uks5SvL9nxor^7E+-g=unQf3TU<8qP_i{+y zj1$En101*1(SngKl@);qH!v_D6|}Y6{N80(NB4=u?IJkq^a^4OPpAgj$%lMq3`{J7 zcrHLD;$xOf0TB!H+Vm|Fc&AN$5P^%2&j8!25B41BT?UVpMaq*g>Vy$tmEo@GFjHxP zb3I8jrRp^!@Um>%EVmOD@?~I>TiksMw#oc&T8Ebc<0~t;xUnaj*+*yJVXNg}g-)Nc zw_gSPG&W4T+HH)FpQ$+e<3dvEq2cTMwUMt#Mw_lOwL+8qV?weuOJZVH4zg$7HKMVB zXNqF-6p;5;>Hv&g_m)e${UzWoPyjSm5mlZ*q+^ zBqjFo^YFrEOU3Qa9Q%{?V%CJ(E{@1?`qZt*beQ(;jtb-{#7bQ*I~%APYYzQ^oTK02 zL1oTsTJGnwP{|NlU!wvlzy}I#eci;D`ub17qn22?XfnhPrg6sa4x8A)QzZVFI#P&5 zf}iGhcizAOGL#QLEomCsf#V?&zsTVF)XYXm3y_s=NyKAk#*iXW+5XK7WX2wM2h`d) zPvOmd+Rs3n1ns0GdwB`$d?ub!cVvDy!0jH|rN<4mdBr4`adK{`if))XEL3wk&^Xlz z3sBPT?>1uk41By0k=J;1NOD?Mg@yU`2`M=!TTjW^ck@MFzw}xs2aEESUFtQ~_@agF z%X_0q8b-?O=OO6h+fppWMg@NL-1EL%owLZ9tbZoQ>V`~4&8mP?*c{680jOq7#;7ST+?iMGCObp1o%Zj{Mt@_mB!*-3Z#&d8o_nzBUyTCy z2?%I$0sL>fT!FCmEns(4bm_2pxG($x(Z&KW zVY^@Cezn9w3sAPYi?LbqDra=KfcK%QbdeuQXSy{8|77~N~#rZ6C;m~6Sv&3A7_YU**`sbjp%rEDK=G-1%9i(MaWwZ^-RD}H+U_TWo zlak|Hzwt8~?mw6rLU9Y}#o$5$0&_R~{>8sU7WZ=xj(cm9=$Awq)juxo^V02A*F)*; z>WqbaBQau*15S~nC9>D=N>_uNMm|sPCGw)9&K@z zWA7Q*LcbQF1~@LA-Dm>I-)b+H>45?mH>uG<{)uc6nfF2Gr)^MFUWIw; zhsD9~RJ9UNe4H(}K*ZHmbN9d#n@A|DSh~n-2I|o$Vxy>(vfO%jk>g<;M$1TCgHH;* zh%v>gB%UHuW2`70-f0wylw_~Cbjy@r{$-9BYIdD7{*Hi;mZw$ImpFYCpN<=uDjo-b zh}JFFcUfVi2&L|z18Vc_Q(o76ESm7VibmQSn4586`B=#4mfYEm4Ip;_p#^?HVJWGA z9q`C;iC8Zb6kfQu=P3o3v(FOaS;sX{Iaw9{0x4}ezinb(d>(ZbZZcjBw1fRwR%(9Q zJwx%-2R?_jR?{mz=wbIXERKtRV$Z~;oUp^_@|7Fs=(*BPezc$FOXyYao6nXsuny- zd!s4sGu)Dy$wGg81=M$Nt29Xg9hL}Ej$*;_NqBfPMetw>Gd%@`{b^FwQ)P2YMCw?6 z_ftOaI}BaSCizm)usJX1Ww0sz{pwqejwI(A$~}P|G~J|QoIqu4*7!A6ZV>h%p~CRC zz6$WbEIyb4{uC^b+v*9ldBT9@`362itlP@!G%5N)u1u)P&gxqj?Vr=lY(3LP;!H6< z;0Z#0#Kj^}-%5mFLlc`9oA~+OpflJ~q#4_IIg{~M=_GeIz4h@Bi=bSE zPf4^tP~!3I!K#6~0)LO$ZpB7Gr>#RaS!f{U3$QLO`ND5b&e^^1TS{%%d5xQI_pX7t zzRGfWbG?3)yA-Dy5z-Zobb`7p%7GZFsv$XC&LS*hl{(syl`iMK7iB>CUUk&teTz+e z^A_;z7$|e^T{lsXTwGjgL3WN-Ur>-t;7pe+R|i=(RHdI+VGD}u2Hdd8ZZN@QWY&-e z=!kJG_h5giTyc8!!rPk+yn9EQURHqh?#8phQITbvuO&aIUy%`Jlne{SzJ^EmGq9TgB@ zOmf*aqLirzxY3hq^pDWaF^c@(Z-H1V1yl?wg~yQKa^l@$yuNZCvBA9rzZ)-JcYJ;# zbwjax6uXW7#aQO$)7EJzB_*qw`!sD;-H?31wQ$ye!LK(jTy+O9zohpX(7dBJFLV9? zVy>#HH2^R>;Gk)}hvI&cfgc7A0EzuJ?S4d0a;YwK`^=6!DOQoCSxpYNGsX zu9)yBH>6BuXP15&3?{f+r0aQPp)^JVE`G%aZyqnNwv@80J;KuM?KJ4Q(fW$@ykmg( zWLEN$QR-gq^7`e(W&gX5#-=1)N1g{(5f+kZ^NuUul|cdeL!`K9d4HWgrZ?`+kw;K* z-l96?nnGGzgTw9OeV*di>5b;5%l# z2CHdlrO}t%!Siz-Ieh4Ff-V1oUw;fhdr91D^^RC?osJrgAM~sK48=CJZ2+00a6nKC z%nDq>jAc!_LhAVCx$Z6Re;1BKOaA7{{BGMpPZHI6_ZOT|yZ7%3UL=WYvi;b11^++g zEL+705E{!+_jexw^JtMnA;xyz00)0kD>6AG;&5T36J!SE1yS)oeS654TR#6f%(A>l zhF$S5=_sE4y`g8u_B?@C&e9oSVMG+2oaQx1s+riKs(ZCM7JX#1?<-Ah(*yxg&Ct(V zSeaW%P({p4l)_(y^*`+B&%hDTAP;DJ&`Ni^%@)&Zz(zRBX7w-%N|X5=<6ZbapExTiPHL=lp)X zCWG0NqQlZW%5WXWfQ)*BNLRf`XMFq~G&kj5m9b`=EH1h4v8(pD$Vh$|_7HNd1Hy6c zbhc~D9oWVSrUj9Cvm@_Pc|I#GePpP23Y;mJoZ>s9c#7dGd-@`yj&Q{Uq?j2^$pICt z7DJzkoO;4m*^C8(FEz&#pG!%>iImmDS!|xkKeE!I5j??7v3XQg&XP50!9ZJpCCTuP zo%+Ue>8Tj-S8}l#m8XT(MvLgDE?1*sV~gWso2{=xnz8sV<3S!eZPNU{mEwWYZQGz^jLP*bVkcjtt%3rULnArEWB~88?iQ9p93)TG?zL z%b!W+;fx3}`M8GB+0dfXr5S>}MI2=dxSje{ubJ`p@BDh6KK4%O@Kbd%CB+Qk5B>wi zOS2{g6f_8qNmzdVCz6Gi6w10MxBFgEl`G}U=LFpYh(3i=EF_#z0bW7YbL5se-Xv=c zB?T-roI5wQd0xWDdpqT4&^_}s&cWo=<2mEl46N#opLcgsT4)nDN{ib>C&&1KMcVq- zwzq^3L+6Ml<^`GNLa{om)`%^JAM;+@o;ShUX=FCk`$xy;vk1~V)LBGx?}q*^aJjgM z|3J|`i+A4+`1L4T0RtFbF%l!J_Lsde`?vvAE5<(1w4$GtkfQVM|F)VR(I+~M?&K#5d<_> zZ2c*!>c7L3%U$OIm^-7aNBJ2ARwHy5AduhD4Lcgxz6x=IJfv-Vp6Yw_a`&hC9&N41 zG&fIpLYl5B*A{q)H5&~F9J8&Ziw$+B@eFbnOJo-(SH1SOH~t80pmdcq4VGQhNFqQlpS?;bKt1{Gv#oYR-EhQHyf6PY-NbfDGy&+fAx0Rleza198Ct8 zaVrL|_+A&ve$&6iS4Ti(^ep|0pqp>ndPRdGn7mMrcO#-i*c1 zkK{R39pNmN2n{kvr09JJVHCWFbC6Wg()z$wI#Q@TEIuzQ_8FD(6f-(4;zR>-IvS6qzS!W zr0ffVk*d8zr}xs=wF4r)>+Qk3b$h6u?R;I=DreDTxNx=EV`3ql3Z{JrA!e_Ub)+Ffv*fL7c`i6mckr}JSZs_qOw<5Cm~i?K^(FI9IN2{3Mqs_ z3&j}w=x1d6txyUzXE_n|MM)Ha*?!M!_N&vL0&C#W+N;8*b|jmA65M01m~x*{Fi<@% z4bwrYdJb@-Nf=?_k3g~+zRaygCBevkm1Rpc9zC%pa3gNrl z{|EuMCmn;3iI44T;dm<}X!4o-f5@|Cwi@+6fN1N~%TVJ|9Xw^-LrtHT~gk~Xz8^T`j%De!fxkq82@ zeOgNyT*hxntjV z8O&X5Fg?%X>r*;;gepy64BBA8*Rr`G+XdG8S4{>co1-SEb>5!cyH~`V_C+YU_^LeQ{Ivgey(1!nE_XCHEh>D0wsM664DkZtq zD7={7zU?&`PC)YsvXXjY|2m}mc>3K?=5^rk%+ZeIwqM|z0bcrl+3f9T$!6=P2iR^2eves(AtI=obLo?%}-N#as)wSFa88epHHHJNxkbwW06*9k?Np%ft?K!lR8tk8bC#7q`{pkBs#A*|V{>JT^4X zRCrM{D+n%&cO$om$ByNqZbJ$ZYrp$t%~O;X6iuBKg@lwpUl@-eSPgoT@GLWy+;L9G zCT_ta^!OvIULjkUs2*b-l8>D*F0zB43D?Y~Vy5W%__wtYqvZQbN{M6m)A)i#Cojso zE!2%lNa16v3ciM6mTIi}ltl#(*4{Z0Uja`ientAkG2TUo+k%)iGm9{P6#IOQfyx0g z5_it(uIU`#BTygE*2GmiZsZXa(w?MjNdlzB*t;vT1kfE{f?wKuh^}&;Wex~$HB!hW zvpL_*ufCGb$?SWLC6&O2wD9(vniEXm(TPdXk4&&l7i36c_zszr4dd6=n6W=uTl$Rw zVK^qgI{oRgo|~D5-l2z}6H2P%b@c>x;SMSN9wZm+85qANjk9rTBorDdtfPG6R(_Xb z$5uVcAl6b6Ef}45JhXhcXq>=7blqIOe>E>}5!Ulf*Tswd%nMo2JDE*Zx*GjS@I-BG3l{-&ZVZ(~^)~%~QW!LS3 zg_B5yN|NQ5%baVnP8)wt$WQikj;ZvA3?M$oDP)0DIWE3rMHn%jZlo0?t;WrvT=q>2 z327IcFKseFeNh%CB?);yrjz_!s8T{4>P(!HU00TwKO<+#qHb*~sv3Xc5X~!Y9~3{6 zRXh5Vo`ual3UP?}fX|Z!95KLEp_!z7Mx=7^SE-;4?eXoRgUy@qipKMugR4CvdDVBc zd0#h_k1i^LhMXV2uYhuMhbA0ZqQWRoc_}C{(prZFsIkkp&$d%B_j|!X~pLcu~;h#IB znsj~b>Mp5iVp6j-ExI=?I@b<;F%Y;G#8Deu4md@&mzzvVd{2GZ#6*6a!2D?hTjGeH zc*5u-#=er>hwZA{E*ZP)wjii9_vsIR&L+aU03OCLek{T->2%Iy1u}k8EO|gh?~)6sv!n-143VN62Lf+TOrwgXpT^c8bQKr7CK9IbIbfEz^f-plcInrhN;3*5O(AmN z?oixX++QzZq&fZ}NiM!Pd{br*G1uy%us=9io~R}gXs&+CHyJS0$qF`bYcY_%oWbs? zc#DrXy6H{w7Z+2NT=PHvyf{9_fN-maIAH)bnvXw&aYDb+_cg?!Ae*?gSvQ@*48p(a znH14>$Z4M8)-6HgiTqa|^)G2YrS1u6!k6EjG9?zZn~LrYZ)El859t9p&%AWGa!nTV zIKTu(ZbxR9$_<->B9r@z;-A2L34e(JsUviU$Bh~QHZ}W`b?mLd2o;6!RoSJD^D~IY zpq5-9`Q?kVz3zbC6^mC>yg%X7%#NQ9E7fL~*r}dnhH^>Sdp~LBd-g?qJ0jEugA%)0 z&}UaY`anJ6=(iV`8AYQ?9|nA#BK?d%Yd<#W@S5pKqxunikYjeOu&cu+HP1*tej={6 zXrCQJeOly-3vu#{v^=c-u4=!vNz493tfgnm@vL$4rVN{Md923jb{11)`@>eFKY4gk z2NdQ9N^nf>+@Hw;=IB6E!@@jLI=XceGnQ34IobUcnzn`T+yLP!mb{AU{)GcSMlcCV|Kxl^6+^k^@3LL#6ZDc&=@;hFI$P9ujo@kSxj<@(Ho({NBOmR_pbyw40 z9JVkx<#m*Kd{MvtN`k{JVV{Yupk%hhg$hLc?>`nIwW!<0i!+leJ~UAyCu}?7U6wKM~h$&d@#Lk zuilP~J=GJ7b-fy2QwB4DBtyZnfTikklza9YwpC8;BicJu$o|}8?ZF2QGLsiCGDOfL zYDo`&*keV-<3e?sjSthQdCE}Tqqz}nkg;pLs>Eu97iX|JNU${J^JKKuk|lzcxdOfM1GVGpi7pv%ufHGe@lzLdmhWR0cP3*;r?i!R>opIKF*&qaha`@34qg#W)$k=wn#W6ndQ!IFqTKOT&e3n^`(cT5(A9EAD;Z zUms~j%QS_UJeK7J!|*S{uNtzQ2xVqlh}jl;Is~$LY8j`_Ld!60beyMq!qlwhh*3xc zoX$X=Zbvlaliz9wW}42mW8gbW>9VwuZ#s>a+Y%72Qhe<@*x|xN#>EP%_>2j;Mbtb? zhYpj~e3?DSE}#SoLZC7&?t{vJ$f?2*k0372cMe#8jy0I+pBdEa4Mu{KQLEG-QfX?$ zM63zyRbCxL4@p4A?R7Q0zl|o-GF%Y>BgF-$TmHt%dS`rJ73r!z~CVx z@YH{|f!m%^s5aia?j#R%uPe%cpObOn5Et5E&hS75=ro%4qP>YP7k`0rct9CZ9v+@# z(3&~UZ>nBg>TRjLxC%JgipbUOY&vf^{Ro@=wwXdsC`t6}7w3hBu=gnRX~CFUPqs41 zg?c_F4;M=vTWBk>Br;~NMzKyS4;%~R63cN_A}u3>EyTw86I*kQf3+ZTk4b0M5ih0x z#6Wx#CZ<9B8$+N9f^Vg#b53}8%0Q~(fYe7LuN62fd1Ftk#TWk5148g3e6^!=hgaiW z=L)o%p;@B6(}sHWn-nDd=cDWImaFZU<*=yiSK-Q8!{Lti9ZAgeuV%OIR?`s#Q-jiv z+U70?uz9UnP+Y70?$@Zs**|m~>_6VHgPp59PxthMnK^EVC39ppPt>t;*VO?+M|}@v z3~ap6OQHyURSNI}i>@&n&v_VbRk!D~n#y*b%y717ZrcH(oA~yV(QV%4Z`4#t0rny( z#;aH+nyPYUSyq>C-)O2+i1dA{yNbv)jaKwyP)KP(NJKoon(ov0KfLWYT{uuh{Iu%7-uAA09)R7IUAfeD5jjdDwQpCQb{{}f|sM%Ck@cw3X-U3U@{ z)S_;Jq58z3|Kf!@i$`J)w5>jJ4^Rb$CR5A#Pn&g}1P)$Zqtk zw1F_bRGs9h_c3MXICfe;qED zceCN)k8hqN3(mFE;Te8~>7dpp4uI9hRJp1)yJmI`|d53pj zt?;nkcA$&sS7E0$)#0=R@imsB(Gqj62*X~6rUwiq@P695sk>#yd*RPyMJOZ)Ei{i} z3Ywgp92e)cxb!x|Jh1H=J~F~8FkS7>J*C{JgHZs;#Iuet+B6{mzmZr9N7DL|7+IbxWf0=jjSTF)PwVjR6=RX%Tgx2rMjI!}4^9Ss-l z^@C%ZgaY!L7v6(`aGkUab)s#mh0ZUHo+t%fJ(@dv8SM#&1pEjT-L2ze7*qU}J=Te; za$qVDz5xpHHy8NoiL`%P?KP}~QaS~^)xhm#Zn=0+%5)mOITG;d3@|o=JG)1D-a0Jz zxVX|ES!I%wJ#nS}E#^gva`Y`N_=XQ>WjVroX@%LN^7$RgI6Wv6<7#D(dJl?%Y6B;> zEC}dGds%4yK2;Qjklqk7*19G1@6fiaFYPK;Tejk7g3NABP%my--cUI#5B0W3-c)qpuAM@Hy64cf}fCgL?n6~b(E+7b^X{gAqd~y99D@Wvnj6*$4^)>E1H(C~zPQQ!D znfV&$3}kA#rV)^^Qf6izh~b2uy-Piyuw%@`j(BP2KOQ~c-77T%vOnm7qEY)N)l6)| zqVC6!H}No+^DvnLRK)^w65m|3rmJ-2wEB;U(Luus4|PXuerpLJl$B!QmD1Gs0k;cP zJ8tREBtxUcFKIqxM*{07e_!rQ7f#j|xuI?^k%MjxZ6D?mL7Y+GrT;YBY=2gvEBiU&UCQj;t!3pvMrUsAyW-Y)Z$E`d zU^x`@K+=;rwO)p@3%>d+Pw^a{&1b>$JPY~!i+VrV4WY2#;`h-HCSP^gGN@^abkOjZ_{N{nvN2!$H1;}TCj0Fipr^ko>SdOu3btT)s9ydSU?A}#mhy4AtbetMoF ztAY7@S|XYM~>^J(pra)L;9D5MdmVs$u~8>Vg5c z#gKvpvmk1T(cfa#ong`Fr2v1h>tmaP@@4rQeN|OYs!}JqW~r)8nOKaozjbV~v!4^n zwjYs3l?}ePWE|b)H6}vgZvWx5J*paES$qJDPEVAy)Q8_}Eplfa%efK(GzVwzu0cC|L#CvIb{hZ?e|_47E*$XUJcH|4&nrlgf~z`vmcIXI zKY7)1djZBwqyNmSF3FD{*XHk9 zH@dgG6AAt?a|9(smWiCAm?G{z1$eNcAKi`2P|gyb^(_wx2eXS%HoZTL2Q&es5R zowc_B?s)xtlJZ`V=&jR6O&q;C`XK$PW`FhZnHz-wKT=lj8d05hl;!oT`@t5odioD! z!@D3Mu58C^i$*sz{hBc*9$rkMaNpTOMarO4Af)aL8S!M{lqSzFPKZf~!g>9O$LcCD zUJ3b2=PojK`0PP!ihe2adNsLxEpz*!k-b%=Mb1rsnL zLFEY7ry{ME#Rx#Y;iRs5ErbbuX6!iS=hmcKA#SY+jX~Tuu^~2QN!(VUt(<$Zu3<(O zj7ay19=VGlj2~6=dDeBU`1EVGG$#43_6eZPZVe~caAD2D29P-}UDQApp|drSXaVd~nPm4?5rIhV1>vPv*=8Rt%OOEVm5 z(qdv|GJ6OUqVVPeU7$D@?V{DRZjU+gy>Ag1F@UM%xNK9=&vEXP#&)wN!RO%KP#3CK z8Eu_t!wK5zv@j?{i+4UmMD&RG3L~%gKm<8rp=bwYt7nrL^u_w^c3Ap-cm8qr&GQ%@ zXR1BLb#R7gZ+(P`*q@pi33AX>#iWu)tN`^S2;&C@HY%tmd?+a#GBxa)e(wnSMUg*L z<@#;BsmwXC4B?>yp}vPN2szNGNkhh=6@d;9t!y6th1(R0v+39gmv~^qJiG->iHqy3 z%CiSix&OZ6i-*_E0HuF30B9cnt{PlmYHPckl!abqFPZ$%Y3AVtuly!%<mkUztAVumpe#87YjdJPZ%c*f9#8%sl#Rw40(3+hR zHYMGP-vp(@^8$#&{R1?8+5ik@b6zu0p8?3U zkAW-wP^AX&$?<MMZ%^5lkq2r9*5d?0Ybupo;QRmr zCLsR(|H8`W-i*7?DkeQZxzKJ6#>vr=YOHE#65nc@&9>Xo$gb`n+f z5w|1gxM?Twx;Z#HsaX(-^m}v|DXmEnVsu)WbY2nPcQUtY6_Ts=`s}Dyl)j2mIsaPo zTC)l9X903=?2oth>gdC}&9h&OTLkm#>#v+0ogI}O&+jIrY8vXdZt@i!o2$&zJnx>? zy>9i#FNk87N$rZid)oTvnM3dt>mqu3COpur+!)^MIA%A(wsmKwdd6rhTayh(C{(K| z-*b}nQ!X>!Z=Q-s>@N>)xsaQ6C{CC-h!tx-3vCc=*1sms>5f1d7$yEH=~0?Bgg8@Kn_+&&I8bvJ&7C4)^vB2YnrKn<+c1qu6Bdi&y#o?N|b zIFZ@*-UyB(!{?5EX~Z~FLh10VsujD-9gXUW@8Hfi-B}GOgC$KIlj41k6DDjfeS7mZ zDZ~hO7fOe7yR=aKM_Oxj4Z=$#Q_P!H4*S0%M>Q|w3!L!X7G*-m~O-P0a^2YB#x8Z69i+d zpxfTGzVAY^zI@-GJ>B1bsL$H7zE&Q2+wgU5P-b!`5jubKH&XCIoU)>S@<`eH*1zRy z`+m>kZiu$TYKALXCc6Yo&hqnpdk*yA-5FgUcsY4zjIVuHakeY2%O8*q{yJ^CrJMW} zJUFZ@F;RP9Kw6e;@?_6^iY0^x%=hLdMQVdhk*q6Ctd>{Xgy8LQ;d;N^cCuG*m$_Zt zOO)=VK-MIOHGA`({Gmsm95usXtjkKr%iiq4{&mSiKGIO zv0rzMQNRK3C-z<)OPg`&xOUoe>u;HL&9eg+rR31?8f)+}9-Q+uAJ^Ivx2J;gyPwaV z+!3vBw*r_c%sz-*d3RST=>v^~eB8 zhJs2qRin=CtWk$yc z0FKs`QAc%-G(K0Bc$mAZ+hJxc7h6S)2`BH=h>N)ooX6O;<>Ybf>2n z0?=-wGT_z<{AHgJY*1lrWGvgbK0996Yvg?~45Nq2nsIZm#>nKd=qE~Jj}!Co?T(+v zC?aWlp7v<{j{IoA0!#5|n!%8j%^k@*JREaB+f!$4zUmB(fehz4G#C=$$Uv{+*R?O^ z=sD*d?j}@54NZl3pl%Bz-YfG<6Y!DEQI*HJStQf@2?Bs1zx8-NX8JB(>u&Kbe!pqG z`0{cFR9DX(S|HeT;bJR)((tk{qDn;#1O=MIF z+<eE#^iL7ZmI>D27JXGV73v@Az*)0O6a->SWq-(=m+ zloTVs>(LvZ&oos=9*&qXH(-4Gx2to39(zsuvz1P}*#$~P{i{d3Etf^o$;G`!6?GbO z5+nPoEW{}Sw^t*Bd=0zZ+l-9|^z!l9>;R%4BrkCWIen`GZ2tt9QBN6RYiJA={~#V@ z+;Z|}18!YZ=W@fp-@FFIkxFn;hUWCq9pu1b9SQx@-9qqnaBqcS>3{9~XK3D!aYjgh@+0WnOEH#cx^E^O9u9im$<|ml%t_eO#cb-#nOT(4 znS)PT_Rqb}GsBcbHRIBO96H^!iSeOc@q=CmcM}P$VXdJ-bpZABhWb{IQnRFJVhPE# zZx8Uvl2UjsCI>wi>x;(SG~uXio3%Y$L?yL)OWj0X7#%Mv3^5168u|SpmS6vH!DZWL z-Vw7u;nf4zjPkt85Im;a@Y*)QC2O*8xZehn3J*7IL?n5;Tl@ z1$GyI&$Hel3r z@D%>YL%qfVzIr6ff4pnSsj*MizSM05T!aoU(;g!F)Yua&FlQS_%soui{BpkY06 zL1l?57rj`!q>;-KqL&d+V#VOMQKHsktox7bHvq%~x~odv+omKF|iz zhO2y9P(4n6f0LNMI$Uiv>2dmH-%e{9h-d7V{h0HXlcPRdTD`Xe)-7n9O(Z#wAX3Y9 zEgdcQ&kJ3!tvso~3qs5nDtni{xOg44$REFOeDq{V+*_Ok7%_57PB$T?s!t}UnBGA|9 zY*d5M4gKeFXK3VLIg?6%Y7(!tslq!^5y^M!{=pTp_WrOCn;mbc#xW7C+P<!(#wL)T%!Kwmg^tde3Y=kZ>`?!*5Qf1zhYI^AE_8yRt{#o?j(@M=g>?f&BJ0EJ`@!k$U%M@L+|3i@a&cLk!B3oUxeILkX@FJm&%xRF z7RIQxJPAh#H)ILMAVUBZvA2p7@@m7nKuf22Zwx+cI7aVFb1yQ29_x{0l=*!#Hlq>3 zaN~o`g2OAm)T@_PD#1OJWm^LmyWaj$J6*f+i#7MsU3b#Nnm$4Ko;sVo1yu6u|9qim zBnpPSg9a?1_wjF|L4yia2(8j*URR6R^2yLoa#iK*J{D*FaBHuEC_{`+cZN0(EZJMM z`%6v)9ot7~%~Q9%%$fID)|NHW<~HNj`nH*>e#fF7r}u4l`U7V#F@F$Uq(J_@%AwuT z_~*Q32YB}@Rb%-WVs5U5v-PcoK3*z4+c0Gw%`n$N^tH{G%{-qLd|tD|=g z{f)3#zmEC>+nZ+WXc%7z6MR{&nz5t)Eu`&R)rTklJUG2RTx_BgF8T4XWQ;BDER29% zk6HBtj1ql1%{jYbpOIsg(={V8&FV+aw`4AR`%C)dxuu$NG>R1L)D<7{kSzc66EPWq z2nignj6l#ycy?7F^Asit}vpZJzSy^oNJ52qLDr5+~s$bGh?DwQ66zY$a7 zaqjwT2`v5xhR_Ii7JoORWP{Q$E|w1UTEz#^NYsaEX1Z}Hz{(!Ud$4|~GM6qcwt$sI z!tb`TF{BSRaM6p6OAmoG825JG^8jEsUcQ*A!zvkEw#3&t)3%+~u1BYLG!A@pao*y) zDs=!y)wGTqS=ZZ`9L`o)w;>rQcqR%Bd;L#%bSnt}@NbNh*$S-NxvtL-3Z584?pE&a zT4YlBE+e1~0`>Y0+UWqk5xz-gA6)C`j>kLi{5FoU&Ag)a6k4mp ztd(Y6=8Z;O7gZyc5V`inp%5+_{ck+vwJY{@!7Vo-HC!8DFj0FGT5tb=bu7|!H|5bR zf;;cI?Et7k&;Sk`tl$Ny-Iq+E{Q*_@{#2_L3!koAC{6z63}&;cKKqUC z?t?`PopUWTwbd1p2>ktN$verW$jR{6+P5`rBqE z{E1M=6JYq#MtRV)#@XT>O;k9~17id_DD9M-$bEO)bnRr(LIEvSY3WecZIE}G`}*o} zgyl4Fu`VN>3$+_vY)1`2VFv*T!5_ob0YZx!J9ATgQH6&c9Uy!bQ8CGC+~inp_A0Z# zJUj6??(Z!-REGaxQ*a90XPxY-qDZ~?7TBEjbtx4tsXahnUdo^%pF7`l z-@Cln+iyMy%j)^(Yzo9{G_GMgdlR>I;g{rn*+mC#8}Rw4s-}_9JDB3=G>_J0`A)CN z>ZK9u$)A0=*C{x1e;;)W4#)k!N9v!fDOR&e`j|yR2fJI{+5EUQqYG45@|@>@GU?@% zJBMb4BW&$sgY!ATu*-7-X;T0bP=GoK*2Y9{Wh8d zAD-}Y?Ejcq4(?~@rQhAQzU+jy`ilVtbr+*DJGc&aXCm|v2h(J*(_l^FY=kR*xOUiz znI}fTXN&GY=`LD3mVW&tE|eMLfd{>RmjNJ3-j{(Ecn83V695>2{tHYTK|o*Vb@_3- z|ILNh#3AS_7a?dm;PBz*+t=Ej6QgI?`<}MTH=_Qdk0%0sxuSe60ICS6))xI;6R*Ru zyL#xk<$Lq4Vxhj993#v)Mey=nnTcp4!1+TNX51bIj+dw7EH}Sf@~=yj25%Vu8Vk5)VL{7XW>HZO$tb05#|4<7+V= zjsc*)ity7J0A`iwQXu2duZn;!-3@*I%fMG=I+FbWfLZq34zquruK-4mLy?y<0QU$5 zI-I5FY@wTuH|IEaZ3lo}$v|fAHHoQ}Rf4R}tg*{%Wt!;I@m5|=KE4MV!uc0>d8EEm zH)ot!?N+R+UJS})j&EGfo|Q9EFFa_VM3wD@_F7(xEy{4@44@F-^@m`f2|=AT^6&&f zi#r8<(es~fmcvuEQLD4g-P{7Vs%~Y8rzL{|Y-*a9rXu;L@U)Et@Ej?_#Vr8nVJ&>P z@&ax@;MaEVeN`$d{ej2F1E@4%v`g@#teZ-+5Vp+xaVj_SZ43J5cP@zd_CiIV&xO!d z_x?dnI(sk0$TMlarCEKZFt69<+-LQes8sc-H|W;nM9}&6;x=QSZnk7N25t@L;kf$J ztERNDK(_-y)iN|0T@(oC^#G9t7})P4$U4x6Zg`%uzOuHB^htnE0oC@EugmVx;5zwhyM~Z=o&q4h)}*y%3-^?^Or`hvyH}6j{G&4p z!z3_D%Ai4)HpZ$ubgrd9H5C+OqCi6z8ESKXFd#_It0RbaPxyzH|NkOj(ipImn>@&=b9g8m3~J9~+EIMR^^5HU<8b0fsSbQO3S}A<3qb$(G{tJX zaPwZ)n#}*l^LuXYtOnp|BP;*`e%rr>5d&O{UZ6@%OpxS5gb95g9uqC~UP(bf?|mn} zQ4`b27oZbH!Evlc(}dw}`+@vkzM%;c%YYACXpcskXUyFLhA5w}e3V_3$on|`DqZL( zwQ1Y~>dyUlzuv%UMK@twVSqD|NMUh`rvtlj zSTGZTqaUvCq9_d4y=+Q46*)vTB#LF+sfS1{<-xk$@T2dakF3%?*jU0UcroPgkT&FSjEL1JeS}FW zd-HFo48)Y8{(;KP65-DjoCY$m(W_JlAIw{lw!exwWXQ;B8VMA_SE85-WsGZMgn=xk zu=iPk>oJt{HIG#sO%Sy#v-<717YLSqeTLYA#v#?%zii%XBHCG4(VLkV8rEBx`A&0-v7E2`0oLOH(QU) z`C@3(WuXKPog%D1PKKjT$g!Fzx-}1BF`j=nnmk->ksO(^{d+)H9ZY;V=pzsO#Y_=2 zfEqZW3jfLWFpz6fxipLq@2LCEffA#D&#~uWTh=o=HuhhLVdl-p2bD&2(J%J%2L@_< z_L1~6S!TGV_=T)Cu{Cfj!^&sZsAoq_dm$cXIE|PnR#xyljlXJq*IZywH+be}n1<2< zAMjtcg0=7y!qYl9zyQBV$>Y8q(IdmOQkgWmzU1qme&^Fh*pb|X9?SnVeY?)Llb6NA znTiTVRSIb@AB#vmMT-`DNo!b46u9lXk#z`_xB7*Ro`fBp@*}wB_v8Z%hSfj;B{1X! zVY*EU&^Nr9iZ_4qiy83J+;7bVo|j<=q|8tjuwP9vuhEH}qHGxzNBpcB(aMi}0pkM1 zBSb91T9L%=raclRs8}+^&FHSDT(*0F-brwxs#3HH6VBg)d?!bmwp-^P<^U?_%H1w6 zcZ=H*Ah4sjg!+8ROJ5{~Wp%t`e&CPUVI^LqeC#1L927>hOLq{bBn{NCup`1@aqCp6 z@ciUzo}iz_v@H_J3Is@SIruD71`3SSgr(h`qAfQvamJ!V-9)eG36r}hVllbev(0`H zolJ{S`ZgAqBhCFQ# z9fcMW!3ZTEDoiyF?WYNpJ`U7QoA8yr0HDq*!RP-u5@lTE$zA}oKHXOf-AYNXaA31~Chqj}z#X3JoY`+fkFWq{$?&zIVRzWZ&J1@iJAI=ldqHkiD2 z-S-?=qU0$O=yqS8Hv{5_Iw<16{jyb1+J4jzOQxFSN}#s1Ix=@V7;?`A@MnhPAazhE zLl#fWA>Ns}?0EPRHH!xuSQ8`6X>|YE#AnaGSHO2-U48jwufncXXyQMz zp}V^}mqCR*5XDJj$Bq&}hXT*Kp%3;8A2Nlv2bs3uWqKGo92Sk_P)$-JoTn(1iQfDu zBS{t(^!VAgr@4r>dPWFp-S8d%7h)W^5vm*C#J_*~5y|djatSylAV48rZ#n<-GnNgZ zc(A^GXaQ|SQk^q{(x=o8AHJMwQxw4grXyI&zRZBzt>H&NV+WHpDHy0GZ~u8mVd@mU z7Qoe+N>v5526}hiryQ=jKCi5>^7oSWrQ7pw0lK;>)}K5=W0unp3^YmR$B0=}D;pJU z>XG|8nB^M>TXza7hicEob_5l1jH02Nj}O3TPtRv~(F!?qeRx%8oW>6TT=nq@GMTs9 z{TL2-1D1zh^4lJFcYN6pD7p8(IFD5E@715b%#|j@pDn!61iI}|%5xfojpXTlk;is+ zZxeo}-10TEKO@N#x?fj&02S==(x<^LQZf>)Z2tIu>*!Cdz$2ifU;X?Q320behu2#|5(p?hVM%5#TIARB3%OI8`idIhG=1KtbjPA8Y1@|2rgVz1;H}FpHf&7$cxoD_rf3^)+~&GlKFa_c3JVJ-~H6*$nQ>sy6S0sEFXLmSqu6rs`F(J96A6&6!aa3a@Tdqzn zBhlIwTmKo%cLpqqWiXnlzyBQ|NGbnJ2OveG`7n}oXEi_&Y3)LFZut)>mjj`qtGFjP zdQT~m)Sgj5;5c6{M(SkcHF#V2pwC4+f=h7ce>&VDaIEd70j=RA?{-Q)Dn12`V`G2( zcqCiJMiTo)b-Uym*U}RD(+Go=miY)W15? zvYfmHE!^6}N|`_dFvD!+IG+A%(nt>(Cb!OACT^Ky6bO!u^+aAq&W%!zdtFM7mFm!= zp|DNYrgCcS^uB0{7=s;(q;BpNF;L5_Wcx1A$HCKB)t+!NE1Ul9W+f3H&W=TfWAGZQ zFf!HkjH*hC0pDX%qmmRCy&eJ`l*HRXFuP7|<#`sYdNQGESm7awERSX|_$$`}Y!JR6 z)Iy|o$f-8az!3I2s5en*(%a4+k*YHj7ugT}ZlBCB{m@WUBk;D&jXl<>qIf}83-V14 zCHf($-KOcSOHa~fbryzhA{!ccb z7IC_lGGf4q;`lnQo;{f@FAIL)vIJR9jSHfXIp$(JD|X?K=g5o_FH3;yL543(lHvMV z1c{X}97$oT=fzN^H!5$1F_>nVJf^$OEw;R+6ZkY}gANaos|kbJ1u8z3LXamb0=yS} z3{yWCj{PHG1(ewbMhiUXptCe^THgC)Lt!%LJ*29m4BzF74Na_hF0{AsMl#(;$U(j- z!hfsc`KMIq9iC>GZuCguilnSeuV@@zlcA0 zkafc+^uWFz#}NceD3(*%l8zYV?<|uGtE3YD=#YV>Wky?}hmVh>y7$>0-_dc^j5YyE z`*7B)@<{O?7$y16%hMHcd4)`iNU%r_Y-Tl15u&g8=fr@&=`?J0=>wdg+5qfveeN1( z(#czMEtaBx@a7*Sd^c&!Y+F^k96E6D#q7K1>cSh5ly*3@(SaJA68z)}P*9S-#oqMZ zd3e(2m%j4<;MX?y?RFOPZsDRlwY7a@jF#=}Hbk6kYh>MG)gMLc0yj4k+L@;$!&(s8 zy2xU7V1*o@X#Gb#dGF<1C}cyAQhlwbHJv8#-oUBPAphXlA>(QzC@uEEZO}Y4XZ%NQ zD>MK%cg76*+EY0e^KrE*`q|r{(V8lfM+Jiu!wC|kDgP045pt9R^rVVg>C}5O(&^I$ zNfdpyqLm@B!9eNA|ARIj|BE)7TP*=UgSqZ`58#@H&4q8l4LIDXhl!bV>kjO#ZNIB6C@zA>~XK< zLm^+~pR$_H-Tz8i@(-Ul=qm9DgaBQ7O5(E4A)rYCqjL9o#3^@{W&gO_)v*0PLX`62 z^PbJ0AM(R^|4Z$0fA?PTgH*p_Sj+LWxmFBARuC14LZM_Lyb;;AkU;zTN&V1ec94@n z)<8PRFPKBXVmdeAv~s`HmS?U1%bCeko)fSZ*FiH(im30t)@9Xule#r)pz!zi7xpwu zZ?aqKOmtZA$OCtd(F2b{sb=6P-`b&!s^vty30vXOa1@V{K#@m-bBz>Y!(&~7!D*z0 zH(!xmD6xeEPB!|S4|crmL3Rnx%8_#e0q@vQ4KwopfDo*q7mHn7Y!6`r{WLFc;2Kz_ zTM9p&_X3l!$uWZ25W0iM0wp!QIYa!B-rIbJ7bh%nlU1d=g?1-s(9Tq=*JJeTMOBp= zE+76td&Lx=s0~M)Z7+oZo%C;LGJOrGX@D)zA@6t@`}pzaU`AJ+*T*w9&|xB=<#`5V z?8g!JHeVqD%ba|_FmUc+Oe1Q!hY7*pHh)isMyO)qx?IT!zZMQf#n6a9#TKDHIy_1x zZV#U%N3i5SJN3Z<1&0a1>~Hb-os&_>5y$c&jA0u zikbi^_XM81Wrhc~Q_lbR)PCuIUwXgQ=KlbvmLVNQzP%<1C+e~0_8}+J&+uA*ac(!l zyp2=qEabH6J&hQSLW{nAEMY7b5{ej12ZojD-Nk~>Tb>Wm-f5+UJY{R|P!nmL_BOZ* z@Ovqm`Yyf5k{WKly{a03Mf~fWeAAdW*8Q;d+pC8}+x9;Mlx=)rs@KnRY@N5^xqF9i z{5u_J+9=RZ(fs`21`7aEt(AoZrRspl2e{xW(M@0>D;)XvVjHU5*W7sp0>n zu_zZ(4}YnCV(4D2ZII8vq$8{JkZ{G0%T=?a*VA@~u1 zjP!DfMj^i^hREl6L_f^8lq*sq3}BRB_4ws2uuHaO+3g*+E7%Te3H~{jgUISNh}$f5 zC?9z2)-JgDGWKtZ8Y9JZ)J<2mB1zEv1Icu#i~gWj++9VAZne1-)r3oM5&^1<1gQJ~ zhRH&80m$b?+DWd85l%%_@* zJHHgvyOIYP3Kc5&==e0M?&fzT^rsQ~mv#16SZ__Ez{7}&-WF@&E8M~tIs#nC&XWWlctF z^?igDlv$V~;tDIG7Be#AaELTzCuMg`MUw_`E;gLB)qvdZ`VZHuxGT3u`qAB(enr+X zb+Z-C7js_o8$l)J(X3$r#>!iK>sze&O-_$4!<~)H35x5Abb$=M50vs*vG}WeLTMUO z9jd0Cwnu|O^f6)}&QvyBng!Wx&jp`pxUCt6u}^SaGTAy#j4u^EanTz-$d-!jCY6uj ze!!#30Q6YMeDcm4Ypr0cfp;ms;?0M<`BFf3EuDkE`WtdnP=QZdfWWGQibOG^$4#8- zJ5RL?wOTN+D&c48tUzEN?m3JhKdKOUeVxCCC^(g;*`4*2UvAO#(-(0u<<%MwnGs?_ zm6p))22&=SAJ4!498_)V$UWhK~;8AloP>1g?!fh(_saaxBXLhh?{8Yxo zW&2tskLbQLPh&V(GaF`XpC@a@>wPs+kpP2E{3|Y+i7HlX)ASJ^Dm04*1rF5^;8bAy zb3yv}n5kIgg+zK4lBf1zv{<4ZatT}BOVhrWS3m3t0CX8$#E1-K@0TTb~@0E{tFnrB=;R3 zcZfk-4l-NG!Y3M~eQ%-9SWM2gopmQ~Ng@nVH5OaJ;y3|*$B3eMHkatq1CiGLWUiY#`cUE{yzVpl zc1p|2?NzaiLZu>qlr$=#bR>hd!r8zL$z`mq_J~(^BuwXoM#QVN9+#89iAbyY$#ZX_ z`7Bmc%TxDW$l6PvL5M3)G1(wW_%L0;#QmQ$VO+`9NhU@f{Une7>pJYm&-J@(@z7?o zfD39$bL&p~y~k$692p~UBTl|D9NSD!me7m^yfEEQaC5uMNAi2c7rE}dRv-*kb6Ky# zvFUE-_j3@KG&cjrlIy{k1@*EYE*kI7N_=>Ja&R{lOF# zXs;St_0P%|fOD#2A7qSVrfI~QsBwuPXrIKIqMlbZuTT=Y_cj&jd}fY# zDdk|TneG$xZC^fckKdJ*F;WexYS+#@7v=GC#feSC5T5y=AWhf61tAr5$ba@BUa)0) z884l~Q=e3(POe*hstSEo#Ro9NHJ^Gh@H|KyDk{nw`}tOgn5uj#OgIZ_67u;gbCe00 zvbaVm=*)|xz{zs-Oux<(=r|4bkZh%Euwz@7%I--^#8|W*1w|X~Rcd1KeX(; znzoXxETJVZ%FRNxbmt*cs+fgcB>KsUei*?4f4XbQ6$fva*p6Q>&xmRb?|ZuNs&R}+ zDkuazlMupse*<%k-%b>Be5Z!}4dEx!qxEx(de5 z`~OJBQ&G=ST&Q~8oj}6mkBt^ycC_H(+@zwcv3lBi@%K2@F{qEOjATwDmC+K(Jmj5!}&@e%N@hlKj_x8Hkghcq@$#-MP zzSU`!mKfHIPjs9IvBn=;!Mj!AX`u#U25C3uz|ilsr*)F^a0}^wSNrkP zT>vIwqiYTNI7e(uYs-F|1p)KFCUb4jsq4|q?Zkx3OFH0RRcMa&?gO5j$iweiAeDS~ zwA>384%h=yY=FdP%N!0Y+Tn2E4TgZ-y*n(EcP4<`bmz6#$Hy!ByuAGU#158_8TK`T zBMHK9>r|#v=RNaXgmU7v<1Z<*0(;{>`Wz@&--AdnabgIMjFTjm2pwih6-sn`3_ zapMWdr@p2Dc<~c2fqZF;y1;7$^R&gu=Wa3ociI!hm+k9uKBrvoKkI>%&_)E5Yh)#l z)NGKxZKfWk7Pa<~%M+ynsT89(?@Ha=6P2K7EW3@QAjMzIIxZY*p}v>3>18~I+5hz% z=I364+LZMYWkbBbHe>yM25Tm_(sY~+cyf8>c_OYf`QtT)?O#SIFMaNLWfRG6&i2LC ze{TZ`NkWrur}Gj}!sJAlN&NG*0gz-ogIxOmYTtP9Z>IlDfx-=mTkj?Y+gpc!oomrv z2PuyrwG<%Fz(O=AJOFw` zqKj}d8`5oe9o}*O1LR!K{DpxS5D+-cYxFh(mKp*>(DEbzt^=g>0bv~A$vQ?J`#`Ri zY@v9|u*q)!Z~KFrxd^^YQrn0GeADF%LE@$decdN0u0o}x)d~%dGYfDQd&^7uE%9VGW8Ous%6Uhf_ly0c1GhbVD2`m=oUgG6pSKyT*^FG- zTn?WRw{QS3U2^&#C)5SV@FDSs1Jx~d{uq~88>HLoRI_y7y#U~yeQ{tnq(n5G#5R^23x9m@d3Yn=&GoPeWZTJK$dwICA z6E!E&KmPgz_Gtj7pp(Et2w-K4bZM6MrW zkR3}-t7qdvB`it#ieKkAUKo@F1?s@qbS+dHZi9_7?Vt}w83uPn#ZYR@N)4W@&h6ea z)^y@=^GGf$BeDi?_QhMYau=s&X6fnJJb{OkB0ri5==D0Ci%#eL{HsEgJiagbGLsKT z{(y_2*oOmn)*^up6TP#mZh)STF}_94GQI``S1upBx4Mstv;dZhVJ>;N8_4fQGOE?O zN3aZv*=(l9P$rZQM!659cxzVL83oo!5p6M(XE+AY;9!aX`|Ds~Id1BJ2M6w8l)wx6o`I7&sjZWXy|hR(pxm z#&H0*2#Cp4$`>(fSGU|Og8u{ zr7=NvsPGvJK6(8Cb-w;u+HrWPy=0>pP~i5^mn|8v6tap<&rV>_!H|Veq7X9k2}oV_<_d3E@T$I&zqM&9!~upzRfefN z0X;Ij9YNDysbp)`r!A$m?&|~?Mi&_G;-bk6W}-hGf3^qHgX)n(T?kP+z?VX#x!Oga z@Yu8Zo=6+a@-6C7xi$z($}x^gLNGKW59{mxwu-)_i1yqUrHunws3%IdO~3-6>Vc!g zW5J1e@!z?nemQpmX>OtMaNV-n$w|YuK%pRT`-}hJVgGBt>6hFu>`{iE7W~U0I!7|r zSya9D_&chi1xyf^;brO%IC>b0qfgA4+$C$)zV}a8tYKPfzUP5G2iSqX9|8Y_pac1J zqMr@)WS+po$TE50Rh_YC&mX)tVw80==i}KVT~1WZcI_5%qCmxPuckK!0XU5?3kpxB z9~OOZ?lW4n!9T(6kBgjs>so$`WoOCC6gu;rl!=Dq?wwQE1@{Zajk;>14Rm6c^p(am zO6!ZmPTmd$-4U7as2pqOTzkzrxY)hA--Ls*$c` z&t623uP{mG6wH#%b{@%j(v)9*;u?{9>qnEO#m!Y z1jV%fn?h?>-MV2nJo{}#$A1s-YRvAptJaPV+oMo=q$`CTUmOnjW)EZkqT z7#TslHeg|@rQ|llP>!gRw=HO_cZrnz?lzHbVOhM%*uBykKFACUD8mQW(J_pV5zx)`;Ckgu^5K5AbDjM?1(vJPtIEB^@@H~0sT1Bw5lr;XP8Bj z2&kMwM-C9o7|1SfusA$8RbHN7#(F^0uql?b%8f@rlyhE=Qd}!=gZ)CY{Dho&-BiHf zvv9V_*mjeu;?~l$1k#!({;3*L1eEm5WVKH>yRG9_N2`hv|9Pr!P4ZHR(trZpMRD>L z7G5KJupN~NgVRkburfYGx3d9yi2|DO7vYa_Xj0P!1owhG8Rz6g0|!Y?!y7@uN|M0_ zbPm;~LZe<`}spx9lqIK@^Kca>=| zzVlqfScKvE+}uz4+UNMwGr_m#SX|xb+{r6dh_FXS<;P?K4YGb{7_FYE-D3BGH&dHq z!1?ZFbN04_{dVrjN?_k+_rgeT3%;4WG6Pw-|0PPf$4hk^_HD%@$qY=4^sgMun(Ptm zcSkye#CvNTid<>>7P`G`9Nd`R$%q=_OGu~_eI0c?a*%?|Resr?o6QsMH2WlRirVWG zMnw1e$wlbyR2eODr>Z{zZw0G?;F4uy36u@NyY%o&PAK=^GYX4D5%r~JTBEfncAwu= zH0UmO?V%d~7CH7XKPZY1*&iC9u)LLIMvGW4RRx$~1 z5IX;Xvh#M)0nv=02~m#F0t;lx1pP+fmW-2O-+zuSBC@!Nes zDnTC7eF@!EHtE!Dx1vV5_z(hN?7Wh zz(eap?7_UjnCsV=rIMc|vFF8QLc6M_Us8fON53nC@J`qR*p zR%F+GvQ@D<2nnZ3lMR1np*Ea;EAp0War(p37-dHXs#TTxoYVlSvyv2pE+i5QJ>6`7 zSuBGO-$;}{by32>!uU-c)fN7*8wTu!Q{>R8wp6z1-6oDX z$lBelR~xg|p^6!jIB(B5nvuFWe*L+dry^xtD^U) z$B@bBB&G7A^V(n1r4n;uCNPVj8y62tYPI5yLS`qo=A z%hZ{$m@CKG7OEBxQuWEsDe~rV)`gwf4mC1j49GXDsvaRcvi)4E`pzi1DXKFQ?a2=%?ap63Rgk|DsW#8zGJ8=_g_^a} z&k#&CIdY?H%0Bcu60gv zrtg?up1}-Lp!tav9u(RnZg}+gL~-k;!Z9yD@4mZfmlOLym4UAo?QDXq21(3g@M2KB z`KZkMp@^Bw?`nbBtOZeK9kAqT?);(l)+QW-JW?1&C?(;uY_Wsft{6f;G44&n=cnrn zLgp`vnC9L>@936_hp28uEM92}MG_(-<9(u2f;$B3MZIszx;4j+_yTD?N3<*tV`GE0 z2}{R~_LU>^W_H2lg(lq~nvE=T90+3)_4+R7F@=H8qCh*+PRW6f&(czyDMnaolrzeM z<*aZWLLDYog8GGb{o`fC0i>C{<*6gAXi8Qq0|o?@Fj>K*P|oxS;qE{$(*z?PIOSv-iP;9 zS{<5)0gV;E81wlG=PFHmN_>rMozhhb)n|^P#dP4s-YM-)@R?#T%FM_YNd?&se8^`V z(X97av2;e^#$>Q%2n8`{c({|+6T?&|%=?3||A1x_i_kyZ+>$_#+}7YC)&B}tM-4Sb zvQiL;aD!(sV`5tYlXvRAN70T&(S{YH#kpH*-YQO93s{LeLVI4$gou7YGhRw<$BgS;S*+I5P4~fBsHjaZ?U(2IH zwU7?A1jDV^lF&u!oA;>Jutx^mtvPCo!xpQC*{&PYaxso(>?;fcCDhuS=(Pk9Yd=33$O2^`3R~GQ+XWphy{}8N!zMPx$s{c?&|0Buj<@20vN6s>_ABrQ8E* zOTdXX0*UQ06#LnOr*CX$gXEcxg_F3}g`>m!CQOs;a0Novv5#iOW9mmJ_C;1`@UuEh z@u!whi8ShXL*H2^`W#kDw$hSy5q*PvF$*`PSv8uGO?#(uMMKuJ=KRm%QL8OiT!ZV~-!sO+K2I|cWM z(2ONY&{0t9OAfYF*I73?E!0{8wr1soC{o$qBD0wx9+*?N=t0eJXu^GJX*t^LvNOh0 zV&?>0a#>@HaW$)`_e;vqX(qdBRY52Tin7E_Iu$F(*G%qEW64^uOEcZ>;LBC}hr*Bo zCFpjSqqCxO1fO*UuQ* zLfFBWztW7E+5EVel5T=##dn^mL%@u;n69Kt+mG0o+xuiGE$5%u>@b}JZ7ToH%%T>m zJ(XWaVDy0Nc*BOPD;`a9msn?0xO`e}R#5gD80Ap+I&$75AB?#NQnVfXN>a&J@%@5* zL^Cp^VYMWMq+I{GgM9;GjA!+OeVQDBc8?9ddoK&YriN|KQ^C|lDBYwa^A2c%*Mh3L zf$5tArTUC#dE%GmWy4GzN1bDqzG&YnwT}vZ6>E(iX-3wE&S{!nXbDg9u2$U!Qpv74Y$2{O;b9el* zo*H$)nql0JApRj@8*h#zD1uGf3Gu#Zac`^x0BDvn6KmK<9ZleZ7cUO(+z%%~TJ_D7 zC6Ori_Z*d~$h^P5Pq{!Yu}Fp8!w6({v_-e5*&0cIeNNC{7aZuyB0wr7ewy@A#M2*x zaFP^pGnn<-L{-%^5*n2g<;x)#9%z1%$Hr{SF-r(mCukL;c1_`0)Ep5-6Uw)j{mDjQ zNwKYeAcr~36{Qh}_|V=TxBLOW?2D#4lHA% z0&ElwLIofFE>o@U&I{M}f%L-_lT4>A!J%@==o|$x_^KkOx4UF&w8jHYM3ZAi%P4DK znsFbq)I%A>U@-S4;A`Dbo?^4-D=I5yf02r8YCX6O5FUWBm$o-CPCBi9#dC8aD;>y} zV$xC&*B$gc&rlB0HZm*y?0wO1){rf0W|E>V%asuM0ir_2qqj-8aWgwP9a;v zC9cg-B|OP34jg?-j47YsS=J8?4P4b6cRNtmjHQCqJXiVg2_0;!W^YeQE54TVHyfoA zq;;#r8OQI6nI{K_74pKU#^_>BFUKe1&{}*t{P>;@wPp1h&WIG{ju4Ghe)_o+%3Vgs zm~9f>aa&cBc@l!t$yXF9MM|rGyo_zGEuVr%sEqSoU5ZYxWhuE={S+&taR>{fZb6r} z&n82bJ9S3AvH97&cxw0U+Z5N(CV?6fAGP*5)^)Yf1W^TIO1&}Y?i0A&r3tw4Rf$q6 z=l!#>7;Lq9KONc0&m+3IswE&hx@1VJ!+SNdD z3JXT~HeS*l5MBOkG-4eW6aKWqnmB*?6pJ0H$ER&EiLY8OZb87*FrpdLlyF-7p}tW$ zf@|7f?`;TUl6XBb(Rqbi9ltvsP1#@`DY^&Qq4*lI<7Od`7alq?f3^B(O$k`uniFTy z+cvo}7%8EEo{J!1oCQjij*~W5_ar*ZT=6tpQgIYhV-dBe%560J+)a9&ciIgzsJ5M- zZ#;PHIaI7o#OHjrKFQ_cG{8b2hjPTIZ8Ce=2N#bcoB~ECe32v1N?X_&_u46UtfuE3QXNuzg@8B*!NN~^otM2 zmBC^%?p$LMs)VKyMrT^Zku~XQOS-uW3Eo=uj!r+8utc*q3Di?R-cXGj@rENfKv<7{ z+;^O$Y+9zR+jJ0=->k&1_OudkjE%cfd#jNms~jV08Uz^T&2#6UUN_BZbF526bk0$7 zv*UCZcilzhl>P7>@CvA43RMcNhFfpp0Vy!dYxWD9jXE!lWzQgT&CPf{bLAlH8 zkP~OT^l~NhepA?jf^#Fy)Rxl61LG7GA%NN)CMAK3++y@$!#VX>3CeEqtL7m#2U5!o zlO4@z0m1AOESuZUF|8~qgE9m4<9EE^U>ubENZr6La|v*n=ca_MUE5?mZ*lm%4+>bL ziYl{Ifi5nb+s6uCjS8Y#Y9|TFF!_p&QB-cT;jUJ7LlAGSd7~u=?tH$SRHtH)Htxcd zp71OW$n5Hb3yNtDAr!gssp9eHSihi|1)D8G=Ma=@=3baiPCeT5WyTkbrs)s4Jr;gs zFQKEm(TDGZf==z(Lx&eo8M@*Y{JNREL8sJnI}W z97U#EP<-4|yV@0MfZg6GO^oag&r_hV>gMc(@Lc5PV{lKON;vGPQK6G5GT(Hu_x+Hk z(F(eioIhQGK6w!B(|l2tOyyKDNxQ-RIlS#L0}mEv@JfpjIvch4*bfZJ$d0P~RHa?1 zv{n!*0qQOpU#*wVCz~{SmCju=d?H8|q8uxq$7tg)5{DnPIh?NOV}E)HDVJOtT19m! z6xH&81p@}gj-8a$-UWZ!%OLM>+6Jo#mA&0x3r#XkI2J z$&eb5npB8nFO1`tkq&ej(%VHrj50nW+{rG<#H6uX_u*+uJy5o}Nv}fV4eOt2aeMf5B2EL#W|X4o*3Jbw zkMR9T{3~PyN-u?L!eRgdzw5x{j&y^?G zmd*B$*IO7&@o1q%3WL^3*9fJz*sHJB5$=*2aVnV->)DYr!tcAST8F?G#%3Gvyh#9xv|HWN0(*xHsTq#`Y z%id~H{fs-2Mvg6vGNo|q^@%TMCWuN)dlAYY2Wq%U4l|{Nr%z_C9%uDt7;Or_xi^Ur zrlo|m>;_m-l&&w$#1ColfyY(KZ712da}4_~55>1cQGc2po8PK+m~&XF(Twn$HLMGo%Z*m^w7YBLqIwe)>RoE+rd z`K{wJYcY;!1M)JO4eB_PQ9A6pxzLdGZ<1cS#p-!(m^H}Tspegc_XwcskV!ar?j}ce zWmWv_L7%g;VaML+NaYbh-Z4>MEh64-J17;Fp`K{MnK%pRY^V@ur0q%rI)Z&6#84r! z_jVK#0|kbgMwy|XVz7|f>pxvad@!=nKNtLfMkZX8FsK@5@Hqf=Ev2=RRu(@W(`dd3 zR$%+t&VZ7iI(fQW;SS;~gnP86dFU$5wgyVIrNJXqNG4sglM2W<=Dg^IDqvXf$^ZI2 zA+FoV&j<#T$y(*GhDLgD9cub?nna*v>g7_zrxs(%Q6LtBGHmoX+dCECmo+pz zr5U(&7lDe)x_EdUX4#5hXr$Xb1ve9ULzUajKN7#04R^gZjRxSkOR%-)!npr%yE}*G z-5Hm9vA?PG{YYNi_w+K}b9oV^H@gl3zT~BqrD`QiLsS)EU~z!|5kQg3J7U9D%?Rf@ zAkY!;!UMK?IlEf0J6c-UngM2lnYAS+AKM2fYp5d~{PJj3Wm!}tA|zlhRCzfmbr1*^ z7Wn%Z0UG%EHp%rK_=WgEPR|VlLK}L0L8URH5&tKg?45hw9q3?i>T~$e-FjSLXeRg!D27j|?yDmzX_2$ExhuZM!8* zSZZW&#Im7$%K0bbQ#RE_J{<+Bxy}MM%`fdWC*>B>POjmw+>OWQw~5Dm8=_O&v)d2D zZVb-?SiR%~@E%isoAUZ}9IOJ`2wLd-G@MLhgT^ zO)gf#I_RH0lkmd-b0$_K2-NGr7!vw8V3>cOh`}BH-|w$>g!0c37;{Dc^N|j=~#~v7`QtX#~`pn2b4_m=Aa1uRH#6;XPQUXVP+@ z{35`~(~coHDqn&ZK}SEPz*rlOhcBVOPlq#%y9{iJz*|=03E<)pS;Nb%&QbP0~;4t{GnLjrOvmgG?4|Fs`eQ;3Gf$>4{4z9K|-E7yH;< zv~3)v%T(Ux$(|=~%}uPPQRg{}#xd2Esr301F0q6_hW_eU(P*anC1c&g7ke3M7Yntf z?dwx)M`7&3I}55bV7KJqXuj2GWWRUOUV?_M5Zu}(i_fK{g@P*VDN|OUGM6GO^?(>& z>c7bEJX>u|2*Uk+6drm%=Ldrd*}E(+HhU;P1BfdY};mIHfd}&wrw|7W81dv#vAOD3b^au(ZL zoyC&AZ(dZ}%@Y8n4H^fVFQ9*Q#4U2Jg=c-7zu4S>ECG6W7;Gnv3x+dTK_|(}d(evB z%CN^CD9KEvB=&Zp%9#REZ`;R{AfkQ`1{#Rfvw3}K)HVoM2ox;!Kc(m-QXMJ3gU2Ub z$UzxACzdd}uw4r>sGbiI(yd zvEWXRGJ4dI=}dC}7{P{Oi{OuE+9j1RPoe)?JA=I=wrlXuq`CHCp(JPMT4*14>h8Q9 zfh_VkJsEmpwQ27r2ml+K6qTqO>TZnNLt0C@h-MR7gVw@5ZZx-M5Uk(twULdRrDI1{ zp@I(a2nT)~VL*%Ke3d;l(KCXX^AnM!5ZTfeB=x%NI!reOu^d-Zk0UmKufTW@Rf~HZ z0I6{>%_$^x^(F_-cOInPsyO@w>r;B?RZeAtxiavj&^8%8*OqtEcyZ@9)@bNCo$+*V z;$?6m6up5UYa4(#k701%%fSdDz~ghzMO@xEg3uDn`SMyfKH_7Ke$vb-LD+Za%gJc- zk75LtF`2}N-a7A)y*qDh(0<=<1Gtr+;GSwzdFZZ$jgl4{;PfXK*Y=UL%fTA94}W$R z8DOdz@}`IzanW;~@q_^m+7^HVqEPjVQ)%h&(Ns0CFyRYY1nBT0^gOm+q@6_*J;+E*_t?^H9q%}-GFe6`wEf&WpRY*R;+Hk!+oDf4^S z2ymm-O6nTcCxB}`^o>OHJ+9oEGvyE)qp!;+JJBveU!SqsCn5!nO2V;)n-9F)Q@e=N zW37F|Jg*0Pdzfi_jLsliqG9aTOkIptw23T6%{V0jO2o0f8;nT9e7B&rtexntTX7X$ zgw-HeOWf7QhzREA&0gXWr7b(j{j3Li62#6dq&WzNeeJU$9*)VZkuDebB}G;@!y9mb zmIWuOW^>40n;y(EgQp$wNo1&3UJXXqn-ujgkZ}$iZA`v1erF!_c5(KK@<}@}(uly~ z&t!{4_f$X!Lhc@fhp%gv5U^lZkJPacGp?dvbV9Zhu{@QqJqQ{N!%_ zLE4{hiOJ)i&^1@nu1#>X)5e}9Fgm9fwWu8;an3+H`Dx>NvlhZ}RN~E}W7^<_Q?yQE zBmjJSieG{c6oCVc4pw&&^LwtRtHK#;h%k~PKn}oIaZ8)pw%fPE(_0#Dxo+F+L|g0x zsAa|`_e(ZIx$6*@z%}M?TzjR%tY0&c`h<$fS^SNkAo=0pjV?B|5cy1X4giB_NJWI$ z17wesDdIVx^T$MpfDKF-@O05T8xt9h{@o~y-s(-pq5^J`bJ0M0p_~&I2pQ_{uV*rA zUjmy&6-lp)ArG_>e94rKctkz-RWUmU`A*Nc00KK$y#@Y3+Zt&2NhfPfv(bsX zVCn6!ox6N*h$!qlKeCK8g$jFC?rNC1eL~N|4~uGRt%&U#U2jixE5_g z&0x~i4MzW_wQeYN-nZS63<_rJGz(mtv%!)qWy{9I)Z>SqF( zXJPMM7QI{faPWwqI6-$L<+*zYjXNDi0|j>YVJ}wT6g(rFTO+E=Cr+!^C^DSrRP54< z%3f)uH@4C$=acAA{n2(vqeKFim-nylfP;`9O0pVRnQ>ww$6%~h4(y$f`Q{IfPB}6_ zyLL5}?Wu9rzmGsq;sgxtC@64KVyLbxX-Ga9K7S3Bm(6tAljgO_0Pc1T?HRl@Qlr zG|Wk40IfEH)-U8n5@Gq+0ZW{~<5<@}Z64L0_B+kpgT;Yk3Vxu=S6tc5l|;Q;T&4?% z0l#Tfyys0w;=#R@5~JXCcb0?Hc?%_LpW{3w9*08WUqJw^OX8$UvbKkMZ#p*E`7|FZ-*Ob6^fFN+XoJtiW*ufj5m(#t1Os&5ANeNost*Tf8J2B zR)reV7#?T3Z~Xkmj-4!>)5>Rbqy|gOZmM$-UAUCuZNF7}y%1B7rMN|ZZ=MDBzy;i0 zM+V00ngEEX=nSGIemLKK6#xLm1dDWy01C7Z2f{k~46vxhpzNf5OC%&-cw36coyi_$(hxMx$?0*YE4^*8Z>X*T z;{+J0VIu=fDE)*pIs!`pz(KowFN>j_&JzS8z90ZbEG}`U=gY-g$M7{|><+>Rt8%hP zaF9&>8cR^sR5PbW9H|6B>%&O5>gzxVz$di+RY;;xZ}#=f?Y+|NK7DYYX|UT`!88qp zzv}BVRIgWE+1ArFpobbVJzM+Z^bL*?EIsF`@Z4t^;bOeX2-Y;V+OajXyiP0UXy$;bv^yz>A(y4qdx0MH3{qJok?nGL~X9sV(4vu2f&~r4?wKfBLeD>w9CB`p=jy_3P z(i%)%Xvhi^6x3j7*!#ChvBRI!fLJ5AKFi?Jw*{+U;#eMjo=32;+0CQg;mmM#mrl%X zb}w-MDO6%}Iq4$dO%EsmIZ8E;z zmllEg@Y-egQ_wIMWCH+@uBGpf9}*6MgtZ83_(w`8U=v$Zo|p}RyN#%;avsXcy2j|p zeVnPUR#^ExZ!J%fGbK2}|BSE(B(je%cj%8DPoU|qPFBE8JRR+4a<1GTL<@5Q8%d6d zQB!>e_lxD#iYW$c$ZJ({dO3(; zPA2lnhzJ0z$pB^RjFt&nEJEwXHmQWGlP7ohOlM~VzIhwtcz1mO{EwXa3&Qm;=up4f z#LPq0C%lZB)(^j)oRmxWEhLQz1gS24_J(f&_12@u*K+oaSy?>u@8JjJ>sPwp%HhP`w4&iz@c|%ra`*VudB0g9jW5TnWD8FuAB>(gQbJj-~#L ztmlgokRTs%&&a`%!~LG0(R9o>AkuPvgJH>|{EZsuT)5#ofSXDpu%!D-QW%QLt~WdP zc4i*MTiw}toF|zwMn^hu4#B+r+(IEtoIef!k}yKHGXdb7(so)G@icj82T5w7kTE(! z!JG$8qc9tNjwixCh8of6zP@<5m~|Ol><6^YpE>sJ)g*;O05~nwLzXI z2D6HRa<>4NMVg22jhMCxDOL zIdUXTqE7^x^mvf`EYKls6P)k3VViNB5Xccc@1o0)ib}eMjMnS&#kWQ_U9#Efb1#@z zb(L}-2Zeu84Nmt`5pB5m$Qge)#>)gI$6?Fm&SCi0_VcngVuE6_u{{TU<)fp12dE#s zBn(JkLxp14hVn0{;4JL{vV~kDIszf@F#t!8^8lSyV2;iBDp{nZNXx4Yb_&a|6K%;f z)ssd5h8v(diQLgLEWE}0<*DpiLO}WHGK5n%RU~ejT=qx^Aw%1ox7qseY=i^=G?FL~ zk#kyY7*{y03*8g`inxeI_oK^Sji0l+e<97g&(zFZ7u6je(u)X`Gz@sa|1^IQF+F|r zyLhoT$2~a3JZ)vSZbBxKt$u`#?o-Di@6%71^KUZ$lZ=*s;aYyfRRsz_$2bie$VQm6 zbe2X&FXOK0@mr&n-VfO3lyuTiYqRE#*a1c}@%h<*n;}KZ3e*pCl5xl=|ilP>#R(carLkTj`{U{LB_AEuDh6xvY7E-I4kL> zzWG!`l4D!0x_JWZSKOUxl9YigpI{qn zxtBe8aU~MY?dqHWN%rl=Pj=7-H@Mu_0~uiP!>>5!jk+!+ucvhrj_?o=&lfjiD^T&i zSDP~v zwpCo&faTF}nPnnrV|1V(73|Tmfy1NrueZCG55RJE_oVPE|4l(nC}kl;(cXkfG|Pp^ zM~xXNMEiO5v~v>`U>~m4M86@zP~|M4g7+gaqosdA~}85Vp8G3N;aIl!@Li8Gs(U_ehk zZiG=>Vmk;Kq3gT54gsT8#1&(W`GpPwX8u_7Vf8RRw2PoY%Q#Kt){Ds;gj<|H*#=VE z?j~1*CTKM++3+JH*HghKY+Opml{G?zHsNm| z`ihZOokvB56p7ikx5^S!S}C>RXVD;U`+E+{C#vt1VREM>NkjOaJ9iypztO_yzx3!3 zY4>%1NE(Uf?*1J?%k8v|ZOwW6R=Z2o>wSK7PEZWzOFZLAOBHvB#R*>Tlt{_7B*V#x^uZWWpHbY1KN6Vvd@cD3w+RI(U1ij92KVRs*GqIWOT`1r^V}=6b+UX07A_9K{8{AuS#&7lU01ftd7>?J_VS*{b%gJ>#}sUYGb0?c zG-E?YhvzmRyk~rQVeA9qCDtO?%V$wsAFa7HP_eb2wiY($cy``W*q!6VNFvcj4!;!a z&g_^0Ddo2i?oqy@-P55Qkk{(4b5&(Q#&MkPYaB#5sxR)n{N<2>)6=Jp>?=N^U8;Z~ zneo_#z76A!sa+7E$U-54jHM>Ju{a3-ro&0~XT-gHG(xMu>8X8q{{`N>haL|x-0nuK z)wj)yp#+2}A#>jd$6VAi9A{S}U*&Y^U|OGt@PLcQzB{7Xr=J5JNbm*YJ}*z*9*uMo zAR*nmMi&&|X5(4{Vm}@h_Id7`GG0%N@H`(j*WU^{`UX;H0;4d0Q+0a;tfWh*Sws}N2~~D1&Trj7vg#R%i%dw zW%)-&%q=(LU(%L?mUJ^UTTh}W7l;TU_v;TVilO5la#A9$z((u+HdQh?7>ns9p^pt9fCz=ykO#%`|yMpt~ylr`u5F$HY)l)Y>% z_lzS!o!nF650bL#?R=RyMm6*f>MhBK+z0pJLH^(nL3nLH&e! z-fpjv`YpQ^2e||n!`+A7q4mOyWO(ZE3^DsXhTqTOwPu_(XZ+6QaPOp1y)s?+$rs_- zSL~N-{*Lr-G=y$oO2(7qhh7)d)tSa0C?DiA*|>y~P-X6j7*X)Z<0czBhj*Q7hrAP^ ztBCydxWPX%;a>Onjg^yb4Jwl0>V-W(#opZ%l4^Gwv^#UaX5HWHWT~l7{hoBwll|=L z91HjjDZk<+uzWD%I}g(O_H>-_c2mInbdX~hN{}1hyBF93{F?K`7Y$a70c}YURI)K? zJo~ZIl~c;~-86L^kS%$^P)vR>VClI&{j5GcSmyhnzm-7|37B|tYjyS%&YVA{EB#OrloY~)u9$i&7;X_?< zHczb)E7#~USs7YJV}2JLHIs@o@*}|5-r+Of2ru^+S^q6$JMX$Y$>QEgwA3~t4YIUT zsRSo(ZnslxM!?j#RRC&?udJ)3J~KUIrppts=>0s2!ycubfu4*kE%dgm=+6CmSC(~4 zNlS?%7s&>|uerPvFt#E1{Wac;Dc;d$?jT0exGdqDyr*hy2!`)@k`?LQ=zu@gLomD z*g(OUbor3)Xh_AzAx+DATG!%FBUX1$TU}%JRGzadx`HKO#FdL0WCyP0^?K{|5a?xG zjx1m*p=xC?MoxnNJTo?|S^y)qV-Q-6789K&cpnhg0wI5WSyT_&cXc;3+Bl(|9&CwL z=A=#GsyLhtW~mXDs-28!Yceh&<)q38qtc&CTke9=?y}}Y1Xr64n99Fw6AHtNbIN&rt*ZJ=C%?5@A8jsM@ zP=ZxD)ZbI!(p5O3{)*R4R8_^r@;Zn5^{eO5e1Z3+)QPl_dv5=`Mb@^nuS{_J#nr)E z?aA@#Zt4aww<&^3<&%U2bnd3PNn2R$;suiGO_q{Xx|1C^Jhe)%hBmxhCVH{|`Y0&n z4WGX9RG`;=avt%-RZQ@uSC&5FMp8!5Xy%O7mX)4A2D9zcmvV|f(&>w{7#YPNFJP9P z?IjqHFL9Vu(;)BQ*^G4iG`tjp_?_JkAw&0S&YiU;gLfnko3=v!iM?~EXU<`;O$-Gb zXR2B%d-QYWPG5LA5B7bQ^}UNZj~V@N6JklZWZ~6oU9rX;KgQNmrH*fN+Q*F%-rOlL15>cl6?D6u-j;KGe7pCZKr+;dr)?Q2 zCWo+&``m9gcQe4qe(g`-(RX;G5#C^c?qq3YZA6rj+y0<28Mx)mIV>EW*IwHY^i{cMS9NUDJcH|ZrL;l{Rs za_5imPraT`mFHFk`c0f}74r{70;mB`KU8`fEH+^-DX>{b6Zo>5dv8)aWs7&I(oA(@ ztITMh+P)}CM_0P)g%|-Wb)fmNwMwPhkMRX>sU4hJBj-3}j0~ZPkUC4lCrr^r1HAFM_GY%*Zx!*PkatRa& z`46XGrXp4ZRc{Y#*DAoyO8Mk0*}VUx_l5akeo)}+Woot4;&Or35JQGqOGg^go|tju zi@l5MB*9XCgwO0Q2>X);c_Uo}xV|=%wKl@)H*-AXgyjyBS)KO8)^|tZWZ|ENySsvy z$xfp@t}Z${uE3gmatJL{#vr-ForI;|9vT9+$7Uc^B2evsg~i15O<;C`Y%xJDqvpf6 zFpHLcI$VI7zs_@@;rWz~7Tgzb=;vpDD6wAwpMDCHF*MCKagPvl&{6NM9@b~e@g$>> zf=l~@30;+;%2+O`sEqgXK73f1z@mGc9Vns z`~#!Q^EU!4UyHIeEId7QpE$}j*tD#;FjRRzKlx!6$OKWZEwLXo7M+mL5ToK*b$h5T zeuD*w(bWFH1I~wWkmJ;M)adE_x`)?rZ{}}=JP&k0Ce8{NrqOEXuK3gn6;}Ph1{BJ6 z6{IB90A%Vn>j;z;BuYRER_V&%-wD-p%pGkl>`jh~= zXAgZz1MF$Km4j13=FOeq)vq5o?KtADyLnEyTuvE`I-~RNKW&e4k7*{txXNBx!%zEK zz5fRnfU{z~X_FEziooE1cGO+k7C-&daVHqvyzO`h?J%wf|EDc4hUEOJ zzW$_C!}3ofULd*i82G^J>Wq&mE|9|xRvzabxfbn(Ryp|ad zoBz3*$OWf!-181NVf*DGoNdjx9{t}xY(FeKpLe`3nN_r1_G4ANLtosF#tZ&S7(m8* zZqf$5KzPUS3hxkgQkSl|{de7_BWsi8dv}o(Z+D_Rg&pWHrQqweDY-RpR2uMRe!!DB zG%r@mhDN@~|20G8f^Bnc*?5(7l9!0zm$j~uD3x5UzXB&aXPlxfOXsB z#axoIB*`UmIyKqyDu_>cW$$gTXs2m@Qhq(NVk|NYBn1AJFn#nP%$A<6Vv{df zyRAz4YrBzTkjsEF?J|9T)6P1EiPuLI2(tJ~+sL&s##{^upACmS$ctV9Y`?krxqyY3 zd)fPIdkm|DvSMT7`!68={n?|4Zpe6nUo(y!TZKsRW;|gKoDm^c3wWZT4^#V!EzBNJ zORxTj&w?Ku5V2L+#J4L=*L1!zY7;%)UP?TJO>}!oWK&d|PeZ`B!2b6cO+H`o16&Rw z9vOTnsm%%SZV~+rXQF~Z{JRk@kJFTdfvXJvca@3E2eY06!V;R(b@UJNn+S=?g%{iB znKVB|I!Lh@KGx`I9|pWH(Zun|e9hHviYmS%9}Q(p2WP5TV^oCM8}Ol5#%<}O9J%+_z=roM-^fG?=XNp-WxM) zQsROwQCNlYfSMX+2Nlmu7tuaRMj(lX{x6+{8S~q)%B4-X}Yq+Gou_3=(p3!^-m#slxNL z;q7R;W6_+T01GHO>H_b{)Q(1)`gL$i;QgJ|E~-a8)F!QYk*OW6Aop^?E6!H-(T0?G*LJ{ zUQF)V%eD5){?G>7uRE-f?xBX&;DOmH-GdlW>TUh|ne=-jDkDl3T}!&wa-Tvj5kVzp zoO3Q^y!jI+OoTkEUBlJu+)U^X@)P>y-ah0(5HItYrBDx>INA6{Dc3eJ>Y^u%0$i0w zfm_k<=OwsI9h+Rh&qo3|?y%KzKeeoKxovjOzJ;K!+JA^zDVZh>gW+v4pXZqq|L6$B z!&VoU?exp5qy0ErKt}*O=o?9u;hUDt@V#``eT-dC?$t0c#rL0y4_PHQ6w&yxx9-b~ z|7*@2RQ2oh%H$hrfi7AZ>7JEVeLg9vpI5TkaWZg8GOxy4gWhVvFVfos8Tor5J^0{Q zr!t^qqD(@fbcw~y^5xF>J^qkINXekC6HSZZ`!FVNCNWO@(?#s29s=4D(Q*|&u$;xr zeuS`|H9t}!lAga9^&y);qX@RoE}uI3F`wq>xyJm!s>u44MG-&NH7}d-EU?ABMMi&->@pF{mxadT4+??)%S;^ z8&xVImKLg_UXcOSoOimLg-kO`lRskU;HVH&G?c4T-ky8bG*8J<4%%C|)q6kRj^8){ z;EC*EcdI#cMt9QjynBCHM-{DDhlQ_GjifAvGHa0UGjbBAx7Ur&()+V;G&6LX9We+_ z83#oa{N!D-#D^*K@qv{!lx6fdhKgZaoErq>cCl!H^XAi)x#tgsz_lXrG`QJ5u&$fs z1Ial`0#<%H4WVw+M8rP{(NP_u(#LHt+Xur|@8Sa;YOj(eJw~6_PaxmchS9W}nGarM zZ-&p`i)}Oc!d;j&zsuj|ppa@rgb?k=)56LL0;j-i$D;K3Q=$qnGvH#dql`0~jd>3d z5N{)9Ci`=zBl>w7w<#yvkS2fII_h=Bp!C(3>dVXN9EmAxhP@>W4cjCKAz;bXZ4|S( z=8b!Kp!4#rXuXYhpGL#h?(I5r;yLQR?|6y^?> z0h`cI3hx3CMg4XlpkNK+pYV?>a$$u# ztI>NEb#A>Hlag?_{SD%Dp<}2%r_zf&)?O8jdwxAf?RXzEiXaMr_Ied`uilriu<#0A z?RbLJb`})7Q*9+Eqy7vT3S*IYcFc0oRT{B&%o3&T6(Bzg!X=IgFRrWy)IxlpSdM#Ut;- zQcXoi6Qwz}J*#vM#SE3!!4I&~fdKxI%ye@iiwf6C_)(i*Oj{*Lg20eMPIM$})0DKF z&9MJ9+-@UfjZ^`amW`)1__WXkY|aq`$w3JP^itXttNk{D_bQ_QP8y6>_|vQrRSt+* z>x`af@niNVFH^}_Q-~f*!@QN2sPGMA#nX}uEX1QhXs&W}fyKIq5E2klRXSTu^3Z?A z-EX0XEi1iB*6Lp;QSTCyk`_g{E}Y#Oi2s;&K^ujs_yTFPsPyXy zx#-MnkGe8e98I$Zh~8Q7*DOiF4$#l%o{z5`$ot>pJ$!BlCXKYc?#VjII-W%LFV{om zDJAS*N)UM7QITKBpWr_=Q`ODO|0?RC8}j8V{a#iMHKNT#GX+`zsWZ=QAdFDxs!XL2 z>oIX6T#gQ+ed(%X-`m-&Se(w2Mb@uxbL31Jo6(M;Sl_45l}>CFJguc%|FO2Z0l9NA zBCZV-`CeviiQBHl$2tTaTo1eBmUHN7auUy*f%CV|9j_cVW4py2r)jfRFMKc8&*!C{ z+oKurDf16DH_z)p4R*a^n*FSmq42Az$Bc0H6SI0rk2cTHt$$iVE@>g2Ox>tz=Sz;_ zsoCqgwZ33T>ava|F-_1a_uHfE9p_nuOdt%nOEU{R>JG- zb?%noCGoU1bszHZ9m3N(bw@tqHTPy;{aoYm2!XZz^+MEdAnh2>;Qb0o`{mT{Dm*++ zXX^q5qaS+DA3UEl^Dt;G zMdo*s|Df4h6~fvDD$~{Ja+&_BJJ|K+tld5o*o09$Dd2Wn zt-Tv)buhlzm}>nZWhrE8It_zeT;9m!2pm728J2?`jwF^eqe2qRZ{!`dq_=WQ>vg0! z$uCExvj>MCgJ34_PI)nhw!ZqbeeM9>4nPLBJdC^?5P4ZVZba$YgU=KJ5p=r8??G?# zR&fw#Y~Oz+^_Y<=!Z1aoCacwNA9nq$l!)Ggb(&76&4o~a!^%G50G((ul#)w*0+U55 z=z~9K6GbL)Q8dz8&52a-|EnaObIMlc#IANIl#a_A`k^>Ok0a;qr!m^^dvE9NS=R#y zUQ4f1WbH;z6F|Sx@V*1E!VU7G1ii;1=^5Fqi&gu=G_N?i93AEQ6I;0`VG2L|LNI;m z=+>$~qgEmHMT(hjTOku|6s#wmv?P!D^@r;nkUSVm^40p!dp3wzs?m7oZVmY?^epK{4Vjg8wpc`49#dB@UzdsBWt`0ctM`F=&_-S{wezrOfzm*IX@ z^1jCexM+KS#&V|Gq8{I2|92sBMYD?4{1rwXOOx%1Vd65xdWkYf(U=08SthIoC}S4F zfr}e_4tO0JxrUbged6kBFTa^E8jZ14xUO0{v_*qyK!IMjROhg0b?_}cMkOkFM#0@A z;O+cv!_KR6>2YpnpXV9Wo+EGf@$!}prW)*R{T=9tLCMuO-tXbP{hWBIXfNKk4{EGl zvZAgE)Yb_LQ^G<5y@s3I2#d&=VP*m|s-y-&#Blmq#6>Xux|f(L-z6<&?S9h}JQA2D zbeh^2y~Q&x4pg8ob6gX}JN^PH1zF$5kd|RAfyn&S*+;|6RD2q%de{yhsE};kerM=iNI4B(BKO zUOOr|$|rj>+MOfqj3#Yc4VeRj|a zxEV}T|EWHN?Zxt#geLK#NK_|MpTWwkuE558QDQlqW(hheM%R@x7j}T_jrKte1d7r> z3Ywf6cH7eP$FLloh-&o72>!W?qH0;L|s zL|>n$@OO=hl{ zS#9`q^nF@FwFiLU;@+gyV*>Al`1~{9hjQ#IK^gepht8LA!a80=48c#5pQO-ImmG_b zDgC0)V=(GxHK|d2Tk4k1*dU z1jv(|NUyixJ+H36PkX&`Y>qFSzqL2E)$TU@vJ@M-NV5_@Tz~APdzo`;XOZJn63ZXN z=;R_T-a=NKw{qV?%Vm0tx9>;}rwtxaa+rRC1>Z*-djUM~+`vl=7?$@6y+j(NPz z%dRJTD>WTiU6tJ+sZ@qm-=5Bs%X~kQ#<<6p$k&|pj3@2)X{-$7w_K8(k6KyNDBb=o zxCBA(TdS?T0q^spVadmKATa}6k4J5ZbU@K3V09zAs{`lVX+LD~{et%`luk3vv>p|% zw-fYPM_T7^?i}<@(Wkpq@1G;4oq~>+$oHAoN4)nxM#)s$wI4Mj3oVXjCEh2x_f3iS z>O}!&l~?Vzw2W>^J!!>E`p|`sJe>0m+3@2?&I_GX=zpu82sb6mAmx2L3UGZ#K5M1| ze>gy050izR)FW4k(=1drZOzrOkPV^Sia!OY_NEu}>C9CX(EmLesP9e=<&WeA=A0i_ zLz?_o`;z{>t1YlT5mJI{LdyQACf?6MewR!!_B;2i9(QwHy!!WVn_cq1%dq8a=PRw( zKvB;%*@o70IyY8c%1%_XG>02znn{f*U!Z-Z7+0z=W-8oO91-$_+@D1HxGX9pH6q%l zEk|?P%avjmi^hOTI_EIN*!9yDH%iB7=ACtzU6dOS3Q~!|ah#jLZvvaodW3SZ7E&~Y zti|%EgfZRm0se&ZGiteo8BK|NURF3_)Q$}_q$~{xWoY_X#EM(uB&dD-=~w#AhsXGJ za>6FeO5Yf0%e!<((0=GBg<3Y!PqP(Kdq@L|t4`#KUN*ofGf6bfs@<@|7WT_YsQr$$ z8umy5b+iRN7>H3@`aAD4Cd^(~JE}IJOWsQ6(UDMt0VW{|<_hRH$rLC}LlD@xAc&8$ z@xQ=KTd}QlZH}+b)+W!^j>HT-8}-Lf=YQo_HMcn3>`e7n>LXFf@6F?F*H@D4(Rl@s z!806847J8?BxE0&-DbE+=PK+j7VVs8{89Phx>j zG@FSTATPtFg!A{A$WLIQn7m>_fM=?3EUj|6eqG8a?;y~vIjU}<-?qhCaoh{2!jX=y zjNfAh1~P{a%EVEUMlOYsTD5K2+a1uM8XlR<)Bqe&fi~G`Lgmz=wa$QaF^4Zl(-l=@ zfKE250gB8oglnoh#4Gob~_!SPz)gN)U`UV+{06klK^; zwOMVe8vt@IZ2NPTG=hX|420^lfP2Vruc=(wn^!CW5pPtQ#jwoN^J>MOET1^T6?wx# z%_`BMxg@$r)^exrAgVe8c!Hpru(*;zomhG-XASIhe(kb0pGv~$aix>$l#No@fm6c6 zh|SUK?^UF0(w-_lBZPbgw-J(ATujEiLHy1J`I!;dNQT@W#VF@4-TOC?!3qxuKpSTQ zQVw)dmUkC<6}}bq#eN!^xa)M&lR7+qc|v_k0}nJNCLgZk-KzX41|-6OVxBWH2nHx7Lt&ae$D+T_F3K)-#=bz zGhaTcE})0mo$ELq`B*if4$atMA|JKPq-`1d@%#qgwjeTTBd4U;rt?fx$aOl4<`-i) zCG>p_GdcA}p8ct%m@zbv0>?iy0?YQWo$bdaLwMw^o!(Q%w8I*4d>sd_zukSz_#yuM zV!@F@1Dvl+BHd41Z1*mtB6w_)Wo2!aSP)T()=(md5_x=Mkd^(@U(D3s$D$JUm`yQa zI{D*kzC%n1usxXQRq5Enb@s{jQSxy^f3?cML6H_{2!DnxY=OP-n)-%v8FYpn;DB($ zr+E~L*{+-ZN97xc8R5kFBG!XhyV&qNOyY@D`kzA$MG(N3$>*%(mO=QrkUG!l%-D&x zgU80RNFN%_X@bWxwu#Y4cJh{}s&O|xZF=?epkwNmTG@ZxM~KMb5WGVvJk)H9E4{l^S5T*)t;oueWP-_|os9YgL&dTXO1I~TQQp4BpW=^& zLKk%J<2a<^K#JQAtC;V#~wul@+#Hqqi}G7N+w&DY&YE(Zatx#~*-2V5jR0>&l> zm->pE0=tW?%b(h`Ufhs{-zm0$1kmpt*Id?aaE!{t6JwQcKoT8;*N2yA;ElMMQY>SU zvlGkVbB$>>-JZwc$me` z04*hyeOU58Q!^S&Uqc(L)q||WMdn}t8m|eJH|!ufz9$C;6_($lXO!&qJ0XDTZG4Ym zpcT)@*3&HSigJ2Z76IH-av0q`CiQKt(fP-Wi*;f}Vg|Pd4t*hcTYoXqhd#gtq>1a0 zP_E_zfFxa^WoD(@Uni!47A3>!-6OHfmGw+?VW-X^{&lPcM3Q0={Ebp5n{3IBO-cHO zGNO1GqR)kX?mJks1$v}~MO`11zWo}$RySM#w^Ii9C!m|S8tHvZx6}!h=Gsjg)W3H} z1<+R$wif_DxlqeUS04BE09h07dkLykosRHyF5+N?bgK3rKsN>l2#~f}w%5|Pc@iB* zv?-nd-1^mjbe5_f*A6e|Kv|sIRWPY?D^$~H7@SqfL_D(dgOb8O%2R*WxPd@0l(mGm z1%^ps_Mo1L2DtiU|2pOh6Oq(qh=6Zp>4POr6Fds}HG9cf;JcV9=dLBsRNobbWfCkM zioLb4l7?h#N?XB;)7?Dkt1K*J5=l;qppgx~{DYzC-G7g8mZ8mP!DnqbMZjT|`WO~; zSAs3C1Q0N^#Xe+qBR(uYZzh+CSzs5D5M1J#+{F^sfaoI_AYk_ z2mKo+6d~DzN64z|n1Z%>0>v&1`Oh6pVfJCMYn*DSUSi(k-($#>gx(djAg{y)EDICh5SY#xMo@Q0bD?w%heKK6_URk z9eeD>qXNO+2?0c{yZlNr;{ilmrVv$)#yWnVU(lEU0kp&9w9y7q&+Eg#(x#2d9VzPt(>7pv=e&Pc{y~hM z-3{isp1oWspYeQ!j5UnL`WrVXNVOZZ-IknCd7fpcT}|+}X9w zduBU4)XBHbM*N1pomEnU16f2zF$?(FgbNT|AgGqnV;mJIO#{6t@J)VB^U))wS~2a7 za8LHp-IQhOOOyS;&$Fqe9CwIe`FzwR*Zk~D3e^$IO)&6SQWI5Rc(MbdQBreh8uaUd zaq97XeAVZ`uZ|mlpD=E0|E~NeH{Q5G7Rbwklu%yA+>08VxQviIEu%sWFtO5l(zZzkA zm0_SE_=OOG`UYmgKNlT9@p)BusV36PWFsc6G;>p_UW|2x4)}RAxr^MvE9D~FgoAY*gxiesWdRH>3-YRY5se z@d)?yUZ`(2rz-81FA)d+i#$xl2M?!2vaj6rQ6Kb{-8+eU7LS3RXQlqXjbg!}T*i28 ze_9(!B_`Ov4=?bHM@X1Wu+6BuBJA+ihrV_i7Zljm7E>8 zY&ll|NAllE^XmR~_dgP?|C2ElslIu_DKtKR^USE}@bqXeXdX^Ow)Y)#J;A`r;Dvft z@{zCqd(vAIVG+QB=6B}s-z5X=DsY0LB%uE$qZeCQoy&PM%BR-RL!rV^Y+(O=DI3ye zNLjF@`cJ;7v;jQVb?}FJ+d4Eb&EI{eMk!Eh&I=+&APuLD}@nf~_IYVt^@oE}azcroJ^2At*OoLoAwXNd*0h?EU z3d^?M>@I_K>wvow+TdPYr)6C^BO|>Ggs=5wv^m+g+NM8H4VN*^uHx2aD-+8XC_kXM^86BzLn#m1y9lWAERu;4R*?RG=7%>ARON6#^cr+_&5 z@}#$dTHpJ!d!E%x0FJ{6bQCXg3Qks<`$d&0X+LJ6WCqa36f?Wp)AkiHDDe)1gv(L@N?aY_eHF-7p!d)X5+XUa>P zVqrzI2Y8=%8&?by46`H&c1V!fQFJw)t+~p4B#1i?R-<+^-;-eB0=W`yVLi6n>Y|UZ zu$!L+P= ztDoju^DL5LBJ+9t5Z>LP`$=Ptlg&V=dJZfGab?KkW32s#-|!0vYcjW5!w8dNGVwa6 zLw~W&qm}<28-?QfIQl^BV8stuD+!l%-fm<0O_|ep{b%-E&hk`yZIw&yED^8VAoVwV z|NO6Ds=#h?Nr-T&buPrgUj_3pVjrP8naW*|aizerVuA_gqk9w(>XN9{9_7sH>6hmc z(<)wSMh~sQXI}4JzdfNKDU2)v>bA3zvh**HlMW4~gwFZ&0!%S%iyYG8GYRVgj<+cV zkpNSV*_OauQhi*3nTNz}6j|#heqrUwFrzZb1YNTTvGzu?oE%4l?e_pUkcmK!Q+89HwyrHJ)QzT%sar z3x4T2j8U1Cp0b(r14iShp*FGWO?T|;nBaCZo9jk^=v9YS!Yac2(s{;te>_s*L??#x=rT1hvY zu0E$~@BNY5B`O~IT=cZ$l*Zym<#M>DE_;r@HiqoDqf9oPVvjEkFBiCAK zA}J`m&Kjxy1x6$}A3|-RVCY{d&7tn)N!u;hSJ_S6< z(Jg=IzopmnvDVYGeQa;kYrrt;>5jK{XY|GfO~tf$uPE7F;O|X04vTM_BJ89qt(>&q z%;1wrVj-XJOP;B1?9v>6u!*KP&oMpk^ed919j$20`^FllMrb&esv_^SOZXPoX04Vf zfrCK(1IYG52MaOwdGX~Wv^3I*C}@tyz>opOU*@t&teZOQGOEQFo%$*B;x{{KZtkp$ z1rCvfbY6I(k`KZIcam}?8wSmFDhlwYJfphzsnXALyL6>EUjq*S1OFb2Fc0d01FU?8=eNfLAyMD}5& zT>M?P1TWv4Hcwen4Art3harkco+eW^x29VRD*0z`xBk)Kp1}1dQ;=v8nvTniry!Vd zmw1;RdBehXJz4L)5mY!T$VJV(Bc(Hl56P= z`8Lg)bhzazMZ8NssfRL{`!5a&`ZdzGz##W9uJ=>%?XT)8_-O}DWHej-<#{!tC)ZGw zv}nYji@(KijLdNLP8Q!$kB$tjgfg3+|INLaAuMeFYI=pK|Btls-^17ZJdrPOg;2!) zzgG`N<6M>u`~E)xUjND@03w~pwuQADX3`D{a!~*0GnO-1oM|=r% z2V?-?4>hI8{MOW0b6`iAz6Kyg`O0df5Q+EtorL5E~RA{#sRZ&ntcb{^nnRbBd=Uu5$s{JSZCJ(8KIUpNz+ z&TzKpI=fXdOe;|Z;%XLvN-`DopSW86tLnd8E!ui09sDz%y6TN=Dh6^d?Qx6Bf5wz! z-CCdGWSS337&a|oa!|u~%C#OChrvZEg&4ichJSu#F(FTW+W&R@Z~2!UiP{YMUPq{$ zbZAO%_@@%Zik~1mZ;Q6z9<;ZIr=zjSo;m>P%`4KW0Z3=LGP$+3URsl5QrlsTbc!fe ze2U}Ou?K95u6{6^T`lwube~S)%h)#9NX~9H zUCAb(weJZ5MF-}k`LW_RP+Z>m2+845ODZ%sZ&u3gKO;#uG$nBKK{sT-V5>kkF-tT& zI=B&sFu=}L6z(fW(fj1i5?rv29**^MCnm;Haz5abjrTs41E1U|g!P{@q4fBRcI!ja z#(!XK^nzlrlr=a#j^1_qch7o9tJb3{rd*stHybW$toOFdZ$_5nxS&|9|Aj2wEaGSD z^8DmZQ|2|}#0lSp8lnHq_f(~j2w_(AZ$;{!*bv9P#BD5Up>xxhSctgHUBZU*?k%v5 zsm~W<c&$w!bN!Q+a`micU!cI7rPm*+&py5mXC6A{^@loK*5m92 zuR!#kF=8TmoORwa?=b6FemK*58uhUZaUB>>-208+6?Aa0wf|Z*azsE(xbFFggran} zo^+$9H?SSd37!4e%Iom^c-NZ9+j%oY7qM6|yQbdBW%1JY`jj#3)x}NH)TJ;_m?WQu)h^WU>#OBOE{N>7Szah06gdY>X&bHRTD!M$N|r`OhQ8{tJt^G z8?kI(0=ujJ+w>6j^89KBUj7is4>clKa`^(4bIY}fv0s!`Mcn>8@0&f6D~i{^4zo|w zD2g1n3Ea9cKmHGMDn`(acns)?slhGa?{4;-`CG=(m$PE~ho;`G*F05>cw zYmy8MVI*i%^gyxzR^f<*uc1bMp-?7C$0vNTGd{8HJ|u&)J5!kEOyR3e=-yE&AMk_e z#YA`+q(H#n*iuTp15n{{y-?!=^b}56*-py5BPtF^P&qVN54#I|$j^125m9WBA%2Yz zn5hhN{h!pbtf;e{Of+sA0B}neELo>Hg8Lum!~>*XE2@;GEyQ$+E2mPM2)=rkvyGva z4Va!gOA?-#Dh3%Ynux^627=%>1Z2dW9%YR@tFuWCfVMEd$yHzY-jA>hX`R8?hOZKb zSmoC!Hui3PMF*XL@eiH23>&B&c3gH18L9ARmo*)}XRX<8+uyt|_^TlnbF+9>dwekA zoybU5me2k-s*?ktI)6Nt{-r}ji#B%ZfNxL|jr>eTp^n#|IH*NyYYIlJuL7AzSsbe<*36OOUa@vaV=twx299POnTmGS6Yj7I z&1_>SzzGN>AYjd!a4+_l)cj3O^Y!`?egIApe3Tk3x5?7E2u>i$j>)9&BK)Bf^;t}4 zn-r+<`}<1n5?rn#<9W7%&=7t~D~Y_U8~iac+n)6gcC@-qAt4}(2w+`X`5qcJ$ z$C@mRcB;T?5D_k7{%eN5W)D?5dZF`zD`6(xu@#9E^2~_l8-OmsvXbQ)ohYa;aN@nx zw~Aieip+j}2D^fNR7)#7Knyui+UeAuL*Yzi1g$jW&>Us0^@UWfi&Mb;D(>7pYQOh~ z5UtqZMGu;okAKYgD@B%|)tc7``O9e&sr+3E64e1_+Bdk?K?thg>S9U6Wih`Ig9@%W z@o?!yVA8>vAjs};};qtP;e(7eBU*+=0N ztt72)HwX@3E4L01)jN1%CAa+9_*W6Vz|D8t)NCXn)N*3C5?dGZ>oBN*&I$k9SR+_6 z3BD;h(MEPOYf6uH3~9kb#PsM#Jvk=_)+67VGmmFe{;#l)g_%e-=09c0>H{E4(g3nz zKA^is%k&+dn(~!$FD=M2`4?gCprEM!KBa9G;*i;!_?t-wAOIwUu=+9rm6V{8rp#0>;0e|1Vf>CF9e(O^+M!z`)@C!(P zyaZKHo?pQ{hO5$ee&wqxS@g8f^DEtVz9qPSue*Zy|9mMk^3$I{^IKIN+rpR(wZsfH zapc}b_Ajbb^3jfc>~vg}Oad{#iZO2jZbFnEOF!INPIcaQciw-Ns3A>@k>y=xO4GT% z*3;u3cXatX@_3)yWwdJpIh6Zeb@-h=xwnVM&E<^ZBQWZUa-~ZbH?M`i!GI(}Rym6^ zZMHUS`3zSTC1ebZu6tDin@;4l9Gf5nfYcJG8N%VE)4$|SxYcKE4XL=kN)K;Ol#cX1?Ku`wOnGxvWO!a`wC~ru(k?9 zuL`;*BjS?sd$=4_&AYP>%em;PtDD!8A#tYN7w-zQgP=8LYiBXvL$H`?9;f!-0Jn05 z&Jdy&jM#(&N+cx;q7@e$KE+R5v0>e+|Q2Dzjt4$IvB~uDKN?=dy%4Wjhz;URX11*_2>jhjO6MNY+$n*Sa zLokGZK;Ne9(FIqB1~isq$Z^+kGJTi{ZTUWb{G9i3CMBoHo*{%dGd7-M#CP|BYVfVFQYydgc)t>^F_V&HHu#+<|UN}v+D=1ATaiMS|)w4}DXA67p z+X!AH+4Nf8$d#!&m|+p^5Jr$}w!$ymld=G`RKH2qI3Jd=a`F6FgYJD{W{%=Mo?>TA zx_E^wc8L#nU?X`&a2D4nuemWrxBrng+SJD%bZN1IHHX7EK?@HEgAun&CjS-(AzdD~0;H?g%CY zz~HDR1%RvxYPUlL1rdb+OYOSpw60D=iH@M{RD?xm!W#qi#7G*3~*K-v8g2;v2Aq( z;i0@C$dx|qYg|D#pW{6GA+w7LLAx#e!s!nm&d^CMHm}G>zgF);qfe&`GK}xP2fK%2 z3|+?(X!$F^`tInz-9VHO#Ay-k;^b-BuTp-F1gkM^Ez_O1vmf>bQl!YYT9W#;t(Au5 zXNDIl{?N(X`^nYMFTOfmtwU4mPfp@C$gcmOiA-O5x$XR(C_}*deE74M0gqQ)U{jtA z!htO}u^h^of74*YdykS_nKz@oHK^`i{oGY7U%3W`v@`q8EObK6HulEJW(GgP#Q$vi z@{UOT@RDib`=50^f(MN<&;zhZ92}$f_*8j!sYZ)@!mNr5gfJ-j&7vlQbYZfmYAFam zF*3q2QX+BR@ppVvsME{WLZ9r?%FjB|Z8sUoa2z z8biiutOR)vmiN|&fd0l_H{gQCo7A@GFwHopa+!|tmmP(K2L`t3Q|jk?IKV~ zwt48=a)7Y$!YH6m%fO3MvKwC@CyP88qVQ|fDbd>~uJ&I-UUql6 z>kj7_*Ugq^oxceehF9WHb?B>SuqZ2yMtM1iX2WCA!p);pq>AimMh{9NrQQ7_it+XJ zEx1(ExYREW!EE0H7_NrKv}B#lg}356hhK6C?Vgu~?qnCVIylmTg2BA#E^{a2A>3^= zIW1iwQb48+ZUgz46!&1>5c@<{#vR(MH~gGuX(vLOR}e1wV>7% z*&+>5#Vh|o>PCoG9aWI0!_hYz#*t?3klLDuFNoZ(084yJ@GAHd%CxBPol7z51E2rLw#Ulbkxc=A;jZ-Ah?j=}G5O^Up-OaJz}G?C>p}QbDb|sg>Ql&tu^^AEMR(c)v!-z;22P%dVPT!8 z_8qO+yu=h&peQuYcEZpk|b01d4a)sGUs!7?~x35{H!-W#u?+^5|nuhV|qrcS;BmE3N8mjLx6n) z*X$-PufWTriR=U{#64z5mN))OQReXN!UMNQesDn<|i=;YNOUOyK1 zBb^2V4DTh5z@9VN>S?l8>4UCY@-{)S+ic|cX7*=D0fzEDu2VHwC89Fcb*}#5p8ES( zt#b!)U#|IvE-f3P(F|NT;`K#>La@(0C(bd{g^tqT0@0Rtt=RJ!PCv7ANl&7yeBKy*qb? z#A###)v2tGyj1h`%S2U2;$jrK+4t;+^9xFNOW(3ncy39WrFaN#KEHdylD|#zI-U({ z))1#g2B+yTu(}XcLq@GrrVep*I#w6WNkp`^>M-hEb4bRxsDvRF4$p4nq6(?v$!mk!cw zQ#ES+gHCpzzzs#bH69Ud*x;D)F4u#UsZ*mnM#LBr)GfR`5Vs zj_!yy!Db63ix*8A;*FuCzCo9x9pGEbY?CiK)jJSkHi z!w80(1S(;PYOV{s?rhu{e1}F^ye%{!L5Uf%b+~4>w0snX^_}uVkD1C*oEv8=xjaw( z4zD@$Pa}sbj#nC+4r0QNB4r>`0mcoQJ?AWn(^{HT#nPN_Q}>_67@!J|yELh15AA^l z*HeAz=B_kXa?`&Xiii}39c*QIL$&rrwP`D_(-*AYWS%zVOB7#K3@_&x)*!e2nU0Z45I%3b(>I=X zra7M4Y3f{-^L=B}y^HrG_?u!n^oPXX%E~LMmoK@3I=gyg6|sv~89PY@@p6rom4+C% zi&$t@XNAkHQWMqc33Q09+x%6+Gq%XDUPS4Kr_e|>&GYO>l?ee8L4Mw`Y=LZ;IPU?} z9vB2QOMh~IZQ%Hcc_Ek-1P*vGaubq%2pYdElf&anoS60eek;%2RuOWT($EY@m6hg3AIEk3Mf^=gsUybb*h7manSfyu*VOt5bM5ZcN*erbVU(RD;=s6IYbO0o%_3 zI^*w4rcP$RS3?+#rjdG`{l{rHDy^+{37`{~It}0UYgT)cxU(hb+rbVZyXk8obMs5o z#FaL%#W_|FCJ}pyu?#}2#g`3GUQM$dg4FSongtE23=nnSrxnAtx1W0(50B$1(-A~v ztUw;8E@^>?ZJnw-bcmO>ka?z_O1#j^MR!9nIM1y^e(v>PH0;gTvcmqb_?_$wqtcbV z`g9o%Bvm2CP+T$CTqY4{prO*(yier+mb-voHd$Z)&!qjxtryksIN{UH~SoQvjz=8Q^Gv@e}q@&|{wl^On?1E9@ofjncOXW|cNJ0mK(V zkHOUee$d^`mMT(|c%1q$QmI{k;q&AOc4-*hP~bnph~q4z#jQ|L|BL-%2}fvu9u4bJ zn0!?N61R0V64^G!Hvm=5DGOSXKnP?Hm@co)xU`WLEYsR2RC}vl8p2!bn}Gsr3)~lf z#b)uHM;P4?In`E5)25;8&Y96?CvH|=_ZSt8aVmSu${5b@miT>^(6YxfoD{F3A5kf* zR@_bwySTIu_q;bhxMTv6zrLhaxXFXaz%^_92FhZAJ+x>x9GDqQY)#M6OZi*O5LrdC zDfhnX0Iy>sN}FI$f>a|~7UK28nDMiV$3I-u!PzPxS_F;eblJ@K4{Jn@OytPS=HUD)W_wRm}RY+wO$oF0R2q^9vt?Cspo3GUbtMQN zEG~_fZ!Q24kf0@Y7|$WIn7Qm8^WqVClgmzq7qw)9AUn}8Zxa+PdBwP*IV#uamPlIm zGSK8(i(`>D#(tfERobY&2@jV35T~kF{@nO$mT8@bsMg9D+zv&Q6e4BR@R`T>@BU4# zKgz`@-rP{Mnz@lnh2MXUA0*}`9rO>Ua!`X+ir^>^68f@Y#|`q`dKHF7mItGZwdPal zr^W?DaNFhmiu>P^NTSvA(0AeY+KVtv1d)e`T%%x)yGVu_@&y0sOcmqJM5|c6zo&QZI5+!r8XHM>9rvD56sjK*ji{oNuqI3K1h3- zkgG?TKBelJ|>fNpH@sf!Vd})P7>-Sro;nuq!iafy#g(J;UZ2E!Oo< z5Ez9RXnUxTRicu8!jDBUdJuJ0_edXJ4UVFDGStaa?%_uVN2*#_NU26Kh&(#d92;dI z?vNcWD<-PAauL@-?~eoFo~m_sCy3V%aG59Ia3K3kc_5iI7)mToRvwJ zHg8PHd)ra>(M!BhK7x3&AP+k9&YtvM;zvv$I#XneV`%R*9GX+?OATiyBF@{RAC1R zj!k0Q!6v)NiRdm_gxrI!$xAW-g&EyvjnN_~K#v$V^1+gy(YwjjpuBa&Chud*>c*;q z#J!tWJ)|Qrijn*j{)5R;`SJnSF3BoWR^{!tXkIx3g1d^f=vKm!o3dwu$UkL=U;&Ov z`%aSKq+wT$gTJV63rT+cEdxM80)f5?(|PBCXWG>82NP}lh1{HhI@VT%=9wj#33nsD zl`OnPL~!_b<@$wwL_yktALAF8Iq&BsKhOGvg(y&fn2-HKxMNNe(W_B-8_)Hwh7^?8-{b79 zZ{a&PKX~UOZAa;=u39yKs1+8Kgyeo zxkgLx5Sy;m6>}KS?$)cF5K$pirHHm-6@+{fgrYbea+<+$Y8{UCmk{&~>&QQhe3x0a z-H$Z;7ch`>?p@cMg|=#N8}Z~M;^gz>!LGbuU#|qPd&+=*Fzn2vcVWN=Okm&sp4yLb z%+8dSdXJ&U5M!4>v|3RPxz3!$R-q#-uej_=Qhm_wwdZ-*Ak*+C0YdUDSeP81Ml zx&8M8qPANffMe~$tG<$_QuuQJrNBS4T$!~^9x7>&;y-kDf|v&0&3+I5-uv((ARCvR z1E_m~7{>D^?2qM$1X3OSe{&D|vK6ENPm%Dq2R)UWGh@q4tmv4`ZE_tXj$gPTC6JP0 zBgjl!?S^AvIGuZmB6VSsn8G}Tq6qgosMY(rnL-#3Rd}2gBxlrbPnmb2X4AuS#HQ5M zr4ipfTvG1E)DK@7od5PEl+fWLLbNrh%JzhB(E!{*>S84T^0&nEC2sbAyDQ=ub&1uj z+f17L)@#Y zZd~Zv8E-3T4?Yqhr@(9Vz+EjUqW2W3_{XDlTA_1?v6}-k^bk#iLU>pY^^vOgKw_TJ zlEHqSN1nbm_ICAVoUASMa8|u{1wTcol%x?3KCE=zm_rvX#gYmGT`PLtoDDChOa#vl zayfC5l)c|4(v*Q>$Hb1Hxx(cd#ynJgl@5R*r z>A8ITUJF2t*Px;TBIsm9{1Vo~)oj%hVxc>;QM;jeMKX1_gA(pXr`S;c}i;Jy~+MwD|Q z>iUNS@Ui*i_6?o0K23VM?@}Xvo?Z`uw>ILzviQ|q?&g(z5$I?@MLv7!U`%TfRrq^8 zCfHbs&L`6?0sZjki{_=H)n_F%Xk&O{9)vf`T`}UmJANW;5>ZFrsDDv>kQVA;dNFpt z*E*Y7-QR@cZY%k+Zd5^Q@h4xV&v!j?GL)U@{H@Q-oM#=k+tk&ysV{gQ8`4^TioxlA zhVQ`SO)cMd(zXGqGl#l(8~77p##9q*S^5Bk3^hfh7e(c`NkCOR4nr=xB)l^ogaanTM*?h*r!NEVR043^0%ckmm#yr%x^f*5FU z+p@x0tdVjwyj(ph0mUBiPz0kLuAa)r7hZ|3oT-*K9BWMF+)?BxBOF2W7Y8EN#N%zJ zAd6eAVy#@lD@qEd$?BF7!htO^d>fk!(cNF~>_vm|ttbP+*!mXrQvx*bei^-ZLy@x; z#rkU-e~`&^fIm>~JB+TW7d+Y3uMS}E@bm_Tt+u>bTF2cii;k1#skCAsb53mRtV{_S z$s?}C0NM=SwlLnW1ecRi%T*4ys3E2ATQpCScPkE`Td7)>mll$-9=j!!g&X{B0-&}z zr+%AS2VX@ATWM-JtMvwfZABqgK8gf`>PFV~$Vlm-*{y+XE-knqAx1CNfH*N@4W`Mi zhySFv882Fz+<6I!zlM8*ro2Z$a5x&bBrE{gmh(QJAtEO|P(c7K8n6~~ zvW}JpOqe;2f9wy)HrUoA@eoNEuMzF){#UdT{Z`LOPJ)c3MsP!zd9p1-b5ntIM* zTJ#)*{|n5J3v{pgrBb~EWBZCP$1}3>6@sNJ{ycEvxxyeuu|pb74&SFc5;qU9%lFfs ztP6H<*zT@J5qT&Dvck=)D*a-3SZYqXGb;-?!rnLUwvGHz#Du~VY3-6K5Vr_1EvRR{ zsm1m==fjY{Ue+<=z30`rsyDs2ENf^FkrRJ+n2ieh9U>C67+<#gUG?=FxjaKkMq6w)gb*}S!}*q|KPs@HwE4^ayPE zvP+tPUtx0@0-dl6mgUpsu6I5^aC+oBa&%cpGIX3ZpxJ(sf3Mr-_+$1@eYSKOBx(lE zS3_LeW1Bh0zBy%v*N>()jT2!T8L%OcgZ^#`^fW6YQUdCeqoUWL8i}h0rT0V>Y>+j{ zB~sB?K&)jbbC@TZ+3!+LIUxfH_S30oP=Q{=w|ZMBocGk*H1E!9glVMF=u^ILjT+fh zy%gRvb6M64_DnL9fptZeyfu$e2MHZjx$N}UhM5>DMHX~N=UB|=%5D*6MT~#EgC(e- z)cM1q!E0`QgO#H*w6i@y>q9Ow@z~qAY64lEf2#&=bTg|X8SSV26Cq{AkqAPh_QHn& zbkg-Avwb&CojlWa`2_ezInI@)?`uT+B2R`)?XW_hi0V+qfO^-2VcmR$zjb$Bd)t0j z3?xPV0!)jaWebwR)cn%XMhg2Hf@Q_P^E3TOugw1r1~oK;BhK0hOrzu>|I)-THxWE? zlll=wcmpl`dbU(`R|`uooAZrNTi$WQX>NZTEL67+Ygnx^J?$WNdaY*Eq%+vfDwF2_`VH^KFHFriMfsR9NR1#fT?et|MrRGW+y4d_n zwBg@Fhe7T;HD6#!=IcR2t`bzqH#7MwUD#-*3+gfBJm*EktRkhXBf7LMrkqsD0~!K( z=0|<}M7@g^n>ZneO$80hlW2G4O^RgBnnjHSH`mi@y}tsm!c6eh(5gT@tp3%57H=lr zZD3rW`aGR{k@lf8&zqlMJ@sHtsJtjNR-6DNxq7PYPr&n?Eye#rn>=^7L``l)dx9n) z9KqhSziCbRIsV*gnj=`m&2qpDT)Fn)2Z|y#yhpY#CG6ZJxlJ9=jr;x>`(B3k#f-?-aHq zE=h=40KKG)Z_7F6+ELli@pt^uH55X%oIdwwD9F{m`HWHmGE@*N=IlCPZ@(|JSKp7W z$*jKeDQ!PXMBZG&tFbT+6XCaZW)6y{TqR<7G_<-@eeA ztIgH9wR_uS5}HF^F&bS%&|JViSCY8#g*_90l$686N97+LLFqpNmZcaNx@1z=^qoo^ zqqm0h&*wjv2X?s{CGH2f@j~7f4f^>Q^u0B1Vmcx_-cj zJexl_dD7Ufp3b3N+nWwE;a?CZl9HO14LU%XC_gus9QnMuA82212~4$N=m&?CEJ^q5 z;EiX^9~Hv$&oW9ZP>J3w;Z?Wg_+1V@a<8Y`7zRhk`Vi>rOA`3Vw9AM?)oLuZ0j~0B zs>*!Y(QSqB{o>RNHgb8nlz?4z5jBr9(`m?rZBRc65kGg5C?o&$xf8d@p_bIaVMXpJ zJ;@X`$+r+gl{=DbL?HA66#c5f{Jqc3E5Ksm`HRjyA7kj_{f^KV(w+Ubrgs8#SpW;l z-l{IEqx&#)(RqK?hGl}wUF?A^d;HdHJaAnB@AwYJ6xz)ppDvZf5UJ+c~e_iue{bi&NH@|9#c#@ec{sb)mg ztJiYKr0Mphbm>_9Cr%XRRB*;mzc5L#FFSn`-^R;lFOnv*Ql@^`uPYw7-j1q%=4nf> z4Hk3M3@kH~SAsLFL2!WY=`bflG4tf7aT7VI){V>pWAW}$w&pX3bkSBiyB)b!c(khJ z+64Zs-lgnrizoO5c$UuS%R^EO-qc)L(LlJa=^|PQQf_v%rboxvG*P< z{kiqPN-=qPr8x(C=y)KR^5cw{VYufj8r&@rCIy&hP?M@5!VQ>zUEOaWY!b8A{4FAcMO!T^xsyc)wCm z^v}4>VHhcrxt^8H7Z_puZRnBqUWecP4a5Ub#?LE&1W)S9!xw>G2>5|e@@ILsTqcL~ z{byC<{KiM#`Ktd)B)dGV@XfTBoY~XAW2RhwSFp(Wi_Ls180lNKmj3>_B}8D49{V1_ z@itOTwKZO6?kZVx8q(i}Nx{~(t&zXvSboIl6Kx{1M-`aV-{Z24<^Ezqr;UM4KpPO9 zCz?$6wB0MjK9-uys|4d8II75vs=WG#E)iZO`F*FDK#`K;_$NRQmo;;Goxd2*g5;`X9_f4Kc*I8>i9TpaI3Ss^&_q5O@T&O9v+AkjyMdnlc~l33DTfWzkYx?ou(9Nvq6j&aWE4MM zlpM32iGV4)SFW7G$8u+_me+$Jcoe;g93|62r-Jb0t9m78PIEK%qk)P2W_%^~+83pq z$MUqX4Q$27KNTJ`b9GHeq})YX3N@U~nIipmyA4_Ki|^k4)o{afmfj(G0O^Y6nv-bt zz%DJL=4bJ1jV6IF!$3h#CYZ-D$w@T0BebUW(V{ge`7?jZ*9j4XtUHiATS} z?}bbkb3cLt64eraDZ>n<)|7Hi_b92DGUl>}370M7Fg0;+A-c$# z2n>!-&neUom*hWYqs5Fux0y?}<}Wmt)u+F{3z^MJ5$or=_Lk8ee0Fs{D$3kPe*Elh z;RX;=Ke)`d0cmNZfPK{H-1$*!o=kGlJ-GbSHcGEJ&r293I=A1q6sBi$0n+rnC5=*% z`CD%Fs>G@&0~W`(XRFH}Ixugl7+Nx&W=uC|YGVfujmshLHp^exwa`&q*kQb=6OIN6Uh7pYtZ` z5=T|NPy`HSCk*B^K{qtWHS0RrDsEzLHl&&b59m%&iaIHpYpWX z_Aodn@U$4II(akobffbK)#*(fX?oyRqDx|aTt-=Vle_hFv3uubFeSu%@$|TkeY|r; z@fvu|hqXm3<^%rI88#X&Hp-^YeS*){K_9_Qx6eb}s8_R)`J>L$BG4^2BPvGre*0;A z^{LOtd*CL*^N#>9f+w;ji7(MbN_vs4{rPf3Nn zS;oClKFx9sr!0-=9mafOB$vK~l5*azv=f!vJRYsL(T6ih~81sQ2VLJMc zGcH$_oWDO=xHtTxX4VD8)Q&1P4)|%>uf%AyddjuFD+ynIW2O z3`qj6IWnjRQ+}}|_8M*8#lD`@oJ%EU9NUSP7UG%oqc47`T)7Wh$exl-t8GE%-10a|SuwtGx4G7r}jkSBxT z7TH#D^CgXI)Q%1vnHMYH1g6d9spNk?=*R=&-CMXZQeV<9FMP4ufI8Fy;|JR(`}vYW z-#Vvin%XUC&tz4A5H-h|yTi`7#-6ij_A4h#re%Gc37vOD4_Oc_F8)65t|WhiXd!?s z;p~>f?QptGO)APSkDjl|U1`1(D$f|tNH+4$#p?m?_pT_h7{1$ura9TZvdxC;yrtFu-m@VN*RLu>=EARKFqq(#rr{kWNb5Ked)Y8 z;Et!y+5dY6mfn#n?8~C>aOHz_!pXPPMon=qdh{gcqQq-Q7VDNO!G1D39xbVESu&Mv zja~s+TFbY%TOV(G9z*9(nD~d!bO2eOQCzftRb_2~etiq~E1=jj{joU@iWb0h;ERy= zKJS@`WX#gh(KBgkNmA<*SR&HluOJQZ_S)nzGtpv>!SN*4YCqKbX0${v|EA4lOY>%r zHQhTcy(1&veBlJy=&R0$+49%Kh*_rk0Ean?_a#CSC4+*K+K29yEB2#OaR8)6NoJj_ z#V?u+6gq!<*E&C$e#mMntZNoWw)87X?L&RrHi7roe^bI8#WYDl-Q5M7$y(>fbFr#v z3laOCd-%d#fNhc})NbZjlfasstN3p zfofp-*s9nVaP}^~$=Tk2=y4#e{;SLikwn>R)x8vMfZKkY)clhOCmq?zDv`N7bo47y z^$khJ-Q|Z)7)Ug4yO#SQKSE)EVN^p@Oa=gMYG*%aDObqzU-d91_Cj9c2&zXn`_|&g zUKt-X+3N85{Yx%(4k`JGR1ugs_s63)Y9dJ7Gx;`ifhOiZ1n|#G#;zdp+|W_DmUm<2ZqiJheZWx*?P4ZWNT}6QkfPVRv?NoHS|Gb#GfjLZ(hB3n&DQBj zouk~2nGj10?bo&CnS3WU!H_D|bd&}za6l?EK?JC9w2m{v=Ui0C8{{{3Rj}n>^5Lg(f zIs88T)H|`z_>)69f}<%w?z>AZk#klN)buliuuj*^Hw)h+_$y2vV1o|G(M|`>l~dI0^|(L!3i;ET3ei*bCb}o1ZXuz&ut_ zo|pqmOr$@LEE=EVDf)d2Bjt|2276x$zClzLdbumfWfj^7ApF;~xDx)g0Zn7ZCBGW# z07BxzFx=QAam;im^t{XbZ0a+u!B1nw>c@*kWjEV|?HoT93}lcX@7zV2r+~RhZr!OG zZh)~s%H`NDQjDw_WZvIdJC4R;G>fVU7Ni?XHm^&wy-_`mLjX6)GUn)rq$=PB))~aV z)G!atsX@Jzq$R$Qzx%{+!liS72q&mYRUwVO{k66RS1+QO>vo3t-HhW4-y$d+14&L` zVMW(R1YgG2zqB|zlUr%e9>fP;T5%eL5u*g;{(&@GgoY#5mhl@7Dx;JpwsikVaLkF( zr`&dOy-pN2{z&jdFKgV&#*FZ+qPpGjCZLgl1vgN%Ww78AzaVHC6Yc!Kc}ejWV@fT* z%o7dFq)~;KswnzH-Dk+PJongyWwcb_Y z9lC5E=DGVFVZA=Bq>EeMT4TE06k-_%lsWa({X}2m&3e1mO6ml9kVDbJr&F@g*VYXB z0rrQAH(09+k1|I~m-W&Td-zex=Zxq%hV=zMThAMd-ezy+@sa@qMhSNZmL-IrU4VL9tP!S(;k~79G4>hxcX3lOC;9drNSp(ytQu8K@#Srxx~cDRW$ea0SDzVy zY@t)g!yp~JoxZSb!B4U*dE z^cI_twswCKQ!JSw3xOCDyL@1C)$G_E;=%N*TbG4sw7aSSNXk`~#Cpd)=g4db=5pTOoTy&7Tm>mPGV4M+2j3vWOLZDMo)?-Xa+WQi*5A^7yROOPLT z%-kNLHEZ?KSK&K_L*(0XKu1&g6cjW=W&9)`MT1*W)k3Q8$nV5rJ#6F1??E`c)TebE z2EFWz5mXJDygsX)J^PmEnT;tG#CL*m)qAsV+Fs=WunTwPBc{+PFu$?8^amL-&yYBZ za)r@~_fU`Eh6}f}4|Z=XX2?P{c1e&ygzXX4$P2QQ*qRdm7k6*n7DpF$do~i>2@*6w zfZ%Sy65JuUySoJU1P$))E{(er+#$HTH0~}_dERr*T=NZP=D)tWsiv!I_r2F%>v!*( z*s?FXQ5|IzY}%LPo?^yAt772UfSJ%+*y{p76RsO`PQKOBw83RCq+$;+Y#`}jT84jK~TQ7&*dpo{Zr>3cmW}@8(X|2Nj!(1%ozk0>Y zY%sv?ORnW0w8aa~SWc;wcx4;#9mqHu|4gxAyWd9)+~3GRZVst^$+vlfZkgijU4k zODbXCi5yJWOxaEH)xur>8kwC!Sx;#n{rSLts^a@d(!mitZ;}BQyweuLh+Vo0obh{a zqMaY(jc+~c2A6lxddOWOiOds(;w(WQ^oY0drK6IoMYDBQ)YNufGtKW@3z2t6fdABR zmPXEGN*gK-6LIOj&2aFWkF5jFiG~Vq2MwvkDizHS-d_3@n8_4%4Xjxeg+_+e>g2$h<@bugag48)EqWO zU0=pMocSd{J7dCW7k;kXyBn&HV0<^Q$Vbr`9N-;-qeyC2{bs~4c?|7dGP6PX)94Zp z*B|dHSd&5jC8kbqAKBe4&6-D;WeHwYR@o^6F17t#Dhi5gODQm|RcrP4RJ;Q^gFJ6< zUc6VZA!lMf=udbV^~~D_DL2S(M4im_4ts-<H)YPn2plpH`_u5I@-?SvgA3$Cm zx*$tkKi47epX7A5{$irG>rK6inTip5c=u2M*GeZEWxV4r zRO-lDc(Aivpy$uA2DfUH%LmVE6y0J=z|Rq!`;k+{)0##S502MzDjDooja}A7XHh74 zUi-kjn))plh)st#YehP=fGLG$-X)Wa+Zh0_&$ePt96|y1A)}I!|0)nrbckr@^SJ&= z|E|#<8!L$`&S~ohb?3PeS_aorr!F|F!XI&s8*rAvVW}oO9U780!B0_HiSWCgh2kY*N}J>@-93_+W!{p&FKIl-$!SpiO7 zljk(HbtB)v&g4&r|IR}ULK3#X5-%9N%x=bxupzxO;K$Go<7J7qP?{9e{7 zxwjPMgV#5hF86j|;Dyj`m!85v&Y+UXoLt6Vg^MkIcsnxhMJ(d8HTZuZVg@R zkt@qRc-bKdyMz`$# zzY$O$F?h@I`X?XWrB#oxhyDuVDxSsZeWb8}L)VHJ!P%{*EXvFL#~CK4ex5<)9?7e) zeC{%rmHz;Qd6u=pIzzX2urSs310eEq1wHLOQh|~bdZ4qf;W?jgLc}l};M##eHVQ~w z4%)z@q2iKbq*c`gEw&s#aGKVn0PJ;sVk*$HEg`GY?3_Tw2=gCTbYe%P$h47lSBcLSjC*i4*+C!DVV9eQdqq^&7F{$+ zWIkP~m`yEO&OFSp;DIGO$S!$oc7|x>gMuKNE>|RTr1~$M)TQ~>`fi^FK?*1^ez7{4 zW8>-c;|`2B*$T)ht;lU3L&LXM7GiG#cp9Pza*U z?LqOJdBq@FSDSe$ZWa`$&FUAGQpL-!wSQk{|2)%cmSxVw#kX$@E976gi=| z4Ztb09RhrtkdSjjUw2PA^P-S~9!olq0YkzsAy1!n=A?uWN}? zMZelgPce@?{4l}g1IwHjIx_6UCsf{%iQy@p822XNA)yiKzF~6S-0rPu^wlM19{-() zC1?||e_bL!ms$&*CExiA^bl|s)}C@ust7A@>=OKvou>xZq&Y2~jb1KN!$CNYgvtWPP{UUn>h=x6a~=^u zaj))6i4cSE{Y%sMTOk6q0|{B>X6J?~dANJ01G*Bgv}ul^AAy(%5n4BeHl@0M%+ihO6n$>Zo2-EU;1ZY1p1DdG}Rt9TE4 z(XdJOUk3GlA$D^Y{c?2Z)&t>WbrA4xT0Yo?wgUMe_RaQ2(TI7!uI88sU(+R+s6&R9 z&)JTlvrmxGr}^B|uj^f0*8TClOgO{AHmB$*35B4+{OapX!ry`Jz}}&TZPZ&d=ku>! zhZ8oCx%pg6)=~u&00|{ly{Oux5Kqyks)}E1WU8u3=&OTez_kTmo@xv4T;8W237`N| zBx}`U!HE-Rof8hldDUxkT)4qgZsO__nC=9by8he>&;~h{T^<8)rI3hw2pltWhI&bo zBiu(y!Cv{Pc~att_LVOVMaU*taLZ(T*IvzNqRqW?1B;fvKW?P&C}ni1xeF@;|B=_7 zq}8gpBQyGKf-OtT0=l0$+&VU%6GS&;@AJU8U6X+;dnAYN;Q4dTJwBHs2aa`5jEr{` z9SsQT&_;Gu+Y9e24TO-?3|M@tt8vS>OR@5$5~uAA5Ii5`-bOlr>=>$ zC1 zS2L>E?E|1lg-gcz>Yab-R&rK^{O%;F4tT)9IcFmmH7l_GvH!G`W2{{DuAYpl!8X-W zs>Rrd{kCym`A}%HsTj>HeIEtvy{wU(`r^e?MNmt-Q^O|jlMqBmY$cdu-oW_4(kmi&WRP%GYS-6p5Xm9Z(0@?+gJ@#7SoM_I$?(dq zpmQGPN=AMia!l=>UFoo(Q~$Fg;3sIg%}1r#YT8-_t5TXPD%$D18UDr>sANaVs2i@T zqE63suiLHCa$J55Uw&KoHV~}RVk46I_NrvHNmS_N)9O)h@0BHa1CG7VjAd{2tHcs1 z5tH@!sT}{zAAY7p0zNhSfBui^bI(iEnVn~UV;9CdVI`?91^ZrpXPDCX@HE7e%BJ5h zT5A;uCGK|<{LdN(LOJCi?V@^7rmr&eE8%vn-YtK6z5Kf8aD8zlqXbkfYKQYUa;+aJRTz};>&-s{V4A)C4I_9#cYao9e*0Wl> zjgr7anOJUPy^2$3P_j`O)?LK&*o*uED3!5+996UAMd4)i9+iqRnYej= z!Rmq;HL*4{9f<^kSx2x*8i$+}=jC9|SKo-t?k7bKyIdKcdTl{G;5)2O6UX5{wx>ol z-EpT_D2aa-4A^3CO=PnPWfM(w}`O4?YVOK0lnBC5pwDNPaO9D&J66_wj4J@ z9_YY)aplUR3jlg4&jnJEXn10e&$F@!>NuB2R*VFle;i zswgI_cv(1TaCtmk$w2qJ#F+e#8j4+~tCes(H7@zpq*x`)OL)zLYrBWw_iG1Sf+3QceJPRje-aR$(@4;;#LkI zIs)b6-RpI$*hqw-f$rfxlEKSuN^kadUJv>Q0w?g4sx5WqHuo{b+=@k#VsGEciOSVyutyk4(&uVlm= zpM{Wy5+=s7TE_1ScJPiy<@FNZp__$9-6T7)!63+p6Txp6b^5f*;C?MDg)yjPNh^+e z={(5t!zV5ae2?X-gkFLH64(+vCAgmYE#&ihP-v0#xdqNoVkp7HKcJ?_foRm*v0g50 z^4cq}PqMz_u!5i0i=GGTyw*<)g%c}^-z-W?HIQs)HsVaHt@f%)j&vw{{khW@VabrD13gyAB8+WGK40ZpDMi0c^I- zuWM*(dtte`_4HxlD{!KE)9Dtk9qrU3kf~o?eRph``GS-#aDTv;e(z1?npR5gR)L|i z+qs=pr^!xU5&`)LPd*Im(F})zF%$!VZjT?Fl z{-|0#habMUG1pVb>hTewT4AM!JSGwy8c%SdMdsp!8u>#8AzKg3<4r9qoz|6dJ-K%6 z`U)lN*HULrqO%{Jcw#ndB3&GC!S`9;E3Z%tMDeR4>Ooy1cDG1uts}wyZsP{K5<_k4 z4gsNis?(vB!`7$bd<(@98*_c8{#KrfvKAcJex?_|`TuDs!v8bOb6egJRQ}5#K!(6* zJDonX1v*e^;Q3?V&MCNT$522^*m3Du*qz|I_!LxU=~&=kP<9q!cTYB)>4P8`@(ByL z!lIsyu=-*=yFWr-5>G}D5~bAe7qz#vGTbXZ*I9qyrUqVbQpW zaB#TICiXGhM`K{p-kP-o*FZUCsPNd%CL|?8SZ3G9wpq7(mYk^ZghCJ9(j8h*YB6e2LMT*;)wlJf1KQT0;bQn6Vk3p zzsfqbDQA8|jKbwTO;-<1u54Fzr3OSk^>SiY6NbC(PX^3!24BG+v2hO<;B!!Xyc-)y zgWl-lPa)OnN+`vu%1<9S@37Dsfdt@oKHxzo{i~|o167*gPrRe2-v-||sn>DrQhJ~! zpV~(xKeV~M15qTD;$D*+_YIqr+o(f>?zf6Mw|XZB-M4lwFL-!UFI=Sv+)%;i(NT6; zuc~w6RGr_by?UVh^bcGQS4kL66Q!+J2wa_UkgRcIb){CwUFT}9Lj3jX(iZ3aOoSZn z%*{e(m&IW@Z+)8gPECWv_ov!pw70&LLY-Q9U9^)DzzmuMG>!`2lz#eB{`=O)(A@Dx zec*@N2#XNg=1OMNI}jf1LI+RS6H3l z@`1CE1fMhw37IYn9Y!1sImVb5Xh=CP(d$$SQeV;F8;qnqKUa+YLl$YvhopLIn0)ZoXUG~$e#z7Uo_chI3xO7 zcxEIU#3$tqLAH^&_&GVCe_RB+v*P1tAq1)8=gM$vX@~!shocUU3M5l*3Jo&g!f+9H zlCpWlL(Nh5Ti@j*qlKhL7`JPw#53eoqGelrf*>)kxo~n#xxJIaJDmHr-n(PZ zwpt1g81(`Qt-vh^d;hGoHBeubu(fi~n+Evvv%U0TsO~jn`R4>8PbgdcD*|@+Ak{Fk zbnQr)S7x)Wi|M?_q?_-Q5B3Bmp^qVQVqu|CQRzD7S$LJov;5LYvF9xoG3b-Uer3j78HO8!n(cAe+U2n55~-b2INVM-9F=l+sZ7x#&h*>Yyg1}| zCRR%0H_s0xDqfLiBOJmA3kYMU&mZ<^9P?kW?-A}VrfxLlzQ}Ndz9Bb1Ng-B< zlO$e$f2NF3eX(=;=;DO>J?suLr0MVw{o>LC@=H!xM*Bo6muIn>4z{_U!mSyC z=__jMj+=+^h_~(htgxYg)vhA*lm!DrG+53ZMbp9k8bpznp#y#Pn@x0yMf0j#Pvfa1 z+=^0qWO4FKKJt8KR17jSb_AQEV*y`PBaT^a^U&_p>Yo4(`^TBlOBO;st5m$+Nx!Gn ze1@Sicl`VT>MX=44-iYhx_gsGdHxRC#k5t3r z`M%%YrAwuR?sX8-KW5FfKuZQi^XwZ&AkxJIv`uf@WWyUu z>oW<>-@%(p2HB=A4Ozi=HWUtmnB-g{m8cF@FUj<;C5!fK&BG8Y1AELz=k2;+2*ngUy!sWmRku=$w|-lEU-|wE}%~I!(tIzM>fHUQs(meJ8K) z$Q94usra%Q1)r&0IpxmwMQ0vF$G77hnSyLV=$veBd+AcwQ&Hk|cx>R*)Uy=l`@7$^ zwnF~4E(gc8VJfk>SA=l+5L*R)Bdn5fqjcq7|7VnZpAkQwK|AJ^hD?yg-xcyXPYTlr z3EF4vqt@@UEs!Oaw@)4xcTV%@B+k9OANvB#f}`d0!Lxh$_HMJ)1z*TeSc&n)F!(ijRnYGKn(~u~jL)qi|!GDxR;6DCu7W0pJ*y&%> zFfv^kWcjgCzm5E3#Y7w(gc3D6;M882GdGsu>BQ6iG03Bc9J)ct4FCdGFRwE_kw(PE z8S5tU^lXiq?KJKzDIoWZRSu5?;?lCNUQ|P3g5B|G7{XU_t0xolLiyXjiekp>h|5wB z<_V}ajDAVu@%&kiTpqSACT^^=DZ-qu)z%j1!U%)(@S51OcI-KSTb2{5XiLN(4gd38 z_4PQTvVpm=f|S7a`Q`eauPuu=%=3c*FrQc4&wn|)A~Q|ItIYJ|bQKOrTs&Q6lEW%sEtE)gU5_z8-DhSi7P7MH5S(Et8^np8#p{YiMJ45z6 zkmR8L)=63?2a90Rw2QDT;|kkUhoYXRQAi4Hc|<5-2?>~&P{_1Mz-6!MFQ6`Uz#yZ| z(CoXvwz6{6qbmA#{t`k7pw*DRz2z^q$jiA30>Czs5Har3ele2+@PSmTLKw$_Qc@g`1BWkjE zhhIP%ES2blGB~ur$Uz==%4x7a&%Vds^(x??^b!Tmmo~baSfY|mAom(--Z1sGI-^L& z3wup)d8YV*`fJChmHRBMYLy8ts!_5R zb|Ysh<4Z-`g~`!3n_@RX0SIt1D*B0 zwah{bIKOYzoFGk?7jJNDPKRfHzY${0mU#15lJhM*W{eb!i^_O{u4AhQrdGeo&Y=Yb z!G9aYRiXQHI~(^ByEMDIt>6gu#8#an&0-1hT``8*xw4@@7REA}$QlU_9T~{k>9M%x ze=Jk%i5*Z-)95^Przz1DWU@|g(0TF^o24V0_4s(I?9%^2e0%q04xjV`lXps5wMTsL z*5{1!{VY62AKQyF1p(pq*78c*=13QO2jV~);1w8gbfaR34Cet%{?6|X7XlL~K)#-K zFi@%uPnT_HNCOo$$^A3TX001Fs$A*3#NHRwSu_n!I}L$0f=C;oc*=oaay1Y8o9g2= zLe@b^x?h@!7kI~3#T|g&Qy@lMucT)(94_d+ zS8lsD5&yTYMIlq#RmVAQQkNlJbKtRa7LV*a{fI|eMH)Bq@Nj=tfs06ZO`^rcxCsl#K z0c(2K@TGK{FFggy5lLsX=8!H6rChq!(NXN%% zL^JF&jJIk2jT?>uw*N6*K~;evb^i)*eGD=|RmaXIEMN`o*;cI9t9A(pfNI zkFc)zL;C>sV-z@jp$fz@b&Y|&C{8Aw*5t;~T}5*J@k|cGDmn3EzwJE%wBN(l7bxsH zUq|@!=KUc3HYys>*NWs}E0vKx1d80svCZ*OloF=-XfVw@6t*`WQPH;P&uL;2&XM%agANUE7>#5*JIi z>whYBdBaMXP=U+o5?e$T?xiMXCTq?72_i`|Ug zH+ENo*7bnSY5ECKk2lL!nGXFmA`WtEsgTkh5r$;?`{NUIu?oO8)_gPX`>`d`eKk!1 z%8pOESC$wp-}eV}+{NkG^Ye8`SO1YrVw>;DwHof^&b7IrH()iU!9=B#$Zl*sF=ev! zj;@#&0vt}4w-l#@kItf35wwK_xUa z9$GSnJJ=;x0Ij>`_WE)&gSB;jadrxEOwpaA_^zfm#iJ_t>p2h*}^Ko8G@h@`Lz zQ$l7FW9zg9y20GpLmT)ZIM(TmC8D8G0ici%ISmisO8@gk68noiXVwCoz@val83Wq5sBaY;>(CM^lN1#iHyjs(}fUaU}v(lcA zNkzva-3Z`F#qdVRsm)2-!pAcCcqqTI0&a;z*tgNL+Un1Kdp|;^16u@#;r&hZUexYM z$NNowZ9-AD-aBi23@W9GI$i%DfWP(2hp#7x0N=5V_s*gq8_F;Lae#{o=GPT+^%!ZV z+V@t?EDa6aHt4;m*K~h+RV_JX&Ze6xo^ZOHm_ri;>LiLZX+D@Pv;NLl$I3E^Z>U-% zRGdw9f&pHlj)Joya!LIj5Q4ufBjr{@ym>038jdeYo&{#+eHlkz+j444Ln|$+pWamk z)ghM!blmGY?(n32POYR!sF*BPuT5l>HtkboWa)K4!61s-gtRPqc?&PJXPg{n2SHe3 zrzvl>_7OrT476|1IJL~d!(8lI&WI_yVnxJ3shGkk_%)Ri! zZKP4=nxNlH%?_(o21-BSx@BR3%F2GxpG?Fu>e@UH0@E4`_zp{?dg*3qJGNSe=w5XM zk{z3}2%?$kVF4O01&z2PqPyBPVw#QY-iQyY+ribF-@s8m@}md_l0DH6H#p}(Yzj?3WNgdQX$^}8}{q_%DPwsBM zl_hA&{$$o_`PR%cC$vO&%LLzy(5@FA1xo}yEk7);{sz|8 zwbpicfn*2URyyq5zn&5%=Kb^1lo9ev$x#+PLpW+n3=^5=A?~H+Q8GS8-$0`^hwbz^ zxlU^&?@RJw3ke_SOkG5`1)$JoQxcZns0`9CF2d14Mac6A0~Ax-C^_7j5%){jg8Wmz zd6y@U@rrDqfS>w?x*(e1Kfz%b(HWvkxHYHyN}>y#UN#}ZBYU$w>6)W6A*bW*1{0Cm zGq!K(Qp8g$wOvWDogr3eDJHs_3O^s_MM=s{Hw!7KqJvebu!Rg0_J@DDIhF2B-tCsvB$$RibbUx%q8{Nmd9xWkF8fYn9!U?fd{#F!wY}JKaD@AEi6E|MKBM@jN z)^;{~-$CSg68Qf#;myW&?yKKvm(W5<54)qBr3tw6WK3@9s@f5Lp&}=bo#lL8n zpI{0J%OaUo8zvXh#?kH_NK3@7_8J*W-2Ii)wEy^CqM&SZ@l3!E^wq7c!^&jP<71Ll zmtXylK7|AW&q$KwgRxA(X5KqU{^Au_y{R+@j>f$v6P@UVEZJyM3d7CY6*pwOx= z1{mM??$cKuK>;h~B8rG@mzu-D)C=ZR!9%-z7}Miss!b8?<|_&N6-i^p@{P*FyK^CE zAP?fNDp)ULf>~cj%_RjZ=cbU%fQ#U#3X6A9&3sB&NJyCZ$5tgwM8l0nl9~QrS|iY~ zSS@)&fXuSuG8qlh+$)hBQjP_sderPMUnkN)?rmusOCwdw2QI#`g-0Iglovc|i)}<= zGz&GRmdh8VSL6KYr4V4_GIyCU+e1!!gFL?{#p|lK-9R75_Tp2L!0lNKLGQlk4zMRh z)&NT)Q4+ndePEz^TUJE|bv1RidU@$8n9O8BW$Px0box@b!hU5)v;t+;=IPaZHTr;w z{kurW@6-FZC+mgdLRIKvh09HLudKyIxzXKVT*li(H#7BkD@Gm2L9Y*s;Vx^#<57X` z(QR2O=d?t@lKUd`zx};>OdeWd??k}HR&j#1KO5>9T7DOD6|)!}ZSbqkpjpW-4lcqZ zilfhoR|eg6E~kI)28TWD_El#2Zzh`zOAKLK|45f@(6%jw3x7}t$+&G)NP~Fe`B9;Q zK)%y-g+Sqfx#+NzXWS1iB++ETNkv1r`*f%QWB88HGhLGdR5 zjm4&P#+jEKRnAkrK`V=bi^r`p3n07=IQ$jyl*yF$|b+8XcXW>POGrW z$7$Sx0dRwJn-Dz|IHobC#}>@;vbj48%qf?|K$*NU?9 zWE9&sPcz^KMK3=5z%rkYwtbw9V~V3;Q6gDbHk4d?f!QYYVk|pw!tw5@>^cZ0P#4P@ z+Mt>(b(jN-qE>5)au3H{9SzxWp;%wu82-A?Fvzu1#~sv2Hz?#P;_g4JG?gK(+NEuF z`10`$u!5kz>639bvv(_3LZQfl19M`7^!%sL(Lob8RF2IR1|M;4=o!A1W8#JujZ^ji z1r|12^U_v2k_#`&V2>w+4IbW>T-_!$hW6t7Kw+ZQwi(>pmf!L(j~T4JTjN{bT$H1>rNq2*Ak#$}(UhE%Tm(U|0LGg(U-ui-qpTTiev-<*g5Z<~~PCZsZAg z@n7)Dc5!ZgasI&B8Z4i&ct-Otdzqd#`e!;%bWQ#QC#3n%II&cP+8H`7gzq|+!z+TH z(v-M>+1tW+t;1`6G~_yDwN5M8%lgp1k$GyZH($XpsRl(ETuL^Kg%g)aXdO_q9#zMv zm3Dx%Kw0}LO|3fSG|3M)B|z@#jY$+WmKQcullZ$PT9YCoLvE@+aWl{YB*UJB+&G5? zFYE>TG0@81#n+&nHq@tBvs0M#V?un%%R|wZu7SwZO^N8AUvm?&b@6cN-0Xw8dJPFS z$33aK@uDKah~WwGM!OX5uqDdA1sBc%Wle&d05_IWZ>q`aLyWfA!gU*g;a*!W<7$4n zsQtyvVnDi_SBBQLw)_0ovNZv?!c#U2#yK6y4w1qgAq#7|5%tW029E=7yK0r7Pgw0} z?>P04lh4a*D5C9j_v5}~TB^hX#YSR?FG>1gw6SNWQFj%vhLXve1(66dTgLI4SOlMa zR2bvq4XUu7eWq!3_?p7qnJCDeWxy{go=3jig!3YFNb|p;I~id73})hP`b;nPCeK5} zKTc!FFU}4H8l`6H@I=aY@V$dYIoppkoB(11y^Q)# zlvji8Zm4oeWnNx8$A%04U2X|Dkmi|^N{<2cYJblzagG)incY=axnae zCY{tqP1?_o57SbQBp?hcV?J|WDLm}PS?_%H@|p9xZk4QE4G?gge?fhtD=r@&&adW0 zHyj-r#ifXk(7#T#rc>;xq@fGe-M)x3np9%5QPg;ohW*Kj)pjZ&q-w!5ry}5Dfu(!v z!Xs6RG7;wf{)JJ45a=yP1vc3!t;4f=k?iFvLZi(`+%-W*M@s?t?K zCQBJQmWM|0x1|R#ij1b*EZgdy2q+;8O5Kb+j9_w)YV*yZu5Yr6YAY3}%u6VEppDRGSaSZG%+4Ia+bMsWx zNT^PSq;4bY0~f@I2b>6i48@ncR{wlOfBMIXh%gcJ@f#XYAPgQ-$Shs~^3+aHj|4aA zo|6<&-yHViKJe@G@**GYrO+}2vcUxCeon&Ta+r_^cRSl+9M{p2?QVsb6O{dVLdaxQ3f!r1Thp*33 z@Jm32XHt&4>Dv{GEMxH|m>Wj+%-c~s+5C29sS!}}cIcE&iRDrQ@bcB#2rXnK2Lj!42WvOtOq4bCW29U@H`O;tVonx>gs(0}^5f?r z7%8@hbo|pUPNczC`9#BT-r5_NRZYF(5)ey+rIBw74JI)ITGt;w8B$zyGw}*7+xjGC zw)I@ofSks{9y&S@RVCk}HX?u+C_^vStIAJLOSz&tLoRT5C{|H z;r10a(X{y#I;u&rZ%XSp9J(u{FkU&3y>qadz0gs z{Mu&GUgF%bXFxc#S9v<&7cB;E(}VKj5)ON7z0!|JoXgDg`IpLTUJ$e@E&NbQAngKUe z>T(;gEIq}%!8ZkcH<9oBe`&rb@k&zPT+~a1P>gx~HPw|~UMuk{r2A#WG`Kov4Cx@Z z)+1|xWQ8PCWs~7fj1ikWs#gTQQixa^m(|AwvkAWcYK4uwn84*d*Os64*Id=3@M_AS zqCso&=l4irpBaP@-853)S=^sY5mPS?iMGuLNnsx!?6XQ#5r3l zA|a9Ka^@F_ymK>gtHQ-3*B24Uc-a*;>TDAL@EBo+YJLmm)nQP*?0j=b$K4=F>TrfntKMSsTKGPJ&i8Wd{{Dt8 z=E;^7DXiZS2xZ&kCf;=%Io+mG$Gls>Sl3+N!{? zj2+9pv)b=6B;~(T;W??uA+t~b&^Zk|e^i_5EQShQ626q2TkzlZ>KjH<(#4-H z?hCVC=juX|NJGPJNz6oqJgt+7c-T%HQ4z5d%?pdDNJFa=!Tvj9^uuiU=XEBb@hdo& z6CpPJPDMF|!Fd`BV!B}iXzQi8$){#1D%;Ljq4axW{2VY|DbSd5#Qb6$c50IvocBa4@br(f4?r=rKyjWN(1r~xcAd)JgR_MaAYJN0I zg>{B4>@IU;f`xSX(RF7@HfwYIyUYOz%|~6H-gpJP9rqo3e3FVln%>kXQ9hc-P4Si?SosZ<-<((^x{x(0U|2?rXjQTB1o z#3qO*=z|IijW(@IbsWnP{na7+j1m6p{x;a7032xg<>KawoSD^krfRxXr|+>yEVFhw zbi_vASfF{cTIa5HvTVmTf4j9yG|8K|r14S$l^(NsHM9TJ)uKYX< z%Xz@Z?m_Z@+ zwpGy!W#mGfuw+g^QWHkgu6B3d8m?Mf+2ro~B zC-o~fmDd6_dc?V%Kh?I8&_QA{wX;o~o&+hz=|w8lkK22cWf>3nNh>dH_k2W7w)ao0 z5(ay)gtAIBP4(X&_*!Dy%$HN$?aNz9!@kSgwmv_@y*7ezt)2v(gwdAoq()H%E&aQ) zFJaMUPtLRWnJlFbR(wdA1jf#}9+AQ^X6@TY9)QwuMvIfE69k zW)JQv<(K!C(#~rlGaZ-ydV&O$W{=V+bg_r*cx_BLr&TU}n@M{m)KOO*Hj}4MIhGG> z*I3Lp;B5uXEL?x4jyt122G#CvwNm`5aPFJqus=)r>uOhZg6Zl zFMX*TM5L5LcpSMBS&vK!^ySo~ugFKoI1#UtF>1qt+3c-vfHg>+Pi-s%6dFI8l%p*G z7y0!QnO=qPkRUwcmw4?s$^?u4OfUNUonh_Q4_$u(uP7?5Cn?}7;2YB0d>ljy0nkzR zZ@<$iy4dT2UW(SU2XD=X364(KamH&Ij6JHNHM`CBjQxL{kf0L0uCl9u`(A8}RCJGw7?eMKxKJa{~_ z$SBSEN`C8Hdlr(O$8Mobl!S}z2qu|0D`Vf96S zrP>s_#thOf+R>dC{$(M0#vP56*TfyvXI)>ZQ{&Hx5}j(j#db@;Qk;t4iVK z=$RL*4CmFXg6}ZV$agKidNU!_Dq{upRX zGHvvF%B4ytLmQ&BJ?8{$65sEl2!@B%W z*7e9h;$=1F^i>v~s1hT!>+<0Dt3APqdWs_ty6xD*7tNc7!Uz9b@^&enjoru1n_(!s zNpt}cNQz8Z`f7zo+2|If;S*8{M}SO1nCOG)2(3KF+$_HUIaAVOC#9dCk9Sc6YRSnv z+Z>$f0sJgmXD1zi;#3QcnP$ToKeRX-611t880s~#aVi0KKHeipR?r*Ol>DOqmx%9b zhg)9&fP~Ly`%PQ7_8+le*;jK!V|$BRW5(~+BrM7%Zqbyv);fi%0Y{ur6*TJ7&ZLI^ z!yc;z{F3z~A!fv@Gfka6uey3CrI^B$vx>V7E;rZQ?0i4F^gl9#B!w$uliPkMe44fT zHvvEE{}ej<8SnzO%?rZ&m*c-`jUvZG6H>-dR-VeV?+?`AF?ej8m7Rq zgWO{W^;tiXo?fkLyjD?t{FYA*uXEDWi+r&W1kCIyb$Tj_LETH0KRs$XUfS$0oWkr# z$ODZz(rpMiU)@Nn1d|Xi!ncc3baqk!4Sx~iL-HWCa6U7rleCTs05Hav5($(z3Uo)y zQkR=EzFvNdL?X2mklh{_liMeabST{-qH}_mbE#dwMo93+y}sd#+h|=5VC{E_QvW*J zWesZ#ISDhF!;^oA(@UHc>w&_5K5~lXI)^J6@cryZ1m86`S^ATJF4RvGv!N3D)KRE} zg9zB!=(?wu2XAdFgJ7?E*UC-&)u2q24(Z|H|6=YfgW`<4ZO;aRdkAhpgS)!~cXxMp z_XKx$C%C&?u;5PP8r&TkyPfx(Gq>*4RL!TUnr~fCwbi40uk~B|U$iCXmVbmNLYI)( z`MYmZ>*32Nqf1^>(H06fyjehI0N(G2hF*{1&PCU7RPh`M-|I!_K3LKS+3>XKTJ&W& z&dw-RX+sX6iutd<(q4uRw3}9{OcsX!LFuO3CL z$aM7voRpD8Q}cn$|J<}F&e?QA52;dN(gfbmtx!G|55T`BqX}Jk&}_za37%($Zpjbino2 z^5sl;j4?hK1~l0#33f4YngVT9WSm*uZa_RO8+L9DDJnqflAAI@5x-)3xbe!RhyxdaGYk<#2y05f@1FD*t$H_vY19Kz>0FrH6mrqa6`s4k0| zeh8*WYC7s$-S!kuYZXyEQQu}{xVMo({pwH0&qj;BpURgsT6c*KHM>;JuUm&Wnp&u% zFR&=9I0=b7gMQYU0qvQFBs{fqSA zLdpi~R>B4;P?4iGULko%H5`_$J)cEg&Z^;4axH`^#gx(1DMcr54vwKO0Bt=IDibL- zNV9+VI8i(KNfItF9o;%>3*^`fHND-@q9WI?Z9T4voXLD#jG@JDWAVq;R4vsA(S);{62qjhOPE^02F}SLU zA|Jep)(Us0QJ@6YxYEr3`IU$2?Uhxald@&2g8hrB(dXsq_0uQa-tY{tP8Sk&X~732 zCm-i8=VISD98sA6R?KH}aF6qd$2n{J*b9Wso_^cY{w(}IK!Af5R@9;H*_p>!hnMr2hJok+;?p=JoSIK$b#6UX z*A_i4)enTnzU!LTA~2IZ@j__Mf-zZLf?<%dvL2_7!`S9luf-Ijz=6|apr!sewHsXk zSpoKnRX-a(ef$)&<^Rwe-LMS`Z?X#O_do*f6SkBui`@`R(X2s(}cPc~eP zZtj?W=P(oyRrweJ3An*Wq}5p|*Pin^?bK2ei$o2ku9SsB*x z93~b9XRy}IYF?ea?}G&L@I4IzYU4N&RkUDVV&c9BaQe?giU^>6OahqLaH|?8jFk*z z#I%%|BtW5}6brWOa@gXw8{6z-5X4e~ZN|!Sw8HbyUu``&y5!BTmFtIS&D6;fSFf6# zz81>ngFQDPA3DZ_>Sn19O}j-X{B`eTRdLi$Bv_HGM-<0%*TUPohgz-msb3cA)ZA>r zxt=5EPExaOqy`wqWbao$2sTw#`{GK##r~a}2=0WNWTFixLvsZc=UslyZXB<1)@u|v zbTKB&u`g+i$;um+KK8cm+>A?X#WU}VktC@a@QwPYF7dW8F)R$h7C~xGd7Bu*Be8$X90qzi=mF-)vIUWPZlh6~eR((j3jv6QnizO7{L- z>uvx3!vE~cR&aJWWh=GoUhW`!ms6Hm$*f;Ma7FocrM@5dxQL3ZPu=KQzucp2u2sUX z)78brmSS^iLV?tZ7+Y-u0Gy%%P*4>mq|(N{bPqJ@dOH@F+fyP|&*1;X*_uZ_M`BCy zze7Qg-wW~K!v}$FoOC$xZ_bGbqZ6Xm2h9NU$mL=mkw2kcFqtc~INiVAb{2kPeH1S4 z+Dy7i8JTMk4w})&ujAadI@A3t8ER&eW3o2@+UQ^(_jj8H*sBMx9$H$bvq-9h)rV#Q z#J1(?K@AO|?gP7|jp~7pSJ1UC&R z3HFtvGtuK;4srs7Dn`^knuu|3MN|3kffEXJIqOT5omIU@5tA~n8ZUtxyyt%yt@uQO zesi|$ zorcD6n4sI7T>eiFvu#;tm%ouBGyVbsGHIzxaWRm2{yQ@2`Xt4h{?C}!xFE0^f$sjg zK&BH}2L2@`0efZc)LH%qBXnC7+n%SB-|l2yWyl7;mtn&IXI!I7g;p_zJ3OWh&^)+H zsE<9aV^v9nKYW<@!ttMo+h}F>LzNr2sT3ZM(9>V&sF}Gy!sqq@*YEwHqs6QD$3_$s zFVP7L=7&m?b9B+F+{*WAPqgBsa^%_w)!yaq!GK0ouCDo*<(Ql?(4W7Y;EXYYsaoMVg8rxeAC;YqOE=gj4=W5@`{YAD19$SVLi!E`c=d{ zx~E(xN~pE*T3y1nTU3o;%Gdnyt0_Y4CxtnE5!Askvk7xCw^Uby*E@}D96WA?Y%m0F zA;Ic@>4o>zT!2v@qEE880(#3$?$Q8T2>Bh}!pG{nvYtPSUO5DuyF6|-@kbIhUG8h8 zdK6`89PRqu@&cUqw}zFkhG`QI49IfTV&KAb(43Vim6+~An|kK6q3A?*+Hx^It-yX1 z*wFp!x_i1#8fubt5wcW0rw;bfRUR{%JV>*kf!Wy39g3|eAWF(GpCO5@;1b&OxLd$$ z(5sZud2u4vKY!Gu*A$$+Ech+Q7HskLjL1@Es+|Bo+WcpzB3<8Q<`47~*Vrd*#`)-9 zJa5PykkP%{#kx;W_0K}*C(fNad>*0|VbUyVkboE*bEN{Xlw%zU2?*-@3aI}2yZ3Tff7|G9Du4Sh**jE%xscFv;w@_n-3oHK@W z1|R5IX!9IQPJ*uM%j@cHo|z1FFcuDQTtpGVxH_D)l=R4RuIne3o1zBsGzVeMa5)LzP&qe&Mz660OLFDng|F04pDE zNB}5*IxXgf-bO}%kMFj=k6mq=3xK=vl{lL3u*ktU37VXM@ zSH=CvK@gUoK9b=?C%%I&ReJx1g?={=>&>6`kGU}E3w6?EdwLvejh{ZP)WHDJ13WCB zg2!{jwQzphe@lX9ylL(Nx6hNH9l0@xx1+FBm(3AYFyeJ{rq61{#OI0;T_-dmo`b!|3inC# zQ=OCRJovB7gRfHsH+NjgzLH`qEq7e3D+#C|TQBa1;*I?TsY*X~JshKf0P`;{*Qna` zvVXW&?$hO)r;Gn%cy1Vhz5u{5UtinG#y3rhosEf5ae#AA%=H%F$E+2&QM=(M;UaO7+UrLO#s_XOYb1@n-8pGx1YpBDau#pY4-?n;>W${bTvb+hcvJS zDCXw%)E}(>+dCYGw~}WV0aoR(wDDBo#HSlm(fP&>~8(ea~-KFT&(8*93Z1IU@hz$j$`Y3Wov=?-c|7 zT}VT|OVV0~h4b3lUkN>knX#>7Y#)+VOyGE0v4YmfguoTJpa-5Y1aqScA=gb0<}5lm zV$1T_()LqbSAJW^-Zqle4$e66`k(TlcQCEAN7!pgdzAi)7 zbmYyoF6{9`&#V*wMaMa|JYAdaBAoE+j8L<1uQs70qhJMT2jH(pri}M9pX#ZeTRBd^ zzJ|mBz?W83R*x?|9fpY79}{cjz{aAw_rPMT2++}T>?~}eJUN2|2ch1H*&lGG+X44p z*40Fy^Qj?Rp{!On3HX%)BdvbDcIoMh?kaJn&O~%)VM`|6hDPu??I6b+20E+S=D(W2 zW9&@7R24NaD05}SpJ=l+XC|(71!C4l^ulkY`&wbLB^!6j3;$=-Ri%jS_kZSMFW6i> zN)G9R5w)E;$VyqXi&hB61yr=VzMA@7o9-C9Mcgi%BgA~|ZY4rDi$D#17xFBt6`0v; zckaOb3e`8#Hn7xoB)$mXTfwq%4Mk)4Y_^l`Y~u{lG+;?X1GfNTO%AIIcZM&eBl%;C zrxp_&D48gBi_Z*HT}U!O0YGch#sht$Z`??N9aWcrt@$mjpwc z7dcWh#wf*SO=~I;HA-wtyEyK%Q!h@A>0iTc+`cq>RGf4_Fsko@2&j28%D6gHbmvXT z<=}*(2pRZC5T0`~`^m2Z08i~LqlM+(RaGy>!uPU7)=!?@vu^Z%x_ms#dIe@ScWnlJ4ubuMc*~|sr-+vKzYF5yvD933k&FeKw8&}%r)vp(e>JMg{&R%?AS+8bIFO1% z#j8HdLAV;&zTeJ{4n9PH%|hb$aOXf3K`^duC(GY9Rp%ZLC8V0O^Rp%xb))v8@Z@#1QiY;ee3)1w zWs)yx5|@xmbC$bis$O$CC!%Ma2-{ItRbt>+cFHEuTI?Sz-(K8cT|I7dA@p_#&a=z( zdeQ%LtV-hOli&OoE-HbpMy4ziutl%a2h5^sfy{?_Z@YVBxv93L?FlY1fk3=4@qu0_ zump>yPn()yX@Bc}XZV)X;8@=}#0tRZc5-k5+lU|a!)*jG!*3h&+Z8H9T#3&wwcVkY z3z?!%08zRU)XU`l(Wguxv>iTooAKWz{WCmf&C9zV2ksjRYX*$9Iz1}jN(q*Q_um+T zz8R6QoGw4#itg(1nVEMkwN5oDpC3^qXPZ+OIqa1S$1zL`yqHE^4xVLO0)bPTR-_aj zABvldK+#o{$-K28Zc01o}qHT=>5S zoOMsj?CCCleE19S1q^me$%vq9j3Kv1S#{QZABq_}sz{0a(uq#}!&Rl?r*;Rm2=&jb zFX&O{(q^tI3o{Iv6TgFmHHw3S$+MnWd!l~XC6@Fqv|nC7=VCYF%)fGRAMzaP9)g@2 z-dPCGE54ZQDtzEszXQi3!a_t^vrenAw|3W5cM_ff+T&#{SXy2jy=tHOSZJt?pOsQ{ z5We2acFgF=Q+s%Ooe!u#*4g0XpCcWHv=BhZJhO{+Nq(W|;uADFzahla-)n?j)H0dz zD9C~EY<|~@ywLL9ROg|Ix_%~tH@_yBs~T7ELnsLUZPLB;L-j{i|4cZf=sKJMlf-k~ zum*~N-)6m!sa^|%<3{5rYrD6<71OyCLF;jOexSNwUG8v8x9Nh9-0`>7?eDDr4_mFE)_q_r?Ns2;wvas(o5tkalfP4k|MXc>N<9i@-{T#C^`CaeUK*C38EvX5ZZypay*vvYy--vhKTu+jViir_yW zZ;Qar?AH7q$HuzYeRjN$t0IL9v6>+Mav~5l+j(C3QZ;PGh<1K2ot4Mw0O{%FpDFF{ zalDuNlrf&>XZx+~!Ij4N!&fuU2jrvS@e`*R7-jf|4vhV%K;e3F6BoyB6F+|t_V)J5 zU2%D4*Rl>6QNm6v#`{${r|R74VpqNd`Bks~F?3<7=XHA8Krl4#KF`QkqtN0TsTiH0 za>6G2b>O)$GI-g<67i)oiNjb(K%WMSqwkn9BO|u}*EVQytc1XJOB%ZkX7Me)wT2o+ zCRAS^M9PTzK8R=N8)0`{7l2TFef(^AiIpV(MJfJ`%wi@YqqwjhK79{1W}3tB;$!)N z%42%A?M&Ea31o*I1XOEBnSeQ5|0$Rso)L_0^|3SiBrOV)F5E6wyKN8;5mU>?BvOxA z{~8|t!r(|YV8OY+a?8b@zl^6byO(1};~GS}$kaJYD{@f1K6abg53v`AT8l$)6}vY; z6}@6{?ck;(YOjZ_WcPGd@{*SF{&lk$_)$qX^UQvXV(eAENjA~Zcbx18YZNqI;Swv( zToT;~WHbcbhS|`6f(#P+iUvpdaoNiN_|MBvza`PCL;h|2^m`=G^1t690Q2331iT3{ z=!*HPHsXKY85{>OtNm}2&{toi@FkIdAA#I45o*HvuP-HrDs2AGM}(em{y+W7ZG|Q6 zLFWcissm!kH2PamfHo1YuNf<~wTXV>&T87#%A~2-w%D2=L)MP}I4{EJa+?QMBAEtP z-g!AfclLz)>IEl>V?9#s9%=%zKvsR4u;egHZ;|Sy%9=NK27R1M#4xwPl^=RyeXjVz z_-LdJ_WT(Iux*nE7oEBBZVh_zfonXS1Fo1={b-*gEqs47;TM0d?L&E=ux41fhY(|D z)7cYMN`cy=KEM2)aV=)45^i~!bRNbNdgh{%9>dR2j7fnPOWg;(p>6)>t&a}C&v+Ts zWfa(GL2ck;xcKseLu5L)8mF_-bRRF=sHUB<4cP^;@2ZVqU1_3RM+N#kMk}ja0w9y0iX?JVQnkx=t~LRPzQSY zH8Cqx?-SSArqFh0_ok*68CI8eFK5oZS2;HX4{15%<;nf!0cP@#t!M|FtsXRHsqyp> zqRg~F{-KCiA$s-1&-F~!0(DVuWsh_+7E^bGwe%D*IP$O`KF&NurAQxqf%2);qzzhW z(MX$XbD+`Bf24`a-ry^aTjgBP0Z#E8-zHBe^Q%g_RsN_o2-?hl$@w@jpBtB<_@a!C z7s%j9DZ;gq^a7TOk;uBC==p4#k$O{ix%eJ8#l~xd7?fOz z#la*3OOQ}9omB+TgW6Z3$xsQV6D`)JAB(cEa__qb0JPeF+jay{008>rxH#UlP{oPd z_n}x2fJIVZwnJ;kW}BavxP`5U?jox`_qf)fJuG|WwPnp6P>UV?v|R_l=DESPesjGeTR0OIPA=e0%eH05o>9_ zBexxpBTq*-;^pv?`E-+HKi-k?qSyMAbRI*zL!6z{o8*=mjRp!%1Zib_wl01X3GIm; zHfhseB0ZT?%4krOOv67oF?aICY_wZoOh|t zy*ziVEhSAuRIlLB)f=6NN)WfLe`NXAG@aeAv|C`$27c#*RR+2lG!tS8M-Y6`XV7Tx zubV=dc2j6aYu(h%PtDq0BdJ+59|(FQ5q)YM9eDXp2I}^Qy&GOi6-B(NkW5p%(UsXKr zO$##P^~aGTPw zLoVWJ^v?!7)-%LT);pSJh#HD1Iil69*mqdzC?acS-QD_YI=pZsSyIfYsc6D3wre?Ti>_TGjeqE8Yc}%?ye{$5^^_Ccgm2-J0ttB+D9KG45>9zvoA?MVyy5NT7{ZOtXzyom`5R)MJPCvgn=Ebqdq(N*W)9oyk;%_u{tHw) zvA7j`4HY4A?qd}iWR>9DExCfP4f2%`wkJ(rBzEi7ISkafO^7w*cnJDLD^zAVGQQkY za#s_{=8or`>7iGp2t|U(!UA2VR7YIe? z>z-O}G)32$+5l}sl&rjlCroI-QH%~bq7mwP6D|Jdbk)Fe+g$HymrZSd0ZAz75StnX zIuMjNHZ%W@87G7?UWQLB#{it_Z5DP z{+|5=ph0UzuF9-B;m2rqaEiBc@#cPNk#?oFaLNu)_nun{hSp?c8CvG=D7?CP^7I``Mdx;_~RQ#s%hSrBYc~oGWejbLwe*h>BHpq%a z537BLDBFOvgo~amn=uiaVV^%ZQ5b;``y?7vYw~C-S_5ax1#scv#=FQQSdyhw{mTF? z6z>*U0=ecRwSsCgr9KFQ;g*F$k3y{_j4}L_&p{#>2?=GQ>SScT$s(v_n4c+j-sR6I zkFVyVT;*~KEe`ef^T1(Q6 z{>W}$#}2|0F59?lJ2n?ZY+nf0XUuSYy)7%A&iHYnOiJN3UJKMf?LZiVW|)7yg6QQQ zZUPsmyfQ(yDL@||RUuO!%^KgQneHaRM1`CJ4|^2LUmH8xB0dfZ=-{Vti3}OHlptr* z%GA$2{{~?3ji%$!21sZ0);M`#R7j8h#=XbUv9f!cP}(nMq{aykf9SUKoTmLBAeVYD3)o_Lx?zI2!r*C8zvSnc~gez7+@;~Eq@p*Jgt>F}n0sh7! zR2qx_phGAf%K4nQwPjwuOMBu@BXVjc`ppJkwWB~ga%@u5)ohj6H`;D2?9fR%2|^1Q z^Pu<>)e@?{goc^yvIb*vZZvz#WFZ0zl{#bI96qzaYq*SL)!cmOS@(>E4HFjI#@^@=0doT6f`Z`?L0-X=~E^z?_& zbD+h{^bxRR_XIIMj)xtlb{tP&C+l`eFrlI1M|}b!91A-bF2y6nj4xqT@Bbq82-5_0 zH3&AluXA!K@6lqj;860czm|aSWRV;F5@HuEEHZhVl|C(hSXbjzRQ^D~#cgg&juT<* z+5w+{G!2eV)5q?L9vTc zMTo2KbpSs-lp&6gafRDZW#doR-|t=46pjn3>*McpGM>rscmmC|{l7pjs2yD0pOzX~ zX5+0AIUE5^Z7gOM4;D0)3NJK8KJkbbX$z3hZy}w(i_@t}1mW9?J=U3jGT;vAcGtZc zW0+=tuc*$GoJy&j#I)n??Ve~(@6p9oUwi-4V*Op!(<~)2Y+7rtqOhq8GmW=D@cmDA zO*?eA@`0~V`Eyuo5@h~D*RI(cL{@pbi6X%$;Zg{)hiQ+UQXLtuoKSAN7df6b-*Wuo zw(c^Sg$JbtKOlYh;4`S&18VIy8`qMwBA=>fhyAD58~*rEih`uS;OQO{VQmKAHT~tD}ux43!M%U%39`94pDaj42W;b}~j8PWk zOp)E)knzt~Ak*J|#2ykTq&w#um;XGIY&d0f?B@Iwsa%3f2MU%1X{lZbJe1hb7)2pw z+N4bwnn|Lt##O*IrheNqXt_@}z$NO{(T(@x++H$)jlst;Dr7?|%)eYcN<%@#CJB`{ zPoAkUQ#TiR_>Jgm{947^J@>$?WMd(MHIjxv-o7GN+zUkggi-<*bg@(1B6N6(l|hZm zOL(hKnPLc;yu9b2csAsqwu=Lq#bDnoei8Qe@40Kk~f!A0OTT zfq~p#x2wwR_67g~I%=o+=AB&<=NwnI9%m9CP8`{ybCMGfwH--V?$ZiTy=s`OkF775 zpKbzvt`6uX?z}`C-U*CW?9SEixlY$lG%ULp+weC*8ZlIz2!U$Sm*@Dg6r7MDd~sdC zK=Lh;;SbOHuD11aAujAHJh~#yI)-m&$p>6uJi%jeXpxhFb5cm2)0*{gHq9430A@b@ zyc%{VZ3j>DOhz`6(xFdH9kYnt{LT}zP!vs9&eKSgj=}4cf>Vk+Q-1n$a(rw|!o{K{ zQsnFkz%Gt}bECX)7S-l?FvaCq!RwomQZyYCjfah(NZ9lxpcsL%B~&!(TWJaG(wY20vQ zqN3o-TD;7v)6<$aUJLwsF|2a5I&VqaIVOw4DNg(Rsbr18symy`D-4z}P7D~VqVwpb z6`BC1!N>n=F;fdA1>tpl~KojS3UxW30-8? zBLOqZ=kUh|U3}3(lrLZb>(Skq`TUb+FZy}%CKhW%hZz4&SYa6iUa7JD-`H}TVGTh* z4DErv-)8$4dE&EKzWW@@wU+Aelfr?#N|o!n5#2Qc?`Xq-J;5TZ-PV6X2vD~nYl{o= z-F0UeZ`EoQsq^%pgD+9R8%KJNNM$}9KR_@B;gB{l}^nk2-`zXye_dLLKGc6I8+ ziwUdS$ZadpwMIT}M61)Fp+YgS!DEO`ke|rz(8-DJHNXa7`lW^8|5P3ox29Bhy~+}S zFh&->mDAa1P6|>xQ%} z-qqrenHcp55E5%S&ZR5$0C)4kkl&Qa90YevULja%|6ACEn-$0APcJZ!9nTcsmK()2wG(QfqmSn z>Mun&cZ`0dZaK!S9~q5zXhpVuly&dn%?BsicX&vPnxI2}=SwP1(-k%WZ*DDAy&8Qr z2;hQi*<5s70&RvuHxVhK^xpeu>s9(>+lW}r7*)Y?eHh~?p$~^9PjRtj&4T}01)1V7Qm>LVzmrFXk$Oc&JVg;iS2e< zeb)*g_A#Xd+LR!^+${Jo86uD z5&SCYL79x3k2(d{ZgeF=WHWkiC;PACt2agx*&Xf9RURZAn5M5pSj`j$uMB5F`u=w% zhj?ZJIJmnCY_2__`fw7KaHF41zEjc0_)HMLF$;&m1mrIjg3rz^1+3T$bH?`yomdaw z0m@|EWZV(eYTbRK1H3lT0?@ONzo;P}ARN28`mUwJ3o$VAuX3O!tG`k7J#FycwAJrB zYm7ynyF(y&28SsnP^WcI(dwO-(kMB)_MN-ip>@J3^6Ouj1_~IOI=|b=ISc^nRo!9A zq@>Ttsf4?qA1A;O>ECHHnoaovb`cTwWC4#_QJ|8?cBGM27lF)>x7%5sxgP%lBPx zf?s1dIX>D>eMFX#Ky?i;s68)0*=b5L+Q>$Ura6@pSu>jW3xx%%WOEVqhROh24GJZ+7+qdPI)L)*k^)F^=GTp+ z>^DKb$Ck9&)|@UW(btx;$&-*lJnWu{XE2)~A8+ngdTFoVI)k3DdOdabWB?L^PSaq1 z+@!VYaTRP&3x?$JZ6eT-iWGFg;j9rmq>VWl;BV>LNL9A+vf6oxyEw6VJoqMKrF*u0 zZ`S+-L0=*ae0>J)X8)G;Cd-z+b0#X_ePQlN_R)SjArd#?%DQuI*nD8ZBN6t$JQmFI zGv|+~)%{CM{)9!z+)aQq129m+p7gcdxf^VK83>m>YDRenmr&Y>nC+*YLL(MO9QJ{7 z-;>7kp7|c)@ciB@iD5&6$(ZChDBTfCS?j zeX_Y*vC1>-VnDO8nO>+hpY?C^V>P3RZukn_pumj*m(;noWqyDd9hvQgu*0VZckG%R zO=jj>4W-Db$FsIK#%ow>`ZuRGrgZ`=6Ea#ruFtP_!H%h4q->x&cAAFMwJPs-O z9a(O>4cK;^rqiF5t!GokJ73bhHBS36@@6XofH7Fq-oZ+)&&IU$1Pf7&ykD!ejzy?B{PJzK}EEa>#ai-q#r zY97*L;+A0V)v-@#TMfgZ(s}}oF7>iQ=s4^R>TI_@OFeiOAo>=i3btp`y-qxXyJZSG zoXigP{-6iYgh27Q!qgvp)H_*HC-%n2Ron2{tcV}k{L29u0xhbuR79lThJTn^j@&WO zd7OW^>mY`V=SO|vE^?AEJahUCse!t$j77g<-bNTmkLQv7jb}!OQS=*}0-xL9#7VRu zz@*5J&Xp$n0ru(ap!_xo?*l>gYi{9J!e#7wk%rBU&q*bH+Iw9okS5~IkV z4^Ttpaso;@F^Wntl|(^A_%RxS4$e@k$`0!w5s$aKTm~YJ>`>w1bSG+j=0CUmf#;m2XBS;10s~H`BgKimq3r>IJ_nGSoo*&Y7l*!zr zGRq4}aT|Ntl7-+F^{dx6!S2X$arMH*mVZ04 z_!AyVJv3@7YF8@%75sJOo_8G&!+ilg$pf#P9r$6K{If2iV%Vmh88tVD6PZ<59yk0( zxKozv=r|tPs;<^k^!nDHe4_>XKu}JA-9JPO9(1P|U@M@QkfSCI1NER}E(c>}A%Q?g z3*^wE0@Ptt&r#lMXdX&tx1PsP2uZA;wEk8W82QEi$C4zT*n%8>O8eo?5h~-iQ<6$V zO(hD=)R87ZKMxFP|IL+4Vyfr0Cq?aXCY>mA)EaRG;?OK3buPan-{4)lBS;P93`=s2 zvbX!^%eC&>kXVSx&yW*oe>Y;8TWnTC*5)jZYM64GnouBtIJtv=N~Rd=GtyMGer-M& zQTnJy>C}Yroos%`W90bTfrQukO|!>Kv>e7JRRycOfTJglr3G(i=X0)puEm2mb&v_h zp}*&HT_u0X)*;hKtzEr3WNdZm(arq*TcVqd3yre}l>FuJ+6_(PvI(V<>vm8lbgBhx zR|2IBRrmJI$R8*zpg$#f)ST0YZ#gt-u~7imxOshy z2Y=iEPHP5%FrY{fE{745%DAK(s%lt+Szz-Nt|W&6NkTX3n6>#rgxaLK`pr}P z3ef|{A={OwLBiaAyg{uO{IroHc4`tkV5Vu^Qh=QcF@?7`c(@vDU3$PcXVmY`Ad(;f zfe_r9S29q*I(iy`uT9d5ET*M&dbR~+mp;t$=8d1UZA-6TfiQ4?c9gKoj8w zA$(XVBp88EMLtj_8mN_45r4nEo#=XFp^2xhVvmX+nMm+t4JceHyiO5UOCZtfw`kma zT-GM&FUWn`Y30tUoTf;vu$I{cK1KQo4r;h`Hj9{UGCWK{-|!);)VTT*?bCC|-xv7K8Y;H)HBf258Ue5*hh9GXz} zD`48KkO9L6)y050%mcmd&lmlrEv)1tVdUVW96-fmrg8CBa745B3W}Iyqxe$?O;2n5 z+yq{r-tO-dY2dI0YU=0dbnUEc3#@K^#ieC6@Ld$1pQXj}SmZ`#vRt1+ZV z%uH$UriiBXi;#Ej`iUK7_x-*ho=8iHDD%7JX~M0A9>du>Ezc!9?@EWJG$Sg%1u ziy-&kE}6*S_F{YfkZ_!%-yYtE;groJY@l+AA$f@k?eMWfX1)6E^^V2wOxL{2FWdHV z#V)g-$1Le9$@8@QiwX%*M_i_{4YgWmu>DgzgQG#44xeCmG}i*x`0%MJ113|i3#^d$ zMQq3W-6MXr1X4`5%ddm+Ta1#poZg3Gpc0&r{(T1=4(9qfT|Ct#d5LgX%g=5nj)m)! z5TnIC8QN3eJZmLlXV~$-5rj&ujMM*~UcMdj=+GG_zpQ=0RrIp-F?8RmS?$!x#L~OR zQ(j)LKa${SZy!>$b!+{w2A=FP&%y)Ivxb$!fP*%65=HH;NpMFWJKE(ilXc_;M911F zRmw!U$G|R|n->`v?I7Llc*D+n7_ZXiJ zCFPW5e<%gLm$$QR_o5UA=(&h z{04+R-a{;xQgGh^dJA_hR%L;=ZOdA5`wy7GeCS~v@9VCT>$de`-xv1wbY@QE^w`mC zF2UQ%0pY!NjX7yrc)bFnY)*rg)?H^IZKL~;&u%k~wE)&#_j#D`&#Dn_tA}Jo&Q)SA zgGtRly94`lyyEE3z&Hm%^Fmz_W7BkbEbAC`%7n>Gbz^u&F^>uk-(3dI`O`OFMYKTC zE-VLxvkc$(wD&Pn;41GB$zsqvgEZPKx$B>acYIs9mPQ6An9Mq7ZGF{a)&ZAS6( zmdquGY7Z!et!I~%Tbg3ewli+*;~fa?C9Hz(a%^Gu)1KS z^QLf*1~HQA4?n8)WbWbXfXs$BgeZj2skXUtcdrcspKG2?iZo?GFhaS|G&~;T18xV{ z3lE~s7CU-B)QIAh+X8l$Wzre(VnUD`{)G9e?^_YpgC92^LWHhSIpkxD>p%~Fvjw(Nu!uB5n#&OGzw(P=+7#PZk>W8E zjaYErx^|(VA`#l-`I1*>40|EchM7wW);JZj$w5%@ z-k3=D+SD9XL!GQ6xQPG!y+->f_0|Vq{X>0(dY!c^wF8qi@AKUCq?fOuRaRmb*IzgN zjRsG(y;xdLNbE`@+Ce0$Jniv3$?*^}nfcSjPv1IKW5a^T2Si``hu(W~KHRZeQiC%C z|AGS7U^Cz!d;C$s%8vN)FY}!73WPt^u;mdJPfL_m=Ck;#{Og8HilH$DbgM+}1Ocm_ z_xN7Rj`2}%Ijw354^NIE)iM4+@NI`$q{hX*`Hvg{O2T45nxKkJkgjr9d!3B}lhIpH z+uC(Wu$>I{eq)yNg8JTK@OlOzy**E6V{3<-SdDdDL7WK10k|>5J?U91 za(9MfZxl!ag}8%tyhZ-Vq48I(9$}1#TwkqJhW+lPB_irTZMFSND|}-3~b;%xr*27&H`tVGdyZ)kfiSeYxj-9@NDF zpS+cBOaBbZ5t_kh8+CXNkU%3+pH>9MyJ$aZ4U_u(8e$~uVyH1(@epOdc>3ld&Q-$3 z^;{0DLTs`V%7NE-!^fykp;%;g>B1}U_6u2Q>h!KyxWs9{CBF73k>(sOQj9*$BsBoZ=t7zNHL%46%V@$Eu%Ih~J z9lD?BY#7h4cep#;F8pEZ)wS8NlyhcXj8-ZImmt{Ms-joo>C8XFTY2^UP{3|W9Q)3R zV;L&t9xJ|kTe8MtNdOiyu6c{(J6s}GgV{*HYes;;9ECq|VbMQ&Y?p~&L@M~?e)R$s zIJ$@-7}ff|BBlBx6@sVEPc(xpmYghQ3SwrlYxmqB*QxlZnbcJFqzP$tJW51k51sL0 zhxcN60t|-SWr1WKF?V%rULp_$vdzQt_&yc?PEqfDzk%w=@|Ff0SNeOY0~7fz0Jcw? zh&ZIK{C2G7ZB#2FEbd#4;Yf9Yr0$5pUN^_^u?`($6krLr0TNV^MYQUWfpe062csFV zt)U4vY?GkVpu1h_D|yTjE{%6ijo%EZc}rqn@VxOJTj6s1%$PazvmTcN&EV;aBGlTw z5@o!5@0%Zvo9{_oq{Lw0OPvD#1EW;wxvTM$;8x1H%6=zIYKf9t)vuUJ08PE$yDnIo zji^;1Z7Y3A&lRj3%9)dS0gnJos8$J%wYsva2CvWMrG6;p7pVX4^aQ6JRdtt_8!)mb z{SQi5Qzh&WVN|v7tSDridBO<@6bpPquh0H7;rcl^u$6?OtRMy4`E&c2BUvA(a7OR=ac(1ti32y)2q*Al$*d99iymHU>Hg% z;<7AT)6=QOvPeU)2+fQZkLy8Vg_f1!o1mUXn7n>yn-x+r0&tzTVM-Kyz16r0#?z8} zz4)5Xa*%`f+gM<0kxtXs=7y}FcI11KvwuiUSF`7aPpN1u(y^a9Tx~gjLqNG!8MzK? zsr?wdO8LhSTJWz%1nf2Bvw8>gZkFMk-aA0uM&NE7cbbYv|!Qu3dD+%Aa8;+-&Pp1+_jD#+mLb zI2$|=mbU8MePqYcW(*i%lVKP;+QLnb+lxhmU^J$W1N!o6n~(Opnp*g1uZ$1lwdMXw zR~iJgPvbgkB)KUCSC6ms$WFy>!}{U7auM;baAT4ceV+gX+S9f(M|U6+H;ur`60D+J zul!tEnr-op7h<~T)*NH$RJW*bUc4#6_G5qQPI9Z$=SGcuC=GaqU{3l@E@9H3Ot?R;$s8Up3FPt ze^`JhNYpM2bfz<%X{Y`7%y4EO z)>?b5_5Pmcd3SpP&aXzkEKO_{>@NI8kG2YrSPoygK()Kg^7_n_*M!q!@ii`B`f$2k zw$_M?_Yg9F-`4uT#bU({I_6GXZtyejCae1wyDLH`F-$z=Vop+NCDvoA>IDHSZlpAW z?KpVI)KFq+&o3K}@F=O7^KSA@xNK{Seg7m*C_drHn7Z{}TZ@ zqoMP05&PAB8@t0;dxN0w17RW^&ee(h*tt9+L4bglcoM*&+P?y#2Bi2|qf#y@vG0_> z!u(A{TrU@sIzNjy6;oPOT1qgk-TTm>5ODVYez{$;`%C9ipaLc)1Ibw)Q}J(xHzJ#V z=^U%j-G10>o1ZUNYTlb+_tXJ|wc07lSRl-g@rfg47<-nkIPIr~Aj!b>JAyHz~O3;~k&4I9U2R=86EVvYpYWC}OD539DRQmo7cc7{5iZ~F|1@d17dac#8gpMIfIyZl zk(2(-kgeWJ`RDDsq13`p{E22*yv_BAAG+N+l?`yk5`6PDi5=aJtcm{(-1pG`q9w`= zzyk`~^mmKgVv*C?_z6s-T{ru?)vI8TV4K+}l_~M>quNoGCB}+dU!ZJU#vk`<6h~_5cUgny*3n=K zIs=o}n7)NII?iD0>D9+{^*eomnypaR-8$Hc$A^3m4&YcOwRy3;osx7ru28>`+-ZWz z?GalXBX&ta(+Z=V0#R}=i@wy_ka8(BM|vzYKl6^v5HZhnCimAN067PTHbaty@3G?z zUvxWf;x{=CAZk>f!nv6nzOkn&muI4qsrH<1=_yd!8LYUO@LuA~5-R;E%M2scZO-`l zS;uHV2MFWa{8q)#h&8veIBw07Kz(+SBc-|X7dstE?cMgD+Sf!J#p9IV%b^(8U7M)v z0@JCspaC$8TgTh8b99Od^7m{aADbQn8n8uih$S1s7Gv=geys`oKtL9dcep*~?Jqiv z7VXrJ9$vvN-2J+!%Z`;hN+BdG*A==(BB+uLdsG7`h?&Hp9HN#=Lo-RNaSG5ZEV3k^ z)1paaXP0~wtQMeHu1krZlHe!aLR+HcK7Tnt)oO>XGEU07#&TjzD!RRz+JAPQs6=aj z2SR>bYu^3Ma!CFg*kh@xW^`wFn_2=ACXI1!pWLB<5vX});W^Osd}G78la z4~fne!XAGES77dKP5Fm71%nUNqjXq&;XuI-3H)8i|Fq_YMlKUN2V z_yvuk*IsTW3u|s7f*s7Ub0N8f>HeoMdZQRHf8v7b-lRqf4igu zi`d6rG(AL0WCbm4_b3s;93Z!a#NP*91u~;S(_hTO&E)ag^BQ5yD_PE7kpI?&n1GEM z73?p)$rdhw-e6Ig<`?#_7BG>pKH3La^aKr_ovr=elf!%cd7^ww5ALj$(q5!0CRwpFVf>Rq`( z(QD1ULVl1$$fPEznjqitGxqzA#gS|tER=w{sH=@*g+$~_gCY$SYjM(Jv1VD5LG;jh z`nhD3Xl$8sR;=mTy` z{Nv0qX>Etee{*+7wi=?)-6JcWeK;MqJj$Za>iwTk>KQLum;66OR6r~JROi{aA)kkg zq7$vc$~*ftR-!e`caWBmvsQ)h<=w;V;=j}hmQt0F<#rLTxu{p`OUer_we!b;uEJ_pB=21|T((bwP231qa!&T_B4Zwc)=g(9JKRu>XTVVLv_$ z3HKUp);oWF(`^Rxa;rXiw_?Jhrx+M?!plRU2EZOMm*Ie^_v*DxmwDJ~uvhhg(RPhS zZGZIvSm3-%+udxQNHU1Xi{TOq6-&DpW-HEc3QlESdLPIaM41051XDE=Xzs^1YP8vo zfz^Y7dR?i5HdSwK;3p8E>$w(Z2YqPV|H2lm%Cui-^mmVj>q@tk;L}$co?KP5@gOKv zOSklRNm%=v%u74CqKa1s`{4mHmXbnWeynI9O+c7+>KFHWHGDfKfW5 zha^9dxx~X^?bt6nyYt_coYWK@xb&<-K`HaUXAYM$Bh`68%k7mawfVB9lC>^rnYS+9 zPfI1^nIhnCe?km5LYjaH)t&NYP_aX7Zj{FCZeS3}hrDz}g?gk&3)Cnz>Ih8KnkqSK zs`=+8WTEZ3bgA%D35-MPS!|xiqIjb>J`OT9hzcwI@ZycG_}!mMs-mpj_X2Z#&)laa z%|dPO_89>R(k4>nSbEB?h^Qe#spm}neah75mOch9naW8;#GB3kNyd5BEwHhbv zZi^EBxU*sc9dWdRQ&{_W_<_xXy!YpgzL{187U|=z_v2n>kcko@(OPP#H6@Eth+@dw z=1YTV6%i=7vdwD!^AbZOz|)Zy3F<{E%spxDcO*3o$2}BItu~iE@6P!;uoe88xvu90 zIM|Yk){EM=FQ57vSQ|GEg=&A<DH4h zPdA&hhT+4rOFXFVuo0mWd>_R)aKqCtMc`An+&`5 ziZF}F5JEhJ;jx_YS*{^VF5k)Zs%LzRHzo2CzxCyYjKbi{h!409?|UTDZ~xa9BK{+x zPfg0tbTw>s_Z2=%d7mR7l|JgBMpmQda$SYuOne6o=Yu|0h<$mSAmX8FpF<7T(3u^j zH*U}TZDs|e`>9c9wzQuojd~7)dq*{WfNkJ!R`K*~+G{eW(B7?=-Ybv3)d1gjQi8fuzEk z$|M>6pBgrWOFT>F*Fl$I!JI;BuUX)vB}MKw>$a2E!QDy#>hP7-xIx$zsFfkV#ZdmZ ziNJNdYoX(Ms54qeW=?o+>Fi`_3;o2{ho+;0?Td#^Sk_Tf)(H6KM)kVbhhKiXE=}>g zFKe`RD=fzgtmS3H!TxMo50r>L2@IFZE6tyOi*&;PxdvZf;|a0$aok65B~lR^U*&Km zAfKu+Q4wRqH%hX1Fpf$|3-Gf)`3MgK){NitT*9#C@VV42)aONz>{#@KMcZ$n?QRj~ zcwU0)&xLAilZ>?`gfF*`-iu!AXM$%ZqdKxa2d++uKLIT%-j%6TOmi&L{+1$T5c-s46J_w=k3=-EdWy4Yr{k>W6-a+IpOEN9u9W}bLdH+ z4To*L?x=Vi!vPZt{GK>K?_7b5uNv z5%M|pm4#oEmmjlL=N+ne#mrZj#K#}SO!9wX7P~t%N#_8FhofHr9cN?4YH$?*sj}A)Cz6e1-(eM&K&R;YU5i&tNKX?eE^EJm)dVPH&eV#t+J=fDp_VuqFe7^;{o`Q@bGw7S?MYPPSawwnFkb$~j zi>!RxPZI>Gyza|`A5`Xeo`rvZjksw5LMtb{Is&m!Y7md-+p6YQhDuKfJrj-=LZm+F z%i9qmXH24~ah)5_m0{?R5VJl{v%PxarLVljfX+6lGu*OYlfYr7I+dOlRTg^7z@!vt z+H@=azfx_km9c}5E(iR=_MZE-Q9Hy814Z6CCS3CZwqqM^wG&@X@@RliwwjK*)8)|(rk(5Q*Q!(3(FK+O-Py~sjdGw^p}}A z%^SSF#2c6_9Wnq`DK-yCsr$@6Rf~v_swdXT4cSo5X$nBMi{_kI1lht?oTu~e2V;(% zXzJotIau?vd#z+uL=n%7`fy?s{8v;!bX#E+K!+(u(wLge zON4c1C?=1x{Zj+XVWa7-6L!5U^?4<2JbFe5bM_yDjj2}`xtCXTX9#HzFCJa2ym?yE z7aa(wVLb1}D=KodZWo*SRDNYTk?eTai10j2?L7fKZoT-jugdT|cAB6^x{F|fN24Fa zT0beqWv-tFT=Rp8&vm+risKY@;km(KH=Vc9kcgolAgV}QW!kO_p$CgEh0QI*J7ztLP2U)0se<` z4A~O|cV^E^jbtWIGk52}n8RS5YswgUrlf>;D=9EhNp{~YvPq4~^Bv8^{%+@*YBcX; z7*qP*HzS(DHx9fb%p<4Hf2X$Raz&UX!aFhuTN%F_^R${qNXz%so{+Q&5u~9ZaN2Bl zq-;dRkR_9B#&eY&beTi7*d&8vBWJO7Tk<;o^v(dCFK(Djl4qh=$Q3vkJy?X^{%Wq7 zMRr{n2s>lhgACk$++weBMVt~n2o(HJT7bY<4sn#^f5i#->HWVSC-8qwr2kJt5B?K5 zFjQXo!~kvoDcNT~fW1Ru&uL%2Fy8Gv1ioz;DaeR^`uT>dz-|$d>&&`Wsy5$=(KcnM z-P;|ood4opgL*tMsU=f`mUVkC1AcvA%-DYrGB8$ZnYYMaB`X~&77H@hp+K$7TY*&b zEt-Q(9;qg!Ya|?xn=M~Zmd>eTisXn}&lyI`H_ko!z?&#CJu1mFwl4bPzIB*2^ons~ z2((Ef1zbI9<0TGmPbK@5#GHgX20r`y75DSRB$d?-mpZl}kb!mk0I(o3m7gG+*~7yW z1~bX(4;V2m8mO6C8%x)k+X2u2HdbtvZW8KJa0tw&AFO{MK|3KHAIMMsSSA62SJ?H- zWEez?0^;mVBu6@t5l@Nl{apK(Z&?3ABHrJ($7eKrivmxTaytRHTFH4m4+a$0&y1QO z$(-F)67ysBZa_kI-3fU3YHvLooS#|wTMDo9m7x^M!?et4A76i)CUfLWHG8Qq^B z2Osc|=hIZL^{{bu25-b3#@>0zzAq+%9kOSHcx)8QEZk;q75)S6Tuiktx18UWvr6$h zh6((tBqu9w9`57P7nqZj%(PBGA*(;y(_?vCgRuT_NBqtLc8`qo0jD$UOR&-(Z?zJg zD(yF1N^eFp&%1mckDGFGMBo-~QL!jfV@;*mE1Nv=3tDG)PS!I8nldLgA3DDl$iMIp z5Ky)}1TrNoFhUM%`s@I+QhUK0ogvC;)97DMFIbOtcgj@2jS+wRwpegHbDmR#{RzJ9 zv`pix-7UM|JRVw&U75Qz42*4P4MFmMp}e2|-~*{s`mRF|>-*J_!gJVX38>U!Jg zU3K9of}-}QP@OSy?|GFxOnEcaA^-yF^Qi)Fw@7Pqy_HDQe=z`vAiY;&AnUYiuFKN? z(#?KYT@?#4A70(I2sbj-9*1fq(|5=7Y1~OcNiAmEcI4J|FHGFh4l^s z&@{6;_xLM95icMudC>F3t$=p5%SwhJr9%jsIZ$y2{P2y>h6j(x+Tz>c++QQBF>?Vu zL%sUIKjVpx-Rj2iJ;tO1m#In<$li{pb(b$7OPbhFBnjF#q~XBgH;IHXn_mIAI^@>H zW@}W;he;P9GR6QL#ji$hs?5Y!lkTM#Chp{-uf9wL~z5^aWQ_~*vP z(RECh^5sc!u_JTLcGXM6AqXQ5nbDM^%{ZR#7@pa1z~|;0zb)f<`@V9es@Tw(Li=T$ zi^@FVsQY@SZB|ibn5wdx>vOirhd@Ou+`?VS7RuKsVo8j`0PEB6f6xtv9zSNqgGYCW z|HpJDE_0h_Qq}vG!>pKYw>{fL7hQ8vy3HaE; zn^qlenNZ5=$W)bf#h@Ay1x;Do|tgcIXz2x@is_Z-+ z#+tRJKYC3x<8s-#jw$#8`8WRlHLP>9d^_2(vQdB%kNmNnD_)F=ib85kxTazf+(}97 z2{y$JG6}b%n;i&E`_&p}DJu`un!u_l9$2M}7Pp^O-T!EruC7 zr7dG;>(sYZAypS~v~c&wZ`T_O#cN3oV4~rjHJ(1jV#wToVPsMJ{Z5d;KQO)Sy?FHb z&s%7u7W%)LDlne&yJ2BZUa1&+?*#(iSKxvU8uYq<^|zT8d%8a)`X`d~MaR8T%2jgJRoE$ywxHkJajb_^II#8vb-dhaW1A^0vXUY zqBPPb9Dhj^0|yzgm6qc3=f#nnOU5aZAL(-{y!ZTH?;n{XYOLcE5*#WWvW`_{#0lRNxWP2UTFM z4mmFONbbH|C1$XF$3c{pby2oe>r;iH?n9y2U$!}jV_2;(Oid@oZfZo@Af0;TSxGZ&i;|Py9t}JDgpwP~Ev^#Dx`d>h4S_ZVL+^uWFIq*SuyaHIdrHrfv`W3aeA8{~S9m0;amL-?~{%2;W9Fff_AtkA$W+mW2tozGR$Yb3^* zC59apIK_JZ6E`r}&$YIG*Tw^+1mzVHd=So`Ug-8)xD;KoCFyi}tn4%WK8X-J<1Zs~ z)=9*k!}5|J}hw7pxidINPX>BOX(dB91?ZLwL_Q)$CJxrM2OP)d_u#N+aP+ zN`!Bxn_i&qxhf)8z)|qP8!-tW{*&;v@ZokGPuGfEE>P?zirj-Yw#RUAq^%=#MRWLvnFg+?sP>cOXT~zX^r~Q{#Zl8`j z%k`^0`||g2m54#ua|>s&Xyih)Dg!f)-&UGR$?gsfDzqo1XG%np7a@k7re!h}XL*FwUWDCZ-lQ`4+TD%~l!NZE&a zX-P`9{rB5egg<%Z^227>VBF>X8avlzxXPt+ z+sr~)A8E1op$`rWDU<}!Wf1WYp^gDOzR^Fu{%d~tUXO8sMDuiD-G zv!bwa>4hN0ly~l-cy(2@@k3iwo36kxG)6^1q9B>jH>awpJ6PsKDv#Ln@6&8ukBi@B zBao5!%#`Rh8!>OAtjsP#T1{{y2hoYr0v0xjX#v$#dqt3j*7Fk)2Jb73(S*()t_D04 zhC5QCTEvWx(yI0yXQK8_-dW;z{qi;_3EV%z4!td>QeDXiI%Fpuxu45ZOiXSy<^4>o z`IE1kJk_Livq`U%rC>44g>e)H(fMcL0$F<&-c&|ita$Rwe75dP^UYVLf((=|VaP6% zh2?Or4yiN|t5k+o)s>s}cHyrj52^J0KVzf81-_H{ynBTHGE#~%(xk({TGA2gAnSPV zsefl6hFBuOuZ%cSR+7$6{o75j_Q5E$rj2t|B8}!Mi^FF1f3yG%S+j7^g$uh%Vx%f* z60quH>ks{Ao?->u0>h6OO#(hn>CKo}f36kZt41!VY__cg7%LbX+#E?8T-c`RO@)G{ z5_TVNy9Cdp6gcn%rH|_boVApX`UIT4g-{#C5|Glc4 zUuHET7%>z0RBX4Sr*Qgl5}>TB-Z_FVA^Bc6*P4hBMSp(XphL`YaoBBf9rh#3UU_Z| zAeJK)TXk^D$dwP>ZO;f;WcbrNPVCZ01w+?rkYBFgcYbahSRwo{qhmg0Gk-}{%jTjx zpWvC3MNUz0Ul%hkfPIFuueeoy6s@tcd`rYtb}L6OuDq&y`Mrj4m&KMgnU;Fy=+xZ5 z03^JlXsLVdg^*C?gl2s2kEd~(rGE1-Ak8PXb4hq-)4%c~COy~7P~Nyx!F>61tKLG{ zv!+8R{x>SubA*du*BNQEnxMBH6FcjUEdpq>N`ZHbYb4xVJi0@WQ4PF}nD;{GwETWZIba(Or3 z^t})3*vwZ@AIo5>T$V^Io*aP@Pl;n`wR`ZmsAadfMP>`h;_3=YTX@^IW!m2KTmSMe zB<>yd!J`4Yu;In!H3(74`PJEdyE-pO&hNwzR)JLoVrQ7D$30saCwxE61CME3E!({! zF0mpzJZG0aj;snMt1VhSRJq6|!;+YYZy0}T@NM^OYF|52Hd5V(2kfQipsg;^;9Pkh zb@9m|Ek-UFn0($I%&fk_P$kM_g^DQCK?ZJTdcHGSh4!jBd?S5X;k}_1aKwc>XNk^e zn%dMVSgu^MV3WM*x1Q5mC99my$w>42@7CJivr-ObmmB?e!!qCW6g<|GzjmL%_WS)? z5JTC{n8d$?n&wk=d2oKyasU$=X;+M+C&8-&X1%L#^Az+H&WKqa4lm`7SI2o7yj-J1 z?Zp!*#rSW=#=eYKtqZ)LaylAd?p?2)Se|=ghg(YgF&UJjKpXSKI5r=>1z%%D^5pO| z?JGsp++JyoE8tnMJZ?C(eRpd<@SHTO2pTIVXf>d0G24wF8tLW5NE#KxCT@dpxeg$` zg4xw7dxv)Xs%&g^Iv->(`<5;|UoiIkJpktsGxdk`WZU$&d%rx1AlN|qaru44{gItS zgD?YUUWsB&ZPQSH2+`@IGDv2J1c)MV`#y)Gx0l^Kdtt1eCh+V(uU!6D$+*nhk(n0o z*}qFD_Wy^2|Nd{@)c^C#{vV1b1o`4>zQ36B4-&LK-v?JZKMzI6YCP9x?-X`;zih_E zU(?9HHfdhc3fVE-p=F209+?%(hrV7CV;dg-SbM0Oe}I*X7;`hd+XuB%QS2*1=T%iQ z^Hx0P9?5EfPV{bRypYoHx(eH_ zvQ7IeO0Hsz9qbZr?xnifIan7{oHyt9?<7@br~_BpFqNCI`~FG9(hql787geMoj5A=;O((JrTZg0cHLOF%cprBN@kE! zqm2&#Ovzf?Z>t<eEDo#98;c;5)ImSSr6R5!n@MLz)0E_+ z-tw?$t%nj`xuQGAmFbY@UC3;gLZZ2>IAp!+)gO~kV!kJbV|cu@XC4ZJ8&w5VIeX`Z z9S9UxGxC!1Q``o~{i2iB!sXk)(JxDP5ac_gR3)*gZf_F7#hZau7_)rvP)x_Cti8TR z?oMcH{n0iUSct4+mkS5r4VFQAQ=aF@2;&7K7XEpGpbir*G>{daj9WXq++gmKe07bvp?4gUTj9>WYJNp6h~}qoRA$9IhD`z&*DOYdENeC&2w9wK z7SI_ix}rerteGPjV{UI|AuGlvW>!fpw$87FPQ#m3eF`hNz!S0ArvG)V{Sd8jY}s#v zsK@2fCyUR&vB`stHTF)o+OW%yYDn{o7uL7*{gyYC;8Z@sl4`B)=CFz#RJt;s$K)%T z>+;85K)7lxMWa2yRwYhkSZ_k21soSp2L~=#UX+#^BXcwD6|4+wzvp^UN7bcFHc+Z zPL9i8T3pf-U!GQ7?7aH$24yGtGk*M`9@$SlDZMta1jGv;9h{Unh;u=3SdRy}UcbvO zvlJqcvkM`V(Kmg-d$4@#O1Iw)zfC>fR-`jg;*L2H1z)iT2fr03vE5&FeUr5ep^M6^ zoXzF?P6kCyJF)rf!S&SLZVN8OuBYBLDb^;i!emvYTNZd$i!ba7yJtRyotPA$eEp7i z_|nJaw0v1Zt6x_^cKq*ZB}K%_E?99@3MP2Em^%(IsXtLGTv4&!bIr5EK@ydSlP?g> zE8U}g1P2AM;e)W2e$D3}FWvc-i;r{7OX}n6!XbL3oL_5ja3U}c83gDLxBK->ZrE2@ z+bJ2%l;`_iHJx8g-VzuW6S3SGBP^2Gy5RmBPA&1ZAs-D(G`A@A1vshhgZj!0YAo;j zBR7M7r-VGd?k9lNvrFdTM2Yhe4rA~Kt=N3)0=`%>^ z*!aT1Zq>g0Jk62e*QPdJ>E5w$GN=T86xy@Z2ePIpHq`>jp}X=k^n%zHjg|-V#tDos zp{w+T1--t*Am$Zb=@Kmi`aU@j2UcI9H0gqEB?&*?t@|em$s7Gv&76f5%~r^=e(BO+ z8LsT0QPe`E2W_{z%Nc}7;fgZ2$%)6?_NTrWO|CE0N;?;Q>TD84FGzKZV%J8!6D^D} z%O8oDt(gl6i(aj!g>R74FG<4TbBBtjz}()M^z)`FS#$w;vn#TB*U#qkB)o|B5<#6T zQ99Nl#D4Yb1+AKJ>Ee?i+C4!7g5?knZ#~uyPbIw#)cBpn)@)F=BK@@>pUg2bqnNM2>4E9yV5LlA(k%ZNRy>G~nsD=S+Ef`t4>q9ZUj8B;^Hi+$P z;IN+iwep1b`nfLP{+5dnUu5PxzkE}h%=QH@bu>FzZqYx2per!#&g1xx;xoqU=3C42 zxrg8+)R}sV-oO*p=`F-)s>Gq^z46OI?ktRj5#rv#p*tp4ZK!L(oBxGaN}fq5B)Yke zxKSY`6tl}X<7B8;V;k(~?3fsIJ2qbdYWuylCK7?+NO`nlgZupl-Dg|cYUboMWh5LI z`}Zu9?3QLAZu7V-bYa5H+M+ImBfG2nX`f*I(mFFpUKtgL0Vs$nbq=Z9i|)4xEwhpy zA)I0c(N7Eoe9q5j(H^BT_;EMNv8_779ky5MiCA`h>{3ARE|#fB{stAOvx4QGof%aayGv^0u|QzO()UJ7nYJ4g4UH|UBY(7 zGdv9>T=RG7sK~)^<1t!Vm{0=Pz?rqtk(l*!hlPKO4=c=eSD>OH)s@@FH;+EfEI8Q@ zF((D4^|WM#rHqRSq~eaRq3!zA!R2$VxsY16|B#;Xqll>wf6i7p0V0QjXT19Xq^`J0 z+0k#s=`f2bd*^248H2xHtrkpk;{7VT8C+zF*jo4Io)#x=G^6uMM* zKVrGa88u4+oQY8d=)MrfXxPF}9 zhcZeBcYg?$bzc%KgWx%=w!_2md(>>`&UxSX7uQcaF$VQU^bdiukvjcyC2r6GKP3#< zH{^QROEx(9vYqBbUXC0oNw?zwsWL6!pJDde5Ebk7AG>_0D&za}X{P~lJ!o8Iz`I!L zj(sO{L!kx6?N@uWg%e0w{-W{CGg!ZsF~q;JWZX9b0t+NJCbBz89PL5Z9qUo$bNjWW zSmiw1chb|ISc*+%%rvUcn0<|+MsN;)yt2y&e5I|GK{X#V)57X@V1eqzBz!b7KOg7v ztsYyD1F@GmF*)Wtfs`slIuJN@_VEwvG&_f7p&1VfyGtv`x8^b|#WXTXpq)>1?BeC- ziZ6T?jqjdd-ax!WD;NlUpyeVG|5!S{UJ266S2)eKobbJSVvZCdv$cFIr%rOT-s`Ve zj~~pZF*^;XeQBa2)OM+(8<1H4lFyj6C#ywY<)!(A7#UI*f(CCgH|Q+R9nsJ}dWw&U zm3lJ)D)}?;YA~`q$}&AX-5eZ}E@$<0gR9#p^VvbvYM~D=s>);0nf*)vb$&_*kuNSPY1K?U)Ftec zqeqQ+ae817N9T}P<@Q3LEVx8XdnlcCfxn*o_jz`5Mc$SMO?t4h)}NAYg2NSla~G#` z^`7+s;#zM8B_mL(l-0IF5&nk%-2;KZu&ZdV@ASx~tWlL_wg@OO9xR;eL|>?sxMnT^ zwWUvKxU4iE_=wIt-(SXu*}^sPasBiCO^An7r2gm3)M1~u^sBe%`}w4bW)gvCUStrY zTsdyWrM@xr60V9Va(#5$$NUBmd+*X7bD{B>v7jQ7#NjU3thXUmqi$?J+wZdAXJ`Sw z`ezJYBC)oV{mHDPrTbz1HDCFGjR$ABipFhf#8PX+#Zt%lQWgy~RrPZ9cwfw(TnJ;3$jLW!8mos`VVI*f|1{+$Wc}&+ehU}B-xjO~%BETf?ECf$A>>uMFN&MSH*)Hn z+obsUhTF@z;P**UgA$NqgQ`jyMP(tL?-VkYEp+osecHM_gCQ$~gs>wM&mCXuHa28>zfLkWFmS@Tx7tdpM^Ya;E72Ep@&(->z#!A5vJ2a3Cz%;H~ zg|C0YAsr%o7851=P(k zm*t5WU7hp1-<%7n1Kc#Ut9$&AXJDwppAes_$D6SmQavv!O-y$V^rEc)7F8K8$ogou z_ACrd!a#jGiM0JWQ9eDh1;7G!a)01xS;=(gim#xM(|O8PHDtI z5J#mbPg7v{G0OeH!R&rUuqun=Gutohc^MsRof()IUt(N;ejMj}<4)A2x>>=8Y&ef{98n=31% zMRxMa9A5Z z2%f9OznpQsA#yn#G0hx2Vl8hDl42ThXtp$1qqDAlQ;1{XS)7L~kcj%^tbDw`ubnG& zI4!nSsG+q?6k+_l;NR?$E+4u!ZX%oE_CYmu;o}5|ANWSF4RP9C?S4+HSs8u!(@Ey5 z7%4fMifojkID7pPZr!4tH>nR->t_5=Pmp0+p-fI9)s)7_OF8**1UQr*xx=wExWsW7 zyRkvt&-N(FK&Ik~rcg%KnzIYpk<>{izZn0pC)gNU&Z-C7@bmp4Y5ptyXZbv8whwCG zy%?q6fPy(AoO1foO&#@BCD-kaBk7?hF!pA_-9-(>D(llJ;U|u&RV*+_s`2ym z1_Q5{xnq77o(mB`!_kFd8^F%IBb!tX(w1J*iPeWUDC4Qs2zyro#5)F|F4yVU(H z;8Q0Jd2?^JpsFAa+KR^jMx9je<%vHfoi_vr6SxF&<3dh z8}N+q3b62&!YwByS{$v5vYhiQt`2teoLZHBc$Qp%RpHKEivvus1As3c4QG9&um(sc zFj(Q1IcKIMvde3P$`WF9Bb>eVI_rwP6x+Yab^F-7P~8To3~y#kd=**`;>b@2&`rZ1 zN>X-TFxi==rSRpDXs2paCLxL%b>&`3gNc0G^dK`GMM*kv6d+u?P^-tDz$6H(i)&U_!TR$6cLUga-;U7d zxCkFH2px4gPROH5@JQ`uk>k=99?>8`oLSnBnEW`9AOGEqRlFY`nmXs@r+XV@?>oq^ z8_0ukhX=)B&($s0SL|_S$Z~X}5hcf###X!zm60w<$Ipj4A}lR8GRCTy&NwBV%X%BC z_<5zjUshAF)Hnr|@|OQ`xkMy5~;7)U)Ok*gl!JXj2hc8pro_QP;wZWEYcz3TD?#v=D|L zt>Xy8k1~$grpw&KC(ZDOO_T*OfXgSH0JcZ{aRg)grHWKo-uIw*#0fIpO? z)XI9wA7DMngwIA)MYm!f#w{7jl(@~?EOvepL==UXDQZ4Hc^x0mK1|*&-q}Ab&l*z( zL8tqr?BcV~X*<6M%d_{hsI60o5WHij;?Ez5WIxj-_f69Qwn zKPF1K>{z~@h4(UkElTGM5?HUN0d*bgwVWr(ylAp#UO4Tww(kFfj5-9G*vV)fY23qV zE-$2d+H+komX_Sv4P1wt@DC=KBKh3E8oHJpBoFU?aHV@Wuwu}i(HEBPge^#Q5l~Z zD*HpyA|j+rlD2K)v^B}@fG5lbJ}Di5^0aiWZW-PAN=b*?|MpJ$K2+RFW*;}sTt+uz z^OjKxC+~M&6!6B4>KUHzM3%DFFC~!$Rz%Og<+$$Sat9u@o-JQYe@~x zyZ58@M;rl+%$B|zz?q2}WYO|#$m_F!2U&5a`#H>k-WKOUb-jzgkm$`jsg7+6be3$= zK99~}zC=*S&}!7n%Z>kqQA{_DraXs7>1}0@)Jxd9cEsoc!TI^3dGZqwC)G2)QfWC% zTI<^Eq|6huXY{W(*lrgkWaJY9^EO{xOVJz%_$cZNq@2}X!ckr4Y&@+M3o?KdWBK{= zJI@L~V>G>e$SpUS1yyJ%K(yY{n#6F_Pp8pZ4SI4;ds*@d*aQ&gm5uaizNdc|WIfCneSNd@2{_f#cC-FA7+- z1h=#gw!c~fq)uAoZNh^t1o&qvONt2X50^xBy>!(6jQyD!q*Qw08+*(TUpkI=bFCqf zC3`x12m<-O`$Vhqz0u+3Pslc(5yS%839IE%+~i|ygGXcxC4ucl;L*FKwQ@;WP+Owv zlAA;hg)FMr-I_mcf1`s^oOZT@5d2Po#<^UIP)fU%oIubj;U*`Q?P}e<_9WxG_hT;c zLLljcO$j*6DrIr-$B+bc>}JPG&~DCQVm~^KY8VS9!Asm9aeUzY-%#Fz`ys>5{|Ewn z-kqWTBWXo_^8f!u$FKh#`15I*BLg^D{*!G}K3y<1?$~&sLHzkcbr`Ou>{amEYv5|< zQCs-TdCaq*D(^VuKct2Q68Wlp&^FyktWCWH6C+o@8Wbzhx}GQ>TJc_RPlq{g(CwMN z$|BP7AgfifPk*p|F_Uu=+vM!8A=US$VE5~~v>^{Z@Ggz0u1|!ave*4KZ>*T-1Mugs z>MUe^bKsGKuW}Kul^jAx+J?_LyV_o?2SIP8HjnE*d#tv?`wl4u1RqI zP_JSbFG!8pAwfrwZa1-I`osJS4UU%b+`a1&fb(SZ{tM?t@-#@NND{fImL-aJh3#z; z;}1SMS&@9^h8JQfbyX$*gVDwg5(c*bRml);#|ayKu6hNTG~Vw&mF{x{0fd~IX`o>} zd`S*_r+MtgP}sHp$)3P8D`)*$!q+-01i{@pl85%`$eOEMDCz$GjE+u>6ehywGE7VD;U#Xh0#rQ`i+>#V5W*0-T6fj z2QlWkjZNh1_&nA4lN-;_tM)2EZB{?ENT+~d@xFeoR*oZQGv)hV^Fr*$7X&d74vVpH zWJQWNGP=wqB;JjMK>0@;6IMyf<}*~efIQ%C_0c)4SU7+Dt2x|@4wMw;=j3C44V|4P zcA#Uzs78ciM??~NsQ=EB(?6XaeguDZaPZ~EF8<1nknwTRG3itHs{^-($(U)L{UYuS z=8-ZHV|X;~@Mc%OnX<&7fl2FlVE zFy)M$RIv^Ch%6W3*}r-yfgI^H_lU8aG@f=ui*qBGgm#hJAb~$LZNJkvjA`94A@aR~ zMt|9pQ538G9rH1w_s`N? zqs0S3lUC7d-Om-i(L^4N4iDX#_xsk+>=KWC-V6^(VY3Nu^b_k2h}I@7bXlb?I8867;|B*s)z ztwWNf`my!uH7b=FovZq~7dw)DTwd~8BqTB7H>Fc812nWEwyH~sli0AJ_CN?KWt_%AFewF!E+UucS>2Qzi&fY8TKS9yujdkdBZ`QVN}XL;wLI@r@p<68?@lf^9~8Z7+!74 z_F_IdWo7tZxI3$;IGeUhH$j62cSu5T53Y?v2<{LhxVt;SgOlLy8k~mU5C~4=+Guch zw|Vk@GXI*BIi5M_6V~cxbyq!Ab>G+CyQ23njOIfnfL15Ka)dx4h*DE!sM~bPk%HV% zUY=qckcAI$v(eJWVz``hKGUQ68XM=QD}@@h)Fq#~MVntC{%i@-hZmmeEZr9gufMX) ziYc%oxY{JJ;K zood#+;`i6{=ZKya7%vN%DtfGymF1GfyfdA%`JVy=%60RKiJ;t+ttIyru8UsNae1Yp16e`eN^@tx!rU z9?nkfJCN~==-HP#@a0>EEZ{2lnO%l8z7L=nf8Y2^AUiIm)c~#MV+-P}0m<9!ZTm_e zn8Kq7AedaK%z~3+>Z`3PGX){-2mB8`Gnoyhd8JpVkSU()V3w zI%^1u27clt!N)`-HTqkw=1cr;p08-P7dyRGy*u%Pkj>I9=S#Us_i>}nhWd{oxW|SI zSOKoHeUD6pK8N2XZlmq@8rF@~f0-GRrB@OZVG@(%XxvUMVfcFNUy54Wzxvozu`qlp zcJF}gmxLtZX%QZ{wnJAFJZIMZZC+LNfi@0*NOn?8`OEBIr_&c!^l1dduBwlPGcdO$|+q+0MKcA8LIh5UgKesB#tlFW}s?BT~`)xZRR+x1{T( z4o`lBUXwryM(r3?u~oA-*@Covfo{KAM)~Pi*uM_kMn-ZagcY{oW3?xgjzMa_j}Vax zI{2hm{z05^^GJ#t`u2F4IRI6XPA`rQsl*avQ(YNO4RHVsv|!!fE?yqZp5DeXjw3*x z{*6#;iaauAPB#&s_|oc)n?H|}0|7g5v|+NzsR_Hqj5_pfzSiT^?W|~@*aMY?%w2QV zg1HUps%?>g=S;BKYQrktp7d9*S+T)1e8C0}-<8MUi+}Ltmg>$0p?h}?t9qdr=fVU7 zS>3e6_U!d%XT!P-@YG5(OK(zhDbwExP@HVuxqTxg!|d06x~`ZM3e>WGdVTxpsc`qf z0IaRB?)v1>Ub+|GTULC&|B1^$j;;BJ`|+RSDIGwddv=1KU!L1-I|?UK(%?%_4?g`# z<^KphH@w1U*0LQ$L5o0_Yu0ZA*rKJB0qRs)7qu`8gadzJUq+^`|?AnoJxs^HK3F8XfK-Y1BBB8`iwSqdv9j_ z7+z7uCCG)dip-F-|It*A#v<~%?IRjYNTVu3tc40f!Zy2ES)mm(vDX=XUzI^Biz~Hm z8`HYgtP&PwbOv+RH6aFxF_Z@5GOPb>ON}#%#O7px0nK8|DWuhYdgt2&kfuz9_dTMq zhFQa8%ECEh(kf1xWH4iwQP5`YF#4B|8m9RtDpf)4g+Qtqi3we?a3t~V>q*7-_2pj* ziDgmiVxe>?vaQN(T{bgYRl0ip%vmxW6P-ORzoeE|UN%$||1J=v=L_*n9?U~y{{9Vs za7F>j_EcU0<2R%TI!MJ)W&#t$aK;c!Zt$Q)%a0h}2_+X7>achbIvn&ax|4-HTUg?N z6Bte;@!NPIWCFToRz0l=wE2TP@jxEK7@fG)0SMd2ZSI7M?e{ExSBFCEsONmT8KFC7 z{u5nwhf~{%`#~`J<5AS&5w?zl~lSq`pOgX!`8G_!mKFJG)%@Dc;koT~QI^#;wH zVecC>2!S|WoXov|c~R8W@WE!;Y9RNlFn~LK5m3j!C=3xXI9!gP-3mkrC8Kj-UO$*^ zjZs{!eI*-)vifGN@IjHZN&d?Y-$ni&SDN4Z6Jazg?>}HxH2p7d$VD?ZLj1I^^6j>% z%p&~8&{Z8}L5&~fb$w}tuioq;f@ppS27}-W?#G2?C#?f&?hvyAUpzqJ*vtt5fBGoC zsv@gk82EKXw3E(+#L(r#RvH{AU+I@4f6mCY9I4XOHn?OO0BCLY_fxfSB*rO6;4m-k zYZ{XDds*+0eJ$B^_#o7!r}|;U(hLJ(K&Wr=nA`6yE(^dt18i}^MGE;K)aS!Jz6^}H zR#Lo3BNY@HUh%Fds#g;nZP>;SN|DEyr{2!AM1$YafvhQcQJcM<#ZWh9uf)(2w&rU`m8DXf<1ws$*cQ8NW|r`dDS!G1VO6M8m+U+hGOe-eWEL zB1QNr;^%x&VuWC`@ii{-bUGo^oFC9h0K+r7$_IB8<4Z7XJEj`+jY}QhD4mOi-1-*o zYVpX9SEyV`FC4G^>0nU-Mt?EH{q13!hBJq1kln!$yU_j`fAY>N+O;S{_Slx!9d$x2E-1VP_50zldyZJ6wyChD--*fyka+%ZC8JXAZS;Eh zW`rVeqK{2M4-P=e0m+soSQR=Qc|q|fZM`Y^Goif*Vk0YL6icjGGP#Y&6b&S^^~o-D zoI>oJQ6ma1#B9VCOX&98z&D6V{(>aJ*1F4!ChmNjnk#r)^kiWJ2K}4+KIuwiageHABcf0O@k~tmDN?0rXyYhL-@)aP z;_$&YbJe*A;zAeR)pNWmK<4>0jW&`4Cknrg+*${d-|f5Ajugu!_iPa)jquVku=ZlS z2z#smgcVQ}?PfmfskhGvD-GG3BuO~zGc6%NeG|-ReIC9TiqVeJi^f^|fLYTK7F}ma z;=rq2=C0UjAxxZZLjxzX-9nTN;y{)Uh-|9=3f*RbTitZx@oIu`RDMkSM!S$ejT%Nm zOlm&>2do^tsZmmmK>B6&9H2mAS~`H?0Nyc2?+Uc(UjvUE+;idC>NNz1<5&$YaFgFm zR!kA^hzq42O&^v-2Pt}y`_oVfKkzzacjEF1RaPY?=hMlEs+?4&TBJL;58TQeDMs{!+X_00T3OzF z1qfOf0#2K|Qavz=LexLQaP}BF5yjDu6!ecnW8yaaNwnEdWCQwP_rdbnwE@s>m`cL* zU($Vcmq(v?ZagzE^pA(=f)<1MrW}&A_8IRzZ~I}N;Fy7Kq?J;Fh7u_FHdQi&wbd%R|QJX-jO z90YJ^Gkz41?nxB92p@!nKgEG0Aad;}36saw+!f1+JKxr2Z;>FYKXy&P6 zv}^USb2qACTf@~!jnps@nU|9JCea#tgRac3^Y!uAuKN>z7k0Gu<*VFefhzxk_d4q% z4aGdWS(2u9#++N>p|9~}@y+Ze!Yf#3%={LcL$5w=E}Y5UprWg1K0EO=JE!Orug-FkXJVYlOFl6Dfa2{g;&haP7me3Cy{68i zNt!TTpe#M1m;QzbyWvz!DoBpCrKD>>OYAJkYt1enud$P1#9ws@4osXE((Z&*qz31I?j+8XiI-@1i5nwP+ix` zbT}bVBu%@U9Gtd6G0z+!?;*-L`9&rAIgWM!)j7*5_kB`Ry~RX&6)h)zA< z@8=^kTkPpi-7`Y`T}gK`LJLdmj~+|;;oZcXrM!vCg!Vt4Omj&DGKs+HOEIAMHSR?Q zy;d_RpC1w z@x|^{>BOO-@d@E5(*uA$;KtZe3eO1N@*)><*&{J4&q%dz+ zF+W4>mELWL`BB1+EF+H_5+jsH{5js=({58cC1hPmSKu_O@X^R-$wfVhBPT=Bf|IzN zKK=Ol(qb{@XOiYQH{1;_VdCh~mXVgVj7uKc@3KD_5;+^{Rn&52@tp^91P*SN2J;AJ z8_zv4)&wb!$tt2R-@V0CYYb0&dZjoOZkjwSrQpv+NSSHi9)D(4lMxp6cIySe)`2sc z*Bnv7MsWsN)>oGg#QUhW7<^Xq(dgs}#gVFHR(~P?DxLjJWa{R&XW`S~HjQuR8I8lFHo<2OYOa0;+9H!c*fVVSPDJN6-NrdC8i9-=+KEuQi7T<&2%+p` zrP7CRRzXr)CK2d#=`v0wpf2enix3O_(LsowNB2rl1M^IZFlVj5?h@7fksW-Pg#WxJ zW_PMu7KARSi_rl{y=EC92RmY?o!{wh$Z4H3dz<{s=;UUg2crj5R~wXP|2s_zaaRT6%$Uyhy74l=3m0dywMIPqIf;Yk*hnn%IP{n{E>=5vmiXRPVp`n|lVBE^(xnW*& zp5H}^{)KQdd1EZKY!c~=>Chx_+hqu->>nNUsdM-fA>ha~Z#NKTzW$**M*Q-xANXgO zzEbW1bZK^nq*ftzBJS_u=1tByprl~!oHpIh2fENpQMqQAk1Yw-`BtY3AiW5=v93Dl zs*?W!aPM?ezJ?+<>irg--hjGTq#02;HfS?rOMkyBXDlREF`vPMcan;F%Pfe>0a9KyoZ0+%aJVB@qZ<^J zS3`{MXpt_syP66KC@xFH-%CWb963O(c$)B?aQ&nB0HxVZp4nR>bR~2yeIvYat2giN zD7096N5PU3;FY>dytN+X&xTqvs1`eh#t(?3Dt#kaW|lQm+R>hoAxTApM#et5)@ErQ zPRA|0zOm^_+tpUein;9c zt(xaiP9x!HQfnDe(hKXfK=u_NNb|lt@gFx5;M(Cyy&(|;R78rP@E-a%keiVsQ43bu z$~|b?=%$`n)#tgrkd~f6-pOz&TJMhTAJV1iQf()HHQU?7OGI&z2Kj&=rBMYJFCAJr z<)oy~D)2z^G@V}~1e$TjC{szSnGF2e4&V^m7Ii>xIWK%a;6{8h_i;alq`ID8$XRF_=Jwwu?8 zTOF!H?=NPLLA|s|RP&R55BI)Q)L_ZY6NPv8b=i}HJXMG}V|X9MH?AjdYqX?sbQK@I z!mQ(~NXq2(?ArQPJ>7TDitr0*f%mYob5mq}Z9RsNE{)+gU4M3!P>k@IzK@7UU;SfF zs5R7|_Ez~Kj+q4*K7!caBhL){*$ktut&h@)s91?Dq_?-bh-)9N;qh;q>_7=D1yIsU z9Q4eptd+$fKwr1^50S^eZWAr@X04Pc-eEIXy$adNj-nB-=$)B_r1rYtFwD8dJDN3e z*4L9{0S+lWBaOcnMkZq1vNu^9w`l+;uXQpU_~{mG&fT!;(2A5Bo43#=B%#vvC*a!Q z)Ij5zYCRpIqax+2VXE{GFXlP;LieeS=Kd48u94_YqUL0EYN~cJFG!s5%$s<=vD)#b z<+k6#pY9NA82`H6*WgDNbKLx~+*{|qOJ6@XjHvnW&R53wpKg=!IcToc6;m1T6&O$h z(tP;XC$YDe&0%DR2aUKr$Umg$I!nv|mSGvl-J`Wf7I!{kDT6#(yDY}p{8ND2uO7Hw zU2l1en}|xOatls+ffz--F&e~u`L|3L>W#{F3R>S@V2gNeD~74a?ncK(BC#X&Ya1j z=*b)=(qQoz3R;+cw&Gu9GI~?+4TY9hmQY0<_9-4iuTYSVM)APDxv@j}N?rzWdE|fz z?>kEU%JOjW)vKekEViIDH)q9?-y7oPFAiP-hR21e3T6_`D0Rcg(MRN4)ke#<;CI3n zo6Ql}3#P;M?5M5d&OJ}wfUiyt7I{aoJoa*Fx%VyJce8hp5I=+TMRIHTWiw9wdz{Rw zR=DA=b(^n;84q`Sn7aP2&-NEyXK{V}jvim75}(s2d@b2-L8HzWD>k{52o^{9ljQ+|gQBkfw1vaJX=v0U(LL{-pwe!%m3 z{zxs5)t>K}*&TF}oF{9v-KiQmaGN)@&HP0Da;)l|54_m8sTxqm{xAo(R$PC^<1ZKt z_?|XK_%;K0}fhiR4~{`(RIs0%W5Y%Fg$jQYYmYd*(=(M|44xZ|zc?$#>Wq(h3ztxR(>)r7pK* zDKe+{%2X-#$`IzZU;kx`OXzh+s##;JRWmvOtgmg4ckt2aP$5cwQ;DYHZIbNt$#dm& z{hbv_;*~duy`j=JE7SsL?(^GNDcQ6MHnLB*5$n)->sk zBwVr_f?E=eL#xWljZUq1XoRr|?KYBzq*#Drao7dlxsu^>CuQ^wA#ri$ueHZDFn^V3 zZ49sfRlydkDPV+Kl{_D4h;jN&CpqK{#+9Eh>y|9@dh2L^5Gfx?a{08L|9IR-*HiZ8 zB0B-T?A@=?iO|Xy5r!g+$!bkB@SP>2$X;&V6Xiq}isGsgoaqI!c`rapY9MvdGciX0 zdlpJP7{raoOBTfaN8V3|)gXh0s2_Ej%sw>9a(@!@@=jifqEUS%^e+ZK;Z9i%T=JX9 z5DC6<#I}tPY#@{+dp^>~ctO)ho;E3SIcCOg&z(z53d$#mB z&>+lx9+P(%U{hzi`TiU&VO~23ya!Q~aI058cH^umb5HIAF9}^iLLBp=@ z8>>uWaCrM#<-vmlZhkH@>PhGB%L(N9aq-6UKf}0Ref*m4I3s^SMElWur}9p4gJ8*x z89txD(NX+3x?h0{YBnYFTZ4dqM&@4LdABwnrQ^ud?FUk zXJ%yl)WZ8jZm*|l$0*+WY<_GjM(Td;Giram>-IUCFWDFOe(XukC5xwqfw@n(EKsoK=2 zlNr|@SSaJ!xn5nOEo?ToK5EZaNHSHr)8{gC`G@-Mcv&3so{r6u6y*3ysr>k6{P01- zmmDm3LiC|bc0lXkf`CYych3D-@G|1Gv|^;r8$^YMOjvQX8xbFCU+jz}5_`WdW@TOD zckU63|NLEvaj?_>*KqoU?f%@!5R_lmlUX&UD%KM&AdkqZwB=iY1`D!gjOEm&@`8aq znbi6y_UZ%0%{(i)xjUK=b%4KRmCwYk)f%bYs zFWk33tJ!|pI|VC9$xL&wC8o;e^KS8*RkyS#c@YuCz>I3@r<~Qyhf3cxG@oe5fE13!$;&NeY-Y&EN zu~}ge?Ud7iK=gbh-C?oWe85S_IiJ3~*-V@+gKce{l~k#4!@`DHc&5+dJ;ttd_GF0x z7wYvrT4|Fc+2Udir;G4=9+Iw+@gWA5JIJ6Mg7|n#oQ@WSZ|qU;5G@BU!JoUf3Xc-0 zNl{=q6LMdU6}owe(>bQ@VKIoiBm;T{0xI+lsZNGGWL=wgtkf@Cz{*RdCL}U9YF@a= zJWFcZ8kZC+UT(-qJp35SaRE**zpr0z7HSN(Hr`jkffjqsp)Rv&lVqR(%hWH*!(ZS3@fl)=A1ZO_R*DZ+|XVv8P`GwJ)x501d@~auRNx zB|b$iGv$|LmI=l)18 zPi2nr39;7t9C?x;rM2?*63gv!Ov42>=8XWgE~q1{xh@yo5*1WP|C1}KU+LW`TT7Do zBKtUM>E_$Ebj(l|ZeV0p&1U*qiAclVpi0r>en-BhByN}vwF;LN$K)`hhN$2ZIV?2u zkFfA(3z2(Xf6WJZ{EQAdNypp^kJo&0dGdMzc!FG-wFv-O+7>}>;8t_?6|LR!K>o3( z@GyTerHYQAafy*A6-nE~wA+vteESKIb1W-h`*`8C4Z582*Y zJ^m3s9XgR(3BHrjH~5on3m#R%NQtTao2!G)h39Ci1`9(_a@pKugU?Oqf|;yQ#X%G@ z1F2^on&kqZl8}m#utv(5g$#pDNLS6(*RB#FP#R{3bmH0Umtf*F9%CVR2}^YU+{I41#x;(~qlzXhI?2`ZDHNsrq!PsyyZK zRd!@x2T3&7%#-Da8mCNSbLmvJ5GT&7A6C~ZuY6W(%gA<3)L!hZ#Noq!@sj8*^5QS+ zb2qq2as#Ew4^z5J&E@2r(-c@*I%H`J*8(lN{Yn@)? zX1!sod6ttF1s}HwEMRF?zgryqtnzm4;$(@7J&zo5UN`^ohGb^*qSECM@` zO54LMG+`aDim`}%S+`G_^ycKpj5k6(*kK7JQjPKR-RTUrj!&abq)FwWk^w@0cb#Fm zD%hoFJ=%V>ZID|t@6xZdq(m&reAcNwh}C!{Cy$~x%vrvVCuN8_=w&Tv)gW!et*#k9 zAU;;la08o%bu*ya>piaFjJuffWdFPbqiJQzV?Ot$9K(D?iw=f}5YyCyXKYd1nzjdT z#}ccV1@X%Fya%t|kGDic@+jphPbB(9Swi(DkGSMfM{xB8T`&*wiGe0oueIVEF{&tK z*_hsqw#W4yj`~lKIKdtj{++KB)SovzgL&&E?J(Fg3oVB}Old7O-&`(59ua9D7%%8o zmJM93|ASN`V!Rrx!oy&KS70IKd&<4lH;^@bjJln@jU&k%qu#-}ZtFBdp6)gGma71q zNui4ZRPZ-ZRv2)JMudOfi~aBVH2o7&el$GGN&-MehpU1#>kA#5W%TDM#3%vra0*7a zhjnifi+rc(u}Rt!`><)qEyDQFFH#y8W+Ve=(v4d0(h)31f=!ea*!CD*H&08RuRpfjaU*Zk0==6 zaPuQzlNt$zJ?8JMk?Pm*MZt;0e_`Lo7t=-xsOjO?H)nujv50+rS{J2Rzezt8OM3<0 za~TqmrJo;?(xL;&(lZ|BUt4M|5d`e2dk#n1c<~G-H=?N$RHahIc9wLJ+8Xd%C377+ zP8p0+)IO(1BfTk*jh^Dp9L-t|RPIs`Y2tpx^^IfmG~EoU0N>(UvJ7q!Bq5iRE7l*y z6V^iz5<|ol6|n;ETjv-U7`h?*FxU@;aMv@iJsz~6mCi<*gVa`O>_AC9A&|>FK6a|lCl{>n6E3~Td+y2F(P_+qQ(FoDzKe zHw#Lu?NH-MN~|d;tNOIb*hlD30t={TJ?yNWw)w5G!;h*O9c$t@t0X}h@OKqo{RLYC zSQv)(q{2f{io1zGN>ZOpVzm;AuLzE;L4?8h9LL z8DU>mXa`TtG#wv?rydfMRY@k@CN4!{m{a3lF6X6snA0+ki{XV}z8PNB(#;iQJCj7v zC0iz^${6DdL;1}Vo490mKPW?+p3_I=Z3;hgwbIDTU2;2@E53Va+r4pE(uGA zOt|Z}YL_d_@Z9Fm7n$aAGHhd^R8<34z3Tb$WOyH2hf4WzTr0s#f0oX?%3*;xsE~f- zoTAs0u{C9b_$TB<`xKpzWYfUmeg0M2bG=1Poh#6+#5WTsr_AcXE~|o-eWoYaW@-wu=7u0lipK4zv6$bwJfbVeQkxHk9t|D(T(3TR_vDze zwyP#e!e-wXISEvc9UjKKyt&8W6^^bsUdU8{p=u0paz0{=*nIN zNw#6dLLd!ZX-}TWjjQOGY z^_1*NU}10mqK~&>GV;8b$g8FC7YLvUnvBjNko+wIdOR`tpjGFY-9ina*E~BI zEPiRri1c%pK)$@1`SHZEVmpT-gt&x^;KHtUyx)AI8S9IkWR&*swBOZ716bVC)D4CE z#kEBGjNtQxh?^bmBX31!N#@m+!)H1V9S?-hG`ou|68EX!XuXPUz4N5Wp~{Rt48*MA z(I9L+8R~U>IUCO5%Mt0Exf0uqep%S^VFZVha%=CmHeIYB72OxBhCaoqftcaH>l!PG zp}up$wk-OP>W96NGr2Wv@9s&zBsdY}jO@(^ra^1TYF#!*#{?}szMs3Cmc)Y<=W$T; z&3T7)pM0mI1D)<5&NK{H+m-f~vaf+^jwz*T^pvqo9TAzBUP5eVF+vH3c7m>4+gGiZ zX1R|{+r>FuKK#&8CqF#X`n_EdSu?hylx7PsX<_{z{HtF~t8>cL0$!i|9q`<1E$3Z^ z)DWd8@P5~uHb-Y}9oRAE#VYqkw;}Fj5vqRp!yUtVmC;S#Yu%#=U5rqI_tNf;u6r2J!R^k=)E>x zl7XK55*fq>y(}RrG1WC!Uo1>Qxmk51RubT?Nk8%;|Zx1=M zYOJj@Q7;!LW$)WOy0JtyFlL2RMlxVc#M8~hY0Br(Ft<1~5+BjnG`mZbSbX;ZJG&+B zpT{%CrAp1qyv=#Jv4=t~xeh97n`A|H{8!ZMS&7$fIG9y~Ptuu4{C?kmgDHA?}%hzj1$xrKr-F_0Ny9t%e8p(;<5Xw%VXre$ZY+=1&x96q(ozCjX%yW{`~JEbh8Z^M<2{?I9uX?)~`99~Xj}@N=#R^Y_JRXOW1`bGskc5&=m8)q9Q$p3o zg(@CXMb^&x6diu2O<$R7o~e!Eg8X1Lp#(S>+7@9iiJVDVl|S5Y%PNwZPV4Vsj%GfZbaO2V^vBwe!t4x?@uOI#FA~tClvD+ zPcYauZP8aTnTkyUOcKR{^Z3~+6{DetSC&2l6Kq@sen<&W=`HS21;TBE4zGV6kgBa& z=zbCw>`~cZmL=9~T#c6^2r7N^C38KprMaspcYJS_VVw<>{@4@xrdOVdETH(x2jax{ z^NjONet9Tey)b>*`TQhX^i|BM+Dj1(bV!tl)t5fm@bh&xl}2Vq($PV{LnBY=dMhId z_Q+$jzZY&=nW=kQ&;X@n4oXHnRMhW%n<<>TFl#nxwL%&4IB>GGpcCaI7&eXJ98V}q ziKw>wuHn(^6pn~QI98Wikt`#s5=lEPuZT9kT>A0A&thJ8zMt?E4>yoOz4~nTPq~?Z zYA%|&21EMOjb);fP10RnORQFe!ID89oDv1eD>XAN6kg+n%R95QigL2lQP9GqTu(RS z%H8-n!w=cp?gMHKH-Im1x{MD=1szBjdR|1|j>L@J{o0o^{EDWAmxAqZcbRB^SJHim zo=KSo z8UaQ&>ubg=*O#-ToPC`C*&NIUOq|s1nxu z&fvEKJ11FIl-nZVbpPmZu{~UCws#?g4>4m~L}uPC$B#_#;tI55xn7t3>}XQ5GfQZy z^<}jsnAqb!cRB!A!vCyIPg#|d4hgBez{sr1n5x_;8|4vb;54kMD+^(EF4k0+h1v|c z*34Jz=;HuY3An$`?BZ*DY^mzKXv!B|14FDom_%>0*GEkkg%@L6_t$-fG``!pdn@b% z9@6r;hFNNIL48ewSg8b|J|0ty3aj2t-VO{)++64|RR9{t>EUc7*55)4JdLr_E?pr> zh>DN!;wnxB>rhem1~;IRB-99`Q(E%Eg(IrdINICEY(VFIb_EReCBC_uarW4gAI~Qr z!!(AE#y|h8JMB6L*=+f+ssE5UYC$G)+Byo_FS4I0#9N(l9AjJidqFlZ#?CIx0mCkLY4x zRR)7POQvX&^FsT#Wx4vNb4x>`^$1aEi4*6+vST3b7<<&A{PO`U_m`MJIq-UMTwKjQ zL$s`qGh(497wal1xbX)&gn#$pROt>Z1Aiom$Deap73{g&UhN=y@C7)?zm?XpaR!LU$L^o zSrpJqv2xGdnLCjpM;f=3vsFTH*o3hi>>e2YgOKrUw2o|c7&b-UcyxWWM2dWIde6Nr#32#Wy}RZT4LN7<{d))5O1W3TXDe%?qY=%J~2 zAQ6wUKZjrHwl|Q#X{PE`P211BC;IgW0m9kwqhBI;`6ucOQd${Y!&bq>euFw_K%#T$ zxq*J$tv~7evD4%8w%jIpg9n<2j#%hyY&~dx^<-cw0dsC34?B@f*=OO=x zQSkkGwkzM|w*SMq|MT%v_w!98xcsT{Sr(7*UrEp_Da~O!z{i#!F?{@<{dhY1^e4IF zE=~RJbnJHOOzz#l$2)hW?**R)b4iQ@zu`qaK@-1ml=`fj)b;cc-k|h&l>e*>SJH~{ zZ{fMw3BytO@N^pe8m~Rf?)DFGQc~4fzu)@sxX4Z9-;7e)&}F@`4n#mlnC|)PF=Ddt zIKDf3{J3i`;Z5ZeBs*iv?0*+&z>W2|#nW*+V()jp4}{{+c09S>EA|b5--oggJwhsh z-afdE94Pr}@h-g=o(>Eh{Oz@a7bcM52L1tdVuuZ1I;p`zI-Ff*IyeZ@}%W=TZ zoy^hWA^T|wWxS!;avIqaw90Q#MDQ(axv+i(J_4>a`fb$0yyaSn(EWe30Jb(?^B1fc z&k*Ghv`K)-@~$~vRj@uoQmO`G!Gj#}easy%uWI%9<|u1mrS6g@Eu4Ssd9awuX|r39 z^jUw{pI>rje#Dfq`AhnCF!ip}Kj}?3Punhi+Y^YTT&Q>>KBim7+y=w}Dm0Oo`4XS7 z#zUsQzBd!9bA38c$ZKox<;q%M-ZB6Bm6)OT=v+n6?{6nWlVuUNNRGf~d-cc-dU{s3|EYtUn)(}E5E~J;a=$31I6o=1XrsUrRWXaV%qg8O_u;uDEu_M!3!@BPHNp6TJyS>s&F^)6v{OoQ8P)l z@uhS90!k3Nqx;LMaCqL~h8*ETJ${1xHbrRneP5>f^f3+k13z=dc6mI z14H{hTjr_kxmd&Nw*V3sl0BlfQBE8eUxlZug1FKW2A}QrZ_r8&l|Lz13-%R=V~8}M zm;h1H9pOlmdl5j7TM|zvB2^wO3{)SAu@3*+%_Pq_6gL0e z)svd2cDSnf8)9!(X>Gmws0q{HTv6rSL%lhBXGzEgWY+GMC{jTjuV4nQu(jc95bKdw zV(jgneK63i^U*Sp)^RQ32dMPj_%+@-eE}@HUrp*hvvogF8Eq(RdHrI18_0*Avd5)Asue)Fq|=eCBrXD<|aCY@h1^uM|#^Y`2Osteo5goQzGvx)~Etf41prTM8o#;f4E7J)kXK z7kofCwi9Oq_g>{fgk+@VTIL$=KCGYIhuo~9>2*ie`LicRZP?@l`Z-WsonWnoaNwi#L6$6nDQ!)e>U^_ z+WzVrJh54|_KIxBX3-f^j1KL}XA#vOYcDHD0u^WP6z0I*wa4iU385cX%q5vtGHSA< ztVRhQV>kxrH1)JBm8|5GSZJuzRYl+A30ZwsgZhr6p<2E1B(JWbpwpF38li6})U!<9 zcB}Y}ff^@Dt()LJ#5WlC{?RE^8d7a4i~`ERN!QGGwpr5ba=DMum#gQghx(-Pxl zo8FjBdv5Z0(Lt&qUrW;|wlh9&&zb$P@>~IY(@NmIbj)h9!t+w*D01mXrTUob`XM_I zsL-@>0b17tb3s&VqrdR!vpAsrtk#H;TxwqAihAv)F@;CRnU&D5DG9-QX6W!2S z;<{A0+&^gCYcL}B`T}n%7rqFiDCKu>wyj5a)&NIK@ISd9>r7CGAWaWoy<|B}EoAr$@7 zY*<>=dMaZ6Wsfs zkv2>q9}cDOR(;BeoH>hqzKNZ-a&>Sx8GU{jh50|hf=D`jkKpQDUy9Msb2jrbEd@5= z5nFt6WY~m^aDXroOWJke$Fw>IBi`i=vt})U_xYlHwro61P;%%B^PJnZz>pU-C?bNb zX$#;p(4Vyjk}EJEzXHh2VePMSD}E*_iGDq3Xe``V7qvvvdIO4)qRa1VD*>=0o{|WA zKxD_dKv#cXrO&=JL5)Dq&rdHO-q1h-}vwN>|f?5o`+T8h5QrI#Sx*1w6!DvcjduXC|`88GvzQaf$?uDVg6;jmM_}Oi< zu~=p0R{E_pKkE50ym9otdiO=i)h@ga7DH?Z6B9NKorVftsOiIiaZVlai z5$P%8mFBv!QtDS-VWERZtO%XC1s|X`UnO_HG-I$^!=q>Pg z@YxfRhmIiDHo6}TwO%i8gZOi7Q5l}QxNv;=8TshOn6IJ_6RaEZfk6l&by5ukyO;Zn zc`S{mC_wUIEBUgw`y#(`gU7qpN$sDi4>E5sy^aHb3~@+E8!&c_{`Zak&)5FXx?i|U|BJh~?uqLS-+c#d zDNZR+yinZTo#O7U#ht;OQrwHXySsaFcXxMp+pFK--Y40~c>yOUnLj3zNhVqAnP=V4 z{kg8|PD)PVLoFr!^!|_zyHuz}JTs|$5hxOO6}ULu6}QcMy1XJ%`;hv4n$9jRBSipl z2ux05&zU8hcZ4sCmG9R!#Cy6!am^O}P$wo1WJY&F^Q0D?etk@`I?-H-253GG*XSM# zh>%`qxjeAHnK-VvlYezHkLv28lx5NPllFf;m&fZLNIUh{tPPT0%YBjT0VizdYYrgywgCn23Em?G?|%MNyG8CK`E?AwRNR zx5yj$Qsa$ouMv>@XLayEYk$TT8EQ4Qh5%~on;XYUHnWyqvWR_-W@+bkAy*T{?kCVe zWUo>>+5J8| zQ7~dNnK6Pn#0Ux_nY-jvgtHZRez*eQx)L?gYv1MHH_>A?3(fu5xC&H@cOI9Z_=JS_ zv-7tzy7wzOZErMAyN;$dt(4Scq?vOXn}#Xh{uoDho-%Ff=s=HW2k|WrCqYeK_U54Rl@cZ~6W@x# z5(jpSyjLSZZoC~hpM+Tkx~3+d~Qj7by;zLJBWWW#V@DwHhpv}O;9yo%je?f_VDJb){|am@k2;$Pq}lA zg_kv|zy4glhe52Hn=plr&h*kNN8hw_XTEUL4^?+Pp~&*}<_}XjOmgVW`HtGjNKVV| zZ+&1j;Mj+o6nlB%gHx0F4;k|m04yxxq1_exi^RI?rEwXj`a0q7{6y5_r2m@` z=i~8=^Zb=!CVHX16!}-nj#ek$b=<&0v!0EE2eC)FW%i!)%N51*J!^b04CK?7G#e`* zv>r0+)_+Iuhs$XjSiBf~WpnB&kP{<{Iw&=D%igrxq&msE0&ddV$@tqz#oJK@=j#ib zq|h%@S-iU*cPjbV$KHE0Kr?xHi@&UPIInu&d9mhIi=nBRn$Yts>re$>RCYZmi-aol z!P$gZlWC!j3Q%Wp77f}v+OvI1sZyQYL3InhHgAQv?=6WVEik+%2{=m{&HJ z!h$Y;WUOM^w-Dn!@VIs(xny%HA2c(gT(ZH;_}qQ7?e*%(7wG4F_TEIB zB?gS6q>Kpj-*cW7hW`91PUY8MDh>&QA}H*{2?mC0xbR>xXK5mf(&_ft7s?m;2CbhO zY4w9V{3UEWpe*vR#`QZQ5d&w2NJyPqmJM;cY)OqLq_!t@#&~vsX{3sir@M2OYca;S zZtn==0iWfAJgi+WPulsCBHPmBV$rsvcMSp)DW@&QccxfC=)(e-pI|Y63cysRp}zpx zVl&SdYRfrA1z)KhLrrt#Qr8vmn-q7MCSc%BHF3Ccu0~Cm&IV%%z2dJw;IBL5$XPmU zKMeQ#U7%QxPla9&YqR31!fU1=cM38enM@OG6E}|c?rkabUvsUSa0s0@FDh|QrctzJ zq*Pg1oB{=TzURGFI`-?+Py_yrk08xHJ|Wx&#>NW(S7WIwP zw~Kyya9J%j39J4D)1jQZEpWT&f-N$F*P4pb52CMe|2Ou{sz9t)rl^2MlMQWC&GUdA zBm;7;-dxLWN~=<*T@l?zP)`1Fx5L z9)}!0dc4U@QGK3C8-xueQgfYm4mQop;0T}aDjtTC>HF%gspVH~skrt{RCT*xr~@gM zlrW$`6NqO>_Kg~C#3)OYRwc6%cPb`Dj^HtuE!(#Vx?tfJ26heo?(jr6p&js&Fd1SW zi&EkLD~Ro%GW-s%h!m{-$;-*nNFX3|V$wX|!Ln4Xm&DjH8kmQz^t|ifQ)Iob>>ZR9 zXrl}TtUF((7$5+is2F z+jmhP0c9z-l(xz^z3Cnn+XgEVZy1E0{8`OMZSqv|+pxwxg}N_Zy^reP-(Z3^$keVs zPBmp%b~?V7hS+z`o=o%qQQps862hPvN)*Q&$A z|HU~ENh}+X_#O13Qsu@2>g#tZ%PzBu$U-bo?NZNY%O&me(m~=IH0+knML?s&ifTEn z0e}hZGYZQ+>X25IGFvF*KV|sd^A0#zD>ME231)VC7qn)L zxKzQ|yzTtF?XR5MCCe8dv<&6`0gioq6fewGKJ%4+w2hS@3p4g!YVu;6r#w&Gbx@0_ z!heXZbJ6U2VxUEKaxcTwa}bTK!6(hi@vYFAD?%qIJRRVM2}yln1Iq7 z0wuVF6sI?RQozmaj3`5|tNozQCpPd_Lsf*+UlyCGivMi{T=AOnS&r++lOK5-&)XK* z02z}&I!kZ%|G+!Y$@L*>ZB1@Kdgmcl7#XruKi;s1GRuZkm5<7CLeLzwG&IqY z&kZO>qBZb6!A%Vv&$snn*%a{s1Av1-=rUng6%tT35#SyxS;;aVgp2-}jz=c{z?r0M4|kcba;TTS^4OIFYgpU|{0=QA34cHnh-Ft1wqH?wlm$0qeeGPR3xl0+YZeYx8=*==w@PaX?|_=BLALA)lE= zxHV|h>4rJzlKU-A(nrA+8ZdIn$!NE&4)IVzH$9?u;@Cv z46OUIH&%b?c4Mk4HX7dk)yqEDnC?hpnD70p;r(s>^~3f0za4Ua{q>G&W~b%XKZfQ& z%@G6Rq4>Klos?iPKlrXEJP)@VRl5|T*Ix#TAw!7Di! z!u2h6d=8KgE&56GJaMMw@;+OS7(}BbE}%)qcE<;5YE|ry1ezV3X0%!&|B<>5_q|^| zOjY0$>$uDX9WNUMapA+t1jU}s#~~|;k!D0JPhu0aOytjO{v3xw^J#70-rTgSV^y7 zKvZ|rXEv92er-l4!&=(pN+`C}$lO5Y&ZaD=*&Hhb!ZZ)aFC9IncQ1_&LrhVLQQ508 ztnkdrma+lXLjxT`|4j~jQ4EnBPtS(hc&K*S@G8&tskarlNG>as%YwL4*K&DTG5_<* z(CIS`uWf2Qwni%3;Rj8mN!R1XatX4k(y$K+Yg-W%cX>NfO$8$#GO6tO7}uN2Oaqyk zcSA^BO7$3TLogSHsYZq{FyT;|tC1lKfKtJ%IM^-DG0 zBT^ERp^+ywpR6SVI)rGpLX+fZ0N92{S)>3;-LLGe-2Z?W=0sWtbX@Dt!*dE=~tN70KL4JbUcLW zz8%SWUk>M&40Hh@DfjO$E$eSRHt*?$)ByQho+z(F@nRpTOni`LpPBJf7E(gk@2iFu zB&f}{^M0r6cz%Dow6H<`H>3P_21fe9n1EFZL0Sb@zDU4Y`8hReod3o5frz(%%=4ib zm^BpiY6lq)x6VX^jQZaQTIlY3ghiZ$e^WdDJ;vNb3yK8wTnW+bsJp7fJB4>7^GK7dTU+7$N2QQH9k|MhgM#t+@DtAT*h$EoLfOo(qR z4KA#$4c@r7Tr&BD*MSNHt>Dwrzm}EEz`_W`$|&bE1$;&(%l@!mk_)NFV{@Ky!i%xv zu9;kIrS{4D#b%V@DxI-_wJ_F#ZG33b5J$yK$%Jb3O5Oz#X*w%dqve<7nBoJ{Vi?t&%-+G*6Ji9_M7bR%*jG6KQ^+00Atkmb2;i zok`V~fIct;h@38yLAPKOj;`yzv&qA2F7v zV#R^~-VJ*6OlWm7eekbY7Q7G z0mbAA<1Kctn%PtNHm&*AE4K-c5qk9(AopWwC)WB>2B|_%M#xbyiturelCe_ToS)F~bbBkF* z)_zve%Sei3%F(|v8Mr6_;0!J72h_cu6-@plvjhQsMOkDN zA>Sz{7}bqlNti9WL$3gnpZP9YObavUpcrCF`OI0gWdsOS&RNST`7@cH2{M%LL!rSC z1jl2a(Q*Ne1`kCE!|%+rt+l0Y!Rst?|3?de*P~VfQ7HRcZpb3VgeRoXaEHm>!@CEV z7h52FjG)hRXzNuHdebyEmS&OBTpEJ!%Xg{2={RX>s;8vqB&JUeGC+->0Mf>rSe!8o z+eItP!aPpQkM@FKI$_!_mAo8tQns=&9#*=$682(-l0W@x2(t23f>U_~Uq)A`Za0Qu z;a%8|9R$t3&JI7~U<5Hnf`;Yk=P%6?vP;iZO9b(wghBiipSgNlWS{Q}g7)d9sWO4! z!|V|gDT_ddYPfZsn&-I39{}npeDoOyvR69&`50nFty0{6UzsK1V}7rCG^Lx4#`jfg zHBgB>;pqqypc_`_Y}Ft~ET?7|vq&pcV02<}1kbO9NYJVM0;4$|R4bW!eoHGl_^bmZ?f*aK+LAv#1NY3i+{koLJ`v+?hyv!khDC*p z(>n4|dUu1K&X;rgP~gnjF=`R7MV-}m27aHaF>C*{HRtiQ~I zLVV+el^=VV)&pCh6`THcqkoqNg{b3Gv3gb+l~7%O{GHu}0#cq5FjJ;4@rq}yMZhv} zczk>Cs>8UvXtQ}8JNenS$<4QsIEl#6etLvZ&0yLmSZhR@$z>{To4MyCvT`{n@)pT(pjg0^v(n<*kz3FEgaMhp6t~-tBXSY%B`g_fP=3D@2Lxbw{ zxLPO;9f|etsFb&*^JM=K&h`TH)?Ue5kDqzvVvBN0DFxDTf1gUl|I6LJP!9g_SM@l( z?kUI9a0U{90(qL|M7_)!?M*($GU0kafO=I_DFr*07{qcyHCyw=-HCQlf7@smMGspcWS44i20FYbD@ZI0zt z9e7LVMZb*=^baTAL0-sI2t$Cjp*BJnq@TMIJdgF`1Ef)ADIXtZcROX!^+=a2X%IGy ze@s6r85!h^>YD^Xs?FKYgU@buOtB%ftOC=H^L?#aQ5t*T^@%Yr&ik zrBlLG$finWM?Vd5PMF>xXchGR2aMdN;-NI|N?4qEjHLX2lE&@VT_484+W(6@F4#@` z2z-dVuj1y+z*i3%kATtPwcMRl8`;}SrHRAv+KR zI^7Mc@YE*n1M4gcP}X+*2^$@*dCt(V+LiTiNoX+tE@<8)cAoE-6&fzGF_wsFxJ@tI zMQ&tpwb5P@{jQGS#uN4Dhg-ua=PagYE&hZ;t|dLTxAmj=GioID{IWXa3;*JkNzv~r zXqw&aWan8P%7OY%4K8y>vn7zzuY8F(4i^uQAU);Jac;Ys%11^q6aF*ecBPuQA~71n za|T7N8mPI=4P#EJSGE3SL6>YVo&9qI{u#T!9R0`l23RRS38r=wi2y9XhBjMk1T9jO z#?s2*2+D`m86Uuk<`gGrU(>$Ml*O;^b8 zxdXDV$5SETzkIP~{ipcHcVA7dA#IkMP{9$A$jUAy;Lw@{Y*iFGgZV+}h=JL$uJjd! z_AaGap(*)`XFpKeS=Ni@vai)$e;(jpfSM`IW&?+NAoJTG^cp97{$}5XJpJmd9U&Xt zXoLeL4_M?aeW7oPMRH43O)^^i_0=i@XL{HW&eJsb`@iS_AnRNHz(b!K?}i`HjP`Ra zD?I~-^CA5=26JSe{GN09ycb8p&BWP*jmvO0Z?!ua55u^;qPDnsRy*74paSdi2dio? z!U-)Gd5OE~GWLIhRYp!L@LE!Xyfpzmq}R&>@2Pm%e(PL7 z&m3fBNzBWE$Dbxm1!m#bO4!hkOD_L1vi~`TnM3c3gFU~jU6syKboWv{qic{Ns%lE! z6RHT2`pBzx8k}mkhm-Q;Ra(32jX{5ga;jy-Ou4zdx4yZSUU+BBm61YEby1e9> zpeiMV1#&vsuHY>eYdVrxq)4rhwA5?=#1b& z88$abLS|t$iKP3hlQ-HUmYEPrCYs=1DnnWfh@p)iIy;A~m(GF1WB7+lTLBw}U&XDs z{lF)9zhO&mqc5~CJk4oD@>rW%%E!JyC^K%{BOytb!3r_2G`GXeGHx=y{p}UiF5E$` zIIHRwc`XguRZG~i>)MX^xbM}tzo)z{&ENGpOr1M(AtyGTJ9$wsB>zsi}~UrILd14=j=Y?9%D zYRoVad#db2N&Dz>FYWr+EuOKY`oT?Ld#+K82N&O}J4=^7$jn*y3tSvIXh<3xsVVbKh2p z*F>61ABK@?G=yp8-ERyHhWIg#K0Pwc;cZ)nOIFAWp2@g|l&a6)8gmPE3I^|vw-99I zf9jPEKXU38Nk=kzUpT=JHzku8*2;RU)T&&a%)c(0x*4;>Ht={8Zq&pE zd0Rot&5>%2iv8w8SkIdy+No^blvm(iJvyl7KM5&^)S~~paaDOgh~IbLI;%T;WG#_# zM+hgo{1J8AX3m;{+oENKM1r3j7+)T*)_*KT(g|~#uJ>;iZXVC$K*qv*q2^Y?vQky` zRbBRohA|lALkhJ$-kg=yvpzo~rf4~1gjxh2H>~+E=giABqGZe*>}a3u7koH#oYY+q znkibSNAywb!Mv6f;Rj3~H#3Nm-j)UP-pk8X+2>PUq@KAu%e2!%stw>;%*38U>H*R- z>Y{!ZO`>io_YuMmWOs6q}w4$WbGEFJz8*j~S)qO5tAVez~lATKg=_Q)}ooo*uz7D_acCp3=82*yy z5e>-xLJ>RV!+-4RzLKs1dtx7yvdmZv50PgnPCH3mjHV zHgRy_Gr3i9pIeJ*`YYWx(>~p^)i{QY*fx*g`%;o150Bg|%!md4opEZcY7}(U+X?;H z*ofTROX)cDt$3fVlylt1RRJr!Viwtrlr)fS*x)JJqQ%;d2I%I{%V)>{l)ruMle|s7 zSWw`#g_CT&muIgOG=vX4J{VN^*IzpUxb5|7w36Sq=l$$O?0~3?twdtOassM^!0YtC zBzM7_+3s4QOwO>N+^MaJnf82&E|pH+eG?jp2YlN9ZPk5fvQ(L3>~IOd9QwujTIkVF^Iik&8M<^={&JTAMTXG#o?eC>YLCU^=$o1sc;+;3a>zJEfWhHStGxp+q+t|# zmDXZ>(}RNAf{+yt<54LcE|6WQ$v=e&&>pQl^RB?e4v=)p5H5;a7yD0j%KRG4vjCCD zThJmFf$C#^@pVCjxSelh%F8mT9i?6&%8`%RP|&p@L*q&1LS%7s^Fv^R8k5AAh?&Bc z`~YK;8Q4B@#B_%(dBH;mIG&A}IFEcKveE0#pdTIkIxj43!Y$g?Ezd7TF@0D1K^d(A zLZqej_6OHMg$#!Y@2|afV*eo5gOFP!(7fnA=~2+4{TmUlm-}f{XfJ;&S`^N z5XV@oiJnlZo|dRfjEy;_VfI5x+SxY!F46Ku5~?Vdze&V7S<&5n@A`OTr@-+R|HeAQ zj%E*5(jn7cZGtO80uW&q+>J^{YD92{#?9E|_qBe+huzCZ7NIgxV}fQTnjOVF z4IgwTh~(SBz9a~M$S<1?Q;B@ z&GU#DSA&8GSH+ZPrle7YVcAeoLr*0FC#B_uT1>aPeY3Q`z`=>LLXGoXQva!coL%As zuiqDBH0g{OXr%1yeBbAsZ}P$;O;0z=D|g4jJ=7h;LBf7B`d1{OP3@B$6fwZB_ zETw6mN@6?n$d_6uk8&k3Ujmy@v;E=d+G*Q90!*cJxnp(?D6pNOg0-sPAma+dO=+Q7 zy*(Xi9X4eQ^`fSmV&_{Oa!>6?_Vn8pqH++{{d3;!%9kozr?;qzd9;H3hVB7o0lV7~ z?<9D*A{Jt<9H7Tv0U@UZ*Cnnw-ufl{`3$on?VTuIR*e`us_`+mbwzQhm@et#$Z5q8 z{w8JsHg-h7ODk4HK<2@S=d@RkiThUrP*`qaUfDS>A#X{kee<(3 zTnzi3g7r0eyFr(8LsL0f(+O043Yc-Wd9%whJnU1R|(i@E+Tc>IGoIHOB|=U@IMO}tqI1_zG$ z4qk#BUr$sQ9j|#wE%k*)BC!-y*hcQQj691RlE@*%+3%1jyo^^)ybxl{lGYz@|I3@8 zZAk;2p{B`|$>ZpYPUqj05?W~$RL|uyJz;%G*Aeb}{pnB6yw}g}bjf1jrzIioIiR+v zVkwQ`$C@k`+MRygRCSbi1||x(uF99&hwZ&@4{@01^YSPhJe_;pN5@W6ObMD4_QR38 z7NmHy6?<2{(`oGRS<~iS{(Yx>2pKxbUuMym$e#TvT3~{Vx(D%c-LGtFow|LX5c zd4|))<3!2L%o|>kXEOU+m2~>~X2%;PSgZ)NtQoALlE^KrjObquU*E_3d{*$b+7VS4 zzxx9Up$xC0iih%7(n;fKylJ*(zh_}-xH#P8CkUld-M{nlonJMk`f&Tu&mRT*Jh_0*$&TbV>~7Ja!)24oIf zdF}Q-voQZCO;@H*2@*|ucvbZ__cnZSaj>*Arb0C{Av^RR?cb=Yq5;LM6??2ui=4gg z;;X`YIGtNRRpKH4{VQ9b$~M2T+l-BOl!bgEFb$;mjZY;Zd#lt z&y-5M)cgCvWqMsRR@cr739sT*1&5H#2`A`c`1L%OI2Y9<%`3wT zRL>*Bp}&k|GSvtr_EA#7moWH_eI+pBu@H;4Ebh#LM3>uAyjTBIO+Seq-gkL?S5%?i zpYd~tv&f@AShu5$%TJ`PpkKq{@+a)VvibNit7jnvoAWpngfKVcQ*wtUpSIZ?4NL{} z+-R=uG2y(Hdv)Wy!r2An<_W`s*?7d5Y4vYR=&;l5*sUYDKlikXzS+F3L~B{r#;$Ws zs*~=Qg-+Ai`;8bqcdU~y=*d#4HXdp?cr~y2cM1eN)u+>Ylc|Vv?k-< zuB-8Q;g7f|qgZCGXPCl6d zyL;Oo3pN2(r=~m)T-}(+(w3xp&J}sp`KI$glGA~mj5D4*N@S9?Dut|b8L<_rra;+H+Om?(}&1vNhO&SunOmODjlpoCg6jeHIb-gOJT^8^F|~( zOUVb!T_4q|E&28&@jX(iN7wN+H{wM~Gnm`e(s^70yQUMk9~gUoFUE&im#eD1Be3#~ z@q2+8*nt$FU~g0CP2Rj)ly& z$+>VMyqxPgT{$$7qIYGJiFB;eCHJUi7ONLD&p8w|va|N6@IGnQk6tg;cc%)>!tRjC z`}~51ZhvIRl#nYfs?!>#=v3X%Dud)dRsMj*q?HdLit^f`%WV@N0tunLakZ-|E;zxp z%i9?dQ8lQDY!XF>E!iM32f0zBYWn~dI$V?xv1Vx$GWH?D7^A$h>|WNzU467m)7D;l zsSTYJt{Jm&(-O#TrUkJs8h?VcB*0%kw%_gL7nucyCLPndekXZ79lQm>Ts5e(i@}C zW#LwuVY{$W+|HMKuylXdhu&Wv4$&&!zco6CzKWtKSnMw9uCR%YjHGomJp#3#qKUR9 zX47NBQx-CM)kW@8LF;jgGe0JKTGAE0iV%fy`pe;t4YgV}rh;pSdy4oEYHo(h^~oy8 zgx(p=SzoLBJb0~Hw1%B}v_t8?BtvV%;{UqN7Il7n(YINaMA^ z?rc@gTHQSk`%U588KVQiDo$aY%Cr36wY7cz>W)A-%1YT~xYBBzM0}BP@FaLXog&=0}?cX~C zdcrdQf8Pn}^7;S!mwd*{$I6V@<*(mrXfLumLv7MUHs)0Jt6_A`H~$zIm){e7=IO*# zRZL6QV`HXG*}U~aMpv*%(#c3mtl~D^w)fO2t#eXZ>Wy}y3nX-oB2kzCEq$K*#XYFo|Zeajs7Qwd38dY7Qxf%*)38NEKPXke@O zOeNpUuOYkIVxpXG?pr{hGxv=v$ya;lB|2i`JxbrQyOw?U!V>V& zrss%BEfXEg+`4t{c664*7$Tk)=_nM7&WYLFAF7pd^j6-38`fkxj$@ZWM`?WzymSq| zZNX@rS9~5zR6p9UANesGi!axbTi19q*}i_<_#rsXC>KM5Kw?RwRE+FuW{kIqKR$8G zz%mJ6#BEIWa<;wu$vJT6HDcSI7bB^O#S$+!2jRg$F#@A z=)>q(Nx2rTED#ug?(<2|wW-xf)EsEjyE(9M<5$K2S(>8l;|#+$Rh`=GSx(Zq-Ill4 zI&N~-r|{b_aL$}Y`-4C4B6}N^cNFAIps)5b$`vEig$_Qm;nzYZ;3HI}5{UCO80%^a zX?ntuy(S@B>>h_Yfc}gy=f#z$V{MK5K$H@A6T96a6;1OpLm8X?WhFw#v$R2ruUH9_ z_J%KnA=xSNN_t&sNBJ%(Y8LYG&e@DU>xPGs07E6RJ-G%GC#kC&AG1k{af51V(%0}O zoR$h=VobOOr#F28kGNnqOPA?Y(=CebOi7)`-F9^>po_WZXGWK)e=n!Vrqx828+N{( z+#GM#{-7Y4()1E^%5C+8i&^G7f#!z@9q8wqH9lw(5PhvG^Yx<-92v2HQwMA1Lmo%k zJt>raNSDrJNk!MsF(>2GLsZcZ=@k=P_=+XUUMulc+gUC!N@ruP?;syJx00*N+-9`! z$4s%HhY2^~<`r=j=I?3=$sSJ1G7CzDQ~4*Zb$s|!8kVNAu4gjI9Bpb}ht5{T`><8T ztRNdH4$Db^Dvd9W&vLDG#X6U?{bk7U3!YDfXqL^Cin_*mbJUXs@%o#8|5DJnmsY!# zw^XWESN?4jDREBl;f|X-+-(HY`+&NNi-euyi(Q{)JyB}Q18eP_+5N*buA97;7G&Gi z1tTMr{Du`DRR-`Q4rm9f$Yr?U9-I{A!mrJ^S5*_~_!hzAJhbPQ!&$i78l@u&vI2G9A{T~ot&i>N71gW-s#6SFX z=v`zxtRUI_Qr3b5*zAr;dtDFNOX!rp|LYGd0Ou;rt{v0q^2U9}vziv`f`5|sF zBve4DHNP!E_%eEpw(!V_aRC3b&6RtClP;V*W_FXx&li#E3}%=dsFmF z);cRMp^KKf_GE}YY?_)bf`5yl5nP|*=7t_tSlyt^p{An9)y}JGlPp@l(E`VXjX6wM z^SS>c2=E7cs&i%}nX`53GwJPIe-Q5OI~5k<`-9Y=1m=t;VOI0Caf(j$PULI+2|<79 z=;R2NUgfmq`rucyy5ZQJiQ!W8z8 z(KBEIaI0Li_R`bZYxz10Ew#Z#orW0RKKAnZ8QBi9`sTijONb}d_>=e9?{D!qz^A92 zG1(TSmofps!ixIJuZq)YSpeJItEbKQa|7k#DRFqd%}7tE`$=X=ZVWw+30Irn9Z7=UA6OIA$k+HPj9Zf+3-`en%2jeYEeRKo6@cA>gU zg$;9urs00o)O(<*biW4Y@#$dF#0Rc{lMnkTy5^l4TT=8Eaz9cOG3D=_KI2Xer|`p2 zpBjDe*@1FSngqi&y7)3au3tf&GOiZs*HH63-j&5V3_2`+NW;%JB+yVsA%^sPjOD_KPdD?cB1lx&^AKY?&qDY}Q5Y(_yr;J79$8o=LR_vP^WQyx`$@2)}Uc zbOT3^Z*296$r(W}G|^PA-&iUQ%4NfN(T9h-(qZ>3H1CyleY31PzKlg!@B^#9(UNTK zLcP2yE!9y&dV-a^@xW25wwEwajQcAS^WmT{3`ot}Rth51?kHFD*hoH2GiIN!;=54$ zfeh!TP9w`o-C-0z>DOR+S$rA>O)n1J!=jSFSKgo`v}gQjLz~D!hF?;Ul=~=GmcRrO zHpd1K|!a2}9g5?H!G+ zvcmajRL9m?oqx||6XZG;S6`S_YoVhep&`dIupiX=9zK93b}>N$U?){2xK1^Kw{O7z z8J3V?QUEG3Q3~t5h>!a)J}0(QDdB?7-7h910R&OPA!d293e`t{=Lp9YL*k1s3TX4hZjX5n>UWKQq_K#f z4tdr3nRa?afcf~uAm0dCH)vtu(;eO-O8d_K#+jFZFR9;Q-RrsETwxlm+XqYfwP^AA*@TMOJY>@IBKYWM1 zUMAMHC96$$zAV)?XNfHwESQo{DH}m#tParSM~H|7Vi7p_QaN=r_mz2S#T&~QmR+;G zGnk8a)5AyhcpGV9i5cm95IlTNqj!+%Z52lR-0>ckZbX=DP&q61NV1@_NnSitgD}JH zX#a|+I$Xh>KUY=nEsKwbr<2ilCKwRdS2T9vp_4Y^?<41dxALIT<>;U{bj1uMV6ogi z8Rgx0eEQn;GFXp+Q`h3L_r>=c_s(%AkQPBdhiGqPc#nY}jhl6IUC->L-EBy)^jt=l7l;u6|6 zeAEQv2w#_e82M5=q(z`Ly_Fpt+hs9 z$mJIw9C`1R92Ylu#^vl2QB#BG?5`1g*70*m{E-nFt;;z!N@myGU$Z5$LGNuq^0z!P z7Ffa5=1u~YN+$l>4;=4kbS<6CJz;BgAYWs z848lKk7ZropL+9Jc01^4fu_Qb@A!rGuF!$Wj3_>-@3rp7aY8?Xx_EzPPP$a$pN*x< zGkk%sar>rRhse`1b-mV~TY{C8WWQ(x0iD@BYsnff#a#^1MoGM7YD9=;^R{oBD3_ zX(6x4Q;=>X2ja90pO!rb&`64hKvFFh{+jJS`XA)lZ0%cWZ_}a)Abi3fb!#A7sZT+K z@u=cLbli_A>3G^!VbJ?oUx!6241e|XQI`zUp`r8qsWoSn`suYJP@ne}5W_(JW0vwM zpp8-9o6pLyk?zse%(-UdoPA`w-E@RO8?LB>RfnF_hHIq9u7Vd8a z29x7nz*iGLlE?DC7OT6>V(>%J+y8jO@uP~Pq|+D)D2A4LtB*PMZvtx({8d*A`z*zs zKt4iKI;3+>nX$TDwmooJ=EBk*e2kRjcaDcy*V5|M{MqDIP(qwn_qRGfMS1!o9r#;C zV;-sH$%VSjBf)OMMsAywPiN2D1R_IXTXT$cU%qOq>``+;Jkt*qA2%tRSfxXJq1|-1%F~!<>QjBgW`}de-kjt$AX%b{Aa})^2W3 z{_Dc09!1fT08&YQo0>X>kyNpOuu9=z#-l;v5l02`mm0%GwD9F|#EiEfL5uS4?&Fgq zt?0{7>a&g4oii}#JX7V?*~4^QgEVzZ-<&ZmM-cFZO?NqV#u#r&=xA3(2RqTH@1It8 zk(@=g+acSQYy@M1d#xQ!5n_oFbfxgbk%RbYKgrA9Lx4V#nC+QX-F*`N48-Q!wRIla z)i5brH~liP_+-l9Czc@PrOU`LxcsNjo49K;_#OC9OZI=;t`bs~|^c>y@M+7&DqgNuF*EI~9 za1G=V!exu0DfAc$z8Xx#X&DD~os8Nm!nW6i!PSNlK*YJTblgZwN1i#s$6aSG8&=Pz z1G^K8Bt#0oqCCbJ2CG)p>C&{J9wjVja={246w~hPCOBQ+$k5;>dNY(!S{IabIhrz8 zFi&YrMhZng{B7V9h*`-uu!^&YXrM zZqE?M6M_{+xF1zz3i3vEZ2Dj`R$Efu_Ry#R*zFExuN@!`AJ%D;P%wO=hf^yM{}I=> z5Lc+X>)>Lc2Xsmpn^^QcCbUC>fTLljiMxG;4mrgeu2k6%6?$|#{JlZB?=K?EXH7lj z+kY8x{K0U(!x)gkE=mcy+;wcbOCh^lh2m>aol<cXM;t3^Ye+a57tONlmZVHpI$mXXQ1j$ zs}l=nhN$@HL}f{x#J)B_kg{9Jxw0`dIWTIC*SO2d0A5mTQ-Ti|hsR2ZU_WozXS$BV zSy}UFtn+q1z7y!I^lt6sVi*b`!q^ex9ORdGZ$a(f?4A95H!+;Q1w8duXgrb?+nIMm z>6&8pY6#Nuv^8PB<5fIHc;#UdVt>NPH%?TCP2zCe<=unAdelN(G?h*%JuLdn43y{ug;~9TjKO zEcy-*0t9yp5)vdpaQEQu?(Xgm3GM-cGq^j!-7UBW8z2OCceoGv-fy3~&f0sQbM9Yv zt&mJWLydw6gBR|@0vBPYro2> zY#U4kUmMOV`5X8)-1dUl%{t*GW1#DcSaUA8sl_jRG5YE6poiKGZV~>SO9h`d;jasisPEshN7p1^&Y3WQzgatS_V&(^1(9Lx+a^hdL7d0 zrOlz2eMQWr%F5U)I5Tc&I>6>B^e{JSZ_ILCz8)KlhxQ982iu^u@ScwooV&F$k-qT}o*{PT`< zel05p!>x3#`J^)=+v`SJw{P&_$r|mjqKZI1HH+)*`F@hYGA+IL!&+TKy5jOuxsmmK zRlN8QlofXPe7_93sO+7$*=#S|fado(YER}0eYR!44e7xYzvj>h zk$$(%a$^O_vk>Br?HwHE3GF-uzw7reAS^~FvV2)1zW1*8Px?Pk$op}WiaKr;9oxZ3(FaZ)D$a9-3*$Z+qfXihY}9xSH?Y1x z9Q2<27o>ExyS*~?SnoIeIgOYW0~owh3yo%hxy{t$K)|d0nQI8htiaYmxc%k2@|gBe z9b15xp(9KzQRAOcNBw-*AEIR@@|?6GM-mMM0>XZW^t#xOUcBeeuumlZcL1jv4U}L! z&n6OAUedX7Z+JZ9+fwQ+onM=pQI@=7k$kZSM=ZSk!x9M62t91E9TU{Hbi437XlPjsT zQ7GhG8C4+z#u4<1F14#de~~iMwSv@k6Hj6VeX1Z39;HB;^dvff9B2d6IQh2|k| z+jqt`nE@T6ZIurvL_c!KPr4J!f~7C^MN`X2pb}OJ#7xj}`!4eJ;;IP*cl*Wm{f?p($5$ADSPaM_?v`l-t`%nF*yRqKBFM z4Y#DBNZZ!R$y$%IW;vTXH=DQ-{sokIaCOe#NV;TxNN?GBAgH~HfHHRSl$ZK9SC&jB zM7@oJTP?6grFo0Y`JPMaeKb8wyZJnYSKq(DvWB_0Yh^ESy{Xb1f551mQ%o*McdxG6 z=K9-Aqc!UUBnma0E`75pSlO$XUZ*1)?Uzft?&RMjoIp?Hh?VndFJfFAMvhDn5+l_p z9*{0#u6>D(q0P7wp1i;_FxR!-7Lrgz{yL2bt)KMFYX%_e!8rIFrtx3u-;zmv(Ud{2 zWE&?xcRBo)@@vV+u^(4Vh<_y3bid7>1?$>h#Tzx)ddnl#q8`;VY%u>MC+7MaM zHGnk@C4;W%*VS(BSF4mI&R+)t?jM#{NJk@J@t=&TtOK=BWLn451>AG7nB|@>DsN?I zvw!IL_2ZWQ=#U!nh{By*=$v5o1af!OEapRiB7}DCvR;p1W#WBa5d~+_{|N#+*qPpE z1_Ks@^0RV-KQV4|=kCaNF~*oQzLG z`}g_OdRX|hY>orVti0=}d-yLCkzRF1d_{M)v@M@KW?+O4pw&|3U@x0PbhPMpbW`NaF={ttkK`jX>-@P93w{cremK0>ArSW8PLEcI4{ zHt$D@vVy!Pr~1f9c{zY{-5>3&4cu;W@=txT92Sr&uf4Lq?LC_IjcC_TJXAY0@m0=| z2$uLX*;4f(nH@9owWMOyWn?ruWY=Xhj{#4PSnjy1cNX2SkvXhme#Vc?IJkwXL*3oD z*0?|J6XX|Mv-2((3x=9NEVj0@xhI^&a=Q*sX|nzd1^RL?=jj*v{O0L;)wa_Q2?~e4 zfwf3r@J4WK6{62r70rZCbLRpErutjSpgyJ9BeCCinq_d{`glmw zx60=&s~1MQV(HB<&Q8utbok2=SbFE(ewSTx|An-qi??Nxj80p6LqXp9(Ec4BzK@qz zTP}v=KO2t~*20s+gEY*wuijwBL!I9{7Gs#R3($_J*zcLg1Zd%N>pU$BHY>$iUnf&Y zu}Wtxr4Y^J#~tl2yU2Vec(}U99&Y&-?cC}^3j%_(XA|2Af4p=f8_<}Y5;|4MAl6~@ zSruc&A=iwVlVhz|>V7S;(PF_1tKcRSs+-$JDR<*+2MyQ5P@vl>;os3j0b-+jm(*7{M6z^a*=H zx~UfR<+#oK6d-?H@l8hV^+}GV?v-~Q9UG15F(Rh6$Xal_R50zyv5zzoYp}jJ{uPiF zz7fjbvY#h!sbyxSns}B@Wk{clfh9#mNm$3$_gfTegyNqig{lNRZ9vp+` z#VlXhxs6jOsri zwpkEb`w)Hjg_}r`?Gr5SNpb9sd#lsv>E*$EGcNd81te2`^M8$`|9C?Yd!>Fe5jU&^KD5{EuY6R`a_8r>+OR)zxjZD@Ir*8D}6n3EBXn{pFExM;oW4a5zFneXDI#NtR~;RgN7upUac44 zwNWnlH6Y7@{u2u8Nq}q1Ie`TYQbte|z=6f50^9xB@1T1H8uaKp{`3l@%%-~{C{Wq{ zI-YaMrLIuyEs?Y0>gs7S2oy=uU~zX`NCUpycN`oL^ztkt=eut2 zw#qHS&>w^9_nuaNn9^+vQjMlo14nPxl;(%^EU!`we&2)n$~;<+uineM_5;7D5>x_x z30KiRfa!@LbLfco6>Ev;BW@Q%@xr zBeL`Nj{Z=j-@iG#aKIGvmL{+T@M_@lph-4}r@MME`&bXMx!(MIUEk3ZiS`0co!r~) zw13fI$v1He(^{%7ph1Hm-(Z>_zWVPE>n0-8l?iq-NL4YZ^V7d6vZoC05^7x(IT6Q| zewGT-N;IW?|LDeBkP%AJ4vUxho2lqDA?+3SP{h~C?O#tm^q)?*&%~@g*>n1chJ0ch zu8viZv-@J0_6x*<%>2SoHs?7OT0NjnfVETREws+YOP+HKQ*g;lbFuw}*IiWNQlW0Z z)U7D-oasIEwA48|iQa7PJEuo3)GxT73LW0a$c@Yz)ULEP-s09QwEvMM0NK^op9F@g zAmE){(3B^fdQ36t6d{WX<>cANwafv^D+ z`B9u}S#cC!BymC?wtYdw@yXz6Ee^J`cYa}Zl+~qlh4RzaniXl=-1FGgkB_ue zKrV{(m~TcP)rlqk!3VvObe`0!=haZfKWBjV$~O`&xa(@M?{(ecyWLoY`L>>$uKx}l z8VA8&Po3?Txw!hO1mT7X z>8F|VZ{i9zv(Bj!l$X3$g%cqQj`@v1NHfKtG!5}=?z+~j7lF``ZvXZ`w4KlM0$;zo z++wJ$AhLf-p{?_FL!pPF+9w(5whRTm{RbnCbPl)Yta%|2g%g=#OMCTi7C7vk^*>l( znvxX!Ye54kRED!q9zv^@e0LqOY1~c|rrsf(_D`exprO0eTzU5f z$>qM>-c=jM(#$Y#fQpW9n6*B>Mz$1Tu^tY$Ed~*YLh)*iob(ftn=0;w7yj5MmJI*- zjspREvVOnN?j1-7McUbFy=oPXQOR)C!tG$4kux|(LSXagV72O9-khq8Q67AtfB5FO zAwH&sDs7&!pORa(q0YwV#4==rv<-BK7StYyCC2_6-Ofvr@LZ6HWy~vW*S+Y0jOFO) zC=k+nwK{XPjdDd1($@kUUg?}|Cs5rB-LGYVz#rdE5XQd2ka-aStrJG3U$UGww7wCI zx|Yns?`WT)@h;T+pyG&7BnnWYwO|KozgaIdVY|OEZAM@}HYE_B?;X)LIh*M*nPw&? zhI*_+DIyT$12P3grlN;{{Zjbu5zVllXZXv0)Ydlq><6grwZnXQU89X9et0dG9uTA4 zapd_IwabHJ;M;*#W6i1J&UUcMbd5bT&(;-}z{?08esh8dDwBE*0-+~K2!B@I5FDW; zkwWOeG4X~kM=Ayf`eSMoM^%qtmGD5~KmybIf3P81UHgQB0vj_!mkm0fj(w$plzIP? zI~Ml#ZwTIcu__;gs`kFOa-~E-g;ti9ZdjEJuVE$su=K@7IShsp*ggIZ)k`X*8SzCo zd8xI!e~AL~OOuZ+a|H1ggG?eQlA=C9ULFI;xIZe-{AB%yF}13fP8f4F1CtGNERD)= z{ouji=6rKWaSD+yv*#-5Rt)7tCcAU@bSxNo9pULi7S^!P;mL@CP(5|1J3;Vt`&&9uDsN6=;52tANF!`k+|8E=@)xubKcV6)i zkJE?)z3@1O|BS~?r{Eo96^fue3TPsN+87$XdEsmP$k%2%y@wh3WF09bH4m4O(p=tC z>gEFKTKHvb5oIMHP&6Q}B6aX}^0j_hrax;_oRzd+3#vwrunPXCZO{J`yav^dlB&wg zCy=D~fy(oPMH@W@6aN|MlA>SF5Z?D3%LLyZ-ad+FU{kSw!!>SXQ-H0lYoh@L1+Dtd z5ZA^KF~BkbF~mZ;2jVS15Y&94LVpAI@by5P?@hj3hh?H}9qa@sQakp!e@(J4?la7L zZKJaWur~b&c;k+AtXuIYK=AATxhA%w63K>MnFJsdI0^4 zHdYS!hx)tkc`3Pli!^95-WF+(m(Ya+qhrcVn{UdFP}`F~_j>WY2HnJkNk9@=o(K_8 zsKl~Zr3D=KV%pFsHIcWks_x(YNBi7VkJd)7-Kf-;@f0P^Ep?-xEuK)7AsV z=2-a6Sf($)fa;mavm7h8lG=-RCs)G1?F$J(H}g=Wm5$-U&*?5%1q&!i{Y7P8{wGw{ zu&-!MYlBEI4e-=ItBM`|H^7E_Sz#!6MV2_5TRQ*!Xc? zCXG}3|3-Bm-I0r7)xV%Ze~kuK?>-!T;a~WlB2SVGIx36n#3>g>hROr`{+!R-$K>-N zeK*`1>Tu-xWYfOU55?Ew#{M`;u7R>Wf3;5oP*Rzj;RD-xZ22V@G)%Rqb^R{^CK=^@|y_LKSd-lky$!O8blerA~nF`i(z=SoWz1F9Bjem_C0`$drPB zs--Mkl%vzv1X}}9BuPZCjKna#-U-&*pF3zUMIirgOI61x$rF0}T?-ManO?7@&9&BuHC9kX{Qfw?yKuFX3v!pQUAwNe_U9AF3PlN{fzdi4j<*{iUk zNvsZx&;z9>jd9i<2r$%c0~LP^cU>5rRChnTvUk>h;^RW+*(HTSGR|k?F-W_-HLQE} z?D_kwoIspS-489Msx@HfW(zcUCP^PR3{uPRQJkgG4Cl#?ll1l7Z#Us_K=UkQ-$4F zKdW|g_#MvDBpdCmoqY-#U#frsNhS>ctUUPBY(YDDbD$CiW|2DG6PN(YQ0HBdY<1|? zk0@JPo0!|M!n%22uOrX^nWs5B|3SIjofNgh`Y)yqr^>8$R|Bj@{trNxEG`U&{ws;M zPQkv#p+S`Wcy0ysLmBncbh%%Fkfzke%Eng&%EJOCp_p1Psm;FVW(s^zMmFFaNqAY&a@8E&9Ea6SQOc+N zET7Ot_niMu#(>t{D_#Sb@VnoxM_aEXMe+3X8%vjng)Z9|yR;mUjd@txlUVJviqX z74AZ-nZ&KI8<>MnO7VY;1~>Nxd!5s4bbpm^K2(BF-?;njsIy{a+rA-1oJU}bpr567 zJfQ*)npnkw2Kn1>SFHlL5kv|UGD?&Tbj~9d|IB;elaAcyggYcGWy_M8k@ zM2|aso1X4AAWR;?8*V`Kfi!NTlLy1Y*h{a`G`-dCw+wBGR54$~@USguh zq$d6R+DRt1lEHcb)4_T$UW_`OEIAfYImMj2!Zc zVSF`UFRSPn9olua%?5(#xe$pdqGTO;jbox_!oqXMMfe? z<{9EVZRsg4=DC(#Zzu>dA8VH&-+Kpno4RaLRuRMi=ke#j=2F@w?8j=bc1(~4yjct$ zp@d5k!4JoCMYs|gA90VJdg`q?Z3H9kX4U4vf8Y=+m2f<{75H`3aH1J1?Y6;ht*)32 ztHvv;lSNdZK!9$PaFWu~Kq-YYs*4uBI(St>FF9M&1#b#aGi z7Q9r!&!W+d2;HAnjHM>`t<`OmD*WywyirZL;+F4WG&TV;)>U!ALsu4>GCGiAW|e^Z z9w#pst+D%ascF_Hs3_Jz0WD}ec;NY(yJLjo;;Obs`qfXUERSvz9(}=KMqyj z?VEQ5mPE#`eOvwYB=HHneWu>rZY~MZv1wIMmZ(PUlY!Efv@{HPE7R8=Z@W#dUGwwzD-)%6C;m*5>1v!`PlD~l zrV3X)KRpjZjc_%-{;HLzBWQ{%cHY1~?6(pb70D*2;8om_`xsds?m_i7s_q#FIcUjb zi`(;OiyT6G@wn8M-=!dRjEkDHp!4?9k z?d67{;|sL~1w4{+6*8L=MUFXOf-k`6Q~>&>d!mXCahuqC`(9KFdan+bR)_Gsp~3?; zzgZ4rOvf2g(jS*jmc|^Y32iF!S#@}LK(WR>hTh}E=I2!vkWMKyDrnJr8q|+_xM*An ztYvxy$qa~5<3|aDI`w5(i2j zr!EO4gLSs|v7_j9!90>h^HsliNm{lYCi%`GVR1Zd46H~ZwALB?pt__!dfjnlpvdP- zU|X+~`I&hO*x&Tc7cmrl#{$Kou|+IBQ&$Der~OFIj;j18P;9*$pX*gP{o)SyxPP zj=^gTr^`X}vtj%Z&$p-N_Z=(2eyB!)`dm%K)rBX3H}D9jzctg=I}h*_)ShXHN`hGw z77;i+5*ky*giiS!JO0O|Lx74u?CPDTsSBF4JVny0n)oHfofFXK)O^V{yMQj_uAHJn z2h@&_n|jzeQZdh*S9s1&WO53(pVK+fySjq0=6X8E4aoQvKQiFU7e7_NTI%dT7cwgm za~|@xC%zOhElppE7WnGl{^diu&dQT_M7UdrV%i?wo(8rg8G`<$SHE-;qs0552QKJe zMHZ0``(lj==m0Jr{WwWp+xSCi%&yyXHfE&t^PK67wkzuMf>7|y^-WFPKjnFF;r-;Xxs?zXi;0arsN! zfQ_+$9~|IaH#FMh-fATQjJ9H_gy6d08>!Hv~ZLIS5%oTv!nV zf{6uzpyc79fp?12Y$kvg1bcA}ClCmw_vHsFfd+-}-<2Zn=?5!b-b$B`{3mX7Hcpah z6c*VmBDEF~lI2{Qd$0z!j;GLAk8gfNgmQ><7IT1?oL3L;T_E&X9SCGjIo9!AY*4pH z_jOrH)Zr63HMP_>N}am2wVXDdoEGsE9sH2P!a~YjSaXXvmD>R!Y=xBD-i~n@t!I3h zjDsfP%d~4GWD5Mf%fZBeA7kgpM5;rMz2z7=T8~q_iz@MjQ zr6Tqx$1*a9*UhCdTFR{4lYy-)9s(NdNg@k07z*9#WY-xA48c1QLw7iux`#1S)X#tC z4w?0P;K~soU3;IW%pvp&I&WU#Lq`sB-ZAO1J-fv#AyZx%=s(9hW5ry`D5OZF&L~_u zovWXrbh1h%f32UthQ9G%WY?J(6*%rd4#xZ#NY8%@Geb-YvwA>k2THlb!ZR94T(|Af z5TulC=K@DNW1YAm*#&fm-Ps@<3ouND&DY2l&ci(rxvON7w(XgDw}!;Zx(JfOG{a`R znbD9-I~pM%oq|1y!$!)Rc5z9a*c~K+Cmrn>%%{}Z_E0ID-o4;@a|3hZMZy4v6iwql z`jY+DJ$mwAjktElt9BOduW<7Nf4Ly~gNg>(ki}ryx5#bg3x%Zd?ogra?9G-S?jQwr znBjFnW1XC8DU%9(5%5P-mkX3N%M75LTUagzA7kwivO zp$u%S9}UAC@U&q5US-{X-EPE`LYK^N)O|j_PX5o$bS*768FR~h`44X|hD%aC1y^6r z2EnsCnC|xQ!hu6Nz^83elz9}Gd;eMNDL)z%TOG+P*?w`bcg3@ZyFPHoB!Ro03Wls2^>oG^B2DQ{9ysC29`lq z929QAOQ%EwpOb}?3MUd_F8tu?I-0M@Qu)KKR448plotE2dL)jjn3J`W%j6hAq!l3Y4oXh*o))!|ZkvOGF7v1moRC0J~Og+3WxYSA~lh@B{#`@!it z_m{SK8sf(uS>c(j+)ck-ZN7K0hBCbM@*l6w0mK066u-EJVVRRYr$kqX`StV5r9JQC zV`uTv@AyZ(xfaa=ZAL~q+nHa&R<&5HgDD9xBSvQMb;qj!%oPj)Vi!$kFgx#`agrMIc;;1ctT8hU@2 z1W9lJL`Gd+M92MLP6bS z6DjI3kRA2gE)$Q_q$zSIi>7y5A<=twI?cVOoO`U$P=1}q_fK|w++pQTVYRE4Ib4ev zz~B$j#-4MK_f8CxOdP6R;RTT2Jk&lqEo%SLFe|snbFx-e6w=rbI^NXB_EBG4Ny^eQ zyx$Y8uXp25ht*&)B5P}E5Nl8)^StnECJl2G;~8oY$y0MKRHdIJnHeu;zU}8mF$9456iSe5bl%LrNKhLX?YOByLfN+Fp>36&`(X z$;73`^{gSxOgYsaezckCBZM27UpmFrz{42!-Sw{M-~$P?o5E&A(F4^8#vyGs0sCf> zVpLk9bav_ZapWM`Oi4>yc$Rll00jj)`o}{`hO`$w-x+FuDB?WrR+JMRx>Im0FGkuc z4IN-ov}INol>;xt-`59BVamxuY!(9~^vNwj>WXY^wdvEXiT(5B^5Wga%?g}5H*%e$ zope$E!Uc>Wb>1Zb@x8E$jFyy~_q)~4*`-tF(_mgMBwDbjRKWzGIp*B_d|)2;tt3gN zSK>cAdu?hu`hMKh6~uRC+AD6(p8sh2S67f-X3>xxek=RTuAFk&vis+7r?AnSNCZ}F zN6YOx?#qXjZ*zwQ7mVN)V^mcOujo6j9TJi34kdr92IzSi<^$tI^Yy#2AVWw0nBf*T zO4sa^p#(2Pd%;Z&i#DQ*ckOQwfe$}M+Ew%F)%XX7#^4V%XDm;*`Mlu~_^#p6d3(V} za~|V?I|b5 z3Y&&K=`76qOb^K4R>$LWkh@C0D7N(PN~uT*(#w z{u{Jzj*lh5w38PBLw_tkU%#}&fhit)aV&W^UAXvJ?X8xdH@-w{K*w~~NEuI)MgFpn ziVpJ%@H+1;CsnB6jbwB0R!I{|k78fve9aZgF!4AqpF7ny?b5Q_l*YX+xA_DT723YG z4$5<{lj>D7mXRr($9203dYqrncB;Ao_NZx@bDQ3EXZAUM7(+m7Tu7z&c`+66vg@xi z=CnUuOx+9pcxil3H>2&-ZWNY8Qe$S>{s|F7HmFD#({=%^V|lk+sVunGU=eju>*xMfn-*#9@H zs*$-M)2NMUn%H0lQ(?23!YyJu{nfO6!{57&>7IA^`FhBlZ|A!hhMoSDz8?^o&0if9 z7RG|Vd4%e?-dwjNed$8_r6v!=X`ugdu*~kECONdCg^YX=>-5^shu7QYuVF??7EXw5 z!6X7V1>oZ*zbq<) zJ}{a*y1AxNo(2X2|hY_3wNG zqC9@)71Q%(dwIVI_=u5I&wLZNLXy;*5S}s_D1UU5`_&;0QQ->>D4hrJy6q^!%QV7M z5GI*hPP5pg53c(Nv{UAr8ak-LzkK+wn*$%^f8XxM&-d5z;eMGu(nl+8*Cz;(*3J^vff<6t-Z4?B85CoNgu66HYU~^pcIYS^Png zQY0<&c?r}ot)Ov4^N~e%geg*L^IlY&ukA6OXMC#;9ak?qKBq6WeTwY5&FL}fa<8RD z4MOD`-D+rha12pi70Ct0XJ(&p44kzP%}2*~m$ACLfjPV1+x8&WW)tbj?K@xHk3D}r z{_tywe`xw>Kfd+Os=p*DQu9{2H(%*12{bzEGMk7G^UaqX8zV9bnL`f8BA@H%!QqPC zdxy(7Tfh-NcS{hdXoncC2YQ%SF3N$c{sH=ms+~5n|YGRxQ>t`qi+e0 ziMcB}E2TTTKfg(_dA{HsU#g7V+w7&cBU9wpYn?de+OjKSPj~aRhq*Wnc*T8YJ2{7HKK0g025*UA@1LdJGN_*t?<{6m0>E%cGV2n24BE zM!%V}XW~H}mTZ|Qp%3V+{6Gc$mDRiHa<117VAkJLAMYC7UA~O6*hyTo-IvysT%z00 z-id!RbklCa%EXx=pIR$fA9DGI7kU&zQZlv(Or+6{$1qb9KOY-=@a%mbWvZn8APnJy z##hhV@7*_HIPC8WN3U8RQ{9f~rVm5_q3$Bdc{pPn=YPrq`qNm;ynClJ!1H_)u)d7Y zAGVOupa<+_x=@rb?)>&CHErd`odKAfZ!4DdomEe}kX~&^M*=@_=p0!UurHaB)%zQ|$bpWTh$#n*_-sfe3}ie@&xuKCvj?VID7dwF=VQ8V*(0hd~4 zCcrG;*Mfay6Od8DK?WYBEQc^jPMTHg$yS-4q0%$+$g zB!+TIiQ@wPwW>Z|DF93;ui>np{kRWNmv19rB%Q=A4FVo{z*x-csQ936WG0$U@xFXj zK&0Aqg6AYAQ!j9|agE7*86DQ!?O=*)EOR2!00F*|TU9cfSmU9lPEFNqf+<_MqG&8D zYHuvlm8to#mzoBQrqKPpmd|-2-ZXQYp7#_m;egRqm|y-dhv2buQ?u!LM^s|fcBfoE>{j8{Q*?R-eiM1fGQ7HGSAlp;<^{)w}wgnCbf z5H>)i&H>+y%VBy_=zVyME+90+gfB8YI$rSyg&`-d<+xtx@SXHqI7AltOTb-tX?kR{toxYw7eO%pslb^c2h(DD@s#^ z`29l+S9_?sm|l`dF+C56Z~0}ybGU~wa^Zu*HUG+WpShle!nvK_)NxiVpZRZ1yGM;; z8m4e>`n!Ouw*4;`$P;g=p2{op8W2a#l}*5z5dYi%W`3H>vc0g_ z#Z;s&nCeT1Q$Cedc|8pUVB9@M>R6s_!B{q}H;zJkz4dNvQ(1EwawhL1342`H*VeDR zsf0b`MwGF&?OD^gKkJkc=?@^tJVdo`Btc+q0SR_6a0I%>ayaR{e_(4i-h_C!gGV6E zeJi8}R=Hbmo9ytEu5q;g%;LWIYOfh>e3}ULa0^M7Ddl3_Bzn zrJd^|*V#S$p5X{Ec}_6=RvOM^@BxhjNaE=D^QfBU%*BpPb&L%|fmv`mbwnZk+Cb@% zqkztr##K@1PWZ1QZy0`r6-n}P*E_aukddJGJzSvznw?Q_Fgek}*P`Vf()6j+*A_36 z*kgfpvVnIH(_8Tv_p3;?{B%ooOvL5mUc*=k&X2W4xLA{>d+U=oKHvE{FD-HQY>Y%# zo@>oT2i7ZDX19mFTWS3Mrvl->vRk9HzibqlQAGCV}u7&v;L3Va{gpRXwQjsrT~ z-hk3Q=HnINc4-lg` z?NiOj6t7{z#htyJOkCw>`u4-h&SmcEx}k)|Z*M5FSCB4fkM^`})IKi-trM`%M3W+* zEDagB*@b43kv9~hFl&Uf6~L+AHxk>o{wvpGQ9hD<|*C zem^^YKjv@@HL9j-9^jy!mDWu{j|ILI-+9LCpM<~-W-p@F?MQnL)Iesh0ecfY*eM%O zpTSOwZ9ybw_ip=Ea*pa)^Ol^NB069~7ncf8v>4Ad*VTEs*)BoeAK^xGfS?HbJojH+ zug*D(v#z+qg)|8`<*vGvHF&^$wGbr;I|}?l<&Sl+M#@pDPzC}P&guL-+rthMotjm%(b=SxudB&$Nv0JS zX6ZGaN1rsYCRW*o`R+#)VvLxt@fs%v$|Qa!!!(8{A7i!Qrr5JC>nM@0&H=5qn`eHh z7HUDE!Mx%gVgbQ;DmR_qv#oxsDlF>v3KpD-@OG`XihpS&kW@cec$R(Kw}*5_YN3; z##Ovn`zsN3En}%(Jqa5J2z;59#Z4w0i?2cUu3a4OK>m=2okS~?1QlHGIUNyJh?5%K z^PjjhUEL1wepzJ&VZrMcudY+0GQV$wgT7eI^zpHDDU|9um_|$_Ex6L)uNMKPb;y;b zm=5RO-gD;C{mS^)eM8e_d*GB?$-I2HaAM&92Vl(n!zE~+CZ*$tj9Cbp>;#-5rg&dR zgsLuc&TpT4@MNr8y?eQ9`XP%Cj5zb_eR?g(wg-%^ugA?I{L29|b{TNO#6SMaXfXe_ z%vkfuSA-4z!DlxU7b0{6q!-@#KWK>+@Uig%{stQi3MW^{Boxj~<<`@{Mpe!KoQl*i z_2cK%nWY1!&%ZqJe*=~O@EJpHHF~0dTez{)@MUIFF)Z6a`TOohineiz#!1Kati&;| zddV&-3vV*P+Pl8uaERb9TnY`{i5j=)*%xY|2S+QG*D}OcI3O*u#cK3K{I;-jZV(j{ z!;f;e1c|=R9G~B@B`52hdv}=;ugfifsx6@*F>_hR0kS6}2<0OsYd%zLKD^3aQ6Uuw zV!h}d5N0v2#`b~fj%d;NtPhK)5h-fq?EJk&1OF&EeVq+^5=Kq2p6Cl;j85!QEy)76 zOACK(lQvkk-nV`Jz6v^$Lo|1C`yADcX3Tz*$%Gu)?LBBs*qB_QiN{<^$P}4Eknvbm3@%!UH*QNA``RY!{?xRh8pO{IGNvQ^o!jjyi?5(cRns>)bV_NQJKGC8 z>3e^wQGW~~Jw!SSd zn}(b3NZ zXIf%EIc?o))H6eK$Uhnxa*-5KxH*+^7L=ENa_{IP&+muNo!V32C$e9p3OAeGOOhP^ zxy>2j6c%c}bVa0vs)~l5Y5!rU78u_0CCIMP`@QoFV60KNVwq?E9F+Yrz7J++r_=J> z4rYI1vDw2STWt0j_>u2s>+ZDi=YTeC_9uJaYA!9i^3sSsINHspUOtz}Yrh(dOqjIdgG-`FUsACS zL~=kcl_Hn1&RjGsaM=xQp=NA13+RNW?mSj{9tm!>>rwnZ+fxzjPrK!wNm6AWC8pd8 zbvENnAdW6F$mk34aWh_6c7E?-dKO*wDb37G%w#Y+Fve5e;k%9#QoT6A*e&PRwC#rj zt=g>^H$mBu8$cl9;t%mLDbI}N-!840!TFEfjA%MnxjVYf9X-VK-qP@Xy1X^ZRLm4M zZZa5MRNL37fFt%+ce?gya+=vb{n`z4ymjb#^5y<(KrAgg&r|R8C7qh5=3eS*2bBbc zhAkBxordeRj?npFXtSY`m>3+oh=^!tZ$D6+LyN;q83UO!uB&rVVXYgI2n!2CNF^no zLZYGj7!?`5W>YecRVpHkx4*ynJ8sIUKMLDRdD^<_dEnPF54C6sukN#pg&E^}Y9_OB>cMD*KjC_Z>N^QN?SJ$5;#tgH90@JR`O7s>gooptYXf`RjtyOR+c9x(LYJV z*U+hA$w}2X`g*!?Y`hx6>T|jg&mYCvwzcNc)L{12#wg_VHRsDbj>w_E9R$QY@D(9@ zOsFPye*IM=d;zYR?qJBIVO=P#mX?;9@`Fq2hIV!3n)xuQjL!#5OibZ^UQLbM`TZL> z*~|x;8csH*5{SmBj9@FPW_bI_SLMB*#bo6elR!5CF$Mm2jeq};Lc8_r{i<>y=h)$) z5g`&${D;T8SUryV#{^YeOogN6g(e!muIga5K`^(L)6d0P3n_c?{EBoIr!8lf$O-tA zhpR&x`Bm*k{ij7WT`;E;7kar)gYV+Z#|4e}H*Zk$xCH(D^RmuMa@^-Cv{sLe_}`^& zblSYn`Nn7t=##6wJU%k7!6LB|q0<{oIsUWK5E%-krW!-tdDpkm-z}61{~RvQE+x)a zXpL)42)mxz3JTLC(kFaSa*&WH>3K&WB%Gw}cuJn6JpvUQS|9`dZJ&pQMSRo2y5Gy@ zS7i@nrdn59tLzfF#WBoJug&m$N|`}Hb{hAq)+2)Vqr@Z6nN~^j>pZHA$S};lHz;C~ zlU;^mN1K~tE3>S>lOsa14C*xW+>b0SrIc5wL3PZWHPqoDW8BX3W~-$2X;t|vLiUg zD5~anT4dNRAcrzCpEd>-!iq`?>g(&rtfLW{3OFR|2BP7h!FuZ(m!6Nl1pH%kl5xURr8>n<}AV_IOr$l+%6cxuDMw zO_DUDrJ@oi9cCm-Qd+v5Jh+5qG6^XeMn*n*4AMIpe+cL^+&c8TRq=58e;9kqs3^a% zeH2B(p9qMgQc9N~NT*0hBi*2M_s}V#G}0XoJwr%$N!K7TbR#vu&|PQyzURNr`EWiQ z7Yk*{%(Lg&cV5?Z@5hFfS}-cZ)YaIjM}aubs{HZ2$dhIvW?ut&D~tIo1#vYU=82G%c6> zbd0m1Om&~)V-VDlrIeAeCY4Q(`_p89@wPO0K1>l?GAQs=Yn$i(_+_2)Yy$%FNy6?c~vy$-hT?VAm&? zC%29bUOUjz$cCxzg{T!77DT^s`~H^T>CpOAVQ=p#Z&_UwhZ|{Z!=}7sXlPDoNSdT1 z@Bz7zXCLxbPn_HK_|i4DWtXmMNYxI8e*C5YnyT;18R%?j=#mPJD|Ao zyS%|6fXUjK$9_FxE6C6SIc4;5GuF&$RL$FcqZ9_ShM238#s&>vyg)ghGzz)r39348 zAX?1Yha~^HYBn{w&4VrG@jRCFe#uY49BazL&i)Fzvhs}G1x83m;9DmoCh{7B8ixZ< zxCm7vie6DEZCW`bFKu-L^$3!O2kH=TDa!~=Pq&4bC3!K(7z!{ldV|VB$jC2>Nb11W z!zE|#&qsZI8oAu-y1L&(#9jw1Gc~?Fv9qKg*Q=f-J@v)pZK{tEBJXv^Jo9IA7gVvp zb;+!8Q&Ts++s;T;;Uw^C7XM2~!^O)}eWp#nL`q*vpqNO`Yd2$DsdJ^>V_kiXZuRdF zYc!o+iw&|Vl>Ap49dd2p42u|`T}usW4byGTg|Fa7x9RE{+Nev~tR$iD924O7={Ido zG&LE#wNMhnO;Q692`fltr?6SkTTy3d*WUUE`Lk!X5J-jvoVQG?tRN&aSb|2bhB4K| zL~h`H1g~Rb+RV%>;WJxM13*rktuB^x%S})y{r03v9pe>C_I8%Af_Y`+2z2^(Az3;JAti#LV3OvJ6>HnlJF5 zC>C>>53DxV_gZJ?>0rr{xs%&7UQ`?4MR+;DfSXDx>+(t~XNsMCcow&hV6*z(J09=9 zC{})eB%^h;hr}G+A3@&j1$9xVt-Df|6o)?c@_X32IQ&Y8)9JXa5%qg(#62UyC1QXc z?u|O4EYS>ql%!Umw2X+NU@aQHE!L}Trmffk!4aevn4pl2>PY*_U(-gU^)gv}Vxq35 z=56J7zk?;rvjm}x3i(qH;aJmHh1j8)N!jEOy1wJK8!^g=4nke=<$GyEs8|V~wR-+q zxSCckw@!ZlnSj7_rMbe!Q++kHF&I-3-gh>>_#}a@Y7byEm)j&s@@{<@r?f+<0OyeC+7Z5q`Uj~Kdz(D$zRS`#-PEuT4vt#?Uv&BOQMBtZB z$qm)lonl#Ef736^8td2j`8Dj!oUewQ5I@j`dDHMQ$Pd9vysg`BBl$ymJAJ1ulPcIl z>FGO@M%z@+|5f3)0~?vrKD@(-RCNuFn6_hQNn7bL_J`+}UY87zMv>=59<08C*|p@S3)bva_`0PBW2Gy39WWji{et z7IcFhbR+A1I;3#&?*F2xAA++LY7k@VVD1;yDJuyo1s5JID-9pY+rzLN0s;aW=Erly z{46x@^@|v3@Ura;9pY*m)dCyqQ#vdG)N41v{}@Tw2HeBm3dy$9Sg50~Is0iKy-^$?8PDg|VVatQ~#?I;vI!lKeNF~3((T|{er<2cA zqHPj2;m8~&s^|~Ld-{#`&6ixdpo7#*OK6leRY~}$vM;ew6A)5qD;Fb-eyYdy8TOqa{<&N437jJeL7$>VIXAl zZ6_9)U~u5l+T}+^@;zFUkDJ$k|JB<52&&@)e3*Pu`Ogb|3v+V~qUa&(=1o|HyE}TN z64r3lbh%o=P@t++{;Cc~Y@ms0b-u~KY)$EevP%h6Gz^T498GKMO&NQ6`S~E?rKe{| z`MTYSL4>J#E&oJUMvMI9v9Z|}&aC0?skhg_M}T}wmaCz!>UAz-=Af1JJc$nEPx%2B z55<_$7jr{cLFLi+)Pfy`vmu1MBEU<@h{w5LKTZOlYiJG%2jf0LzU04x*64b+oQuHy6To=gbx(%u0dKt0X zLvwbMwoz;7=Zth*T&fQg(a)Y%I0W$DpTqn)w0&}Q)ldj!KR}%{^!C1LefFSP1^@fw z(n>BW>-pJ$SE&Br)R(ihe>1bL?KI)0v0?IZbbXykOVf*Sa!Q zfdS9dn3ve8{YG+wm0zV|?$=hCUgtY)IFid|Jpwe0$>g7^b+HWP{-|RsGQ=Ux*TPo^ z&@J*R!d69iDyH)_zSz+d)w(61Jr%zFI~G@2dH(tE;X4{#&^nSY%uUUbv6biaP3sIK zE--uD4;eWYb{txZt&iEVVJV`Xfg9 zy1`+-RXbjq{tO{+(CMHCqKzNl_f~zDB!BT%S*Kpj{>Md5R3S-;b_+LhSzGUxC8Vq;B50_Unmy7yBh8rKaD%A0A~Hoj?I}6B1Yd zhDu3N5@pJ44M)+~?5EOj!6cFe)9E|);MUgj=yktvY7~!DuZ=TbElXHFl)2P+a$>@> zSu`A0#-hyA*0E3D=j!M6_ya4P9+5eI!Psu{YdmNInWw1=smskgk`5K3DoaY68;Xi| z;b&+_ODkeE_5($Ke4pw5<+GI%_Ijt6w2@7Q4sCl$xrMwA(O$egV}&8$kIYFfHtIHe zb;krrcpqRoqPjXm5S^3!?r3@E#_X3wmyJJ zedbihQ>vuOf;OUx$MOvmt`=W4yj@d3;88i`qEBI4xP6@$ijsw>)E6;2im|4Zx+R+1 z?Ll2vr=*T{8X3{`!rkp)D?m}Kp|Ag&66$v{kae_XzMu};(F>8Ya7%iu<0tm2Dn!HE z4z~Ip13odRV$JPwcx*)_Ly7KF=qO6n41h7b#U_(8X3F`3nyQu2&!}+J|a?=Rn(J5=b5F+_+`|W{tzB=2$7SIw?Bh z(&LadEc&Miv(=cY&p#>y%hYG9Yz*8KvS z;VB`-Brg5+eQU&vPe-i6OF*om6W=)KBRCruyLc!W1Rw&CqLG&=@15E!jMYQ@HnfPLSn^=$UaFdTD#Ujp*o zRVd7n45UUV|@lU_<|!1hUv$_~`b+(oAvR4Uf8{ zN@t~W2rQ#px)$oef0p$p-RupMAffc+(EJ6p-7c!hwad+tz-XOIAT< zg+S5Odbu{t*L1*WnDyc2XrH50$hiq86kagtv)8z0rd0Z^RJ)}rd;gu2Q{PHgt^L$5 zr^CNH?niEi+J4bcpR-0Srw8f0CoBgs?{~RPo(=FySs_Rgu=(#-2`{V~crE1zQ?jsF!AlWCqpm56yGhM|K9lg8n<0 z&oVvV2&2`AH4UrnKJnWVcd4<^{5-b)`uTH0BsHs4r1*_hU2Wq)MS3D?sa3jOe4$}C zgFc+J=#Kv_gVNwXzf*}&kD<-`z-Z~BprD~&rHnG& z(flVJ&nX@3evs?x>c;JczS_Y3I2ll_hldOlk5vFjh_=4!rPN503ParNJdyL9hD1=~ zekIiDG`F)8(f5mc5$~ln9F+fpf<9EyS&Ym$N~MbE^(Z`}l}&V_jH-Iu-kDeP*Orow zKn_;r48h=jp#tyi5`-X=$5Z0rMw$UG0-chHri{iqDqhg1E0Gfr#DHFhG-p7dg+GHB zfS{^GQZC(b3|uSv&mSJ9LiB%afNngkcDzyF)3cF_ zL1|p!JQXFgEFSn2G02(2-tdO!yz9qPhv&q0TrZT>k|oV|o0@oR)?J6VC!yUhEgK#@ z5|+YHPL`6?4A)Tj@bXF5o8p?&)2JxCk@`4na(V`ay0kP;{rWCrB?X10SnK`N_Rs3E z3R_mpd1k~=u7dwMtwF~5GFdEQxTr_1DP^^ahywuIZGh2WN?H4I5iH;B<%vP}JUh>G zCCZq2G(*`WDKUW)pb<)%Z_={|VN7=2k5;ETM|!p;p0K0SpjBJPUPB5vv8G&P5q7(B z8juqHao>nW{PUYRzU*i=I8!FrOTEV0l6jjqWaHFNJYsb-l>Gg?;SpaWbJn5osU?Zs{dX1ziV}uqK28s&3VIu0P1aW{-83CGj zS$5GsXLAW4J^6qh-s9rG;A9Yk0N!qGZGDdNS5k7TA4|z<-8fjhaqIXN>GM!FRzb_q z>G|1YtJ_2bzPo=XAz5>i`8??U>d)wk)(eM+7fq^l>@;n3hOKJqT>id%(b40T+k9!FQAbA`ghpKJWwAx)!ubVbV7RIic| zWTvxV^s&zL018sKB4aaP0WL)~9a8~J?@dnZE7)qZJ~&)V6vEP4cG-^Fuy=s1%f&6=%x&s8O-jGN|8FlSl7M^Di{^Q^QtNbcyAM z**~J#(*R24`S`vQfxZt8T<}Af?71g*?Bq7mhampZA}8la*eD6{b7pDdqVKo|GM+Tn zj(poE<4g9|R#s~dnAhKhgoVLML>B%m)o2f*UX++eL$&OUS2jluCIC8xT&zz>=AYTM zUk^0K3i=$u96Nw)S4)RA&N{EwKd>oJ?rK*j!uO9P+0b(OX+&wk<1!~LuR7t*6%-wi ze*l;S!vd`tVRUys&hXxK=irflf))j&{>6DYQ&>gQ#{e29hZ z-1;}0byrr>-IBmk7n{E(!LP7>pdKLI{U?@`t`+7JjACm>E(8+sR*5I`VZ9(`)#i}dpRM7fcSq@?RT&fq~ua4DDT(`H$WI=|BGAt%ZV7^(Fnu-w4d>chBasAbSN@ zSssVaPl&AUi(LtaBXB2;3R1EXy!_0xnucl|+kMbDSLY_J#Bp!;kFBpq4Qh@NcC+qH zP3y!KU7u+#(N%E3KKXPPGPJMP9%w5ZOSdxhvj50&iAVjGX^cwrO<@- z&KIBiPzjS_&;}wb$9qz8E}}`lA$ag;ppdH~eQDc={LlYCNOsqrTtw?!+^0}-Gp-aM zDEKgmY;FsIS=YrV#CRNGVmxw-T>ZNU9_9G|qSZg!%eV4gdlo1aFdA4y2ON#{{KWjf z1q2$47~^{PFg|^Kl%FDhv0Y%0bBeW5}P@ywBH=)DDOv zdgQ7^K>X;*$zlvc?jc%)Rj{I8 znXa~!7Rvwg`}@x*6uM%UsIig^%OhX+L7&?=*}mR z4NG=O(3%H-eJlQH zpUbBAm1g?@kGnv)2os6G&EhS5Iz=(Cccc3?C?YyMHK>Q9Gsyhlj+}Bz$2X07Fc^A@);is3zuXC zh3beZ7&PL?d2`q)bA2~O#_U#XS9mrtfzI$>jr70WUSBZY4qexB9lQ7M-Xh8Z-+ijP z&x(;=RoEL6_SgbGTAG=^r0$iK^KYc&vt*oRN*OJf2zc}CLeOgv4sj;d{3Zw#FHc%U zvD6>lml*v{jG+|%j(V&;^W!uz)%cS<5h_`8g*Ow4I$hegUBu7oX zwInAN>kfCV$KP&Hm3*({es?~$#YFSlGBP~!x!DVJO?nC#V@6;U9G+<1=d$szvOlOZ zJ==T`ZW=~`uEA&vV9GpQh2Tnlo$?yJ#LEvU!JyS$41_E>k^B>z%uRg-AF)Cvzjx$6 zlKOJ1I&$ZHarKA%9iN^|Jnz~*dG+f)2{NwZ|7Zas_+yzzw@+~0!4eUsKz#Dh>|p@G zWB(=#GO2^6Uzc}))CVFFqelB1M?UZny)0m12nN7`zJ$)zS7KLGKs`vLuSlDPK=+r(BOnsp>FU~zActaJiI>PJDyJPj3LQ2hYz`xs!%%_W2sCn1G}o7tD< zAW!k|@JPnT$I~U+0u~TdRf3t1!S_cQpkXU(tx>wR{-^$^ZI+M(xOKhDMpL7UR(EIU zN-c#pWmG&*tC7J+kL;$ot=P3-oOQhtk`~&eUzk(Kx?gDU)B!1G>_?6shFx~;Nq z^<^F)z03DI<}X$@s*cAiMxAL`SOobw+!3jZW$WYoHr>Zd^Lc_4X}k_j{Hg%vi==}B zX@@49-t>_<)E>r^Icey>x_9T%xUx^MVA3>X4%i}(2%swf2q2%`!au}BvdZcx5ny!2 zMo_YAP-75|G|dSB>_@|Joyf{CHaE|mefqqh7G=Qh^dKw@4|K+^{^H9mz7Hw#>17+1 zFKzCCyz*ixw;-=U|M1WoJ;rTrh)x$xeQZ&mNK&RWDUKQxj3^28ySNF|RMz`|Eh^Ra z=x?4|8OID!-sG7~zQh#_ZC2pOt45@3xKR3!@~(xEZXV+n?Cf`yRsoINrV$sX4v?mx7nF&x#HUr&8A~ivc$MPxK>zaLx(@ zoq}S9pwv7E4KMF$y+zjFnrT~2za0RQwq`pH?HR?>#ciS-J5DCUTJC`jSQdnDTKxbd zI|e=;2GEh&*zFoV&?Kt|`wsp!q)sMr1H-FV<4?2maG@n|N{5PGRffs*1S@pq)R|6; zGXw7YEf<3`^Y~h9*Ch~%HF`Ee>HAg>WMY}?Og7sDD46l*?#7nDA|`Yy^BeUmEb1g`kMpMtZDyjJsbwR1a!3zkoOcOwcG>SJ)S}MzNQB7=9lL6m0v>m zf5V)zzE@R^S5zEki5!PxQ`eQvZN(dKQDgVfO&9wjy`Fnj{0@B&K7}FmC5eQ#jg7-3 zft2*=i>J*kc+8f4A8T1W3LGb#1zCx@a*BdZzvW~C6;Ufnil%~*9>k6UL5jK7xJJJ) z?tG?9(Ari25Dt96fefWI>c;E|pUxq$X-n9PboKE|VajpF#AQgB7gls;2FQ6{^r*SC*zCwTU zs{{r^mCP=h1 z!v1*jqi=~-bPnT|40sx@gZ*Fo!*J~lRXUNQdi($y#sX`S*TlOd6U z<#pWJw*lvhtL8H8%94_sn=`Sx^H>FYL%{znG+*T_roA8zen0c;zX$hu7OC9(a7B%< z3ARoyJ>X_LQxAgLpEjAd%724;N;HQPv~LxkuYTk6uQ_a4;uJ(xTK1OzC35|&tC%j< zRhKt77%m(JMX$)hRF;9s0w3=Rw--q`TJBrETzfb1q!f>VarR=x1GF`w@L>Qy3i;zh za8b}w(F%a(1Lm$oyC#0|#i1K|1yRfkhXDBYh>T5^%c}bm1g*s-ayan4Uf~L)AQTzn z0Ino>L0l@zu`lDqV2J(}5aBeb=^534EQ(e5XSP3lF;i1hseCq*+K2NSq9vP#cr6eo zz&%6U2Z6^HYYzO@Tfakx7HG2R_0tZ6?qXQ%D*h6AGFPdrsd~J; ze6)^WpaH7e%IT0^^Xm1rU7CNH79+5q9C2$mT=R~X89zi3XIE~Q{_(o(? z5M`lRUqZo_NpTm$N-tIxr55jQkt!-N8c3eI%gOJeS#Fs}rrx6w&nLNgcy5mT7Xdw` z?RUOUaB!5MWr)zjS@<$ydA)Gfl4h$6Orbr=$d7oArKQa4irT+Ps}ix?@x83oUengL z*wWF!*VoEQ$IENx!-aQgsv!MzCig3mU0_Q1)S`!b(4Y$Wh592A_>kA`;B(Y&Rdw~= zLWcjvnm~DZxsZE{JKA#tcI4Fh1^>%BlS*L-Mfx66ew@>H191j}*?7%*SBO{{gYEu( z{pVbVaCoVWT1Eq+Xk|5xT+D!3IXaZx>sB_Cb^4DlHjCfhZSlkC#pRJ1VGvgqTEw?FtT$F2dN2K%nY zX&Fju;9SwX&CYfA)9O%jLz-^Of_0Cw!I+#+I<7!Ub2TCvB>eZU2&CknX+6F>zf2p6 zJ?<@|Vxaj>OD`)slhOK}&$4!wIQqS05nj)P-Jav8HKV+IL9VwP{Y^|kHc$Zgs{)?_ ziDEH>HzDMdl;Y`!91Rs19PYA#5Y^Vd1}2*R5ow@w=GWlw`umOLD?9injl4|L~{Vd;63yl56H|=sPRGQM+G@&kRm7rT|afwYvAHPjH8ub$r3-P$flCIrpZR+U~t-|?wq=+uA_6b~{d7HXZJuQsPY z>S`H3&@I*kM+VsIJ5S`wpP}c^Zm+1vsf4-*Jl$y|VY_n|nF8!l_}L6D4j-!nYkvUm zIfy1Xb=%hg77M&hT~m`%$jxW5&)>hY2-{doh zoXjm5;gXz4;CcGI8=@beLXKy?3XMy+G#)P+P6d>@No?+q)nh5TXSigj=U4Q7$3P~d zKlfxhOCyn7IPAB8M&g>L)GHb|^2KXe98xzULA|C;&1k6b*>7vkzgZz5cmdHdG^k7X z`cA9$+H(;&>H&mXR%^w z{YO^w)xQ8;q*ky$Le}dtv}V09aDK3wG}jV>ohKU`8eKq_Lic|-kaJJ>z6yX-#&+g( zdc0b1_(I4-^OltW=!ii54=VOcowo%Whzv^SANlL|J3&3~1xnqdMVG8g*TIeLhzNw( z8(A(OVE`TqefGO^9ld}mCOT## zj46!5wrBx919G*8T2sanFL!MfZ$ny$rLFOMRpaXzhZaa*B(Kd}{YFGdQOR9RP3g!y zkwp}4%WC#iqx+)gMuxkNlA8u(2)IdXHv>!zGri%|%|Y@jrw3L$I05bCl7^NR%gLxf z9LONxHrf%|Oe`57@3|^{bg2B+WbXT{Gdu5}jsZu}#~IONNwaquUDn#3@ZQN!^x`{T zp{Y*I?5@6wTc2|kU5Y|JC^CxO>rY9E%q{_%A z7|*?KO`1aw;gzqvpyMe`2*ZCR4A6vlK!y)FEwMsTa&OvX$vjgu=2tBOHiXbl^rh<# zvn{KqLW$4*^$mS}r=t~zAf}Ti5|xBEY5<;`R7E6?Q8 zRWXY&Pm#Y=)XRPtFJEt2uRzok@JrE5cvd~xMQQD1RDfeP-P}p#`0ro3=D%@! z7q@<5oQi$1T^zo@Ru+#o=IPCw2>l<}#hS+DvO7F`itK6Q+c||wXa9V@Wo>FzhVZ(s zlMtz-C5!BSqWC9fZA?k0w5+UFx8y@K1w>u*wf_e7%$r;sY3Mj3``%PJd}J4nTUC{= z*SsEndFh2=URkf4B|0<&rXW3nY7l}DRQ&ongVX1M#1eY?JPgr0V}oKI%?B-i|K{d= zhyv1-wEHVke`I#!&FpYBnv3TZY9qnpcwhd8df-CDb#8dAa&k|-U9am_dt-8Fe)ID2 zg&MyN$bQ`_)%E=u;g{U1_`kXFf9ZJYt#SJPbh_JRYQ8Nms2AYaldtkEc>MU5HZuch zjokfUX=zDB3bV1Meew;CO@FdwBG&}-9|~1N@>FA>hItK*&3D@q*G9uk_GxVD49NAG z4IM_>!!*m>)iwDOAO`GbftXSS>4?Ly$94fvgLch$jZpp)@mgCX%>d#T$&ktda?%!s{EmJju7z**t2@epRE z<3bD1aievQG)04l5A5dQP>13s==-&SRAw3RRCnX({yKqE7DVIriBz>OQOh44| z<|NKlC8wxpdTfruCURtfY$_5a()gMt9zE#nZ5yku?qj*~b?5n8`|%p=N4rQJ$^;Dv z#Nz6-8elzY6B8EsxOFS0f&tRCdculuWCJfBhs*gJ42$7RJJ&{w;TFi^!k2rPmwY_l zmpwhyqCRx}rd(1|8FrRGpx1)?pfV4~r+RjVr1bG_z85$f0=IUT{8U?r=1CW|OZBRT zHRP{%_RXjjxc<~R#AJiw-&C| z8fxnCo4EX5e+$t0R|$&<~4iKzE^X{+uyd9E}+NE892GQOJ(f; zDqb6t%kMNgw_ND6+?9lxmXxlf!_9^=%`K=tt6MW8wy)I_5n~t3AAgu79Yt0SWZF0! zEybtydAW3F)vl}D_~JsA%VMX!wl!0`5~DkAvSEbu7Q4l8vAb#7R`2CJ=_L7xcr5|5 z`d^N%vuj?r^%h;*r{^Zo*H+Wy+2`36wXsdW2p8-e#t?-^x5!kNLyMLvFq;JIV@kZ}fu!-Fa zR`Lxu$?l-MkI?${)+gB1*WP_ANs=|U^A1_QC-`NPU((ZG zv<1>64Nz8b!AdH_;%1;G@2Ipoi01n94F#lan z&Y|&SJ*OuMB)(Ka#<;k+s*Rnmzz(4i`EYD}^tBB**fn%kbOgt;mezM#C zj@$KF8p!*Td`eczKG@OvS9#hWd-bAzUbLr*@%U7kcI zDW%6>^~mE!+86j>1&rio31%Nvi9znJ+8;yOvKrbGU+ca7j!%gB07*R)?pODYA&%2V zTh~ce3Vf}96be|0eT<>gF)H~Lmp1qcKR1_78PUf)XEeUh4`n&v6ybMs1?wWFgbSI$E7Dz?88Cm1&A9cl1;iTg_ zkM5t@))ur}h8aCe9w-!2YpzPF-5T)X-H*CqW(+l%n*o@ES=CAcVjb%x9)~p z&x-cY;@EpOCdQ!ueE3!3j#>QF*iX7l5iSK2J<|h%oKe1l9{=W zh`8Erb}}WU<1r5YU^*w|?J}+7Lcq#O(4>(VGc)IMVLp>(xpow_`zF`)?Tu7aKZ}!X ztfHKMWKF&;ZZcH`kZm+J0URv>IdBo7MY~AW&RUVZGEwwCfj!M-5( zIX4d<@D6&;SD!7VyF<}8?(uF$ej!T)#fMEP zC4JQLBDG)fwki|zYqe+=khOO$$gBB29arb{vqpuadmT@4Vu-J1^GILle~!B}5Me4> z?<@ilv@aC1lq&u~8*^59_a>p|MyOxHsTU>%ND3zwT{4ZJDA2Z10QWX2Ntc$ER{DuD ztDv@1cHNVArlz^28ZX(@)hQM#AhR9#qAyu|wht$=YU8XyKw{M@@dFWbh-6^=v_lbF zvU2r2WmVMRVtSl84woC;N=Lx{IzD??YafEdlbr#Vr-5 z+I(4-pEbzaR&L%>UCYW^ey2xSB2cBB0{L!(_pd9g2b`@bRJxGE|Wpz1cRSAiXnq4D!flc*LMRkGF zNp$q2;nU6{M`T+dGl&rV{S@Zax&R6nH0?!VL`bhjJm>4yHE~sJQ1OLIWav_p{Q2|45g7nJ$<9={ zjn8Qv2za6BW$+daJATJgAE>V_^28Yj_u%YC$dS6TXXd;<>i`i9+~nc`A%IEU0q?C0znpdx{`oRr)OexD?e7y zE1SCJ^FN<4QaV&S*nfr9qYIQ$*bXE4cj1)Z*?TLlw->q#g5YMQpE1q52kP3Ia0E>{WC`TwA>pqmP@}*UAGmIi>m8Ehugvo86AT#3BI+kPvyxLh^DO|{96%7 zKS1`1Nu11dZYRT{*XKn48L3i6Y!2lUyf%AfUl7<+;CV??HVnSG>?)P@HQ(t?x8Y2Pjf+cMgAVvcc0o5#5FU;Xlls#(F$MM-O2Rr# zXL%`iPv8G0H+Hl_y4D*t&P*e4FFD<1zB@9lnpjk2NTa8BZ_y|>itjO-XFeSxE=6+1 z=dr}}ZN`iuxXpowwNm3b($KtF+^jUHq6z0);60Y-1GJfeK}Ua*O@+n(MiM< z9E?rnze7;Kc6YPu&f)c%ro5jZ;6K8Ou4_e%e5I5o$oA>M^lB%z2`BdHTje{bf<6ndB*jl7ju2!$d_E_$UQ8*f?i zdHdZ^2RM?2L7TYNa)XBWjD`92b~ayjUf$YfjLGzBH_7z|xs$nm?)O&`r3+xR_d@87 zjN1~7;%G=qH@Lkytj$+!uVRkshbfC0@Oa88ebOsPc5*vGaR8?u9UB8*hlef2LN4aL zKVH>)Zohr|om#|g2VUluOUJl1swZouGoSJnTqmsW*Z7}Mw{Pqa)g>986IjD$+d~y^ z)2?N3N(3RJlHUmuk26y1w+7~TlFde`4^NHTN5+;%##4!w#Gtr&{wDjbfK|&=_%%b0 z(`2d7iC#*g`Qk4t`9BvrxL83VkUxF81!|(Sq6H~KDyl%Ot#J@Y?p~r4g|kyV-j(8- zQ`DKhAD+~7n-hG7@dq!doK{26pV;IM3E!X$qMso8HLKQDpMP-VtV&jq$yYgyi+<_YlO{rlt7+sZj+#0pTTIYHg=|b zW@0#Ns4u`we;e0?bd@i)PE~tN4J>%Lpm!@fu?!=@bmPQ?rqlA^^m@GHY+kdYWV4}= zf1lG#3I+!0+kfW*h%^ir78h5O*PMihhJ}Q@A$tPEj4NN{Y)Ot4>2zOMzmaTPBENg# zmvYkIJt(I|Wj?{~HoXWz$j4)nEO^%@f0TMX7k2TWTAsSPXZr+3nyeGrAfIe8vA>P` zk_P&NhUD}?w#^^a4PhFZ2G`5y*sVeqhsicG8EmQSmA}Y;DdZBKzx8?U2fGNDkR(F; zy>ak5C2LIxhzLh#(XwaQIhHL}?M>Zf48AC(?o|+>?>DuzK0Q8Gd1}za6nATiFgq{8 z^Z7_a^Oyq{*Z%59=k*uW6Oz?YJ}s+Sesp2X3cEWsS#{4`&-ly?Y75czCbS{CkIV{f zGCDssFNPGSjt>d>EwA5dSvh^ZAMK!}3=Wv1Wr(0mOiZnF8feMn=Y3pSmZvN~P_J30 zMVa%C=<*4c#Mkyu+*n3E)oFe(A-{jurX5%`Dx(bIVKd1tyTRY(qO~-UrRRS;XZ`oKXn~T32D%_ONsggnk-=|2)m!`urMQ?0F~FyI0XB_* zARs`H_5LJLuZ%KhTF!m6OwxY^33QLuuGi>kQ18JS#r$^mmnE?6W;8vTDo6rt9@8;) z*VfdWc9s)hBr8ZKHP#nIe+gla7?`(R$^8Y^);9?bW@da65~n{BfHbNEw0pJ|nB`ASmKdqp!5l9Iq3lx5lhvxjH?;_C}M;mUi=<=W0T##gSci#+t& zO_c7Y_uh$DJ6z=n9jFjc4YwEn?B~p#y{5`5{V%%Y;nLaDm2PK7jJ1})&hkjPkEi*~ z;i!oxw!#rogb5$+hOmVBDEl;pQ^L6z6A|ytC^M%q+`|`}M{WDtLwx-h$J{aG-7iIi zs+xcChVOMVx~OOeEh>F*3#%B4t54>AkQSXi7)t8!do-iYo!k1wFOSB>N^dSwCDO#X zFB^O&wGwweL(;9js%6gkE$zlzIZ>5d_owPN{vbrYcb?qcIL1v5ECgf{5!$V%Q4^>n z$<(Z@UbMhz_V0-s|9E5_C3x+2*(Ll(W5jWM`C`b!lL3|b@na-6d4ARF;7sE#d+bDX zCp1(XePvq80iTZvZXMEKx50Ez#g$kcnfxk?>Fe&}Mr)4WwYUzgpi(aGs17Z(>l}C+ zv)9($0d8G*Evp_H{=P!vuFl<*xrdfYruu}bKf}X@qnqy4bXdQaE&r40V0Rp!p4PI* z6*yyR32mu+?>^(I8go{)?kx?ZJ2rgcyx*pE_x*dix+yO^MmCA&-{ph z+e;889!6uPi1`fawC&wbd%GkN(FB`s#7O2L`flc<{xv%MmnDti)r$(8RkipwSjkS9 z1zpsi`7h3l>n-?I3ATIW;q!Ru)(--t@$+%plj)kONzo+2F*q2$5x;akYLqqM@#2`0 z`tAR`Wq$hKwGIedhT`Km_omn`-`+wL&vVHFI3Qc>;g?z2iHswfbs0S4WdWC_>=+8l zU2$=NHMwx19?B}dY)mWO>wVp(Dql z7C-IbUF!FqiQij?Cs>8gb-@yRNpM6Ds#PudrgqzK9V9B2&ffZP^tQ0DEksFFGr6!} z=ZKblVPTu!vJpGq#~748<`H*WKA?z@{SDj>gu?X@K zFxRA^K@p3xtBy`py}INOX??z?WE5xSeN%h|!%&QkW24~)y5Z{epGE;+Z)$2wl9n zecq?V%gJ7h|5n&=xF+P25tBuf^YeNATFa{sDVT5SjP^N|10}17S5uyueBxZ5dY;$n zazudPSbL7JY}E^JW~8Eso^z&1^fjp**PL|6aU8ZZ;$j#684<-reo$y0oTV0dzVO&+ z+PPMu&&`V06!#DH=ZHRV@QW80*!eoWcw67ls^!B5@nr6&dqn4%L;;sIU$%SUzwW*+ zKELbWdItT>d->v3e}Kh`OTSB zCW6miIUNXIH3dMl&sr6>qxTx3P!Q!F#5ckx7ewPwr9+B(1&s4D;?Amb#L_>2n$}^^e0;H6Awzy`9`YVB(T-_CXar4x;Y&w_gY7O^8FhI z+3DyR@;{sHMu#fs&c=u5_KB))H<$djBu~)adFVaN@<)lvjm4Y?R6a&Z<3GV7qdl0% zf7uvcczJEkFOpCzn0&$q~$#+U-Z9k#VeWi>+Zpzbc7<-461#l93wfhKV~jHN=578o`vrz z){U)Zg}hjz(XO_}3D0u05M}$&m&ryP( zX2Q%zRxix)=XD{++n+$vGmw>(&trGJugy(x*F@N-X=bTzOMPv}&dc7}9SrWuGbSxR zqk5^ivtPx7V|1`w3}fi0N{qJi|BJUbfu_2D-$uV?B2zMyP)U-xGK=s;D4LLY3Wdm! zF=LV`l}ss;N`pcaGS5j;AyekeG9+vf=h{8L|62d`zVCV0IcJ@7to4l9dw=(5xbN$} zuIv7MI0(|5wr$POGY3LjY(Dk#`|7iqmZvCtyQ1Fve%KNj*re{?cPZBAC_~u_#WB)S zxj~yvwN*{BmCTNhOo?>-1-m}(-x_cy#%JeTvtschbxsc{_s6fZZP;J%Q-I7Cup#*#Z{A2ka5i?^HpF9jnr{%m7rpp`NO0ihe{q& z+5BO4Qp&`^Uth@!F7owbL2t{=w_cD&?{Vc6*w|Z2rO#5Qz6vF)Uhph)1?`ex|y3>%}DrIE1b5N{Me%o^Vy~~f!f3lFH-PrV=%JbWdqT`cS zS19g(9|<}CPF&PD)R7&_O2NZTR8;7lc$Qqhtd3#Bp1bF3yrk!j9-aNONh*(>?ek_G z>ZjuA$5JG2@$TQtQIj0cceEiy>PUcCdiYu5hUk0kQ#$rmpSLKL^OUDP?pyB_~h=wfn^8Rt5^|70U)O?c&;zo!VSi-U@c~2auk;bGaF2R&OOKAayv<^4yz#I=xa> zDAH^Tpqw*}y8;XxjE&nUPDnVN9;s$m&nOeF-F8On&2Q=FMyxs}!<#4Fh81rgA*SE` z^gJJV)$p~cuV%s*8^ZD^!$FZM632%v&$7-0y=j?Ci51vR+kJhR`SpCssCy{y>h6|vNEtiydgw0d%j6~FRi6=@^jww#kLMt?njxkM>p1G-hac^ za`L9_LigeJ3GLFmC`*R_t1Mwz_%z4Lc07D-)~{rdolyGC5wIAQdhpK6fd$_-#%F-| zbAjj*PtI%F6Cqki;q3Y8I769Hk;m>0&;Cqg$v(2G4Jh}aqHKTmsCVqu`T}=+{Oe2A zZvv!_lTjlZ8*S*J)ok{Zr(F3D9$C?>=o9NQFng`O#BM*c zW5c1lvO(AIqqdDajQAY|avTQ=_WY2AqxB<0m>UHi%z8$Yx03(6wOS!yw~hC%4UT3D zj2H5ak9JL(yWmlaqEy6zW?$N%uPQm`ny{`}&FT@mq|kJ=nxYqDMI^Kxm=%XM2z=AR$6KkGu^8E#za?d3L!s5*6{Z!Bs> z;Qa?}4UKdyGogA*NsYtzpLV+U7PB6I5)nN++V8(wvtq84o``E|26rEtcI207#%4T!y)mDCM*l%t+vI|8 zX|Gnr*uvtu1z+Qj2j;d#j#(#{_wv#ZayI+ZUR=5~pTVFrJtTsd62VHRZ}tljzGE%jIO^u z^!T+6zcf`pGe5mT?a}SpYw&<^Fec8pK3XO5z$-=Ce#hO^^mj~OrNQwA;1gfxguz+_-c|kAe7WYWko0KIyE!K1+TC)<-XLCN2m*kaWu}e{=N> z{Om;ZJtN83YuBFC=gX=PY+;2jSFW5RCdrFcJbxzeL$*fx)0K}`B(dO+ldQst<1Q_i z_j;3;Hk;?h|Gu{If(i0SU%MvUN{(@CY{#G2;4`s~_3O#s0Bi1ga{T}K=JOEKHk!TJ_jfEes93cR@;n*J?B7_O zKq#vl2BiGo9@Ceh|KQ0={{b6ct7Gm}WI7?n88tjt&zIYMvb(quYInhfp0!`uskhE9 zgHh#&1|C&g;?{Paa3B3}36xOZWtX**V!=JrZc4#X(n1V+-vzRHU1k*5>-M$GexlA& z>UbI>@fV-&m=K#FiJF~ z1-7^Dktdr0R@%OmEHoTBvVF4=*Y(P!>|iNM!q|9jO%`S45rc30wk$={29=&BEq7g- zNj15ivd^_!pW~E`McY}0k-z%{m42hpk&}g2wq4imk-5cDK#J$89qw87 z`?)l=IdQKDbK}o(nx(Z_X}+1|(ozG?2dPIK&Z*-xEmgVII z&gi3G`U<~u_6=ub#w-64_&XyLX7As>=QsXEPej#{mDe*(Phql+ZsyCpFz!~gKHJ5w z8U2nuf-^|?Rpbvye9U(?_vP+gT}Pf}W!)Zbc_m7vrTryMC{59R5yy6&UCwV38XtTrnr05})x6GT z=61?Hpy{8NQAQHK@60wneV?dNxiEIFkGu%pd5$?wIE2UWm8>0bYb+l3Rt)>QvwgYD z?w!6hD424}{P=+DsmGlskwGr3V0ysnCacVdXPyk0n#=UCK)0=Uvz6DEDyc#tip-ue z6OBQq?2mU$Ub18`)>|IlV&3^t%II&%u!XE5W>P>!x@6M#ETQZB7EaHvHyPwkF{add z>8S5JCbMJLn+(60BUL-&X4hnuO?BHO3ECf?HaQYoRq+NM!|(g@mS$YasqVu9ko4`m z*IMfLhYu^HPIn2l=RC<<^M7$dcr&~84fe?tYJnVCRqlJ&o@m{5I`xwI+G2|A{ZKaJ zo)28wF>fcyPh%+Jd6Ximc6IbowuIkMlS^~5b3x`y)7Njaph9Q)x4vV0+W`fnM?6vR z2z{Kwb4h_MEJszHcV1lz&tPUec-)vW zyI%6^z{SpCx2Sas@42%?v&xdw>CubjG4be|c>Cb4?5B(toj;zksE~rh-%O*& z$XX+z_Ca$NdCP)eCV0lr+2sXv7&NmtZXke;H#U{EfPx?`EqyANSUkVs31hv0eU7wP z&?ROHXO|!&z329Z?gupLV}BJ_c26v%I=b>rr4Mb#2P%~RC3GpjUf8gAn@ZT$-m<&( zUt;nbc|6SXoeL{j8Pu=%>S)lJY$7L+Fv|aT637M>T6I1C%3YJBJ={z|OK#h=W#=vp z7exGBlU1<|wjM<(e!qpqQ$gKH^C)%*NNu5CGQFT`?UDE+`ai$a+U)yk(IctO;NRf? zH0^b$^Ym7_C`DG!n}n?q!T4Am3Q)H!eC607(LCRz}LDI9xK z)%-5xQ&pJw>GuT9`i2lpY=4u@ZTrs$R-&)-|4XDRxA!Y`oQ)-~P7ROk4~D|GvND8b z?-Vd{Q7x3!ViHtt3E3VH~$RqVR{;AmgEw2s9$rA~kn(AL{$sPLg+54iG zh1aC85vU|Dc$jZWbmJnJun5LnVf=0+g{U=llcEGEw}iLZ0wh&BELs#DAS!l z)tnFK3D>E0-o&LG@`qd_c3q3ipGZ*<@V@6+tNC1F^d{bqjg4XNLE}wE_J0DoA7|#4 zzF0a)?(O|w-|lNw_nPC?8{9aGzc}$*|I_Wh^5oln(R{id_`kT__XS>&_xE<+AM?&@ z_>ceX?Y^Zxrbl~L*2_P3+Bv$2I<;zj^!A)f2Y_ z<0A$4s9)Rfm^ykWbKm-!QTfu^bhEtYm6d=YXXW*=i(k7Ovr8Ad{9aqE7`MNbNq_ci zgFpX2k2Xhfj``c~qNm0kPy(#wVozh!MBc})e||ywA+R<^E5Q1nKT#nbhO+(FZ|&5g z+xeeA2++L2eE2`VwR&A(TQuH<{A;9bhZMNUZ;AhyQw;Ht{QLg&)Pr8sFH^2U)rd6$mHZh4R z@8f2IWt=9l@sGVpm0g~Wjt&n~or;N=nxvVTS$uqasHkpcODE?wQVpBo!2 zC2h~1&Fzw;q@?`vC<(2d3hQd8jGyHcki@}jkoB0ymP>@`szkl)$82+{r%;5 zKd${*p=po1aif1^1TLoEwL1gE8WY46y=U(~eYz(BRy`h0&Ntq3)@xNWedU33gJJRU zn-hknr;iD+&e~rYn3~FZ@uKv6n~49&^8BbpdBElMwaXMot@An!3=HyM$qV@NHpn_T zIoWS%`tsVUd;+=^?ipsAZ&L{{tuW^n7f0!~BT?LpU4LYEk@+x=)BX4{Jw3f6W(yx* zYC-}hCns%OaBy&%N?>oPpX?hQd;8tyrjb!mXmHWfYkvG#h#+w9@K9|>hY>v2>(@LK zE`NUTkKf|dK#_k)va;VL^qahSBa_l3bW`h3!kK)Bn^94X7J+|g;xH~EA|jVBUsh97 zBUz*IL{waSZII0{%Sh_NH@UUd#l=fBXzt)YsC!Sr^Zw~y~+DlH`sU+0bR z{3!d&-rYSfC8b+cbN5XxE^*U}Tj$Q5i;0QZDtn*Y&> z6DK00qify{wq)wz%*pnbW+ug#e#oW?QO>c1c+Bb@_48YSwWO-5>eyYmT=&sqNk!JR zkysPfXItCa(v`VJc~TK&NmNvZ(&fE+HM_3rBfMu1&w=x|lajb``mp=Rho8fZJ{#y680M6cdpot+(Uj=M;?o{&4FoE-t1jct$qar6eWk-j!o3mq=_Jc9ly?x_{#7 zDG|^6FZx1n++Z!U6PW$x()0GTfx*@GO6)tOd$D~rHs`=2e~}Pm-=m;ljJ-M4na9k` zOtl%bfRao*UY2@+g9uY&a}8GwxHY+J@7|TQKYm-crliQaRPmzy#m~<#FfdT=1`dwQ zb8Hu16^9As_=yuCF@f_VM{%%waB$_qWP5>2-^&LNC>smkz7^TCXW@CMvXYYYzI~4# zJ;K8IoXu2~)|G2hZ}%a|%GUNuj}BJ)Mi!QG@3{xBUP%-8-@d(5X<5;-n>_+yrh{;C zcBUa(+uN%JPo>?ub!+?f?fbWE+-gx;T8fpkNl3SXzpK7p)7-qwVjGi-Wu-c)E@rET z!nTS2w{PE8RjDZ}D?9B)hyK^Ebqb?ff9GXn>=YIrdmq1dH5^uMFL(FqNlS%$WuB8? z(R(Ffod2Ytz)(+b=5vPT5I}d9#XE) z^f&p~;PGSBH4F$Rp{0V`x8J;TC-R5%r70s>*#dl~ovrPY=g;$uL>U>Q zunu;xMU#9~6-c8vy2oy1@dw@xdqqdn_HRk&BMc^q_i~mVMqvN>_ZI0$kPN}p`qFviHV759EHE} z>r1ng)YOBv?^vBqVkyMMo%HlPpnFS8u!NU^k#T-*jwkxiTML{b?Ck73Fh7M|bL`l$ zaOQ1QZ@#v-n;044pcm=n51o1Tc-D>GX#Mu+ub>c$OTK$oDR9l7fq{YI#4WXS%R2bp zWse{K{AXop{x1FZPwDD#Gbtq$vF$ueO+%x6`8P)zqCDcmXj2LufjvRWD0uz)(L)>| zRfF$fnS4rQbE*&_ps1Ll{m5E#W@_r;X9t(Qvaln};W)@*^h0u}$~Qf?(wf@Zj0X?) z@82I167t5mo0h;gWnp2Fm61u6cSoSidX7`reD*b)-@JJf14j^3GD58Mh?ZD)l6!XU zY?&G8E%6zeoZQOI?Y%H@T2r$gVSQt3PHJjuQ;Mw0<=^|IrP)&twCdvgA;f7cKU#38cTMS?-T^Ko@4vV7ung( z@7`6ES3i9CkXPRAA-1=!P`UpyJE4E#MAd*RUQ|_GjTiNY75Xi`EXOT()y%wd_`_Ft zbyil^PR;8a92_M+^CKyGn}SL8hp_&K+nyUD5*$8!c&I+MepEe=GraoD8>eKn{0fZT z?)mmjNH2A@so7Hr&w$^v*std2;{zu#mO=DZ*^jlgXTQI@dHwqJd-v{TTa;foe?DZ> zn1@2oyLV&1##{ROM2L#J^6qNt>bZiUl@*hG0p}eZ>AG4wI+9XSbcEtCnmXFrSjl+1 zceX#VG4FSY@7>$d-d^rG$+?)%>U3l6L6NbfPJ(Eq=u@B&WN^~Bi;vIpr%(E8vJa3{ zkd$}s%;@bk$KO|1SNEKJTyYdI1)XnEQBisM`KE|G>ulK4vj+a0QSsQie0*g{YsiQ^ zTee`f6E#nyBqw)vbpdx-%VXjzEmxOE)BdEkA^?M~`PS2udlyY8$lcy-NPwZC%j+Z&5>FUxz^QBUPz^XNTX&y>aOa7^tENuvuJLnn8L%P$Wmb-Mi_CvB^m!72ufe zVlNk8-`|m&_sU%O_Rdy%=Z+mYrH_x@dmFeOfU_I3ZjHBORy$VqB>@^$%SK{%AeVdV zxykV=+%rFQ>Wakp;2`B|IqKh%4vvoVT2>YoeF)Z<_12mA#1k9s@|I&B8_mN;LwoO7 zxQ(Wk7Jb*AoCHlxO>6_;2U6{8< zt+(FJHbC z^8I01q@tXAEwF8M zesFkrm*pf9jfy{M_V>bMrEbsT%uH;CpC6L<;l;JmW~QcJvn|pR$UiaxtKKXuu{U>W zQWC#^|HfK&cXK;+>XehSb1c6KdEiTg=ouML8X9u-*U=TZ4us_8?c1+5Ix<2_N2jQu zKube|KqIkh7fr(4uU|EOw&q1{wG9mner4FPB_$=5%_;b@)tSYFw6t_rcehn0V8Za| zs7?JAd;^0lEc2Y48|llX`;Q;Rg@swOLK&#lY;6VYC?)pp9ojQHSQ~}pi|op$c!`M+*tv6_G-rdI zx=SYkIcDIfFE84Uzg`-ui^00DzuNKa^m8Emty{Ndo0lqhO`8%G$WH5|A(p}gAaanS z(z3Gk=4k|hnuCso@4Ktqp9xDR)km3`E}gGv9OYHS#KfXF#j1Kk#ysAlD*Dk~FsJT~ z%)EMCp)a(5?Ymo%Ap6t4&KCeQtEMf$xaK9^HRQHa9m1$mM>xJNfzZ=b@ogy+1Y+tUNqE*#C1w^;>y(XlQBgq@<|(yhR%l zf}o;eF;?_&Vtjm|APiMt|ja z#^FQF8}aTi_m|k{nVRy(if!D&1vOXV{KboN+tshC`tkJ=ec!(MqaIRGQ2~fq6;VBR zZd@~#PhLUc81@9x4)&7kVw#rVK>(u zw{M@avDtZWz9N{4kyBJsRyH;|T97@0MB%+Sbp{LpunQMg;sM96{VWuqFoRSiye7ciQPYK1z1Eq?RqlTs?OjP||qN1Xw^!1Z4IojGA zMx>-!u{u#7Z^vh75}}nrk1s#DDm8no;*)Ke>p+#n9TC=R>(W|u>$kp@2jchxi8HS> zbaeKLh-lB2oUpdG4hX=WSV9}IkIcoQZ&$8RZwMn}dR(f3lx3YuE-F)%ifrnci3(gE z$#ohp|3>PZ(jH@76_ zI>B}zyXxv{9wyqg-1@vE1xZO(z_e*TZtf>IZvYL|V`JBN`jd4>u+bze%9!G?y0;>< z+g-%Q!D6i4+TYgJRz9C4g*lrIU|T)tgPI0d5SXH=si``gB~8Y83n3sQb7^s^vm-=D ziF76mb1ko^h|`P_9%-qmH8eHLeHWftu*3}x4k9^<%2CB@|Cw)AN&k^kT6!5P3mIMi z{cMK;19b@IH#|H%D{Bg8oBW)g$1_EzxsOdxFV48MbGk>7#H=g8>agGV{P_v2(gztCAetWh6NN2(UyO&y z0g0oou1+d`@#5&AL)#SEL?s;KF%ZE3mLM7V7X|{CzJu7gPo80&MAe=!FnE)bqpz<& zyST{Az<}SaT-?D*k8;@6!=vVUYFu3CE(!u8AL4g}z*~ZCG4=ITuwyaLu?zY=8HTo^T!ckc_r@>15LrC)6@qG_UhM&B$-w&`{i?qE^_IsVu5^{u02v$nR@@oU!H>}*i%da#_w*eBEra|U$LfTQYr_Uzsb zYXFAb%&Z5wT`J|%ThGbagZ@MiYNF20&dZ@a4=~52rGF;co+Bpn9`u*_&@95Eu0bx5-GLPLeer3xL zq2Y_If-eE66j`9b9#Mk;*?%t-TOV-ptgY>=%(*e|4X5Afd6pte5d@jzI6Lv<2Lij; z+U0&^ex(U*fIP(URg2HxvU39)ZtWt&=vQZT{QMMeYF+U)Mk!faOY_m7W&9Vy`&|Xk zXRltJFgAXB|Gof_oT8%QzI`W+jFOIJu8>F-MO&ix*?$CvKeWx%#6%G{*W9>q1EG@1 zyc1=Ws6`oXstrP~yZb)7?9+yZOMrGcF8ca6UcY|*^5ry;4Yr)rIc6RO58;FQ0>piM z)Ujh1+Mb;jWIu-j_m9E^Q<=(ktTCOVN5iCq#Z3#rlA@R0Yxwn652pJoL-%iK!piII~+>z77jE^AXi6NsPE(kmVP3y zpr{Dk7mIMKHiWa17tlzh8MCFfTnA-~>h_MZcUUxbAMX}j=uyzq({te8LeCt&iI>;O z#f4lF+*9;IRQ=hl2sr#aBcr9eTQP8L)u#S>TWc%#)~)UB?THBqK=H$PTjYgHmo9b0 z1&n`rwENiIpoI2-ix)2*H!!ICy7e*(nHX!9p3fdbj{!K4PpyJGcZSBwQU=dilM~G* zEpRVjv&v-x1wbGaT-FQL6|%Wh&$G{tWAkQouMEVvBaeZPuDu0-&d0}x*o(Y`lmMtT zl09!c-fEI!JvBSFf*)tL0g9vxDN86KXD2N+c zf*>SPWz7rUCsbMj+5_V#$jghF7P@}TI)n08sqz+9Z*Cu0Mfrf$!lzHiu^*N*ikWH( zFAh!p_yK-1Sk-%OuomeRg)IdEr1kN`2aX&YC#NYq8^%!b!nZAgyt zLt$F{_AQDV0!TD@w;FGFb?{y}t6L4WU||Nb+f}cxg$CDJ&oQ|JMxc~UE!gJJWLD~X zKo`73neW1RFmwd5C5DrW%WIW%kz)HVp_ld5C+~w8We3FpJhvGNllP8?wD-j%jJh0fCfXdW`&ixh!|N|GSLhzJ z_EMBKym~t;J=T>n7IuzRwRgftk4u-{78MQbcHfR&wtvfuf?Q<5`IHk4>aYC$F7 z(p$1eTs#2tj@*i%HQSQyouvC1pK|qT9mde2)OQ$XXgqjOHJ>^kXCWbzvQez2p`igt zhMF?{%^OaBNyfp+NyZtY4_jXs7b}99joMhhZ$H8UKR( zgk1Lb#|E2yDT>(%s~gJC&&Q--hi{W}t?2BO7Z<SaJbrw2#$O~}#PaRbO!@jTZS5|IL%siOb((A8oaUOTp1M{Pz=*QXln4SU!^Gs|kYNmKL=DK8z1TDI^2yqd zukqox9|#wtY6U;DGvhm(=9ZrqCJ8;q6Jw?(=t(;%K zX8!e`@#*Q8j~;o>_8;Q&x)1Ts$k@2bNS3sU5&GcpXEZHv`dbl-A9pM?@KlKI1MhC` zoa5R;=$o1SIsLq*Y%u^}LD~10@M>&9;QE?+ICG`Z5SZw|wPkz!0DT0luM4t|145!2 zhuZn+Mr``Shx^aBJ^_B~?(PQvWv;861ycXpx4R9tGW+*KfZTl03s_|(h82Z6s5juS zJh$QZ=UN_Uj856;B!tE@%Q_E=S4T}W|pa*9s- zS!beM78$?Sa0@p#fLUbU#YN<5oU-Cgn%%yrg(5^-SNGS#!fAc|ib%7!9uf6Qv_wvR zKDd0_Tq6igKHzDtvF+p(H@)Wk=W1tZeJnptFp}G|=Nxcghz_nFvBL7#@4RyL>YIWB z8=3fyjt&rt-CbR3pX;o1sZ|`))k9Ej1J4u0+n6uozYtP<{QOc{+nf4}%`#f4d@~fzgA2 zn{=+Pvht9wuCBT|(8)HiVBr(%_QmGhfV~(yLu>0DIHg<3ANSjmkqFCkSUsS!1_cGd z3vfh7r&>n|G#T;-dRM^|Gv*xG3*s%*C+zCgpQ86UR3XFbsrKPJca^pdsL9+)STqi^t;kg@rcyesnB+S|FJ`Z}{uq#;HDh*JZj%jIIn0a){+&6y7$g0=m%wU}#F zbG}mZz{nPQoS=j1*1*uvBFB=VH->r>k5bxa$jHHsK?I>Iv`L|RRuXbK*^6M5Lv%4l zXbggZ!{av1f8Qh!f(7Uc;P>m72OS+9vOAyOcK{~f=S%o>#E;r2E=UyfSgWki7mgpF zL+QxFlN=ej0kUH1=}aQ%=TA3>j=F4XT zI2&lsUB*$_2Q4&C=xA4-JqxKkEdj^MmP6UFu;9NN8?vlqeX;wE^Pj_^eDp$bK0m)V zK+L)l9&S_T#CPCsYAUlue%T8ZNHfb}KcT4P+!y91>oCnK{>SNd@7|3kV%e`&88|pT zxb7MF z?-r`3B)(yLM0C;%(s>jb*PM6U)ar1bh6cs40YVdXU9Rz4k3E5}5x+a`>{ikhYU%3Q z^7|jax}P7uAX6RKzaLT7`fFvd_pdRwyO)QSJCxT4s7)%tyZ{0Ieyw9QtGBCV+yj@5 zLbsm$DyAEQOQ!LfOCBDil@+Mp+qP}<^jrY=ljdfkhzH*kIeMAw^YM+^(7_0v))&46 zU*A+^KhBw{T*L`XGDv<1W%z@kjQtfw=e*4kr#5cbP(`U_Wsith3ci)^A`_7$chMRH z!$iw8bi`^{%CQsF|J*zk6D?J0e?#2vBZBO`+BFs`ET}Odj)2||iL`)7W@@^MWlZWn ziv@X-0c;Sk8frE$fK`*@X`{XrgbbKd%SuXwID8U_8>~h-H_d47%1zE@?PU`S4W4_w?ejOdxfupMVz}(ynl<>o;?gN7a_laGW7P^7BJiQ;(p8cpDnkx zLq+#cKo!g@^9n`?0Re&i`)?o4fSX`&bIIMi-@w%jc&LO|BSH`PnDOfdLPCP}*zYO0 z+REd9b7x!wluXIA23v6XdUy8kQBvYvV{B?{T=_MA5`Gzgec*W#h4Xv zmG=|Fuwu!w06)`K2`3pp$Ubl}acrQOA+5b$+8XebHwCAWcXq@g)nC8P9FT5`@iaAs z_*(*A1Zkk78yO4bEutq#EpRO%2`;2S+I^9Va&nM{lAtcWl!s27aKju}oQ{3?@H-}az)%DyHu$L7fGj}Os(<9jc+~cNdUxgK#y;-^ zX;?+nlft*b0bGlUN>lLMuu}33;AQDYw-?e4bND{H z58O`9Jc1~7@kUZoY~@#^wr{WO=^?wxIuu8de$I#{SnjqIiffo(;JucV)B!TaXV4rt zW1vr%tnUEO_4ivQad2_5(9@$JzAy?^&ebCv7?Y_7Ogz#W6;~=i zU4mFnkg#Buh=U9O8iic{PIUyo@VH`H>brpQFR45jOT>w#&hq!k)2A0=Rn{sRH9ojD z&i`z-&P6TK`RP**2x9LU&~I22cubh|0>P<4`oC&1;s`C{_4(8O{w2A&Qa80)TUv&a zjR)L{a%4eJt-AFBediurzPhq8B`x@7|H|**SDAPy+ulGV4+uE;cti@>^+9&_%;;$S zK0|c@R;b(#=g%9TI3bM)fc1LlcDq+jd}E$W>CqE}FW&15}zl5hQ)^3e35YZg%mV#vw{M~*yw_AK&nMo*D@ zxaRrQovw1cGAUx->Ff_PGa=g8N~XoG@juSU7y?>GSPqF%SNeDdXRIP%=deucQDV1A zCsQ(ADHjL1L#f8k#LhiB&3~@B{~SaE!^7)bmbpgj{a){um$&~}cA**#>{n@nAPtzy z7Eyx@DkYT*ksh&4BA|(S&gRJF)l*T%UiD z&L2TAeM$Tg_|;(c09*aTtITFH*Q}L9e%5Oxxr9(xG{4j?6H(*6VCtVuO-roa|F|5y z)Lj0@_IIa?%&Zu~1gjN=P=EPM;CG=_ujR*D-|1_XLOmoyxJ2TgA)0wJ%&t@Yng2Z# z^n1CT(oCWzaFa**cGkWPzmvBA-!{Acf9|IJZy&H$i^Cv60sl!9$p$Q)o?c57p(9Yn zuKLBZ+=`5hgz78W+0qhs=g#|Kw?NCde_y-GdV_h*=bVE>PF`L$<4N(vVhBnmCf$Lv z!f^DUNS!4UGVpH@1TbbxOI~T|z06re7QpuY8Bh!e4)8<)-QlC4W2qcGxCXTv72DL3 zDwg2m$B#iStXaoFc|pYj%Ofp84|^jBVtvT9xD*V=Ft*00&!4xnwQU=7-YzLQi#pHf z)!Vnm78dJKN7eo{8<*29YswN*0=&$-m6b0KRE6OJO=LGJf|dRXQu@bKWfL8p#;&g4 z{PK~A<5gjdr%#qQ>QBW;0*Ho>pKY92(pm~ zg2V>&>Ehx-K-fG7|7(Os)up9hzsRm3P}r7Mu(92hvy zW^f3TnFJuRJ9mBqlmh}l#zc8gVMn&EBs|oIS(WB_4eA4MwHD6MK%;6y%JBu@A(h;A z7Zwq#Di{*NP_;4hNZX=}kxZ+#hGAmJa~3ryic0uTHpXf_I*4qU@r(Rb{syORMIza#KH3}f?b|o3H9I>yXgROa)3@WeMSyx>S3`aMPpz%EP+&7V zdsSlg)2C;kr}r+y$5UTZgF&jRsHphx!3p+Bycqlim^=u8IK)&*6U%(RjEuO5NQgp5 zTN@B1*>6X-0|6eRyvx3SAKVeFH&ALLG^`=Y-`b@^5WwFcI~>oQD+2NWlz|7AT=xDG z#W^sE1qEj>j(V1eISe;A%8?Wq(3MLlOQAKDLm6&g6#N@%`t&A-G9!Nu1$yiaP`sf` z+Fje+JcCobkZ(QAK_Z0! z%M_e=4gLW7T6yLg&;S?}4nj3uAEO|dZE>x$3xrw7hDb{txi(=}t`wTS1ZuIf16K#bmNGOG7(jF17r`pf=;`VzEFl5%UQ18! zuW)_8u&|?|0v`P%@S~Pj;)Fl2FjnW!KZ}ffueuxV8?PT-uMt`>X23@%O&dOcJ`Pt2 zj5knJK`LOEAmf_lTL0tfDoF@PNnJ#@0~inpB(~B;AeITqv+r+XBRqfl^s?p*6j*dp zkZ9o0-5sW}1CI-aSQj2}sAU+{l|*L55KSB{&%`vFj8(|UCC=-R`0?YhF=}3JZsEOq zi)|ZjsjQK9!p9>k>-FW~5!Yc}vg`8#eB5Ww@Z|NY!RHp&Kuy4%ID+yS^egZ!O5tya zLeV_?uupuL>usgQL`6}u&!WyKQ9}8J!|?E2m6ll+<*5y}=5IaDfn>rLt4(Nv%fsH* z79Jlpba(dl24ExY)=RzeU>)xc)d$=*w3uW?uM60R7%8wwU|yuS?D2l+C0Vb=yr0Ax zx_9fA^tmq&12cZY^pW}K5qv3lgG~_{l))8td5Aa&%@9e@3J?*|05|RIOB&G4NHyQe zE*BRR$cmPrI|2v4qJp^9@Et`mGNO5@?`F=mm6>v=IyZ3MYiepQ_|7k1z%CSHV*;sy zUj>W1abpaE0CME^?deiBb@-CK&CM>5DoBTM92tssz*<=B+`biFBpn5n5v20Y)(ssG zp!;->B}r14+}*uv7sw5|ec&wcNOuzxWkD3+QKqqtuz#?U0YS+wBVZZWe`Q_x;0o15 z&LGeCT=@py-t{SLAzXGaIyx$0@&=IyZ8wjpE^KoV*T(}QAT3Rs2 zhhglcR!5s{NMb{tJrlHai-1g9Uat#;z9QE2{{a6}Jd zW0()1al>;aVfOYH1ZU{qv3$z6Zr*HYZdM`F0`l&lUm%v($85zqKd>R}L3;WjLH11D zWJ*H+arQDF)MdTBy$D0cPoDJq`JJIWPXihr9s+ETUKtc8xGK{-VVAP%rzg-E zkXulYc6GlaDy9fbcVMGQ&aFtNc`aY%ojST_;V)`Z5((Yh8 zfr`Z@W8e?-0{DjBfl{u|B2Z5+HalCwZY?@8@;7`V1Mk7E)kuffZr4Z(@UbwPCeEtfFms^q=Y64A}XU>^3bfUg>YdQX>npz;u$SF9}$g5$>uoa^PN4 zP*Cvp*nRI9Fx!aKwYu6`G2?s(ER0WDqC!G4s3lSCh$mt&yJy(YsPYJm*2|aTV0BdF zWT8H>qiQ6%d>lY0EBekhGBAu!OrT>5%6gp(Vj4AJxdML3GKE|_s@tj}Rp8219 zPpU4iU_#2D%Q`ibnVvoXEP|;7ypXJKZr1zfpRnCy)GX*3Koc555{hBaY2YN;^tm^^ zLS)>X<#O?2F6tzrAI2b%g9;vFtSL=(Z+>1$>3DUPG5Tn5c!MqCfSkPiGH3;=13?-) zAi~jxZWk0p{TaF*$@e$DUR&Qt#`yA=rjo$W6&89U9>W+iQVZ)hLoJUke7s~=i~UvL zG92;|Ec%pESWFCSEo`JYfHB8NbW4oE@#9jq?`|Lz98Hly-hvTREy|7T;c;-VvlAk4 zKAiEHGgyM4NWq&#H`t<`tggP^(7=EX;$vmy0QdxQFVdz>D6ZoZ5)MMP=?x8OupNw_ zgk2MICnk@ErRJ}bAG3fAotD-IE)II>Ycv|5-FV|x8F1kU4q8W!00E%@Ci^dk#Hk3_ zB{1#aQxCd*e+O{R*K%N_m4ZOaYA0OvARk~Cy@$Qb#kKU>Eb?!_9o$Vf-k)|G=6w{m zpnbOy;N;2iU6;;=f>i)cSG3a*K`46xm!KX6R1cV!2RNTSd%&eviB!rI(BZV0BxQr5 z2B9K1;Eyk%ipd5x8)%<`pZ&T^Gmr)a0RaW@lZ%}lamo$ZUrH)iiXUAiAhDBg-TH}c zE#&PI>`EvL{V~}HP)Hpmh^cm)!Cj{z5@10Ib3`J9hN(5+4hU`Sw|+|(PMr7xcn7m} zdW$5GG@voA(m_I_AOhF_EP-(ZdX3$tXm|d6WS|KiL=)#nBMMsSsa@xle}xV-pbup3 zx&7>adpT>?31M?;>l_d&vAD=bO>Iz9_B*3%k?EG0!x^9P9g%t9V`1n9!2X7|%zFO7 z*_ofP6W{Y-kJ;w;Q^@3 z1M~nOg}NpqGvHrco|HU)?kKs$J{W~mZxae!oAH^pGZ&?^%DTWm-s9@(Xdp#Do-fKTs(7DO5^}89v11=qX@Db4O-+S# zlO*4L1tc_wJxNLFt}fryi!z*74nKPN`kLR3VP_{N10Xo3&Q}r%Kz;o$&5FT#F%XjY zL4Mx1Z)nfZ=&1dL3usX^GcXvLoYWz)KyxJvu%eq-Sy{JkT>(^FQ!nwJQ-d_tV7tNL zu$|oq$N-dY*U4t1QN%H9hxNfd1c65aC>J+-D|r6{Dlo8>u0YkI_4W1P)dN#~K z`7xn52;I00ogik72_iZs25mdwli_TEZ{h)RC;zjeriNNY%f#52ciT29 zO3EC@IfQ^uOtjWFbQ22we16;~i!hAhC zIx9Pyzl8p3`1I1)4HC&4B{dmg0PEwIQ5aCgug?yICL|bu4I%oW`s1y)$h+C%_q4U& zL-Z##0*b)A11>nbtn471S>*bd+;;{2N|z4J!#i@4UMV5F=Pkid`CLee$lj3Y`UF9x-D(o-Epi6E=jaT^eHTxg5X`sTEk&!`2ydsav z9Hmyqz{e5FQQ5DvL~c1be3-UG0WgUOLS0UnQ*j~qr@8Tw``SH8BjNhRxga|p%pY~5N6x&V^2KhG1Y zIw*iHHo_e5RTZF@gOWl8XHn+QGXi5T00cV9Hn#FfCr2;P3jKsn=jo{l6lgh%Ff9oQ z3P$rO|3;Qa9>q9m>^P3~0wRY9ItK!x5ex}~Lwe9rZnRWNctC+cu7ny7;5U0#^5*S( z_l`a~AvN67*?A=6Gu$|gad>nzRlH(RboB4@_3_!WcQ5*1&Y}p13r77aQ>6^r0D*~M zL#-ABgQv5KS|3&&w47Gj?`K63h9U>#2h1=z1qidi9vA}@FOccL)ycT@e#kS#tp=zQ z2vyX}BghS)1tBLSLD~scLEktmF`}G0CMJGOcMd>CnkYEZ^7tq;|C*1vj~^dKbpU`$ zlAgVcG7J#FacuC5I(gu=aEcv`-Ep=?xD+)JK{Kg=g8ynfKCfvy0()OQs6 zypsHX@2nNzQ6{a`BO8KL8_0f!UaI<2P7V%ZGc)LEHq+NfqJ%hhO=AZy8!XWKw>YCJ zUyawhr?3EeQql*E0j3{?a~84qikwdW!O0H(Jit@fA*Am2??I5(KtBBF8-Dewv5^tE z{cpY1RED?@eJ}2e_x%VRNn|rvA%afebcV>rVPJ6l3^c0VyP2A5jyuSpilqAdz&gWY zub>S_-buzpTYCZm(;-PHJfxu^h)Oh*2aes4LE3DQ{^LfX29}nV zsCDr?$+};^e5qQTn3^JYi|OeBE;fGnKuthIhh>E#t_R;H4=(lhH&9Wa4nkU- zO@;%+f409;RT+nCdP3hrQuJqmCq(@KT57iO@&dU^jvJVo>I$;wI#v$20=~gKW$EYU z?%rVQhTlf%fm?dPXC><%1UkbX!Y<$V{yjKrAk#1&Mw+cTbT+-5s4pSq7@`8Vlm=A* zhrgkrEXt3aJ8h6h5dJXdp%)!_n4lUqH8e!T#B6&)+&vXsPy;ZFplsDXFyJbO*78)6 zVNWxp8T?4*J$z`3lt7k6p|9OR<+!Vye@l$ajTAWmesZhXzg?#lbb#)OCR; z5M+le%(!nnx6^6r^Ff$8U0h~xq4JYZ2%q?pbBo;-W@-sXEXjxu25Fo{F955Z9I%S!R|AijYV|se^??FQQ`ubM& z0r&tDaV+r;lZ|kJ%u)A%OhUw1Q>MuHAA1+S{a5c| z_x%6VyU6ZT!58hb5{3GjVdcm0@Bs`Nxhf+##f+(mcK~nytwnJ0g3PCf8eU!nadDdn z%ho5ysZNLWl%lXgP@0>Y1Lzp>*+iCbLF)9+WWPp*8oAWWBAXHUViFJW6Pxc6n z5(?ax)r)3Ki=-wycRAkFL%#U#!KPP08s@Z={O#p*_xD#K1YiP@lk52WSxQ*g0e*Yf z<8zqS0w%dC|1=M~9T7ZHJ}C`$LMlU==m)^WZr9S)t?_eEH8wGUu>?wKI!+iMC+A!F_{(-lA@BKNP|AKPLvZkG4ln%U~lcgmV&BDSx43?U67A(fCRWX=!`WJ*F3(jY35 zWGouYnU$eJRFVv(%(yDmIj6Tt8BZ~_ov#qCi#m+KgP` zc9>fMyC8a~sqKnUW>R5^9mx@FuwPpIC=LU(k(KstwV|CiyK|k?R8=z;C@Ux{XP3DO zVLJpNRry9rNma?}vTQiAA{xa+6Z9!Vjg3oHPYM3%=~g6kzqdH>tX#c1Y|owt>+JQF zhQxdz%H8z*I)gd~>6hmZkC+rHz+jT>reN@C_BZ8>(xZ%o_zn+r9k zod?Na5E@|0=M$DFO8WMW?(UkZs$|`2DbYd%;+lb8Vju%R8Cu({v=REd^`y~f1kXPp z`ggaE_YEbUXM|iSp;||G__rLZ|ADj;NeA*i;_DwEhQ#bZ%HUtCca-QxOo_8_AV{W9 zPgzJO@skLNb|zqyGekU^+bfK zZUzw|IJiU6a227d=Hq1EMqO7-T4ba%U%cr4xSAIv_=9UYIv#@r6Gek3b-j8;{+-k_ zo)!+#9>zXfFl-}G-x)Y0G0g>KQtWe=NW-lo3UDMzRP9?PDz$F#rth3;IGR}Mn(n) zjCV?DWN;V`jr!T15&qx(VV5(BKUWr z%9^nhm2R4ZzQpCD>!jB0F4 ztou}Lzq+!m?N$eqK4ZE^jOcn`1mnwL%T1TSzfS6Y+_v9S(JT!k-TNnO&OJ#BEyJ5pNe2cF2O^)^R{;}o#s>(Zm?!LLY=sWgcujlzx8SbXL z05q)UJbJh*pC3pX(TOOKae&Azn54nLArpo?eA_UjNmZQL`erUw8nJ@;Myf5R$02_z zIZZ!eQvKRu8EU?B!O1GTw5p~?w5?%q4d1H2&JRkzl>E`sLy-SFxCWLBs$X?z>X*FE zPv*e{9z8lxPcH?X9SQM%vY1IZ$Vi#W0` zEiL<&Lrasv{5`$j9?l;2*xa1XnOZ|3my`b zA(-Q+2_7FGAB2{n?Frt_a^iZUCVZ4;yuU&g%O`Qnl&!C-$GZ6!04~12dwxc%HXi^0E zlnQN8JID0;GYo|$R0d4nMP)(S>mXP$zzWKcqWqig+M`B!su!Q@z~RIDAC>d1aj0IN zb!x^rWT5FUI~|+^VE&`BG7Xy8OJi`9Pg`pXvLtQ>ecgvO&+_v@t|*#YnwuRfyHx(h z`y%D3Mjn8OvEO1GDCmsWUG`db^4Kv)aCB}SqZEJ?l~2r0sU=X6@=_E}4( z$q$Z7b;^|X#6DB--{aUH10F$;4A9Mx`-~)>87ElXMSHX16n=<7R zR4}|N#L$H+S0LKlplR`Xzz^&9Z>sU(>&iPS#nK}D214V5XZCoWk>SKEjt)4K77iZ- zLAHqx$2e&ZMa7&aPYM~hsk6T+2$BJgfT@F$kj-W`cU6%IqHyy(!p1Y?Nr7L{a&put zeW3P!Raa-6xW+7b)X}4&sl*hAtu2i`Hp^Ul-+1&JaKhb_CtbX}{&1UUW}keOH(&Ky zAMpj}jV=QC>)KFCJSLDizToK;3mzQ9{1-2zF7#2#Plj7Tt49Atzv33=$!D#4g)3SwG-v=vdiLxYABe8IG_~8W z&qvMH>MY!>fCXLVCN9bd9Ua86(OZVcnQy{+;}7;Kv;duK)U%Y1H#IfEv|>qhEe3VG zI9!} z*Tss9+|trQ62lM&IUo^#F=IO|M~9n83Co8Zf&Zsnqz|XICfWJ5wQMwP`w9ol{5nJ( ztg;}0RSjc`pF@^Ojfi^zSwr4jeQ{V`|vefhdaShrnXz z=Hzs2XHA*-*^t?vPP1h{Is8LOz+hBXP@oe%8-N8rsy`C|d-k{%`bY@C1k4-I_sPQZ z7ZouK_yZ8Nq@?8Y=Q`>s#*27OQAdv4E0!Hm;#{VOuw?GTtuwb`LBZ*PF6QN-LRvaF zitLymBlz=%L4P@1Vx44Z88@@t+}X21UVt*-d-d!i_(p)6&{DreRfOXlNLkwQj?PJ8R3N)4#5p02o7+ zgQr5#Z*ef!qaK+P8fQaFZt5+b;{68?knJK}_{23bn&0KrwQDc(^W{Sa%Eap@NXV6h zlqrEu6OoZPJtYo3Ob({qovq!$@BYK)>TE3<5569Qu-sygGGj*AXUzhE*gj95%z`6b z!Rw#tPgR6t3=a`+^hSzmvqg)ZdMWESD=9T~!mdXAL6Gc!1up zzTSjMsvgoGaBm0QQgpt?+%(`YK0AMjIX`jEoY!Q95_SJ&?^8E**ZRH9=A^@2pSM|A zeMXE>)7qw7MkC29KvvOI^RY`|05C;iBMO2d(NRY*qIRdwW8#fj21iK9{GMk|pWdOo z1B!>jq*QY{xlKaLpT1ugjsKlHqqMb!pHa!E+JHrPBwS!ndQrv_t^Bp30u=*zQQG>? zvH@0*$0*4cU{<$af;__n0HgX(2MYcZdNZikL=A>ohe#4eFbxSw58k}Ai)&7&Wzr*J zM2J9N@u%LSCr<)Hb0CnAawkkt)rQ}~^DHpikLQlugyvAX%-ibl(j+@iv_T4;cg$d> zssA=(au}cY_)2i)HAw4Ueh`GALvPU5^gw2F;6Qr1SD&_0$`hJ}hS!ZU%BvXV2Okje zu4}Hj5Wi4jD(`N}n{1I&?YD<hoPOGaE2q<-MvqQ~8r63< z9y@cU2~+YqI``7k{c9K1XKgxJ{f!XST}g>atyrcLXj(nDBYXLWSqYG71jG9u^)zu6 zZ5X&$p2pA;0J@nST&^Z3hq*5PXy`-Whx<&}Qf8KS|VO<0{G&k$wB zBI;@q)yy-t(-C*gotwuPH4nt*O1F)hG!**oKNlZghpL~8$`Cj0Mr7;P7yYKb(2j+^ zL|X(+Py_#3;F&;x#ZZ7?3Cz>hTsuwApEU6J=IL4vCI|4VCo6D0Y2mha>Rwg*skqc9 z>d>Jx=g#pshMZcWweRl$c_=-ukj|_(!4HU_Dj=PgUQ8TNQL%S$7-V1|n;T3uKn+Cp z2LK-P&ndb<*X7I2K3wiz5Y&xB6FF$Vl{U4k^Sy2>E%e{1nAg8<%n8C)RAj?mQ2lXI zh!ixE6c@Hrroi?F0hS{ZhY-ykJ`-wAR%rQ&vYhtG?qVEy^m zC-5wuJn5q4A}bujCc?!fGilmmU7a2g4064-v7^Y?r6=;!U$-YS)y2n0&Lx!xDwQS_qvvdRZ1anp*i z)d7t0yqxu6Vz-@RX+YC%fQ@~sDygUlYv}uY`4BvqaK)foWuX1b=kr9!^4D`t_GVH41kP^l;c&zd9B4A0M zacz+AKgnxEug;q{8<;}nSz=){?9|nW{rge*(NWVC+S{jhyzLF5gBY}QEfombRwWG? z0avtD&2w}`MelaxLKpi^r`6cM(C;D%DcII3JCSFND1Z`_J^(ZeT+vDQMq(n0 zsm0e^r!chmDOyBl$&T3Bc22TOI<)Qm9h^*8or2+zuKU~8)r-L#}{-vZYtBd^X{T8jZmLkef=iZUVCaGNXw$rx+vgx`A9 znLHvXDJg121Q0m-XE@} z5xvXThu_+KfGmWW9e!XXfrp`pf)$l)I5e z;G&;k{+A4HppJ8U@B{#plo$i*NOH6<-_98U4WxyETkN{Y@XMVkxQVUOR=LnclPjmJ zq;${WK=2dG#>Qrx{Kz?QgESGn`}NC|5LL-y0w^p5BWv{>a1f(rii(LA7IzUW^5#YG z=Qgkp@0AxRPR=u*$w(xEL;4i7Hvs>1G!6F0u9NG5<3<`7?6J~zbV=aMFnL=rVa1Rm zIF`9(L2kKa28nNH*f8ZDJ)Ev}FaFgEBmRdb(Wm>F8RvMv`6;mKi7mCuhx`LfO69%@ zTox!SV=_z|ErgRw6oCZtk79ovYFEJ@3{7kk-<)@D)1rMMVv>>&274Y* zmY2tii{jDY`ts@P*46CwZ2(X%mZry;K7HQ2PU8}2<}vhq=~UHb;dv2-efF&aKK=50 ziC3@Ulh^adA^Q69+Vc1n(iqWyKqa8LWs;sYmjZ^ecy#;=DpkiTXBar=fruzwfU7Y= zobl1$mKv#Wmtogbr(W?GZDr+{l3ow}!&^JFckkJA=Y~^AgDq0}C%i8a1Pl_UOq({$ z*qAzU>cokU5Ro4Dz~U?4=jkR0GPo;D#)&idUXuS)xd`xV z?~4AxO)|#jUKe#3I0-bTqRa2R{y9;yh z_8OpQMaa%}j@?%2Gr?wY9PMfaSz!0>sWBsVbUnlbE(wwDj0+sj*n40gEk0st(Msxk z_1&#a3=Mb|lu#?~-ffP66O{~!eOd02kN5ywxDYy2e$b#x0Hlo#4T+<~xk8_GK#X=B zI*h6N0x+9ocbh(!Y7eJz(`6lto~5?6@1lgj_rrpLt|<=a`CGwZw^IGW@Bqqh-!Rm~ zWIt+U`$QcJi=ub$nkg2^{(?Vl;~E+ZO?Mf7(n|+S4geOok|>C z!VBiN7S!h;1kbkLqlIcSYv;D%;l`QsW?#5FsUrA*boCn7hZXORN$hS?>anmsG`?+Q z!1R{!L+1Nw$w<454St!nZY@0Cr10l$1{{AxI91AqHTxI&`uSP<4*9L@RQR;3^>Mq_ zNdx`MA143bT7ag|c)1SmHoN|6m9o51qs!lVZpFN7zDFCU9sY1w>TO`RlS>~)eMu`A z*&5#8v15Q${X`uV53^IPRiSNHzU@vk*p@MEOM|6dyTG>dUY+X_RJOLZy?VTpj%PHr z!|rW!0UC67=0-TIH9 zs?|o{%|EQn(xKyhIq8ZE&0&hl*iVb%uKR|;asBiLwZ?Y|sL#;eQZ=mR)|a-CdymRq z|K0ZN#J}pV`UZ2~j^{53!m$+joCQ_W4og?-Viu;J;j`_=?|>Vbmh%-w<(am;Ul)s? za85T`;tV=`=n&ZauZEs~k*4!s>M@b}{*SDzdDnj}HR$nQOAQA8*HVMI|FzWM%6~02 z_=^;`A)-eK;gR=($r9ETJbPAMr}$O*I7OX@M^&6bmfT5F!{<>`vB3cdA0KrSAP$e~ zeg~JB*|?1r{OP0PUWPynD`l!9STU%^U{=s79w$Ody7wd-B)xoXOe5dC(Ms$lA%J(7 zKjwc;NKVdH!~J?{yj)!-Xcp`n!zrz*@-UcoAU0N5V&m{y=KrrKYrQT=42dK!Q35CI^;^|NKQOgwYjQP zO3)rPs)eLwG@YTEw{KPBX2JuIv&M~EN<~GH>4573rwjEAvwy$*ItxCJH`w?P45e_0}vfH zIuUdbJZ)Nc`fKS{UBA-NPEL$$c1fJf#4)n)(49Lo!XY39fkKI|06Yq%NHGPm#2XqM zC9|gM!D1LH<~9)U^VGmBjJv;qD>X7G&(oU4{*nllKxO0>@_#*BRxI)C*62Xlv{@RNI0PM{K=-dRY;`i$Cuh=IriVo02Zy35nB zXE+L3e8hzE&!6W`pDrOds)@o307fi3tCrovqMmAfOLc!9ugbIY^A|4s@%5`J4i3CC z$|}awOV<(exhwqcJKtRp2n#)u_U)VD<;8zL=U6yN0QfPO11W>}l!u9W2K7t9<~eMI zIQ%2Ja#zJyh(~~x;GCR>0cHWUqMnme6S#T_-ai08^qf`WofzRpxY{kC?YeG#azcW5 zsptkk_PL^rJ>DZ`9>XUQq2z!8kBf`b7#{jNHe_aICJH$A%%+;B*kh90$H9K&zP)>a z)J!07O--c**dT^J==|ZUuc4QI^k~IH8%0h#;u{T(L4Ersp+M%__PSPGTZ_c;;FNvV zK&nHf-FO zxrY82<18jp9=41Fjs<9z(`@TnA-Sgyvt(HfdAqtK#JbGYoDyiQ-KujosFw}f@)`j^ zj-4CK-UAE}XU@-8$#hO6dtm&B1yje*5~8!Elz(Q=oGNWfu2!Uq>&UxXU4DX<;Fu{(Eoxh+J^{IUFQ#<>LL z&+8U<-f=H4uZ@flUSGeEkxR^T7*|G=jN=p*kI1U}?0WsnWPM>DV!CpOs3X?Xw;uUgK+A zIDZ}-3HS*ee1PRv503aeIC$_Qeq~u^EhgVS)0d%`0K+Mn zCi++LzDP3bi(;&g!=^|Jh^hiPT_Rf{`13Ez;+%gJB=Qr+oVQU5?W3*jzjMA)=w^E`F+7_EBPM^Q)^#$dJ8h@;?sEr* zE?E;Xq`-w00v~>lr`qAYQq5DyDJm*5&4nW>xe-r%i79rxULFPNA?n;42o7)Dh%sIL zPn=)tPKSUD$5h`IHIv0_pUz*zYJ~?6q}8%ui@# zbZ`((9F)w=GN3C?u;?!;y-d^W__O79of)qJamyIEkyRG!k|2oj_r+-hSrCwj$X&*a z3bVPuOU3$o(LInzN_B2t;=uSbXYMWP308_xjf<!sR*1~Kcaqo?;UFHdg#!INX>&3k+Ap5#+^GI&wSS}C!f=T#CVka%DVM&d+IhRr;H zAbt;|StklMBIe#hhose~1IV2|y_6V0a-<@Gj*W_%NBM@EEYv33qIwM)M7W=^c=2Mr zOZ4Ex0iz|=452qES7abCgZtsS_>t^)SbzQTLzMWkYi2O&6%bS@K^#Y$pvTWMsQBLR z)im}V5S$|cQ@#Q5q1SfnB87cI_2yyy`Yoddtg&S5knr^ zjAu$(%O7?eX+|GtdRrkW8FPI6id^_R{T zRO11XQc_NpgHbONTVfLpfia1(z$cT$G>=c%R?y? zr$DAb(ctcymiP22YPL$wDSkM62K|PF5xFw1CKRp5nNVO4Ndc6JL_{6ee3(YbEV|=^ zF~{vFSvm~W+yBUI)vBYU(J&j}ok-laxobvGIxO=Qnd#G~`eTJXs z0Nd@?qR=V_k7^f~5oxye1Yf_dX@;JnPQ;heQqdz92%1hLqP80iNP>Hhd#`V_{V80- z1H@aI8aLiu;T%?#KtJ$`{O=N8)2w#}5=132ZmpiG5VT zR)zvUR8|s)Tlo8K@}1rr&1$1Hg^#89=d#R8a2$;;?Bx+MQ2q|#w#LCpbTG_pSnjY6 z=ucHf3zyk@0;njeePlK;ps5Jynsq^sCBDZ(yLD-@GwO$-9@*N_kR?}D_)oCEN4G1xadR7l234$9VbUcS7e z9QZJn1}w#EuikB;&bGQyW3+wEL^`GK(4oIk#MB?)Q8BsYji(+{8my+f%w59ts|qUA zEk1K%8_^q-U+&C8sz$nOdug7z4}W_r`I;1$n!SLKBTf@_=s@Wg^df_5l}x}9reo{w z8EiLwddBPU_5B79hV&Rcs&iXlmyR9jJ#xX9c}m3Bd=saK&4NFd04S7Bscdxs114NS zZ;=38zTC}C|GLwd18A3W8kVPA%$INeR2rbcqz(vF(Ow5_Dq zrONzs|G*Zqv97MzZx}Td%d*aF#P)-U)L%Y(BO-SGU4%hw&o&=+w-crvJYXhzn2x$U z|HiJ0LNIO)123GCi+;T5)`rkQQZZBcQK5VG+$AG(F-uhft+ZuiWUMNBAnH9mgOO$| z(~ez&=R9}rCR#2*h_a>J@S?8Ty*r0kNCjD{(1$7r$UZgdkhuCm+!D67KX`R%Def)E zX)LKNE4}6Rg0b;XQ|p$2NpO>BC&9$A9zmP!Raw;X`}^F~@@+jwZN5(2A{5x`vTLhL z*RE6ODW5(i(Pyn%HGyt>qyN)FnJ&I;2YO8UH6*Xd(&!nw=#XhYXrW zRh&pmTWn?JA3DCXWVN9L^8AO`AZAL{hu^(;QD(loOxLcIFy7wvL>WSL$XL(kjUG~C0IOj9IMd2XxZF1*|K-c=8lSoAOfxy2pd`eA!#v3S zO!Sap!#LF?J1Uu7U_Hf<4^l|UsPFJzk^25f5LLghNst5iUDev;Vg^|XC42=`KrSY& zwE7w&JSWVVbI3{?JPBL(3~R_>ihPf!)oX8FAz5Q5z_ghl3YkeL%U)#Y208mvqfo>_ zc8cOLBw&PG+C_+Oyny4uugmgFnf# zTGx4OI=pg)zmHk|4y;REhAa@@Aj!>2?;ZH`$(2vv>}ff~x(%F=Uf$>ZyWPDL?XKGEO9zfVZpR-7 zIIW&jns(gx`SR;h9b_@FUqbBwp(n0;U51CMbL|!O{}NI2Yc`iZ?1pDaBr1;1hco8Q zpAY0C|8yoDLL)P*n>I~}8G%f}gP>cm0c4iZyIpZT$7r{*K5e&36v}QPorntwiVtIA z{zQKpW~4SxDNI3NgN3w)@l6zVa~&MQc6hQBjqSB0ci_+{3}#tu8D;yR zNh;wZuIY?qj#~f8*2~LuVei8+F{9uCp}JF^%2^Dp8|;x*iSWf}$MF*YHfL`}F^sb$hS)5BM1D)8pNOb**P5a$r^AUEAzgl9=c8CC+d zVsl05`G%_qcEM1G>0B549&Z7*43rk?o0!Z*RTTO_*s?WA?+MidH_^@?N#{a}?%OCH zY+ama@*Q0`Jh1@*5};f^7N~4hRZvxZl$j~D!DI90Tex^2Y3ex_c_G3g9K7V$XSNpr zh+*a7E1{t0PMLx;3C$vN6dY>$wMi2uEM%owt94mr}z zKsFN&bm=N*%B(83Ur=yS3#Y8(j^Lo7s@9Rgi|56~aZyoh&nc^@m=Z4{oK-q1W${U& z#JuUPDclKqeve3rRgQQ^E|hAde5M}A(VKdD2C1eXHBCMw?XN^P|<(rC^)#^Ujd><(4K9+-H5v0Pr4tR^ge0zQO30nH+^tA`bJs+&F#~>cY2De3emVe z98WZ40@Ef=3~)U~4$9@dLs(;UK+i*_tYHH}mo9h*W*wRV&Z^A#4ox`ae07Zc4(n3= ziNvPeDtnI{`Bq-u?t3~LgMr>TJi)nx9AU`&q6$-Yy`GeWf4lW>lJ?kf;}Z8O5|gua zvPH15z;sCI?&g1ridqpnr1b7604?{$az(GEV5&GYC2AP;=WRPpZHBIxpoF8GqXk2* zIxuUT?t*Fa?CsB9zPzU{3=4zoZ3!O=pK+Q{oHFq*9k-l;0MZr+vOSf)IUZH4!%fx+ zq`k$hO3Egf_6j;pB=*C#NJx2aLx7-0{A)go$RVdG>)pGa>Z41Sj=G#Hfm;*$D)eZy0fInmsUNz!IG44MWRvymV+3^qa?;Sa!xy6d z|H?81_1}9zd2@~o?ebIoUUoK%6ML$tglJ7`O>K-KslItL*WMn#F?D6-VJ;73Ojos( zlxQDayq!T_(>!TEN&7l3Jg11m3T;8X1qy(<6#MAb1MMMrCJI~<#hLF z7jGPGS%Yp%RAMuJ=Y;a@SvX-xjUv9b>p4+ezmo=nc3nJp8&(4Cs*Pn&YI4B6d#;hfrrfmG;;13`H=2-*7beOE$V!tTyfti(+Z|if^XFY}W+jhDsh+%ZM?-D#+t-Z=4Mq&7<7!v3 zHH3Ln;^7+l-soti4b&+}k#NT?BB^)%rk%%o(iSF;9X;z^t2kUtXNtEk65kBqxZ}qs zP>#Q_Hbl#tJKsB7PBH)jXy_8N84%(+5mkM%l?G*8F`JeV$)4fDRFnA2w-ALDdTo5S z6SfEA9GT-Ezkk2YrZOTFHO1)JL*RP5#Sf*Fa6QQ(h>9i*i()Cm|>M&vGt-7z&DUC_h{6G}QH zFHHG&&`n9RPdteNq{coX;x(+Pv-l3AVB&uiFJAz6b7yxW;QBkTM0;iS9WZU%QR3HyceK^%@v zHeT@@18gsV7}R`3ATUZkd2H!DNttYJCgLmElMRkd%N;Lo=bwWfxZsRS|H+8hBDQa) zjjZOpmq--JT%(85HHg;ht6p{tyh7TCPb+QJrkaV=y64dlyo9nO z+UYnEgg@%;>^yjh%(2p+TW~ic!y*;~FoV)`_8L9G-o60P*XG@opH%hHpPo}I;zYu% z8l@f@OL3Cx^h6&Y^W85_9XnR?<%`+U$BL-Xm=tIH0yAG!H-eB*()>=plpOz;b(TPIoBpj8_k^A{V$C(P4x@-Be@fm)!! z=ZyHm15jTI{vd>$Z|A9s)Zz5fJGR7T>|IT@neC%wxG=?kN`56PZl-<(qucXExtD># zUFWRMIo-H)s((DNiK+SXC&;Ng8+VK|MlJN+&GFfNrcHBC=}&l;Z)IiwanEJQugm(f zz;HH}Y;qeq0?|u=U+I_u(|M-#W?&~EZEn-u*rA?qdO9!!>l{Yox`?ud3WHwscvHKh zU33pl+A*^sbM@3Fso@?a!UC1fNj2FI9-uV6s`@HO>Zk0NPoIM1f`d2yHR@;hihgMB zrTOfl%DLHBMp~`u%y{fHiqS{X>G}3gqw5I?>nQVTk855mhjH-PX0|D_W=pqAmry=K zrvD8U@sY5VLsEp>MCn|U(*C9BgCoOp7e@zi>{P&WKUq)FmM6OgHoRfuKx(&c0upy4 z#*v;y4ggEQikPl3q2UnNGxJI#1`PN{myzG{p2Y{<8|l};pLo?-(en_@0GB`lc@jHQ zWvQDUj6CZzO!xIP8Nlcxf3AW?QDgx^qtONkNI5PoI1&zx=VF z7-(qNRu*o_-%!$aA@03Fb4v?F!_&7`DXj3r6K<#0+$WD7pkwM;!fChJyUgeaB1<=v@Opawo2r7QeNhIr`iL3?GZ_U1>>U{f zeg{?Q0jYtJE`h4RFMVluk6T{!Rvs40(!ygF*mOB2ZQ{4T+qTJjwNt+T_)U`)C#y`e+H#yn3)&&f4IiL$myP^z7M8Dcs!blhjhAo&Po&3t)B& z%T#RY1<3F){Q(c#IrIbIg;tLqJ1$*3f8hde1gF7l!(9;1Tj1RI6IHj> z6YkhQ^)zSX>xDce6i_ucjn>8PANC>=B{zF`{l39B1vS&lQYgm=1IAYCzx&lPlQtOEmSs(WW-Z!vbV+Hgx|R^LKX@K zFrjK{xqQ;n*~DxPoZANfNvAE?h>)hOZ)`jr=1aYr0~r|=71mdOCxHCIe^{7Gy$5z0 z3nRseB%}iDVI0PY0Gxu@9dm17!ty(*{5##iPWBUL&+-a&H8o?2aG(`q>h=M5rC5|M zdoxW&DfCrwad_Szq@vuj|i!T`x@H2=ZN`3t0+>RP0x6 zZ5KJYVl1}g~mn~MzL&iE1bjx_HK=lb68fNVQ-o^`*{?016j4nkRkg0`?D*wmfG3Tr-@Sa!|f`}X5j(p zyPaPj1}mW-dyH9BL!Q!^xR18-&=?gV~`4o)(GIdiv<0X(@ zDm?pJadBEPQ$PP)BHlBZbf8etojhlWENxEjKcUDo7}hvlKYSyB!<;mL-*H_{&9?p& z?b*S~|E@$ti}g{a=g3q4IvRQeO>_;MblQ3TJh0EFPi52o%$hpYfbmmES@HVq-_Pru zY-_tjl)=TO86&70_n6vS0W7Cn3t$5^a~itiwE-oD9<=_kVnY=a!A1Sm5K6}c!3%>ZhX3AFpd-p zJd*wP(y7aSz9Az@Bq^4orEjJ^B-Wr*8Gkcx4ubrhV;fazJ=rJ2udu~OUlkOX!8ZQ1 z)QjF>&rZttScqhJAg3<#x7EuY3(VcP#`+mhbYbDhBU^_Am#=YGR_y$dARMhOl?Z?~ zK5gBv?Am0{mj4Kt_Z#d{kzFEZvs+S9LNL1C-c6-ksFzqfI@n1@a2r@PJ|wK2P;YZ( z%6+|tGXdbP&2uXZvrb>@Ai(-+p=+*6D(}_Mt8_!K3lZFHzSn&{7eUa8Fnc$^*yq5i z`-{;6`@9Gm>V{Fu)p2I6eOo_yWn^a$JJC_PSiz!wKz(1kEbHBpy>+_%b)jv}t2Vrv z`yWLxB4YLbQ(ED_f7}127}j6PT_Takz`uMIwytp6<2_Pj;uPa8A+>27roj#p)XD_LP@f?3GhC{qaAwS@l-@utA z&7{pGp(i(Y;1=+U;|25sfa-B`u8j>yTk97sQDjTj)Lr=t0S`c}H#0a%D_@-_Y?cnD z(x8?SYqrzZ>@Nb~KxbTGiunFE4HS&P$M@aj3CYZU{Xnmbw7Fj9e-t5yd4B}V1E!y@ z&$jI!52??1%^?K>jAh3c~n^^;XGZ_rZHAX3ru@GdflZV3v z6Vg6^4%X^t8=0`W(3H3WagVxrZMBv<5#aK^sfV-U?VdV|ZgGYK#duSs<;Jh?%JpV8j94ZF$X}@PP`zx_??F1P14+W*C#8DiA4h<=8A|tOpS~ zT2e`W7${YkT)c}>JuIZ57W!5*^Nvhxm8M@aj!vj--n@UG`)4(U52Pmly99{t z3M5q&Jne+4>guiaRT7$G{?}4X&p`}XcI&2kxi?0DQ^vo3^M=!1Hj_b_zOj^)uP-}n zDSsG24)pi;hX|Khv9`Rd?C6LM0~Y8k${Ed|J!PrU(wU1FGvSltr4yQU!cLDgNF9sC z=&5JR6O8zVefxgOvuuNtSoQ=n2*~8l*I@er9&l^m4tG6YNNNeD+TXrCUB;-lYdXMkz|Cbo_peW`ZD;II*95({w$@<@ zFYRkVfr?;<^oXUNWe>U%w=fK4rkp^LRNT>U5hK)}p2nH!&dTA~Y+l z-dmy56*YYLm=%I>%V^jV76g*Z=3PGo9(2D6+ga7k%itgBeEEUE+R^R`_NCxS38T9V z8Nf_cU|aKDw`Bm?qAECU24)2-tTlV~M2n%uhQBj`ct0*5qE^%wyGfetDFb&RbOB>b;-{mTGe>F7SWAK$YVpucF0{(9Po7nFG`@QBi#|BtNk`glnJ0c$}~k!+kbuG?}nWJ>(>U%f^l5Lfh@|FP1svePJzo2NX{NV-c3`}pkKcZS41^q)~&pj!eOn^A6uy30c2u=hgeDBv}bwnk9&2`{czIxum0f2y3 z`jxLHk~SpGUAs;^TTWz-G^8zstwI&xmIb1*Y%<=7K^;iTz?MLwY|QK7dqiE(hHgMq z9WFW+|Kb~t95F(3__}ri!tO?X%d)hq4r~B|?tj2m9C`!#$G^NN$^{q>R>madU~R(T zoElHWLY&wUxms;)I1laN+!4L$ae-~@4*#p>)5UvOcDf)ymtiZw$6`S`*vBt6WO{ni zdGl}~|7(B!x_=pOAW_j*+zSg9Y=^gPW1mR-04tE+=d_0ehc1E#>-&_H=Ac<)djv2Q z=LdR7*|6Ks;ynuXCK3YA1QQ&C)DpCN=Vq;h?}FdDgDz=^r{`V2Hj9^!3sT$tdhMTP z5i?cm@+|iBvD1Fi>2>|5(FVXDcPC-<%yLEouAV-9f=6IXu0?xSBNY{5Xar2Tnn9{cS_TUll3!tMF956n2JaBl31h;F@X zXC}@0M{&lG6`4M(G*6$(QW`vDz}UA-?S@57nDqE%f&00_Sy!)5c(>%{_sa0vnA-Yg zgLAG8Q=e>VeOBi4bX45>r=NX(=6#g2#{%A!TTMcftQ5tJA`eFRB%C)onG zg@{$V!o#OoTW_1t8$%&5s^e4wTwhGHYV-tu=rC|FuCa@yqh@%p<{F`d>&K>`%>|zu z)A|u}eJtW^PKIHekG_;eN~)d`NM6UmJbcU7QS3~Mi!B}Icqn;@5SQcQsZh3Sp2(L{ zkDbQCUKn&SKkwa8d!CX5e{YWu1|j ziRz=ZN7R>nWEO-&OvTNjEaGzQpFiL?AMvV!ub^Jn!@hK#Chj z%%Uaby&|gNx9XT1EsxvB{VGUd+yN&4Eo0 z{bQ>wf6POkM}=mQ|0cyuh^g{UWvY!mf{LBl%*vOmnn!0!tj+_1xGz15LXp|;%14Mj zt4SmjOM%i|2k7gMJ;<5hP5^ZL)CfO;eE>%G;A;i3Z$7)HVLD3Hcz#d<*L~o?3nxz8 zD=0{Tqbo@dU@jkbN=iWGksB!^nPMc^!CP4mrM*GOObenvXb|K5r&g{Si;H=1X2iaI z0Luum_%#zL!>d;n6>S4PSzTTJOb7V+ow?vh*+tgRh&wT51q!P@7+Ab{!?-@=q{&?m z&2aosjhBS9$7ShYH(eXC$jrOR7CS9Te;~)^d5qoMzI_|DCPf^gHbHyDh+B8=Fslug zmiYDu>K4J@PA?iKb?}zj2EC*QU}N|oLsh~jKF>fVcIJ=1VrPJ>E#Vwo zE|9lw-yYsmc6K$975`E+3#a1wYnV-f$|k}f#kxOhus9HFp&laJ>Rnpx9jY|QTIn?* z-5vh{0how<{sr@=uU~I+vT@#}SG2TDU8)Fv{U*n}iFO@4viZgfs zGu(wUKkGhtph@e?k0b**`|5IPMCe<)A=Fp=hOf(l)u#6S4g zh+>TU6(Z$JQ6PN0&$zy|G?>r6{wmsYo==0K%4X4kI;aP8{DgFyFT7FoQT%*N z;g~`r$zp_s|0v_~EM8K4|BKF*O1ONh(~>33>g;Y3O$T_+=Z5;VFW*MTw_EBLTnrvZ zSYMKn@j%0k)D2+}QqC++wWw>?U&soRR$4S;IGJA(B z7{>;hb?3X@f;KM3xw&EAlrvnfQA8xvT)2Gs%(Lax#8iExmjeGrs$x3(Q}eh@cT!WK z)wEr8L7E(K~DIHrT*XIXnYQW2lsJiVwO7KU^|{P_phO8LJUY z=TiPIVh2Fi>*Np+2w*qVDm{DZVy>3q7;Wjdh)(AI{p~g<8|v$M78KVksxwyE&9HTy z-vSBB`}3)(KCraR-*J)&C}+Mk@jw3SnSua_pjO_1KIOinQPmJgICzy^sZrrQhm#4O zzkR!6iL}gvTE?Np=gnFh&xANZU--&vwndHqrj2e45i-KyDE4wez z9=~=#>j*If?BIe^_9nUmTnv2O3g1Wge;F3YF}_pL0$%fQn=d^XrKnQqP`1%o^z$F~ z=#Edrb1qd;k;TxVV$#4xk2vy!9t?n#*N-z=RewDzl&LcrL990UyG_QzQj9!QqZx0t z_Bz<kYUIHg` z9Rc6kwWxO=yf}ODV)Mtti;0j}bg?vX|Nh%3ca$#rScq|pAmSidv*ys@!{ZIJC75oB zJyI|A#w5zNcMaP`VG5L0RU6PNahscKo*43=#+{jW-Rxn`ZrNwDH~ARTuninCM6qEX zIMfMgJ~?e{)y}R*Lzy}ZBz`7Ym%PFJzwAj3V}K{I{;uBFDido7 zrBQjGf%eaAEHPILQ_|9!*0mEl7yQ^A6J4oF$MyQ-i{Y9${hHz-v1!fcPoMsL)y0vd z{M)xlC!g`zO&!w(QY>&EbO7<5j`PDfr7@#N2W-Bwe%(6ycya#e+Zu5fSjRX6F%o?F z`W0dRiFI6AS+7F%hzZPLjNhQrqYOE()&UcSEe*LVs3$I3=;$~@LxHRl#+Sc%#YK;f ziAlUB&i&BkR+|H>`?fYL`z0NhUB+UIUrIw-%D#OY;r`BymZNtl2hAfP1Zo2kS^KE5 z+T=xxkYg3{^XT)TtXq!-AX}mB0M^RP%v}4C2P;YwQH-RPRkXPDXJ>Yen(*V@P15VW zBX_4-TRX$&(aTspHzEZS2EN5IVf4Q3^3|fQ^*$EtMaIoYx@?r8mOxiTm_j|VSC%Fm z9_e2AC?5+y7>GL?j0DU{B;UJ_jr-$R{+#Nb?d52gDDv`MRD9E2upu;f^Wec5FoMB@ zuU@?9hFF0s^W`~sLmFRg%$Ur|yG;g0M)D&kgkTX6*5@i`kLHiZ1&#|01ddVc*Iz`R ztJYe3R%Jf{pdtWlp=?4_#yj1+vbYCp-s-5&?ySDm@wlA|AEQT)-?3%HMRc#`W@eG! z!girqp$8M4xDZIPTH^GjOD!*^Sx)cX3^vWLvN7fQqko5{U;RDG$w-B1t+Tc#pCMLA z+-LJo`|-2K>|kONz+Ni3?N}nO=v*+l8v>`;rxscLs?EzT`1T{ybHu6sOpS~}!o$aJ z8iM322_YI)fca|az=+65a0GAkwH=r#;W>?n#m^1;mCPr?RT<-i$exvp{Exz;C8k9AOTY&96{eFI0fP=L8TuotI;TN7~4;s z2%I0=AIw^mU)EUEP}|zGr)-CQRyMM)%_a$lp8$Lr{ZTqbO1X(G6IZc(E~DL*Wo5db zZsn^RZ*34qfT6SL`1Q;f*vl1<#hp92#hD;YUOAb%i3wxGxWAGdK!c8C%Ba6##5Cdl z_y>-{7n9Z5U^7fE3XX^#&{W+ysf~EYskoZ48Sd2d?$>x9YU=7U3n?G{e!rSq*)~by z;~$7z@3voWRMf&gaZ}Ppr63353u|j@o15cQs@bSe=Vn@nD4Fu<@#D^&K8iz(qR@EV z7zWBIl=OGaT>INwWe}^S&7mi zlmz>T@xakuyl4FLp56{(tcNOWQ)~0^p|=KvXMc}*BCPoq|C%bGG`s|nhtGzI8;xF!I0YQQrTU~_z>-%s;l!`>jf zWO{kZC)^V#YhmReuj$#KGPvCN1KapARyP8QEW{cYz z^89#qXHCX_#4&P^eF7_OZnDBC%X#|A$m8!F7aG*12T0k=irak6bT!-`d|by_vzh<}v0kOj#fU>iX8HQq;{bp+snDIHmt(ti6 zMTPKi32Ho@8r_Fd)-6n$LvTmsaunwKytMAKGHTT-i>YMh|6s&~euz zfPK`(kU(E5jC!2!sI+q|!x^)x!?5K%_0PWPPiXm!qHH}G29J%4lM@K%&_eKRU;1pI zyhDEVd+dmqJsaXt_h5{G+}2)w0RGYZA#gM^eH+V?-|hS%tt$%>%b-T;Um!x{+q(g+ zLfle}dTrb&!n;W9?|W9EbAp}53pL_o2=LL+b`nC!Qt2}}f`pUsf~h&eGhJbTQrFEOqTvcZ8~Lv)Z5pTBtV z$G30)w9T8<*nC%PVv6P4ZD`>FRiEYoGBCP_%@bQ@%BT%l{&252Ou#jG`PyC#=KSX{oDE9(uw=g=I0R#LRaLd*{{PkNlUvF!!#~HZroy*%9=&hS0lC zLQg9gr_mI#BkIxZ!mXOyHTxw{jOOKtsm>)3jqqo-Ebd0(NOD0prEq9P8a z$D;U>?pU2?v{glY7q^Zh3l%3Nf1OrE*I49xVoe!O7Zh(zs8N+N+jan+*g^*2R5`tp}T|^j#w!KKa&VKK`Y9#c%f)pK;S3 z5&56rRQ35c>WlxTbn^Buj(`6=BjSfUKFbjQF#n(JhTTpCiZM$3&0?M2?*DW+(LDY@ zV)M1OZ{~l0qIUB%J%i>oqnB2tjgY%nEcYx!E2QXDo6^rWEyK>6{^y4Tbn4z#p(@|% z8nXC)hrt`9Bhx5R{{44(UDpqc98p#r+pcs?P(h$&^!{^pYcHMw6+-o3JF-W9l0+s$6Q$a(s&xdN>>dl`|;;^Tv#e7w7? ziC2gIl0n$COA?2lz^OUm^eG^ApndmMYg=IvSllJR%3EtfYDdY^P)GD-wtY<)_5knn zOB`r$_$YtF!Gk+wfq@PgIE-NJ5DPVGLcK4$(eEfJ4n`F`UJdF+Rs_x2G zjT0xHH_e3jq_G5K$cY}_T_}282rEWP?5?SK7olova9OoCgL%ldMgzU0Y-w8a?kJ)P z>GthO6L6z)JH5EdgKDk;5H#4P>O<-%&inh@c@j$ z^iH2@Y?52pTLCj|oG@8D)3QY;L01RW~9O(XhW zKyBxfl+9>(A3u6@2N^H6>L3H4%)~us6J&lU4A+xn;tr#TNx@i3UHxdXLsN167HD%V z6Y&JZ^)lD2q~;{sd5!@8l1Tr*$a)WWEc^bC`;bbhkccEJNo1xJp)#^ZMluo+8Bww_ zOGXMwh%zFP9Z}h`lWc{oD6(bm=W|}yec!L=|2*fb`*l}WIM3tw9lzgqecm4s5ePP3 z-W_%4S%Ts4ZH8ta0x1IHY!GtDm>d!oZmz2vwTZSr`2xok8J<}#+6$*ysQ+9+xUwqn zJ1N!!%_fhHT97kQA7Kc?6~(p0yLFuSp^(%*K@;NMrJdCek7ztn4rsadX6Fnobu2yLi7G-B6^qx{7wif@wQQ%q};ZRMw}NZ z0w*m91lUMtkCCwii$b6!bk^3|8i|aJt?foRwG^sfXg3B#qstZ+9qo>9;B=V{O$HH* zMhJ)@`tQPM+gmk+4NXquIaoVL69>xCcf&L@YC2}-=9>w zi22c*METSaA^_MH65lbYnwtoPBow{CRl&FxdU8}spumh)^<11{FRsHzjXOmG{$v_0 zOiz=H4|4r5L~weEB(#T@8X@)D1lQaA{5t?VqWu9jMP(8WJTOKHFBH~wZ6R!dN46LnB z`F;&U)cD{?LJ>k?QXBpQA+VT}mnR716EG~mTras7iuunbs$trcsdfxYo5`>I66!+n z@g}i{A)v;ScLU=uh#!D#O!GwX7i$RRzQ0RuA@X#)clZCJr}&AC9GN&~J^-;KCqR@* zeD&&aijtbz(6sa76doUgLq<)FNRj}doi|`t^!_y@}ph=Bp zMTyIdZ%RCnYG?(7bkh+s9J^y17`AODN(ZJJONI~PgBy4t<$`i1{3V_l)a*BT{Tm8l zbSLf_y3jRW0T9c>91Dubf1OWbsSv2Xd^*vM=np9+Nh6BAkmv)!m%a=$p4f-UyB;91n2J3yc|x zh}_0}NAhd1_b}|ATmNj|<^e6Z<4 zUMhL6{2F za6wFqS?En(kU#gE`yw`qJ7@d;F?yN*T(#q@%cPw-c9&@^^W7;IeDrvXa;$h`R+Jzq zd5?pHjmwgZ2v!|aRPVw4IV+7o7bQZ@T_{4~seSa~2n04L%X~mehg3KNoezTFs2B|v z;70J;4?!+Ls*K!1Dzmo@lVZ;hyT*WQ@+1#4uGS~^yD(sNkP#PL5nW;iDyze~wHz8E411VeyS9~p(gIm1b&Mls9B9k1U11XeL(2BpJ`;>Uw>36; zCDQ8w?`oihOoWuVqJ%(NbJq%xY~s(6fXqIBzCWT4zF9RBH*9T#Wd#Wos*s`V-tuY# zdDG26b?(7wXH3culjJM}8cbL}Gi=z)N(~J^-r7Q- zLYaIJ6}lapH_fJ<`-RITzOwO0Gkb^6InH~i90jaP4Trz9Wh0nR-IBq``EcV)>l3bx zac2>V;5P`SF%k_ZdsQ@MQ%DiMzIQAyX#1GN_ODA8gti9lM7%J=iYf@Z{UQ=5U;`jF z6i#74vl)I#XM%-V_b;!PFd(h%nDWf=lFT+6yP-tjr68*+lX33KJ#{7W&2;$lHo{N! z=NWV57ggQ81kr;3?Zw|Z+1@f0urV{eZY*%!#@O6USdicDhB-laZFoLVS3SRr5_gjz zb}7iqz${_&If5YDxos2vM(y+cF#O+kJNZkP$)>6x{f{h+mumli1#8YP#=4zOYj122 zQ{Nl}vMVO$~2NiUzi)8wGv$IjkiTIcv} zGI(Lg-ebYlrayjRhC29Ik9pAx*GZSy1rAJyl?v`G|L51J#D|man;3nK|NS-Yog?($ zKg!#_zU|o4FC644b_+5>>M)w-zV$0Q#1SD4-x*5B>bO`Tz)6glQ*pY^v?f& zWzm*jPy)V?r1(d*iLed9pJypXs)q;zU0^Nb#or63~fr?2jdM7I)h8KL6PNl~vs8%i58ks~HwEemJ zYcc&(e))2Kr%ot6{oqSRopl}oo|@5$J*8PU+7++w^mWMD&!ARBS)4QQUDkmw8ebPQ zp<5T;_p0}xaTC|yQQKHa?wb0}TYa}f3slx=*91#frV_;ob;BjAIU`MjAm=}ip3j~h z4xj8u=qY1$c6QPDY!!1}(x=Gc*5QM5yCTwi@4hZKk_-wC5R5Ju9%M-}Je=|26rZ@~ z%CCoUp7EcIUMAd*&e*15QR7}>e_mg5B5}poz*KnERxo5o^}O2ykI6l&cPr+kY~^UL zN~T;7>igZl#mn!#Tg8e}m)H$*uawUL_kJ90V=wQ#U3Q@P&&JK+dpjn77bL@oc4d~G z!?TT3XuE=IQg@otrc9&NaK_PF6+4K+p!_GbgKb^ZdB?fyM_pOpQB~v_@_2@2M%oVU zn=&x--%B_ja9E3saR0I5G4S-y5rv^2P6jTFXOF(r*k4?AzJ#inVR>+UWSm0z%U z8-Hp<8!k%~iz|A5{!$Viryb3r8`R4quXAUlb4hMyocZvxFV|GK_{1L@op~&mz*X(3 z`e)CzIxAV(O1LfyOcd;g(Kf0Ta*0}rh;empM zKhozjx5i%@=$H{b8kLc1F6h`i8FasWLDFJ8(8d)@I5jTqYqh}R@YOBE?P@j2cMfJ+ zi&h#B*15|{&w8VC1HXnqMff!BnwvAFJjE+9ht>GB;-qlo>4D5ceuX!7_jaZ7CE3kP zwd-7r{Hm{YN#pYBvB{cW1s3$VFW1Ljj(?pPBCagfOiKn!c~H8BFwO|gmls^^!C*vT z1MB8Ox7+41>wW9Z2anW+Cojf_C?EJsxY~_&c7u4!FdU)H{y-)!=vsAXct&naHi?R`-LwuCze9OlGE?ldoGc>W=?u)P() zlRt1c=RgLV=)>fZ^0*e8*CU%sQ~O-CEX(J^Jju?O$zC$~;x`phCTUKUVA?=SSv&Z3 z!{6bKzxpOgGO{hd%J^9GZwgj&a&|`_n13;^p?;w&%VN3dK+yh$7iXj%zi6i4n9lex zHBtERj*>D_YB6tAaa-HWXNWz*r%p8ax}~U-q3bsRp`7e*jFPl``-BagYW0S^^>tR= z*WNzqY;-&jrP8|+m&==XU}`Zh_K$(p#txPTLaYRvlz6CL#6s!sU-3U_x$izt+GzN3 z^mZzF>Fsf{9TB#=+3hYtVeTppZ3E&SR)$n>$7en?tTCK@Z)KIDV|^?4M0?Q6A{AfB zkdua@j>qi%BgC2h-yc2Jo#jTpWk30p-5g)Xa^v$zl&P@n*-JKE{r1h-JagVr;Bt|y&e>peuH8b;&0Bep40AUxHN+%FH6m29@;VXjr>fB zhuf&r0e82BJHHnO+rCl^hG{Lt%wzeBSbCSAETHY)+1_PEE$IQ{RyDSJ)keB z^l(S?`0vh)t_<-T!o-UYdk3vWzm+xjH7Q->63^bV#>PFCS2QuuSr)~%cPSK~ zgD5RuV2?61KW@`_CGg#=MO@nW1i$bltHBRA)IHQx$Eq6yczTSq z3Z;lRMR7_VOY1rA8iPSA^I!vU*H_bj_Nl&Sdu=3{Z$B~h)oj1h)(!jg!dHufb1I+W zP1X`A)IT6un{mCxAW`ik>)#o~_v}wE?Zs1*p6hIE!@udDUWxM2zR^z2t|4R+%2)RV z6V=31dWM@JwVABFTfFi+qqwXBoB}cygPoduoVpBKADV0;BCpp<`vzMZ@E#poDo>lG z6EV~@{AF#9F0D(a6vm&fsQ{Dh$Xt|V6*woBdL6efOjG@a?T5HY+GN(oUCD?rdb2l10}jaBkj|wLG;bg z?>gNJB~PEvp*4L<{NQ+Hx#w1%RCh|xuqe9sHO9vj<6bAW1P4n=iC;~gAAZzoDpCID zy3w8(iteAk`$HZ-?O1s)a9icdDc4lO3ny?pZ}fecik+|Zf6UGC2=IBhbuGlE#%yh= zKj6e7x673{V{qZl-*=}brDHdF#k@QceRjdl;cwyGP9l%*{p^%`a=egr;mhk3szmw8 zZ8*AF@Zm3KJ9Z5}s7k&wAur*bGa*i=-Daa>d;Lae{Jp~1kCze-D=R1kd}BGrevHp$ z_30mLsja!k+k{wq0{kCL_L@#Qh|aba*EjWNHt}@*xhhYjFqQlNj_IO`?Q&c+NKIne zIN~{R&s zu``J}nehtli{9;)*5Z9F1q>WVmlAXQ40t{(ZRq9Yja-zqykKzlM*F&o&<2roYXjTJsMM^fJX@@H(f z@3Y?7J|M4H*ZfChHlAPTclqFT`zJrwHx|OilScCvF15IvsL+={RGKlm_xZE>^KC&P z5!ALjwm;yV9`SlDtbg_xzCA+LVOr?R(Q-lJ1Ifnhl0$^iCfW<(*oVMSP6+xl~`3 z%{Mwr)Ap@B@9mLOR)VoxdunPIZ@f1in#g^)?($q~F7=0T#@%m4>bGarj0N^Hjm!pK zi{B+%aR?D!g5JQ0o>-f939Y1OWAlNPg0~jqoZ`QvdgvK?>YX$){kPxrUme@ouFtd- zxw6qc_C)?wF2CP1<<~>$Lj>t@ZauZ*u*xxVuNRLdyTTg=e)k)Ga4Wanny%*2s26BM z@#y(!?Mo{5U6e{(f&whPD}tr2HG+o1ksKUc?8ndac;xlqp&0jTAU~txpj}Z{t+vT_ z&}_q>($l8MQd93jVOH{oswoYJt@{ty=5gri9+MP*iu_tlPPu`V4K$OkVKY`&iGx7ma#O!1xcxS{&D zzZC=Ly37)j+S_!T6!pJg_hfxz^kDDX`pVEwb+v@!-7Zq7hosCl%Vxazkr@|%E!PBc zzXZ+e4HFcn3s}8$ehrz9&3{m&a~rzm;mLBlZl%f9M1TD4p2I59Mdsa4LOsfo=?~_< zlHY>W(4*e71x<4H?# zC_ytfq1{-YN`M6A`O0H$aoz`!`h$m~zY{eR4l|~A_g~g}{NDQa_r>IG?IY$AQZj_P zhR!Dew(lc1JMJAh%2Ql=rsYch$L#!TV}4HbW`{PN`&5xR7ts)+UBct?Loukl{4zWWbKeuLa5PEAH$5on5c@zsPP~>k$?~#hTub4?$CH&5_o2EpvCZeL{My zbKKe*dVsHSG}?}Yvc5Y}m1oHP<8(HqB0)3F!#TE;5T-w0bEd-oN2Me7Q*0kafG7H z6~o;2U+SUWJkGI_vx707JI;$l7x+7*k*oGwPyQWediC>r#@vHgDUq)|bc5ISeSJ3C zS6C9JG@gvgK-Lg-u-+D&%*r2W7JVJYqn6}kr~>3{P8QnCxrv|G2xo_X=Xb2TA6y+N87x{j2Y>f zSXJuX1m5bd3);4Gjij0hzM)j1OGa8oWccc@^NLT-G7R;0#`CTZ7~bsfc43$ce?}9Y zVIOJy@tIA(VegEJj@uo(fo%V0AF`KA=%*~LQff>;PrlchNM(KJSeaKeoAgC@Fe`Fc zZ6|R}m;d9ClhC+TVM>)9(YR0aPgUKAXEpE5sXvOm55-gP^EyJn0*}>AmQkHY9=t7k z?=G;lc+ItU?^*WUquS4dChTT+I?MfdyldCo#SO`Aq)o)4w%SR+eB?7Z5v_VYGLfJ1 zD1|LOk##wDJHgUBt*PR+nyttl?H_csyAOt}o0lGm_jA}SbkkB=+U5E*@)|@W zji0zEw3E}gS#2%EoZgbJls!{s3n9+P%RF_bKWvxhv@}n3fgKxaSF(e3o51|nhhpDm z;ygFszyIJ9$BA7I4#QjMy;Y??n8`{>-reFj`n`GEw(SM3-Fk>Oi`w3;4XxrXv7WGW zTTQZirz5A@UsZRKh&v&2RIssdweLVl9L>8^fA1Ta9cm^Yj2<7_RQj3EwaKcF^@zfx zkp%i`|q@6uYNIgg)_L<}zzdMTYHitiZ_C*k-Bky=T3dSX-ZT@Qv6lN&3d z8EN*nD?JMz@)veZ#9yWhokvFS)3dDHar{L5(}KSjKgQV|)~YIJeHUb$y8Q_Ip<`CX z<1f=wPuofiG0<2m(Ldr-s@JiVI;rI<-H<{yjCmeoUZ%&qlj|g2FXo zvXqU!Is5PMuDz*0V_n9JM)DGxl12HQzeL$~4XPPRyRS8@GHacwxYD>Xz1{khoi8_y zdHSZq2Q!_2|88;LAMw(uHZAOlf`I{t3GI}T0}~?kJl5_wuhe9Lh}KshjPnN??|*CR zCLYH|D{!{79w=}QoSE((U0U37dGlJrn`5uD^!_jKG!ST8atoVNh>?bd*li0D;_EN+}HUdYomt|(KU_U(UmW_1=ih>I~H#9efr4Q zui{;K6kogJ)IZ>}&sH4|S9q1*X-R6dUzoWitYN+35_-Rvu$X}G9ox3Al=vTH376+=e%ycX+oWaUH45K35iE)RJv1WG z=EttasKjklIyHE!ElXIkPrtwa>~p}a?ML>RC|npz+PhWz@#CkvY3OblT>0rSopM%+(z|zq-WbeZGEwfTBmqp^B{W^LmbPRd(}*D(1EFN*Ql5gmbdZ z4WH4iT%TOVj=OopGF7`Z_mvsNCc@`A#V^%V9^Sob2aX&%7!k4Noomjx&!y6Sqj0!% zCe~lqQ(@mFV))x+Z$9PP@^r$X<6zv-n-S{znnfraIeWgjdT|rIc3V-<#5&!4^Ts{D zrlWPoyQpu4)ZU2sMs1xfDx@D57vDZ@Cz8l}j&7PqMpfgI+~v1LhxhDRYVRH0Jo;o$ zK|6VAujskWJ~B_+MC^~XBpf`~#PfFj0&xbMT)MmkJHuCe8#hlx-|A;Be5hCX<{6D| zAX7tUDn0Ge?|q}C$IYp3xE^q`{nhS%ZO3@yo>vW##O(XX~CTwDAuX0bQ)@oA@(LrvX|3dUq=q{3Wk;e(YNg=pIEG4`obJGSw> zxt_(RtnkQ&zv$Wh!RznSdo^isiIF9t1Xj8JK4rh}oEs-sXvdfs?Vn%YnlnyXqQGmZ zRPH@wd+pVs*i(%%=@0PxpkvP*XPV!n&9*K%292hxII$FPCnet+{ru-?#rKDIZON{z za|U)F&ZOFZiiJ>}blOX|_ib0!9>Ptvptt0v%Syt?w+q&nKVEr!)80( z9drAxm9g5If4>kc@#Yh6s&KbhNB^m6`0I+t`OWBd^&!{g!GD2gn* z{I>ZeYoCE1;axk7iQ`(k$1${Ml<=1e;NOkFf5wQqc+TN#5C zT>JfVcTh3-8Z$R_cRY)~_apG3d2_PX_BUiiDI`i+g-wuY(%qP-a!$)guot$Yd z7@1C$QX1D1`ZHeU5U0IxbFs|ahaU1%Z3S+w6mOiFoTb%ew3N(`5~%w6J@+$j);dP` zFHM~oAC2JuTy^E&E|sqSZKo4*X(dllE$EPH7R%zJ7RXE-9|@<>j?>s5^dT*9jmEKg zp~+9Q!BM>P#jLykvdb9zN&F0ot#9O&0y4SzwtAtvAsorPF3gx8cgSL)uTSu#gk}S) zWHQC4CW{@G(rXQc%<<=s5ZnSsOg8mdE~Gu%DJLyWzRZ-Qv7d1#S63G|v)s<|EFA}@ z6TavAPoM|W{J{M{kMs_29y zrzNVL7s{>(4~vKqf|2lby#E^14nKid?~})Os#3S|`cjWX+KF^>9Fs8fo}2A!*pT8W z+^7uQHRqt}Dsj?TM?wYlv0mD%hC$9`Uf(p}f?RlKrSTt3y#ST<%X7C1`RImm86|dQeM{3rv7`aCQ7gC&(nYZ z?w1|-Nk)`-T`{!TB{ZySTNYw$cPH+$kehn2Pr}``Vx*cqNz@05nEbB=nm6=jS>$KL zlzms=dLbc%i_(*5Zg$l_{9N4R&Y3Q)F`gXlJ+nyow=j=y2Wz?j5=9IpqjXhYn zgzgOgrBOG#x`2{QsTY0p^$<!C?E27WqCV%oJ&!;UTc*1{SwL+YL^W6 z@KumLfz>6a;Qi&(J--U#jpR?ikWIw~lF>+C-gn#Q#*W<-e$>kw`VNHU_PR*r=$yTaL}G;%=}p2Riou z8uzsJ=9@(c?ljQfl(2RoT<)wd~rSLg_ zMKi|swkg4r+gK!ro%$?pGe&;uz7t;@B*T&JaH_&oSi)9p65rd{~ zy?JgdqSUM+`wIR$3o!ZV*M7b4GP1DA5&*NoqudQ$)ua){J+dd#ps{Rh|>J|5C#M0#1^}$+ZX0) zjqSw7FxHY>ZYLtvr+-e_^T>SDIRx|>-TfKK&C78`?%H~P8PIw`{ru+4s`werUzxYg z8i)LD9uPEP^gX^E1AbdffbNr1Yr%_YTSjaHYDjKVt3p&25TTMCxb* zXI3c0?CrWn`&@b7PaM;?@Vlctf69I_W7388!Qh7(K`X`oY?%umgxqN-6ic+3cWM;) zj`m+k`rf@Ko}Z~O+4ZOIWPJGCeS!GPySdMao=>~zx%@cBjRbC0$)zEv@&I?K(&+fGI?`Z_B5z3oyT(AF->*Uy3LST(Q3R zc`sn>{fiRl))V8NE-!ssRRL=H|PTgA+IQ z!|WQ06f$^k)dRqT5ouUgf%l`JKmyHRrqU?ebbE+1#+0DYgkY`W2}TMrZHnoPCIFqG zeWu*8gGArGLkDsYC{aL%wfjJ?foUv5r|ZlS{~*@sP?yd$k^PYyBp&{U!)-cP+Wc%HK z1n0ph7NjiD6GE3lK%s{rY0R}k<~0)YaO8rg{6AN_$~|vwn8X)?@z@xqT(b<1hSthV zJ_2~ZkrvlWI1)3|~pL3Wd+!`SUWoH|hjTSLQ~O z($mLBN5z5sf=+m2b?KOtlqV3exB_ddOF0i8k_bQ;9%ISMWa23z+!`p*dJPJX&; z{Rn6R%=Upj7{n?CYmpqtKuM~2&*j-S7Y6#Y~tA zi!4x5s!2{Ava>Q;JPyEnK<$nXkI`Ic-Z8ET^O?R`mpQhRGB!^!Zfk5D5)N=dLG!h1uVGq3U|L!oUY(_-amB?RFolv)#7H)V z`rvPk!PMRK4bW}_c7X|DIZh0!b;A7>Uxt}YNV2ffqr_`rS_N;?*I*Wt^ogG<;A;Vw^Cp1I%YUTao|JflhI9-anoQ+6S;QQP?pC zLE^te!V^H(E$Xt(B(^)@;ifizK$7Vw6N`&k>M_I*pwThLonK?<$*>tou*)cO&0t6s zg27~u8Vn7eau?em_e(bGrisPaC7>uz926iHCt!pd-+=*dOm1h}v>8N!w1D@@6~5CqCNI{^Y*!=!f6g%YDC{_ z>yAq<^BDuN82=5GOGpPI4?~3{zL{_&Mz{g`z*uj^SKxjidWT{aY67g(6QT*Q0h5)+ z1B91>0f`-ztlCMsIK9Pu930r3_O`dM9JhQ5sTNiz#G_ENKf&;^rY0^h?rR4>Nwo@T zI_xbmRZT|;qQZTk$*rMCiMXj!V3!qgSEK-e#Jkw!**e~iTxFUrf*v-2D7< zIoO8M+bPD!v0wW;oklq)R)C*BXeH_@GN8Rs9KoLyKm=F=a3nP(`Yne_)BWRoiJj*h z3_XL~ot^#Dqm&K`2pEB@$G~vWzyMA$LRhiMe<9G{v*TFi6CJBgKoIhpvwh%D%NK8!?2WWI@We#8eY2L@$1NaP=&uxm`S!^7LL1Hxbn5)Dv|;QWEnU6SM(x6@;78B>6eUttYC zk>|vNLOjE$GzMdFjbcu_+yYMlnvWcxP36n9RHj!kHN2ORaT|d*oW?g!KvqywQL$ND z4`=7007=LdFcuFZ)%({l-3u?%lrlgp9_oF?DGQSbD+>$a3=Cz6xO?5u%Hx5VTe9An z3MLieJ4_ARFU#EFXO903WePd$KL=(X%o=!F`(y4FI}kpOCzLPHCxUtfh$y7RVY%bk zFp!8=#cpq&eqIZF76T@r6yahI@F2+fxMUE&S5;Kp9@Tb8l;SaAUNy6wlmwnOEF?q& zrb%1~q+Y+qqB(dF^7WUssrL5vq444WD+!BU!~N7I2%e!pS5{Hc7-ieDClneSfC6p< z8&hA&1HnCZVyN1nc7(77L=A}l(p(scleY$IAaRsFcMiknc>IB|Y*Z4Jlq`l)QCz$L zCz+J<6s`n6JNru<&}d=-47xuEEEs&Dk>6gi*~xY&z?M??L6#VR%$zuCFx7v z!3bmt2s;qB!UidrQ3%!x_jD`k>v27$MADO!{i8aHaQC79#zK)ju8EI&{7R`8Ci}4w z<&3*v=sCIe;Ihd%f%~|-usiQLz|ejSkqX!y`btWvK9h}7%v8I59lSuao+*(u1t1bv z8g_EfSA9Eq=+3nAl@o0;4Vf9UG>e(w51SxJAP_C+5hHL zM3LbNlze^IB#1bO8?&>Y)Kt+iFqq>kGc^Tsc(=Rf?%~^aK(7Z{7pM<>U_34QBp5VP zpxjG!f{laYQ*$%Ih9|n9cc{)%5TudutehO_2V{Mia)v$v`b)$?GD>&@=cJ{IfF2w0D#u!WLxD>aMq zZCa?NrB@FMrrGwLIq@5+Bs?mH?{7pyz#R~vSoZ+i5ttTO^q>wk(PHu%CwNuwZAJpI zA*5fLaAEK2dcGJ?q1#VmtebR(FIa&SGV*V= zfdv2r$oH`Val*E4DzF{y+C8u+;JSa|6x<*Xq9V}3Ljat<9fS;cJn^V?baX&!j@^(n zDDHX#_SN~f|3LW#_|P6^X2dWoOiU>W3FT4Oa4ul`N^WNkQv`ShFIf`N50mr9VZADX znevgLq4TpWTL~;=j66RF7A+-wD}nEe-5B%#c#gng+=I(~?ATQaW&wdoKtGu%jK60Y zTbxSKstSMo;e)Qcd~!NjWmb<@>KtcueRK0)ghMzr0N#*O0$de_GRzDNL)gBptxv-R zhC|4^?0cS#KEN0+Uc3kmZNcFKEciN%#3rQ1V+7!l`sx05Xg%^h*2JuiTRrlUzHfX0 zNY4apTaf3)bpQ-|`Em~q)3ESx+OSC|VWHKuYwxip1Ek@7n+W#O-U259cmjc*^-3Z1 z{{8zn5TJ?9UyjdjWu+Gi+Q@!?GZuFqE8(WSeHYF)5{xH49)AVE9*pmxK3p2_5(NXG zeHPmzhQe2&9EENc(41_T3;~aVI4|1bEjfX06+4u)#92-5r?8~mycdeMiUt)#7m(+I z3i+ws^|_zldE81coB-%+qSX>kc=M*C#M2YP2@@B4+!5T~DXcek$cy(0n?h+=F$*G` zdK9*hn8rtxol{L+UTQ$5T7~oidIl;YE5;UpU z7B5cMDkN`W@)PGbv{u!D`@hLD+`DZU*O`GR8bV{h6<$b&yzZyTO*wqu-)s5Yutv9? z&`p26mbU3P85!WH=oP!UV1Z-X0{4j|Zs7_&1;sEhN(lQQSAlvC+S`xQd3;IRsi|3y zThfi3umd{+PbOk>VG$AV`$n31Kkc^43_sW|?a`tC{cxaM3&1q*-XSA{ViGS{%VBll zH!&w{^kifzU@rm{5p*WcHs-YEfnGt#5D^iPGckxQ5}3k@CpfigYHN>wn@kK3*Ku|} z*=g5P=mHrVytUFhOFT=8iX@^`)zl(jKh)mNCB~7^@&~w_XfcNr#3VQrAt`}mzhgNU zobAr{wy^;3;IxD0tFEr@U-1rfg4eHH@p=u3hPnwnI-pJFQll-ubC1gHuzj2e7f=95 zQ%Gy{u-av~O+XD}W_BoAHEGpPh69Sgmle?CVQ0ZJ8Ut&cXw?#Eut)$EV8LI$><90= zbNVR|1^U;Iz+@hr1ssmkJn_`vbSdHlfIRKNmQmdjMr_DyR30Ad@PvRKiKOn*)C7G+ z+K-BiB&`+@$jr|Ei!}vZ(1Vy`fO|n>({$VZ`eOj+I!l3|$2P#PTur5eh*YV?Fj8C_gFZ+M3r_UWhz>VdJ$^n91?64%~ z2Vr5LTyga8#=Sx0yL&g%XfXCc)Wx28p8g?0BP6E8HWk{-{+QG5^EzucaEAA}^B z|J6Srd=zGmohPm3-yBubM)P@-Gf*RP@NrZvO@mx&yDLx*uFSg`7zB8DOeA6<0s=Sy z;zue*!7Hc(SextX=y2iON6rOmKFkT*wPiX;xFdD;{cm~r`M;Kxokg`ecLYv)7FkT~ z-IgZ?@aVz@5oeN>@Eyi>>Dztckrmb{=jratSYEgBqo<<-LF?TiGYDD#1<>dV@XG^} zhK(S!C>xR8rc$s2JZH4Jl994R^wH!}{-0vWzv;x}l%zPEr}tT%Hzi6<(KE|N+M&St z1VEdS=}2v8p0GL}$S|RJ61tL>kpbrti(B;GWpH=GKh)IHvi{}*C;GR!t7Ta%iR8Vt z-7$gv&auA?rxJWTcj)87@i52hV4K-lom6C3(V5!ee{(hBz^K8Z{oR}AhRm;etUUd% zuBBYBsmEHGci>u|sJ6{rqd)(7!=&oTz92PH`+^||^*+NS^2)=^!*9|MIpamX-(%_T zmR-eN!mZw}6!R!O`5J$pgeDHh`p?!Tu%ICSEST}f10=!}=unHhi<-#NitE?9x`Vzf zmfG0lu(5k=#4)z(+g+iX!Fh!I0+BfhV%3>zWnuag&mUGL?E@`CLzsTzA#mpkg_ih| zC>)~6ykJa_#m@=X>yM&bp&wDKLAVAQspC@RKmCs?4oS%#;J?njBrS*oVoz<-@7_HN z@n{r_kVypudiW`oQGlbZ;E1V6gP0Ua!axEfXrfM=a1cQx{sFs0s1+2Q2rHRN7O=L< zeRn+!4BSHU0me2I{|oku5P{j;y8RVl5e|{f1h{5)c%yuL>3AAI-P}})23A%CIG#u$5zInvpZ(eZXBoaj$BFag zcT}GVzWlhuJn-~CWZ!ElG>nWEH*S2*9|WKmP&AYi2rtt1;I`NZ&$;7eIFJ!teEUR? z&E>5FLy&Q_KY7P9$f=1^(1^%LK^eGto4gP?_}#w`7BDQEaELGw;7^FbpQP$}j{ALJ zPfh|7gp@gl|7l1FNE&CQM`*G8b$t(36bSpj)um&tb(~3RDduJDmI=^)!-)fK8Nkm5 zwG1^&uSK%wqbP>U{h$Mnv7fIm*n8=Exg+=kb`Mf0_4exdfnCp)V52lJHuj~VVG@>% zmX?&n&aKiHFD@Vq#3|oxuVFYs{peY2Y%drbxQZJ6Rvhx+<=mWo)NE`8W`SXl!6a77TSrsVhGnG@@87 zUn?uakV9?_hyu)lP?4-WxJZTxyc+(0VS>&^4ph<&E zse9=X@L;GRdbbRC)!ea=NG|pJ6O(_r`i^y}Q0#=bFxhBez zcM=5(MnyPyu@F$D!pyVQ^cIR*2!tRzE{h7h1ShbNtL&}q?Kn#a6<%&`BwvVk0Qrmi zv>9X^;=`?90rBxau~R)rhd~1Xv&fARTJrHlBQ=As0%|BgjN#q`$nf#zfE)zpAX(rv zB0*PUB%Xgi0oD#I7}5nP0ZUf`(G6VwCLa;d-llnUn9qjKnHl#gpz{b)N7ObriR9|6ymGRp30RYws8YgC)%& zRPWl=tL1uc(z3Fq(1}Ugj&elPeRL6!o+v9nLWmBa!@ixq0Pn%dqr;JeDo0+E!}qG? z57JGGeBhPZ)Ad1T;iOdnMoYp2E^U=nRfw))fs?=~J$wtN%f-u=Gg49lI;&81pFkDV z+BNUpJL`-h#Zb6e!w3Woi-yX|MEJipG)N%<%=@v;>I@#UvGH;2n7R)i5U}S0T0W;u z*EkT=De~PE?aOcBt$|yJ#fi8Ngm~2aN^br7jAIB$d{miX?~(EP^))lIEhIB_6!UFL zM0SoEkVd$E|L(~#55~L37W(1CB32Mnl5zS>3WzP&ukV8g6W->(c{;9=6uM!kOIvr} z#Ao|YNszd6^)6*D>5!+RYaPlFO2b|WE8$1`+j7y=BUSDjTkBLGO;!7HgK7ZOCn%<< z=)mK{;GIPXYS2LCJ-9eYLei3^Yi>XJo%`QqBj2i zvi8Mgdk(-7X=rHh;ItWBufj=0>MG_BBKZb}FPZ<6iVARSyYy5=X0GI3Dcgh zaR6}(S~$QbAj${h4Bt-V*fFaYBurr>Fy|?+Nqz-m9mnD|kH-(b%+Fs&Sc8oNTNtW@ zNN+`$Y*0N!iRE89@1?gUmAKgZW2M320bS@OLNT~!;Y~T3UBxv*5j`ImQam8o5)mdj zySnDgxx$SO3B)cECm;QkFd&h%wcTfjcUwiFGnps%X{scIgx!K&iQZSeqrV3S!JmR( zuL?&93qXzlrI^O!jU$pUzj_rhvG-muZ9~%UQsy_78Lt$F`*PBs3(1j2PAgVP}ul z$~-mXOnCd&2tv71yG;J68l|PB+b197yjA<}EP&-ED?U1lYpX&} ztJ>ScEsV#8hd-e1^KZKb97eR^7MGVvG@rj_w-coJOi&N2pGydhjm>=Zsv>{0L0u7p`1VC7{sbI?jpJVrJ3zU3LtZEug<@<#DkXFsOi=qqOPjC2Iz@Q6mm=)9!MKJ zR_1pRs25?Axs)nf4@Y~PmmrEF>_c?}$w6}A&&iSvRNn0Hx_$dcw%Nm|D7`ah&J09d zC#G;`y}XF_4z8=s!eY@ALqp%dx<@GuM>dM_aeL3=BmtTt7j@y!-@pxrv3;igdsQ7B zM=TKTtI}ua$2w?2D7+B-1^D{|vrO$!=WDq_?uB)Qel(&Sv~19r!hNaJ)BAvKG*0`U zQcq%HP~1`0dUTYV8*gj4^w3pZ3Ola-pg008aYfgU$1{UdU* zjreRjEl4-9&BJW@Dgp{XV30QgMhL{C`yZF&hV$0=U|6*%Sz6bjs*fM6R5*87otsXp zDFVJmC&v*LwFcXvUWGJ)3{K~FPzsPyx=pfN_SzVU#Rh&(Q*#f2%IVtbDz-I$)Bja0 zCs6J~a826ZzCIUK1Lqp$0&W%9I-t4hQ1!T~+l}lDc4BPcXgFwGdlDSn0ONL?kRXSg zb=^vU=$@~~0y|EtEj012Zyi4ZWQxKx+O7!fQFeTgorXJ#7NHB;XcnLdi}LWmfaNc) zAX=%2pv<}zkPQsv+n3V1;1NbRiiIVwukVV&5*oq<@RT6pDENq}g@p!eUnL$A#OBSL zf51H#&mxfpQ`GhYJlxzg`!r@*_Lb*Tn6nHZR0jD9j|$k1740;!>DLYuV?9Ot!`MJ7 z*WjiTq0$<-O!XG!dbB4H#<9YkLv+c4mUNfCBV7Y;1?MUP6f&aiZ}bTpSZbryu=P&H zGLjzL<4dC(gcoqLm>HSd!- zb|VL~Ff$7a4YkL^+s^ecZR<`(ufHeIbw*45r8+kVN@r5h6m0T7uDF!|M+h7e#FRU% zx=#}b&lus}f{GQkqtfbXblj8hL? zmpchUHC&r7X=~FXFGakFipSfx(>OQ5AxEc%WcY;W1tlG2E}wIeLRaOwu5Kgn!vKf| z;_(s^dDMZ4KHN_!+-LMit*`4a=-r#06fOp^;+QR6gsqcj-iEs zw6PseECKydBiou|bL%nd&QT8N6G%LG5R`N8 z!m`txH?$sAMI~GOxGRE096B}FoVAr1XlU5-H(RJ;i*a*XMcd6k;*h(pi^~!|ESiSj zeJLstxiZd+!<~VHm$v})c(i!e7N@V0pp@S-;ivXY%wYt91qMgZAV&3azo-l@n0noH z^oH$8{-B~yD&-bB-;Mc( zHUzHE_{4;2>t+;A!BIr2m#ikJgYOF35{>}8NJS~&e%+R`@nM>HBw!AJ$RsyJ><%-! zt&*r%Ae2WO4-gRSKpMgWQPV=5hQN7JXj)5)5+)jLpfqhN1q>do6GWRxi!}@k+yF#F z6BN1Ec1p@TAxS*vB=79;O=W<*YAZFhwxZdY0u#}J8$r15- zmiFAa3|!uS3b&(YO0YZHZ1jxH*!c^NIZe&Xpq_z+g#GX?YAy)2P)y$pj&=#^K0Lg< zNRWU?3K~9D4#Ooxe?@OC`FCZbUW{iresTu1rutY?3D*(8TouQ`&WEdacf*pMW5oTb zHj)l~awjzV<4dj($r%}3ceu^=3rrx}12>42=i!Bq3JB_r8yT3NLS>wR;TxI~gqLa( zyooUv;A3G@q4z1_)hocsroS0^zI2lZRt!zzM%{42?$_rqber2_wj(q{_K2!HT0($1 zA!bqDncvKbBm@?&9HHpG0Uh`g+faho{p9s73^XMvN1B+KAx@~y#{ddDs-uq{nHru% zn+7!zd~{k_UF6bf(khtJ`qtKlVkRzC!aYeDT&MIGoMK{84s040bW7-yQd0*b`!p;d znYAMUwMI#9xES4GlF1tOPk4f1LJYNYRQ2(KH3>RqNC3}_RbY1p9J@B;A?!9fI^8jK z#&Nvk=~S=7tMGP5Wt9DZT;D`a4pP+tcot#O%uOAuA1!}o@ZgcGh$x34Ou}23Ui&#Y z*-%&aP>f$$LE#85?+z*|*u+^5B*a-}qHHnwBh*&);^vfKRGa=UF{kZT1xW2}I3ueJ zZz23Z3zv2-n&iAdLvuz%PEA#nG-QHVjYeyD;e>|nv3!pE#ed`orUDP)R7X6E*a;0t zY?QDRt*=MF;4hZSQ~fjQ)zzrdtfC}`-hys*0942bH!(7kyW_)eJXRtR4%>I_a)`un81^#3i2f7)Fxm^OMlZt;G(guGzn zmxamRJ>7vhZ$RybKb|34=RsmdH_n27hSOVYoDS2||H7t>Pd4`dMai?tE}T%mc#%|> zLlHGTN0vZxO2TRr9|{W4plw0xs5M!Gn8HznZP0CfHImWIP)6p}&Gx`rQy7ISqgjLS zwfm+7KEpr190aJIR+0Qxe*AEQlL9s>oQ@b=`FG8eV2wzH(3O4=)Btw|v|BOALc*+3 zQZh3$R&-1-BdQ zPq^Y}6cJZYqQ|6{o?d>fwEx40d$ve=ZsQ3P!(~N)g6$I%5~vhXQ22rGZns=`hX!SU zEL1!M84=PTRl|q?8b4^ky^wqpv&C;)=idAOzp5Tnk>TI@c^IkL+*&M@BtMUPnKmQz z{M+A7s?_9UQlbtRDSBU+18I5(^TvByb~K6v$^pBN(gX5d{3JkR+1UCvzKc(O;0{^{ zrnX~dK5&1B${BXH0N=ekP6W{H*k(erTekAvZuN=)$~<+gM(*(Mg5RxPF~UV6fb&Ad zIq`~t&1X9gu&sTb3|=xbT9N3Z+E%?ga=}PEr(r^J=5ANFx%ux%^dK>?xVktH3_>H) zl4F8`sQQlop+!>@uX}dI`kOhmV&&D;4%2Ky!#9hOl@-p^mDh57M(MXc@fVOj%fS;y zNyMphXF0>02(85a{QDFN70=JMB#Cm&nriCmCc`wT->&c0eS~dTPB`iDvzVBNrr9c& zKdUe9;-K-j4f}t1dlPUh_qOf(Bym+lnuszaO%x?5iDaoH%~2^+GesqY%;QSKT1|=u zwVEeQNM%SgOCwT-1}T&#Nrv}#*1FgCO!vFJ->`kQcYB}bS!q2hNSQy%%nVf}m@k2ZLiQ8T2Lc}bIp<^U zE@JZ$3jjgfkom1VnX9I*&Mts*<57#3FW1*wwsa}NCr_`rBZ^Q$VX5z$OYcP(+&V-} zk?(=_frHIwOJ1^Q5o8o{t}!~wk<~>7QWIqS`&v#GZMiYv1hfGFTQFp{o!xuv%egVM zUR^9F%69lm1^;A;v{r;6{&ekPN&1v#cxqjax(cE`!=v<3IG(B?lWgl z3Vf!62ySiuMtEaS1YX2Hu4@E4URd^+qroXj0yAmiGV%bW1iqah#H$dy**MaYpy*bI zNn}KHGz(%nl>Cv@;m;#;DbVVi{QwaCisE+`8DhfZt1VBz5mpyJuE?Z@#4W_+v(G{ z++2VqDchuo&Eigv(kfm$D{uJh;)+C#pa!WP?De}Ew>a6iw6L%{eqCF)B7R*`t2~m| zk0y=!fx=liW$@T8I#VZmrO)kTIb+6+rNz-*#%mXtcJeC%dg3R$hsYEKw~`~+yu~9N zvAXhFUY-rtJH>#Nm(R zGR0*RqNGvYx3xE};dghN(kcws)s>w%aYI(P&Wq5qXNT;zyZ$@z!PZt@_pyb=W~+U^ z+F$abER$F}ONT^tNauL%`gK+;T)%eB`R0I3)y=N>O>0Ra>U$hMaA3>Mokx!xk&OET zvH;9@<+|Nr9cHr<*ul|J^wj5Z?2TWDwi{|7y!M;Yq05)qMEnG$skXNCr0-STbUJzR zzEQp%opFrsEolByt&rQU*1Jo7zQUy8#-b1fYsx>yvk(5vg$tC17m||^D)zd(UB26R zL+rGbWGs7ixc~I&9I`%|7NmY_K7bB#cF@zwtfz-Q=T%p04X6iF*2vA6pz|Q>(rCH~ z6+RDTD_PxYaMklLofqqQW4m{=6RnzH54-^7m%=_G7t>+qEtEq`W3vib=@@Q(fJ-P5 zoSmIF@7neB(IejY3TI~nKYdlbUk^x0*7)OWPvQi%o_fc=Xu-Q)Cq|P;1OdIMdPkn# zSbAH)`?`Kef{|G5&P_UUq~YD;fi>q*2oe>&)N~#BxEFxZu3TBi4o}SY85PyOWOu6+ktzGp;l7=yHBou4EwP|4 zf(&e*id>d|hLDUhue>?f%i{O1+q6EZS!pVj=`^S1#CWAA%#vWWdm*)q^Ngra)cqZ2 zzsw6dUv@0eU|=w-`PY#n+gyV1EC&!v8C z73V%&%M73FdB-_DOmuSpX{#R9x6L!P@bpaqZQd<@(}74gUOPiG)-U|a+kxZHWc<8E zVFxsx_qDW3yR+yVTj`v`&dyh+zz(>mlJ@jYrjNo;2ls12)}nK5{afmP{sgJ>#N&7G zzMCV;sT<;~xY*!8)z>3`Mi9$GLq_2=O1XiA5&LPi!c$Ziyiu22S`Z}EVkt-C#BuCx z9ar@>kv~q%qCY2UcHdgo+M&@R_rHDV$W&Jj3bH8C=6c&Uwm_dca%A5$v9;41FyO(@ zg=C@bX|w0dVTDZA*dTU+QTcs%dZ9ybFWPmWO_$%6FRumQIkm&hK&7aja7?}G^ZHg- zA}|&DNry9Gw;NCfJmZa?!BI?;tLT+Z8E9Bo>dc z@aLi(3zxopzGvP>5ScK5jXkH@;zLXzdbvE@B5+Gn_d^YBK*Jz@qPmiE*t{0ex>0-3 zAZ%i1YyYvt!$aPk3Koaevykn`FYwFet2zV&ZxQqmRBD*|$OpFr1fo;Hl>Nm(s214W zwvUb^36YjKvXY_MfWa=)B$XNW_jMbHsoJ(g22<-wlY!4Ant=1b|9ot!l0MyIo14_+DF19cv|FSDH; z$&36GFHgS2k|q5{$FVDKyshn{hYxcI2g?u`gk<`&9|wN#+_}~0h>+<+{oZ)J2T_&h z9HcyBG?jGi5+&=6deo9RFPq1r_GG`y^}M_wvgq_fw)Ail7cLaHF`<8r-?Bv<3ZW)# zY6?8DhA>7v9Ay{dsv@)hn?x&)oiv}ILO5A2E1|^USc*zPg87@-98Nd!1Th3GF57zf z)ck4cAh<~O#(H>q4j(oQ4cM~DV=($xUZ2||E>B*S{Qc%`0%ULil^zElQQwb-2EO&o zq96sW%~n@lam-mE1uS&cXF=5vk3JaPBlm%DZJz-%w*KxS-sO~|GpO`=<+Qb{dKR6$ zOBVo02~1~Jo+8Yg#L>5t2Upi&X4{5ceb3DTxUf&Z|T~K?pwnlvDWzbTwUJK z>k}MAxAlE=bw!vG7=ZMu7k6>p4`aTvnZJ?V=)i_#cM}M@SJl-psl@8HwYBR2PT+*W zExE1?;@sOcY@oS$E0;3<3S}>E)qj;@sKu9d)Jzm#UP&)jd|PFrUUcPlg%?cdEd0|s zxU3qWr58ft;~fA7DEQFN(Sh^31OdG}MOed@tkPbmZh0nfhmmetqXdpc4xC$F?#${; z7LGi)>%v{gp~>XAp_y2_sk=tL{Nh-;eHTT6oqV&wJg|zUv>CFN0Ra)a_V54U=Ar%j z!>qJf!pc$r&N;{rnYCB17UQQBG9V>rjl$m@(s7vddV?QeofOv#U5uLI_zA)mkS>1j`2~0ej4{ z6kBP&J~E3{CW#Za=w?f3f+ zJTyL;>wfqEEhjrnpUxiS&<(Xo(~j14*b)?Sq_~`0%Qc*vT0 z^LhpyaR=buU>#n_b`j0&~G&)_sdR6+zRT<&Pi4$n!EeBWmagxWdVjVdh zB{``6)%t}oLlXPkg5>rxfgHBgeOO#9dS;uN&K)yGO0CZAKa|#I4)~u1d4oa+%H)9d z*>V$nU#_D%dvLX$*taT#bg7PIMS8Cw#nB@wmb1NwM1ou#f(~#2=7%#ccVTAOf`)!i3JS6w zcWo1_>A1xLhCKP`N%)hYhK8YTH=!MpHy?lktNz|ye~u1PlCBqJHy}d*bu=+C$@+et zHkA%p9d^UMQW!-dpE2Mu>l&$XZ{2#wMWcjlV4Rr^&u56PRFefu&OdrI10`5PF$)2P8-AQifttUl!+M(yVH-at|eSgP{LM5j+a*y868YYB=e5aUQ59 zBic~;vbk=bKH2wEb0S!1iF|;adcAz>Tsr7udf%r#02<+qAO zA;5BaRNz zd6ZMG0m$`e?asI^Sn!HH^GSw+rjgMjkOO8bk@6>VulZJe%+2?X*Wuv9Cj%u2rh)L> zgk|U{MpD?;wPE8%_Bi4tFSeO96ukSnBpY^!K6x^0=FG2bdT^T{%|T#~#P=hy7MlJW zyspM0*1}a@W<~1x^X$8j3~c=Vo$cNl=RDlq!S(q&N)V|)iKxiuQQVgg>aoFxY9ml3 zoL#s~0Z_)TptbS|w=N%}tfkaOI`NyHwzlQrhi7b%_3G;84O2jfvh%b;q~!$GSQGl& zwd2~cme1G6XJc$EQM8knsq7|C2SYAoQL)xs1wbHIM-ewc|LHJOX zsVFZmBNz=IP7>iu^e{~pcVY;cb7(#{GIk>_v344`NC!133R#aHozKYFlX@3m`&&)%SRG|_tb|_fnZBML5*4|V zYr=&7Pdf8=KpPDjJQ!(3zo1*%;`%(55^!>GdK!wF;|oy&XJ(o&l5Lq?-^le91nJPM zVFfFw^@|=I;1idnzjRAxW+pSr|E24dEvu*_;nt-foZWYS39ys2prWDz zMQuE67)miU6&3mUpJjw;C;GCAn2|rIrxVAImu%Sp;RKs@?%dFAHU}TRMSK>Ks}bBJ z5+mS>$r8C^^D+Ww&!3-hI8ln!kgOPy>x#IB5n9jUvyr#0Q3!y>(^k;sXFX^O^a8@G z(xV6ROL4g=z|rtO#=la&$k!zJ(QKNtnsB!rHNM!~)1cX(oD;d+?e zX{|4!;-}-@FIU9jyAw6&xk#MkP`WcO!=uP#_69XBg%csm3L$81UUtV5Z9ISZb=?lq z0_bI0<1$bXwnDKiBx-EsYie31RS@jBu8)xtD3_eW#>-f6%Ue74?|+mGAktMVQnS+5 zcgkqm;S_`tFWq}7v*U15P+<@?IYSnUi@?W>soCK*c$W!KAzg(^ydQLZ5-lRm3?o5zG$o8Tq*OGiFp(R|Aegi2;Ml z3k6*E9zD`2fmUQr=6>E^ViZ3%F4uL!#EG<&y%ORgK6L0YY}pJ%n_NQ~(+sh;MF+(8yb^*# zL;XEx11eAoWK5Vi6;kH3UZ@{qbBry-fPxS zU87uLbnE3D+o){ks<&@9sE-gECGfnfr@Q7XI_I)^D0>=v_S{YNc>uJNN#qF6{xsXPx@_BIH)F1x6HKh&Z-(ELcTacrYq*&Q0YitLz4&Onb zexVknn(G?dPdjn?%aQnky)|XMs?0kZHdTrLx!krSC*7aR>&ld?Zn7~vLTYbme6}}P z;cpZ~ezI)Z@I?h9pM7|KX}HT(8Rb}t=D#TUJnbH{T6gQ#^T>%qKW!MiWP$YGh)mlF z*VO)+>@)@#sC3}=goKHjN>upw3Wp3HJefjc(6O8Z-Zpgu`L&lZk878KOW3hv%RCcn zI=5-q{$OI2cO#0%fL$IS00CbP{IHTtZ@RRQ@gA>PW#Ipm#m+qTg~)23wNylF>6`2Vc?R2bDMwRHVr%ug$IXE1D&_`%#F8Q6cAwQc=*Bf z>*#D{?LH#;JaOz;*zIKRh1C9BcUbI-fUodkQ;t3YTKKwPih~2#ZUY1Hr!LI4-l$$Y z%zjF$M@dTUo4vt#eaGZB4EO9$Nrq%;-q{5cJOi_eF8O-W12YGZ8gOwC1KSMouDhH~ z{Hmy_i90=F?WeyuSfUwpIq)j^gD~P3&Ytp9YX+xDB$9HQUC|cunyrx+4F!%JLdcaf zsV`6>g7|QE*c$r2=nUoVf&U37=z4qmTu_7_J^VRE`~lkdihGBS9ZPq+-jP%th%oWA zW=4U0&wgEOkV*Obr_&cQ`-esvk|3h?QGxV?M-x@#qgYofN}r+6Krg5F`m?~-;wH2vtq}~ek*CtP*ZS&qx$<6d!!sa`W6^< zLtLEf;i=LK9r`o7a2A|4-k`@lG#!8x4YUM$cRz+;dqB=lZpx(zDlD|;Ezec$EYxwO zxJiL6O{%B&BAh(NjUD?EEZ*$953U+ilBF%Z zmBQncuCfzp7roCq3blq?05&jSl%v_&DUKf@DhP&PX^DIGfIBP4BCYW1zRd>Cp|)Nb zd_}L@#3>3Ye?pxghr0LVNj((|jXC84v-TGeP$W0^u%ykt$-{!>fIN?^y-~2R$Y$%7 zEiWr7RsypH9z@xZa2FbyW)uK~N}t62YGm@<1m@bPC2300k|McAt05&ol+d(9wpfpz zB0n%UWqFA)d@t?QkMG}Iwo$XusUv&La*a<e*MF`~h0{P{{-3MWXilni&u+ zbOrPpBKZWCmVfWw;Gsi1|9A*7z-~qFD@iqUt0I z^7?lK?Z6Kd4XpNF!T{msgarQOd?Z{Qqo>om4j#N|_ZyxHO~&*2+6Lm!6s3IM^&t`O zIwP-?kxsgDrDr#qO}dXFj})&fS1pu3F6=k{T7?&+?CV#raQbK?AU{5s{QSGdW~ zFkSh=s@wVtYzA!TQvdZUlXyC%QQuy56NO=e&co(aQuTtju}Tcn7CZ!kge=|wDYg&q ztV~t&7x_t6p~~K|Z5un|Fy%1XX-h~Ox<2>aq=)p$8Lce=Y5Fm#Tj6YIY)k#17=f<_ zf>1HCQ6J0$&hkhbWaj(ckpNv7JZ0Ln#+RGS4PMey01a{M%1=KiDA;%ER0i6s6NeB2 zJNh>K__5lAY2?!k8qGJBq6utH>)Rn|xa^fD&-8@pW>PW9arJ)!O=Q#pLdsoDCT>kg0P;c$ zg_$>qCnN;JB}icEW1rr+qo=944^i!S9oKPR7l;GCPoM5$cj(-?6Lq)n_ByJYB*Wn~ zJZ~;>Zs@n2*vEuB<4k-7dPc@Um1DPV-=4DMzP7-I${w*+VN&ub`DP1%-+*(CdYr8O z0?yGT4RF?F!2&*sssEQM`WmWCid_vrxTL7h&3HP;l#k&~Nve@w;@#x4$Tyv)vO zwY{>cMX6n=U;t29`<9Xa>dhN!uFkR7h z%Q@t9pn5xPD^aPD1QX^EoIU znSTNkY-xC@c=ucExJa)e^xrni2K*t2f?-4N0eS%9ev&RIFl?ZCpoItrFP+}@PB;l=th)bb_YL?J$vRO2n{MErlc)uS~af` zKvhh4Ur}?!V{!nhGK+qMk@wnpIuH7~UyPjkqLE;)|*;1XK5GF8az)FK0zgY`EqT)xWS$2?qG*%>{bN z3}pdR85z$$e(cySApGcik_fL(mMYU{&P3>SchR|?>gq&$ddPL}pN-(+$7_dIf6i$Q zn4pTgIx6r9j;si|?SjXk+OO58BC?F@EJNJ2TX45L3P2jBIl1NL0JJW)KM$dAC zuX*<_okE;FinLh{7nj`MPdj<&;6W*Igbj}M`J+b>Jzbrh1-VHdEgT)yt6jSm%(Yp( zxbJqAeRFkmbbwkYF?pejJv;(mTx-`<3Mu1p$02oxc;JS6&c}EJc`wa0%^+$*IiZ2w zvPrM03<3C@byLL&O(F;_*RP&;@{xlFBY$(PJ76GfxIpzrP4txrn}bZy_?~1cYbZkt zsj02VH^+^WJHbX*0|q!4Axllwa2(zmK&Y9_AxB`ztWsXE``Rye#RRp=e+|yb!Vm)OjQphx; z$AoUShq{!B&!0OZGHv(opJ57`-q8|Em}=}X@ON>0e&9;qe?XnQ(M5qdltN5b_3e9@ z^Ra(vH8KTD%@zfe3$zFb*HAHlUGwliefu^XgST_%sP^Z9ZUPL@w53({X(J8?`jwDr z3zis}bbpqWrHLcM(WCv%%${duIoIv#D?}x@Qu`9Pa6#$6JyDnpU-o1y1C@x|Y53cB zR&OKFxf;7aIRT^6txK1z9^KZzuBgz`*S~_N)v4()z}T|1!muG4Gq|t`?LRlb&o7N; zml+$>1`X!63C0Q&$KDAybjx#IH#*F3;@g@U9_oRNjL}Y$HF=ZPtrP8MUb^yy(+d2~ zZ5qAenaK(6JW?g*KAd;9!`FgD3HanNb!zsSIof~p`>Y6djja007u8TD={5-saf9`` zt+&;s89zrQ(W02y+H#3azm}F)83)B0&>VR)HevbZ-(}9Yq0)rQXf~%nXtUR=`0?Xm zte9Pq6LFgoJ%#c(H8py1XZ0|pW2e0n=4Bi`I-w}2*&I=UeA`%qa-~SEZIj~B(p=Z9 zLi)AD(^E8F)ZKz+8`03s3NOT-Ly-I_#{!#m>(S$P)smv3wDk0=wR=1?c}yIY$P&5= z4m1riSOe!%dU;3M{<9J|lEpz4-Zm9KWD^NMgk{@zj9$%2r?COXW}Eek zd&syd-oGEzr_TjKALj%00stimTTed-hMB$9i=5`nS+;0VJ=41<(ioYTJ-axwrLjZs z91&?;R=Ec`9L3uTclXYO8hl?inYY|1RJcK}OA~c_=FV-~4&uVo^`cm6ilY~#4*#`l z0nR2e$^q#b?@eay)~Qo5liw)5(7Zwbv30iQJG`hu%K#DrAFcMuKwsZ)*gO1Fb}IU) ze6Glmqw1kw5q!fW^tluu4CP<~9}jo_st#4B_+O3{tu^8-;}GDg)VaTiT(KWF4;C~l@Mr%vs39HY@j z<|`PC<4PAk+O-FR3l`4bxp4#LR=p^7EB-}D)W9m|SN_2}LFabuNf4TA)Ez(vSy@7Y zcJ7+D6cE~f#AsM@0iGq?_YQ1T7puj0I6xvFS+?w{T5G46miwCmKJAM(wA{NzGbFm3 zf45H@f?q0{%VQe9bp6Z0>Frd*B=h0`#e1249Od(GAGTdttla)!N&m5}IjP#crSF@| zj*k0YI0zx&Pw^1{L!+@rUft~BZPp!qr%<(}*MCFDx{A6-CH3a2(VZ->z7G0KK?lN7 zH_UzM(u;7YnhoJULAV!X1-JW}3gx5(;z-Lkd**{@;~kKpi>KYii>imFzs%;TQT7nn zsdm@KqcdByc=5N#1G}yN?cg-XnM==67Th!qA#h%s^*pq=!p~`=-Qk?amYrf+jl!?| zzLsK~8B3>gWWNnPO}ASgI8*F#VhDpy6xs#`O2?K&k!AnZt~Y->0v)If$BP=kL8$+&26cn!b)b2u=4z6=)el?i(i~(O!BF^*8p5fs& zFCV6k_d0U-{CV@5U*GN?f6y6r5}Zd)Xo7(5)vH&*7CJNXAaOyw?4PL%SMUB#vqY#_ z+tM^bq&!ow$|O{ek{Lm@3NSe;*q$M+GyAHdHG*JYFH)A4mJ_tRe0=f>6GyF`MhlRe z+g7MU!~m(owYofp2Y3AVK*b#l3%Ts~wfz$^j_#2`dynX2cXI1UynlA18 zXliPjna$(w-@N%2%QdevrAY$!Y^;^G8)_S*+6?iZr-;;v@Z>i_pzC7ps4;V*}> zw-XG;Ii6AmM-HM(4*&E8jdQwjg(yxj5ap2;npq*3 zS!}Sy?JXm4Dx6*JaH^P=D6goH5>R@%!=FV{(m<@88gYw$aj>qgF=zl%7?|qh zWCN5v&IXI_?Wu*mUJgwa9u`*TVjB=}iKjprQ+aQ%;^Y>%-%Nb}9{e>SUQ`_cpj^7u zb_BvQz9PRbV2FjhT;s~gy=qETh)V0UXqN?n(LTRT*x^l|HLLP$@TXVpY~TN}b0=S> zU7K|hBoc4k!hcGnlp|WlZU-j7?F=Yme!90fqeqXA$s&bh*A%C*5}m1oQCMsNRBox2 z%Fa#R)~|2h>p3|up}QMwkT@A9aDXfiPMhcG2vAsY>`mZuyeILT!wPtglhcQaim7Ph z1aLOPVZ(Yx4F8nv65mgEU*8`TfRwsma&3@~ZLrW3DX?zlIKG0j)zx_kg1z6C&6}NF zTtZKWQa^O--W})-CJ_-zJGDC)yR0UX^Kyg`6o5ynS~sN@K6(V+aIK?=QUHh|`6Hp? z^c9IT)oVc=sT zgOxhblCkpa4fv#BKt;kfF*95D3#D{utOPVYbpU;c*gPw>6$&0an1d(b-n~wX7U}99 zqWSAq@M7wW83?6CFR{XT5*a61(>N(%!J_98l!h&obGKG(*KNSkO^Ym;Ck{Y9VV> zO!cYB4tnh)!>+7lLVW2;38IV+0W4DDdQA)sz?hISQNeO1tw6gtf}r6YT54u2vt7 z4%D+G1rP1ct$HuLOkfWn1_S5J0o3ntLLHY^K@9YM7;?}X@310+S3j)#B~B}!O0$_= zS?l$+?K&o4U|(@q$06n&A)epsGA4W81{7VoZn={T(%B(oxCN~9sC0QH2SNHCo%a&bThSG*v zSae#A5Id+`3BE&A;)u*yDn~C|_zKnlx!>Tm|Lj==$RCj;2q8#{(H}yh;q{GzlR;|E z1cM9tJBN6a4E_}H-rz3;_@<|K$ zeaZYd>MRM}un-s(jXzJ_aYx8D(h)ua4UH&WG5*y41Cs;)z;%QffT;Q>GHY?YF&=Q| z`t`*)o_nd8|GE9{B9V}y=LB%Yl?LtX2yD!7kb^&i&oaSf0hzAKCuZ=R&6Y~8S!hKV z$O`*TpU&jApoHhz*FL|rh#ApHajAVon4ngU*r%BQt5M`aXUH{!1)$J7-!TbUVxkk;KxR{y=qh?InqzFXaj+;UF0P0!#CGwlgB~;YPQ!P*@ASI--{)MUKd4V>)u*iw z^E>ee?0{6K9-{kRurvhmxA5cSEOzq7u zC=z)PKh8GFB`iA^`3(;N>Y09Y2I8A%&m1Y?xlE=bMy%Q3A_(Za2;zKN{3}9-!9mq+ zzuI*?@P$f+AZjE4{7;`AEP4!xpy3b9A7~a5L~sg!IXL=| zohJ?-j@HnV6a2ot?^)>WDrEhQd3VKOCgkg%)XlEOTmv#M7Xwm(lL$InR95)kaoaW* z`8Q`&Z6sFaKgWI=Fqp^2VAnABEc4j?jIP$Los(v0zAn}om-jJkvRpz%UB z<$d8*DGUF2OgxT3G$zI~{wN71T}El+Rrj69g%U?=;J}0(I~HR& z^E`uB#=sM_1mT}dfc-r^DQYlo`s~pZVJ1d- z5&d(6n!nngQaN3K2Nxr7#M6GSfOSwyDVnUo>D|~JWWA#CPRoWQh}>pNd#PI zyFW#7gmZ@{`d9UiZ;0cwv3Oo59nmch)h22U zZfbWini#KqagA7abzZ~e4Ro1hWo3wB@~^ZJ2vZ`wxxqzAz!fB&lSP*)T3(wDQ3?GC z1jlRH&|=#icH8!IOv)C6G0&qXPTVQ{cSBNv6Fo=dj5#9}d=@u*51na56L!uu5kFvbJPaiSg>l!6eZgY!{DHJL+2b$5M*GQ1cA4Mm~Vm2w=N+?V4TTgP>=qZU8trnmM5yMU6O$MmZoj zV`$dU8DiLF_MVHfowd0kOHQve2)rJ2N0hyWX9EwsYTUH=Tro@+7C0xOqVgEAr?vB~ zDT4M=a7i2WsQ=)>sTVHb(H9pJV=;YndfN#R7GDyWRv^d0qvu>c{}05hD3LHKQ`dVX zbNB@Jv{i43KKwVIQ;Mko2tF}Zt`jE2f(64_<7)@YvG0PNlKj|Q+4`F+TwNJVu{-fC z*8TTZp2wx2-*I&k$LcVs2@lVq>R^WDS#9zlA&XxP6jFXffu)$^Zy+|{h)+nGLT^Yx z1+75!%&TZ8V+o4dG#6P4Nsjjn@VC79Y};NXAi!uU0JmR`la&@|rSPf%F>FGyqHt$a;Nuq3)Z`Ur=U4>iYQF>V{VdsUv<8Hh5 zUd04-`tr8Y_X8RYB3C%8Lb?6-96MRFMsLVH)YxEAP7UF<-(;^~Y<=yeM-9j)#)Q=215MkA#FvOCRbY zHzQFZH>0QK$uT=a)fwmh&OopjH!eDL62hMi)^pD<=_IhK;vW=yx4X}$;EgUvin2x* zQ?s2>IW!P@$xBd?Ro{W(WI8U_REEqjl0Y>^`6ZX+1k-^qX7IMUdUA^#3=zZ>kmAee z-_Z?_=apiw0UMk4?JJkZ?#-j|QtNX+)zzWF%iG^W9*Yrh3q}r}FeGqD6H66Ub;)pa z0JM(r1s+(z!FMu2+%U|dV%H2pTW4L{klPD^9;kM+4pYEQTy-IFUjp$4@~o2$;dRa*^}_6)Wwjl^RUM zhJ}X*6t|bzA7EmZ6X2PN#q?HWj%mH{t1{)~EPD3f!6)7;Mti6jV7jq(dyHeIXOY7Li^JC3&Qw6gTZq?6nkCjs}>U(nTwFJ!Uu~HrW`?5nQ6zI&>|tcOZC7}T{;(R z>3NTdLY4ufKgVJAB1{8}CKE<4KfELUh*W<{3O?1>2lUa=0W=1#YQX^=-q37aBT9Jg z2%I4$qGbX@W{9q}wEoz!LvA=#hQ+~Y{Fy56k&eCp1Xq)Bf&xX9?_sRgi&<*E_J(<< zaIHj62vA2qJAFEmkgiWeq~J@{eM(UDLnJI_a%hCTx^KBjl|WmhlCgmqtSK{Q)TDeD ziF<2^8=r1ap(+_1Jmt*(&`>GcvvNBLHI&xK^RHaK z%&-~`7HiSsoVfCT1g)pE<5SU1KYwp2uK{e)%}!+~gvSmu=Y%FD;wrpM(2g)jQbI3>>XKpwXLg~Q=hE*<2h967&5N-+%mRk15Y)3~ zZLi*-9yNh~38A>)TrnS==m{Odx1~Za&_x%H7#8e`p;=@Ockf~|q+I61edyi$z=~}Z z?cD%)6fz&i#>Bw)VF^{f;o{YJayj+$RT)`_KK3dvD=T&T_kUYnE_6k+jbE@8CFZjq z<=Jg0F)8#A7-tRJh@TSgjTdon-@cGd`_dQEH1JWFMy95`tlz0@6#AI;Ug@`E!kPuY zn%cgW8h3`4>nm@bQr7L~nCX9zE81-OyzvnY18tmao=JKln1%tQ~QOB zcjb)eyG~~KzU#vI^CBbT^ds_LI#A81e&VkcdTfZgr;rKp44e~~?#&a1XA-h_d&noE z9#bg7hNG|o-I{4_WfiAlC>`8_)|1mpc13HUnD+U3*yt%A{~N;obBI3s{wC8nC4V<8 z?@VcmXSdSUe&^YqV3sOYzx=lY_i?x%QLBM-dr?7w#ew^WDzM;Xtfw>*pG#XZ5-823 zmK_A6Y|k2JB(tz2qNmlNLn$18=FnUMj9ww*Lb!P8;>DXcZ^CmxNigA@B>7YF#V%rx z2ff>P-7VAx$&pzI7b#gdKC(G$v_i$f`539i1w*$=nwRC;+Wkq3i8>c_d4 z{m#%vfVM@}7Am2@RHFwk^6)_gxy=Rv1?b$oi>nU)no+g*U{&>`lGw_wDH01!05C&c zH4{s5{GZg|2D^rg7hkoEYq@IC!X^GWL_4x@c?z0NlmuaAB{(p2?%XD|v$8TZ#*rEC zqJj&aJW085A+m(e$^gi_dgUCi@3)zMlnyN@E$z4-=oVFHk@h7^tSWXSX?EIX(^kMX z&S4ajaQs%Uc~{{u@9um1P_2{y+5UQZGp0`E5_=e9`g9(_&BcqeCr|!BpbmdIsu#S9 zYWvJFGSVMUKG$N5_x1}}gWR9F1Gp~I@I+{1d5(hNh&w+h^+>lnsmlIDwd3h$H* zgq}hWNLWjadYrg->z1?tf^>C1h%BX<%)@<2VH9Mj9A;6PiKBP@&jE}y&{bgIBLvt; z3IE_84aG}x)O9*l?UtAoLksaju;F?9|QW_pDy`lEMEeqhhsrjUfhM$ zR2b%au)f`p+i=YJ*;gFXske!G$54x`71e@(j{if(kB(1x7ZeDP0%-$Bj}8L+;p_<^ z=)Qyym`#CL_`kKLXg8E<{{M+Jg-VTq_1w9aM6XI_oNFp8#j%0szGYGZ*@FYiI}K|3 zIPMN6Va4#@IR8`MCr8;G28PJ-d`BGwqfAL^wummXir^=NJU10B#6qA@!TiU#?<-ik zVg+D@(U2imt;TwV>bz@b=c{VzoY_x0?3aJW2D~Xzv7Y$&KXt1oU{r+5-E{xc`j}K(uOV z2~a^bnkTW_WWfZDXujUN59Vkl5kYajV%Vj}F3Ic^n< zRf`fmh)ST#f)>Tm|N2<%+=@KvNyYFAsN!IKi0HUNf26ElwG%ZUie#7@?6-&Rv_+3a zfx!e2{bCU4(U2i$4;`}Z*P=KH8sjjNY@|}cuHx}O8n1Af)Y!n#*y!(ZYR<1l1Lu~= zccKbgG*R*N5MBS!TWbH|Fm2ipmbL%{;M>Np&t8&K{x3_9M1!b*TSx0L;4^e633s!V zHkP|OLx--0{h}}gPenGek@?meHww6RE4TgaxXz=q(r%YF=4y1dGoopbnVzHklqSs; zr+-AtKgeeEKCpgtWXDlWQjT;eIhxc~jH5Cc#+-6YRtb9o8pLn_W>`A{iO2I~&vw5o zUm`*$1wNSwE`X0jI`tU%74r|`bR=$#RP0Vpt-N4RNz!#n%61D)$4fqUN%X+{gn3bO z%qq5^=0=|4I9zR5v(vfr!>3Q%-^0gu*Y@qQsV-Mv6MGR#6qS^alsX*IQp#@kH~=L} zddo_d?L^cTwi2#xPuU!kQ-OeIAqX$@^Q1}oMn*G=-Zv?Z*DjSmG}hmTzlB*7Ya1_IP_XN4f+NIGtDta+%!`D-G<;P$+4(+fucfVhxxPLD3=?o) zv@!=$#pjaW;q^Q2?{mGqzaXeerD>yAXUwPO>4j>L5Hxi=QCvAV6w%AUJv88ZLDRwB zKf3lNa8ufOrrckpUlXl41#s0~UT-e_W?{K*BEjuft{*;rFAf#e1I2TzWzx7ZTJ?*8 zbyfIU8Ltl3zCPGk{QLjTc2ZTxn19lKOV2=mH`#|>|3zv`8;(*fFI9Q8?wQ&YbJPDF zr)_ujHSo*pH*a3L1FfJayfn;i;zWr0oI(U=kPY?TpE!Et){ZfI{~^s?CEAGw;-)7` z@@x3X^wixApIEyL5+sxwx56D&(U=4G{YQ?7&cUJVw`I%T2_xhF`M6OXueNim3uG-3 zsU1qKpumeM(V`xCR}N!g+I=HD9;^{o5O{1+BgmAuC?Q_BgG(to-AR*{qdplm@l@&>qYm?xp-URSSW~01*OYF6{F-o=R+uqn#vf5C{-7@{H`yfD z|A~FnRZpc*i@@VwUUnQ>Rh=h5O^!*LLaec48z^uwkQ$Vuki}>!0M7jRdss=PXx@ZD z6!Kci0x)T2ui&d0_o5u843QR?UBvD)XRon|iAsV2F1~HWO%IX3{msTKQj^mlCet0B zAVi5o%(O)>v8d_ubBce=rM>}lfVOm+imvRrc0`Df*cWmANKNVX9s^|}olHOi4au*fd<8ZCW*4v=+2BHX$3 zLF)zIH!BTmTVH0CJ+%FiVe{MB9h=ks@~G|Cu6T#`gG1A{YY#BBPg_uZ=)~;bk9$qH zpW!%h{lRHTSI#ea>i(om<3rh-QI)2(Nmr}Ej7Pk=d~fHswRe|RUcMKQ!1U3un+q)(l6-IHg@Iwy;Eo#HViB zF*wib*vXRsvoSz$!HXA^hbdh+o}SLT+2sIUf(gWo0WpgbIeup|5yLTwWVg+ddVN`DAgeSOiU6nJiR&$TRvq_5)#B_KZyUpXL+@1MzraLI8Y zU>ZBX-@o2>zHC3q)Nw_%cO}_54_n)W%Bw4BKf0pn{b$~T2WP?F(3XH#f+I7|Z`5NF zlDHW&ylFgv3C;VJG)uH)1;O0XskPDA$cSmF`*-e$c<^w=9|+&b##Ch`x<0^Uw0tBgOyD+M&mfdx z>BIW<-`uv#_K{gvWDB=$KC*S4;@_XFyBn%!W~xHf z!m-HI-uP7I)K+37iZ&v4-g-(fDnb+%;QUq+Qrw;V{1rq`#v(lLIhQkmy$59`IyANt zw#>co=)-8q)Hf_K1je(G_usQ?*GPsH=Fcw;y89?gTFdfz2TR`vh;*2I`26uBZ;Ij8 ziSWl%9cWbt=O=lNxh4qZtvkwrg5lk`W zchLZ!(Nfx{jim!w=t!l)vEW~oebtf0dG8oDQ;QZ+yBSucln#Jd#`u0_2ThqEac?M6-UTC+xf;6P@bL=E)Wv+qi#zwNDr%U;9#@wGk!n_5f8?_S>A4UmVR zR9ad}AIYOfUIC`e%2oDA<`DxgMs3~&jP!fgfhL(pv7cZXzI*vT#J`?D zn=YgEj=yNN(q4Ye*DhA_IJ|$^-}qOs?%w>HH$~xKUbweWp12tg6eHtfx%ih0)f|}`s%`9nFeZ{p0p#An@gPb(~g4O zg17Ua9j|-B10q|Xu%p|}45%z=t9az^@5IB&9~0=`Ui-=P-Bu@pgNxBm(eRx~VBwwS@9OuFO4DY|I(72o@`OKa4yFXi0LgGHT`S+);X{O=&loz5 zrJ}X7u!jVx5xrHQ|9B3f^SON(6*a1-6jO2694A(sn)*hGbOLdGY;3zf__Yf8VUzez zKoUQ?vlR&;FbCPI=e0W*PRD2eOAByEKKdioDeC*`CR{0-HVLzm*QiO{wHxD z%>YL<^T%6xb#xMRe3NW#yC^9k;QB%91{&IEI=xMYh$9Jr8DIt29Nd5ZVW35(dkk~9 zh|aC`#5p@;I&9HEeMYU_Nm-dN1~P14($mytH8Gm+PTIgT+=UP>(dxGTAgd9W8nKId z)Ee6~x>I$TlMlrXz$68h>pIX%QpZPk+3>0J=Wi^7AdD5~7OGpDK2HW80~Wm8fMEfH zG%FV#NJ*(@3>^qV=Lv?pcJT(GL+{cAth_q`Z~?Uj)FGQ)7EAM#!E?_#oS+U=9tgUO zS{Ta|O8IBQ&?VWNms_m>bV~;XqRn zf#3Cxz(6z-4f| z^M%IwPTk#@8p6H&x%RF3L2s1!O%*)^OR6i9Ci86!NAiQ+7Xw+h z*Gw;+x(odw^#OqZ0U^kPz5TePDfrp20qJ?_;je9)bvspmbE@YB;Kzoio`FhS%3P`r zu=)`3sIcSW`ao5AYq~YaqL^U_&m>8}Muddb@AI7vOcYD%^~JSEN|BjTtSC}j6SGf}DqYryx`HkRgY`GvHKAn^TGs2@~yFKcJ2%zI) zU}Pmr&Khnw;w}V)3+I=1o*(-ha|INClzvPz(;%WbXo#byi0;_)>HABX5ip$;qDzc= z?6w1|UABDr>%;@Hx*z-)QP^5MZgkO0>{tB9YCg|S_p?ORR8lruLEMlOi?4~)tW)4^>X zeNf-e@VapVyJV)qcA~nduKv;Z)t$QHMgIok8WGawzfXipT1{eHJyPMMaE64A$1h5k69>2YAc<2%?Xu7V;ofc>C;4iDN<@)L)r1Z+~1sz_Cs%2`8* zOe;b6KX=NMWY!v?!G~PoAtuP&U`mJ#YF+-p&oqXzzjE5p4Nmg}@S{UAzZoYfx$j zlL=Rp)^xPZoP13-e{eux;N{JmmCh8^ugpRAz?8G7>SX)M=FM4M2j#D8M-)z6XAW#j z>v(5pNVYR|)xyP#SI>It)v=AZF6LBH4u~}B<(tLjaF1KvJ%$5Y%Z39vC|Pn$D9RJt z7-26HbuOzCC=8iGqKcL`K@FiiS7XtQ&02nwI2K5vQ4wosl%b_3C8TiAYapXV7b)ri zLKGQ@(qH@|)I$Wcz#sJ|V`C=(W<$AyJtHVMGW9^r7-^t`ryU2%S?qlq?P^Q$L%9NL z%>T0Er4TXc~_cHa3~ zKHJ**&}}1XE}B4cOWmhW(`L*dzfzGZwr_v-!iDDSH}`#mDq<88oy5r_FXJ=rOO}-P za2jJ_QO=d7FJqkb7z9A!d-`LpsFmbOaBHtkm!C1mhFT-vdS#mL=s}?@lfq`q4))aM z;ERqE$;g~@{sfv!prX?XU&hi}C= zwkwM>^%m90wQ^5BIH|a|wc=O_;P4=vDv+J0&F*129w&Xo-7FHqnx5!PcO#yD&+GT@ zm922vO@?~;HEpV@{Vq}pMOjLKRKf5@|Hg@&4m^SE?F%XAzw z5QomGex+{kH1at^sPXW^)an8E_kQvfw50bH_JYA?tMeVt24>P|ya1TRQcvME)e~b0 zS&yrn0EKQF(VP+S_~yJ}aT`F_t{if@obUJhejVF9x|5noW(_^KQF+#gTSG0en7s4o z(H9V74iAy}aYLr8LJw~iA11D1$2hbWKUk@u(xcf)X?0t$;0toe^1{T&LwKtOI8_8* zLIyW!=a9C(Z!5fUtbr-X&n{51Qk_V9K zdsjO1Tu@MtNq6ioxa35UHh3VtHYJ22A*a|mCH3?YE+C&N4LE{{P70X=es=Mxl#`S+ zzaSaTt|i3=l}vH*cfME?vP|*}vJ=h*se1SBd4ylyBX6z5$6m$Q!{NN}<>eOujI zlvnvq8YAJVv)!jxaSd}~)80+n~)`WFwLJ&UWhV9OW-d^iEobLMZec64kaLUU;O zp?>$%9MWz5LI&oJ9iuoPKCES#IPris-s`ov2$)|B{|s(}R$0{2S@wgVHZ<&1IIGhb zuz93VQ!nk5*{Aqrt|9*Fj*};EQjx1e+SBkG*wp=bHI%+6TY9%Vj#f~6ax-xfZOp4< z#jH(4G>hk-ugco*@HJdD>TglMa^@`7d7rPp94@CNT|Sqd3UL?fNY)be0Ak3ngi|XC zs_(lje4`tt>|)|t%Q_z?7FtEdz-o0AQV_a}=0%=CTsAsS^vZIexLa*mbWm=t6A!!F}DZ{AQTQ5WHO z9oNf@2e>ObdNEag z4f^<^t>N?myY0*w^x3ds(xoeJ7?R{jeN=I^)kVeBKyzXBZ9u-S{nV-0CCou+xv`$k zjNb$2k5#g6zkXG(Uj0P}zhD6h)+uPveQ`v!pl9$td-ibNBhNeT|XF3&l?_rN7>$X=rEps1E?1=4i9FovM%K z_kQA(S;J|%mMphhq%z2J;OT~7`|+=LxMZh*cdI1jHTEcqC4PY;-X=7{{^R(iRLctf8$nLTUR3U*7YB0 z#ujUgwYw`K28lg<)pqh^dt|eFbL&|(k-P|Ic&VR1ZFM?+O>G}4LQ4z|ozy0m&1SiF`I3?PT<)&v=__9a=V%c}6 zyyEnt^)IpH6n}!+HycbVCYtdD)}p|r+Dh5&zVz2thvmN4NewqJd9myMc#v_z6-F9p zitJ>~(XWU3z^%Kd31+)NP1Rla$%`V@N3 z&X(dN-{F8(4$&UqqNR2FV4UM2jM$zJtH_0glX1Def8ZatIngr(1iw`8>EW~ zoc#9oCS!i$`croSM8I}{AJ82T?q&Uigay1<{p4&CF{CVP$47xu=`ub<`|2wGq9M6w8Ro6cRl0< z)tg?o3CgD9p`;>4uZ}n_c zF)t<<0QEQOeooYMH5;bXA}1we9uwi&HOu2r(csKV{|SIZMxc(TU;!6%_4M3J#>9;C z(kn1J3@&!&#rK*sX7c6829Cki)aOIzN=o1 zzifi}7!?8z+@nWlwA?MqlKKhwk6TKZBXj{3lAHk?kj>!91W}hnORM;Q0qScEqju~l zWWE_V&T4WqhlL#jS^4?z39EilPfL4_`2U@4YRuD&;L~Fm9cej6qCYSF5fB8JTT4p| zy@F$Z)Vs0w?}*})y?ZC?VZ;LHwtMJDxFlLId^|3EhGCKb4YpRvi!H(_PO2 zS1tC|7MHD6-KS~Q(-5iHGOjB6X*_=k&=d|c3WG5+cub)Pq(KM+lTJK$iTxy<7sjVB z*+)JzU3-8skK$Hbg2EQs({~gd;3g+eW@{*TkDFKc|CiL!*uekA-kXPG+4o4Whz6FkjgxksX{0sL#7ZiRfdf3y1Jj|eSiCR zJjdSqJ>LE2b{zL}_uO&0uJin!pJ9F0TA$u4O~o21E#Qq}ZxIl?s6)uqKprno_ff<( zB6?vElYRU4Va&TrmR!~sHdrIq0Tf!;%jcv3aX6GUXybS894kqpf5Oj_o~VfZeq9?2 zz|^YvHM@q%i43!P_4$_-SQUxM5z1sBe*B7V=@l=31>jz{$IOgwr^kiBlF(7*^^dXr z0LtBEZn;_Tj!)&=ox;)Uji=<<`q`E0TL3dLtvgmD#}wRSTA+SgW6aKWsxP?)RTIW& zXtLqB@MCI96^i%Ls2WT1;t~Wp_)GIkS<$zbn}ohs%!N=akhx`LSZj&p%3=-B;r}$) z8Q^&gz##qq)eNaLMENom029n zVW7$p`+glk(26Tht6V-p{t1(ZN4WleGtnnXRm1tuA1e)LZ(#;U{vstcNr=3( zXsQJ?3cYTxe>}1mZi1ughXTmbKQuP3+@XUWl!#l45Z%Xdo_d5dh>c;^xP4H>fe^@*{k=##R!Ns~$)=SPn{lU|PiSkRoE6?85w} z>dl*S-Do)BRKQrybP9uAIB0*Gd<+0(4J?alOE3aQI#|Gbia#SM8wc}t_=SgXz$;`5 zTBMK;AMkom19(cG`|{;W%E3@@TM|;8;pj3qH#tm^3*{cDB;t`k!v4{5xO%9Mbix$Bo<_$O4fJ)-aZc(S6&Z! z?KvhvFvCf(f~iz9IC=+DoU?i{kVR%!{F18$%vyf!%on>kK=Q?>I43{MeqQk+pUA$h zm8~_L>>-<3SySMj3+hej4UMfdbaZelYwzt{D=EE>opQhwM!3NPfnO1}FhKa?`O3)E zRl1!UlL%zbsk>xQsnx#$^$>cQWAe;lxhO5DC@F)=$d?p3317Hs@GktRipWsif|MLB zVFn*;-%{v#Ky^p(V^K$qjV)ZWGRg!sRuDdW0C}GR&J#xe zkx+FdbL&+AnCg$h-+j~nknoquSW>#N00U!W&1w{ZwJrdGj6e0k5t^oHqPjAL- zo^cG`%?h3RE7n#a7ypFxJl%H%tk!mM)Tj22cQITo@$@aL^j^kj9%{;P?NqY-jFAI{ zEruQadKj?)OTdr=iwV`}dny8w4yHtCr=oyH&x_<3|12%d8g1bM3C|{aXPB9za-kOl zB@I^(gW|vFmXVfL9l51wgv587It&cXL&nqBHw}OZgKoVCGQq!&08@N}l`EJ>lN$+Z z>zWg~%?@0Eh_7QpMt>Hs23e?&kD{qnuCber7snii^b4+xOwY z-f>72!8m(!-v;#ht5?zd2=5acm;&gF^~;85&g>EsQ?~DX)!KR-pLie?0Tb{ucoi6T zBC=+G^=c>pJ7R>ud<%*nyR z1Z8af1Mq_W41{x0XJ~?+qff!NL3s#75nSG2J%A#gT3UibLg4Ak!pw|jT%De!;0JkK zC>*XzjFe>Ivxr*>nj`FY;%&t741gp8yD}6(Lt-i(ryfkO04V#A{1ze&RCN+ULZ2K4 zCe0kT4CP1uuNV`H!9EkW%ywDX=%l0oyhZeB@dc>>G03xQm@&YOcg7=(l&OaWv0VebsK$kABsE7sfVcKM!JIIMZe5}u(2lURGWde~jo*1Qd@B-tXJarG4 zB52{MsmHOC6yFvYNDV9vP|uX!Cs&j5@GJu#+EhRSS;QjOm^{Ohx*v%kguM`v?_lMOepqzh zXS@Z>&XZX!wrn=1P zm`Q;}Q-c&}Ho##g8+R~eq9ga(1!GQDR%y%XAdKtDAbD^3($W&y5b}G;oAWP$hq9<+ z3xXB^mwmQK!te~n&=&*uMqpCFVSy68WctK@|M1-WJQ;FLOA|3ATTGy)0DaK&1xLh3 z5a{aa>M%D%DA#{7I1N4oZV0{sQhnG}B6A>Y13j;<*1#AJzZzUPv@_&6lOP6Sa6n^c zWrgG>K0KVnjJtED$VKEx6Bi#JStUN8x3)MgfnwAnlXt4SsH#Xir3KRpEHNT82(8|R z<8s1ZMKBOd`Ws7+z;3__1MtWN1F`)iSu+GfkYZ(9adby85&;y0Scb{1wvG<&1j0Gq z91=tIY}5IdXO4~#W2hD!9mBcltmrs8`wt8d^KJYmFyP` zfz^X*EZvW;N4`=HG{i6L(gS#fwgfMZ8Vr8`eI3tZ|KK240%e|4e8Cz}?jrqo14l=k z#aSG|^d4JFP}O3riQ9~}gZ3H(^GmqXxROYx;2i)gNcpON@d>7m@E^qY0$4`G0ht1& zw@@Iqyi39~6h>zGa)qeOuFrGuQ~tqrc&1L3<6$Aiu*XASLVRQ$?E( zyxn&~aLa4;O}-#_kzq6E!6lR<>>+5vw4QuINMuom77 z|N5BC`N`Oohu;qlQ+6aEN{l$r6_UL~!6n@)B!rKn%S#bc2mlo91>|F9btF6#4LuvVEwEt- zboO>3oC%OfKaFAlJA*tt!1%hVstSdvynk4B0geq{%`ud+95#PD3x^*`{MTL^SNNCx zwGrk;oz(rUukShh;U;;l$W_nF{aWxo-2qF&|15$Rjb6 zi7@t_9Xk=o3@0Vb0X<#X7`o-(x3sV%xtN&50|7zVpV;CgWg~Ko(bc z62E8%q0|3sDUt= zo<2lJM>im5EcO`_aHInAhDl^|uqrS&)YYxWnE`Pgu3})_0G{z1dLM-%bp!6`x^=KW zMF|1$1S<$&{`m{X3g`t^9c)9$i;MFGXpF`IT~7cYFdQN{rgFnZD1u*k;0?|Y*>xRW zM4&AJQG2lldcvW@he16dZ~KK2V|={H<;%(;HMhdT_%Rzq76RBEJdSC$B#L6>UskQl({YSQQ{zVIq1e#}p*J`OXx)JD+b1n~(21M7eM7n;W5*aHKYu=r z$sBCFqwoeHoyO-x5sbqQDHXs}Ks;AFM4)2Ase+62+qc{I?c-CuUrrt*1!-)>Y{v_9 zkg~U;6smEmxTko?r4*QjBc z7#U$i!!2d?7L^qQBcM&bfMOGqWb!JEO;Uti833Nvf*C!dAe-(7e1c_&)09gUF8ARdyxp3u{YolNXVHy_R&@2ocKGll*Kwo17u&Tf#Ei`8r=vsFfwY5)88=o}#V;fgqbF1>$bt$u z;p*wBsT#n)-x?U?$aQO_FU?S+zp3<`*~NBl56%q6n)yN(+>edS+mPp&Y-|wfL74yQ z`E#gw6>wazbOhxx%roEy4gX2FK8?t0VorrB<{*$7BujJihtLRMstQdjt|dUzq@>;g zHnIv2@IBDRvGH+`t;(RG!l#7YAkc*X=(zBokP|m-*ie`$he8FLb$(-ju<+*(x(f-6 zh%hMu-tf=PN)!k1bT-9A5BIm|>o~c7Q}q{)B(EkzCG~w)KcxlxUV=j;QP&};<8Kz^ zQ61nI6wYw|-FyX89hjlHniD7`IXGgFN&5AtQNANgpUt(TX?Jp>7sLz$6@jzIaW4?7 zE?s(x%Cx1QPcV?tQFs$WuM>D3=!L*OGKk$n5i|5J5~FQyCk)#Au}u`_R>@1uQHL7e zzLgJHRko2rZ48U@~6L%5i zA|frI{CQBJaU#(h!?mdclL`R=!n5&>_1UXnwDE1}$HPf4h>M7h1EZkq1`c+1{djqn zdBZohsQ1X~o27HiyT72Yz8@cdd&v#kDyq>~85-_^Zz$-xPzvGU#dx>Kr3T&>a%bcA z+M<-GL@5zWA>BEV(VGo}3aC5-83oyRd6xk+CU=mS2m1T5n43&u#G;&BGz<$1UM2)O zl!4N3*hYg*OYLejWqsr0&@O|lk9UR54UtgvW@qc0oK-3NYS=W$fMZCSdYEK;tvnM? z9G2Ub`_7Zsr$ONbt`HCrqyroQB&B!^K5)Z*osB{BO-=?O&f3!QCvqLI0JwBKLtBV& z0(y)W9u$ni0qmfn4Blpph6p2XJf~#p3=I+2Ga>3 zt!OkF8|_gBgV6!jA!-GrrCNoV`FXU-Mkh~h^S}fS=4|K-L864o90bS-3a;C-z2GGn zkNlFLFR^1s|K%96bExc2$RxPHIfu5ibGQxyN5FzGPk=K4Qek|Y;-%vrKfmc9*P*Wq zWKPikhjLy?H&uG%6fEX&_$JMrP>|&_p!k8S0*s5J#m|nRGX*>aaSk4F%%LN+g)hIy zkSzYmL9%lUte%X;*iFgwM(pzq)&%nd%Pw$*$qtE%il;H2f;kKr)NsC#KwpU=*A;EY z^XKzHcQUz*3=XXvmb9J*j|JBrTWWjqGd3BeNR>(n2_4YZ)<(xrRYjiPA4=OaN=~*o zsXKRK*#SzyX&`pM`;ocEzJG@pySYCADG(fbi_&^Dt0>j6Q0W`lH3+s;$jzu9QJ#T! z1x5jWEm|{#+<3j8nDBBkfjQ9)=nD=dv>W*j%j|?g;(O|m`{>r-HZ;PG%FN@Mqq#XI z2w-T$puR=y!PA853p1+ZwLd72MuI)be$Gg8kWXW12FxB7CzyI+WdQIiUyKI;Az}9I z_R2A)ou|ZT=0~~NR0ubY=7P9?LMK-56r%zGM1iSFvPcx*g}}gSfQIEmZ!yoqQdb3saL5+^LP0Vt7|n~TA&IgT=UWrj@~LLiwR+|W?!zoHndfeY^Q=cfn@EA2J% zWU^$v{rA+8S+k(gy^oa2Z3AlYw6tSqI4G4pJzI{ZO>4>43 znWL?335pmz!-IVNXnR3(L@hed@DZ^ed*nuLZ!gqhChLbXA|r=h!JP@nGDwt&_Ly}8 z_=5b(Wt-RH?+m;hKvH<+BYCI+g0#LIr0Qm?raQ>0H)J< za-GHi^&pfX*UW0UnCOE}l?cHG7{S4DsyJnrZGORA52X;9{9;-f%bAhkN=ESUd68&C zc$Bc`9jxCsn9AY#1&jpYO=DxItxW3o?-#mXh=_^V0W?P?f+__eZ5R&?*%~?{<06)I zy;A}Ji7_zz6V9Q%Dx^4pQ3IYj=U144Ax1!MvprrO*BpT2f&i`_+9l`vSM;BNf6d8p z4*WnoobvUj@hYgmMy+Iu01+T2;R{tLsxOrL_mPY7yaC48R{X#m)gF!+fDbG&krIC- z7>IrWlU&JN%GX|Zl>3!HEjV)LzzrrYn7e=(1EmPcb`W44-nWT^I)+I#T6fnC=6L~Y ztEh`}jB_c&@^3Sb4O55EKSFHmzbFpm62#dTFJI1xkQbw4=m~zQvfBcB16(BN4}uL~ zKQ)XKsj(+`R0C6#>39YDM+nQ8|9JcO;I6~-@}`#=z$J7lXgPt&C{y=>0xI8?U*@;O zKFL8W^lASvJlb<)WX?%#Kp+3_Cl3>m)UQ_3(vIzY4{?09YDc=V|Jfz9Z(QCJl1 zqX&O7CPozaVN10{4@k*-{_&+=?tPsW*M3G~;G&I9OhSSRo*uIMD;hwQcthAL;D8fLM*r+ zOo5b^thPpXVY~e+BtZCdkUm0U4Nqn=EwHvWUnxsi6kHYCc5#?LfVEn>ZO@)&fK?dB zw6(b-yP#}CXJ+DyZoTX6+jK~3&_3dcgp^W)zJEy+axPqCj}k@r%>vYbqSV158?phd z{jqy2)a~q^p@hY9F>$RGj4$G?i*Q&l4tZdVI97b~rdHP`Zt+?$mRQLCXOh-7XAq7N z2LOxs!JX@fwyTE+(#mJ(Jh9DcdRo9z3KtK-5Wflwi-517V%ii8*()z6r*^A87Czq! z3VP)yq0~Iu&5(M#T#vyxkz5r4K2#T-o&3Yf^LAXmE$F! zfGB~`56jGM$4lV1qD86xjM{b}gAXYSlXn%Xx6A;&V9tP11i~S<=>!^rbJi}2WF&F6 zSmQ9)7Y3l?N;VRY{4y?h7zd{%*g z0ir{IG4X3F4k(+INkq?s{|izyvMK0?e^5^RGgbZlM&jsgvMCj8FABPw-LAe|VLG@q z0;+%L_Z@qR)3BOb!Jh@Ytg-)iMxIwtSU_MJvgd-buo#GUZXHCghsY%*D@)$_D|5k6 z^uAz(_CjsQFL^L#aDo0d_%!H!;v>BT0ugCY{Em!{LinrSZM#iWv;@-l%*>eRXg-KE zP!efy5rO~-QFNzaT_SXM$^pvdXKNvQ!szb6tGff;xpCmBJj660BjXR!48R|kwnxq< zoNDUoe7(IPLX%fg;>UE+)-(on4gd-CeB>e%wCNI20o4}@HSO&g&v>0fmmB7r3F&-t^^@0Te%4C5#n?qO9adf!Colp z^vkP>ip2eZ+Rp=kVWGkR8MWxGAmiuYB|}G-AWgRUMBFVvHP$Vxqpp56c8yL@qZ*rz zPUz|~R%{a=^swoIU(f6HnJ6mI54}0@ZNvKYHJgR#AHl8!(;oDf*uMaH0&3fJ9I}P` z@_<`|O#KZ-eNVF_JZV2;Fc^H(0!=qg5Kfal z_DCWgsd+AMt%=2e@I$QR0SygdoCKKs6^hinBn{r-BCB37qHCG_H4ALVW0k$oh)@qY zm?C)}H0f4kdL#xidi~cp9&)uo9+Tt}M#wFO?t_58sqWFIQ6}1J<9z@Lfo{SZ$rN7H zh*OG949;DFVL1;UI>EsWZ64wj&Ne0wSjnP@{v2M#BZ#jDAPfSr6^K2#RC@OgF2bXL zd&m3dpPa!S}gpG7`H(|U0WVm8&72VBm^4!{E0uUOoHP|#&r8IBC03z__ zGZFpJmzKA7(Z>f}$;ZtGgv4p-hm?a{h&h{0i#C`q8XDh_MB`lzVRkcc4CEcmtpGv+ zX`>3(0NSvGehZ-xGZ)x!Bh!O(E+8(B3b-75q|jSKgVM*vgQex8FtBxWL~q_Z+4Bv( zGJJ2QZDr&10O=>GIszbMMiW;ZYmR9LE>TCZJ3wU#@%ylPg>5RrJ;v}bIPKe^!K`jF z_#99e((^vAX+p5tG8ZQ5u)-ueCHOkSD(nrCHEL&MYI&9NxoKOJ9w1VoK0>hp>bEPZ zn`#SZgUx_uAjnBJBQFyNV5ZQ!#q1-lK2pFohtF8207YTO@uwIPU3(p?;0i}}Ecj_b z^9FVz%0?vfnRFBM@-S#8PgS9wz+-syDC~cD)#;OFQOJQvo0&1WE#6X-G_Lv z1zNFdpg>d^lr}8D!NOXsQIfF#OGAU2Phkr= z^Qz1OR{;+d&ziICET*#P+&0PaVsaC|14|A@7GA~|CKlz32nk68TZ#XOfjZ6se!JWg zaQRN>T3*Ng8t3|umeJq&S$eoXofE5AxwL|QHs5nO0rQ}<*<@OP-504+_&8u(dIrMA z`7dZl@eHn4*9MUpDhoU@!0h4nQPY%)IlMzpF~$a-07T&n&B79aeuKPJi6fd^yl>tN zr^P?WS)hC=-xMnM6pql2S6PQ;n%G>>b^bJYG&|<%RzXoHe(Xmm-)ORY z*o(M{FZiQl<0$9=g#t3}W39l2VSY+xyM6nHKLE1kEr1}ZJL{?~Y0zQ7?l1uMLW}`X z#cnzSoB|LmhFU1TaV^mOLCsVOC^g&i_O)vVpl1WQ*XhI!aA`2jQD9}(>)S(~u_nqE z)*T@)5P^$VNz34z9eP_(+6BgTVb4cVZDg#JHC9n=LPLdWk>xN-4qzz*?Qr(h&`8bB z2C%(>?0f+RG^%{39lGl3$k!Y=DA+^+KmqZpHo^|u${HIH%HUqre_07->9)vIpx>bi zMpj`R$4Lf>UnhP6vk!cN&gh*;IXIdiE}#uX*ut3y!b&PeF^oqA%U}EQuR_J)s z0lwrVUVi-e5lGjpHD^Gy!Fq^*1R~!}$Zp^zO&_CLNG7wV3e_YZ^AxLmGMk$He(d|T zWnxeG%8xY(m3OLa=kV7gkCku^qg|80f3D0)uToINAIM+k=2tD5 z{`uqom0DH2@NWW_lp)W5Vr^ad&p-FSC|OK@-vs%!Rk^m;{_{Hsf2sdRI@tdQFTBdH zV=`!A!ZY`X{A+bI^)<59&955jQc+`7EY|0jMSBYyYbi-_CkGo`#kGK7Lw&9F>$t&5Bi8F^YaAsA%1rztM^8?i(mmJ7)Gr1n z?NhD(bgL~#rC5As_p`Iq z_~sR(GOf_O5OcqLtX}~a;dBW-e$S#%+R=*>TYodQGXC%Xg8zf}_W%Frf4hYdd5q>M zt)mPx88ielZ{$7B-LkwVQ{Uc|_HhfxJ(k>ciE0m>=KJ$v_v(jSa76cCx_k@nO!@}e z2jfk|V?_1dm5%MlZLaR#P7!;BGGh0}UmrUPw_EWZCk*WjG#iw65J4#;TGpv)nI#I^ zI76{pLK`g4SG&qmE#KOQ=(li*%*cKv86XR3pd6WvFq6slt7e?HMH zWvpraB{i-WOjQx-^4>C}@70BD_Yc!L%s&%*hbAe*d)yNjohq^|^WqCyJiaK;= ze$M`NmIqdDsoi2b<#Mp@+G|Oj;8*he zcyQ0uc2PH<{^j{>a`O(f3|^;plJLgFvOa3zR+ub*sHPuRMS zu}B-dFSGVPe(-d0@n9M`&`3X|CLGR{C-VN_xoE{Eb@vz>(Rx!_#5wn<+S&9=Iy6M} z-M*_0RcsXaW@Cb%mBe*vo-d;I{a~`xU2CZ?=f%D)a^aJ}OViE#mYBjm5ko%4hiYlGg<=oIkMG~)-Dtwh&3)<40E>E18~S?V5_;t~b*7}u zJtLng2FwrYhE&MNim&6M+Z=xI;QkXGAAj|h8<3bSRbnL0O_|zqTxI^1Ol^)7-EeB< z8qY{faYEeW6ZzOH=E0odA40D5KU7rNEp%z$ZhEz#w#}O@eqU&KaQ&5xEys0cY0EpC zyZYGNMs^lt%0zi8Y-(;4BJudS&!2d3uEQvZYDq~Rqjpg65z6nB*9rB7?aJ|gmK@hU9&HNY z*!8M&UDnAnXSY0v6f!P}KJ}uy^SV&=?*;h{B%ehF!LvLnrv=zI*4JmYjkodfMSe)! z{9H`hEj=$pGw75dk6QZ`(ossm%fH)<-ZpN2{-dxyW=h%b^!81XVj*d|k6MgNtO8^C z3|L89MQUh8_is{POwM4~WkgAei|cDrjd<|>nK1=1(lprPnRP}+z2V9e1~suGBCeUl zw$x7!rGd=E!Z+4<)r|z!k&hi$UJ!^DdmS!FJa^b~D1;*0xk5Ia4a_@?%yLu+YESlog*~SXF)7%_am3WQFA^+;RyWfH>2ZP@Q zMb@VoJ`t^cLOnP1I57NckqeDu84dCJwb$Gik0eV@yY8TjW3OKrzoHLVrnr%Nh>Jl| zA+dnMZENUIC-q&+UmzX^xbJWtW#9b5cXa>#e+~6bF890 zeu4rFNGGT73tx5|n|>=qJa^>x`0?EB3%w-IA>wR^!S3+51!t3la)lF{q(!8mG$0il z(&(7$@-gdPWt7@@j9Q>Nc^%`-S6^b!c_u!;SL3dmSo^|UARWke4V(aHPb zPcc6`YVpWK+~5|&2W@?AqXStx>7zM$sH?ARvW*UB_CH3gXi7bFX5*IK_dRE?S1%RWB7Q_nI?W^ku z!-q$yOr-yQu5Wvv2!FIwQ$IYM*Z%Mmg;RH-q>R`PZlE0fxpma;?t)$U{V8E$N0e7H zG9KypL?0+4vI-Tvho7!?dH&>~CA5W79`2OkvuhWHIR53iy6M?=!l}zXR^eCYNWE3z z%t7)Y#t+Vn0i#m1_n-xMN*ZgK=E zYqKf`4XwroM5lLQssoi2gx6Tcc;+evHI2pS(Pw8vTt}u?myBOj^U?@cQ>L%SRd1mA zzV{N9Kx&SgqK1Zm63?AGZyT?FTWs%7&(bvJY`s)iA|$c#8twf@_mnm5iD(TW3Z=XC zLkV^3nAPoWn%wzeM|kyL|9X6lFgY6$OAnJ|yLgz&6;o%E^H}Bp=hJXGT}tJ3lbp4oSIx#Y!NV zx;bxEnT^E!Q8zEoxP+ac-3XSZU)ky7Y?hXUc@x|ekD28h45}fQ>(jL*Qv*M(3FD$o z+1c9)`);hi@r9%t{V?MlHHYxux08F2S+JTmDrPXNfH41VsQl~p#cVF#+Y4TV;m%y^ zkc-(mL1~8MR|0uGJ)4%a*Vf$8@kM?4vefblh578Idr|j)ya65L`7U)5Oi@leA!vO;l?JCclsyR+e%dK549zKY-n|{ zlp6TvQlxzG(D}=^){8f52es{pTKIj8h*jJ?-+gXzoX3WC%uPl*oJrsw(Qtq_VLKk` z$z=x3_pjf|Chc)xZLsH$k2pAi#Mb>js(F+UkYr&x7ky@VkiT%vpIDeR`q60}eTLcc zQfU`gdj0HbF)y$A4G{{|!E{2b=OPk6yF5gUv8umQ`LDwC_uc~fZGpc#T2dBOwwvc3M(5_m9En9an8LHee*)9=Y15%O;*GvtfD8hw5mKRqXpS42M->gh!)H3_G2jWzkHZr=bC?_ z9Z~ay{h`2KQ;#;C)q(HT^1}62Ql~Bt-%B;l_@jG}UgGi}5&Z;85{H?F`9n=d71wQ( zB^wEkiRAlNQdQ59Yp1O;A5J*rcb>{VzSDkISE$;Gn}>z{1~!Fx38?aa{TeNf1!bJl zw0e4+D%^EppBgF?Gr@v{9BBURy?<)+K5Mk=n(MO4wSp!V7tXP<5tT2jPo}R@1O}S7 zY$fFVxcU98u2V99q*B%+EQ5F6XCD-;-qzM?K5?3u{#B(baVm>5r~KCIYZQHX?M_3t z+HURFo?m!CB>&CoiEP(ey$(?ZcHGsAGd#VH*k$ylrsh(OlV=@|BT*T(%lKvOr5b@$ zUzrW06zz*&-iq$j|C&@c*dkA;XFq<%Bq*4kUHjZZ-j#N4?z7l!{hPt8&I8mMTdiz_ z#85?Y30&YMiM03-@zJB?ApJs&>ifJ7Zd#OFuZH_x;@PQlLu33T!yvslr(ccDmst42 z`2C-|c++1Dds0U9+^v1TzK81Rw@iaUp}^mAJ2&Ij61AaKRU6Ng$PlDcFZXzgWAC4k z|4LhDnqcadefbn7e!Bz)_g!)EPEI=ncctrXnJpdk#CZFG?XNs8o-SRH^;s>QRj59UrjtNfg`eOJ}{D6a*J=EN(h0e!wa zq|)nL*;(47d)^r)BnpgMZl=^+w_8t5yLUU=!rU36@Rxo=ti{Afw}E~O-P2dY z{YmZi#Fkg~o4(s_`&$aJ6R)#wvh9e=H5BJ?W!*4vjB*IgNkU@yZTTXTb?!du_50P| z&i2bvP(JrBJ5k?KM#C6>_v#P3(s{l_KX#cXF~6xUJ5pWH{d&+WN92zFJ<*z18EcQ! ztdcDTRWI6^ut{y$No>!5vh{r8J>UA}^xHC*=mfs`tgI?|Owp2V@*mU)%+vj}K7#(; zJK|xR<>*n{m>bNbn+zo1=8*?IyM4}OyjrR9d#=Hhj!u_4-;Q1^nwrCk?=ijFTX*wQ z!ombeyR|pwYn%$td^Z)L5n}Ss*Y{MboBvC*{c#f^u;HF@mUbYM;pnKm z8$H1;RvE!WVf6N3Vei$2>FxKx)( zKV2#s<5o<482I=;iyN*TJ$9ge_RNMU9}30ryghso^+V@*w?5SVa@)J5_K@j64SrL= z(mo3Hw4&=2Hm7iGaV{npHhKH;n!xfivdKP-tIl>b~13V2mzZLa#t9EDhFh zWSxC5F1*QN@L;#U(u25Mw;lP81s+%E4J7Ms**j4wkL;8?Ga+WQGb(>Ejm2dP93|W+ z?7mzbNg`jBp~;e&PX@$vmt*0d^R_XME7JdaB=eLY1g+F|?mBRE6T!rP=SfmNek^mM zK`r3}`LULt-pli|57S3EhaE`KY zIGXfIM?i3;y(UCkhk`USDA_#nDd#keqa*qdN^;M)zJJTUZKMyK=P7*_MN`erlyQfK z63_irsHv9aVhcb{qb1eHEKMaItoB$xos_iidv~jWyQ<(y&wc5R;?2ZkgSvQylj65^ zl$XQ~hS8G1utZ<`k=eiBk&?)pW0mSdUslFPY+`-A=d*a|j*c%}b4+%Z-n_6T|7s3X zQ9}K#n#;nTj~|J??2Cg(&}hJ-Mk>WcO&!1 zsnVaf`e_Q-!*@djOMjhcWD;htDWP_XdW!MUbD9uXTix&VuS!%Q1R_BswvDN6Js2kY z%+~D(XTCl870vL9|Fa%a7LIh6?;hH(uDvT-Q=O6s(zs#oZr3!PQ}v0JF!iQ+rOKB} zkM}9PVb$n~sM8YVE7fRnSP?gPaF;77`TMGXU~0ldm-E6NVtL$*o*~!cVnbCOT~5UY zLPSLS@GBP!devz;3b&4p&DGT{!9P=D`|@x83up23_y=c+yA~KO`|32gh1J(LF8bJ+ zCix^_jmN?QTS{*K8p%4#ZMn1%M-*Gt9{vkYFhS9dBcwr`_+RY z4xa0vYW~Ek8*{ouW?0TQp)2Wa%k%?-^{hY${rVc$CX0G@Y_x7}IIR39 zHILEi$X=O^Z>}yxiJ#eV)Mw9+axKx>dooh%p1z6J_doC}Acl@XF#em>y(o&xrziS! zW}8lxar5yJ&}DU=Ml|gZ1L}2A_^vhWmZyKBNB>BjlG>WKt#s%wV)(Cu$NyC!?gaD0 zSFL-*#D%F1RP84|8b{~kSo}WVEcx~FCp>?$Aqpq$t{rPm$n5s%Jf5vRD&xo>gy1ok zJL%}!BWq-dca?#aXqxz7j z=`@|!Ysm^~1O{6TejI5>PfhLbS$|oNxOI=MdM@v7!8#y79O9TdK1VX?{m*F zrJu=vfnxqEBOxiduxN|ht-hVYc#}jxHj%3lby#<1(?`d$RmBGn2=f)6#FJ~pWI0d4 z*L6fj#@p|$$91%mW?rp-cwJFNa9v84T z$TuAg4Yiz`$8TMu`@?)AeSPI!uYEj*sOZCJ3C&w#rqSzSt(XYGREd+>fucXWCVtUxZkqa(MoHs zbB`!~Oh#*>epfN8G2kW7IMz5;T(Jm`x;`_A!0@u}xb51XniKj9TgR_w9ezwGS)@SbJ z`VxtF@zs&cf-VK)!S-!c0t#Gm-9&WFKut$Q(ne{j;G&rsUv2T2f~?V^cJ_>=GX=aC zN|=w-A2}T#G~JPJFYn7vu+WXc&pUzWtYHquk%C*)akkjzUX$_k^Sl8J9+Jy}+hff28^yh8Q33 zHF&X3YHGi&eALo6+fGqg&xokBFswi)A-r4W_?khf@>2dyQFnQZ?p6!i^2}9h8W~Sgk^K|B zhd40=mCxINHSzkpLv}lECOryCecrrBHavV^-$lv`UGq(4lgm#sbc9mEBjS^Zhx_7p z1cyXXj;Wu}-AM@iyXad;E9M?=ry?2O<}k(Se<>|d`fI?mG4wQHQ0~(8BR1Gb;Y-Vx z)tXfAjiu8YZ(PyOT>Blm=2tuy(0M)~ZC%$uS`1T_u$TT*iAz=(^*wQAqq4L=| z%GBJSh3U7g?jO$QVl2v|{R_G~%TYQ%tmd5;Nj38w*>W$23gOYoBfrDmfKPtygKq8E z+T0ob($lj|7MvOqvF!7cEBfLa2!Dh6(*PJTK^FCmLVB<~ZMAzI(RJZ_-O=>PS%dta{FH0A(kz%TXpXkFx;!7+-{gbAEsF!AS=u9ccs&RtuUa|B0i?bxoVLT~?SceAZ*tf~F{<%?A< ze%^aGKd{eP`O|uSk}A4rB>47nXh^xO!^cPMZK_1&mo|%;+CRS% zLn$BHfA(AMY)Z24$oe#o`mHHkU%jX@GSahZehvlQ z$^XW@&Qf}zgVxFYJR>zCWR;rQeX&!UBdbHHfF0Kgo&wonK>CSri>XGSoQuo!7aPLq zlV0J92V?i1@hMjx4xXoLG?|k>&doXsmnr<7ZQ`Hj8KCL=9TBpN|Eo{GTdq#_<@Kwp zH%_ogoPDD-Wjt`FdboMAl8R|!!(qGXQtysjDq?P`t~F!0{LE*w5!o8Q9Q)6bOo^uM zBMsi$_*9IHvUGGhytfMRlM=37cx~%>u#rJ-Vt4Vw7W3a1uo%e^X#}{id&{7ls#BBd6XJqHtN--- zjX%Hjx+_X=WOSl;pkMqq7r;%Xf$3RJ-L9P2c~gw)Bq?4!YjjLsK;Rl-R?8(ZyIPz= z93l2Fea@1e@98|bw&vsaLC>{uuceuQxuxlYKW}ba@TFrRC8;X?o~x+H$hx%W(*)CS z6IN#sxQOzXJ4)xb%H9lPAkMna)ptHW6hYq~(o>R)ra*add+nXQ<5_nm>$}+I%k(pC zIG1f_&$7opmm8XE$q86p5Xhw?A$pyBpMUnasqEkiCoPX0_ur1t*1`NREnng`(uUi* z6fTNl+}iY#TxDOIP3>)Nwq-W@WTyDK_MWv&UrjpY+O9ge#pZJt7tQqzra}QO4WX}z zLyWu30+xRrC~1nF@sHfr|4x)bK!~c>-?o;AC9bLj4T(7MyW1e>dTLt#TNc7=?i3Tx z`SK;+FL6r_%N{s`9*sTHlevboP0qjEPOt87NC?xXZBD)D?>KtL@oVps_P7ZOzaGWH zLNaR8y-qjqH}%vewU`p3nN?LV`e7S)e!i=-Wa*wTp@8kZXFeWX$tm+)R2iPI{eIVQ zyO;24^vKu3t`Da4<|CqXcg>cw%MYH5j-#RGJbiNAy64X4%(AP;z9dY=?=WhMdu*N> zFnE@-P%&GDL`fldKG%I$;m|zCZn(PKcSv41`^R*7LxO%2eJozmX0ZnlQt0De6_2*h zb)_ragw=|lLz_@n>qvd0%MK=%+siOj}Msisb; ztlZ#yvFd4*U)=4z6eXPC(6Z=+lr`C|gZ_y%MJKDX`_kvP<~dW6>Yrv=4EWm5Wf zqNBKNPsf1b5P#N%bO%}iV#Ab}jQyy#YBlbtH?P_VulewK!rkX8hP3aFGG$8cJX-kS zW}w?8FQNRWPuC%XshJB{o@;cziGyKhnqOtSVo>r)U1|MX_*?yjZ@UV18@oR-6ehyw zUYo^5+qJjuz5kQ1yFrZ*>k7Gl<=LH{wMI>cdX0oTjjAV)=rj`fcRU#$N}uy{44x&} zc68GcC=U2`(fn6B!)=4y*CG!XD8lar?lK|()%AU|`dQE4?KiwKH0q;LPahjFUoqBu zVc3uL?2P&NF>EGfH$k^Fb&b zSD%yOUaAgxQ&CcWJ!LY|)o^hVieyAR;gLCN%6|bsY(#a-uN0||>03x0iFY?uy}Wo~ z`|2NqNVCguSQBNx9iDX9J54cGF|_b9fu zQB-#3G2i#n`q^Nn|D-fNyZt341#6twRIAd#xVgpQzP)eVYXbQDKZ|DP*dIQ<(6}+_ z`~$na6_sjL$@LuK=ARx#0O$7ZhcwZ4Q=0MW ziJfGgiH_uJu6GQhmrzu_-gNF7N#4-%t5o>-llF0li^{Q}`0=(#k1s##t}_CCAz~qv z>~-w4wOMuX(S4(TV75Zg=lulL!^M$~FN_?evLo+|99Y-Uh=sJy&y`nP);f3KS6=TI zR^4dxx6Fib!G@YG1v|w{jMusXepUDkRpV;uac?0wBz(1E#P4$9b}6%tIDgy?7K+!Q zqjs-2O|Au8av8RmUH)pK^R6*{+xf~Dc5q1se-&R?Zgw=Ip{dF7!i5DVhI~FdSH7x- zxcP`j`?qIjZfqL$m7ZrTe2^N+0i%<3B(9Os%rJ;QPTG^Vg)M7W!LGer`j* zr|xe2d_sa|8Xg?{zyr zf1+i)sXej9;USB&BR|?10KCc z>+WjLw0)%`K&c(x&FlDFEc0ZhE2KEsmJ5!vi_2eoW!KQNRbj&eHzIy)@$8laF%*JD zy#z&fn0{$hCzn8lhU~%Ag=u55pWAEA7xw#dc z-*@Oa_a>>HFga>CJDRz~UcOgO+2w*+PKlQ!pn&`L`7T~`s5d<+OOw!X_UMt;Vsocv zU@&L*;L`vj{yE11e~JU50Wxyy znhn3`Ql*5SOuunYsUzEf6w6uv0{l%AJ;!H1LG&zE>c!I4*7PILENlvyTiR8_Y&-%z+19K7w>>im@A?CVU`=RPO5 zvz0y<^!b@(@woWKiG_udoaG9wwUYBjwFU}#CmzTp8AR3eT&@#}T>8DSb`Pee#~zcc zb*FqidgFI@QxgfLR5T6hY4TJu6L|G>R2_X3iExuc7>9 zO{wW-BMI*yc}rfL>Dt_qdo=yuHCgOo@Zt3tv)@;|(bFEk1rJeUV`DEK2te!;f5yM5c`W&idWBR@~ zO;>Ma7k7I}_4caTeF%D~x|DH;NvXnU%RZ&c!+q1It|jzL96sYE<%CaINjbP$yfsws zmQGMuOd2KN4cAZ#40a0H#2u;YghdYRHWNF8r>bSHf1jx6$j>2%d25b!*Woe@AAEi# z4>6sUgvZFlpPO%aY1pK<;lb)pnxm5iaoSz-(n^}sJ?ar9L&d+|kt%t2 z<-gXv03u}ZxY*RRQ}0QK$zjX!!T)}WnjY}``kF3m(Xz{$2Zhp88yRmv+9`n4Dbc01D%%B%8ViN6zB zTa{c&iBf$bW|y<*nEC3t%izG2#7+q+r+F8D$%|jpbq-|z5kJ|K*z{C6x1>0FBVf_cz^{Ol^ti=03ePYa*D} z(S(VY%zma5^^g-&>q=LBS@Gjr;=tI8Xc0e7rjY3ed%AihsyD;!l=0dj8acUd!w(#F z4;~{UFUk`%-`Do4B(=4-CqbED@4E`Ve71`}==NQ6WHa}Y!dUZtC(NLx)`zDEE-PUi z4M&hY9_&!0fks8ZXNRmA$g|}juBh#SrO@E_E6^6!x(yCL>noXZ`oT#kua)XNU90ey z|14mi8`5(}|XF$Tn z&D!EuwBBX-rG?JkVDR6nwBPvNRN*^Lv)X>-`G(o%` zF1a4wKsF8$?N^eExcd8n4TdoO{3Yq-#Gf+{BxTLJ(Qu{W_Xj^#M{bL|mK*3rrGEAX zc-#1e(yG0cpGp3zSJ$W*TS zCvDvw0OIxjEbTWt39;ZX26Hu@?+gz!GITPI=i4_m!C`N_4{CG(`cM*Z)bg*V_LVo7mSkj+UE3UUB zPTHB=I~i+6TUpgU6v5$`Q%cfR$a-m9Mj2n*G{@te5;nc_<(#y%r29?+Q_x<2>Hdbp zktsMF%X);p5@lg6Y4uNY@9WA##OW+qSV7wRmSc75rM#YmDYzcwtEeg~cS8<&mnJ_O ze0xZ8ov&cAGpdjmzZ5XLs?80A?}E%9uiElU7ce0+%xng9y|bU9jRKU5jTlH4u`CC){%mBYqURmj=byh8?i9v%;(M4f<)l&foh?Ck zWNoi3UEM?ynUSGzQ`lgx_Kma}PeASfu>|fg?z*Y9f*;;({=^@ouxm@*mUhy=eO922 zyB*00`B~2&-v2?_S4KtkMtcw4t#nGMbT@-EQVL3^wA9euDALm1A|TR8r^En5*U;VF zJ@6j?@46rE$9vXrX4bIQ%$%pre)j$az-$7<sbQTCm6Fl$jy8_RDFtO{7r?4F^ z`adL0HG{q#ghs|6N2U^eibuv5R>fA14L6MgJo)GewOr!q}00sgj9sH?)?e=`S?ZC$b01$)#=GR=^HZa-bClC%lfM|$j z?w?%doll5+JFu2Jovgemuld)0b#-;;B0%pNPy*6*0PRLrJz0pmYTzwUi;BQjWP0~{ zEbNxdrycy*pPsxIuf>(rb3EFD(Ty+ zE)pR|#y&%%Toc>AmXeA84ZhqmB%xOw5m>p!#efJ_=^^nQAVIU3b+ER^3+QgwsooKX zhwk|#08VNE>)C)35IdIwe)qNuz`g`jV0j32ik&Qau)Eg4Pe6aM?_63u-bn7Z+dg8@ zYCjdCxv{#F<%nr??%|;z3|bGMi)%uk?{cfx1~%kudeF2%o_Oy1EvId(s}f6Zi^}oy z@_+$y6w@M(OKJY|>>3R~Fs=C@lS6(dfgZ2dWAS*#miR8LpmnsqS2SHXfLbN6NY&eq z|MPs=+;q500LUHyftQmIuOtomDmoDB{_N@Q0*`}O3| zEZu-C6cZ~hU+>MViDQcS%jaVE2Yljy+Kl)$wd74l?WPbG0H>41>cIX78vh3a=_2m< z5BAmYF{q$oD#11jHFs)DJ&pGP*rtOe0{_x?t@0kb86<)2X1E{A{g-n9&I_P#^jEks z7v}cNz|e61$ZX^A&_3OV%i!DfGDe_ddk^CJ`iQbUAmwtG>g!$rkjh#wxY0oDr(X^X zo{=<1vMKA`j|KO7t27K5Q|~SH{A~5UYUT(i45-ez-#?61w1{*hjqv{7cPb?*uF)09NcG!2CSl1^^{n zmMZC?U12^#vvwmw(7N&`G=t0b-N)03ua`fWP@;coWz<|dUo8=C<7+1s$8~yoGy=rM}RgU$QQr)ca>qESfC4q`(+t?{8G$^?u8R z3**s|6P%^5k#5jE*_T|6Avy%p2)`Ww^N!pxoYkg4T)rsNebDbPbTSgY%!J)-x{jR|1*zNuhzY6(8t6jB=qn7)UvzDj6oekLhIA|KJV)mOBCvvfq$g^o4llw*2+s^>FNT909tPHt7tgJtt(w0USe+y&> zQ($7DAQx0*w>x+CC?MlME%P7Xy$v8nsQ6DvzT&c~bF2VDs<-rkYF6R~+W@J0qRQC6 zAJTp;5)4;o z8d*gptBvOTlj^B!1%SbYBxRQACi!QI>=&1ZITv2qAlF#t(LI5cTfUOPiV;k9Fzdrl|7?Qw9c?2X2(zhbn z-|2i7=BOOHsQQm|x7QIITmlL_?1%*Ha278CNlbtp4oF`BM#r21h z=AttZdWgcD63eX5w=Y94hlbc%_t47i#|?w7XcGc%PKxW4uGgmrC!lBBToJCWyLCcu zAWsMx@SWlZt)Bshf6ga3}q`Fn3Nj7oL`0;F zGw+(7{L`g5d+rw~k~rn5rOx7)&D)%8tmI-}KRMAw+091c-s>z=b>W@#I$w9X0?yF4 z7B>y9{U`bNZpfm<;q;{Sw%pwQH}}`x@)SHt06n&1x|Ry>9bKxySblZ>T6Ftk`a8oi z43^n>E4TJXvy{KSMM@~gNVyY2#}e&j4Oi423xJ|6Frwz?n_XO_x2MraIDKo+qx>g~ z@d_<0Qj}q@U$Y_2%+KHB(QfRo3k)v1Oc-AIm%|swK5EbY7dL~sgr=y7Yx<11Uk`XJ za6BG`sMNfsgH;1GVu0ug9NX16?J5t=O)W@)8L^1TFs3VqJAe@l?0&yq0b*v1>NznV zUxIv(kK3o0mp$hQbMCf}9IhGd`gz*<@qt2g3Mi^cpL_-x1$l1r0^!HBQb6PwlOw32 z;kxxm2d6uydiFurMUMNW%}l~j6lNft9v;r8pq4J;e6g`I?We3unv_&lm3s&+R4(2< zRnL0&EijNX9+-hu*PY7c`r&KN$&n=7p)ro`aug3~NImWxV zxdBpF{MZHN3UJwRwvnq}&S{fedh;mx-n4C;9{SFhWirgE`7@qT`7dx)5z{dcmcyI; zjBf_tFcx`L1#jUeIc@JX<|UM7PP@yz!ia-KnWW|HLqK|d6OWP02EPV&t3#1jxVec& zQAh$0lGo!3PA4*s8ur;IN3Si*oro3 zX=FS%JB14952e0=;8uymx2PD`4`omHXD4KiPv{-PMxNU)W|oGz0%fULGX zO3>2qrAAiQ?Pt@nVWcaEs1UY;#g!En=c|hgyq6Wf++5s$m#~MG$4v>ofnypn)~d!_ zMKu>>MHXb`;P@U07`=$jsO${4xBkrkVNm<+FD@Vj#AcgOn{H`umQem4D!7~Wlf~W) zaBuwR{+Itb5@Y7eY?3Xp===Tt_+@p{W79FcNI+0b3)f;w4cZM*KRFpplRL{E!4H*59H$HS6A$je_aX{uC{1z8HK<_#fPt?^XToy zzbpM4Cj#R_E27t5N=s!-O`Dfc*A;YU-3+WwR?4AF=;&9Lg?BCDiiO3${+?|rs{9}v z-P^A?J?R3Sj4RL7mTVu-U-qnWCHSM59MeYtxelI$3K|-IO2F5!kcZF!(1AmCS}nN3 z*{0I&sO1J^Yyo|jqAPFbA2%umFIwLfSs+Da?mV4TQy57e0R(D*1Ai#52T)dkG#qFN z^{1=mw~UuaGb})&de|O>2*?P0tl=XpT5}!(ikQIVWQ%^twRaE_nj{Fe}Jf#_F^j-eOlo3)lLK5eqW=i2JrRXS~3`yd|fMBLea{8?3(bZ60raN-7@In|25J zFiqsj_dpe7+5m6#*_}Qz_vd2Uf92gVuyZWJt-S5$B7P8%3nHg`)*im{Tq1SNH z#4q56i_sgK|Kg&hXKJFxjNOF18!F`G$&XKiEj2p2l9|v2MACwGxrBkSl7C%B{vnBU zTARWg?`~^k&Nh~u&nfQ=4Gn@(e2=qMyx^E+ zV*0wko+|IIdF`e;Lhr*Q{rR)}0#TzO(*>>aufXyktT*FXEajpyRs39-TN(rNkii+m zcw&w!V_-7q$D?DV4PYh*k$7dT;ZLO!Qz$Xa5+AS zWvB|U4F0`XRpZ=R&TeU>=;<*G3;8SUnmROt#YQ+8*)zpZMl}&mN$Fc%gQgCS_E_F@ z!z`|Vej|GMIyjc#?0ofTDM1KPd$^)a^#lMr%5TEMY-3z~!r($2W;b(CvL$C(UntSHsUtF_qtsLz@8pF2F@ zHpl$x`f*~%wZXU1EG+o6ppgQ%Yv-~@Cal_CpNN`TC*1sGYv|@k4A^CS!vt6qFJ5rl zk+&mv-X9kfV}gwQ{*X;QRVQL}v7{H?wd<5Cf%Tf!`!=H%UQ5jD+3?`5AMWlRZ~NSP zF7H4TN_0%%Z5CN&CT_FrK5C9|OP)`y!)o+)TSm44TUY!=fTT9SM*yPx!<`j zzaEmR5qad8Yo@Dtknn52yqCd1T!RrwPi|voa`hrR(aK1oo^7ZtXp_jtNIrp9fwr~D z#QGikf`LJO5%wTpiyc(TSCIy4`e0<>=jwPA2Xj{ z1>Adp22Xq|Y}71wANB-O@$=vs)I`*<4?ml-2Rn-(taqz|-PPTsgGT3}uo3w6Paa8+ zud@nhSOyKR)iDqvS{@n|V*Pt+J8rDH2xij2m%i<`)vNPj=QEK|b@1I_mnOM9LGEr5 zTCkWTxb0?PmSi&8y#-VcfwkQd;iskvcR)&e6O_Hc6g*1BBy9@Td3iGM91%saX<-2k4%Yd4`l}>v zYnxA9vftB-fei=nj6B;cUw%n!3MettfBV)Eip4#J--75Yt@woS2HhM7oK9-O#SvlZ ze45MiI2~iN{x$<4rb4NfyS5Ur*Te81bgeDx);11K&6~Cd2eNIFk|BP6g$zbD3UiD6 ziKh<1oEi3I$1WFk+7oC|Sh>3UEgXm1S;LQY6tFP7+k!XiNq(ZIA08p91*{%Fr8=T8 zFDS%(zZdOKS*GyU96X-=GLC?GBpJM)p8SJ&) zkV?9ZeX%~cl}avL;%cz=wdYpXyG`SRI%G3n@>NfHVKsW{kwlC`?IiXr@tc(@O?B!% z|0cC#!krJq-M;MY65n&xIrl$) zfni+-PLd>HUiWw2#=l52Im|wOGz?(%5@Q(rcQb;lV;lNhc8x6*Bih~C9~#e@K=K{p z7vqB>u?oC7dLOa`H+(YY;UgB zQg_GgYp|2Wgy8;V;pX+vr-|mX@wN;jj`T;98+NdIfCBK)b_|P2^0enr%jW+PWCn$t zG4WHn_D|Fp(vwSgci0V+Qbls;16GX3fXw{V$l`5(kmHh&>ZS4WkNE^Y3+UK*PE3l{ z~%@duk!cT(A|if z*c60s{%@IYRV2JmnCDF{!Nd`?*giZj_+dqG+Ee&mIjv}t~3ik9HLQX%SF5#}@ z1qm^pSfVbOv@k&IN|XiCzn%?@pG8#f?M2|XJ1-bW__p}^wPJ{git4YNHpZD&V9tWd zK!Ld>y@f9-dXLdTs<`^E%~Ad!$7OYNjl?OVWIw89KgMK-(9GK({+g05;YUU0Byp`T zkISO@+l3c`-DrdoyKkV<&wF-GM2cQUs__b+rpcR6{*Lv&-S0^q6vKH1tM87=B%Fz) z(wepn0LJ^e^=<_#Ol)xToUCa{=hz3%T(NsQ9MWXW6>;j|*G(2+Dk{)U&SwwrfaQ1h}`yT`j4= zrg1O@>(U}vyu1~@V$;)ey;cwZAm}Ne?I@X~Bgj-KY;8SHV!*~0wzXkGbArtbnwQ1O zeO~`T>c5Uct&Fv?bDmFpJeTxA>NqNy96W_!Ph!ckqXrTZRz?NNp}?jq?(VXQbn391wz3gR5cKsS%og$>0&*@)U(~1~t&tCgC1o#5f3w4P=Mi&m&aP*tlm~~K z`$t<|LoYip$>l*ofkePl2lwA;I5I=(H2mv?o)KS<>d>-rd4x3~x&Tgu?49OSlm6ae zI{B5OLKz86Wy*E&?r_h3q!5Ygzu86rW+fvK>tbYqNtZd`q3Y@y9u-(~+v)7fhJ3^9 zT0_;k-YHmdf0}Ov!0X;gBpwe|Pady0rk*f(7@@|-m&PBaZn~M6zv zSn}um9NMlW&?MuV%6s*&8E`E^*U^HjqQ3id6Igq7TfH})FaWyo_1K5H2VKKCYlGVM z%Ohz7gMxjf7DTQ?kncAao57=wP9M{`LzcGI{KJ0#S&n)l!n?Yqy3LR=tTf~#8FDN_ z;(JVfOtP}tf!rf-Fq^y;)Z$!MQmV7|@-HTx%(+x57hgk$MD#$!FF}sS$G>UB?Y(F4 zbMPVOAf zjZfmYX{_oPeEsUK`g7Ppjgb{COr1tjp7H=tSTW%uoW%;2F4w?dG)GmjMLBkx_!w|D z99~Oo88815*=4{;sNl^-eZe%=;M#nsx22**)z9i5dDV&&KN{y;^0EplnF)oxZbZCq z#hM7*pGA;^0B&PANmcWhY$mb6DEn@}nKz-)f~@+TLnuVv{5|c5{(jEGuE71^)HiLyvWX>Gt-~ zdZaCGu_F2iOvKgX<8Ng>G50fiTd+)@RO111&KskqGK+pEzfsR>-v8Ti$_rvil5xgh zZEkAFI{dQ-+yxp^anePrBc0{N5%)g-39+2X_kD*O!f9g7XKojycIbHjC7CTY? zY#g)|pFRPKvO*r7`VnyKXDs4$XsBJU9{zwgpb$iMlM=+M9vaZ%qAhxS>)1}dx#27T zVsoy}>}TYF*(ePwYP{9BKoPMO^+p1vMtwEUmk_P<{FGk~@iW|Nko9A#DSrRi;h8UO zeWVLcrm~3x**5XdfaWhH;6+ZsOMM*OoB7SP>MlocD_zh!&+WJaN5D;$;Q5NGvyHP_-ZS|`;r`UubSq2P}w zrRvOH;ySI~daMBVz6ShhjghW%Bmf`8)%FdCs}}om2Qeb<{lo|IMH)#tZa3{oCtfp7 zKAp>`%2LnvKNwm?^dmdo=Jpx$=mbnjt#5{0zKO%2cab7H&n!|qh4Yq2E5%b&^{ZsQ zRZuTt{W?CTxeF+CZ^(vATpfL<7i!Y*=Ny1_r7d)rTfUHtoIgX$_F8Ni8S;{7flHK8 zsMrwn{@2UB@r@FQv7+Vl8~bHXJ$4AK!87Loh-%l*KdRd04pBEn92#lV_|dBRm}k40a#4*lEy z?oDaR4g(Dr%D_00YNP`|Kygv@W7Bb~<9Ta?ACzOC^bQ_m{IEUJ`mnWCB$28AN%!lt zxW{Ocan`2j`I&;yQsUi$(HQIILiJ8k4Xu(ZOr$>1tv_FXpmF23GAY`t{dnh=%;)BD z39?4SB1#*;3po~xG$!d=I$cFwr2$0^cCMbYTNR_>KIhk5R!kxs{km9pTp4J5X+0!n zkp(2Gr)x^%I^6u@@4#cD^ccRhz2elq;@hT$a9QQQNOGi_;jnY8IQ!L^ zEzz(+47!;o2hiC{0#ghW$jLRW1jIu#)YiyV@urZq$(^4; z1an@q3qofoE|2~kcH$(5CJTA_WxqOn^Im|dH%rACC1D}%r5Jx_?~u4Ag^X2bPn&z} znU%8p1>Mrav`4bhleBpm=@zuY-%D^`8)O4=!OFrC=D4wf6PV~du(`U|qJ*%bk2=MP zs?~Y8()v9Xc9tr0q74$wet7Ib$yr)|F2TE$vKc^?`5Si6rF1^xd2WzA|FoAJDR0>m zVrWU|^$H5pRU<`H+9*t91MiT~}y_n-EVkZ>dp(vSKmVB?Do4wOIt^OPTgj5ElH~ zPk2_*>db01yYF_cobIQb;is(spseo;ypGK9MIJ#Fg3qiv9-OE{Q{u=+)Nl(~)KqQI z*JWNI#09eY@Mt0kXwtQ;g|ok8w8l->Fxrm9`i=tQL9WHdWBJi0%jC)b+h=S9V&@pD z?$3L$i-`=P0Ps-^g7YYb!y02CGF8$^jLn6TI399|uAtQoD#=kvrnN_($ zxdeW$o<+O7$Uj|U?mENx7p+(x!HhNXGpIL`IQlZLDX8b*^13R{?M%e#8^^86g=^FC zhr6C^*9#0A9-jG9sf_gYn_NAHkYBLUO$ zH--E43e>Zq%+bFMT^dJr!@M4`on%rR_T%8z1O+h0th&c@%2&uKQOnvGp_ zMNR(R4+Z-f_)U&$abMVxb?Mnk!HI0unP}C4m?Ajec&oqHNR_*`seBcKHoBbbbCz@C zyyEeiVWTB5k3l1Gyp72rj)}ZwV6i|79p9}PXB`oB;-r0mUog9MUKI>|-Uj}x;G zok2I9K{i!GA%C#4nQ5Qma~+jtnrp|F$M$e!QAuU#H?Yeg9+@=L1|-$HzOFCJ_E1Ys z^IR`n^#)XjUKO^8`|}F;SFdbP1~hPv-zmhgmB&1U*SE!$#?oHW&5jspx&>RizFs)t z_P=C%*wfYw@NU&Z7nB|ScBjPBa3~(@C3RMVq#*i&)!=ryR`sF9Yy+;$@(G5c*Kzj2#J;VHaUqaz zF@enTdTZPY!b(+>wmIgyr@iKH((c9sWVa!uLgQ%8lE7MK8}zQtC5ZW*@7X zA6t*vjCTYh0+|2gs#i*o7Nf>970LCKbCidOypk8lD@pe!zawH#_gd!aU?cXdHqz!_;kKIhnMrq z_lsc!{@$=(0lIwQamiI}_fMO$Oakw6D58GIbvjVO$vxbn?&qMbH0w)O#a2$e`q1+e z<#^*{L_GC(i*}}a=2!IFh}%Tg9Eim_A?tagtd`0T=TFl|UT4VX0+2`VVdD|Xvm(l{ z`#tofv$o5x*U>_uoo~*Cqb$V4_)4`bh9&iHQ*1wvFCR;Kv4FaR=7lemO>nDm$xh62 zzg+%l)%~s)>~q)bD2^EP2T3+OJxu<|TGy<3dar&I-ecCB93{CZ8n=o=`@U$!m>Apr z)|aNympkjKNX~MfdZ0P2J^LK)@`%2qJ#zcPV1SuGbqhn@g;o9>rJ!*vwGg-T+$ECg zON{)R+jbEmj$KCh+BF_HW9GBqy;lIcRLLnEQ`!O3+}^1*KhM zLm>_bI)ep=yPgi+yt1-rEu<~nanN9z1hdIW)xA;EN%AX(idz(w#n*>8!YTfs>L|l@ z;q&^E!WR)%VB{Yali>6I_4j7K(dqPLeslEc$yno5PZQeW<#$52JjF8D*Ei-1xSp;% zQ*!piF79%T+91^WlT&-fv)MNGw0-AL=s2`@f|VqBIb4XCa6EbzVm7=;kBw*3$#rI6 zl$@G)sT>|iju(-yPMT`>=Q+doEi#2x8nd>Z2tDp2`)pU2YOj?jR=Nt9Y*(5Nlf>-z z=r4Ru0a|rV0;tH69!zWYXNCHjVSCVJY+PExrMWO6e0nR>Ai(8i##h*rG`_<=^I5F< zh#o9Dy3sg*X5ZpL0>t9Bb$ou~CQLdl_XLVR8HILt_*{*V#Lo7&Es>@i;BVh8`-1D|x+^RV}XV)fil60z4Lc zf`5;gOu*%2>qXA?OuS_dZ@czm1;Nm5TllRRM0}#g(fqn?Y?+!|`I%&XAZvZKeR0k0 zJ59d|xP_a!29G$@u^od!l~=j-ovy<`x)kIBTe@$Hwmlx-y4mNP3sg|U{bVQx z!X^EU#SThsVQuYx`G}+#<@0*V%Y9;ZHPn%RGsVrcSA$%+A484o+e@L?WO`eiJb}JB z>E8n1{`DO1@oxdC-qE(-Rerkb3Xj`8V{zTb0X`?2Pry+BQr}}|6u+VA$2#Ug+%aA* z2REua3#QVl^Qg}xAEBmE0z9_qsFd2Bts&P)%31Vr=PV6_JRax{^d=2iNW3c@!N}X2 zUS#IF$rdclA}k=zm_|>VVkKX{_XZ{^vn*Q!PKP8*F;43D4IZbV6=n+)f~#(9&{0dz zk;--_Pj4mJwGGdgd=$gIf7ALQELthqxK?u47myr93zCuptQ7%vq~zRHY&e>4168Ct zoh|KgtV-MSC>ltQk(G!Ws<<0=`vbH8Evy7A@!gAaJGOg77o~S}Ce^T2^k&>&oOSh+ zO18kIj`_-|oKLp3H&!6m@$F9c&nJVN0~>z}Fq?Q`&Z-^ewo|!FDvYZ@@fG%D^K-s7 z=N65IS*p*@e7#>;dBZSB+UZoN{T(hwO`IY878Z<{w`i>`$9AWUp=c-X!$lY}locil zNJ>`2Cl&bxc;hJ36r*L&8B3F6*&QOY$o0K1CeP~CIdW9wK}@`VOC3F0?%XlD3OO!A zvN*yF$u45*zUTx9_s{ua@oS$ScAYW^ay>>$B^Ibd*LlSLKAri-XH)mt0C-4++84Vbm!^A=D|G!W+UHsklTo#tyuh;a?^a zRu9Y#SxASOf=P>TUf#ZShLublvc|Ae9!09OP$<$8o@th%^O^y^!ecJOac&izVxn`k z0pQ0tRbP%*d`yV7^~h`Su2yVN@X6cjUm;7ujNT6>r6Q{aTcVNcizXo1Z1r1-Aj{)w zz81EW+r$DQ16q73`NWuCnh!D|;f$;ar-_Y?!91?)XQ~xz^%&`U3plH_KV}&@SXea} z$0kn_19Rdpy2d7fz1b3uS@2*l$)$q22Oh2m4V_I2wyJ7b=S?pkzJtNTeG!RUu^9do z!%ADuvJ))q*wRFV=ORVh*TZRjp)Bw_o(U%dRR?umHhQhqd3FgKmBX@=Kw#-{6GGC0 zOnMvddclJ0ahp7cjh;{Hb#^@kQDM|ei$I=Dbz01%&$`tI1B~?jkFGBuFOQDJb`yX; zMxsE{y~2>_{5Aq#!C}WnpOX%{fr{nmIUsSV;K z8erDs2sZK`L!2#joY;^Bo&rEQ@WVg_oqx~%^AU;d88qAbVTlQ!K;sL=7BN;A-V>Ek zkDoplHF17!OGZrIW3*wV?{8D&*L8lHGHD8BVn?wUcJVmzbH;S{tm?S)vjER=I_^v? zTZ8T~N`Q~2oqwQ|0qR-@CWs6ph$kllhl`Z-i^1V#HnVEm^RmZbxwb7)j|AuxXe8eb z6mEl%%1q2>Ota>H9&MGs`{Bc&%8LXu&HYnis9N2hOgmd7POWm!36e6IFwxjn_vwsl z_30_qf$B#Y1)H1-tet?h0d2_%a5k*P_oA$Og$JZ-Ro>sowUf8(xV}ak}1s#;2*iESIF`4_h2! z@Gu+w^K#=eZc~QzUTkhD&&HYM=7yrB^kT@n+E?%MoNA8?VjU^$^!aC|e;J%w@|G^` z_!QiyAGcq-R1AnXt@K6YC4j1tpFY5KN&Ev!^>y^=?0%J|Jh&<4aP2zvNAY|;*PEr| z+~(99{HieZ@gX6+E2Q80Z?%1`koTWgj}cc=F0HqDI5ok-QIo57D=phG2S;@N9NFRJ z)_Q)X+esX4+{E{U{!c37$rd8nX{m~Mz;Z6HlmnZmu)8=>i8;|oRaVdu|I6HE!1A|{ z(Li*tP{ts+#*J|7yZP1q*ikmgz6ZhY055ahvBkTU8PAs0X1b>>f&F$eZ1?n^+&=$J ze7rz@kl0m@?;{4+gI^rG6)v6wJf&F-O~g!eO6zg+hl*&5^0v#Xv_fVEj%JPO@5!P3 zp(S+H--FpWuwLo*^+~@at#(d|r8Nsw7{jH%(;4pC^kpylh3Q3y!Bs&`On-yQKvL?n zepy)2KJC6DB_ru5I+pl{^`w#NiS1d`7v%7F^c2`k2IXhWLdM#~FZusYy>wPBnEe^2 zf>0C{Pshh+l?ZuHO`}E-RTx$s5iHCi50c8 zCI3JT<|`iN6jvBiM-v^eamo>8tIX*K-C00R`kp#T}VeZY& zC1TISnH&q*#Y}lG>tntLlzs|P4C-p-nL_`N3Ls>j^lv*cK!VSP9?vevfNb%@-DRha z`<#0UBJ%z_MaLW~y(~3p^Xu>E+$ocp=q8ERKagh5yEC31fj@>4swqPi?8<{7H?I0q z{AqfaEVAaaVE)irpi!2X9+YM?5*M-hv%ZI#8z~M*%dge&0*q(&Z5|X;>mW8dl|y@q zr%mGR_u@ucWb)jpI8)(yQoPT;!GT)-lXagE^;vXS@W0-|Wf9T3yGi+!T55eWoZINw zvfcqX*JpGKQ)q!gXGeb|_QUeot(Z5=U$HT;iXm=-Ur}#FLh->%=K(SB+j+BoI(Per zaUU>SNSTDw!*5N1FFZoiusdh=h))s7&X|xq-Y+Fd5g#Ak|6%fC-whPFC!I1&aIPq*N`yRl)L51(74#1Dz zaj%}6V{37m6U{Q1ht=ZHn&4HkpoRuofav=dO3e4GCPkpcRBZP(eilKJdw&V8 zNTe_CeU^jg&swAFC*Wl(j3IL830bsFm@SPMC-BQWRrr_SOk?qj`pA8?)wMA0M;z)~ zQ7r`SrM8aJ&g@qtH`+-r9gl=~F^te4h}vI>v?K-eoeFJ)DnghdW$5Y_M$Jo|vhjUI zH(uuN_S-3+1h=Em<)jNNtRUrRALF&hJDY?93zkCESF7=woFbd?#GJ1-lYtX6{c5sC zaH6XcR(+-bj|Gf(EkVPVSjHrf3W7qEdqc07ZPm$5_scBrT{$Py*Wi8=dZIJ+(1&$~ zWk{dUvwxFCsovJx=Bt^8zDXqqx99tbipdroeku{tV{uZkb)6Q?Tb|6%g2}H5L|7Tv zkTRcPD@xL(kkcX-&1nMRlv<$<2mL3UAlq0vM{x;!Dd)!C5yK=Zy05byk(7G|Y;)qU z`2{w;FPmk)3XJQzw9fcvE3n7v zWcQpK7_6Cjtw!5ry-cHX%^I}ufrhC#B4IkEVWwc!xQ6D$9}#iVtoBrjtvJKGrZC~e zw!2FpLAD~>6eO4R!2p5gqrU^kgI+e@8bkO&e@R7Rg&d_n(GB|%m&={x;N=lvNCr)T zWj4ldISr7I!|DiaagglMyp_Zw^KNR@xSu7c_s;G%2(hY;OpoT%GZPegy(M3BOZ1)^rj#I;w?WNXWT2t(J;6cg{j+$^SG&>!%*+eU1FX!3 z8o>!e?nGPX&aUiaS##P9AU7$RQLSfD9_LH+#}y&q?*ypbCNC+@SpRlfGjWq*Me*N+ z?V%J6mn_%Uoqpta`+8f9_E;QvQ0|M9g4aELcf)Up`@}~&yO37m)-+#1e9sFnKfA5^ zeHKTo#=UvkWdOx1lY;|PImzGUcsbbY>_jw$z+@1xE(F`&T^H@;4T1?mE^K#KZb?L; z2$NPh>t^;)afbq@t8V7{yCNNd_GexfY$4-LtIrY~YTrZ&faNNS0S z3l)C`Rk9ag;3VkT=(h>y;=1&kg0}Z>Wcrh*Sgh*Ym4A3-_xns;EiSb6_vJ`*<4kc! zbQ5rrM|1elL2gFsf6SX8r}nmKBT@e?rUu|9wx}_lqmFw1Dkl-ruY~{V>*SyTjW}oL zNb|!WNuLkOY%Z7vzvl(erovS(`4PC!GcEdq5EPEy~(4&W0duh#8&S!yo zokCf^fgRnTt&HxbH_>`q-15!0Jt=>Xi&FF)=wcj^wTUGR=QsHB{F?Mz0Ej~<7^g$K zC47elb!3#-oa0UAydFIVv2JDrjCK9&SbZh@k*nV8=n|_{C7A-&f6~{{Ke!#)4F+L3 zD1ClD_Ib;Y{+ykqk|&7Dsfs5k8q?0eq#z={qq(3(EcV;1f_@Q6V4{1!5<||#7V%}H ztl_`=ljN)2_;}=alM?ZG-Q+)zHrThus8p)3y`?R*7O7Pni>Oj zRufJ<&q)$a?OwC6tj)@@lSEprRoSs;M;CU7F4j~B@{qbJ1ZP9~sIa_WyisS`C?W8E z!Jw{#;9DbYDf$Ej@{lefA<(u+63*Q_I?UfC^tQn|eUruLQo@C|>sxR#L!tW3R7PY6 zc1IH!)y&tznbFys%jJh?{e#O>M{GO(EaS9JA1y&a-%SEk4=<`|${=}@!c%!QVzacW z{z+?gKG8JVG?i#IOL>-wf`r{M9dFqWSKs&`l0=emjw+3+@FgUW11EVO*I7jLk%5k4 zSVOI`TH`sEB$a|UZ%Wk9b&`@9S&hL|ud4p)OvP=IJ``^YSt;onGb_!7k;ml$D8=Jp z5;pjGPC~aQ3neTH%13fK2{c2rh5TAtxTocd7US z;Q=))X@)2rL+b}}2UIC3Y>$UdUs^dZ>&YGazH5GZkxuzuFk5cI4A^n=OZ+kjw_=Hq z#7|6G(ImjK^eE1mx1$8VJ=G@v&5QHFfK~<$J#n@ z!OqU&A|hKCH9TmAL%o;P;>i@Tg{=HYbTE}4Z0T(-Q8=D|8Pr?Vdc$Ovyj7Pl#7%{a znQISFiv1enG?ysZ5-43CE!c*2{Gznp_?9Amsz^YWu?B5eJCGY@YAZkC9!_I!LH;obP7--u4$}Y zF5^_JA6kT-VtyK?$1};M0Ez|IYgaU4iCid)^$n9LLEl8SBo6KNpZ_HZ`|)%x=|9{Z zpya9c?S@p&H!@10Zs0rLC+8Oel&Y~RKjoA7te+3jr&ESo^lnPG|5f316BUGr3g#N> zUI;Y*ep=rwq9%%C*>|}@Yc6PmZ5y(L-O_oa0)a2KG#SXn zc>-f1KZGwYjd@+%rl41_JP%Ce5bh20i#9c8+*3WWbS_!F>1b`g4Ys=qqR3u{bF{9- zZ_@oY)pb?|z~0I9-@bG=ABtrhbE9L#xVu}QwfXVfQjwg8E1bB=YPkz$4>_?gqM&%# z!2i(1m4B-U?*_kV!J)?sr2mHeXue1z9-4pX!nx!!J7BB2NQ@Qi83v?z&xgi>-bnGF zJS)daod9g5;cy``G{(=VPgQF%tT6!r;w}+Z!MM7~g^?NHIcB@uI)yQT-c{ z#=bi*b2IsLTt`oq?gf{dp$EyT?DMFqPTyf)=RFoQ5PXDW&Wn*6zmHIKMxSdR502{_ zgWR;wD7e3tGrfWie(K3;D}L+DK#FUQ;(1+l-R8J{4%jHpRIOj(DbU@m`Q6FTVbI+V z{DW}B(1;y1-rNT33sxNv^Y`d-`W$g&X*9BLG^rQXd!3WzwBKX{?zSI35_4`us4vet zjo_hN`)^itzW$&CeSp)1#QMp7bjnPz?;ZTyL*q6Q0emgt52Tj;naIcwUwjrh>K!|> z$$pA0FXc#vQk5HGfDW~d>rF=(=S=KKV4QExiFLMkXZ*{OC*`Otb>7!xl0g>pqEb+V z7HSIaNbnSzOYQi6?mg#f_R&hjsrpWjw_*rw za{HpGyoeEop^lqtR&{6Pqp&@;ZA{5d0ozJ`CD>S7uWqQdh5u0qgKMM7?4-&OJn7Wc zGZNqgc->|QX?tkY=Ca{a(~SDpa~*Ybgn!mU+G;&YO0wVj(7LwiJ~9AY88L8WrL*_a zoxqo1#O&SQui-0HQ7?_ZOah7&f{xjG^qH!pdW#sw-jCMX9U#eefRPXU*ab~L+XgR@ z?bfwJnyl1p8vJZ>$h)w&X(>(GT6KFGtr00>5>}6%;kRG;13h>`VkI;>#phYHEU-vx zjz~YEYk9r+ZM8b(2U)S+?#XH2+;e})qWNqvzO?smsptKa$70*+j!eX^**O`V=&uYR zt&}g?*Sbo-^ujZszud1gry@xBzFZ-<*aBm#=%yuan}&uQHSyHrq#Gp4`PqXQwl-Z` z?-;iaDKU6f#a($DM-rkVgfnhp3a5EDt!rh<+akr*c9cvb<}mic!+@Xd%tUhENO$&^ z>=c{BLH6_dE8Q|-9v4Lv&y?zaLv5}(qG`P;QcwzBieu+FUG>}X&%Zt^#bZ$3;vG6r zK_|0ZEJ{|Y&>GAW9C)+IJ{X}6h(FfTi8ifXHCxKi51K8qvFZOQ_UBeX2x$W_`JzhK>Yxiysz}KYN9NBV5sv3AJFN1%tyZJ{y*;C zDlD#O2^Z`}0|ZELCn2~exRVe3O~_2d zUY#?wukzD47>*E1_l8OH_O1d{m5-J+kZpA9(7WE$V3r}gi9dyiO}4q8zg*d>jSEfX zrG*CZfe`xKqU4jbog3agK8GmRF(i3KaYZz7SCw#uZGYX9(DS%TVM|}GoKuTO;tD}G z(^DQ6Es9&a#6lYT+i5I-4Lt zJAE7bd)X|{fG+1Z-OJ>iG$UJWdSwONpd!)2{#Hg{EqazHHy{V><@kN!8cYEt^p0-X z5$hU`2QYg!`t_P;A8P1I1 zCvSoK{#>#=TMU_70!6(W-cu;$!Q`qv=)rKS>VneeWitCB2HKroaKcN{Z^j(tpW+H zsgTBXsk}gy*5EE~So;m-h?e*dav7JC+FxZCj7h8kb8Mab>z9kcx9asjDsvxbzrwqE z6U#rX9dW7E#)WNMpM{Q<81-7?+g#&7MDFQUzieFL7_>4ec+===M2>cJ_E@vuQH|be z$+QDn^$9~SvYw@ErZl4!SH|+GNmGZ9y#-8WJ%9j8jn!+ORc|B7nv>Ju&55Z2dF`sr z%dgv)U;Aj`f%)SQn?EAU$+7|kpj2k_ZW_;5zg>ek0fr&oo_sGgJn1A2T<17}xVMEu z2{?+M*G_*$qJ?{L*cyb7lz!4c-Jy9l2x6gH73=Kv`ia2zs~I?aD?@e%kUc!3@p` zCr56JlDDv-{r0OJi_0c0*Zrh+h163`W{AiD1^Z1Dim1%``p=KHgs2%z@{iqaXi#$- z2D75HE|_2YN>t$Syx}9*LDN*hWW3oE{=NS0v$b#EjjrLPvX$l z1mV2C)fI2W$&q%#U&gTJIAW-GMYK}vX%I4Au{%CFn?;uIFp3A@$C2K8 zbWNW5S{Q3P&o@Uz6Z0oBaI##jo`!P;qX~qH3)4OAKZ_X_to3q4JgsN4Vo$e#shZn7 zrf{U2cE`nA&0k$Lo&sV#^Tn{9MZRW!p5+dELHU4f)Z4JO$NVW z*T{P3SIM^Hd>&c~@8ivL?hdUrY_jynX-XC$dr34pKt$Cs))2egLY|jdg$gkE?jK{I zN30);(|ny>P<8qyR4*JqCJ9*EuFCQCypZZ#ffu4t4lRBjqeN)X_(efmrvC* zxq5B%<~b`Yw>B+R=xC%c{;k#ZLd(_B!xh84K8=1Dxu@qwh=`VMnc;B2cbkT8o&9%< zVhtazKdoFK2ufG(y4^P0+_Hr_qw+!r8Fj6qnLg~|&Xm7e47%G2Ep+Z+zr@y3y=i5y zr9W)CezIIR_6fOQ(fCZ)j?m)=m-RVv255D881R?faYbO_r+e#*a2g<5S~G^I-*tw*{72ZWw^~vpBkEI z`qY4sqBL1if?%tpAv;w?=3^5YM7%Fx z%ScW+q*4G(ViZyZDwwP@c^6)(>7VU{@;tNLQ3;aghochEFx(ZG7(Ny?7BCT@)`oj~ zd(0aqLV=C9X@LUPf)-~v)scuPh+BcR{&)Xqfdi)n>weOn1dUWP`eND}1-snV5pfA# z;fsEXzvBfu3`)k}YnkptG(1HO*wGHixGb1&#o808%?ApTrkO_>Zf=ADQcu2#K49mqxOWK zHr?=Jkb`CQQ2&M7k}AR7L5T*u7-)*8_u^(;B|T_1^_P{bxq9@k01c@Rf*If|aSz7? zW&7=oME}a5bPlyN>nLI%>5BaUvb3;*hM%~Y&zbzg?&wqa&rjnn&$F?~C%U?}4tNn^ z@CN9fNg8El_*LFD-0!buk7|fQH$$bGn&oZkDG69+t{WLsS%J5*QFs~_C@fwHDRz)zX6 zO_aNuxzaXaZZkcW7rOMG5G*^?Wunp3_rdNntd^N&WTnHg-u!;VdgJ6p_+sVelcK|_ z2geU$o)vWsslIx1wr5$8F7vIk=C6O^kRzF5NHSrkpPckWfU{X1_k|=T&igjr`}wk0 zuSSw@v)K8}>It6?G305NJ+{h-leKS(rrkJeXZQEiUy~2O_lK#+s(rTO=AxX!m=C=O zK{9f35#iw@)W}SJo%+hkvCmQ(`DOPjXJA@Fa#Gx0=db zu@Rw%I*c(5ZSAR?`3|QclatJkt-@gp;_p}84$3fC8{b9SFcPu}Vt6~jrmeU3JgzgD z5jpxOJTE6K%9{#`z;ZJJrN{hwD2!6<>BG-k{m+gLrjrFu9P9UEdiN7ASHg72$~Hw) zyl5s=U)kF5I-bg8t3Mg(gKvdS-Xa2za()`-?A6VJrG-Fvj}IM$y7VrEsuvGbgl{0+ z+PbnoF*T7D-jM=6_7*1%%-g`I5-8+@(b`b-Y5pD+_7-@<^T|wXZRq)=Hz?svg2+in zcDVqaA1~`YQ_spbe=HctMpB9#Yd<2M?nS%=_r0wb64y=GYH#1Lzr8AmD4BC1pW%%E z6Oo?L3-mnwV>+Nj{KAa>8Uu5HR@UD2?%UppkQ5ouv6J+jnHb^86*usc(Qx~j7Pamq zr*X3sSFD%RFz}xVq}_JCoqx5=4FUX$mGJUD?2tu7T5?p&xI#xffd*pKZq8j#z_Lf$H2t#~mF{;XH0?<#F(? zv{6H4o(C*uN1De4sUcyH$Tnocj|P8@|30o15L}xJRb|0tbyC*}x|O=sVT^$kJo&`o*$7*q+tqg_P#J;AA9vHYxnX-KlfXMSMgzY;sxaDwVPDdfFna>J{)^QGl0MHlHZLy z+w+2R#+{UK=FpHbuBoqcCan6{bBHHCHDv-`LAl$U1#ohD=l?W3ASI_Vlp~BvWT808 ze!O|#)#ExeJ(m5`bkS$j`+xjK_#Oay|gZX@%5OLs8P#y9Sib@t6;@kgiSm^&ANm4Y$ zK>Ke(!2cfZ)a5~_U;i&X`h@BqX4TWRwOkCO?ykCHMfithF`Js=`}}iM&ENjVcYT#Z z0C$uA7Xz-&$0*d>Nf%nPd}wfgdS!omm-_S0`=JowZpN`n6&eP{4B2mTQc8FQOI?Yn z0kSR+{leYm{A__{DaHYrM{sCO4!#eHNND=o&9n1OWa^7v_kEld_GpS@LOx>KS7wr) z9{C1i?AHCGq4V)c`N6XE50jX?Y<>l%R2=+IqsM7pVNL>mGjjZ_(Q=brX2GaI#8f8jy_^&mURP|$67mh@ zIiF^mDBF5;9}kpSQ}j|uLedEqQetAdd2#FBvg1RrF5tPJs>+{tmr71fiTOKMa1>ZX zV$fSrUm3m^B>^aMU0&*+8*a{lFm*77+Ni4Gcj`*%5(Cd#q zyS>}Bgr56lbcK-HO@Kwk!*1rXOYePtz6y{j)is&|P{UUgd)F}X-Es^}L~XKbWa_qD zFnCQ8_K{pUzYxK?C59w$PoVBaM@4|?=(FBJHQv{tlqisk5ivN1>bFJ!+$c=h?LWYA zgT~4W<|zEDL0%%W7#&0`H_dHSF~-N%kq{tz zMyC7zLF6MF+(uHtZQH6(`)oN7i0%2h5!}s;Z-ElWc|uClpqR2Slf6u#(QZ`tp=f z`wEwJs3aBA$NqocM=24wwUr1rFmodx7e$`#I-aJQGVepJm!3dD*WLjoV`<>9BW_rg zM!u8XL{g}k>mi$}k6DE3OlZlb>926YjHf9ldf8AV`@9T(>G1+E_gl$FTntqBwkT1| z7}u&?Qii~x3g@3rQvx}(Z zl*S8<;_ad-^p#BnL{w`WO1q#NRb%6{pWko4g}ff0dT7PKa%SIQ@J1QIu5w^#T51C zTW774^o=ph{{QN;;=olw^s7Oy)8 z2lxE#`oq!LkIrf4m7e_IEtR)<-F2!ZK}uFf%?ju1aK>Vm)jxSAYd1DG$1ZRzlkNKgXr<<5!HY#K0&@PD3_>+%^US% zU8Kr|H_~WEy>eNEw+6`|UEWJX?EQ=mGaqx1C5BD-{8bqiMV6A>)NTRsayIQ;ne=*= z##Hr~iW!l+RKOwf8uOX17{ORVNX~1d1_XtEDWh+srJ30YMm&`@D(|t?9Yg_IL)K`0 zKg+EV?{C^6)Ar*XQz3i`UU48O3M!^(F6x{nyfd8Y{z~G<)uZO?R$TS``jBdR$hSd- zy~#UeRGb*|7@nD8K{4ZR;S&$-?ArdpH7@j8yW-(O12uenu0K4V zOFYw#XME>fh|onAkc<;IXS4}(PN%Lqi5hEdrpu%mXU?**sBq{yK9NR|;GHufkCr^I z69P8EBIEwtH#ZiPGg+*S6{JHHZhj(TH|BdSLYr|_B}P-F7Y%)(N)mO<%i)F46=X0I zSHTiG`&IupeZ+CK+c))y5DZ)fw`^43U;92eOAF{rW{Snh@cKfO`(bgV!-C~jesU(C20iY-mH-7dcA7rrNN^Qs4>cQ09vhaG{; zgSeDj>f_jFrZCxm{iyq5k%KxdQa6t`O@MJ_sK{hDX@OU|ZGGUVK@UclA^oI;cNucU z7oYb2VkcxR|mtem-0r74*S3M?&f)SX`#~*kXmMTcn%D8wR2dbma9#j zu;wFyk(~~34iUKtMu$~Nq#!5$Ot5;!MCIq03m2w1;=p!*r-`3^s%DATnw);@G1_IS zBd+IBJ;8JF;|f}7Y3;BaJN}E?;ms$~fP>uaushkC*rX#%|y{&gi=%Mf~9?GgmCV#Q9m=MQg&kz{$ee z26BIV>A6&tW)|)Qv7%b2keUoPp@Q+*7XnRXW%abgnNCzC43JZa`$oG8a%Gg$DnU07 zZbJ&nAO84#`FOw(ZXIesky}bPAnKjHR2}Kqun-%s#jUedKwQ*tZCpep6j1$j4@cF` zuw{PQsb#dj_HE<5{_6^HmS15`j5$) zWeBE14Vy>}g>knhaN^@mR9H9^bDK{wl+xOU_X?O26^9~KDn09R3>1d*70k4IiSf*< z-wxJxB@JpG9m_2rD6n${TOwIa^;VlFw~%SYGZjVm$-w|9p-qiu5iP#)Skw-QB`uf5 z#tMOFi2S~@7OEo@S2~1kQt;D!44!8AAHu6ruD9D3!HGVhmmD{ac&PDnU%`73=?z|3W^X0;WUZ8&G#^-6oQYYpCr(*e<4Gydx@r|m>PjwqCR&x()F}K?EU!SaQbpc$ za+G2I@>1(evMtGk8EZro7#9!qbuL96Bg1?6yc~LL-#T7SKOcXGM218GxQC(jnb(*z zPPXaYFg}1tg{MRNe0Qy~W`|KqnVC~aQsWi7RIK6M+-rCgZwOiEi0${(Fbc99LyiK< z8pe|8IX}%p0OF&`qdQAa0Vf4{Xo_QUFuCI%#qXq2P9!GZ(eHtyE2s)%s%skk82WA@ z3p3_A7L6_ANDWFXC5i@mmZoCpQtPs*a*+$IAu`cz`#MF~GbKvg#+988^bI)@@igCj z^GeCBK<>}!P$~WV&bl4iHMbgFP4N-zef##ldf+Z-6XK)g>$OIbCGCk^P$3ztwAql4 ziFr>iKFXshSx*G!Sa{Q<^Al_%+^#-C$Q75b{D4%4k7>*b@$MKTReQ}Xg>MBja~Cp~ z*k$!tz~(&-fZ)cZarsi$B2=S?fzrktcidmJtK^sWWxA9Vb)d#LD5}35=X%-^PJGVI^ml8GpY}6sC zU0J7bZ;ES_gYB7TmCE$aa@80Z0pg@5j{F<-V{U73A@6sPpJk=qPtYr z+(46rW{wcwUr^bZ(YzEwzY*y@HBbnu?-i6B#nsxpWudsd^q@(WWej9ekE$$S_?8s& z+su(Ugu}4;Pri2~s!x0~>I#S`YZsZgU%i*T9(5OZjB>0{h>5R`u&s%>%QVe7bgno4 zE#I;vIT5%h74D|9|EUS*hWh{{1CdD&N+Ye&(!erRtxCG@9`w)u7#mJ{ZJdPm6v4&! zx8+!^ft`4$2DbKWvY-+Y_&qfW9aY6X|KjQUJyOfCHf~l6giky*;+8#(VQ`5guv7d% zDr78u?@P6pZS(i}vcU-LaErl@c-Ba&nm4MXk{ZBx#|sLOVZ4BXDP!U`uvwGKdX9*@ zc^WN$G9xsBn}QpOmC(4v6Cb|q!|@jIcG)GG<%xyHUmvPg&bZ`AlTGE7!>ba$ z8f`d9c(XXRMGoh%P+)(bOhi%KRDd@4HqPrI1^7Bp#C`C9N&iJnGx@tV^M3nA6g_nPcmsadoD@LxF|AOM^;;@0O4oqooYO#sU$Y6zCtp4^A z@xu?1AD~!<$KX^lv5#0zfc3lD1~RBl;@0D}-4?HBqO}}t8wi_~7`(n5IHr7@)-OPO zAgEJOO}hVrzjuI&{!mTTidVsG%=Jjy?YCWK-eZ?+ftjVIb{u2jOEQMwOyH(srFP>k zn59+DDoI#50){{++L}ls5*gi?nW4_Sb9%>bAhEiP5isOKpt|@`!K(+e@QWA`t>>C* z+Z&bz&n)fP>l8{GaA5j-q2_{PkGq=R;rqdk4J0V90;&b+Sdo zeqh*|BH9=NXHaMSEI~D_d*)e{is>H~hTnvwa&~4GNU9shJyL=UI*hmy=)jDpS!P;As&n#atP`np^H`&^aZ-(NPlkU;sQ8@UI1% z^cG+_kGp&U>5cTHCCfyp%8?%*wx%Kn$b&ykS|C?~^L4wU)Ljck1(6ZH zL0vLPq-ts?b)~C?ert0#@3rRlxC%z%ev6|JFgXstHHwhd(C{*vfFrg>)lOpV>mwxz zp%I|CM&+!V%Y;^-0b=bFqfhiNEIGt!LTg%X0Kj>{iW4>pnJX*MtA!e9jvkpbG07RI z$}bMg)FnU6e`e{p&a&c~g9GO>ZsD+S%(T!^d7?qxlDSPvCz~}`QKWH2#=Z<3 z!&gWmnrQWNf_Cv29(Y`vUQNy6m1*YDJ7eaUC*MYNE$~?8!YeQbyi$sXh3G^?1%)Hx z02lOE^RwROoHhQ??_!?7_?HQ}Ux&4CNk@kOHROvmgG+M&x7YTsdSC1Bf1J%NdAHnL ze7B5Mud(_gihxE97-DlAXWw>=N%HibZ2t|ZZ~BbHm=jQBdL+D_pnL($IR^tj62ud? z7EdZvX^b{mNBI@^swb1(XdcKv1>PA(lN5GnO&8+jR&50A#ntjHND97Ul)7?$NOlJ2Oy)H)qe;Rg-%cuXlmY*(_ zN4duhTzt(|w2K$VYLWS4hrTnr)g7&r97@ z?LY}TjsD9bm8l@DEBClG$&+}h$5kknxbdZa1Le3MBp5+E_pDGRL0`R>$S&D z^No&DXWOjt4GZHM*&EP{S9zA5>{fBZ9oq0Z@R>@aqcQb!M;+D`&~~d}M5RbFiE=jqDY+EJ zQ4X!ayS$ZtIWaiTay(On}r_!T`nl1P2&4%9bYE%NiOcC(?h{m-(`7-b53ob{}Gd> zZC?e@71_vJM*JlPob|a-tM76mGrYRRS{IWYrs>MlLHcQMF-w4z*q6?XC#3&rs*B9WLF>QVPr{CmpHy8{Edk;6P+KYFcop$wn+Z7pfWRexksdjvl#fr{gggV7p-&A+l7nEoI z*!zI? znWp;r)sqxE_(9yqT*_p^j4NlIy2J}wW=rR<>dO~Fin$D$()Bsj1jUNAN~X=mkk!uP zyBM(-0rJ#~J;vNW7|Wdf$=+9WuOQYk0!t;cMv!j4)dz)RVqMjpuxmn!T&-!nFbS2b zqF=?biOJ#p$4E>(11$Loi}jE%T?IM< z>3LC~zTQ(;j^52mu6h@>J}%QtaS&@&O~bJ&Sm|?UNfM6gHl-5-&TS1_p}N|!f{eHv>lP;ya1K$ccw*Ju4)$5K{(IN-!O z+zq{&QH-;)VFFx>V_rsH2fFzh1I_t5)3D zS2J3@%krq~YU~^rk}uyxx@#X59RtR$oEoQgLI6-H~JHlb z1O3yo$yXNi;;}7_#Z!B}!`#Ve@0OHyv(lLG)j4h_1PG(s9x@3Os1Lf6q+j|6Bq1zH z$LIEcIduS{O1Gt2_{jR$#n_5eE^t?90Slhto<86nz1td9HIXC_3jq~WRrnwH=z1{y z_qQS%9;pw21K1%aH}C*cNNNue-&rLbj_wddYQDfhr-nT#N5C%d-UpE&cil;+x-F1h zKpO2TC#XgmBw(ey>Tc{%EWQt{FOiqG_|7x-ZY!W~84e9qJJFqHmE5QV=%#a5{EXFD z%h8?6Js4FrAi#pp+x!wRhOme}WXAOa-oPH`W-blxi~Y>=rdJn zsoe|f8?86CPV(o5L*1@!SWz$PElV=sKoc5x62ElyOW@wcvgU2!xjS8DwMzT71MvbS z;*Tr7!|C`zmF=VIc=bLCNUK5_mo>5~B6d+A5y_v{87uR`j*5fEPx9(P8w=I?R#v{gS^RVs{bFh z*Yi;BtI?^8Tckb_0a{dexi`KqrSl~rIxW#^aOGWhW*9;dL%hA z*OoP9{iTYKklU8OnILx-l;_Gyz=`w?n#+r4|E~2mj8u5}$nVU&M|`K1!*cu2uNfA3 zfeGj66>04Yz)6-grY|!4h6u)cPP?^9AQMUOEY&^UYlGC3dsPwv_JYM_+f zx+HMEm;&Fhj}iB8qqUs-uW{y{h=V1Csk}^{pCb>f+K1xgDT7RQo~Xpja6LZX#~%qJ zA1o-Ji%zyM1idNdd`Ae@q;bPRa8lkhLK*SWTdoPfeG~ei3wl{9oR?r4S|#MDA1*6) z0YKmd&vWtYo%>nX5l3PAdh`a%2uAv#5pR)RCXHGPlne&9vXl^>Heevw5M3WR&8GCr z&$46xJ|xFWmAsZTCbt3XBEId)yL71wdEa<*!8t)>Pf(1^xHW*Zb7B0uMtGPj4`Y*o zKL%j9MDa=X`$?f=!#B{YQJe|sr2vh%#@oT)##|-WN5df@oN~RxgN z;Dh$Fn$jm*N+)W_6`!QaEjY#%#KL6oL|(YBeN)nBF1J?N7uGiVSf1auM@4Mej*Pzc zz0Lr*^!2cd+2Qkzxi$e5q{%08;}7q$LMtS!5o<5(3FXOm?W=0cvd|?yj}uz{?w-ug zyBDTk`XS$zt1u6Y4J$0zo50tr$Ag24F4lJ{e}15+1z#)cF@0&aEfK6-doS6!e*{7+ zyQSwXi>=@#>OMGMPIy#es{*8J@u7-ELyaVO=09?|%$^3FX8lIYwDd}STjmqh`0{V+&(ZZ6Nv>k(A(b{gaa z9E(NMYcw9@Px&EU+j9j2KJw_;hI5*=a`srPaoctJi>xPT&?;%%;}MV1S&zZf`{gQl z{r|RKsOY?qOrL)Z%KXMZEOoW1PoVsF-Z&=mwTer{T2r@X647VK#8&A7hLeL~#BHK_ zLGgzMc-C)M^ka4{eCbsx?{q2zRLpI zU=gkXk+q-dmJgkrcLMb1nkJ2{)gAL4-P^R>q1}!2SFQ3*UJuemAl>tv2a@mD$zAF^6~81o zhLZfb_#w;4q-TABVIiCLX+8vw0JKj-1#oF5hb+CdTh7a0MX;2sx` zStUMUEM!WwkQmbci~4>qV?;Pb{aN4L0ccX7cTmr=Kl$*;?}OC27u~=p=C!ePv1>nz zN+P@azV-(|P)(=xYi*$!Va@?~e%;TGmv!UDZsau0@CeO~#70Yp|6{0(gx{0@Aj?iP z?OUynp6`9N>Dkah5+S-HG|oPldJ^R_`D6x_pcS%ZStgx7DjDLAS+m)=*$M2m1*O8F zJ4)KsA142{i&iav*UW?+`+c6wJp|mMlLfra->x$#;oV+;D;=RzNLd44J0#jVCaVz|%@I zVY}$(Bfl57k8Fb|*vo?v<8~q!A6>jU_rvszwc^~eI7rsStyZW zO@cY<1E^Bm{9>e?5JH-Jy(0W@FRF5@M~;`Ht7q<$7Wl^9+4gm~{KDoR!@oQ~zq@?( z_m3{U4pEWrKK_GtkF$mir0?S3%}`0KluMmSUQRzu{!*hZ=vA?GHKe>mqLXi7;pf0S zP4V7_JUz>K*f+T^ZSYx2RDSYu*VV}+$cxr5UVG#?MH>F#6d$rD+|`#Tovn#C7Rf^H zENJgBTK13?mW^Ayq)q^DUTkW7hs&{(rcc)tsJ!OC>_C@XU~-|%pU=28XOx94YX~ql zWwoQZ_5hsHsF2!~NwwH_eWnO5vu?fSb({{a(v&3uO0NlyakePqB*r^_EGOE>LbR)83d+wHVEYNM0xpCzbCn;2SAGX*(Dn)4*HqF+f z94pO70w^eW3f{4jn}b1P5)%IzO^B4qjP`1iviqA1?o zm|aiIoYR?%Rw=6*b{i?##pIQySsHNI*8qf$$K^Kr0p((jh;qAHqhQy%_rF}`JwBM8 z+9%L7YL*t2n~sN?vwm6`K|@7zC%&G6t;)~0*_f{PYyZ_K0woLeK;-k*WG!j!Dl2Sz zM`}&e$EezyByug3c;yOAmV6w##pE=WOK5CWHxxS35DUpX8A?DKA8E~h_3Hi}@qrsd zD@f9Rj(9ERqxCtWTYg`Mu4MdX9KXUDPhOxbUBls%_pt*nz`0F6K}2@o;f+hnO1M~b z9s!0-wV+S6*oXl$Ycw$;JufA}FMqkZl*RG)vtb@-@g{uK&YcXv*3cIY`K=BG-TCj8~p_e5t9UbXf14 zPu}aeDChHGjoDg@C_Oy(V7j}`3U5Z&^FyvtbesfPHf9x&8;=@`{K88?u*3Qr_p0E^00|*=}1|3j)z_F z-Bes_?Po20YYFq9h^v{HbAa}nZLU0Y%`u0cE0rXBCdPe$Z!pJA`#K;01#WcwXqqoV zgHk{-Q z9)r#!3NHku(aOIR=Y(p)$8xiXppL-(bX?=7SxcbV08%{r?Uwb;4()T2j(>8y$&K*& znYVC(zO`n$xCmSHlt9K+3`k3paD_fnc`iy zyvVlqU4_#uRyX_WZgyejZQ#G3`re-xEA~MD4TYT`hW?*ph7>;Vrwqub{(IB^bwB`t z_}}Bsen+o<{Cm+i%>Vhl|LeE?_l_rbz>aA0;}^6rSkT|*n#=f~&{ErjcC9|qvlYu* z)gsUYYm%FV3}1)1(}XNMRX9Y!J6Q1$qKr3^DfGf1jF)-d!H<&BlX*!S0R-T#VX&`x zwIkO9d}wSCmP(|{O5mE5tZ~e=TlCTEHN5MEu2_VtCIXY!a3l)aDZ^cW5U2ZV?Lgto zo-Nus`j^rkawA4MSLAw3WF>@Is2TvucM1sG(0exBe`-He=F>9G$^#@oJ!7wHr$hlX z>}44O2FUh#?h=}4xR<5_T9qN8JQBDwXJRxB-0&zbqHfG2DNw?3^^6xd3L}+K_Sbcb zvK6Zv-cfF!-iAtXIrp^Va9L@kBc)CyzE1EgNt!LKTmRR+Q;EvWk4uZIDld8Rs)z0)sV&V&U%qaNqF>QbX;oxv!reEb` zB_0%3KT?D*=~?S$R-;c;MB{58j%Q=IHzu*?S$9B! zSq=C&vy}4Fi+X>Pu0-~-P#NLA22g&B&auW=Y@Ros=?knRpu#{IT(D&YU;5;F)O9)P zxge-Q{Y4n&tMVajDl8_4rI+s`YtbM9-_kF}vmd!z1vq9xbcyQRCb1zaPmDV<>gDeG zSa<@;@OkLF2?`IXmUwZES1lN!iMP|NVy`s5ddnV_x#Sp1_GXG-Ko9WqF(9i3#ArD? zn$Y4k?rS5Fn9ceUpPEhDglx6JB0mK~q`$+&hZX7o^v>m0f8#pV#tK>`sylMzX>bMB z?@3DZn}=K@4ewW5tyl=-V`iv^zd}9^iLy&8>3>au&dn>^B52`7N#W1V*dHlGyiw)ab0#h{njf$V-T`03X!R z*gcgfNSQs`w!et;$2V@@-L$MS_}Ap*F0PDhM`i-6*9<7gRHFCPIbVO#J!6CHQ~#o% zGa0Y=LP?8--vvsP>e$HL{m_yyB`6VUrZC*cMZ-}i|Hszv>oiptv%os4nzf|fpvG^H zWD~-{rVp5hq5dd?>k=CQ{kU}X1~7fo2@ljrY&I4LO&M`s4!T*D0>LXy2oXP;I)1H`1t0JCE#P1T?4dh#&Bf zT&XLK;srV_d4zxYh17J@wEOo-p=i&Fv~`&r?d*+!yHJbYo? zZ((30pa`dMX)&rMK7+>X$a;H+=8m3@u+;Pn#V4|K<#+@B^`w#LDv(SfA~(fRa{qXZoFjHm&oBA0|M4CA%wal8TNopMG<1=OKjE>EI*! zxtd`Q&ky=UtC{-qBcGSV3;j|oQQ`BfeciO*CwUSMk|znR7~$1`&ir5Ju|$ii zV!1a-)qqO21ntI~G#!(V3e9c?~Oas-*n~Ii_?4+37&qA>+y2OnOw(w%Si$GePb}$VVZ|Bz5bKCjzw5 z;9@){OtK4{c8Y<_Mb95s$2xrEWuZ}R+r9p+%9v?C!L>2Eqfy1a%~<+cvY0N808a8% zYItRY)05qyn3GrJt^xbP%{c7pBEY(NtRuhE6zyF-`oi^`leO4`6D!|c$7-y1eXn>? z1^$w$OZ9B?vMu=RFU=KCl9oUQc~Do7+g$W5yC%zU zXwi?`5~12eycILFPOA5BdV>5DA-bSQgrwT#R~7Y`=R>;+7~xT~`8OXX~C4K|@-mOgp$herRKN0w7+5ZxMmoG(=$RGNwAWGH6G zLO&-mm%pqqJT;GY`Ww07UT_Y7=^&98u`@|RX=WzhPIV{%8XE@q5Y>df_4xck7pa)-t+B=EM942q8kxB zcJ+N6)z#1`3O5=st0cyU%6@(M*8-W~CmR;oKY}lte)@Gb0{N*SBpHEKeHT8~g zaz1&~qR9DPmYNSbO=$52=y;b&~)2JgnO!U(^ zQLEyFh?CNm8EV|crEy=N$Mk3Os)ttJtqobmJv{pCFSpnsG$I_ksCX^SQ|+BdB3}6= z=2%(NQxP3SSq$GV_fxILt{TANSuBk3uNxIWGQ-PGl zvggdA)(9f` zHIXS8>T)$n4?UI2^)^a}cWw1{NoENw>F>2>Dj4QvXRKEj4QHy}48&y-Rvh#?Af30a z>(Wyy{No${!8PYj3eL(+T=Gt$y4-XWl#|qQ@GC}^x{%gkmI~=sh!rbjKAJ`X7x5rV zN$MEXSM%cHEMEJ3NC=+VG9~;jtMH}|jag^>un;4~P8@4Y2$tx$OEq9sO zmbxj?<>?)BWeioj#IA8ENP~H~<&m6Owr|ZXy|~VH(FMiiS2Haeh=SRdFki{5jvu^&ArUYJ$O#FqoFJ7trC!+~R3UdX$Cp)&m9%g9t?->pJ z)>DVxf3+n+>%6BaLBan%=sz0fBY(V~evzj0uiPe3_UHfh*#9{BKN|eGe87{K+h-eQ zC=72Cjc1h7=F-HaW&OQIeF?WB4f`|^eOnK@IT%LeVX~3eekt@L#Bz{m=OtOL-Oho z;UQV|!HPeFmS~OEckhs*+_64b(->AGRGL(b!GJrGKVRAhT4(xj7GHmzn_s5(SeRfn z3?&IddVtm;@hg4Vw?KVx4_W5{dRTECboRTIg?xnxnTiy)^DORbHC702h%vxuL(%x6 z%!Bj4e(Eq?>f_)Q9a_hhPO11;hJ`|J^&$r(T}5Z^k|`dIy}!9WBn~BDwmKWz09hS>=g@VOqWu zNGT!XG=&ySgIJZel+=`Ab-Gs^A*k+`<6Q`N$)X*Y=F3St=v=2fP8a(51YR*a#HCjQ zh1CeS(d5@jxtD2t+0N%ueu90Wn0V(5~P#lLGHN2fCpY?NyS zok2cJX1{|v!XAJ9tz2=)W~(SlNkd+W0IQc7g(bZJ%Z3VQSV`~{+eB*!l~8C}K1H7g zuWqSd+Z?fqyI4EN6uGE#4BV&6)@57|EU%V>IIlXzb3MF($E}_n;O3T*r1mw>r9Lq^ z0PA6T`nno$t&a<4-4VPNimH9Cjm`O%#` zhv$#P-sMBG8E4%7HRI4xSihD1Ib;4iO*iMF;C|M?-ibXUX;99lG(C}6bQ3{JwdWyx z*b2EMTXg9Jw_f|(f=l(_NW(wSU)IFq5x2>!M0auDH~;=}uoDN&1rTqPX~@t!Ha)U za)BFlurvLNox{Dx`E~76Mo72{;@_DXxNF@p`5cGu@>3feD+U$?PL@e5rZ=fl{@`my zN>vEH`z&;q<}-{680u@z_AfjiuyZ+PrvIYaMq`s~#{B=B`ns;B?l!urIF_)#q0$YJ zW4U5>I>mjPr!Y++GWj|mV_7*jqVMNeKkrD|Ws}YFlmMS>E4VZCO>gWmzhHHo+O!#A*p-|tA?knn17@lf?C{I#;g}B zs@$@Vzj3oQyfbWU!f@-PSzwHgya#4@!lVoR9ZKl9CR{2)9>LXz{A|WkI0q{s^gBzY z@IKE+(4*Bd3R?|DaaUSfxYXC3%!+p3CVx#8)dYD+;z|87CP5U1rLT>lkBT>OWj80c z7KjM&WMViTgOkR|3LF2jqVTW-X-&yMYu&+CA@W#7y=vhF|D!%O(3?x#Ar5)u z4*ORy)6wujbpaV%(Ri*~XqJ7Z^PJcZHdTiZjE8*X?Q-!=E+I2^1_*q@QaT#jBN&!kvc`?>l&HoPT6Um|_z-?Ye;^Ee`|zxt|QR~Cu= zmRb|oc0zxov;C`Spcqj=EBJ?*(Oe~%*t6ZjM_H$W;3%e&kk^D~fs3FzHli$)WTP9u(Nbt^P^h3OwuuSEXv!A!y8fFoT`}QdJ zkVhZIABpuqwOD(YIw;>#?Z$_nQr?zBm+)Y0bK#nDAy_uCrafoi?pi|i%eb6_H1J*^ zT`bcBj<>;>PGZM8<_?J(3$H?tQtLYkiX`IT;oLx`-d$H);(4hzYHg<>i^KrIbw?lD5%taFl_&wizohwJSdboyGHC8WvCSFpb z_8crQ7bT+h(4+p5g^#6ywkdSF^{e^E0n)>vaApEox*@jfydv=a@AP)jtrN`aCYVc? z86IEAMwMz=jtD89wQuD)Y#N#o@=T_ybQ6*YfsNcqzfb-;OkM{%9f-TQ$A2^pI%EcH ze2>T~e0hFdz=KQ|`w~kb5gVdmJLkuu$C(;|-Z0-#RdXsp7)7|~OOKXfh))p~CV!cd ze-4CfMu~P+&i++xN2OhnGaTm>9=~Ox)f+d|>!O|rJxT7RwYTOHmTUTOZNCDU2h}Nf zQm`bGsq}CqoY%u*zgkivj1TV2S?Tm)O>k5%RN+#Llcg!@9%`Wfj?)hB`B%bP@0Dq& zw77MfLi=tTycb-EhHLwCFT{CHhPF_2i1UkjEsT)O57@SEV%B3vrv=r=3`O>d$Bv!s z6odYy@z8&cKy`{>Zj(fFUa>VMt?+NWBKgw3{Y~YfZgW9jCRq-5N}Mp^WAIHhCFL!# z_iJ?}IE+YxNvsX!aU}YJ&@3XKVt6=>Ve9sP@g|BQ*hrss&4qI!p0M)Or=N#cmz&6| zI_mk6Ae*Z0P+;BD?tT zNlh`z&)%X|PufCtBgH?kZg}bwEhtGoufn+VmSzSQ8)g>O)QGnX^BhTuqmEzPu5$@- za?~NV<BBIT4XPcKpZUrDtn$oG6}?F&Q7^v3 z-)|<2Pm9&H%o*bww|Fdtc{>Puk|jSDc|vFCWjQDy9L8RV>3z^McWmmT_f}vT_fit8 z_4eo|*HxEgHSPVy%3&rN{=_0Wj$d;rAzsluu5&4L(#MGF&=`ek4cNY8cR^YkLR2#` zM;_&zCl638I`b4ym=?~3T42s%-9ObYSerh6=YjiU9o^_`Az$V~J(e(pZb;K1i0k;J zIzU*FBVr2x5kXLVq5`}MngjXeMsp>NI&<)9__Fzfg`%~)&;2(x@aYa?1!m&lB?!0RB!d=;NaVdX+0>p zzms4x+&k%s87BP`-K9rIiSwKXIOtR-WGAy{;fxYJk&u+GN>eY3GJ3-M7uLn*8>G=6 z83h!1iPYv$nG|20w%b)3ZT+eTa9*bbhd#_WiA5lX${nJm3b5u571^aO+E6rR=d6Wp%(g!PNoIPEzagFjt^Fw13C<(azi%tg}*nwP8Se+9QI{Ha29^7SDd>})2Kf2wt(+f(s~x&rsCKPbEpLk3Gh$dNCw5_JOrQOT`A>z{Ft2yfkm?uh2tP^CtR}~Y z7?zzL>Hezh-{iQNZkD9N-3q?qgzSv2wB2EsehVfSI(G%eLO5Obg&LCbf=}MipuApg zA>&V}i?CU-mY+*LlU+_q3X$mO=h@8>GjGFE?z``PVG(T)Z|L9abSyiHzi&_03GTNq zVvOARo}3Vjw*+|M`}Y6M>=}czLFH-M8L~QRv&U$9lDzC$%=kUdyaT1}lh_mni9=fc z$y}F@s`(Y5#twV5p4OYkgQA}8W531<@hmmLIVqf3Z{|A}-V)CDkE1)tYfr0o_H8@F zsFjEHa&3Y**uKFI&?2pfpCC|isUsrh5B*@&|7b~tv5Sj?^#~p zMcMO4KEYLcODsF+Uwjwqf6!AI*gNp=Nn-ascg5%bBj5FJhUz~q^M9iuW3?IVz1zCi zV?%E)54!jKn{fYiUFW|@-2|_vJa3wta0yWV@O1n=oc|1pRbUw6|H+0|mOr{4bI%8N zZ}%L}b8D}cn9rTDkEOr5=5ID40QTzc1g z_jo^ySbM+xZhz}-e?GnQj!ZQM*hU>-9zEKh&xh8YyVqW8pSO7sy>EuzKp>vyXY1Fg zF|S+h5eE1z{`cc>3B6x4-X6n>Gl4wZ_OA*a(1iW=xaIxE^9H`Y=5@O^3_}+V(FdgX zwkFTd%Iz;V)~_4ZZ;xxQ_x%7otq$Mq!t+WHOBePM5+&RY0ya@WDSVml z0xUKxa1?^5h=3dj1l|k$<9!4NTGV&)vPezFoccjVC* z5D3vr{{kE;Krj6X8Cf-qvb84~`o`NGIOVaqZq$@b< zYDk81g6V8@1^lZO0|5b{@U+Wi%LDrVmosJx2u{SWa-*$4>IhGF67%mX@*9GliaWb_ zFYa{>5rA;$2fGqVPM>u(9UiK1p3f+psBHuQ#~YQDm(kqJSS-sh7rR+fd}@yl4mPo{ zZ6lJ5Q@V~~zIS3qFF)_9FUBypqJdg3RcSR7*7Q6!x5W+#4(|JWC9uebPlg?4ynxlM zt}*E_A9VlEy&|sg4*Keg3ta@E=vc{_zCZYM?x5J>K%1DDh&a6k2a~1-z+vV!!6iqz z5{_K=hI|zZ-P#Uph=4d}77`E;?R<#5){}MuotKgGaHnmUhf3P_SP~NwVw(@6n)U*n zdD%gx9IP}{=K^Vu%;FUfiUs}ivwrHC2w9tEZLi_o^@%IxZ0SNnW)(x-w7`MrKmAQ` zDP+5nrnq+4sgUsj`Y*}P&;O;IY^L?Ia_ZUtn_4v~w*p3(1y4qDTmQFy(a;xXPg)sv zx$yMU#Als!5yrNZ2%I{mEQ66e_irr)pnS<-|&m~kjsrW34-%F5dEyWq4(`bJc=H8oocTb%e6J>M(?zoW>SiG-YS z>f>7^>dFgAUYUD_d?AZQ7L-mkEvZA^a{L{EnXC64pmb zK-Zu_Xtf0bR9f`x8}bdDqY(u;?&H8nDK-KEwA^IwfayPa&$p|eE<$98j;;klFIKi( z(6}2+L2Xx&!zE+svBdQ$r_Z8irVc)I&iaWBCBxp|sZ3z_dDJ-v`m99nT3X8`Ok6A! zv;4mcn9CM3ifoYq$FI^b-Ut+zRzV>ZUf$#YKxyIyjL~ref=0h{}DH^bB7&+uJNqaYsd;S z&zr?bUurTcX5{+l;6BYTZLixXAq!l+2`1Y$#}tZ-+Whdj$OV|K--$(-iRb*9MrI}^ zAGdFEnlQKCy?}|tv-eoiSi3pcC-6J%@{tTeP|f|$qHx6ON05ty!pfhKzgV1K`LJ|Q zc436{3A46~d8qVt!8;<1DJto}{*a58Xy^9TLC7w@q?)P}9(DTo67uHLM;~C0V+Plk0Xe-JN#(y zVQ|KHUU;i@4{`9N48R!pE`!Gkf298}nQJZ_^A9k2#;T-sHRKA5kC|N=6Q}Md{hSINrY+l-RGmowa!_< z&3D7pm&-hcQA*D(gWL9tafH=CR~}>pZhwKwMS7o?3G?H)C9PU$GBM*2xIJPAnN}xX zJ5%kidtq%`Q0W4wYbHOLZVF3Ej@N(}QKWRGgH2LJ*L~CSD8POw+x8DmQFh~sf!^#g z7spBU6W{K4#CIE~dfBF2c1BP#ay z+55oN!yZ7T7`!2QO6!&XrbkoHh8MvzmNDiBk0mTdIStdY@K{$x`jK+)hD-zpglx32 zD@A9u6_rsXs1(g5fS&`tEc|9>X6E;xImyovup_UHiqJro#;yFD!Pr zJaa$S29>1D0iuSAchzH(YA2)*pU3%b$&Tkab*4N2XP@^{0bIx8%;9g!+{xYj<-*|L zCUGL`$MvBz*|4hPpqGcR-QSkDIe%axTnQ~pRFna;+vYM9sFL?DQ@9i1Ir8oxT^fL~ z(NM@L8uv-nR!C}awiBJW zD90sEBjP!eQ`{o9S}ym2VPj**%+h8Jd^IWJSzv^d0h6#79GgS>&J@1U{H%wtw=L~m zI|Z@c_;VJ1qRPx|Y~Hh3qSj`kOTqc;6}>bu@ABnv?3@K@flI>NQABU394$y&Uf(tu zvm?|cqI=6ceBWV3+xS-KWH5wQbDO)rS*N6Zt9`6DEegAmgtfj^-DP1D>k77k5K59Y z_3U#*B?plMC8MH)@p&yl}gmBZTSsJWU7p&xSZ^Q zmqY|abrN;KK^oXr1iu-E8!)6X3DmQ=Tlyi#r>Tn%hY^Zn+`PWYb|sO;SW6hOx1irC zD2KO22cz6>|DMGubt>$k7N6!DYmj0uVUu2Po?f&U0Kb1)nw`YjEMjEskU;(Th8t@k zF+>_nuGrM=vQOg9JiOq#nJ2jAd9DE2<`kW9R^@zF&WPlAVS$wL1Go)o9m@A^NLe8_ zllleJy83pRJhMVpCya)R+OXRB0+IQSm9Z3LMyQo9p5*I9dSQd%eUd;7{+#( z>N>c*q)IsPr|j}o3D&!fUi5ddH25q8n-zX>g&CzCa0F*~JJU$&7vHOQ!*&byTYsW=_h})3d1ghk$+_^%w8jIs8-= zI>i?2jUFzAvXtzW_Hwc78~w|TM8J3ycHWQ)<)b;q$N$z}DxOs?-wCJ>W*Cq@D%C*) zK~~gBD3U5|^yp-0m7Q8gSH`M&x395#2g)j? z!WOX;e&jDFY=kVYGi`+Tj&O0bTC5x2$O74yspno6f;Ia&=R%;Zrt>1tb_Pv;1qKHG z(2_24r!ND9>d>V|r|OHCcwhhr0kdA>;-KSZKFh%irLd$8V4>UYkld^EFC1*om=}B4 znjKM6{9XO7@I)1x>YCgvi#T`%vg=P2i{F~kGBon?#FIca3!H}5)t+h5%8`SIt-JjR zd7Xb@4Z}m!4Va?SJS;;7xwmEs2*pA%+MnA!Z-t+$VS8(h^A?aVuPCQuJlthAS)NL` zgk2uVBQluWYjXnT132YY;0W0*c@_)<5I~>6waJwQn?^8MnLV!LW-`HjAYYFNgoMdw zJhMc9Ug5!DF@2=Rrw7cto%zLkFnl|@i}zz7r7chwCuAS(5NQbSY_XVSxk84`UaTn> z2Go(tSy?CXlCdWV!u$Gs#}j_0m7A+cm*voN5h9>?hn0A?TfES;b$|OmhQ=>IcCe2| zNa|HHm45Koc>@(Q$9AW4#`v4^aDCJXEnc*`)&`0)6Fw_4`vxD_$ii@}v^dO{66ROS7W+15Zao6)8*&aRkaC0P{<0xu#hRbS zt83LklZ{fND5pl>LeyK~t+fceOri=+`^Pohv0eG%)H1Ov2TaN?wp;XRTYS=c9$PP1 z3-~Q9hcq$2jiXD1oVMSYrqlxo5(N5!Rb|%wOtE<@=RONa_t}!}xd9TkJZ=W7Wu`GvN>THo1VC~K z_Qi?_89{%Da(6<@9e=$#w@6sp(m959$QKCyQouoZJzQhSuOdZH0$8D2s3F)X_#dQ# z!%3`ro0xG}6qNcBQpmYPiI9738`NLh&NK!|7<+QB7_P2ny7(>*b`GPQlR=TUgJ%fCraK(BerSv_sU@=Ep*f6zB zcI#G6#!4rR6m{XEdlf~VFsR9%2n~P%v1DW$*d&3z_}rYy<{K`IUGz5(J1@G{L6cws zb}!su-S;P|0IJe>N0jpd!7LotX7*nGg;^3&+}697LMm4~BzB+f zKGQzlP|JN*{|W4<-1=e?KaMGOKOjyZpOeTTHF1&HW2tV~oADtX|NseKdV;Fm38EJ?c1rL(kcD}99EO=)+ zWeG?`GUQa!U!&klpyb=Ec_xfuYP5Xj1Nro$jttp*-!=)~03yJcM-z%mih<{2U@yTDUN*Ml>IJVa>F7}t$i;Dz?vFGmq&vRyT1)T{3IhZ|r zd>7x|+S@26ul|WnP>Jiv>k=g;hGB2)cY119;p=wVlPSLB# zCfpBx<1lz20?gsm`WL7)?p+vc=ZA-eSGQ$b=&}ZI?^i~e_GPQJW=v(xfZN+Rr$~m- zxQ6!GI22GSwv~1#k(S3!b^LFP1)fwEwH;b#AZn1p(bkNU!$-pRM0?3bbHAmNlR@FS zNw^Uz=5q5Mdg!N}m*n?!Yi!afdbwJ7EK;27QAJ|s8b*yXQ&n|2rq{3wX?>a$Z`j3l zaLB2Vj)MWB!h$pV+hb1KD>lyMwD3HgEs`SPdS}1_Uu*ltn-JfFi%;8NUWz=DbOKP0 z{*kNl%w7GAvZ4~OS(RKMH0Un(g-~Nq(6r63dR_=>*dwrW$S;zKxg(u?*AHU`Q&G<| z<6KM|9LBxqg*)L3O{Y8c9Nk7AG2On06>p<&Y$yO+&8(ubvU0h0t-d{#?7i7{tG>s> z!$ZlPTAW8dq2)e@UuhBj1pR`T3(Yq-?_GDy1-jn1Y7#HqYO0K`#jdQ%@RJdb$ZkMm z=P}^+sp}Qv;fRYW=TG#e+fu&eJ`_ja77G4qXe~O(XR=C>B&ZeS@xSnqd0{F!4X5m! zZ=9gx#Q^iNPVHB}mKKG(@X2s=%5F$d1G7h696_p7_nuNgIesiOJFyRt$L~ohC%7i} z?N8q`;6wnu_HF!H$Hk3#2_R&Y%>dwa?=(<_&)43V9%-|L98hpGM2Kz_ z<9|DYOunr;NcXPOe*gXeIupVE2gJ0(jOA;5d)<`wUaU1n0!_~Z&@`7E81qzDRm-o? ziXm~y-e9_i=@TRvH4%j=X!Ao9gQS+A_l({iOHD!S{0&EiryQ8fln1GUK;V~jNMitG zvrKaDQCR6eAnwv3r4{~lZ_FlZ<5vI*L%n0Z9cBcc$MG^u$IYa;ahZA$S%!d=R8g~_ z>3SQUQH3>E-c6z#2KvPzU3R6-*GRFea%*+a>ao)qVuq?KcYpPP!TlY*7=$^g-V*;C z0qSb#OfjgVIqUh}A+Q|ynl*AgJ@wAcMqz%1UO?;9^Oeh)`@~f2B)2T~{2JlgZ5l;+i{q-- z%|HMNc?2`UR8rpM)kR|apZ0Wzenbs#E;n~TbW_G9LWSoVbsZ9(zmPjZNll6E!~G(Qw9Ge<4$EB_(epK0Y4DY>1__cFk$) zdtRwZj!N6|>PtV*XNrAde9x88w0O|^miP>~vRQL1%q~VShtgtY3H2A26FOpO3X{(z z86rrlq3%UNaXNk05#CcZiZVX!ujqh*SZM}ZZ``x#Mga8Kz%aMTn5nV`YP;Jrj3kv_ zaM=cfhl-@X7A_6|d6FS8d>*^)j*2m8@1<-n#`KuGPOTV>PJcs5H&axSy!3 z8o+#ih&>6Qj*e;9_{q9I!5NyVWrWjZe$>%yJRGU?{?oo}+2$0kkA?=_PbRfAJ`j14 z@tWk2C(*g~8c12*v)T$e2L#|ki1U%0GaXPAQvcQwyC<+__^U<6`09LmN#a=H{yy;; zS{|#<7!o1w8H~kN(^Ytdrx=oSfGBhKh0)VHetW%TN%d}PeY&15BB)**94!})o7z6WLX~n7TI)?j1y%oSen_aG6c!DI!1QnE?_Nok zuRXEzq~-cvs;xju#ab+*QSZ}VQ%UGU+b&E!ShW}9rDol>(8mkQ9$DThfKW7&L(gJ~ z{rc*h>JBUmkl0QqCt<`>SkLzX^ijt$`I`zWeL@x9yh}(CEQpS3`6?AFIQ@{D$rQ-n zgx2IfIfWOLmEmJkd}ipAkws4T!rn{OKjXeZvuaC@)rPHr12F z;hu88&CvX7QzYuS6OJn93(i#!IRbT50qz$P%@hq_7!!oX9fEnpioPI}5 zlOs7Xt(tudleV@Y_Q)xX7A8&r_(a~i>X#pAH^ksT+la$x+;5qQG*7yJN_y+K`edb_ zz&IyKp{~sg@3f8w$J?!Oa0;_O;?ulM^sG1fJ;4bRl9SCZza%m#?d4)`TM0sDqu~zV z)ROAsm45v0AZ~vV;#|+H3!56{SECFrR@+e~+Zhl1!9K+@)U}5BGNq6t07qg}>g9{Y z()Q1%KAmZ2#g1lRG}e1^y4H4inGn9%Kw^|LXn}TCMMeercP!c^=;n279&GB1AG780 zYhL=ck^C^3)Jqqsnpc6^>TL)W426O_UP%E~GU*nH?mSE}IQi;6+O}z7=mj<be!zoTwt}!W<(7FrcE2G)l!;Nr_MO zRI-?u3+)m8*d=?2RloEYfNB5RLBc?<^AZy0WVZP@gFnQ1!K$xja+uH@MeI20IErhr z7TIWjvaY z{z~{D<&^sTT~y&6Wq=07l`J?&2RQ32`6O&$lli~&=P+-7L1j1}w_?=$hB>UDG4SY4 zMbUYC(s0bc^c}pz+8gfc`FZ#FJ#a(ja9 z9Wh|ND51hA9;;oGU$uyBpC3tF+J2{`#OBJVYguN?`KELU-b0YxT{+OZ({q}hfe2n> z)r}id!tM6f3P~z3ukt$ga~(R%I=VSl_xyJ)Kn9)HU8rLLW#wR~>lGk(Mq_o(#l^Nu zmf>gz`!b2o-Nm=-Jypq@St$4oqyP+EYs8S{U}6#UgHSU z;v~`LH0)u*Vzd)_sVB=V%x0V-BSf#s?cK(8F)V1fb|m$}!4b79bXa4-{*MIP2(DeCL0$Miw#qL@boe&zFTYc1`d8S~b2 z1T!m(OR%5W{Qrdyue8eFUlQi#*$$@PmiS~!IAYC>9;&dFDuep@9*0iSmDxGZuA4p} zis7CnsB6coYu8pWT`l{qyF$HIU-2XETytOVx8L_3M|nzcxS@f(Zi-J=S9j065~B$< zTc#6g_e5kZo(mySzbdmp3FasUm zMk;Vk#uR6pdBiQ>HB2n{02GWnyI?Kj~hx>)GKQ{9o zS#UxZX`UaxfT0K3`dDVU89IZ zSGLyBb{M3BSv*)$UU=cE9H&222LL7jTlO@ObrEvb)IC7#|n3UeG)A>#MC>k?}0GuU+gwG$G3V=Wi1I% zQ&10-EesCMm!;uue$Qk1YIDnEd&_iF2e*C{T^qCw7gX{>ZKspm8;$=Eq`X6*Rcn`~ zB3q)ts!ny)$B}zpQhk0s)$nY`!~)SV=Jnz0`T9@X+$0}j8GvKKpqfxz?wp~Ul57)) z*RmGs0s*T2@N#!iN(K>BK!%lF#F?hp^6X!XIs8`_X&bdVLtw#E^)iK0v2<6ppayXsn zlBW)bUpu|XFGc-2JSqsFvENHp?({V1rDfd0lIHCNX1@bpktvDPd0t9YBp)=U+^H56 z_0mr6EiT`@9GaNaTicA}kWmbfpV1j_xDY;1<`LrH2hkA;Ki|JBiYn1$h7`V5JfGSN znf$%EM_Z4o-^Xfq*d-oD#dW}L^_9o3^o2zf3Fiq41>kkV%BC_2OOsgOewc^@eWR#> zs%s|k)-@?_Pbfy)!EnZ5mwG$Pf_nv(AyNAMpmkv$zpV8j9)p~uFZiqaPPgbAtBrDo zNg~2Bgj?M`+W?#@8>-IJsX)(*dq7$3veUy5=EWvelA5c5Jn!9EsvM${ z1FEpX^E!tR3XOAb)+}=$4u07Lr2Khl$Ky&=`RyqNc$%eueH1b&8=lN8FRq8Z<0ZQ; zU;tL{Ga6~&sb8U<9`HQobc=6)mGI!U4{r{4mwTMK&$%?IoxFHIV0yeg0iSmzCYj|i zZSj%-w<)+kki=G2me9`YNk}XOTm-YAiX1!hMZBVz>O~HDfNuI<34Jvl`cX2s@qGb_ zWAg-B+$w-xJ|Rm`9p<>cY`xQpU0T9eI(dD@w8y_E=oE=2lx{Wjd~9qAO1=ri%;*OTZ z>!PFG>RU!OO*#!j8>}ba0n8Soceqm!n2u7}{X|5|I&*HZXcF1HBb)|OtyW|q`oifoha#B%UU40r|)RDFiee6txdsaFp42un5rhq>& z>CerGv`Y+I<>qY;j&U4?_{T-i+lfawn&d=bim$v3#!k{BINi zbX3y>2{%C_Pe&CxMdTTPwNoFa)`=FJ{D+t-&TVG$D2p>h6)+9FLCv>p=%vRZV(1B@ z-7G2|U%*;&Km4iv)`_qdeG$`rZ6V984xG+bF9PrE%7~o_gicT9Ck(@5RLaU3Lj>fx z^`a^~ofjcfN}8H01QZ`ijc20d@l7or?4EaM8y?LZ9KjlHqt7&%lwXd>+U1vswYk4R zYelV_l$W?l&bAmCvQ^k6$Z@O3jmmMh5MCV|!EPirpU}z1(0;?9m-v)R@XkC7h6-5y zKwS()cgop6{qU>y;Pkh~pyb+vl(j++4Yr*3JS?KhNEbopEyV0C#5mg3GuCF;g4lzF z>|cg3iTjUOUvZJPJDoz;G`GpCixI4VGtZoc_K0~1p#_{$dH*iZa!`DXtR6p z5Ri0SlYPpWs_VG;3fJ9bm9c!nSo}ChHE0~>3Nc94)IEPvjp(c|#hu{JmIMYWulw8H zVwk9_MX$|fjZ%^-5*H0nLm|CMSh*$e(pN;I+@dO4#d;8BxzyWoJu85?fZu5ZCRG@W^6&rhuHyfr~^d7)79Gf~vN6IxGM zUw;l#sXbpxmk;r@S|NC>{|Wf>_3g!UYmepVq0H9pJL-6bcKxIMe1BpQ)M@NmYA`7c z5D4hG_845G->naj*{(P`<=oeM|IAufU&D6mK3K@oi!M;fxfVJO3p{4GfC|zmasBhl z7XZL%QnDq6_%emj+yvUpQ8YPoxPpW3=6|AI95zhzJ|O^T ztv+dS$ax&8%b+yb2$Mb) z;6s9~?x|@jpzlrdg3|%4-_ly8_m{cU!c@ixQ$KQ`CMUJ-wTDi_;d8M(r`Vj5^|#fA z%z@RLlcL@f$6QbgP-3MxJ5x?g9kC`NYJ1TOAR{ejo*yAWI$J{Iux+=s(aVY;7Agg& zr;-9!z2+ab>E}U)!ZsovpSxmA5dO}B0)-I3wwq6|Vof2yg)^b$xw_~t%y1Fl6oE`| z0bp(ydX5N@(@1wiwvV*A>?MX6J)6yN!jzY;uvRx?^18X>2(^gzIAeAv#ZN?#;lVrR z+7Sgi0}+TC%@3$-Z9}TEWdlzHb2nscx)%nG#T5bioEPaGbcmL0TLknMebgfOqCPj* z(yKvS&bgm-hCs>px?|=nDIg&Cc5_Bk{JT67py9%0of#HNRMVjeQg0f^LTo;R+Aibu zEiLgf?t4T|*>M^?z1E~Y5xrf&{rN~P=ZpKL-zpA;D{v8gf}P0BSl|f0I1Ra!G0REt zdNdfjR!TE^9EaCh0ROmSykJA2)FViBo$fNtC>?*qISERNaZPudLo(4UvTQz+G7BGu zJ>z1>A71)cwAFieqka`W>aa6diXVk`L!etXT|{{meTSsha|)|1uWyrq76>nanh=XP z3>yErFdSK-6$X$7MOa-_IeOP%m zX0~R0`ZG9|G zJ5s8}VL=oTP+ZoP@#+uU)FN(ET-z^8XQfHOd5F|UgUl{X&x_aMj1>lwkk!d!b^9Jt z%>2hAQ8(u%NEafgd1u249&ct`QQ{_;4=E3!048k{W6ishbD5gjl~dxQ&P^j#H}N2D zirPBC44YS`kG==cn@t2H;VEmc4mq^PB_WgrbbYUOQ}uqh@`M zMGss2zg0YH?8I_b|74gZZqZ`9f|S)u_dr2M55D#+D=+FwbIz;b*C(-nkHD@(l`}9l zVM1!KDZ1~x!6nQcW`enb)E*WHX*^{IsI!IxQVzKiO*p~MJ)Vq1E0PTP?h*}pO3cr4 zM99n&--jQ{PQcif56VVG?OkW|HKS9!@m+V)%1og~!^UV^?pq3Dje##sa010-D7UM3 zdQ0DzJ*x32P8%RX{l+|LW>&CynnJM_^n|_xird{~A2EBEQJ=L7)7X`%m+LH-O7W=2 zzt{e<$vhR4M`2sB_mH@hq4w)8BZE6A+K*v4$At?uqVcX3Nxh!$?5W4|>E!-ET7EGz zgiqe)fzxn7Vgpx(B9k&{6XQ%f?xCN+`|tCZb}Mp-nvr&D=;zt=`li>K?!?7NWRkSU z2ZZD|3Na*(e5tgQLoJy+^@dO4iJQ^FI;x=a{p=(zoS}r=CiOxxpD?kw-~i{vTvJ|U z8E)amBRk9EgkdqZshFUsfZNuUm*$h8HSS{qrX77XyETrL2;rXyL2jOgo#2A@juzKh5f+kSIzbaNqNO1|Ub@j2C!dh3}##CRvd`jQ*Ttal_b$ zi73=*8$U;Ue+oZCr$9jehB(7V5E8C(ItZy+QIqwxck`WkkGz(r?MuvG&PR zbGURavb|8lsmm$`tLdlR-<5`Nvn7>8z4_cwf}Q<5>4#Pml*LYVI~>2_ua6rN>>F{ zepx}${g`xy{p$0w!ksz1#Y!l%xlRh`3naeR=la!@L+**f0HWDu>e~)}3)n4{IT7Q| z{2h+Hk@MlSgJh0wM(03dsp$R#nUtb8h3f%kJ+;gj;4{2E=XhLI1vNRR)_k==7=F4} zD#pYK)RDmZa_rsIcpC|k=apr_j)Ueyh}}CfVX(M@52FWAWv^^;S>VRH>HH%V3wa@C zD5K7F(&P6F4{rUMNUhu^T5Mz4T+gL)QIx22qR%g97ZXv7(R{K15_Xwg-%`6*+v;dt z-e4d*&}f{~pYjeC>!m$T%=`5RYgzQ(R^5h7EV&#eHtX{U%*IZg z1o5gD!$v*$N8C>wk>OIB5bJShFqf^K)(Y!#hwzkcXvELxrt1n8v6UhN;&*)}anY#1 zBG0BGkC>9@b0y*xf51ay&ch^DK){Ac8e4n1PNlw+FB8Tc5QyCO zuebFLI|-j^%BddBq7n>m@Wh~qHAV^EZm!aC$L`;l|PHi!5gqpI;lNd_o?q$9-8`so+IH@97B{d%Hn5O7r8X=;d_!Rkk zyTG`X_yD~Pm)?#9 z*Ea?D<{f(sFqt3twVQU7#S={fxf5jbrve;~!2df*<66!T!3k|L=Qu8_OV1fngo##% zrQoQO1MMWoUPz=~b}jjQ%#^J}iyb_*CF^2j0;0e0gENlp=0li!37B*HTWQ$;OsZ(pYb9y~(Lrzk zl{TS2`qHWf6dTJYvj#VPW+azKlnsPSi^C0~D}vJspfmcW6F?UPXAOh9dwI&{!GV)P zhoUNuI>Z`mjWD2A5W*^Nj2~f)L|Gv&Z#>+BiphmD*B93g!1jRuVK!2p!WxX_(Yo^p zc<#xj2r5AcrOqbI>bT)0R+u_v7tE1T(6Ftci90wMcX8e0Tf5${hpS1k)6ATkIiBw% zi7_BI%er8rbwRNaiLONhaEy$KMh(897wkCH{e=2VY4wb4P&E>vnV)s@qHHZ1VjOIQ z`U2WS_%IM%z4#lK*h(3_#Rgtip9ETRJ#>bVQsj>^#v$!RtNdjv-osi1rTk`HE$ec^ z+T0!(jXp3a1c?y`8vUm>f*E;Q=vVTeo(Q|24<%Z~#FKyfW2Mjo3>fbXEBK1RaTRlF zBq3mSHA!(d2{lP6r;louO1v-;SoPxbDiqWODOhaDW#!`Xm|RI^`Gg_(eoAIh2vVh( z?u3-x^Hs&xOmn5^#9cEM-re50T%si@@n2LSqOlLrxdcKp+9BJj@>}st@E6ccb2h8U-Z7;7mHa54?Bq7JajPjD6)YlV=@!`8nS zQf~+UV*A2GM@daV?KSX~Cx8{>qsbQG8z1G@=8>puUQ{ab+HBmM%VG9|EdxOVSxcm-8Yw=6!$i%D1@oj4}`q$NK$;-?y0;m;9l3Ek0sI zsR{PUGGqJ_Yse=p#2P=uI<3SwBV?x4KCQ%B0dfLBu!K z1{Eq9CgM)x0khR@om(GI@;HsoMwQGpb7m6BPU*tj4~T?3C2A!@^ulcVBdjzsE5vWs z>x4PBFM@6v2e#O<(2nMVWz_{E_Up5>l{FP;8J2RBmyTWC1W1GwBx5P>dN(Vxc3)K_ zjAN{r^QtWZJqE{rSflMLBI;-GyxzTDoQL}RuM=ge2(1e|8=ZIk+PFq@pAuN*=J1%z z2CcDu`6E08a<6&ci-Z9VOAwa)XR#vWtOCeSMF0HyiVL$+P};YWxpO!*1EWo`+dwhx zsD_Rf28YF}I4WT(CF=T(7+p+k{C{(yC^}#zvDRYoj*SF^v4+e@$?bcMfjNgyKaC}l~t>P-q8{fkOIE5 zI%C{8o!QVv(@YuIo5}jIakNNGI(0Nl%)I5O(=q4DD<2rv)L(+he>Lbp>Uk!LXl}E0 zoO4q6mXmH@eZYHj#^w2*x|FhUy!6XB6*PW?$=5x4`dy(lVXkoBmA+k>t)LZJmG;!j zpfd;Wz7mFg>5wVxZWnOBOC0y@};2Ii<(I31Xno=cSb+?%cjg!M4~Z(Kx|VW=al!` zpIV43Q~v^XZgo?< z6nTrMYvrSMtVWN<1)k?!HXbzsT$_5iEYIAf5QaGA^<_?zQ-xd$Wd9I)ogDmmkH6{6k;KR+HA zu9ZR^^rg6fHpJW-Lj_7S>m;!zs7_9jDv2m&SG>PH-cf-n0ULEs0y30R;LS2k8{^9a znZh|&=lC=V01wAFI*}=aAj|n81x#`T&P%nrm{DS2Q51Cc$5fRKkhrzUr>;5kZ8;sz z7^!Z`dTaKpF(Q8NQ(-dSCs%Iq?FbqLpE`!ZmM-YZ2Iu$B8`-d`i<4YfLSWJe*Q=4s zzlHKpS?q^633~-m3T`sZD|s%ib$Q7Vt6Zr$Z=rH5=B0SS3gpJ9vWSrOg2f(7w%Ach zt@)lt3L0E8@C+}I)ltiB<`d|td_pz4ulKz}h1)Pv3M3#0Z)oF4{{7*!f&RH0?@I@% z(rsP|JQq_@g|R#;gUvWNLoqUFcE(FX;jA-*66*6|t_A*CRe28(gpHft<3|Ho5fr8W zymS9gHVV$BD#(YJ#QIFT?JoiO#3zeS)U31pjhJCmgb2pB4!H>d zY72D&$7uq`TI)nwC8THv5)^#@rk#Wxz8iG998ZLJfIkzT6Hcfk2t71cB`?|KQ(#SA zS~yaE-*)q(baO|!bHgT9^7Jw+hp~8#oHBzB2f2b=ouf?a+d_cJH!jRIgaadx^UREA z$lS`FDQ z<7b*Xf6xzih^IuG#crcFw^|O@kPso2_GV=QXt5^kZACg;1>TTVWrjGjz6}tdWNmwm zil${y<{d+ao-Mico?X~_^=*aO!#DK|W4@(lGt&hpA$>Nn6cU4~3#uE8b1IKngnNWE zSv?OKahXhzsVk(#umfIQWB}7ccCZPC|M97FU~qHsD^dB`3{<8t4-Zc(+d_9*+@Li0 zPC`*;D69izATx0@@V~VHrs5kjWi*6S5fY7sTUAn20)*4y;*CtI$?SKE@hLV#+(ql|5Ko6oI8(&iaexUQv2*`^C@PR}6Usa4?x4ho zBt+Y&9Wn_e{gdq{e=pGVbvD99(JVtjJsRb40{3n6$k6X%RLf@sF?a_%Y5)JBy`)jf zyD;M_?Lfv}SWb#SGCqn4IOFYJ3BpJGo)MAcOFj_sS}R?yRgYjoSI=lN)U(=aOIK13 z|1$T|J;x*q7c{rPW&gApSpQYMKzn5>-YN!0b?(|X&e*!7REb7tZj@m7%iMS^+| z^eigoZxSXUh*c<(E_Il)-=tPLpQQp2b&=kn%VOr;h#2^?{$prQMehgGM4^YEO^PJ& z%8L0odkPTgs5#x2MiKNF7%SKUp5!SA!Hu?27K@c=9u2VX6soxAvY9E{1eh|hA6mek z3D?y~iKdkdaFQVG<=$vZ>m%Es_13JVi!FIWj3)5%bScqWk#ncC!3u~cRg~rZiYLZ*fyON$&Dpwq9!=ylMqEuPf;bxMQD=AzjZ1OX5LJSq)5HKh4bl4dyvDe^H1TV32DaW>Z z$a+lJ8o?d!0IB7lohY-;pY79eYXr`G6bhEh<&r~j$y5^C$F`Qf=Yg@3-s>sF2tx@< zVAh_oGMI-X6zlx?L#h015kj6P zj`PJ#v1ECSGKKHNUjCk8yxee0RLb}cW)eFclKWK11@5@-w?a@ObdOY4|F3*8& zHqX~Ew}t3_&%N(0{ztawDRNWCJr5_T2RK}m-iRsZ(oXSp65H3eaP(9gJW0R?NWaP=nkE?SIkL zF2w)n>W0LF@Jqkw?|w=Ie$EGe@4Av^v{8EK29gqeW9%OT;d6o;|u~ z_`OAaC&Tn)P~FIPVn+m?8|94h{+CWeVf2>fNh%1Pd_AaYD3MlL&P$@q9%RVP!`;Q{ zyO=Ip(?eP5s9fPK&KZ(M!#=k=4#{IqvPooBbi|7M|5mkRX{|)L;y=X>@VgvSHr7G- z_Z9=|JktZ{UEe@5`dZDxL&ttG7wse6dxtsRQLoriw<_kBIsIC~_ivrWFL)v?Kp}TZ z6rTjjjwKI*TbGeAgDy&b*FWOJmxzSPPZb>v5Y0Fkd|OG_YFE~P_x<|+o++%hfbP=x za8F`2x&sAKEDv-nce~rg07{)W`VUC&QwqJ$+`acgRv?hot*qUby`0O9-&I1Km{Nzd39(-1G5d z1Mk8jPuuLai;6~6OPRP_3#4$W=8fbEy0Ls~DMOF&>{~ZPdnO zCFfFP@~?A_7>S2-E5=iZ%a~&K|EF96ImC*AU_Ib$!$Obzd%#7tgna zcYp75GRq}p5WxSe#!tJ&j$lnICD?qY)3%Y(C@hM^9w|5>P9IuhG7(PvSw#w)iStWk z38V|#)q`~-sx|lSj6Dqcs^FJ0Y57Lq0Jm`0Or>iX!XhJ#<)8_ePCPpT(}{;xKiSHS z=NGn|%PbC;{YgHTGnS)kzoX)%O_zho^mLBv>~o)9Q2O&0PYwLyddJ;iX|HR4TXisJ z?HSZ!@8yO__sNAJ36aNrr1hMn48xfIz3x&Gx`E=%jJn|UBnNWkbaUq?rr-*FD7hf6rxtdmmi=RjgV zsPh)ZbIchB`4pd8q1=Jo<(5-)G*Y|P1>G%efbBSnoBs>sRVDj}zXSK1&(G&8%N7o? z5~4Ur)z44IJb(Wl82Er*ezHz2#m+;{jR@iN7@&uISJfdUDl zyPS|~>~}2X080!z?>D{u--U=`Umo%Jjbv`CI=Rg6IzUcK`p1E{fNpODc(TKQRT|Cw zXe`fdk`&*g1ovyXlh7j2j+SQ`a#9w)Ak|K_L;cr*h558mzBTr9j z=RRXfj}NBf0R#|>-CsTncgSDNJjcbw`b_GdliJ9*u|uZDQSAAp`RuqB1m))R8WK%X zC$UudXTD=+DEx5K`}{SU+|CEc(&TSrEwMo&>wbJ;jn{tsM&W!h49<~ujf)9>`Y<-J zrT9WF%sBkC^?c?{+y}XEkd}|2ALsxLZKHlHXVTs2Ri6wyak!hT)3%$7?DRK!+LBI` zxVreD_3TgVoQ>y%?HRV_4_SLSKC=Hx~9) z5d@Ea$Uhpt7{_!-=B%D^;GZlw7;G4>e_uJXk(9ZofLnSkel1|pShOu_idc7xMSI-6 zKP2bRP;Ine+%egU)Hxh#U{+#aDSY zJWDWiB!&x8KfPL8`|A&gYy5Mmp?6_AAr8hoGqh=uP*oQ#U*wc(RN$ntk*^6xb&>yZ zTjdIq;I+kOv%1!iE zP6OqDbmZO-5x5bXqprpOEA^G}$0K%C8?!3u8{A@PbP+>3JIcWWhh^`}QE2YV@5{|S zp-ALtB16DX=G&NjCG!Mh)jINz?!NlgD*s~UmL~M9oDo3l)&tK>BT_UZMaK8=xv(n3 z+^z>;rTj+FQLEJ5HVUynf7sAR;VaDpGLc0qD9dRcs7c|4hv@hAhxg59JM+658->tC z#DRLW#*)?&#;9Tr4@U$`e-uXJqfbzR_vV5(7V8FL*56CAh`&TNN2SkpEjQq5@pf`v zcY=gmobzY;9$jRiNMG-e{V)Cf-#6af^X3z^t8dD6da5#(;c;_*^PKl>*QY-9slJm< z3;$eu!yWwtv)Do7n@lOTN+X2=#xD9U=v#4Fiq1qLax8N_Up{Qg!kI$IqOYyj-&jhx z13z7BxRX#+nYzqkq=sv|v8L-F^HdyENR)3|!hMSh*bh^)Ry=sUvEVac*=8cPRgd zH`3H_=$A+|&aoa3vtekaAJIfDX0F_6;GBpx{XC6S0o&tsKDATm`Fi}UrX0{80q9F-iwF%B$$N>RAefW@ewo96LB1W!$9VX(T;IVZ z;?>dzdP$YcdD%kDO=3$)Ayg#cdz_C?GCKe=y%rj_^SQHyo`X2p*%Zkh&YqpXod$HK zoVZRW(6O$vhq)@>Bh)$m2nUMl1n9Lv5T41zGw~jaX#%Gyb@!xhnn!xZrU(6aY`<<) zZk{|rheW8jP@=qt{2ll3$X-flG^EMxZ)Fgc#=3XqKH**hyfx<{HQ?LBylQMt zgxgOQ2WwwY2A5_#L~YYyw{pDs0{~A2x6l$8_#Q*{PL8|r7US@Dx0OajhgL>?= znXf~*1~=++4PskIuLXG+Y6hlya}!FONI@PX3hz*|D%W7`@P*cGxBJ4RDVQCHj60Ab z(P&1ch8=15?`#Vv<0IgE?P~b}-gK@Z7QNZ|RZgX0{S%3R!x&c7VL`U)$roSR_tGTJ z$dSutKSse{!~Kz(UK+-yB7?SQX3-*p1T7g>s`P)f@qOb4e8yPdS6{q6} zgO}gy^rp}Fhc4d^wnlq_B^QVRPZ`plEj_@!g=(UOftBy*H@*~=?9iFLly0P_L8t!R z6W(WUQ-SZVmgpi^_bf?JNq+z%>Y0)b2+GuxUfQt8{N^N}&W|Fus6Owo9%ug0LSNAr zW4B5`Q$=!GM@dKt$Pi>NYHTy(dmGx{LPo*bX&UjZQ_;5@C z2lm*`fq6-Y_jfJCk_fHTu55A375pPP((w8-Fw}4%+3w$w%S3gW!F~OJ@5phuV$UCr zc&Ayo_x)VAM-xlA^<2i7c=TE*0Gt+g9N7utW)-1rTED>hZ(k_Whh+>TQ?o+P21Z zy}XfJat{z5?$_Py{s;A4;y7%_rs+`cqiA0QG84n{l04r)pd&E>s47ryQ;%@xrFLo0RMBy4)OfSxL% zZJjOCyk25}Ju;FgrduzE?d>9-M%%k9cuMqKgwYe4)vtXd?+3TGJ0rqRf3+2IrJItO z0&0EW&V5-FvTgLdtdEx2?3M$Lth=5T(yv%|zTb54^8b<{sPtyg{X24f4|*>>*BA8f zfaWBW)zq7NcUcnwJgR#>1<+)3BT4ay`u=pqCIT1!|?GrjF^o}WDP zh&11^FFEj}9U`l~7I4+`{VobQ;R;thheG8waRJ?5eSBa;??x}U8d+l<;`f_jZ#kdy&YV>o}1p0XVR31IBqEKDD!sE-oC>)Dmt;LR6P2l*QJkray(f4E&%dKtIu{s= zymvwh4PbJUdaf5=?{_H4ej^?zdI-MWw9B#xwfhMrsd(;0r}|%KcJqLu7-}3hJQma+ z25B7E>@5)G86wxR^G~pUq)Nu%^0GeM+Dto%4+1GtT=IFg|08U-?xTw z7+3)79%FmQZ@)VsX5VYApwJd@3Dgz4zJYe$f~-2@0HrCFigyxrg2md zxWui01HV`zJ~(cuhd(}lSWMr)>~9Cp9+Uc6v`DAJwmr=rJA>9JuKn7xDirf(cwNrc z8xJVKJK#o3Sy@sM1zo=*8U+_f9ps*KiVQucZWUU6=xrrm>cvNBT;Q6{B4Jttz zS(KVJ^m(lX`P|wnvb05U#`a!Z@Q^(p7Y}`ZwcFdw*_7w$I$h)&C40{jK%-K!Jaj_;u^u@5cMx#hQ*?MMh}Cp!;!&S-11I(++r| z)_c$XJY4?<9Vve+@WX!=e{aIe@9ZwMlv=>g<}z@_6384jWM#T{wW;f%bvfpbhKFjh(A^bQNMrTjF1EWBWGr8X_21};5;}PWRc?PL} zaq)Jb2-yn>wtoA`=RPi=4eew^@dNbSlCTw;zdWg*di_q1j=JC97=-WYTmAMqCdfR^ zwn{Qn-lxx#gdcwQ=_UL2V}43_s!s0L%`3HBVR?DdM1Nlpx&}Semd28Gzf@#8cuz?F zXn%#(zODyLPdRS?3Hi?vXQ@oTb;eWO`z(JTB24#$ z#s=FJ**X4WZ1k{7c~T=>f|^*U&0cyb@Vhf+|1}#TBy#)NjsP5CG`OcJn!7NJeL816 zWmW<3c$C~IiXpTw=lTBB`{eN>kwcn)tzy8wt6bG@mcX!{h$MP(i|MPBcRRu2Q}lyzGQ=0jRj#QU)af5)VCn=Vexn9yW^RsB>unxc&i$T&U8YL< zW4q@Fa{GL@Zx_0A{v5B0c+>p;s0=IrSsSaIp*}FKcZ!bqXiarPD z!tHGr1rBAcfIZty&bJJnQxs3<3hkfn2%=J-A)ah`d4~Q9>7oX@D1N_-9`U=l>4;|W zp4g~eyIIWB(gEhSt00L}n->r;JP3ep;g2UAvR}caIsRAPnl(fo3)y5{Tk4eL1RV?} z!>MNDS==b1VF3^z;{ABu<#aJk1j}&=F@y_tkPLyUu+F2b6c0+*PDmhtlk#950WtK) zZ_rPQAl|=z$`CT8$cVZBwctgF6*3MAf`IZrh9w^oy+DW+DcX4&$X_wAkZuwG_rIQ4 z)epdh@Igyw6#woCj}b3e*y%sq5Des=oXN%f;s1YNf7)rMN2u_yY7JY*XjXnnqT@aA z=B~e}T6752^#m4Q0smZo6CS(ajJY{WaT27ERBpr-xJ{`_$DVzJ*hpU*Y^RJs&%goH zf}TA3oh{7p)~cIJ+F5px;-=wuak#YvSRTY!qEk=*W?OuG8# zpnr#;E1SIjvi3pUd^kt5Ae;@+Vt?C2ia2$rl%24GS5S`J>#3@9CB?QOX=0JL>Vo)) zzI29Cg0txYmyjE^Xa@`=U^<=&cJ5&8c?TH0`@PJ}_;c*WmjVX~GA~{%e@OnY&}X++ z*yl{I4)5XsOcsK*J7nUMCUs7V;5}1lG*E2$RFQX%7TH{68#MP8(-Dq*ARF(;m&#-! zC`YU9*If8B1^H4UqMP7mH=HxwZ8H@bJ{QEZG-MYBinoU~j`ia!wfA64E?-AoIwX|% z%h>2Vm~YJgo|0K-t}&kbMXVK`@7x0ImsxyFWN(Lx zaJj}V;;c!|3%^hu+2jyVm&?>&>E6=6Qn(?{p8m6PIP;T`W;8rt<9Yz_Iq+^?6?YNSqjvX@M`Bv0DwqytdN+qe}uW{07&mJFdK1MQB_xG`e-pI`MZj zG!88kvQ0E@R=((0w!H)1@O!V)TS*|#crw5hrtwJq70YZvpD4C73Y^0{CsVL=IiOf! z>}+Lqq|lf?Y-?ybXdx$mT!I1a$lyN{H2jg_KjQh&*xPha;{QH0u*rmG;cEv7}r@i-vpTCqCk8h-Fe` z>D>;8WJe($N$WFkPh&1dvCGV8P@;m+^41@7)(v94jffwxy-?zg6_f+>uyV=$Lgu)8 zX_}9MhxNIOU2Mmy30M!6a8FF>Nb6C4d$in4*hQ5PKCdHrUI;IO$nSOz{f!>#?-uZF zR?+`Ow{2~XcLrt>r*0uWULD7g@h8WSREb4pBERnQ$vFaDI8aoCt7PH*C@=$ihj|R{ zANp_bM!g3sJtWL*X*kXgbvJ&#EqMH7>$#3s?ZJHGvWv?Q-dU;gE#|+q0N(_WF(#%Y z3FL=XHFCb>v;QAwqB>yon0pp>x$#XWO=9uukEdR^GjcOCi@0+6G%UAICSpu4bY@}} z?dY1s!F~C>n|F|y)To_W#NJupi{0Q{#FmR=#X??$OF&;!10@&BapIjMkqvVwls{Kt84`Z&`Op_X^YM{OMKsb41_}sIT zpOk3T0+{;zj0o{Rw7|F-ksc=EL8A}?!a1cUp}33;hv@;I+>B(r;TAu@E&f1Rw&@f$ zww1_D&oedr#z4faS~-jbg%5ligf>FpJ(M$z$<~INfwYrES=F&d!H0S(#G?t=fRv!( zi;lK^%p42Js#Z?)zk%gIR8&qf&#W|?>nppiS^2Q_(Wt+W#t!Z&;L&Qlh?xqhkau@! z&SoaI0QOv_Qx@1xmUitC*Brbsr#cest+h8me;^qk)aT)nvy9szmz&lqKlXO=0qv6p zuIxV4aN%qtINx6uG3rLr{wD6*WjmGsJRY=waXASalK`$?es;ObhI&evP)+bhffei1YqDqP zGs@`aN1vP!)!4&M)G@7GBs%WP8>zfWw~g-#Sz(kd!-wW3($Od3O)3FD){!m8e}27j zuY?k4R+)lPH$qF}+Bb4rB36pDC|K2tiu5d<-^j|x>M85dfulA%E>G<&L{zjxhB(C} zH0%t6$wuBHLI14L!fnNjNR`m+w~dnCk!6$4WkhV1?-c@2X!zd=VN2```Ocgz%P=Ga zyW@vClpyV)n{e*j|0=Dj3QFsX%1hPnwKuSIslOf*E!XAL0^wVoC{o(p%yT)rPq|Bi zvWIVQJ9#W}@#zZIXz!%>RN>uWDRpd@u!F+i4iPg8I1;OVqu64vy@@W>mXK<|5cbt& zIW062Ug{b$Mwz~GjKn0g#x<7L;UiLp&Q`k4#n_Y~+Ouh-UimL`V}4%k`ZW{l+sDb8 z#m)S}kW7^S4SWLsu}OgerCOk1Fo!DeB->`i6O)BI8#> zLxc*UN}YX5ZrJ<fu{gtqu4w3Ssyap(?bRb?>*%_ zCkvp9w$aE0NG77rd3U7 z@$w-6(@3)KsRvEYrWFY7tFloA!$lCP3|)fy#i6vsow&hVnD$qt-02^1b2@8OUPXg$ zA(`7#ajcQ0t2`Ityq(5^abALv6K2Anir}vmGv)I7v0jlT=oJ$`5tEz>uuwxXUGBbA z`t}b_8jIJU+}1|ujM1(E>+CAG$`pP0UKNpj@SaY8&}Q{$tL}N1LrOyq*$y6eNx&+3ufgg?OkF?+i1`!&MK*mi1?v zZawi%c}Pi7CW^2ESez3POk%I7qED*g0gVldD5J+FsMI=gUB~2}-rB-yReztGQL35# zTIaG>elAJwp_tS$&Di?3yyh-x%VaiD#!cy36~C7FW0vN|Xi_dPy+T*b{KHDlU=wc8 z1{bJ>$I4bCK9+Dc$HL%KYmqALqk1HFA+2J<_IaGwz9xOB&b$*VrBL3*ow-KyXh?rL zEShv~P17ADk1^9&nR z8ga@Csd4Q7{fCSEGL73>2jzm&vd75?1hN(A6WA7kS4r|$LpqgxVvGrm zU}}V;{PhJBc3jGCn;`g?DPQR%BvLfuHLOu#qr=6trRINfp2911ohQanf4jTvhu{1cok6sG_v)I6m5 zKqn()RsuK2jQKr`tF5?}wF+u=GR5a)gu5uW%X(@%nVQ{Iw&OMi!;m-5B1g3~C)F`b zk*z+-1%^6xmwBEK?+FKyGUe7EuYWmL;4*_Zz8YfMH2uh0-gdHqYvQw}(t#5C!KuM& zY>i*{Wl zmj~%lp3(EK^BfW9tONEY{tOCPrUw4{I!0Y9k7jPic1*7d>f}mpdCkAjm{K$3ISaXE z@r=>Pp79~Bm)L}zlsRxZ>(O6w1^8x=aiwfvLm~0AKzg}-so<`ymNt0`EN@0|O+9=o zQy#QeR0j=reP@dlJ&BH$Ol3~~keKX7NDAXV;X5OJXrk1#6_!s!UO^wu)280D&6ghg zBM{?~b5X@Ul}^3t*kd)O`jnd`gtY>PBJg;oL#^;xv{mNXvo+Udf$J$qi72#4yI z#P`{TYLqC6d+&o1yE3o(zw7ZqMlUg+iwZB8zy&Ozqc4-JDx>W;kOw4a%Dp|UFyPB zJ{_pLFO!Z>?Vs41mvwZ+d$XZK8W3>rBV)1=Iqh$lIrz=E+nof}i7|;O*KMxZ6|EK< zLR?*rb+RuiCW-D~M_EsW*duxgMw)23X*5O5Tnr|TP)4AI5<<9jf-s;I%F!;*pd}zzZnP8{-(G?QCuTUQeSONWuBwCY1@M~!om+@ zo~X*6r58pstA{VaLSC!#CU#N=FeAC$iC6C}e9$$VRh{f9%Z>TGoio@1Qyd_0CNot> zD-oFOJiWG4e^_N9SUA~n&T!-^DBcY0*Tq>m&Wx?9WwEWyXoY8IjK0t~_2J#pgSWyK zvs+<}QzE&~%12I-EBVwMqMS0?5v3MwZLLmFy3PD+83*gQqx^?}xrW>oq|(K8U(x9# zBH2yW@l|NgAP(jiCB^4%m`Wd=CSjr z)Zr2I?uoQXqhj)*J=$4HqF*#UtZ+5}jHa~Q$honG6dJj;^Yy>9$H|$yBMfMlvz9-4 zht4-qXUF_4;m){K$4#)W>Pt3D)H>S$z_^7&(6P)e-Ik-?iw=qf2$uG>orWW)c8jm;GqOcLL@H#6EWJ+4__0M zvX)L1Jo;=E!K>cbH|L1`&J}ek2Aj0seL#|e;TbZivjfma(*uV#@(s~&}_$R#tZBnv!5+{hQ5Ite+9}7AC*>$_f1*Co8zi3HMM@iZ%WvgT6s+u~S8$cZJ6yAW)CRm+`6O z=4W|ASW0ec?dD~b&P^dcOXuu(o@NUq6lUsV`6Lh=Cq~g+oJ$6?-^e3HvdmlzQfd$% zm&7~9{ul3(bHd6&dpn1dGH@BCp6*3MBHm3U9DHcPX-<;w3~St~1N0SrcBDbLUTi8J54zQK15n4u2c0piKLE9{;l?0H3_ZybxMgMbPq{U(1d!`1e=up zr;$h<<+q08+VX-0d-|&p;}*k+{uv66DAEaB$X+jjk-~Euo)xdR0SW$4PnAGs%b@9{WugOxsp1Paro68Rz5IyaFF_O@FANKy!Nm{gtv zH=xW~HJyD>mhBq_Gy-3*&dHA+(msB~>JoVpm_6pA0euR9j?LKrTYx1H))VhzF7;)d zKcP1FproRm-7;{a@0(GVH9Bg8qFR7o`FjjBWgoPBUgZ5M6!>fIUGfeyAcTKy?qs1{ zZk%}7PRA$k(86YJ+O9YnHS%wZ`uB>7$Eu6l!8nUNjb@DG2;&R_jOGW#5c^=pH4PN7 zla0CI{HWS=jIa^@a-pwz_PHtbVg=)F)k~+vI##DsE45XUv?=GK@0Uk`dE#|J7gxCD z*{n%Rb6<5zWW$Ak>V|C@GS+HqMD^+!`aY|Sdr37j4Gt&W)7?NlJCjlvNK27`-;Bv% zPNegLf$D0zvR<)dHx?yW>Rp^IMC?^30$z;l#ze?dK`}n;T`|ri(<*&Nz$TpBcgqs0 zJ4>=h(~xUB7NyI&$<|_H%=H!=qtMBAloM!ouc$aVRNZiHYyF4`lA&ngN}P?TTqstU z69nD$r9f$>P`*4xnRj}nL??VvJunQQw8VwDVNZ~jDNBRR-fdkDO1EH4&9_xT1bidg z`Kpj9)~XRiZb^9P@KacM30!QeJV#pibuZ7m#KeN?(mC0LhnYnqK$S~DCXWcH0uvZ(-hxYXS+DIQ+Q(V%~ zkX0Fkm~S}2+Lh0&P`}gHh{EO!p}1#(Zrzfc%EHI8$`Mk(FVkc^77Df%+fl03-NFQ~ z8Ir}AY<_3X$R!PI$_`iTn=_{H{f%3P`TQ{)=>{iwvgxr74mGl1jl0<+SShiPmMfjU zr9tzUEU~}E68mSj7l0qJJC9RusD zVKVg{Q8d+KZ9{Ph=u(j}ias@Ic)_G~nz;LUH<5IPAwBy!a8FI7>M_)R)TLeO<^u`- zepZ5`4%DAzR2yZ@UzYx&G|)0z<5v@j+!$`+zL>$JB3Wij*|+}}1Ljku;x4v9Oy@cQ z8nyqPwDenjFQV|etVz4M^l?I=35hH|bbNY|$lj34B5}2~N6)L-q z6?_+*Y;KwZXCEb+y5C~#SNI=cRBbYx&hxTLgA2OXmi?2_H+buZcIJ@+GiXe7hi?AN zXsra*8~3GXu|!R`-3*RoD3noSPwSuSn)jXf+z{j9N?8P_k*6?|RONn2a1%N_}o zY!u~YIoGu62Fa;0pBpg*@dpKR>e)!ulZU^CAyrs(S)xy#^h1OqRiE+{=L;#MF_676 zGc^5gB0M$0nqf5&uG)r?kWzI0&mZbZtP$lJjp^%Sh_HVPpY`GLFe2ILZiMlC+PJr3 z!s;T@u%lRpIe{y&EBN-1Kk`ezdR&1wU%uc8H-Nvcy{%iT0MjH#t+jW+Z1dbqZmU_j z9)^Odr+~neL~`G}S#i+Dc-sDqR!6E{7!gG(+R&b7loP-D)mSG4J(7cf=H}K@wwtcQSR1an`BIMUQ5M0( z-cF3)c6NEDz>tWE3MRlSNZdO6bV*&t$AW{Z8!P=3&XR4;jyV@Yke4JNlKC6Gb1 zzRJm&5HQnbh{C1H9O`HguKnl~_F<*K=#OBN^`b6G2Gr%Cso@#+XTuh+BsTAsaixcr zv{Fe*h*L%%d%T9F_Y)_jqaGePid;zVR^ zi6K)`o%QG-w4v%>qT0GlqwOK(#gl)*q)IL4t zlOwpo=+MrPdry45AnCQQm7}jUqPjB(S_BdHx%t^FjHN+0VtEzjR{t77N#wUfBgQ$R+Af?xGp zVbisUepnEmwk=hmaz8THCR&!sq>H0;T=&q5e^J(wR%vjr$Wcq6RHuT@h1U+p_In^P zeBnt}Xr6Ov?02|Jrj7K?S$R|(sU_XP59yl2^>U+(Va6^6O^HibgVT)9#;TQ1MU$ew z`ho=&#^I9!%j#Z_Q+MWQkDgSE8)cOm4zt&!*%tQ;p|FA^26UKoR@7~3Bd<;35=Bb4 zH3|W%SPG|iByKx9J6ifZrWlwgLh9r$_wtht;2YgFn!T^?-$;h=fT%4T!|Lfj~~g0JkpBW#1zdv#5& zT6&oD=1M(?H= zDJB&=f1_)hjbh2N*i9Z8w&O}XC{m+{1FP*HUr^xE#6>e9B;y-U6{S;tLbF!QsRK;o zCvVk@TX8B_6g+zv`v8x2ddT0>1v_d7ip@6T9fyl}LbGGHX)erZ5t#VyF+Z_j8@{U{e_w!z=#UD>6 zaNV@ZwL?0=M&6&+L#Fr~%JZT(_@rSvYw>v;g-_MfU`!eRUYSQ@0g@evQeKT$!vsP0 zz5FK$0e;3zy0l*u?0R3Ws@>MH!?Fwrpvjt**Bvd+ISypXB}gD_rLNFo7k^Xtw4tzj z!&xWtHmA`DF*N{S{~;$O4#U6!UVn~u3go?(vQfrm+y&Mf<+m#g*u^Qa1tEB@0emC| zYk0yn^zM~BCdBr8tq%&JV`FKixda=9O*+T=MzHU=UUMm!@EecyJJ+P$dh*Vyp+&v) zcwABRO?C-;t>@42Q}}0>sW~%7Z>B|Rn{Qwn?bfmT%b06H)%1h%!m#uC2_=h=qvBRm z>!e@dFhmHJ_)3U4AQ!#EuvhBSd7tJSoBp5^>iTMYxU#PoZ^7t8*}Bn0t7flMktn1% z2esgb41zVp$-q#F~aR9x6iec{t(H* zx)s%>8PF?(JT&~AK={SvS~a76GR328wvY7jz7iFBX&63G3ka{bezmG)?)5iMv&A4Q z`O*p>%F>>_fRv>remtQvrOHklsb&dFEO!Yh9+9NC*-dB36)2)SMCLP=Fnp%4$L-JU zL_IkWzg>JEF@*-D59#AFHqvdIJ}u5i792MUL{EBToh|k)fdr0}LRWT;kz150u_1%5 zSXGB}YnNc}+7M>xzVzFN)T0c(t)&B>xsoe%=fjVuevrd3qY1NYrVS1U~zJKbbVPY&zc#?=bt@C=vdZqskfN3$6$ z81fW8iEimcHSRx`!sqPP92tG-RrhlTkJX*1Rh%aRHA|4PuBNC{_Zl2Y(4i+%*h^KF z->|^L`K*{(9IR@sjXWUlckvTN41S8oG>H2qX=7-W%Omc^-6_y$NOaUQ^J)Dc;xED4u(G# z=N9P~L%!)BZu8l$Cs7Qgg&aW7d>6BEiT&W<%0Pqt7x4%avq}x52aHk>SWSi09gG9n zDuja0_V&PnSdg8YtNW?01OWbToJxZQ8Wy&g)K!8?Omf8x^AVL}hxJCLVvQLizC4YY zz+>S+5sE`~^n*rlH>>@6{>OglJF*2#9AVE`33C?8bYf9IkOqbE@0;T z&{vh5QOf>F1W$;@gjJQ1W{bsb-B*}D`v?GLv3^DRwXlv zcY$po`(wYJVi9&n*1)jdu=JhsAj(0SSGCVrw0@Xcxu8Y~xeanxj41PCBI$N+KZ1TH z4BxQnEMj3n(WR*K%cdoI2+8KKe}_1{9X1pFEpty+^!o|bXlB7NF~(lK>#p_d1>+!- z;=6=P)MGPE3#}=Z?IU@-r3OlGpn|$D5g(=ND53Z3iXP|XX)szit&+SRTd3D7vsh>k zW=~9&v#5xp^=nu4xQVE2)x_;g&5(L*KEs%@rCg7}+&Wq@Dy+_EO`$(udZSgJijZ1uK` zy{46`X&5I_IT=GVb&QL;wH8@XO zYzCS&&T1fJ!30)hAFOOO8gH$8iaY$Vp>>>Kse+XAadJOHQOtS0lg2wh?Q>Kq*Zkdb zKS%pcYw(a!f=LA7jmq~nQ+0)#{A^fqn!&O6YoEzn3+8xwOL_R}>THk+UfWPXz6v>2=)|Y zPWFz?nAZsO{5<49kU?8m1--Yq`s#m=SEF*%F8v*aA$Q zI{bt*H`quh4bcxRQfqyk+|k{K(H5JVRgXGYtPv&Ml58shott8GPq~?G|0wyIl@yv> zJbkrMR-I*Jm)Ojua3f{_&!$eAAQwe=)=vE`0zu8A-fbKwX?L8^)-X{9E*#wnO@e%7 zCV{d~wwn2j)_2o<_ig%RB}+F3zd0zuXq;G|t{w?@WD|Gx8q!LBF<5r!Y~S6#iXAs8 zmC+cpFC1(k$=jGbU%3RE5zO)|Nk9O2^pxV7V@g#du!12a9V*4VTu&u^8|!q%W>FO` zr2<%pfZ?rGZT*{s4ug1T1>~zslw*goJyTEB?wlBU;-#$O=W)wxwRGb!jGMiC+v_4U z#l6d&QTjYWZpm`|efj#N$>8m-{NQS`@uxp0=V=l|Mzk_jN~2?fu4xra@#+?O(0__1 zVm+g4wC0-VzC~ksL{@ym@y8R|9dmu#SRG-9CnaS^QH&(B5%ml4@lh$RJNmtm%C=f@ zc~jqC)2cn|MoF0F$jy4HoYLZ?Nu=S)5ZH(q#;*xM!dsbmC@0EozLsQ9%ArY{!Cmk* z;xS~!b$##t&5#P*AbX-T;D?KHfch{HvjZ zPmEkF?BE<{eTcwUSAO1iy4BpcJ-G}|GXIb2gJPOy<$2(|qkRD%wsarII zc8*f3nfHACA*nOCGv8yNHNM`D{&-nY-t@_Z+p5n8{>}^T`p6?E!Tu9gk_PU>S9l%A zN^N`FCeGM2JYJ6^KjqI$k@NR1A&x`Q7r7I>uU9d#i?XbyE@UR?d|Bkwg2ZuT^3w(D zcMW%jctulnY8cGD+aE$ni!B_dK(n?j7vEH>v^$*=t}YvKy}92OyAn$5Qp(hqa@!Q` zIfUF=6rvy!``i#f+-=B(xXzW)RX0P^tw zfbx7tb4N2bdkY6wb`N{IpZ0A^R&;3Ryeji0(JT1fw+`|>^`a|w#qxG6UO;@xRldr+ zaoEx!m1;J1o2ywbdS?`wn9g1k)G~ahR<0SkV`~LRvSuJK!`2$D?Lxd=-?FA5xLM8S zwouxMnDwYk5fkm1Rm?*)T1L8s_gKMyn?a%Xvti*y+!$`*%0TWwML9 zS>$)UsNCeR4LQ>2HP>0rHA+&CEj^^l`u>M~-Nf)?Pd7w4AOEzV#3)-6LgFv(vOsT@YK{sQTp&{*ks0+ zf->$~5P3wzJ727nIHFc5E(r6droLUQM^&krNd!^KGA1I%yB@A4FaE#c$=N_wjZLt#n(b4VV`c zn`8DVe%P^~68;yoqT+!8@V^V3aBU`Ark@r#I@h&3!E|l37`gl*I&WCZ1#Q;{O90#MgRa;L9s`} z{X3MNAN2QNdWQHlXzbsZpG*J04TgD!`q|C~J8NL%P;qf|It$(B$NP$vr(z8{r8gM7 z|LXi}JjQ>+Oq`s~{PTD8A-8y+1&9s+(bs+s^q02H;JbehYUb!-aT)w5vrhIF*zp<& zKU)!J?bqOHDF24L!Cf8g{~@^C!r-d8S0-Q_P^QbEDrx_XOKE{-1AZSyrq7R z%V)q}%Fdq$UWn4aTa5?0#078w0KGc$Z&s71`cvzFbNmjUPzM7{1T2! z^}x$zBehck04q?=>rp(5dQlJV%k&ukfk`VY0Ra42aByo|%7qlV~3EdUgOa-M^p z66+#|&}AIs435W(GypIM%6V7sBt*KvajAP)K{GmL<^W&_l=Es}4_#D)`%+ieF0l#y zhyZ|bP|kBuR$*UM<5E}8c`=eri37={( z%?g4^I$Oam%;Dyu<)Yd0zi%j0N|fX1@HgL-Edb=JBxpT|2H{o z5nLxf$9BDMVQ+CEht1Sbe8xftfJU<4?S@Nw4)_z!^-FOy5C8y7;13z7f)y61HSj-I Cs*5rJ literal 0 HcmV?d00001 diff --git a/doc/消费量报表规则.md b/doc/消费量报表规则.md new file mode 100644 index 0000000..a678470 --- /dev/null +++ b/doc/消费量报表规则.md @@ -0,0 +1,84 @@ +# 消费量报表规则 + +1. 样本编号 + +2. 污水处理厂名称 + +3. 所在地(省) + +4. 所在地(市) + +5. 所在地(区/县) + +6. 采样时间 + +7. 污水厂服务人口(万人) + +8. 生活污水占比 + +9. 流量(万立方米/天) + +10. 人均日吸烟(支)注:各省数值不同,可查询实验大数据平台左侧导航栏地区信息 + +11. 可替宁排泄量(mg/千人天)= 人均日吸烟(支)* 0.14 * 1000 +12. 测算人口(千人)= 可替宁(ng/L) * 流量(万立方米/天) * 10 * 生活污水占比 / 可替宁排泄量(mg/千人天) + + 注:将ng/L转化为mg/L,换算率为1000000,10000立方米等于10,000,000L,而1mg等于1000000ng,简单描述为,通过流量乘以污水占比计算出总流量,然后乘以可替宁浓度,再换算为mg,可得出该地区每天的可替宁总质量,然后除以 可替宁排泄量(千人),可大致推算出测算人口 + + + +13. | 可替宁(ng/L) | 可待因(ng/L) | MDA(ng/L) | MDMA(ng/L) | 可卡因(ng/L) | 苯甲酰爱康宁(ng/L) | 吗啡(ng/L) | O6-单乙酰吗啡(ng/L) | 甲基苯丙胺(ng/L) | 苯丙胺(ng/L) | 氯胺酮(ng/L) | 去甲氯胺酮(ng/L) | 四氢大麻酸(ng/L) | + | -------------- | -------------- | ----------- | ------------ | -------------- | -------------------- | ------------ | --------------------- | ------------------ | -------------- | -------------- | ------------------ | ------------------ | + | | | | | | | | | | | | | | + + 以上为实验所得的污水化合物浓度 + + +14. 吗啡负荷量(mg/千人﹒天)= 吗啡(ng/L) * 流量(万立方米/天)* 10 / 测算人口(千人) + 备注:通过检测污水中吗啡的浓度,乘以总流量,得到该地区每天产生的吗啡总质量,再除以测算人口,可大致计算吗啡负荷量(mg/千人﹒天),计算公式如下: + + ![image-20240417101958546](../dlp-drugtesting-biz/assets/image-20240417101958546.png) + +15. 可待因负荷量(mg/千人﹒天)= 可待因(ng/L)* 流量(万立方米/天)* 10 / 测算人口(千人) + + 备注:通过检测污水中吗啡的浓度,乘以总流量,得到该地区每天产生的吗啡总质量,再除以测算人口,可大致计算吗啡负荷量(mg/千人﹒天) + +16. 可待因转化为吗啡负荷量(mg/千人﹒天) = 可待因负荷量(mg/千人﹒天) * 0.065 / (0.3 * 1.05) + 备注:可待因转化为吗啡的比例为6.5%,可待因的排泄率为30%,1.05为可待因与吗啡的分子量比,计算公式如下: + + ![image-20240417101824328](../dlp-drugtesting-biz/assets/image-20240417101824328.png) + +17. 医用吗啡负荷量(mg/千人﹒天)= 1 是根据文献取平均值 + +18. MA/AM = 甲基苯丙胺(ng/L)/ 苯丙胺(ng/L)Excel中红色区域代表MA/AM>20 + +19. K/NK = 氯胺酮(ng/L)/ 去甲氯胺酮(ng/L) Excel中红色区域代表K/NK>6 + +20. 人均消耗量(mg/千人﹒天)Heroin = (吗啡负荷量(mg/千人﹒天)- 可待因转化为吗啡负荷量(mg/千人﹒天)- 医用吗啡负荷量(mg/千人﹒天)) * 3.07 + + 备注:计算海洛因的消费量时要减去可待因转化的吗啡以及医用吗啡 + + 消费量折算系数如下: + + ![image-20240417102214943](../dlp-drugtesting-biz/assets/image-20240417102214943.png) + +21. 人均消耗量(mg/千人﹒天)MA = 甲基苯丙胺(ng/L)或 苯丙胺(ng/L)* 流量(万立方米/天) * 10 * 2.33或46.6 / 测算人口(千人) + + 备注:注:AM=0时,冰毒消费量用MA计算。AM≠0时,若MA/AM≦20,冰毒消费量用MA计算,若MA/AM>20,冰毒消费量用AM计算。 AM为苯丙胺(ng/L),MA为甲基苯丙胺,用样本中甲基苯丙胺或苯丙胺的浓度乘以总流量,再换算为mg,得到该地区每天产生的冰毒总量,乘以对应系数,再除以测算人口,得到人均消费量。 + +22. 人均消耗量(mg/千人﹒天)K = 氯胺酮(ng/L)或去甲氯胺酮(ng/L) * 流量(万立方米/天) * 10 * 5或26.6 / 测算人口(千人) + + 备注:NK=0时,氯胺酮消费量用K计算。NK≠0时,若K/NK≦6,氯胺酮消费量用K计算,若K/NK>6,氯胺酮消费量用NK计算。K为氯胺酮,NK为去甲氯胺酮 + +23. 人均消耗量(mg/千人﹒天)MDMA = MDMA(ng/L) * 流量(万立方米/天) * 10 * 4.44 / 测算人口(千人) + +24. 人均消耗量(mg/千人﹒天)COC = 苯甲酰爱康宁(ng/L) * 流量(万立方米/天) * 10 * 2.33 / 测算人口(千人) + +25. 人均消耗量(mg/千人﹒天)THC = 四氢大麻酸(ng/L) * 流量(万立方米/天) * 10 * 152 / 测算人口(千人) + +26. 总消耗量:对应化合物的人均消费量 * 当地测算人口 + +27. (化合物)人均消耗量:各区县总消耗量之和 / 各区县测算人口之和 + +28. 人均总消耗量:所有化合物人均消费量之和 + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2b59f03 --- /dev/null +++ b/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + + digital.laboratory.platform + DigitalLaboratoryPlatform + 2022.10.11-snapshots + + dlp-drugtesting + 2022.10.11-snapshots + pom + dlp-drugtesting + + UTF-8 + + + dlp-drugtesting-api + dlp-drugtesting-biz + +