public with sharing class ProductLimitController { public static String contractId { get; set; } public static String plrId { get; set; } public static Boolean isEdit { get ; set;} public static Boolean canEdit { get; set;} public static List productInfoListview { get; set; } public static Account contract { get; set; } public static Integer productRecoedsCount { get; set; } public static String alertMessage {set;get;} //page public static Integer pagesize{get; set;} public static Integer totalcount{get; set;} public static Integer pagecount{get; set;} public static Integer currentpage{get; set;} public static Boolean hasPrevious{get; set;} public static Boolean hasNext{get; set;} //1-5分类选项 public static String keyword { get; set; } public static String category1 { get; set; } public static String category2 { get; set; } public static String category3 { get; set; } public static String category4 { get; set; } public static List category1OptionList{get;set;} public static List category2OptionList{get;set;} public static List category3OptionList{get;set;} public static List category4OptionList{get;set;} public static List productCategoryList{get;set;} //页面初始化 @AuraEnabled public static Result init(String contractIdPara, String plrIdPara){ Result result = new Result(); isEdit = false; contractId = contractIdPara; plrId = plrIdPara; canEdit = true; String recordTypeName = ''; if(plrId != null && plrId != ''){ isEdit = true; } try{ //获取经销商信息 if(!isEdit){ contract = [SELECT Id,Name,ParentId,Parent.Management_Code__c,Parent.Name,ET_SP_Dealer__c,ENG_Dealer__c FROM Account WHERE Id = :contractId]; } //初始化第一分类 initCategory(); //展示的产品 List productInfoList = new List(); //新建页面或者编辑页面进入时,初始化内容也不同 if (isEdit) { //根据状态判断是否可编辑 ProductLimitRelation__c plr = [SELECT Id,Status__c,Agency_Contract__c,RecordType.DeveloperName FROM ProductLimitRelation__c WHERE Id = :plrId]; recordTypeName = plr.RecordType.DeveloperName; contract = [SELECT Id,Name,ParentId,Parent.Management_Code__c,Parent.Name,ET_SP_Dealer__c,ENG_Dealer__c FROM Account WHERE Id = :plr.Agency_Contract__c]; if(plr.Status__c == '申请中' || plr.Status__c == '批准'){ canEdit = false; } //编辑 List plrDetailList = [SELECT Product__c,ProductLimitRelation__c,Category1__c,Category2__c,Category3__c,Category4__c FROM ProductLimitRelationDetail__c WHERE ProductLimitRelation__c = :plrId]; if(plr.RecordType.DeveloperName == 'ProductDetail'){ List proIdList = new List(); for(ProductLimitRelationDetail__c plrDetail : plrDetailList){ proIdList.add(plrDetail.Product__c); } List productList = [SELECT Id,OT_CODE__c,Name,Name__c,Asset_Model_No__c,Category1__c,Category2__c,Category3__c,Category4__c,Category5__c,SFDA_Status__c,Packing_list_manual__c FROM Product2__c WHERE Id IN :proIdList]; for(Product2__c pro : productList){ Product2Info proInfo = new Product2Info(pro); proInfo.check = true; productInfoList.add(proInfo); } }else{ productCategoryList = new List(); for(ProductLimitRelationDetail__c plrDetail : plrDetailList){ ProductCategory pc = new ProductCategory(); pc.categoryOne = plrDetail.Category1__c; pc.categoryTwo = plrDetail.Category2__c; pc.categoryThree = plrDetail.Category3__c; pc.categoryFour = plrDetail.Category4__c; pc.recordKey = plrDetail.Category1__c+plrDetail.Category2__c+plrDetail.Category3__c+plrDetail.Category4__c; productCategoryList.add(pc); } String soql = makeSoql(); System.debug('soql:'+soql); List product2Selected = Database.query(soql); for (Integer i = 0; i < product2Selected.size(); i++) { productInfoList.add(new Product2Info(product2Selected[i])); } } }else{ //新建 productInfoList = searchAllProduct(); } result.result = 'Success'; result.canEdit = canEdit; result.isEdit = isEdit; result.category1OptionList = category1OptionList; result.category2OptionList = category2OptionList; result.category3OptionList = category3OptionList; result.category4OptionList = category4OptionList; result.contract = contract; result.proInfoList = productInfoList; result.productCategoryList = productCategoryList; result.recordTypeName = recordTypeName; return result; }catch (Exception e) { result.result = 'Fail'; result.errorMsg = e.getStackTraceString(); return result; } } //获取第1分类信息 @AuraEnabled public static void initCategory(){ AggregateResult[] categoryList = [SELECT Count(Id), Category1_text__c c1c FROM Product2__c GROUP BY Category1_text__c]; category1OptionList = new List(); category1OptionList.add(new CusOption('', '--无--')); for(AggregateResult category3Search : categoryList) { String deliverycnt = String.valueOf(category3Search.get('c1c')); if(String.isNotBlank(deliverycnt)){ category1OptionList.add(new CusOption(deliverycnt,deliverycnt)); } } category2OptionList = new List(); category2OptionList.add(new CusOption('', '--无--')); category3OptionList = new List(); category3OptionList.add(new CusOption('', '--无--')); category4OptionList = new List(); category4OptionList.add(new CusOption('', '--无--')); } //获取第2分类信息 @AuraEnabled public static Result category1Change(String category1Para) { Result result = new Result(); category1 = category1Para; AggregateResult[] categoryList = [SELECT Count(id), Category2_text__c c2c FROM Product2__c WHERE Category1_text__c = :category1 GROUP BY Category2_text__c]; category2OptionList = new List(); category2OptionList.add(new CusOption('', '--无--')); for(AggregateResult category3Search : categoryList) { String deliverycnt = String.valueOf(category3Search.get('c2c')); if(String.isNotBlank(deliverycnt)){ category2OptionList.add(new CusOption(deliverycnt,deliverycnt)); } } category3OptionList = new List(); category3OptionList.add(new CusOption('', '--无--')); category4OptionList = new List(); category4OptionList.add(new CusOption('', '--无--')); result.result = 'Success'; result.category2OptionList = category2OptionList; result.category3OptionList = category3OptionList; result.category4OptionList = category4OptionList; return result; } //获取第3分类信息 @AuraEnabled public static Result category2Change(String category1Para, String category2Para) { Result result = new Result(); category1 = category1Para; category2 = category2Para; AggregateResult[] categoryList = [SELECT Count(id), Category3_text__c c3c FROM Product2__c WHERE Category1_text__c = :category1 AND Category2_text__c = :category2 GROUP BY Category3_text__c]; category3OptionList = new List(); category3OptionList.add(new CusOption('', '--无--')); for(AggregateResult category3Search : categoryList) { String deliverycnt = String.valueOf(category3Search.get('c3c')); if(String.isNotBlank(deliverycnt)){ category3OptionList.add(new CusOption(deliverycnt,deliverycnt)); } } category4OptionList = new List(); category4OptionList.add(new CusOption('', '--无--')); result.result = 'Success'; result.category3OptionList = category3OptionList; result.category4OptionList = category4OptionList; return result; } //获取第4分类信息 @AuraEnabled public static Result category3Change(String category1Para, String category2Para, String category3Para) { Result result = new Result(); category1 = category1Para; category2 = category2Para; category3 = category3Para; AggregateResult[] categoryList = [SELECT Count(id), Category4_text__c c4c FROM Product2__c WHERE Category1_text__c = :category1 AND Category2_text__c = :category2 AND Category3_text__c = :category3 GROUP BY Category4_text__c]; category4OptionList = new List(); category4OptionList.add(new CusOption('', '--无--')); for(AggregateResult category3Search : categoryList) { String deliverycnt = String.valueOf(category3Search.get('c4c')); if(String.isNotBlank(deliverycnt)){ category4OptionList.add(new CusOption(deliverycnt,deliverycnt)); } } result.result = 'Success'; result.category4OptionList = category4OptionList; return result; } //保存 @AuraEnabled public static Result save(String selectedRowsStr,Boolean isEditPara, String plrIdPara, String contractIdPara, String agencyIdPara, String categoryListJson, String applyTypePara) { Result result = new Result(); isEdit = isEditPara; plrId = plrIdPara; contractId = contractIdPara; isEdit = isEditPara; List checkedProdIdList; if(applyTypePara == 'ProductDetail'){ checkedProdIdList = (List)JSON.deserialize(selectedRowsStr, List.class); }else{ productCategoryList = (List)JSON.deserialize(categoryListJson, List.class); } //get recordtype id String recordTypeId = ''; if(applyTypePara == 'ProductDetail'){ recordTypeId = Schema.SObjectType.ProductLimitRelation__c.getRecordTypeInfosByDeveloperName().get('ProductDetail').getRecordTypeId(); }else{ recordTypeId = Schema.SObjectType.ProductLimitRelation__c.getRecordTypeInfosByDeveloperName().get('ProductSort').getRecordTypeId(); } //保存 ProductLimitRelation__c plr = new ProductLimitRelation__c(); List plrDetailList = new List(); Savepoint sp = Database.setSavepoint(); try{ //新增或修改产品限制申请 if(isEdit){ //修改时,删除该申请下的所有明细 plr.Id = plrId; plr.Status__c = '草案中'; update plr; List deletePlrDetailList = [SELECT Id FROM ProductLimitRelationDetail__c WHERE ProductLimitRelation__c = :plrId]; delete deletePlrDetailList; }else { //新增时 plr.recordTypeId = recordTypeId; plr.Agency_Contract__c = contractId; plr.Agency__c = agencyIdPara; plr.Status__c = '草案中'; insert plr; } //新增产品限制申请明细 if(applyTypePara == 'ProductDetail'){ for(String proId : checkedProdIdList){ ProductLimitRelationDetail__c plrDetail = new ProductLimitRelationDetail__c(); plrDetail.ProductLimitRelation__c = plr.Id; plrDetail.Product__c = proId; plrDetailList.add(plrDetail); } }else{ for(ProductCategory productCategory : productCategoryList){ ProductLimitRelationDetail__c plrDetail = new ProductLimitRelationDetail__c(); plrDetail.ProductLimitRelation__c = plr.Id; plrDetail.Category1__c = productCategory.categoryOne; plrDetail.Category2__c = productCategory.categoryTwo; plrDetail.Category3__c = productCategory.categoryThree; plrDetail.Category4__c = productCategory.categoryFour; plrDetailList.add(plrDetail); } } insert plrDetailList; }catch(Exception e){ Database.rollback(sp); result.result = 'Fail'; result.errorMsg = e.getStackTraceString(); return result; } result.result = 'Success'; result.url = '/'+plr.Id; return result; } //获取所有产品 public static List searchAllProduct(){ //所有的产品 String soql = makeSoql(); List allProduct2 = Database.query(soql); List allProductList = new List(); for (Integer i = 0; i < allProduct2.size(); i++) { allProductList.add(new Product2Info(allProduct2[i])); } return allProductList; } //检索产品 @AuraEnabled public static Result searchProduct(String category1Para,String category2Para,String category3Para,String category4Para,String keywordPara,String selectedRowsStr,String contractPara) { Result result = new Result(); category1 = category1Para; category2 = category2Para; category3 = category3Para; category4 = category4Para; keyword = keywordPara; List checkedProdIdList = (List)JSON.deserialize(selectedRowsStr, List.class); contract = (Account)JSON.deserialize(contractPara, Account.class); List productInfoList = new List(); //检索产品 String soql = makeSoql(); List product2Selected = Database.query(soql); for (Integer i = 0; i < product2Selected.size(); i++) { productInfoList.add(new Product2Info(product2Selected[i])); } //获取选中的产品 List checkedProList = new List(); List tempInfoList = new List(); Map infoMap = new Map(); if(checkedProdIdList != null && checkedProdIdList.size() > 0){ checkedProList = [SELECT Id,Name,OT_CODE__c,Name__c,Asset_Model_No__c,Category1__c,Category2__c,Category3__c,Category4__c,Category5__c,SFDA_Status__c,Packing_list_manual__c FROM Product2__c WHERE Id IN :checkedProdIdList]; for(Product2__c pro2 : checkedProList){ Product2Info pro2Info = new Product2Info(pro2); pro2Info.check = true; tempInfoList.add(pro2Info); infoMap.put(pro2Info.pro.Id, pro2Info); } } for(Product2Info prd : productInfoList){ if (!infoMap.containsKey(prd.pro.Id)) { tempInfoList.add(prd); } } result.result = 'Success'; result.proInfoList = tempInfoList; return result; } //根据当前选取的分类进行产品检索 @AuraEnabled public static Result searchProductByCategoryList(String categoryListJson, String contractPara) { Result result = new Result(); productCategoryList = (List)JSON.deserialize(categoryListJson, List.class); contract = (Account)JSON.deserialize(contractPara, Account.class); List productInfoList = new List(); String soql = makeSoql(); List product2Selected = Database.query(soql); for (Integer i = 0; i < product2Selected.size(); i++) { productInfoList.add(new Product2Info(product2Selected[i])); } result.result = 'Success'; result.proInfoList = productInfoList; return result; } //拼接产品查询sql public static String makeSoql(){ String soql = 'SELECT Id,OT_CODE__c,Name,Name__c,Asset_Model_No__c,Category1__c,Category2__c,Category3__c,Category4__c,'; soql += ' SFDA_Status__c,Packing_list_manual__c FROM Product2__c WHERE Estimation_Entry_Possibility__c = \'○\''; if(String.isNotBlank(category1)){ soql += ' AND Category1__c = \'' + category1 + '\''; } if(String.isNotBlank(category2)){ soql += ' AND Category2__c = \'' + category2 + '\''; } if(String.isNotBlank(category3)){ soql += ' AND Category3__c = \'' + category3 + '\''; } if(String.isNotBlank(category4)){ soql += ' AND Category4__c = \'' + category4 + '\''; } if(String.isNotBlank(keyword)){ soql += ' AND ( Name__c like \'%' + String.escapeSingleQuotes(keyword.replaceAll('%', '\\%')) + '%\''; soql += ' OR OT_CODE__c like \'%' + String.escapeSingleQuotes(keyword.replaceAll('%', '\\%')) + '%\' )'; } if(productCategoryList != null && productCategoryList.size() > 0){ soql += ' AND ('; for(Integer i = 0; i < productCategoryList.size(); i++){ ProductCategory productCategory = productCategoryList[i]; if(i == 0){ soql += ' ( '; }else{ soql += ' OR ( '; } if(String.isNotBlank(productCategory.categoryOne)){ soql += ' Category1__c = \'' + productCategory.categoryOne + '\''; } if(String.isNotBlank(productCategory.categoryTwo)){ soql += ' AND Category2__c = \'' + productCategory.categoryTwo + '\''; } if(String.isNotBlank(productCategory.categoryThree)){ soql += ' AND Category3__c = \'' + productCategory.categoryThree + '\''; } if(String.isNotBlank(productCategory.categoryFour)){ soql += ' AND Category4__c = \'' + productCategory.categoryFour + '\''; } soql += ' ) '; } soql += ' ) '; } if (contract.ET_SP_Dealer__c) { soql += ' AND Pro2_Dealer_Object__c = true '; } if (contract.ENG_Dealer__c) { soql += ' AND Pro2_Dealer_ENG__c = true '; } soql += ' ORDER BY Name__c '; return soql; } //读取CSV文件 @AuraEnabled public static Result readCsvFile(String base64Data) { Result result = new Result(); base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8'); Blob csvFileBody = EncodingUtil.base64Decode(base64Data); String csvAsString = csvFileBody.toString(); List carrList = new List(); List warningMsgList = new List(); String note = ''; try{ String[] csvFileLines = csvAsString.split('\n'); Map> csvContentMap = new Map>(); Set contractSet = new Set(); Set productSet = new Set(); Set keySet = new Set(); for(Integer i = 1; i < csvFileLines.size(); i++){ String[] crrentLine = csvFileLines[i].split(','); contractSet.add(crrentLine[0]); productSet.add(crrentLine[1]); keySet.add(crrentLine[0]+','+crrentLine[1]); } //查询合同和产品 List contractList = [SELECT Id,Name,ParentId,Parent.Management_Code__c,Parent.Name,ET_SP_Dealer__c,ENG_Dealer__c,Term_Contract_No__c FROM Account WHERE Term_Contract_No__c IN :contractSet]; List productList = [SELECT Id,Name,OT_CODE__c,Name__c,Asset_Model_No__c,Category1__c,Category2__c,Category3__c,Category4__c,Category5__c,SFDA_Status__c,Packing_list_manual__c,Pro2_Dealer_Object__c,Pro2_Dealer_ENG__c FROM Product2__c WHERE OT_CODE__c IN :productSet]; //判断数量是否匹配 if(contractSet.size() != contractList.size()){ for(String conNo : contractSet){ Integer count = 0; for(Account contract : contractList){ if(conNo == contract.Term_Contract_No__c){ count++; } } if(count == 0){ warningMsgList.add('根据本期协议号为:'+conNo+',无法找到对应的契约。'); } } } if(productSet.size() != productList.size()){ for(String otCode : productSet){ Integer count = 0; for(Product2__c pro : productList){ if(otCode == pro.OT_CODE__c){ count++; } } if(count == 0){ warningMsgList.add('根据OT Code为:'+otCode+',无法找到对应的产品。'); } } } for(Account acc : contractList){ for(Product2__c pro : productList){ String key = acc.Term_Contract_No__c + ',' + pro.OT_CODE__c; if(keySet.contains(key)){ //判断经销商和产品的ET和ENG类型是否匹配 String accType = ''; String proType = ''; if(acc.ET_SP_Dealer__c){ accType = 'ET'; } if(acc.ENG_Dealer__c){ accType = 'ENG'; } if(pro.Pro2_Dealer_Object__c){ proType = 'ET'; } if(pro.Pro2_Dealer_ENG__c){ proType = 'ENG'; } if(accType == proType){ ContrctAndProRelation carr = new ContrctAndProRelation(); carr.contract = acc; carr.product = pro; carrList.add(carr); }else{ warningMsgList.add('OT Code为'+pro.OT_CODE__c+'对应的产品和本期协议号为'+acc.Term_Contract_No__c+'对应的契约不匹配。'); } } } } Integer totalNum = csvFileLines.size() - 1; Integer successNum = carrList.size(); note = '读取成功'+successNum+'条数据,读取失败'+(totalNum-successNum)+'条数据'; result.warningMsgList = warningMsgList; result.note = note; result.result = 'Success'; result.carrList = carrList; }catch(Exception e){ result.result = 'Fail'; result.errorMsg = e.getStackTraceString(); return result; } return result; } //批量导入保存 @AuraEnabled public static Result importSave(String carrListPara){ Result result = new Result(); List carrList = (List)JSON.deserialize(carrListPara, List.class); Map> carrMap = new Map>(); Map conMap = new Map(); for(ContrctAndProRelation carr : carrList){ conMap.put(carr.contract.Id,carr.contract.ParentId); if(carrMap.containsKey(carr.contract.Id)){ carrMap.get(carr.contract.Id).add(carr.product.Id); }else{ List proIdList = new List(); proIdList.add(carr.product.Id); carrMap.put(carr.contract.Id,proIdList); } } List plrIdList = new List(); List plrList = new List(); List plrDetailList = new List(); Savepoint sp = Database.setSavepoint(); try{ String recordTypeId = Schema.SObjectType.ProductLimitRelation__c.getRecordTypeInfosByDeveloperName().get('ProductDetail').getRecordTypeId(); for(String conId : carrMap.keySet()){ ProductLimitRelation__c plr = new ProductLimitRelation__c(); plr.Agency_Contract__c = conId; plr.Agency__c = conMap.get(conId); plr.Status__c = '草案中'; plr.recordTypeId = recordTypeId; insert plr; plrIdList.add(plr.Id); for(String proId : carrMap.get(conId)){ ProductLimitRelationDetail__c plrDetail = new ProductLimitRelationDetail__c(); plrDetail.ProductLimitRelation__c = plr.Id; plrDetail.Product__c = proId; plrDetailList.add(plrDetail); } } insert plrDetailList; plrList = [SELECT Id,Name,Agency_Contract__r.Name,Status__c FROM ProductLimitRelation__c WHERE Id IN :plrIdList]; }catch(Exception e){ Database.rollback(sp); result.result = 'Fail'; result.errorMsg = e.getStackTraceString(); return result; } result.result = 'Success'; result.plrList = plrList; return result; } class Product2Info implements Comparable { @AuraEnabled public Boolean check { get; set; } @AuraEnabled public Boolean orderby { get; set; } @AuraEnabled public Product2__c pro { get; set; } public Product2Info(Product2__c e) { check = false; pro = e; orderby = false; } public Integer compareTo(Object compareTo) { Product2Info compareToesd =(Product2Info)compareTo; Integer returnValue = 0; if(check == true){ returnValue = -1; }else{ if (orderby == true){ returnValue = -1; }else{ returnValue = 1; } } return returnValue; } } public class Result { @AuraEnabled public String result; @AuraEnabled public String errorMsg; @AuraEnabled public List proInfoList; @AuraEnabled public List category1OptionList; @AuraEnabled public List category2OptionList; @AuraEnabled public List category3OptionList; @AuraEnabled public List category4OptionList; @AuraEnabled public Account contract; @AuraEnabled public Boolean isEdit; @AuraEnabled public Boolean canEdit; @AuraEnabled public String url; @AuraEnabled public List carrList; @AuraEnabled public List plrList; @AuraEnabled public String note; @AuraEnabled public List warningMsgList; @AuraEnabled public List productCategoryList; @AuraEnabled public String recordTypeName; } public class CusOption { CusOption(String value, String label) { this.label = label; this.value = value; } @AuraEnabled public String label; @AuraEnabled public String value; } public class ContrctAndProRelation { @AuraEnabled public Account contract; @AuraEnabled public Product2__c product; } public class ProductCategory { @AuraEnabled public String categoryOne; @AuraEnabled public String categoryTwo; @AuraEnabled public String categoryThree; @AuraEnabled public String categoryFour; @AuraEnabled public String recordKey; } public static void test(){ Integer i = 0; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; i++; } }