ソースを参照

Merge remote-tracking branch 'origin/master'

yumeng 4 年 前
コミット
e8b13fdf85
14 ファイル変更241 行追加31 行削除
  1. 21 18
      jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java
  2. 1 0
      module-common/src/main/java/cn/com/ctop/common/module/entity/Project.java
  3. 3 0
      module-common/src/main/java/cn/com/ctop/common/module/service/IProjectService.java
  4. 11 0
      module-common/src/main/java/cn/com/ctop/common/module/service/impl/ProjectServiceImpl.java
  5. 1 0
      module-common/src/main/java/cn/com/ctop/common/module/utils/StatusCode.java
  6. 124 0
      module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMonitoringLinksCheckJob.java
  7. 2 0
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaiShouDailyAgentMapper.java
  8. 47 1
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaiShouDailyAgentMapper.xml
  9. 3 4
      module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouReportDailyAgentServiceImpl.java
  10. 5 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/entity/ByteDanceAdvertisePlan.java
  11. 2 2
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/IByteDanceAdvertisePlanService.java
  12. 9 0
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceAdvertisePlanServiceImpl.java
  13. 11 1
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceCreativeServiceImpl.java
  14. 1 5
      module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/controller/ByteDanceVideoReportDailyController.java

+ 21 - 18
jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java

@@ -48,13 +48,16 @@ public class SampleTest {
     private IByteDanceAdvertiserDataService advertiserDataService;
     @Test
     public void loadBytedanceCreativeData() {
-        List<UserAllocation>allocations = userAllocationService.getByParams(633L,null,0);
-        if(null!=allocations&&!allocations.isEmpty()){
-            for (UserAllocation allocation:allocations) {
-                CtopOauthToken token = oauthTokenService.getTokenByAccountId(allocation.getAccountId());
-                advertiserDataService.getAdvertiserPlan(token, "", null, null);
-            }
-        }
+//        List<UserAllocation>allocations = userAllocationService.getByParams(633L,null,0);
+//
+//        if(null!=allocations&&!allocations.isEmpty()){
+//            for (UserAllocation allocation:allocations) {
+//                CtopOauthToken token = oauthTokenService.getTokenByAccountId(allocation.getAccountId());
+//                advertiserDataService.getAdvertiserPlan(token, "", null, null);
+//            }
+//        }
+        CtopOauthToken token = oauthTokenService.getTokenByAccountId(1667284088260616L);
+        advertiserDataService.getAdvertiserPlan(token, "", null, null);
     }
 
     @Autowired
@@ -127,18 +130,18 @@ public class SampleTest {
     @Test
     public void loadKuaishouAgentData() {
         kuaishouReportDailyAgentService.loginAgent();
-        for(int i=0;i<20;i++){
-            String currentDate = DateUtils.formatDate(DateUtils.addDay(new Date(),-i));
-            kuaishouReportDailyAgentService.getReport(currentDate,DateUtils.getNowDate("yyyy-MM-dd"));
-        }
-//
-//        try {
-//            for (int i = 1; i < 30; i++) {
-//                kuaishouReportDailyAgentService.getAccount(i);
-//            }
-//        } catch (Exception e) {
-//            e.printStackTrace();
+//        for(int i=0;i<20;i++){
+//            String currentDate = DateUtils.formatDate(DateUtils.addDay(new Date(),-i));
+//            kuaishouReportDailyAgentService.getReport(currentDate,DateUtils.getNowDate("yyyy-MM-dd"));
 //        }
+//
+        try {
+            for (int i = 1; i < 30; i++) {
+                kuaishouReportDailyAgentService.getAccount(i);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 
     @Autowired

+ 1 - 0
module-common/src/main/java/cn/com/ctop/common/module/entity/Project.java

@@ -114,6 +114,7 @@ public class Project {
      * 最高深度转化出价
      */
     private BigDecimal maxDeepCpaBid;
+    private Integer checkLink;
     /**
      * 创建时间
      */

+ 3 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/IProjectService.java

@@ -3,6 +3,8 @@ package cn.com.ctop.common.module.service;
 import cn.com.ctop.common.module.entity.Project;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * 项目
  *
@@ -12,4 +14,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IProjectService extends IService<Project> {
 
+    List<Project> listByMediaType(int projectType,int checkLink);
 }

+ 11 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/impl/ProjectServiceImpl.java

@@ -3,9 +3,12 @@ package cn.com.ctop.common.module.service.impl;
 import cn.com.ctop.common.module.entity.Project;
 import cn.com.ctop.common.module.mapper.ProjectMapper;
 import cn.com.ctop.common.module.service.IProjectService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * 项目
  *
@@ -16,4 +19,12 @@ import org.springframework.stereotype.Service;
 @Service
 public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {
 
+    @Override
+    public List<Project> listByMediaType(int projectType,int checkLink) {
+        QueryWrapper<Project>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("media_id",projectType);
+        queryWrapper.eq("checkLink",checkLink);
+        queryWrapper.orderByDesc("id");
+        return this.list(queryWrapper);
+    }
 }

+ 1 - 0
module-common/src/main/java/cn/com/ctop/common/module/utils/StatusCode.java

@@ -21,6 +21,7 @@ public enum StatusCode {
     COMMON_SUCCESS("操作成功", 0, true),
     COMMON_PARAM_ERROR("参数异常", -1, false),
     COMMON_ACCOUNT_ERROR("参数异常", -2, false),
+    COMMON_INTERNET_ERROR("网络请求异常", -3, false),
     COMMON_DATA_NOT_EXIST("数据不存在或者已经被删除", -101, false),
     BYTEDANCE_PLAN_DATA_NOT_EXIST("此计划不存在或者已经被删除", -101, false),
     BYTEDANCE_ACCOUNT_DATA_NOT_EXIST("此账户尚未绑定或已停投", -101, false),

+ 124 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMonitoringLinksCheckJob.java

@@ -0,0 +1,124 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.common.module.entity.Project;
+import cn.com.ctop.common.module.entity.UserAllocation;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.service.IProjectService;
+import cn.com.ctop.common.module.service.ISendMessageService;
+import cn.com.ctop.common.module.service.IUserAllocationService;
+import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceCreativeService;
+import com.alibaba.fastjson.JSONObject;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.Map;
+
+public class BytedanceMonitoringLinksCheckJob {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IUserAllocationService allocationService;
+    @Autowired
+    private IByteDanceAdvertisePlanService advertisePlanService;
+    @Autowired
+    private IByteDanceCreativeService creativeService;
+    @Autowired
+    private ISendMessageService sendMessageService;
+    @Autowired
+    private IProjectService projectService;
+
+    @XxlJob("bytedanceMonitoringLinksCheckJob")
+    public ReturnT<String> execute(String param) throws Exception{
+        List<Project> projects = projectService.listByMediaType(3,1);
+        if(null==projects||projects.isEmpty()){
+            return ReturnT.SUCCESS;
+        }
+        for (Project project:projects) {
+            List<UserAllocation>allocations = allocationService.getByParams(project.getId(),null,0);
+            if(null==allocations||allocations.isEmpty()){
+                continue;
+            }
+            for(UserAllocation allocation:allocations){
+                List<ByteDanceAdvertisePlan> plans = advertisePlanService.getAllPlans(allocation.getAccountId());
+                if(null!=plans&&!plans.isEmpty()){
+                    for (ByteDanceAdvertisePlan plan:plans) {
+                        Map<String, Object> creativeDetail = creativeService.getCreativeDetail(allocation.getAccountId(), plan.getId());
+                        if(null!=creativeDetail.get("data")){
+                            JSONObject data = (JSONObject) creativeDetail.get("data");
+                            checkMonitorLink(data,plan,allocation);
+                        }
+                    }
+                }
+            }
+        }
+        XxlJobLogger.log("监测链接检查完成");
+        return ReturnT.SUCCESS;
+    }
+
+    private void checkMonitorLink(JSONObject data, ByteDanceAdvertisePlan plan, UserAllocation allocation) {
+        String downloadUrl = plan.getDownloadUrl();
+        boolean errorflag = false;
+        String errorMsg = "";
+        String token = plan.getName().split("-")[0];
+        String tokenInfo = "surl_token="+token;
+        String appType = plan.getAppType();
+
+        if(null!=downloadUrl){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!downloadUrl.equals("https://apps.apple.com/cn/app/id1468454200")){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!downloadUrl.contains(token)){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //展示监测链接
+        String trackUrl = data.getString("trackUrl");
+        if(null!=trackUrl&&!trackUrl.trim().equals("")){
+            if(!trackUrl.contains(tokenInfo)){
+                errorMsg+= "展示监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        //点击监测链接
+        String actionTrackUrl = data.getString("actionTrackUrl");
+        if(null!=actionTrackUrl&&!actionTrackUrl.trim().equals("")){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("app_platform=ios")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("tt/1967")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //视频有效播放监测链接
+        String videoPlayEffectiveTrackUrl = data.getString("videoPlayEffectiveTrackUrl");
+        if(null!=videoPlayEffectiveTrackUrl&&!videoPlayEffectiveTrackUrl.trim().equals("")){
+            if(!actionTrackUrl.contains(tokenInfo)){
+                errorMsg+= "视频有效播放监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        if(errorflag){
+            sendMessage(allocation,"警告:账户:"+allocation.getAuthName()+"(id:"+allocation.getAccountId()+")下的广告计划:"+plan.getName()+"(id:"+plan.getId()+")"+"监测链接异常>>"+errorMsg);
+        }
+    }
+    private void sendMessage(UserAllocation allocation, String errorMsg) {
+        sendMessageService.sendMessage(allocation.getUserId(),errorMsg);
+    }
+}

+ 2 - 0
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/KuaiShouDailyAgentMapper.java

@@ -23,4 +23,6 @@ public interface KuaiShouDailyAgentMapper extends BaseMapper<KuaiShouDailyAgent>
     KuaishouReportDailyAgentSum companyReportSum(@Param("startDate") String startDate, @Param("endDate") String endDate);
 
     List<KuaishouReportDailyAgent> companyReportAccountDetailList(@Param("date") String date, @Param("advertiserName") String advertiserName, @Param("isExportNullData") Integer o);
+
+    void replaceBatch(@Param(value = "list") List<KuaiShouDailyAgent> list);
 }

+ 47 - 1
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/mapper/xml/KuaiShouDailyAgentMapper.xml

@@ -297,5 +297,51 @@
             </if>
         </trim>
     </insert>
+    <insert id="replaceBatch">
+        replace into ctop_kuaishou_daily_agent(
+        `date`,
+        `account_id`,
+        `kid`,
+        `advertiser_name`,
+        `advertiser_create_time`,
+        `cost_campaign_count`,
+        `balance`,
+        `cost`,
+        `xianjin_cost`,
+        `fandian_cost`,
+        `kuangfan_cost`,
+        `jili_cost`,
+        `xinyong_cost`,
+        `fengmian_show_count`,
+        `fengmian_click_count`,
+        `sucai_show_count`,
+        `convert_count`,
+        `fengmian_click_rate`,
+        `convert_click_rate`
+        )
+        values
+        <foreach collection="list" item="agent" separator=",">
+            (#{agent.date},
+            #{agent.accountId},
+            #{agent.kid},
+            #{agent.advertiserName},
+            #{agent.advertiserCreateTime},
+            #{agent.costCampaignCount},
+            #{agent.balance},
+            #{agent.cost},
+            #{agent.xianjinCost},
+            #{agent.fandianCost},
+            #{agent.kuangfanCost},
+            #{agent.jiliCost},
+            #{agent.xinyongCost},
+            #{agent.fengmianShowCount},
+            #{agent.fengmianClickCount},
+            #{agent.sucaiShowCount},
+            #{agent.convertCount},
+            #{agent.fengmianClickRate},
+            #{agent.convertClickRate})
+        </foreach>
 
-</mapper>
+    </insert>
+
+</mapper>

+ 3 - 4
module-kuaishou/src/main/java/cn/com/ctop/kuaishou/modules/report/service/impl/KuaishouReportDailyAgentServiceImpl.java

@@ -54,6 +54,8 @@ public class KuaishouReportDailyAgentServiceImpl extends ServiceImpl<KuaishouRep
     @Autowired
     private KuaishouReportDailyAgentSumMapper kuaishouReportDailyAgentSumMapper;
     @Autowired
+    private KuaishouReportDailyAgentMapper kuaishouReportDailyAgentMapper;
+    @Autowired
     private KuaishouAgentAccountMapper kuaishouAgentAccountMapper;
     @Value("${jeecg.path.chrome-driver}")
     private String chromeDriver;
@@ -62,7 +64,7 @@ public class KuaishouReportDailyAgentServiceImpl extends ServiceImpl<KuaishouRep
 
     @Override
     public void replaceBatch(List<KuaiShouDailyAgent> list) {
-        for(KuaiShouDailyAgent agent:list){
+        for (KuaiShouDailyAgent agent:list) {
             kuaiShouDailyAgentMapper.insert(agent);
         }
     }
@@ -240,9 +242,6 @@ public class KuaishouReportDailyAgentServiceImpl extends ServiceImpl<KuaishouRep
     @Override
     public void getReport(String startDate, String endDate) {
         try {
-            if (!loginAgent()) {
-                return;
-            }
             String currentDate = startDate;
             Map<String, String> headerMap = new HashMap<>();
             headerMap.put("Accept", "application/json");

+ 5 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/entity/ByteDanceAdvertisePlan.java

@@ -380,6 +380,11 @@ public class ByteDanceAdvertisePlan {
             this.downloadType = downloadType;
         }
 
+        String downloadUrl = dataObject.getString("download_url");
+        if (null != downloadUrl && !"".equals(downloadUrl.trim())) {
+            this.downloadUrl = downloadUrl;
+        }
+
         String externalUrl = dataObject.getString("external_url");
         if (null != externalUrl && !"".equals(externalUrl.trim())) {
             this.externalUrl = externalUrl;

+ 2 - 2
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/IByteDanceAdvertisePlanService.java

@@ -3,9 +3,7 @@ package cn.com.ctop.toutiao.modules.material.service;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
 import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
-import jdk.nashorn.internal.scripts.JS;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -45,4 +43,6 @@ public interface IByteDanceAdvertisePlanService extends IService<ByteDanceAdvert
 
     //查询需要预警的深度转化出价
     List<String> selectWarningCpaBid(Long accountId, BigDecimal maxCapBid);
+
+    List<ByteDanceAdvertisePlan> getAllPlans(Long accountId);
 }

+ 9 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceAdvertisePlanServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.toutiao.modules.material.mapper.ByteDanceAdvertisePlanMapper;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -408,6 +409,14 @@ public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdve
         return byteDanceAdvertisePlanMapper.selectWarningCpaBid(accountId, maxCapBid);
     }
 
+    @Override
+    public List<ByteDanceAdvertisePlan> getAllPlans(Long accountId) {
+        QueryWrapper<ByteDanceAdvertisePlan>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id",accountId+"");
+        queryWrapper.ne("opt_status","AD_STATUS_DELETE");
+        return this.list(queryWrapper);
+    }
+
     private Map<String, Object> queryAdByAdId(CtopOauthToken token, Long accountId, List adId){
 
         Map<String, String> headers = new HashMap<>();

+ 11 - 1
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceCreativeServiceImpl.java

@@ -207,16 +207,19 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
         Map<String,Object>resultMap = new HashMap<>();
         if(null == planId||planId == 0||null == accountId||accountId == 0){
             ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_PARAM_ERROR);
+            resultMap.put("data",null);
             return resultMap;
         }
         UserAllocation allocation = userAllocationService.getByAccountId(accountId);
         if(null == allocation||allocation.getAccountStatus()!=0){
             ResultMapUtils.setResultMap(resultMap,StatusCode.BYTEDANCE_PLAN_DATA_NOT_EXIST);
+            resultMap.put("data",null);
             return resultMap;
         }
         ByteDanceAdvertisePlan plan = byteDanceAdvertisePlanService.getById(planId);
         if(null == plan||plan.getOptStatus().equals("AD_STATUS_DELETE")){
             ResultMapUtils.setResultMap(resultMap,StatusCode.BYTEDANCE_ACCOUNT_DATA_NOT_EXIST);
+            resultMap.put("data",null);
             return resultMap;
         }
         CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
@@ -227,12 +230,18 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
         data.put("advertiser_id", token.getAccountId());
         data.put("ad_id",planId);
         JSONObject result = HttpUtils.bytedanceGetRequest(token.getAccessToken(),url,data);
+        if(null == result){
+            ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_INTERNET_ERROR);
+            resultMap.put("data",null);
+            return resultMap;
+        }
         Integer code = result.getInteger("code");
         String message = result.getString("message");
         if (null ==  code) {
             log.info("广告创意获取详情失败,accountId:{},message:{}", accountId, message);
             resultMap.put("success", false);
             resultMap.put("code", -1);
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }
@@ -240,7 +249,7 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
             //尚未创建创意
             resultMap.put("success", true);
             resultMap.put("code", 0);
-            result.put("data","");
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }
@@ -248,6 +257,7 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
             log.info("广告创意获取详情失败,accountId:{},message:{}", accountId, message);
             resultMap.put("success", false);
             resultMap.put("code", -1);
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }

+ 1 - 5
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/report/controller/ByteDanceVideoReportDailyController.java

@@ -124,10 +124,8 @@ public class ByteDanceVideoReportDailyController {
 	 @AutoLog(value = "头条视频按天汇总")
 	 @ApiOperation(value = "头条视频按天汇总", notes = "头条视频按天汇总")
 	 @PostMapping(value = "/bytedanceVideoInfoListDaily")
-	 public Result<PageInfo<ByteDanceVideoReportDaily>> bytedanceVideoInfoList(@RequestBody DateDTO dateDTO,
-																		   HttpServletRequest req){
+	 public Result<PageInfo<ByteDanceVideoReportDaily>> bytedanceVideoInfoList(@RequestBody DateDTO dateDTO){
 		 Result<PageInfo<ByteDanceVideoReportDaily>> result = new Result();
-
 		 Integer pageNo = dateDTO.getPageNo();
 		 Integer pageSize = dateDTO.getPageSize();
 		 if(pageNo == null){
@@ -136,9 +134,7 @@ public class ByteDanceVideoReportDailyController {
 		 if(pageSize == null){
 			 pageSize = 10;
 		 }
-
 		 PageInfo<ByteDanceVideoReportDaily> list = videoReportDailyService.videoInfoListDaily(dateDTO.getStartDate(), dateDTO.getEndDate(), dateDTO.getSignature(), dateDTO.getCost(), pageNo, pageSize, dateDTO.getProjectIds(), dateDTO.getAccountIds(), dateDTO.getSort());
-
 		 result.setResult(list);
 		 result.setSuccess(true);
 		 return result;