|
|
@ -4,6 +4,7 @@ import com.peteralbus.entity.*;
|
|
|
|
import com.peteralbus.service.EarthquakeInfoService;
|
|
|
|
import com.peteralbus.service.EarthquakeInfoService;
|
|
|
|
import com.peteralbus.service.EstimateService;
|
|
|
|
import com.peteralbus.service.EstimateService;
|
|
|
|
import com.peteralbus.service.FireCenterService;
|
|
|
|
import com.peteralbus.service.FireCenterService;
|
|
|
|
|
|
|
|
import com.peteralbus.util.EstimateUtil;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
|
import org.springframework.stereotype.Controller;
|
|
|
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
|
|
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
|
|
@ -12,159 +13,186 @@ import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The type Fire center controller.
|
|
|
|
|
|
|
|
*/
|
|
|
|
@CrossOrigin
|
|
|
|
@CrossOrigin
|
|
|
|
@RestController
|
|
|
|
@RestController
|
|
|
|
public class FireCenterController {
|
|
|
|
public class FireCenterController {
|
|
|
|
|
|
|
|
private FireCenterService fireCenterService;
|
|
|
|
|
|
|
|
private EstimateController estimateController;
|
|
|
|
|
|
|
|
private EstimateService estimateService;
|
|
|
|
|
|
|
|
private EarthquakeInfoService earthquakeInfoService;
|
|
|
|
|
|
|
|
private EstimateUtil estimateUtil;
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* The Max fire center count.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static Integer MAX_FIRE_CENTER_COUNT = 20;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Sets fire center service.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param fireCenterService the fire center service
|
|
|
|
|
|
|
|
*/
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
FireCenterService fireCenterService;
|
|
|
|
public void setFireCenterService(FireCenterService fireCenterService) {
|
|
|
|
|
|
|
|
this.fireCenterService = fireCenterService;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Sets estimate controller.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param estimateController the estimate controller
|
|
|
|
|
|
|
|
*/
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
EstimateController estimateController;
|
|
|
|
public void setEstimateController(EstimateController estimateController) {
|
|
|
|
|
|
|
|
this.estimateController = estimateController;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Sets estimate service.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param estimateService the estimate service
|
|
|
|
|
|
|
|
*/
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
EstimateService estimateService;
|
|
|
|
public void setEstimateService(EstimateService estimateService) {
|
|
|
|
|
|
|
|
this.estimateService = estimateService;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Sets earthquake info service.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param earthquakeInfoService the earthquake info service
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
|
|
public void setEarthquakeInfoService(EarthquakeInfoService earthquakeInfoService) {
|
|
|
|
|
|
|
|
this.earthquakeInfoService = earthquakeInfoService;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Sets estimate util.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param estimateUtil the estimate util
|
|
|
|
|
|
|
|
*/
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
EarthquakeInfoService earthquakeInfoService;
|
|
|
|
public void setEstimateUtil(EstimateUtil estimateUtil) {
|
|
|
|
|
|
|
|
this.estimateUtil = estimateUtil;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Gets all fire center.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return the all fire center
|
|
|
|
|
|
|
|
*/
|
|
|
|
@RequestMapping("/getAllFireCenter")
|
|
|
|
@RequestMapping("/getAllFireCenter")
|
|
|
|
public List<FireCenter> getAllFireCenter(){
|
|
|
|
public List<FireCenter> getAllFireCenter() {
|
|
|
|
return fireCenterService.getAllFireCenter();
|
|
|
|
return fireCenterService.getAllFireCenter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//获取一个地震区域的消防站位置
|
|
|
|
/**
|
|
|
|
public List<FireCenter> getOnePlaceAllFireCenter(Long earthquakeId){
|
|
|
|
* 获取一个地震区域的消防站位置
|
|
|
|
List<FireCenter> fireCenters=getAllFireCenter();
|
|
|
|
*
|
|
|
|
List<FireCenter> fireCenterList=new ArrayList<>();
|
|
|
|
* @param earthquakeId the earthquake id
|
|
|
|
Map<String,Object>mapParameter=new HashMap<>();
|
|
|
|
* @return the one place all fire center
|
|
|
|
mapParameter.put("earthquakeId",earthquakeId);
|
|
|
|
*/
|
|
|
|
EarthquakeInfo earthquakeInfo=earthquakeInfoService.queryInfoWithLine(mapParameter).get(0);
|
|
|
|
public List<FireCenter> getOnePlaceAllFireCenter(Long earthquakeId) {
|
|
|
|
for(FireCenter fireCenter:fireCenters){
|
|
|
|
List<FireCenter> fireCenters = fireCenterService.getAllFireCenter();
|
|
|
|
double distanceTwoPlaces=getDistance(fireCenter.getFireLon(),fireCenter.getFireLat(),earthquakeInfo.getLongitude(),earthquakeInfo.getLatitude());
|
|
|
|
List<FireCenter> fireCenterList = new ArrayList<>();
|
|
|
|
List<IntensityLine> intensityLineList=earthquakeInfo.getIntensityLineList();
|
|
|
|
Map<String, Object> mapParameter = new HashMap<>();
|
|
|
|
if(distanceTwoPlaces<intensityLineList.get(intensityLineList.size()-1).getLongRadius())
|
|
|
|
mapParameter.put("earthquakeId", earthquakeId);
|
|
|
|
{
|
|
|
|
EarthquakeInfo earthquakeInfo = earthquakeInfoService.queryInfoWithLine(mapParameter).get(0);
|
|
|
|
|
|
|
|
for (FireCenter fireCenter : fireCenters) {
|
|
|
|
|
|
|
|
double distanceTwoPlaces = getDistance(fireCenter.getFireLon(), fireCenter.getFireLat(), earthquakeInfo.getLongitude(), earthquakeInfo.getLatitude());
|
|
|
|
|
|
|
|
List<IntensityLine> intensityLineList = earthquakeInfo.getIntensityLineList();
|
|
|
|
|
|
|
|
if (distanceTwoPlaces < intensityLineList.get(intensityLineList.size() - 1).getLongRadius()) {
|
|
|
|
fireCenterList.add(fireCenter);
|
|
|
|
fireCenterList.add(fireCenter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fireCenterList;
|
|
|
|
return fireCenterList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Gets one fire center.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param id the id
|
|
|
|
|
|
|
|
* @return the one fire center
|
|
|
|
|
|
|
|
*/
|
|
|
|
@RequestMapping("/getOneFireCenter")
|
|
|
|
@RequestMapping("/getOneFireCenter")
|
|
|
|
public FireCenter getOneFireCenter(int id){
|
|
|
|
public FireCenter getOneFireCenter(int id) {
|
|
|
|
return fireCenterService.getAllFireCenter().get(id);
|
|
|
|
return fireCenterService.getAllFireCenter().get(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 根据地震ID,寻找附近的消防站,并随机选取fireCenterCount个进行物资分配计算.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param earthquakeId 地震ID
|
|
|
|
|
|
|
|
* @param fireCenterCount 物资分配的救援点数量
|
|
|
|
|
|
|
|
* @return FireWeight,救援点权重,包含救援点信息
|
|
|
|
|
|
|
|
*/
|
|
|
|
@RequestMapping("/findFireCenterNearby")
|
|
|
|
@RequestMapping("/findFireCenterNearby")
|
|
|
|
public List<FireWeight> getFireCenterWeight(Long earthquakeId){
|
|
|
|
public List<FireWeight> getFireCenterWeight(Long earthquakeId, Integer fireCenterCount) {
|
|
|
|
List<FireCenter> OnePlaceAllFireCenter=getOnePlaceAllFireCenter(earthquakeId);
|
|
|
|
if (fireCenterCount > MAX_FIRE_CENTER_COUNT) {
|
|
|
|
List<Double> FireCenterIntensityArr=new ArrayList<>();
|
|
|
|
// 自行修改封装后的返回值,错误:资助点数量不能过多
|
|
|
|
for(FireCenter fireCenter:OnePlaceAllFireCenter){
|
|
|
|
|
|
|
|
FireCenterIntensityArr.add(estimateController.getPointIntensity(earthquakeId, fireCenter.getFireLon(), fireCenter.getFireLat()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int FireCenterIntensityArSize=FireCenterIntensityArr.size();
|
|
|
|
|
|
|
|
System.out.print("FireCenterIntensityArSize长度为"+FireCenterIntensityArSize);
|
|
|
|
|
|
|
|
if(FireCenterIntensityArSize==0){
|
|
|
|
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Map<Integer,Integer>map = new HashMap<Integer,Integer>();
|
|
|
|
List<FireCenter> fireCenterList = getOnePlaceAllFireCenter(earthquakeId);
|
|
|
|
for(int i=0;i<FireCenterIntensityArSize;i++){
|
|
|
|
List<FireCenter> randomFireCenterList = new ArrayList<>();
|
|
|
|
map.put(i,OnePlaceAllFireCenter.get(i).getFireId());
|
|
|
|
Random random = new Random();
|
|
|
|
}
|
|
|
|
// 随机选取 fireCenterCount 个消防站
|
|
|
|
double [][] arr=new double [10][FireCenterIntensityArSize];
|
|
|
|
for (int i = 0; i < fireCenterCount; i++) {
|
|
|
|
//通过earthquakeId获得想要的地区的估计结果
|
|
|
|
if(fireCenterList.size()==0){
|
|
|
|
Estimate estimate=estimateService.queryAnalyzeById(earthquakeId);
|
|
|
|
break;
|
|
|
|
int temp=0;
|
|
|
|
|
|
|
|
for(double f:FireCenterIntensityArr){
|
|
|
|
|
|
|
|
arr[0][temp]=f*100;//属性1,对于资助点1、2、3的值,因为基本上属性是固定的,可能资助点的数量会增加,假定属性最大值为10个
|
|
|
|
|
|
|
|
arr[1][temp]=estimate.getPopulation()*f+100*Math.random();
|
|
|
|
|
|
|
|
arr[2][temp]=Math.log(estimate.getPredictDeath()*estimate.getPredictEconomy())+100*Math.random();
|
|
|
|
|
|
|
|
temp++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// arr[1]=new double[] {0.847,0.63,0.921};
|
|
|
|
|
|
|
|
// arr[2]=new double[] {524,439,842};
|
|
|
|
|
|
|
|
double [][]arrNew=new double[10][FireCenterIntensityArSize];
|
|
|
|
|
|
|
|
double [][]arrNew1=new double[10][FireCenterIntensityArSize];
|
|
|
|
|
|
|
|
double sumProvide=0;
|
|
|
|
|
|
|
|
double max;
|
|
|
|
|
|
|
|
double min;
|
|
|
|
|
|
|
|
int strictNum=arr[0].length;//代表有多少个救助点
|
|
|
|
|
|
|
|
double k=1/(Math.log((double)strictNum));
|
|
|
|
|
|
|
|
double[] e=new double[10];//第 j 项指标的熵值 ej
|
|
|
|
|
|
|
|
double[] g=new double[10];//差异性系数 gi越大指标越重要
|
|
|
|
|
|
|
|
for(int j=0;j<3;j++) {
|
|
|
|
|
|
|
|
min=max=arr[j][0];
|
|
|
|
|
|
|
|
sumProvide=0;
|
|
|
|
|
|
|
|
for(int i=0;i<arr[j].length;i++) {
|
|
|
|
|
|
|
|
if(arr[j][i]<min) {
|
|
|
|
|
|
|
|
min=arr[j][i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(arr[j][i]>max) {
|
|
|
|
|
|
|
|
max=arr[j][i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int i=0;i<arr[j].length;i++) {
|
|
|
|
|
|
|
|
arrNew[j][i]=(arr[j][i]-min)/(max-min);//假设都是正向指标,正向指标的值越大,就说明该地方越需要救助
|
|
|
|
|
|
|
|
arrNew1[j][i]=arrNew[j][i];
|
|
|
|
|
|
|
|
sumProvide+=arrNew[j][i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int i=0;i<arr[j].length;i++) {
|
|
|
|
|
|
|
|
arrNew[j][i]=(arrNew[j][i]/sumProvide)+0.0000001;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
double sumArrNewHang=0.0;
|
|
|
|
|
|
|
|
for(int i=0;i<arr[j].length;i++) {
|
|
|
|
|
|
|
|
//System.out.println("sum"+Math.log(arrNew[j][i]));
|
|
|
|
|
|
|
|
sumArrNewHang+=(arrNew[j][i]*Math.log(arrNew[j][i]));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e[j]=(-k)*sumArrNewHang;
|
|
|
|
int index = random.nextInt(fireCenterList.size());
|
|
|
|
g[j]=1-e[j];
|
|
|
|
randomFireCenterList.add(fireCenterList.get(index));
|
|
|
|
|
|
|
|
fireCenterList.remove(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
double[] a=new double[10];//每个属性所占的权数
|
|
|
|
int randomFireCenterListSize = randomFireCenterList.size();
|
|
|
|
double SumG=0.0;
|
|
|
|
if(randomFireCenterList.size()==0) {
|
|
|
|
for(int i=0;i<g.length;i++) {
|
|
|
|
// 自行修改封装后的返回值,错误:该地区没有找到消防站
|
|
|
|
SumG+=g[i];
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int i=0;i<g.length;i++) {
|
|
|
|
|
|
|
|
a[i]=g[i]/SumG;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
double[]w=new double[strictNum];
|
|
|
|
|
|
|
|
for(int j=0;j<strictNum;j++) {
|
|
|
|
|
|
|
|
w[j]=0;
|
|
|
|
|
|
|
|
for(int i=0;i<3;i++) {
|
|
|
|
|
|
|
|
w[j]+=a[i]*arrNew1[i][j];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// w[j]=1-w[j];
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Map arrayStrict=new HashMap();
|
|
|
|
double[][] arr = new double[randomFireCenterListSize][10];
|
|
|
|
List<Double> arrayW1=new ArrayList<>();
|
|
|
|
int temp = 0;
|
|
|
|
Map topTen=new LinkedHashMap();
|
|
|
|
//通过earthquakeId获得想要的地区的估计结果
|
|
|
|
List <FireWeight> resultFireWeightLists=new ArrayList<>();
|
|
|
|
Estimate estimate = estimateService.queryAnalyzeById(earthquakeId);
|
|
|
|
for(int i=0;i<strictNum;i++){
|
|
|
|
// 依次设定每个救援点的指标,最多可以设置10个指标
|
|
|
|
arrayW1.add(w[i]);
|
|
|
|
for (FireCenter fireCenter : randomFireCenterList) {
|
|
|
|
// System.out.println("第+"+(i+1)+"个地区的权重值为"+w[i]);
|
|
|
|
Double intensity = estimateController.getPointIntensity(earthquakeId, fireCenter.getFireLon(), fireCenter.getFireLat());
|
|
|
|
// arrayStrict.put(i+1,w[i]);
|
|
|
|
arr[temp][0] = intensity * 100;
|
|
|
|
arrayStrict.put(i,w[i]);
|
|
|
|
arr[temp][1] = estimate.getPopulation() * intensity + 100 * Math.random();
|
|
|
|
|
|
|
|
arr[temp][2] = Math.log(estimate.getPredictDeath() * estimate.getPredictEconomy()) + 100 * Math.random();
|
|
|
|
|
|
|
|
temp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
List<Map.Entry<Integer,Double>> entrys=new ArrayList<>(arrayStrict.entrySet());
|
|
|
|
Double[] weights = estimateUtil.entropyMethod(arr,randomFireCenterListSize,3,new ArrayList<Integer>(Arrays.asList(0,1,2)));
|
|
|
|
Collections.sort(entrys, new MyComparator());
|
|
|
|
List<FireWeight> resultFireWeightLists = new ArrayList<>();
|
|
|
|
//输出排序后的键值对
|
|
|
|
for (int i=0;i<randomFireCenterListSize;i++) {
|
|
|
|
int count=0;
|
|
|
|
FireWeight fireWeight = new FireWeight();
|
|
|
|
for(Map.Entry<Integer,Double> entry:entrys){
|
|
|
|
fireWeight.setFireId(randomFireCenterList.get(i).getFireId());
|
|
|
|
topTen.put(entry.getKey(),entry.getValue());
|
|
|
|
fireWeight.setFireLat(randomFireCenterList.get(i).getFireLat());
|
|
|
|
FireCenter resultFireCenter=getOneFireCenter(map.get(entry.getKey()));
|
|
|
|
fireWeight.setFireLon(randomFireCenterList.get(i).getFireLon());
|
|
|
|
FireWeight fireWeight=new FireWeight();
|
|
|
|
fireWeight.setFireName(randomFireCenterList.get(i).getFireName());
|
|
|
|
fireWeight.setFireId(resultFireCenter.getFireId());
|
|
|
|
fireWeight.setFireAddress(randomFireCenterList.get(i).getFireAddress());
|
|
|
|
fireWeight.setFireLat(resultFireCenter.getFireLat());
|
|
|
|
fireWeight.setFireCenterWeight(weights[i]);
|
|
|
|
fireWeight.setFireLon(resultFireCenter.getFireLon());
|
|
|
|
|
|
|
|
fireWeight.setFireName(resultFireCenter.getFireName());
|
|
|
|
|
|
|
|
fireWeight.setFireAddress(resultFireCenter.getFireAddress());
|
|
|
|
|
|
|
|
fireWeight.setFireCenterWeight(entry.getValue());
|
|
|
|
|
|
|
|
resultFireWeightLists.add(fireWeight);
|
|
|
|
resultFireWeightLists.add(fireWeight);
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if(count==30){
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 返回值自行封装
|
|
|
|
// return arrayW1;
|
|
|
|
|
|
|
|
// return topTen;
|
|
|
|
|
|
|
|
return resultFireWeightLists;
|
|
|
|
return resultFireWeightLists;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final double EARTH_RADIUS = 6378.137;
|
|
|
|
private static final double EARTH_RADIUS = 6378.137;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Gets distance.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param longitude1 the longitude 1
|
|
|
|
|
|
|
|
* @param latitude1 the latitude 1
|
|
|
|
|
|
|
|
* @param longitude2 the longitude 2
|
|
|
|
|
|
|
|
* @param latitude2 the latitude 2
|
|
|
|
|
|
|
|
* @return the distance
|
|
|
|
|
|
|
|
*/
|
|
|
|
public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
|
|
|
|
public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
|
|
|
|
// 纬度
|
|
|
|
// 纬度
|
|
|
|
double lat1 = Math.toRadians(latitude1);
|
|
|
|
double lat1 = Math.toRadians(latitude1);
|
|
|
@ -179,7 +207,7 @@ public class FireCenterController {
|
|
|
|
// 计算两点距离的公式
|
|
|
|
// 计算两点距离的公式
|
|
|
|
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
|
|
|
|
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
|
|
|
|
// 弧长乘地球半径, 返回单位: 千米
|
|
|
|
// 弧长乘地球半径, 返回单位: 千米
|
|
|
|
s = s * EARTH_RADIUS;
|
|
|
|
s = s * EARTH_RADIUS;
|
|
|
|
return s;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|