| | |
| | | package com.doumee.service.business.impl; |
| | | |
| | | import com.doumee.core.constants.ResponseStatus; |
| | | import com.doumee.core.exception.BusinessException; |
| | | import com.doumee.core.model.LoginUserInfo; |
| | | import com.doumee.core.model.PageData; |
| | | import com.doumee.core.model.PageWrap; |
| | | import com.doumee.core.utils.Constants; |
| | | import com.doumee.core.utils.DateUtil; |
| | | import com.doumee.core.utils.Utils; |
| | | import com.doumee.core.utils.Week; |
| | | import com.doumee.core.utils.redis.RedisUtil; |
| | | import com.doumee.dao.business.YwLinePointMapper; |
| | | import com.doumee.dao.business.YwPatrolSchemeMapper; |
| | | import com.doumee.dao.business.model.YwPatrolScheme; |
| | | import com.doumee.dao.business.YwPatrolTaskMapper; |
| | | import com.doumee.dao.business.YwPatrolTaskRecordMapper; |
| | | import com.doumee.dao.business.model.*; |
| | | import com.doumee.dao.system.model.SystemUser; |
| | | import com.doumee.service.business.YwPatrolSchemeService; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.github.yulichang.wrapper.MPJLambdaWrapper; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 运维巡检计划信息表Service实现 |
| | |
| | | |
| | | @Autowired |
| | | private YwPatrolSchemeMapper ywPatrolSchemeMapper; |
| | | @Autowired |
| | | private YwPatrolTaskMapper ywPatrolTaskMapper; |
| | | @Autowired |
| | | private YwLinePointMapper ywLinePointMapper; |
| | | @Autowired |
| | | private YwPatrolTaskRecordMapper ywPatrolTaskRecordMapper; |
| | | @Autowired |
| | | private RedisTemplate<String, Object> redisTemplate; |
| | | |
| | | @Override |
| | | public Integer create(YwPatrolScheme ywPatrolScheme) { |
| | | if(Objects.isNull(ywPatrolScheme) |
| | | || StringUtils.isBlank(ywPatrolScheme.getTitle()) |
| | | ||Objects.isNull(ywPatrolScheme.getLineId()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getUserIds()) |
| | | ||Objects.isNull(ywPatrolScheme.getStartDate()) |
| | | ||Objects.isNull(ywPatrolScheme.getEndDate()) |
| | | ||Objects.isNull(ywPatrolScheme.getCircleType()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getStartTime()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getEndTime()) |
| | | || (!Constants.equalsInteger(ywPatrolScheme.getCircleType(),Constants.ZERO) &&StringUtils.isBlank(ywPatrolScheme.getCircleDays())) |
| | | ){ |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST); |
| | | } |
| | | LoginUserInfo loginUserInfo = ywPatrolScheme.getLoginUserInfo(); |
| | | ywPatrolScheme.setCreateDate(new Date()); |
| | | ywPatrolScheme.setCreator(loginUserInfo.getId()); |
| | | ywPatrolScheme.setIsdeleted(Constants.ZERO); |
| | | ywPatrolScheme.setStatus(Constants.ZERO); |
| | | ywPatrolScheme.setCode(this.getNextCode()); |
| | | ywPatrolSchemeMapper.insert(ywPatrolScheme); |
| | | |
| | | this.createThreeDaysData(ywPatrolScheme,loginUserInfo); |
| | | return ywPatrolScheme.getId(); |
| | | } |
| | | |
| | | public synchronized String getNextCode(){ |
| | | String prefix = "P"; |
| | | Integer countNum = RedisUtil.getObject(redisTemplate,Constants.RedisKeys.PATROL_SCHEME_CODE_KEY,Integer.class); |
| | | countNum = Constants.formatIntegerNum(countNum)+1; |
| | | //更新缓存 |
| | | RedisUtil.addObject(redisTemplate,Constants.RedisKeys.PATROL_SCHEME_CODE_KEY,countNum); |
| | | String nextIndex =Integer.toString( countNum ); |
| | | return prefix + StringUtils.leftPad(nextIndex,4,"0"); |
| | | } |
| | | |
| | | |
| | | |
| | | public void createThreeDaysData(YwPatrolScheme ywPatrolScheme,LoginUserInfo loginUserInfo){ |
| | | //循环生成三天内的数据 |
| | | for (int i = 0; i < 3; i++) { |
| | | Date schemeDate = DateUtil.getXDayAfterDate(new Date(),i); |
| | | this.createTask(schemeDate,ywPatrolScheme,loginUserInfo); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据日期生成任务 |
| | | * @param schemeDate |
| | | * @param ywPatrolScheme |
| | | */ |
| | | public void createTask(Date schemeDate,YwPatrolScheme ywPatrolScheme,LoginUserInfo loginUserInfo){ |
| | | if(ywPatrolScheme.getStartDate().getTime() > schemeDate.getTime() |
| | | || ywPatrolScheme.getEndDate().getTime() < schemeDate.getTime() ){ |
| | | return; |
| | | } |
| | | if(Constants.equalsInteger(ywPatrolScheme.getCircleType(),Constants.ONE)){ |
| | | //每周根据日期生成 根据日期获取是周几 |
| | | Week week = DateUtil.getWeek(schemeDate); |
| | | if(Objects.isNull(week)){ |
| | | return; |
| | | } |
| | | List<String> weeks = Arrays.asList(ywPatrolScheme.getCircleDays().split(",")); |
| | | String weekStr = weeks.stream().filter(i->Constants.equalsInteger(Integer.valueOf(i),week.getNumber())).findFirst().get(); |
| | | if(StringUtils.isBlank(weekStr)){ |
| | | return; |
| | | } |
| | | }else{ |
| | | //每月根据日期生成 根据日期获取是哪天 |
| | | List<String> days = Arrays.asList(ywPatrolScheme.getCircleDays().split(",")); |
| | | String dayStr = DateUtil.getFomartDate(schemeDate,"dd"); |
| | | if(Objects.isNull(days.stream().filter(i->StringUtils.equals(i,dayStr)).findFirst().get())){ |
| | | return; |
| | | }; |
| | | } |
| | | String schemeDateStr = DateUtil.getDate(schemeDate,"yyyy-MM-dd"); |
| | | //查询当天是否生成过数据 |
| | | if(ywPatrolTaskMapper.selectCount(new QueryWrapper<YwPatrolTask>().lambda().eq(YwPatrolTask::getSchemeId,ywPatrolScheme.getId()).like(YwPatrolTask::getStartDate,schemeDateStr))>Constants.ZERO){ |
| | | return; |
| | | }; |
| | | YwPatrolTask ywPatrolTaskForCodeSn = ywPatrolTaskMapper.selectOne(new MPJLambdaWrapper<YwPatrolTask>() |
| | | .select(" ifnull( max(replace(code,'"+ywPatrolScheme.getCode()+"-','')),0) AS codeSn ") |
| | | .eq(YwPatrolTask::getSchemeId,ywPatrolScheme.getId()) |
| | | .orderByDesc( YwPatrolTask::getId) |
| | | .last(" limit 1 ") |
| | | ); |
| | | Integer codeSn = ywPatrolTaskForCodeSn.getCodeSn(); |
| | | |
| | | List<YwLinePoint> ywLinePointList = ywLinePointMapper.selectList(new QueryWrapper<YwLinePoint>().lambda() |
| | | .eq(YwLinePoint::getLineId,ywPatrolScheme.getLineId()) |
| | | .eq(YwLinePoint::getIsdeleted,Constants.ZERO) |
| | | .orderByAsc(YwLinePoint::getSortnum)); |
| | | if(CollectionUtils.isEmpty(ywLinePointList)){ |
| | | return; |
| | | } |
| | | codeSn = codeSn + 1; |
| | | String nextCode = StringUtils.leftPad(codeSn.toString(),3,"0"); |
| | | YwPatrolTask ywPatrolTask = new YwPatrolTask(); |
| | | ywPatrolTask.setCreateDate(new Date()); |
| | | ywPatrolTask.setCreator(loginUserInfo.getId()); |
| | | ywPatrolTask.setIsdeleted(Constants.ZERO); |
| | | ywPatrolTask.setStatus(Constants.patrolTaskStatus.waitStart); |
| | | ywPatrolTask.setSchemeId(ywPatrolScheme.getId()); |
| | | ywPatrolTask.setCircleType(ywPatrolScheme.getCircleType()); |
| | | ywPatrolTask.setStartDate(DateUtil.getDateFromString(schemeDateStr +" "+ ywPatrolScheme.getStartTime() +":00")); |
| | | ywPatrolTask.setEndDate(DateUtil.getDateFromString(schemeDateStr +" "+ ywPatrolScheme.getEndTime() +":00")); |
| | | ywPatrolTask.setDealUserId(ywPatrolScheme.getDealUserId()); |
| | | ywPatrolTask.setCode(ywPatrolScheme.getCode() + "-" + nextCode); |
| | | ywPatrolTaskMapper.insert(ywPatrolTask); |
| | | |
| | | List<YwPatrolTaskRecord> ywPatrolTaskRecordList = new ArrayList<>(); |
| | | for (int i = 0; i < ywLinePointList.size(); i++) { |
| | | YwLinePoint ywLinePoint = ywLinePointList.get(i); |
| | | //生成任务数据 |
| | | YwPatrolTaskRecord ywPatrolTaskRecord = new YwPatrolTaskRecord(); |
| | | ywPatrolTaskRecord.setCreateDate(new Date()); |
| | | ywPatrolTaskRecord.setCreator(loginUserInfo.getId()); |
| | | ywPatrolTaskRecord.setIsdeleted(Constants.ZERO); |
| | | ywPatrolTaskRecord.setStatus(Constants.ZERO); |
| | | ywPatrolTaskRecord.setSchemeId(ywPatrolScheme.getId()); |
| | | ywPatrolTaskRecord.setPointId(ywLinePoint.getPointId()); |
| | | ywPatrolTaskRecord.setTaskId(ywPatrolTask.getId()); |
| | | ywPatrolTaskRecord.setDealUserId(ywPatrolScheme.getDealUserId()); |
| | | ywPatrolTaskRecord.setSortnum(i+1); |
| | | ywPatrolTaskRecordList.add(ywPatrolTaskRecord); |
| | | } |
| | | ywPatrolTaskRecordMapper.insert(ywPatrolTaskRecordList); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void deleteById(Integer id, LoginUserInfo user) { |
| | |
| | | |
| | | @Override |
| | | public void updateById(YwPatrolScheme ywPatrolScheme) { |
| | | if(Objects.isNull(ywPatrolScheme) |
| | | || Objects.isNull(ywPatrolScheme.getId()) |
| | | || StringUtils.isBlank(ywPatrolScheme.getTitle()) |
| | | ||Objects.isNull(ywPatrolScheme.getLineId()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getUserIds()) |
| | | ||Objects.isNull(ywPatrolScheme.getStartDate()) |
| | | ||Objects.isNull(ywPatrolScheme.getEndDate()) |
| | | ||Objects.isNull(ywPatrolScheme.getCircleType()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getStartTime()) |
| | | ||StringUtils.isBlank(ywPatrolScheme.getEndTime()) |
| | | || (!Constants.equalsInteger(ywPatrolScheme.getCircleType(),Constants.ZERO) &&StringUtils.isBlank(ywPatrolScheme.getCircleDays())) |
| | | ){ |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST); |
| | | } |
| | | LoginUserInfo loginUserInfo = ywPatrolScheme.getLoginUserInfo(); |
| | | ywPatrolScheme.setEditDate(new Date()); |
| | | ywPatrolScheme.setEditor(loginUserInfo.getId()); |
| | | ywPatrolSchemeMapper.updateById(ywPatrolScheme); |
| | | } |
| | | |
| | | @Override |
| | | public void updateStatus(YwPatrolScheme ywPatrolScheme) { |
| | | if(Objects.isNull(ywPatrolScheme) |
| | | || Objects.isNull(ywPatrolScheme.getId()) |
| | | || Objects.isNull(ywPatrolScheme.getStatus()) |
| | | || !(Constants.equalsInteger(ywPatrolScheme.getStatus(),Constants.ZERO) || Constants.equalsInteger(ywPatrolScheme.getStatus(),Constants.ONE )) |
| | | ){ |
| | | throw new BusinessException(ResponseStatus.BAD_REQUEST); |
| | | } |
| | | LoginUserInfo loginUserInfo = ywPatrolScheme.getLoginUserInfo(); |
| | | ywPatrolScheme.setEditDate(new Date()); |
| | | ywPatrolScheme.setEditor(loginUserInfo.getId()); |
| | | ywPatrolSchemeMapper.updateById(ywPatrolScheme); |
| | | if(Constants.equalsInteger(ywPatrolScheme.getStatus(),Constants.ZERO)){ |
| | | this.createThreeDaysData(ywPatrolScheme,loginUserInfo); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | @Override |
| | | public PageData<YwPatrolScheme> findPage(PageWrap<YwPatrolScheme> pageWrap) { |
| | | IPage<YwPatrolScheme> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity()); |
| | | QueryWrapper<YwPatrolScheme> queryWrapper = new QueryWrapper<>(); |
| | | MPJLambdaWrapper<YwPatrolScheme> queryWrapper = new MPJLambdaWrapper<YwPatrolScheme>(); |
| | | Utils.MP.blankToNull(pageWrap.getModel()); |
| | | if (pageWrap.getModel().getId() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getId, pageWrap.getModel().getId()); |
| | | YwPatrolScheme model = pageWrap.getModel(); |
| | | queryWrapper.selectAll(YwPatrolScheme.class) |
| | | .select(" t2.realName as createUserName ") |
| | | .select(" t1.realName as userName ") |
| | | .leftJoin(SystemUser.class,SystemUser::getId,YwPatrolScheme::getUserIds) |
| | | .leftJoin(" system_user t2 on t.creator = t2.id ") |
| | | .eq(YwPatrolScheme::getIsdeleted,Constants.ZERO) |
| | | .like(StringUtils.isNotBlank(model.getTitle()),YwPatrolScheme::getTitle,model.getTitle()) |
| | | .ge(Objects.nonNull(model.getStartDate()),YwDeviceRecord::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getStartDate())) |
| | | .le(Objects.nonNull(model.getEndDate()),YwDeviceRecord::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getEndDate())) |
| | | .orderByDesc(YwPatrolScheme::getCreateDate) |
| | | ; |
| | | IPage<YwPatrolScheme> iPage = ywPatrolSchemeMapper.selectJoinPage(page,YwPatrolScheme.class,queryWrapper); |
| | | for (YwPatrolScheme ywPatrolScheme:iPage.getRecords()) { |
| | | this.getSchemeStatus(ywPatrolScheme); |
| | | } |
| | | if (pageWrap.getModel().getCreator() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getCreator, pageWrap.getModel().getCreator()); |
| | | return PageData.from(iPage); |
| | | } |
| | | if (pageWrap.getModel().getCreateDate() != null) { |
| | | queryWrapper.lambda().ge(YwPatrolScheme::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate())); |
| | | queryWrapper.lambda().le(YwPatrolScheme::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate())); |
| | | |
| | | //获取状态 |
| | | public void getSchemeStatus(YwPatrolScheme ywPatrolScheme){ |
| | | List<YwPatrolTask> ywPatrolTaskList = ywPatrolTaskMapper.selectList(new QueryWrapper<YwPatrolTask>().lambda() |
| | | .eq(YwPatrolTask::getSchemeId,ywPatrolScheme.getId()) |
| | | .eq(YwPatrolTask::getIsdeleted,Constants.ZERO) |
| | | .ne(YwPatrolTask::getStatus,Constants.FOUR) |
| | | ); |
| | | |
| | | if(CollectionUtils.isEmpty(ywPatrolTaskList)){ |
| | | ywPatrolScheme.setSchemeStatus(Constants.ZERO); |
| | | ywPatrolScheme.setTimeOutTaskNum(Constants.ZERO); |
| | | return; |
| | | } |
| | | if (pageWrap.getModel().getEditor() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getEditor, pageWrap.getModel().getEditor()); |
| | | //过滤数据是否存在进行中的 |
| | | if(ywPatrolTaskList.stream().filter(i->Constants.equalsInteger(i.getStatus(),Constants.ONE)).collect(Collectors.toList()).size()>Constants.ZERO){ |
| | | ywPatrolScheme.setSchemeStatus(Constants.ONE); |
| | | ywPatrolScheme.setTimeOutTaskNum(ywPatrolTaskList.stream().filter(i->i.getEndDate().getTime()>System.currentTimeMillis()) |
| | | .collect(Collectors.toList()).size()); |
| | | return; |
| | | } |
| | | if (pageWrap.getModel().getEditDate() != null) { |
| | | queryWrapper.lambda().ge(YwPatrolScheme::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate())); |
| | | queryWrapper.lambda().le(YwPatrolScheme::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate())); |
| | | |
| | | //过滤数据是不是全部未开始 |
| | | if(Constants.equalsInteger(ywPatrolTaskList.stream().filter(i->Constants.equalsInteger(i.getStatus(),Constants.ZERO)).collect(Collectors.toList()).size(),ywPatrolTaskList.size())){ |
| | | ywPatrolScheme.setSchemeStatus(Constants.ZERO); |
| | | ywPatrolScheme.setTimeOutTaskNum(ywPatrolTaskList.stream().filter(i->i.getEndDate().getTime()>System.currentTimeMillis()) |
| | | .collect(Collectors.toList()).size()); |
| | | return; |
| | | } |
| | | if (pageWrap.getModel().getIsdeleted() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getIsdeleted, pageWrap.getModel().getIsdeleted()); |
| | | } |
| | | if (pageWrap.getModel().getTitle() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getTitle, pageWrap.getModel().getTitle()); |
| | | } |
| | | if (pageWrap.getModel().getRemark() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getRemark, pageWrap.getModel().getRemark()); |
| | | } |
| | | if (pageWrap.getModel().getStatus() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getStatus, pageWrap.getModel().getStatus()); |
| | | } |
| | | if (pageWrap.getModel().getSortnum() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getSortnum, pageWrap.getModel().getSortnum()); |
| | | } |
| | | if (pageWrap.getModel().getLineId() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getLineId, pageWrap.getModel().getLineId()); |
| | | } |
| | | if (pageWrap.getModel().getUserIds() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getUserIds, pageWrap.getModel().getUserIds()); |
| | | } |
| | | if (pageWrap.getModel().getDealUserId() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getDealUserId, pageWrap.getModel().getDealUserId()); |
| | | } |
| | | if (pageWrap.getModel().getDealDate() != null) { |
| | | queryWrapper.lambda().ge(YwPatrolScheme::getDealDate, Utils.Date.getStart(pageWrap.getModel().getDealDate())); |
| | | queryWrapper.lambda().le(YwPatrolScheme::getDealDate, Utils.Date.getEnd(pageWrap.getModel().getDealDate())); |
| | | } |
| | | if (pageWrap.getModel().getDealInfo() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getDealInfo, pageWrap.getModel().getDealInfo()); |
| | | } |
| | | if (pageWrap.getModel().getCircleType() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getCircleType, pageWrap.getModel().getCircleType()); |
| | | } |
| | | if (pageWrap.getModel().getCircleDays() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getCircleDays, pageWrap.getModel().getCircleDays()); |
| | | } |
| | | if (pageWrap.getModel().getStartDate() != null) { |
| | | queryWrapper.lambda().ge(YwPatrolScheme::getStartDate, Utils.Date.getStart(pageWrap.getModel().getStartDate())); |
| | | queryWrapper.lambda().le(YwPatrolScheme::getStartDate, Utils.Date.getEnd(pageWrap.getModel().getStartDate())); |
| | | } |
| | | if (pageWrap.getModel().getEndDate() != null) { |
| | | queryWrapper.lambda().ge(YwPatrolScheme::getEndDate, Utils.Date.getStart(pageWrap.getModel().getEndDate())); |
| | | queryWrapper.lambda().le(YwPatrolScheme::getEndDate, Utils.Date.getEnd(pageWrap.getModel().getEndDate())); |
| | | } |
| | | if (pageWrap.getModel().getStartTime() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getStartTime, pageWrap.getModel().getStartTime()); |
| | | } |
| | | if (pageWrap.getModel().getEndTime() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getEndTime, pageWrap.getModel().getEndTime()); |
| | | } |
| | | if (pageWrap.getModel().getProcessStatus() != null) { |
| | | queryWrapper.lambda().eq(YwPatrolScheme::getProcessStatus, pageWrap.getModel().getProcessStatus()); |
| | | } |
| | | for(PageWrap.SortData sortData: pageWrap.getSorts()) { |
| | | if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) { |
| | | queryWrapper.orderByDesc(sortData.getProperty()); |
| | | } else { |
| | | queryWrapper.orderByAsc(sortData.getProperty()); |
| | | //过滤数据是不是全部已完成 |
| | | if(Constants.equalsInteger(ywPatrolTaskList.stream().filter(i->Constants.equalsInteger(i.getStatus(),Constants.THREE)).collect(Collectors.toList()).size() |
| | | ,ywPatrolTaskList.size())){ |
| | | ywPatrolScheme.setSchemeStatus(Constants.TWO); |
| | | return; |
| | | } |
| | | } |
| | | return PageData.from(ywPatrolSchemeMapper.selectPage(page, queryWrapper)); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public long count(YwPatrolScheme ywPatrolScheme) { |
| | | QueryWrapper<YwPatrolScheme> wrapper = new QueryWrapper<>(ywPatrolScheme); |
| | | return ywPatrolSchemeMapper.selectCount(wrapper); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |