Merge branch 'master_test_gn' into master_prb_gn

back_recharge
jiahuiwen 2022-05-20 15:08:52 +08:00
commit d319cd953b
17 changed files with 359 additions and 42 deletions

View File

@ -11,6 +11,7 @@ import com.ljsd.jieling.logic.dao.ServerConfig;
import com.ljsd.jieling.logic.rank.CrossRankManager;
import com.ljsd.jieling.network.NetManager;
import com.ljsd.jieling.util.ConfigurableApplicationContextManager;
import com.ljsd.jieling.util.TaskKit;
import config.SGameSetting;
import manager.STableManager;
import org.slf4j.Logger;
@ -23,6 +24,7 @@ import util.TimeUtils;
import java.io.File;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
@Configuration
@ -81,7 +83,7 @@ public class GameApplication {
}
}
private static void setRegisterTime() throws Exception {
public static void setRegisterTime() throws Exception {
ServerConfig serverConfigTmp = MongoUtil.getInstence().getMyMongoTemplate().findById(1, ServerConfig.class);
if(serverConfigTmp == null){
serverConfigTmp = new ServerConfig();
@ -112,15 +114,23 @@ public class GameApplication {
serverConfigTmp.setRestartTime(TimeUtils.getTimeStamp2(TimeUtils.now()));
MongoUtil.getInstence().getMyMongoTemplate().saveWithoutMongoRoot(serverConfigTmp);
serverConfig = serverConfigTmp;
LOGGER.info("============================读取数据库serverConfig信息完成");
}
public static void test() {
try {
TaskKit.scheduleWithFixedDelay(()->{
LOGGER.info("**************当前开服时间:{},缓存:{}",serverConfig.getOpenTime(),TimeUtils.getTimeStamp2(serverConfig.getCacheOpenTime()));
},30,5, TimeUnit.SECONDS);
}catch (Exception e){
LOGGER.error(e.getMessage());
}
}
public static void close() throws Exception{
start = false;
NetManager.getInstance().exit();
ConfigurableApplicationContextManager.getInstance().exit();
}

View File

@ -19,15 +19,18 @@ public class ChatRedisEntity {
private int status;
private String openId;
public ChatRedisEntity(){};
public ChatRedisEntity(int uid, String name, int type, String message, Long time, int status) {
public ChatRedisEntity(int uid, String name, int type, String message, Long time, int status, String openId) {
this.uid = uid;
this.name = name;
this.type = type;
this.message = message;
this.time = time;
this.status = status;
this.openId = openId;
}
public int getUid() {
@ -77,4 +80,12 @@ public class ChatRedisEntity {
public void setStatus(int status) {
this.status = status;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
}

View File

@ -92,7 +92,7 @@ public class ChatLogic {
}
break;
case 4:
case 4: //跨服
int group = GlobleSystemLogic.getInstence().getCrossGroup();
if(group==-1){
MessageUtil.sendMessage(iSession, 1, MessageTypeProto.MessageType.GET_CHAT_MESSAGE_REPONSE_VALUE, null, true);
@ -263,7 +263,7 @@ public class ChatLogic {
if(user.getPlayerInfoManager().getSilence() == 1 || user.getPlayerInfoManager().getSkyEyeBanTime()>System.currentTimeMillis()){
silence = 1;
}
ChatRedisEntity chatRedisEntity = new ChatRedisEntity(user.getId(), user.getPlayerInfoManager().getNickName(), chatType, message, TimeUtils.now(), silence);
ChatRedisEntity chatRedisEntity = new ChatRedisEntity(user.getId(), user.getPlayerInfoManager().getNickName(), chatType, message, TimeUtils.now(), silence, user.getPlayerInfoManager().getOpenId());
String chatInfo = gson.toJson(chatRedisEntity);
long l = redisUtil.lGetListSize(key);

View File

@ -35,6 +35,7 @@ public interface Global {
int MAIL_TYPE_IDIP = 2; //idip 邮件
int MAIL_TYPE_GM = 3; // GM 邮件
int MAIL_EFFECTIVE_TIME = 720 * 60 * 60; // 有效时间 30天
int MAIL_EFFECTIVE_TIME_SERVEN = 168 * 60 * 60; // 有效时间 7天
int MAIL_NOUSE_DELETE_TIME = 3;//已读邮件和已领取邮件3天后自动删除
//sysMail state
int SYS_MAIL_STATE_NEW = 1; //未发布

View File

@ -0,0 +1,25 @@
package com.ljsd.jieling.kefu;
import com.ljsd.GameApplication;
import com.ljsd.jieling.db.mongo.MongoUtil;
import com.ljsd.jieling.logic.dao.GuilidManager;
import com.ljsd.jieling.logic.dao.PlayerManager;
import com.ljsd.jieling.logic.dao.root.GuildInfo;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.family.CrossDeathPathLogic;
import config.SGuildSetting;
import util.TimeUtils;
public class Cmd_reloadserverconfig extends GmAbstract {
@Override
public boolean exec(String[] args) throws Exception {
return false;
}
@Override
public String exec2(String[] args) throws Exception {
GameApplication.setRegisterTime();
return "true";
}
}

View File

@ -9,10 +9,7 @@ import com.ljsd.jieling.core.FunctionManager;
import com.ljsd.jieling.core.function.FunctionContext;
import com.ljsd.jieling.db.mongo.MongoUtil;
import com.ljsd.jieling.handler.map.MapLogic;
import com.ljsd.jieling.logic.activity.ActivityLogic;
import com.ljsd.jieling.logic.activity.FightMainEventHandler;
import com.ljsd.jieling.logic.activity.RemoveEventHeroHandler;
import com.ljsd.jieling.logic.activity.UserLevelEventHandler;
import com.ljsd.jieling.logic.activity.*;
import com.ljsd.jieling.logic.activity.activityLogic.WeekCardLogic;
import com.ljsd.jieling.logic.activity.event.Poster;
import com.ljsd.jieling.logic.activity.event.SaveHeroForceEvent;
@ -520,6 +517,11 @@ public class GlobalDataManaager implements IManager {
HeroLogic.getInstance().resetWishDrawCardInfoMap(user);
//玉虚论道每日刷新
user.getArenaManager().setCrossYuxulundaoDailyRewad(new ArrayList<>(Arrays.asList(0,0,0)));
//终身卡在线跨天
AbstractActivity abstractActivity = ActivityTypeEnum.getActicityType(9901);
if(abstractActivity instanceof WholeLifeActivity){
((WholeLifeActivity)abstractActivity).calWhenLogin(user);
}
///清空当天推送的礼包次数
user.getPlayerInfoManager().getNewRechargeInfo().ClearDayPushMap();
}

View File

@ -40,7 +40,7 @@ import java.util.*;
public abstract class AbstractActivity implements IActivity, IEventHandler {
static final Logger LOGGER = LoggerFactory.getLogger(AbstractActivity.class);
final int rewardResponseValue = MessageTypeProto.MessageType.TAKE_ACTIVITY_REWARD_RESPONSE_VALUE;
int id; //活动id
int id; //活动idid
public AbstractActivity(int id) {
this.id = id;

View File

@ -1718,7 +1718,8 @@ public class ActivityLogic implements IEventHandler{
CommonProto.Drop.Builder drop = null;
int[] markReward = new int[]{0,0};
int[][] markRewards = new int[num][];
int[][] markRewards = new int[num+1][];
markRewards[num] = setting.getRecruit();
// 单抽
if (num == 1){
// 验证免费特权

View File

@ -131,4 +131,5 @@ public interface ActivityType {
int LING_LONG_PAVILION = 20005;//玲珑宝阁
int DAILY_SPECIAL = 10004;//每日特惠
int WHOLE_LIFE_CARD = 99;//终生卡
}

View File

@ -108,6 +108,7 @@ public enum ActivityTypeEnum {
EXPLORE_EXPECT_ACTIVITY(ActivityType.EXPLORE_EXPECT_ACTIVITY,ExploreExpectActivity::new),
POWER_RICE_ACTIVITY(ActivityType.POWER_RICE_ACTIVITY,PowerRiceActivity::new),//战力冲刺
DONGHAI_XUNXIAN_ACTIVITY(ActivityType.DonghaiXunxian,DonghaiXunxianActivity::new),//东海寻仙
WHOEL_LIFE_ACTIVITY(ActivityType.WHOLE_LIFE_CARD,WholeLifeActivity::new),//东海寻仙
;
private int type;

View File

@ -1,14 +1,25 @@
package com.ljsd.jieling.logic.activity;
import com.ljsd.GameApplication;
import com.ljsd.jieling.exception.ErrorCode;
import com.ljsd.jieling.exception.ErrorCodeException;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.jbean.ActivityMission;
import com.ljsd.jieling.jbean.ActivityProgressInfo;
import com.ljsd.jieling.logic.OnlineUserManager;
import com.ljsd.jieling.logic.activity.event.ActivityStateChangeEvent;
import com.ljsd.jieling.logic.activity.event.Poster;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.store.newRechargeInfo.NewRechargeInfo;
import com.ljsd.jieling.network.session.ISession;
import com.ljsd.jieling.util.ItemUtil;
import com.ljsd.jieling.util.MessageUtil;
import config.SActivityRewardConfig;
import config.SGlobalActivity;
import config.SLuxuryFund;
import rpc.protocols.CommonProto;
import rpc.protocols.PlayerInfoProto;
import util.TimeUtils;
import java.util.ArrayList;
@ -23,45 +34,139 @@ class RechargeTotalActivity extends AbstractActivity {
}
@Override
boolean takeRewardsProcess(ISession session, SActivityRewardConfig sActivityRewardConfig, ActivityProgressInfo activityProgressInfo) throws Exception {
int[][] values = sActivityRewardConfig.getValues();
int missionProgress = activityProgressInfo.getProgrss();
long now = TimeUtils.now();
public void initActivity(User user) throws Exception {
ActivityMission mission = new ActivityMission();
// 初始化阶段奖励
ActivityLogic.getInstance().initOtherMission(mission, new ArrayList<>());
user.getActivityManager().getActivityMissionMap().put(id, mission);
LOGGER.info("累计充值初始化..."+id);
}
/**
*
* @param session
* @param missionId
* @return
* @throws Exception
*/
@Override
public boolean takeReward(ISession session, int missionId) throws Exception {
User user = UserManager.getUser(session.getUid());
NewRechargeInfo rechargeInfo = user.getPlayerInfoManager().getNewRechargeInfo();
int days = TimeUtils.differentDaysByHour(rechargeInfo.getFirstTime(), now,0) + 1;
if (missionProgress <= 0 || days < values[0][1]) {
// activity check
ActivityMission mission = user.getActivityManager().getActivityMissionMap().get(id);
if (mission == null){
throw new ErrorCodeException(ErrorCode.SYS_ERROR_CODE,"活动信息不存在:"+id);
}
// 获取活动标签信息
SActivityRewardConfig config = SActivityRewardConfig.getsActivityRewardConfigByMissionId(missionId);
ActivityProgressInfo info = mission.getActivityMissionMap().get(missionId);
// 条件判断
int state = getState(user, config, info);
if (state != 2){
return false;
}
// 改库
info = new ActivityProgressInfo();
checkAndSetProgress(mission,info,missionId);
// reward
CommonProto.Drop.Builder drop = ItemUtil.drop(user, config.getReward(), BIReason.TAKE_ACTIVITY_REWARD);
PlayerInfoProto.TakeActivityRewardResponse build = PlayerInfoProto.TakeActivityRewardResponse.newBuilder().setDrop(drop).build();
MessageUtil.sendMessage(session, 1, rewardResponseValue, build, true);
// 状态推送
sendActivityProgress(session, mission, null);
// 打点上报
reportTakeActivityReward(user,config.getReward(),missionId);
return true;
}
/**
*
* 0
* 1
* 2
* @param user
* @param config
* @param info
* @return
*/
int getState(User user, SActivityRewardConfig config, ActivityProgressInfo info){
// 表里为空
if (config == null){
return 0;
}
// 数据库已保存且状态为已领取
if (info != null && info.getState() == 1){
return 1;
}
long now = TimeUtils.now();
NewRechargeInfo rechargeInfo = user.getPlayerInfoManager().getNewRechargeInfo();
int days = TimeUtils.differentDaysByHour(rechargeInfo.getFirstTime(), now,0) + 1;
// 判断金额和天数
if (rechargeInfo.getRr() >= config.getValues()[0][0] && days >= config.getValues()[0][1]){
return 2;
}
return 0;
}
@Override
public List<CommonProto.ActivityInfo.MissionInfo> getAllMissInfo(User user, ActivityMission activityMission, Set<Integer> filter) {
Map<Integer, ActivityProgressInfo> activityProgressInfoMap = activityMission.getActivityMissionMap();
List<CommonProto.ActivityInfo.MissionInfo> missionInfos = new ArrayList<>(activityProgressInfoMap.size());
long openTime = TimeUtils.stringToTimeLong2(GameApplication.serverConfig.getOpenTime());
for (Map.Entry<Integer, ActivityProgressInfo> missionProgress : activityProgressInfoMap.entrySet()) {
if (filter != null && !filter.contains(missionProgress.getKey())) {
continue;
}
Integer missionId = missionProgress.getKey();
SActivityRewardConfig sActivityRewardConfig = SActivityRewardConfig.getsActivityRewardConfigByMissionId(missionId);
if (sActivityRewardConfig == null) {
continue;
}
if(id == ActivityType.RechargeTotal){
// 2021-12-22 09:00:00 之后开的服首充不显示累充满100元任务
if (openTime > 1640134800000L) {
int value = sActivityRewardConfig.getValues()[0][0];
if (value == 100) {
continue;
}
}
}
ActivityProgressInfo activityProgressInfo = missionProgress.getValue();
missionInfos.add(CommonProto.ActivityInfo.MissionInfo.newBuilder().setMissionId(missionId).setProgress(activityProgressInfo.getProgrss()).setState(activityProgressInfo.getState()).build());
if (activityMission == null){
return new ArrayList<>();
}
// 库里存储的
Map<Integer, ActivityProgressInfo> progressInfoMap = activityMission.getActivityMissionMap();
// 表里的
List<SActivityRewardConfig> rewardConfigs = SActivityRewardConfig.getsActivityRewardConfigByActivityId(id);
List<CommonProto.ActivityInfo.MissionInfo> missionInfos = new ArrayList<>(rewardConfigs.size());
int progress = (int) (user.getPlayerInfoManager().getNewRechargeInfo().getRr() * 1000);
for (SActivityRewardConfig config : rewardConfigs) {
ActivityProgressInfo info = progressInfoMap.get(config.getId());
int state = getState(user, config, info);
state = state == 1?1:0;
CommonProto.ActivityInfo.MissionInfo build = CommonProto.ActivityInfo.MissionInfo.newBuilder()
.setMissionId(config.getId())
.setProgress(progress)
.setState(state)
.build();
missionInfos.add(build);
}
return missionInfos;
}
@Override
public void update(User user, int count) {
ActivityMission activityMission = user.getActivityManager().getActivityMissionMap().get(id);
if(null == activityMission){
return;
}
//更新进度
ISession sessionByUid = OnlineUserManager.getSessionByUid(user.getId());
sendActivityProgress(sessionByUid, activityMission, null);
}
public boolean checkActivityMissionFinishAndTake(int uid,int activityId,ActivityMission activityMission){
try {
User user = UserManager.getUser(uid);
Map<Integer, ActivityProgressInfo> missionMap = activityMission.getActivityMissionMap();
List<SActivityRewardConfig> rewardConfigs = SActivityRewardConfig.getsActivityRewardConfigByActivityId(id);
for (SActivityRewardConfig config : rewardConfigs) {
ActivityProgressInfo info = missionMap.get(config.getId());
int state = getState(user, config, info);
if (state != ActivityType.HAD_TAKED) {
return false;
}
}
}catch (Exception e){
e.printStackTrace();
return false;
}
SGlobalActivity sGlobalActivity = SGlobalActivity.getsGlobalActivityMap().get(activityId);
if(sGlobalActivity.getResetGrade()==0){
activityMission.setActivityState(ActivityType.FINISH_STATE);
Poster.getPoster().dispatchEvent(new ActivityStateChangeEvent(uid,activityId,ActivityType.FINISH_STATE));
}
return true;
}
}

View File

@ -0,0 +1,129 @@
package com.ljsd.jieling.logic.activity;
import com.ljsd.jieling.exception.ErrorCode;
import com.ljsd.jieling.exception.ErrorCodeException;
import com.ljsd.jieling.globals.BIReason;
import com.ljsd.jieling.globals.Global;
import com.ljsd.jieling.jbean.ActivityManager;
import com.ljsd.jieling.jbean.ActivityMission;
import com.ljsd.jieling.jbean.ActivityProgressInfo;
import com.ljsd.jieling.logic.dao.UserManager;
import com.ljsd.jieling.logic.dao.root.User;
import com.ljsd.jieling.logic.mail.MailLogic;
import com.ljsd.jieling.network.session.ISession;
import com.ljsd.jieling.util.ItemUtil;
import com.ljsd.jieling.util.MessageUtil;
import config.SActivityRewardConfig;
import config.SErrorCodeEerverConfig;
import config.SRechargeCommodityNewConfig;
import rpc.protocols.CommonProto;
import rpc.protocols.PlayerInfoProto;
import util.TimeUtils;
import java.util.ArrayList;
/**
*
*/
public class WholeLifeActivity extends AbstractActivity {
public WholeLifeActivity(int id) {
super(id);
}
@Override
public void initActivity(User user) throws Exception {
super.initActivity(user);
ActivityMission mission = new ActivityMission();
// 活动信息初始化
//SRechargeCommodityNewConfig config = SRechargeCommodityNewConfig.getConfigById(1000);
/*List<SActivityRewardConfig> rewardConfigs = SActivityRewardConfig.getsActivityRewardConfigByActivityId(id);
ArrayList<Integer> integers = new ArrayList<>(rewardConfigs.size());
rewardConfigs.forEach(v->integers.add(v.getId()));*/
ActivityLogic.getInstance().initOtherMission(mission, new ArrayList<>());
mission.setCreatTime(0);
user.getActivityManager().getActivityMissionMap().put(id, mission);
LOGGER.info("神尊特权初始化...uid={} activityId={}", user.getId(), id);
}
public void calWhenLogin(User user) throws Exception {
ActivityManager activityManager = user.getActivityManager();
ActivityMission activityMission = activityManager.getActivityMissionMap().get(id);
if (activityMission == null) {
return;
}
if (activityMission.getActivityState() != ActivityType.OPEN_STATE || activityMission.getOpenType() == 0) {
return;
}
if (activityMission.getCreatTime() == 0) {
return;
}
activityMission.setV(1);
long time = 0;
if (user.getPlayerInfoManager().getLastWholeLifeTime() == 0) {
time = activityMission.getCreatTime();
} else {
time = user.getPlayerInfoManager().getLastWholeLifeTime();
}
int day = (int) TimeUtils.getGapDaysByTwoTime(TimeUtils.getTimeStamp2(time),
TimeUtils.getTimeStamp2(TimeUtils.now())) - 1;
if (day <= 0) {
return;
}
if (day > 7) {
day = 7;
}
user.getPlayerInfoManager().setLastWholeLifeTime(TimeUtils.now());
String title = SErrorCodeEerverConfig.getI18NMessage("shenzuntequan_mail_title");
String content = SErrorCodeEerverConfig.getI18NMessage("shenzuntequan_mail_txt");
SRechargeCommodityNewConfig config = SRechargeCommodityNewConfig.getConfigById(1000);
String mailReward = ItemUtil.getMailReward(config.getExtraReward());
int nowTime = (int) (TimeUtils.now() / 1000);
for (int i = day; i > 0; i--) {
MailLogic.getInstance().sendMail(user.getId(), title, content, mailReward, nowTime, Global.MAIL_EFFECTIVE_TIME_SERVEN);
}
//ActivityLogic.getInstance().sendActivityInfo(user, id);
}
@Override
boolean takeRewardsProcess(ISession session, SActivityRewardConfig sActivityRewardConfig,
ActivityProgressInfo activityProgressInfo) throws Exception {
return false;
}
@Override
public boolean takeReward(ISession session, int missionId) throws Exception {
User user = UserManager.getUser(session.getUid());
ActivityManager activityManager = user.getActivityManager();
ActivityMission activityMission = activityManager.getActivityMissionMap().get(id);
if (activityMission == null) {
throw new ErrorCodeException(ErrorCode.SERVER_SELF_DEFINE);
}
if (activityMission.getActivityState() != ActivityType.OPEN_STATE || activityMission.getOpenType() == 0) {
throw new ErrorCodeException(ErrorCode.ACTIVITY_NOT_OPEN);
}
if (activityMission.getV() != 1) {
return false;
}
activityMission.setV(2);
user.getPlayerInfoManager().setLastWholeLifeTime(TimeUtils.now());
SRechargeCommodityNewConfig config = SRechargeCommodityNewConfig.getConfigById(1000);
CommonProto.Drop.Builder drop = ItemUtil.drop(user, config.getExtraReward(), BIReason.TAKE_ACTIVITY_REWARD);
PlayerInfoProto.TakeActivityRewardResponse build = PlayerInfoProto.TakeActivityRewardResponse.newBuilder().setDrop(drop).build();
MessageUtil.sendMessage(session, 1, rewardResponseValue, build, true);
return true;
}
/* public boolean checkActivityMissionFinishAndTake(int uid,int activityId,ActivityMission activityMission) {
try{
User user = UserManager.getUser(uid);
calWhenLogin(user);
}catch (Exception e){
}
return true;
}*/
}

View File

@ -231,6 +231,17 @@ public class PlayerManager extends MongoBase {
private int exploreKillTotalNum; //探索杀敌总数
private long lastWholeLifeTime;//最近一次领取终身卡的时间
public long getLastWholeLifeTime() {
return lastWholeLifeTime;
}
public void setLastWholeLifeTime(long lastWholeLifeTime) {
this.lastWholeLifeTime = lastWholeLifeTime;
updateString("lastWholeLifeTime", lastWholeLifeTime);
}
public int getExploreKillTotalNum() {
return exploreKillTotalNum;
}

View File

@ -473,6 +473,14 @@ public class BuyGoodsNewLogic {
AbstractActivity abstractActivity = ActivityTypeEnum.getActicityType(ActivityType.DAILY_PREFERENTIAL_GIFT);
abstractActivity.initActivity(user);
}
if(type ==GiftGoodsType.WholeLife){
AbstractActivity abstractActivity = ActivityTypeEnum.getActicityType(9901);
abstractActivity.initActivity(user);
ActivityMission activityMission = user.getActivityManager().getActivityMissionMap().get(9901);
activityMission.setV(2);
activityMission.setCreatTime(TimeUtils.now());
user.getActivityManager().getActivityMissionMap().put(9901, activityMission);
}
if(drop!=null&&session!=null){
PlayerInfoProto.DirectBuyIndication build = PlayerInfoProto.DirectBuyIndication.newBuilder().setDrop(drop).build();
MessageUtil.sendIndicationMessage(session,1, MessageTypeProto.MessageType.DIRECT_BUY_GOODS_INDICATION_VALUE,build,true);

View File

@ -16,6 +16,7 @@ public interface GiftGoodsType {
int ENDLESS_TREASURE = 14;//无尽秘宝
int DailyPreferentialGift = 17 ;//每日特惠礼包
int RechargeSumDay = 18 ;//超值返利礼包(在积天豪礼活动里购买)
int WholeLife = 19 ;//【神尊特权】活动 购买后每日领取奖励
}

View File

@ -66,6 +66,7 @@ public class SRechargeCommodityNewConfig implements BaseConfig {
private String[][] condition;
private int isRecommond;
private int[][] extraReward;
public static Map<Integer,SRechargeCommodityNewConfig> configMap;
public static Map<String,SRechargeCommodityNewConfig> sdkconfigMap;
@ -216,4 +217,8 @@ public class SRechargeCommodityNewConfig implements BaseConfig {
public int getIsRecommond() {
return isRecommond;
}
public int[][] getExtraReward() {
return extraReward;
}
}

View File

@ -19,6 +19,8 @@ public class SWishActivitySetting implements BaseConfig {
private int maxTimes;
private int diamondMaxTimes;
private int[] recruit;
@Override
public void init() throws Exception {
@ -49,4 +51,8 @@ public class SWishActivitySetting implements BaseConfig {
public int getDiamondMaxTimes() {
return diamondMaxTimes;
}
public int[] getRecruit() {
return recruit;
}
}