/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.social.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.social.config.SocialConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.FailReasonConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSocialInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialSoldierMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.FailReasonConfigService;
import com.yifu.cloud.plus.v1.yifu.social.service.TDispatchInfoService;
import com.yifu.cloud.plus.v1.yifu.social.service.TSocialInfoService;
import com.yifu.cloud.plus.v1.yifu.social.service.TSocialSoldierService;
import com.yifu.cloud.plus.v1.yifu.social.vo.TSocialSoldierReturnErrorVo;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;

/**
 * 社保士兵
 *
 * @author hgw
 * @date 2024-5-8 14:55:36
 */
@AllArgsConstructor
@Log4j2
@Service
public class TSocialSoldierServiceImpl extends ServiceImpl<TSocialSoldierMapper, TSocialInfo> implements TSocialSoldierService {

	private RestTemplate restTemplate = new RestTemplate();
	private final SocialConfig socialConfig;
	private final TDispatchInfoService tDispatchInfoService;
	private final TSocialInfoService tSocialInfoService;
	private final FailReasonConfigService failReasonConfigService;


	/**
	 * @param addId
	 * @Description: 5 查看任务进度
	 * @Author: hgw
	 * @Date: 2024/5/11 15:08
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> getFiveJob(String addId) {
		List<TSocialInfo> socialList;
		if (Common.isEmpty(addId)) {
			// 获取所有需要反馈的任务id
			socialList = tSocialInfoService.getSocialSoldierYgsAll();
			List<TSocialInfo> socialYsdList = tSocialInfoService.getSocialSoldierYsdAll();
			if (socialYsdList != null && !socialYsdList.isEmpty()) {
				if (socialList != null && !socialList.isEmpty()) {
					socialList.addAll(socialYsdList);
				} else {
					socialList = socialYsdList;
				}
			}
		} else {
			socialList = tSocialInfoService.getSocialSoldierByAddId(addId);
		}
		if (socialList != null && !socialList.isEmpty()) {
			Map<String, TSocialInfo> idCardMap = new HashMap<>();
			Set<String> addIdSet = new HashSet<>();
			for (TSocialInfo socialInfo : socialList) {
				if (Common.isNotNull(socialInfo.getYgsAddId())) {
					addIdSet.add(socialInfo.getYgsAddId());
					idCardMap.put(socialInfo.getYgsAddId() + CommonConstants.DOWN_LINE_STRING + socialInfo.getEmpIdcard(), socialInfo);
				}
				if (Common.isNotNull(socialInfo.getYsdAddId())) {
					addIdSet.add(socialInfo.getYsdAddId());
					idCardMap.put(socialInfo.getYsdAddId() + CommonConstants.DOWN_LINE_STRING + socialInfo.getEmpIdcard(), socialInfo);
				}
			}
			HttpURLConnection conn;
			InputStream in = null;
			Map<String, FailReasonConfig> errorMap = failReasonConfigService.getFailReasonMap();
			if (!addIdSet.isEmpty()) {
				for (String doAddId : addIdSet) {
					R<String> resultFile = socialConfig.getFiveJob(restTemplate, doAddId);
					log.info("resultFile=" + resultFile);
					try {
						// 解决中文文件名的乱码问题
						String fileTeturnUrl = resultFile.getData();
						if (Common.isNotNull(fileTeturnUrl)) {
							String dowloadUrl = fileTeturnUrl;
							int indexOf = fileTeturnUrl.lastIndexOf("/") + 1;
							fileTeturnUrl = fileTeturnUrl.substring(indexOf);
							try {
								fileTeturnUrl = URLEncoder.encode(fileTeturnUrl, "UTF-8");
							} catch (UnsupportedEncodingException e) {
								log.info("编码异常！");
							}
							dowloadUrl = dowloadUrl.substring(0, indexOf) + fileTeturnUrl;
							URL url = new URL(dowloadUrl);
							conn = (HttpURLConnection) url.openConnection();
							//设置超时间为30秒
							conn.setConnectTimeout(30 * 1000);
							in = conn.getInputStream();
							// 实际读取文件内容
							this.readXls(in, idCardMap, errorMap, doAddId);
						}
					} catch (Exception e) {
						e.printStackTrace();
					} finally {
						if (in != null) {
							try {
								in.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				}
			}
		}
		return R.ok();
	}

	public R<List<TSocialSoldierReturnErrorVo>> readXls(InputStream inputStream, Map<String, TSocialInfo> idCardMap
			, Map<String, FailReasonConfig> errorMap, String doAddId) {
		TSocialSoldierReturnErrorVo vo;
		List<TSocialSoldierReturnErrorVo> voList = new ArrayList<>();
		HSSFWorkbook sheets = null;
		try {
			sheets = new HSSFWorkbook(inputStream);
			// sheet
			HSSFSheet sheetAt = sheets.getSheetAt(0);
			HSSFRow row;
			// 每个单元格内容
			String cellValue;
			// 内容行
			int dataRow;
			HSSFCell cell;
			// 循环每个sheet
			if (sheetAt != null && Common.isNotNull(sheetAt.getSheetName())) {
				// 初始化每个sheet的数据行
				dataRow = 0;

				// 错误信息 所在列
				Integer errorInfoNum = null;
				// 是否处理完成 所在列
				Integer isDoCompletedNum = null;
				// 是否成功 所在列
				Integer isSuccessNum = null;
				// 反馈结果 所在列
				Integer msgNum = null;
				// 身份证号码 所在列
				Integer idCardNum = null;
				// 证件号码 所在列
				Integer empIdCardNum = null;

				// 错误信息
				String errorInfo = null;
				// 是否处理完成
				String isDoCompleted = null;
				// 是否成功
				String isSuccess = null;
				// 反馈结果
				String msg = null;
				// 身份证号码
				String idCard = null;
				// 证件号码
				String empIdCard = null;

				for (int rowNum = 0; rowNum <= sheetAt.getLastRowNum(); rowNum++) {
					row = sheetAt.getRow(rowNum);
					if (row != null) {
						// 循环当前行的内容
						if (rowNum == 0) {
							for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
								// 标题行
								cell = row.getCell(cellNum);
								cellValue = "";
								try {
									if (cell != null) {
										if (CellType.STRING == cell.getCellType()) {
											cellValue = row.getCell(cellNum).getStringCellValue();
										} else if (CellType.NUMERIC == cell.getCellType()) {
											cellValue = String.valueOf(row.getCell(cellNum).getNumericCellValue());
											if (cellValue.contains("E")) {
												cellValue = String.valueOf(new DecimalFormat("#").format(row.getCell(cellNum).getNumericCellValue()));
											}
										}
									}
								} catch (NumberFormatException e) {
									cell.setCellType(CellType.STRING);
									cellValue = String.valueOf(row.getCell(cellNum).getStringCellValue());
								}
								if ("错误信息".equals(cellValue)) {
									errorInfoNum = cellNum;
								} else if ("是否处理完成".equals(cellValue)) {
									isDoCompletedNum = cellNum;
								} else if ("是否成功".equals(cellValue)) {
									isSuccessNum = cellNum;
								} else if ("反馈结果".equals(cellValue)) {
									msgNum = cellNum;
								} else if ("身份证号码".equals(cellValue)) {
									idCardNum = cellNum;
								} else if ("证件号码".equals(cellValue)) {
									empIdCardNum = cellNum;
								}
							}
						} else {
							if (Common.isEmpty(errorInfoNum) && Common.isEmpty(isDoCompletedNum)) {
								return R.failed("未找到对应表头！");
							} else {
								if (Common.isNotNull(errorInfoNum)) {
									errorInfo = getCellValue(row, errorInfoNum);
									vo = new TSocialSoldierReturnErrorVo();
									vo.setErrorInfo(errorInfo);
									voList.add(vo);
									return R.failed("数据错误！！");
								} else {
									if (Common.isNotNull(isDoCompletedNum) && Common.isNotNull(isSuccessNum)
											&& Common.isNotNull(msgNum)) {
										isDoCompleted = getCellValue(row, isDoCompletedNum);
										isSuccess = getCellValue(row, isSuccessNum);
										msg = getCellValue(row, msgNum);
										if (Common.isNotNull(idCardNum)) {
											idCard = getCellValue(row, idCardNum);
										} else if (Common.isNotNull(empIdCardNum)) {
											empIdCard = getCellValue(row, empIdCardNum);
										}
										vo = new TSocialSoldierReturnErrorVo();
										vo.setIsDoCompleted(isDoCompleted);
										vo.setIsSuccess(isSuccess);
										vo.setMsg(msg);
										vo.setIdCard(idCard);
										vo.setEmpIdCard(empIdCard);
										voList.add(vo);
									}
								}
							}
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			if (sheets != null) {
				try {
					sheets.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		} finally {
			if (sheets != null) {
				try {
					sheets.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		if (!voList.isEmpty()) {
			importTSocialInfo(voList, idCardMap, errorMap, doAddId);
		}
		return R.ok(voList);
	}

	/**
	 * @Description: 获取单元格内容
	 * @Author: hgw
	 * @Date: 2024/5/13 16:34
	 * @return: java.lang.String
	 **/
	private String getCellValue(HSSFRow row, int cellNum) {
		HSSFCell cell = row.getCell(cellNum);
		String cellValue = "";
		try {
			if (cell != null) {
				if (CellType.STRING == cell.getCellType()) {
					cellValue = row.getCell(cellNum).getStringCellValue();
				} else if (CellType.NUMERIC == cell.getCellType()) {
					cellValue = String.valueOf(row.getCell(cellNum).getNumericCellValue());
					if (cellValue.contains("E")) {
						cellValue = String.valueOf(new DecimalFormat("#").format(row.getCell(cellNum).getNumericCellValue()));
					}
				}
			}
		} catch (NumberFormatException e) {
			cell.setCellType(CellType.STRING);
			cellValue = String.valueOf(row.getCell(cellNum).getStringCellValue());
		}
		return cellValue;
	}

	/*public R<List<ErrorMessage>> importDiy(InputStream inputStream, Map<String, TSocialInfo> idCardMap
			, Map<String, FailReasonConfig> errorMap) {
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TSocialSoldierReturnErrorVo> util1 = new ExcelUtil<>(TSocialSoldierReturnErrorVo.class);
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TSocialSoldierReturnErrorVo.class, new ReadListener<TSocialSoldierReturnErrorVo>() {
				*//**
				 * 单次缓存的数据量
				 *//*
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				*//**
				 *临时存储
				 *//*
				private List<TSocialSoldierReturnErrorVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TSocialSoldierReturnErrorVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				*//**
				 * 加上存储数据库
				 *//*
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTSocialInfo(cachedDataList, idCardMap, errorMap);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}*/

	private void importTSocialInfo(List<TSocialSoldierReturnErrorVo> excelVOList, Map<String, TSocialInfo> idCardMap
			, Map<String, FailReasonConfig> errorMap, String doAddId) {
		// 个性化校验逻辑
		// 执行数据插入操作 组装
		TSocialSoldierReturnErrorVo excel;
		String empIdCard;
		TSocialInfo socialInfo;
		List<TSocialInfo> updateSocialList = new ArrayList<>();
		TSocialInfo updateSocial;
		// true养工失 false 医生大
		boolean typeFlag = true;
		FailReasonConfig failConfig;
		String ygsHandleStatus;
		String ysdHandleStatus;
		// 养工失办理成功的单子
		List<String> ygsList = new ArrayList<>();
		// 养工失办理失败的单子
		List<String> ygsFailList = new ArrayList<>();
		// 医生大办理成功的单子
		List<String> ysdList = new ArrayList<>();
		// 医生大办理失败的单子
		List<String> ysdFailList = new ArrayList<>();
		Map<String, TSocialInfo> socialMap = new HashMap<>();
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			if ("是".equals(excel.getIsDoCompleted())) {
				// 插入
				log.info(excel.getErrorInfo());
				empIdCard = excel.getIdCard();
				if (Common.isEmpty(empIdCard)) {
					empIdCard = excel.getEmpIdCard();
					typeFlag = false;
				}
				if (Common.isNotNull(empIdCard)) {
					// 初始化继续办理
					ygsHandleStatus = CommonConstants.THREE_STRING;
					ysdHandleStatus = CommonConstants.THREE_STRING;
					socialInfo = idCardMap.get(doAddId + CommonConstants.DOWN_LINE_STRING + empIdCard);
					if (socialInfo != null) {

						if (typeFlag &&
								(CommonConstants.ONE_STRING.equals(socialInfo.getYgsHandleStatus())
										|| CommonConstants.TWO_STRING.equals(socialInfo.getYgsHandleStatus())
										|| CommonConstants.THREE_STRING.equals(socialInfo.getYgsHandleStatus()))) {
							updateSocial = socialMap.get(socialInfo.getId());
							if (updateSocial == null) {
								updateSocial = new TSocialInfo();
								updateSocial.setId(socialInfo.getId());
							}
							if ("是".equals(excel.getIsSuccess())) {
								ygsHandleStatus = CommonConstants.SIX_STRING;
								ygsList.add(socialInfo.getDispatchId());
							} else {
								updateSocial.setYgsRemark(excel.getMsg());
								updateSocial.setYgsRemarkOld(excel.getMsg());
								// 过期自动变为终止
								if (CommonConstants.ONE_STRING.equals(socialInfo.getYgsOverDueFlag())) {
									updateSocial.setYgsRemarkOld("已过期，自动中止办理！");
									ygsHandleStatus = CommonConstants.FOUR_STRING;
									ygsFailList.add(socialInfo.getDispatchId());
								} else if (Common.isNotNull(excel.getMsg())) {
									// 如果找到了失败原因配置：
									failConfig = getConfig(excel.getMsg(),errorMap);
									if (failConfig != null) {
										updateSocial.setYgsRemark(failConfig.getSimpleReason());
										// failConfig.getReplay() 1 继续办理 2 中止办理 3 人工办理
										// setYgsHandleStatus 3继续办理、4终止办理、5人工处理
										if (CommonConstants.ONE_STRING.equals(failConfig.getReplay())) {
											ygsHandleStatus = CommonConstants.THREE_STRING;
										} else if (CommonConstants.TWO_STRING.equals(failConfig.getReplay())) {
											ygsHandleStatus = CommonConstants.FOUR_STRING;
											ygsFailList.add(socialInfo.getDispatchId());
										} else if (CommonConstants.THREE_STRING.equals(failConfig.getReplay())) {
											ygsHandleStatus = CommonConstants.FIVE_STRING;
										}
									} else {
										ygsHandleStatus = CommonConstants.FIVE_STRING;
									}
								}
							}
							updateSocial.setYgsHandleStatus(ygsHandleStatus);
							updateSocialList.add(updateSocial);
							socialMap.put(updateSocial.getId(), updateSocial);
						} else if (!typeFlag &&
								(CommonConstants.ONE_STRING.equals(socialInfo.getYsdHandleStatus())
										|| CommonConstants.TWO_STRING.equals(socialInfo.getYsdHandleStatus())
										|| CommonConstants.THREE_STRING.equals(socialInfo.getYsdHandleStatus()))) {
							updateSocial = socialMap.get(socialInfo.getId());
							if (updateSocial == null) {
								updateSocial = new TSocialInfo();
								updateSocial.setId(socialInfo.getId());
							}
							if ("是".equals(excel.getIsSuccess())) {
								ysdHandleStatus = CommonConstants.SIX_STRING;
								ysdList.add(socialInfo.getDispatchId());
							} else {
								updateSocial.setYsdRemark(excel.getMsg());
								updateSocial.setYsdRemarkOld(excel.getMsg());
								// 过期自动变为终止
								if (CommonConstants.ONE_STRING.equals(socialInfo.getYsdOverDueFlag())) {
									updateSocial.setYsdRemarkOld("已过期，自动中止办理！");
									ysdHandleStatus = CommonConstants.FOUR_STRING;
									ysdFailList.add(socialInfo.getDispatchId());
								} else if (Common.isNotNull(excel.getMsg())) {
									// 如果找到了失败原因配置：
									failConfig = getConfig(excel.getMsg(),errorMap);
									if (failConfig != null) {
										updateSocial.setYsdRemark(failConfig.getSimpleReason());
										// failConfig.getReplay() 1 继续办理 2 中止办理 3 人工办理
										// ysdHandleStatus 3继续办理、4终止办理、5人工处理
										if (CommonConstants.ONE_STRING.equals(failConfig.getReplay())) {
											ysdHandleStatus = CommonConstants.THREE_STRING;
										} else if (CommonConstants.TWO_STRING.equals(failConfig.getReplay())) {
											ysdHandleStatus = CommonConstants.FOUR_STRING;
											ysdFailList.add(socialInfo.getDispatchId());
										} else if (CommonConstants.THREE_STRING.equals(failConfig.getReplay())) {
											ysdHandleStatus = CommonConstants.FIVE_STRING;
										}
									} else {
										ysdHandleStatus = CommonConstants.FIVE_STRING;
									}
								}
							}
							updateSocial.setYsdHandleStatus(ysdHandleStatus);
							updateSocialList.add(updateSocial);
							socialMap.put(updateSocial.getId(), updateSocial);
						}
					}
				}
			}
		}

		// 处理社保办理成功或失败，
		if (!updateSocialList.isEmpty()) {
			tSocialInfoService.updateBatchById(updateSocialList);
		}

		// 处理社保办理成功后的状态同步-成功
		String typeSub = CommonConstants.ZERO_STRING;
		String handleStatus = CommonConstants.ONE_STRING;
		String handleRemark = "社保士兵自动办理成功！";
		String remark = "社保士兵自动办理成功！！";
		String socialType = "1,2,3";
		Set<String> dbAuthsSet = new HashSet<>();
		Collection<? extends GrantedAuthority> authorities = AuthorityUtils
				.createAuthorityList(dbAuthsSet.toArray(new String[0]));
		YifuUser user = new YifuUser("1", 1L, "社保士兵部门", "社保士兵",
				"社保士兵", "0", SecurityConstants.BCRYPT + "123456",
				"12345678911", true, true, true,
				true,
				"1", authorities, "1",
				null, null,
				null);
		if (!ygsList.isEmpty()) {
			this.doSocialAndDispatch(ygsList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
		if (!ysdList.isEmpty()) {
			socialType = "4,5,6";
			this.doSocialAndDispatch(ysdList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}

		// 处理社保办理成功后的状态同步-失败
		handleStatus = CommonConstants.TWO_STRING;
		handleRemark = "社保士兵自动办理失败！";
		remark = "社保士兵自动办理失败！！";
		if (!ygsFailList.isEmpty()) {
			socialType = "1,2,3";
			this.doSocialAndDispatch(ygsFailList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
		if (!ysdFailList.isEmpty()) {
			socialType = "4,5,6";
			this.doSocialAndDispatch(ysdFailList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
	}

	/**
	 * @Description: 查找失败原因的关键字
	 * @Author: hgw
	 * @Date: 2024/5/14 17:55
	 * @return: com.yifu.cloud.plus.v1.yifu.social.entity.FailReasonConfig
	 **/
	private FailReasonConfig getConfig(String msg, Map<String, FailReasonConfig> errorMap) {
		for (Map.Entry<String, FailReasonConfig> config : errorMap.entrySet()) {
			if (msg.contains(config.getKey())) {
				return config.getValue();
			}
		}
		return null;
	}

	/**
	 * 调用成功的社保办理
	 *
	 * @param handleStatus 1 办理成功 2 办理失败
	 * @param handleRemark
	 * @param typeSub      0 社保 1  公积金
	 * @param socialType   （1养老 2医疗 3失业 4工伤 5生育 6大病）
	 * @return
	 * @Author hgw
	 * @Date 2024-5-11 17:03:12
	 **/
	public R<List<ErrorMessage>> doSocialAndDispatch(List<String> idList, String typeSub, String handleStatus
			, String handleRemark, String socialType, String remark, YifuUser user) {
		return tDispatchInfoService.addApplyHandle(idList, typeSub, handleStatus, handleRemark, socialType, remark, user);
	}

}
