madalino

Tagging script Update(get own troops)

Mar 31st, 2024 (edited)
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. javascript:var encryptedData='U2FsdGVkX1+bTmtD6k2I310BRz2MFFm86HcDgNEYuwXcPjFA6mrh6EQGZwp9sKf5JAMCD5vDexmUMqhm5EQ6dSweLvT6GL1deQ8ydPB8MCRP7IedKwNiOAQt4sD00hhixoGcOjtcO4Y86us1RKI4BYBwGo3kIQQhqYRq3DqybiqvZomxR9wNrZw/5/dwjaK6eikhiqqL1PfwmkV8VBqNUT9/EvCiArrZre/dZK8rsajnhgiM7RAmWoRB0QYHDMshbT0G2bUSS18B1DJEAu8ldO25ZIckZjjjG0KvL22VkrE=';
  3.  
  4.  
  5.  
  6. var dropboxToken="",databaseName="",worldNumber=""
  7.  
  8. var allUsers ,tribemates, permissions
  9. var filename_reports,filename_incomings,filename_users,filename_support,filename_commands_attack,filename_status_upload,filename_history_upload,filename_troops_home
  10.  
  11. var listCommandsAttacks, commandsAttacksPromises
  12. var listSupport, supportPromises
  13. var nrFiles
  14.  
  15. var backgroundColor, borderColor, headerColor, headerColor,titleColor, headerColorPlayers, headerColorCoords, headerColorFirstRow, headerColorFirstRow
  16. var widthInterface, widthInterfaceOverview
  17. (async () => {
  18.     backgroundColor = "#32313f";
  19.     borderColor = "#3e6147";
  20.     headerColor = "#202825";
  21.     titleColor = "#ffffdf";
  22.     headerColorPlayers="#323232"
  23.     headerColorCoords="#4d4d4d"
  24.     headerColorFirstRow="#666600"
  25.     widthInterface = 600
  26.     widthInterfaceOverview = 900
  27.  
  28.  
  29.     allUsers =   await getUsers()
  30.  
  31.     permissions = {}
  32.     tribemates=allUsers.split("\n").map(e=>{return e.split(",")[0].trim().toLowerCase()}).filter(e => e)
  33.     allUsers.split("\n").forEach(row => {
  34.         if(row.trim() != ''){
  35.             let name = row.split(",")[0].trim().toLowerCase()
  36.             let value = row.split(",")[1].trim()
  37.             permissions[name] = value
  38.         }
  39.    
  40.     })
  41.     console.log(tribemates)
  42.     // console.log(permissions)
  43.  
  44.     // if(!tribemates.includes(game_data.player.name.toLowerCase())){
  45.     //     UI.ErrorMessage("contact admin to give you permission",2000)
  46.     //     throw new Error("you do not have acces");
  47.     //     // console.log("you do not have acces" )
  48.     // }
  49.     // console.log("worldNumber ",worldNumber)
  50.     // if (game_data.world.match(/\d+/)[0] != worldNumber)
  51.     //     throw new Error("it doesn't work");
  52.  
  53.     addCssStyle()
  54.     getInterface()
  55.     showButtons();
  56.     hitCountApi()
  57.     filename_reports=`${databaseName}/Reports.gz`;
  58.     filename_incomings=`${databaseName}/Incomings.gz`;
  59.     filename_users=`${databaseName}/Users.txt`;
  60.     filename_support=`${databaseName}/Support.gz`;
  61.     filename_commands_attack=`${databaseName}/Commands_attack.gz`;
  62.     filename_troops_home=`${databaseName}/Troops_home.gz`;
  63.    
  64.     filename_status_upload=`${databaseName}/status.gz`;
  65.     filename_history_upload=`${databaseName}/history_upload.gz`;
  66.  
  67.  
  68.  
  69.    
  70.  
  71.     listCommandsAttacks = []
  72.     commandsAttacksPromises = []
  73.     listSupport = []
  74.     supportPromises = []
  75.  
  76.     nrFiles = 2
  77.     for(let i=0;i<nrFiles;i++){
  78.         let fileName = `${databaseName}/Commands_attack${i}.gz`
  79.         listCommandsAttacks.push(fileName)
  80.         commandsAttacksPromises.push(readFileDropbox(fileName))
  81.  
  82.         fileName = `${databaseName}/Support${i}.gz`
  83.         listSupport.push(fileName)
  84.         supportPromises.push(readFileDropbox(fileName))
  85.     }
  86.     console.log(listCommandsAttacks)
  87.     console.log(listSupport)
  88.  
  89.  
  90.     try {
  91.         console.log(`${databaseName}/Support0.gz`)
  92.         let response = await readFileDropbox(`${databaseName}/Support0.gz`,dropboxToken)
  93.         console.log(response)
  94.     } catch (error) {
  95.         UI.SuccessMessage("create additional files")
  96.         window.setTimeout(async ()=>{
  97.             for(let i=0;i<nrFiles;i++){
  98.                 let compressedData = await compress("[]", 'gzip')
  99.                 await uploadFile(compressedData, `${databaseName}/Support${i}.gz`, dropboxToken)
  100.                 await uploadFile(compressedData, `${databaseName}/Commands_attack${i}.gz`, dropboxToken)
  101.             }
  102.         },500)
  103.         console.log("files created")
  104.     }
  105.  
  106.  
  107.     try {
  108.         let response = await readFileDropbox(filename_status_upload,dropboxToken)
  109.         console.log(response)
  110.     } catch (error) {
  111.         UI.SuccessMessage("create additional file")
  112.         window.setTimeout(async ()=>{
  113.             let compressedData = await compress("[]", 'gzip')
  114.             await uploadFile(compressedData, filename_reports, dropboxToken)
  115.             await uploadFile(compressedData, filename_support, dropboxToken)
  116.             await uploadFile(compressedData, filename_incomings, dropboxToken)
  117.             await uploadFile(compressedData, filename_commands_attack, dropboxToken)
  118.             await uploadFile(compressedData, filename_status_upload, dropboxToken)
  119.             await uploadFile(compressedData, filename_history_upload, dropboxToken)
  120.         },500)
  121.         console.log("file created")
  122.     }
  123.  
  124.  
  125.     try {
  126.         let response = await readFileDropbox(filename_troops_home,dropboxToken)
  127.         console.log(response)
  128.     } catch (error) {
  129.         UI.SuccessMessage("create additional file")
  130.         window.setTimeout(async ()=>{
  131.             let compressedData = await compress("[]", 'gzip')
  132.             await uploadFile(compressedData, filename_troops_home, dropboxToken)
  133.         },500)
  134.         console.log("file created")
  135.     }
  136.  
  137.  
  138.    
  139. })();
  140.  
  141.  
  142.  
  143.  
  144. // game_data.device="none"
  145.  
  146.  
  147. var speedWorld=getSpeedConstant().worldSpeed;
  148. var speedTroupes=getSpeedConstant().unitSpeed;
  149.    
  150.    
  151.  
  152.  
  153.  
  154.  
  155. var nobleSpeed=2100*1000/(speedWorld*speedTroupes)//ms
  156. var ramSpeed=1800*1000/(speedWorld*speedTroupes)//ms
  157. var swordSpeed=1320*1000/(speedWorld*speedTroupes)//ms
  158. var axeSpeed=1080*1000/(speedWorld*speedTroupes)//ms
  159. var heavySpeed=660*1000/(speedWorld*speedTroupes)//ms
  160. var lightSpeed=600*1000/(speedWorld*speedTroupes)//ms
  161. var spySpeed=540*1000/(speedWorld*speedTroupes)//ms
  162.  
  163.  
  164. //formula ((base time/100)/speedWorld) * stable time factor  //https://forum.tribalwars.net/index.php?threads/next-lvl-of-barracks-unit-production-speed.54638/
  165. var axeTime=Math.round( ((1320/100.0)/speedWorld) * 15.58823529 ) *1000//milisec
  166. var lhTime=Math.round( ((1800/100.0)/speedWorld) * 20.88235294 ) *1000//milisec
  167. var ramTime=Math.round( ((4800/100.0)/speedWorld) * 27.84313725 ) *1000//milisec
  168.  
  169. var countApiKey = "taggingScript";
  170. var countNameSpace="madalinoTribalWarsScripts"
  171.  
  172.  
  173.  
  174.  
  175.  
  176. var troopsPop = {
  177.     spear : 1,
  178.     sword : 1,
  179.     axe : 1,
  180.     archer : 1,
  181.     spy : 2,
  182.     light : 4,
  183.     marcher : 5,
  184.     heavy : 4,
  185.     ram : 5,
  186.     catapult : 8,
  187.     knight : 10,
  188.     snob : 100
  189. };
  190. {/* <img src="https://img.icons8.com/officel/16/000000/long-arrow-right.png"/> */}
  191. {/* <img src="https://img.icons8.com/officel/16/000000/long-arrow-left.png"/> */}
  192.  
  193. function hitCountApi(){
  194.     $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  195.         console.log(`This script has been run: ${response.count} times`);
  196.     });
  197.     if(game_data.device !="desktop"){
  198.         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}_phone/up`, response=>{
  199.             console.log(`This script has been run on mobile: ${response.count} times`);
  200.         });
  201.     }
  202.  
  203.     $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}_id${game_data.player.id}/up`, response=>{
  204.         console.log(response)
  205.         if(response.count == 1){
  206.             console.log("here")
  207.             $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}_users/up`, response=>{});
  208.         }
  209.  
  210.     });
  211.  
  212.     try {
  213.         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}_users`, response=>{
  214.             console.log(`Total number of users: ${response.count}`);
  215.         });
  216.      
  217.     } catch (error) {}
  218.  
  219. }
  220.  
  221.  
  222. function getInterface(){
  223.     html = `
  224.  
  225.     <div id="div_container" class="ui-widget-content div_remove" style="background-color:${backgroundColor};cursor:move;z-index:50;width:${widthInterface}px">
  226.         <div class="scriptHeader">
  227.             <div style=" margin-top:10px;text-decoration: underline;text-decoration-color: ${titleColor}"><h2 >Upload data</h2></div>
  228.             <div style="position:absolute;top:10px;right: 10px;"><a href="#" onclick="$('#div_container').remove()"><img src="https://img.icons8.com/emoji/24/000000/cross-mark-button-emoji.png"/></a></div>
  229.             <div style="position:absolute;top:8px;right: 35px;" id="div_minimize"><a href="#"><img src="https://img.icons8.com/plasticine/28/000000/minimize-window.png"/></a></div>
  230.             <div style="position:absolute;top:10px;right: 92%;" id="page_support" ><a href="#" onclick="viewSupport() "><img src="https://img.icons8.com/officel/30/000000/long-arrow-right.png"/></a></div>
  231.         </div>
  232.         <div id="div_body">
  233.             <table id="table_upload" class="" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor}">
  234.                 <tr>
  235.                     <td  style="text-align:center; background-color:${headerColor}">
  236.                         <h2><center style="margin:10px"><font color="${titleColor}">Reports</font></center></h2>
  237.                     </td>
  238.                     <td style="text-align:center; background-color:${headerColor}">
  239.                         <center style="margin:10px"><input class="btn" type="button" id="upload_reports" onclick="uploadReports()" value="Upload"></center>
  240.    
  241.                     </td>
  242.                         <td style="text-align:center; background-color:${headerColor}">
  243.                         <p><center style="margin:10px"><font color="${titleColor}" id="progress_reports">None</font></center></p>
  244.                     </td>                      
  245.                 </tr>        
  246.                     <tr>
  247.                     <td style="text-align:center; background-color:${headerColor}">
  248.                         <h2><center style="margin:10px"><font color="${titleColor}">Incomings</font></center></h2>
  249.                     </td>
  250.                     <td style="text-align:center; background-color:${headerColor}">
  251.                             <center style="margin:10px"><input class="btn" type="button" id="upload_incomings" onclick="uploadIncomings()" value="Upload"></center>
  252.                     </td>
  253.                         <td style="text-align:center; background-color:${headerColor}">
  254.                         <p><center style="margin:10px" ><font color="${titleColor}" id="progress_incomings">None</font></center></p>
  255.                     </td>                      
  256.                 </tr>
  257.                 <tr>
  258.                     <td style="text-align:center; background-color:${headerColor}">
  259.                         <h2><center style="margin:10px"><font color="${titleColor}">Commands</font></center></h2>
  260.                     </td>
  261.                     <td style="text-align:center; background-color:${headerColor}">
  262.                             <center style="margin:10px"><input class="btn" type="button" onclick="uploadSupports()" value="Upload"></center>    
  263.                     </td>
  264.                         <td style="text-align:center; background-color:${headerColor}">
  265.                         <p><center style="margin:10px" ><font color="${titleColor}" id="progress_support">None</font></center></p>
  266.                         </td>                      
  267.                 </tr>
  268.                 <tr>
  269.                     <td style="text-align:center; background-color:${headerColor}">
  270.                         <h2><center style="margin:10px"><font color="${titleColor}">Troops</font></center></h2>
  271.                     </td>
  272.                     <td style="text-align:center; background-color:${headerColor}">
  273.                             <center style="margin:10px"><input class="btn" type="button" onclick="uploadOwnTroops()" value="Upload"></center>    
  274.                     </td>
  275.                         <td style="text-align:center; background-color:${headerColor}">
  276.                         <p><center style="margin:10px" ><font color="${titleColor}" id="progress_troops_home">None</font></center></p>
  277.                         </td>                      
  278.                 </tr>
  279.                 <tr>
  280.                     <td style="text-align:center; background-color:${headerColor}">
  281.                         <h2><center style="margin:10px"><font color="${titleColor}">All Info</font></center></h2>
  282.                     </td>
  283.                     <td style="text-align:center; background-color:${headerColor}">
  284.                             <center style="margin:10px"><input class="btn" type="button" onclick="uploadAll()" value="Upload all"></center>    
  285.                     </td>
  286.                         <td style="text-align:center; background-color:${headerColor}">
  287.                         <p><center style="margin:10px" ><font color="${titleColor}" id="progress_all">None</font></center></p>
  288.                     </td>                      
  289.                 </tr>    
  290.             </table>
  291.             <h2><center style="margin:10px"><font color="${titleColor}" style="text-decoration: underline;text-decoration-color: ${titleColor}">Search Reports</font></center></h2>
  292.             <table id="table_upload" class="" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor}">
  293.                 <tr>
  294.                     <td  style="text-align:center; background-color:${headerColor}">
  295.                         <center style="margin:10px"><input class="btn" type="button" onclick="loadReports()" value="Load Reports"></center>
  296.                         <center style="margin:10px"><input class="btn" type="button" onclick="databaseDetails()" value="Database Details"></center>
  297.                     </td>
  298.                     <td style="text-align:center; background-color:${headerColor}">
  299.                     <center style="margin:10px"><input style="text-align: center;" type="text" id="input_search" onclick="" placeholder="coord" ></center>
  300.                     </td>
  301.                         <td style="text-align:center; background-color:${headerColor}">
  302.                         <p><center style="margin:10px"><font color="${titleColor}" id="progress_search">status</font></center></p>
  303.                     </td>                      
  304.                 </tr>  
  305.                 <tr >
  306.                     <td style="text-align:center; background-color:${headerColor}">
  307.                         <p><center style="margin:10px"><font color="${titleColor}" >filter tribes: </font></center></p>
  308.                     </td>
  309.                     <td colspan="2" style="text-align:center; background-color:${headerColor}">
  310.                         <center style="margin:10px"><input style="text-align: center;width:90%;" type="text" id="input_filter_tribe" onclick="" placeholder="tribe1,tribe2,..." ></center>
  311.                     </td>
  312.                 </tr>    
  313.                 <tr >
  314.                     <td  style="text-align:center; background-color:${headerColor}">
  315.                         <center style="margin:10px"><input class="btn" id="btn_off_coord" type="button" value="Off Coords"></center>
  316.                     </td>
  317.                     <td style="text-align:center; background-color:${headerColor}">
  318.                         <center style="margin:10px"><input class="btn" id="btn_def_coord" type="button" value="Def Coords"></center>
  319.                     </td>      
  320.                     <td style="text-align:center; background-color:${headerColor}">
  321.                         <center style="margin:10px"><input class="btn" id="btn_stack_coord" type="button" value="Stacked Coords"></center>
  322.                         <center style="margin:10px"><input style="text-align: center;" type="text" id="input_stacked" onclick="" placeholder="nr stack" ></center>
  323.                     </td>    
  324.                 </tr>        
  325.             </table>
  326.             <center style="margin:10px"><div id="report_view" style="background-color:#d2c09e"><div><center>
  327.             <div class="scriptFooter">
  328.                 <div style=" margin-top:5px;"><h5>Made by Costache</h5></div>
  329.             </div>
  330.         </div>
  331.     </div>
  332.     `;
  333.  
  334.     ////////////////////////////////////////add and remove window from page///////////////////////////////////////////
  335.  
  336.  
  337.     if(document.getElementById("table_incomings")!=null){
  338.  
  339.         $("#contentContainer").eq(0).prepend(html);
  340.         $("#mobileContent").eq(0).prepend(html);
  341.     }
  342.  
  343.    
  344.     if(document.getElementById("incomings_table")==null){
  345.         $("#div_container").remove()
  346.         $("#contentContainer").eq(0).prepend(html);
  347.         $("#mobileContent").eq(0).prepend(html);
  348.         $("#div_container_view").remove()
  349.         if(game_data.device=="desktop"){
  350.             $("#div_container").css("position","fixed");
  351.             $("#div_container").draggable();
  352.         }
  353.     }
  354.  
  355.  
  356.    
  357.  
  358.     $("#div_minimize").on("click",()=>{
  359.         if($('#div_container').width() == widthInterface){
  360.             $('#div_container').css({'width' : '120px'});
  361.             $('#div_body').hide();
  362.             $("#page_support").hide()
  363.         }
  364.         else{
  365.             $('#div_container').css({'width' : `${widthInterface}px`});
  366.             $('#div_body').show();
  367.             $("#page_support").show()
  368.  
  369.         }
  370.     })
  371.  
  372.     if(game_data.device == "desktop"){
  373.         $("#div_container").draggable();
  374.         $("#div_container").css("position","fixed");
  375.  
  376.     }
  377.     testLoadReports()
  378. }
  379. function closeWindow(){
  380.     $(".div_remove").remove()
  381.     list_href=[]
  382.     // window.location.reload();
  383. }
  384.  
  385. async function getUsers(){
  386.     await insertCryptoLibrary();
  387.     var decrypted = CryptoJS.AES.decrypt(encryptedData, "isFuckingWorking");
  388.     decrypted =decrypted.toString(CryptoJS.enc.Utf8);
  389.     // console.log(decrypted)
  390.     new Function(decrypted)()
  391.  
  392.     var filename_users=`${databaseName}/Users.txt`;
  393.  
  394.     var result
  395.     $.ajax({
  396.         url: "https://content.dropboxapi.com/2/files/download",
  397.         method: 'POST',
  398.         dataType: "text",
  399.         async: false,
  400.         headers: { 'Authorization': 'Bearer ' + dropboxToken,
  401.                     'Dropbox-API-Arg': JSON.stringify({path: "/"+filename_users})},
  402.        
  403.         success: (data) => {
  404.             result=data
  405.            
  406.         },error:(err)=>{
  407.             alert(err)
  408.             reject(err)
  409.         }
  410.     })
  411.     return result
  412. }
  413.  
  414.  
  415.  
  416.  
  417. function insertCryptoLibrary(){
  418.     return new Promise((resolve,reject)=>{
  419.  
  420.         let start=new Date().getTime()
  421.         let script = document.createElement('script');
  422.         script.type="text/javascript"
  423.         script.src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"
  424.         script.onload = function () {
  425.             let stop=new Date().getTime()
  426.             console.log(`insert crypto-js library in ${stop-start} ms`)
  427.             resolve("done")
  428.         };
  429.         document.head.appendChild(script);
  430.     })
  431. }
  432.  
  433. function addWindow(){
  434.     $("#contentContainer").eq(0).prepend(html);
  435.     $("#mobileContent").eq(0).prepend(html);
  436.  
  437.     if(game_data.device=="desktop"){
  438.         $("#div_container").css("position","fixed");
  439.         $("#div_container").draggable();
  440.     }
  441. }
  442.  
  443.  
  444.  
  445. var loadReportsOk=false;
  446. function testLoadReports(){
  447.     $("#input_search").on("input",function(){
  448.         if(loadReportsOk==false)
  449.         UI.ErrorMessage("Press on <b>Load Reports</b> button first","slow")
  450.     })
  451.     $("#btn_off_coord, #btn_def_coord, #btn_stack_coord").on("click",function(){
  452.         console.log("Hererer")
  453.         if(loadReportsOk==false)
  454.             UI.ErrorMessage("Press on <b>Load Reports</b> button first","slow")
  455.     })
  456.  
  457.     $("#input_search").mouseout(function(){
  458.     if(loadReportsOk==false)
  459.         $("#input_search").val("");
  460.     })
  461.     $("#minimize_page").on("click",()=>{
  462.         $("#div_minimize").toggle(500)
  463.     })
  464.  
  465. }
  466.  
  467.  
  468. async function uploadAll(){
  469.     let resultReportsResult= await uploadReports().catch(err=>alert(err))
  470.     console.log("status uploads",resultReportsResult)
  471.     let resultIncomingsResult= await uploadIncomings().catch(err=>alert(err))
  472.     console.log("status incomings",resultIncomingsResult)
  473.     let uploadSupportsResult= await uploadSupports().catch(err=>alert(err))
  474.     console.log("status uploadSupports",uploadSupportsResult)
  475.     let uploadTroopsResult= await uploadOwnTroops().catch(err=>alert(err))
  476.     console.log("status uploadTroops",uploadTroopsResult)
  477.  
  478.     let totalTime = resultReportsResult.totalTimeUpload + resultIncomingsResult.totalTimeUpload + uploadSupportsResult.totalTimeUpload + uploadTroopsResult.totalTimeUpload
  479.     totalTime =  Math.round((totalTime) * 100) / 100
  480.     document.getElementById("progress_all").innerText = `Finished in ${totalTime} s`;
  481.  
  482.     UI.SuccessMessage(`<b>Upload all info done</b> <br> <br>
  483.                         Total Time Upload : <b>${totalTime} sec</b> <br>
  484.                         <center>
  485.                         <table style ="border: 1px solid black;border-collapse: collapse">
  486.                             <tr>
  487.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px;font-weight: bold">Upload type</td>
  488.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px;font-weight: bold">Time</td>
  489.                             </tr>
  490.                             <tr>
  491.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Reports</td>
  492.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${resultReportsResult.totalTimeUpload} sec</td>
  493.                             </tr>
  494.                             <tr>
  495.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Incominds</td>
  496.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${resultIncomingsResult.totalTimeUpload} sec</td>
  497.                             </tr>
  498.                             <tr>
  499.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Commands</td>
  500.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${uploadSupportsResult.totalTimeUpload} sec</td>
  501.                             </tr>
  502.                             <tr>
  503.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Troops</td>
  504.                                 <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${uploadTroopsResult.totalTimeUpload} sec</td>
  505.                             </tr>
  506.                     </table>
  507.                   </center>`, 10000)
  508.  
  509. }
  510.  
  511. function addCssStyle(){
  512.     var css =`
  513.     .shadow20 {
  514.     text-shadow: 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black, 0 0 4px black;
  515.     }
  516.     .scriptHeader{
  517.         color: ${titleColor};
  518.         background: ${backgroundColor};
  519.         width: 100%;
  520.         margin: 0 auto;
  521.         display: flex;
  522.         justify-content: center;
  523.         align-items: center;    
  524.     }
  525.     .scriptContainer{
  526.         background: ${backgroundColor};
  527.         aspect-ratio: 100 / 29;
  528.         cursor:move;
  529.         z-index:50;
  530.         border-radius: 15px;
  531.  
  532.         border-style: solid;
  533.         border-width: 5px 5px;
  534.         border-color:${backgroundColor};
  535.  
  536.     }
  537.     .scriptFooter{
  538.         color: ${titleColor};
  539.         background: ${backgroundColor};
  540.         width: 100%;
  541.         margin: 0 auto;
  542.         display: flex;
  543.         justify-content: right;
  544.         align-items: center;  
  545.         margin-right:50px;  
  546.     }
  547.     `,
  548.     head = document.head || document.getElementsByTagName('head')[0],
  549.     style = document.createElement('style');
  550.    
  551.     head.appendChild(style);
  552.     style.type = 'text/css';
  553.     if (style.styleSheet){
  554.         // This is required for IE8 and below.
  555.         style.styleSheet.cssText = css;
  556.     } else {
  557.         style.appendChild(document.createTextNode(css));
  558.     }
  559. }
  560.  
  561.  
  562.  
  563. if(document.getElementById("incomings_table")!=null){
  564.     window.setInterval(function(){
  565.  
  566.         var rows= $(".row_a,.row_b")
  567.         console.log("check incomings")
  568.         for(let i=0;i<rows.length;i++)
  569.         {
  570.             let currentHour=rows[i].children[rows[i].children.length-1].innerText.split(":")
  571.             if(parseInt(currentHour[0])==0 && parseInt(currentHour[1])==0 && parseInt(currentHour[2])<20){
  572.                 rows[i].remove();
  573.             }
  574.             // else{
  575.             //     break;
  576.             // }
  577.         }
  578.     },10000)
  579. }
  580.  
  581.  
  582.  
  583.  
  584.  
  585. /////////////////////////////////////////////////get all reports info//////////////////////////////////////////////////////////////////
  586. async function uploadReports(){
  587.    
  588.  
  589.     document.getElementById("progress_reports").innerText="Getting data...";
  590.    
  591.     let [map_history_upload,status]=await Promise.all([readFileDropbox(filename_history_upload),insertlibraryLocalBase() ]).catch(err=>{alert(err)})
  592.     console.log(status)
  593.  
  594.     try {
  595.         let decompressedData = await decompress(await map_history_upload.arrayBuffer() , 'gzip');  
  596.         map_history_upload=new Map( JSON.parse(decompressedData));
  597.     } catch (error) {
  598.         console.log("erorr map history upload from dropbox")
  599.         map_history_upload=new Map()
  600.     }
  601.  
  602.     //if  database is stored locally
  603.     if(await localBase.getItem(game_data.world+"history_upload")!=undefined){
  604.         try{
  605.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "history_upload"))
  606.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  607.    
  608.             let map_localBase=new Map( JSON.parse(decompressedData));
  609.             console.log("map_localBase history upload",map_localBase)
  610.             map_history_upload=new Map([...map_localBase, ...map_history_upload])
  611.         } catch (error) {
  612.             let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "history_upload"))));
  613.             map_history_upload=new Map([...map_localBase, ...map_history_upload])
  614.         }
  615.     }
  616.  
  617.     console.log("map_history_upload",map_history_upload)
  618.     //delete if it's too old
  619.     Array.from(map_history_upload.keys()).forEach(key=>{
  620.         let currentDate=new Date();
  621.         let reportDate=new Date(map_history_upload.get(key).date)
  622.         if(currentDate.getTime()- reportDate.getTime() > 8*24*3600*1000){
  623.             // console.log("remove id: "+map_history_upload.get(key).date)
  624.             map_history_upload.delete(key)
  625.         }
  626.        
  627.     })
  628.  
  629.  
  630.     // console.log(map_history_upload)
  631.  
  632.     var [list_href, mapVillages]=await Promise.all([getLinks(true,map_history_upload),getInfoVillages() ]).catch(err=>{alert(err)})
  633.  
  634.  
  635.     console.log("map_history_upload",map_history_upload)
  636.    
  637.     $(document).on('click','.autoHideBox',function(){
  638.         UI.SuccessMessage("stop",2000)
  639.         list_href=[]
  640.     })
  641.        
  642.        
  643.     list_href=list_href.reverse();
  644.     console.log(list_href)
  645.     var list_data_reports=[]
  646.     var list_data_typeAttack=[]
  647.     var nr_reports=0;
  648.     var nr_reports_total=list_href.length
  649.     // addWindow();
  650.     // document.getElementById("progress_reports").innerText=nr_reports+"/"+nr_reports_total+" reports";
  651.     // UI.InfoMessage(nr_reports+"/"+nr_reports_total+" reports")
  652.     var current_url
  653.  
  654.     return new Promise(async(resolve,reject)=>{
  655.         async function ajaxRequest (urls) {
  656.             var time= 0
  657.             if(urls.length>0)
  658.             current_url=urls.pop().href;
  659.             else
  660.             current_url="stop"
  661.             // console.log("inside function "+urls.length)
  662.             if (urls.length >= 0 && current_url!= "stop") {
  663.                 var start_ajax=new Date()
  664.                 $.ajax({
  665.                     method: 'GET',
  666.                     url: current_url,
  667.                 })
  668.                 .done(async function (result) {
  669.                     const parser = new DOMParser();
  670.                     const htmlDoc = parser.parseFromString(result, 'text/html');
  671.  
  672.                     // addWindow();
  673.                     var startReport=new Date().getTime();
  674.                     let list=getDataReport(tribemates,htmlDoc);
  675.                     var stopReport=new Date().getTime();
  676.                     // console.log(stopReport-startReport)
  677.                     // console.log(list)
  678.                     if(list==null ){
  679.                         console.log("recaptcha, upload again")
  680.                         UI.ErrorMessage("recaptcha, upload again","slow")
  681.                         // addWindow();
  682.                         document.getElementById("progress_reports").innerText="recaptcha";
  683.                         list_href=[]
  684.    
  685.                     }
  686.                     else if (list == 0){//error( player has been deleted)
  687.                         let idReport= parseInt(current_url.match(/view=(\d+)/)[1]);
  688.                         let currentDate=new Date().getFullYear()+"-"+(new Date().getMonth()+1)+"-"+new Date().getDate();
  689.                      
  690.                         if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>0){
  691.                             var time_report=htmlDoc.getElementsByClassName("vis")[3].firstElementChild.children[1].children[1].innerText.trim();
  692.                             map_history_upload.set(idReport,{
  693.                                 date:time_report,
  694.                                 playerId:game_data.player.id.toString()
  695.                             })
  696.                         }
  697.                         else{
  698.                             map_history_upload.set(idReport,{
  699.                                 date:currentDate,
  700.                                 playerId:game_data.player.id.toString()
  701.                             })
  702.                         }
  703.                         UI.SuccessMessage(nr_reports+"/"+nr_reports_total+" reports")
  704.                         // document.getElementById("progress_reports").innerText=nr_reports+"/"+nr_reports_total+" reports"
  705.                         nr_reports++;
  706.                     }
  707.                     else{
  708.                    
  709.                         // console.log("herere")
  710.                        
  711.                         // console.log("reports info "+list)
  712.                         for(let j=0;j<list.length;j++){
  713.                             list_data_reports.push({"coord":list[j].coord,"reportInfo":list[j].reportInfo});  
  714.  
  715.  
  716.                             ////////////////////////////////error reports////////////////////////////////
  717.                             if(list[j].reportInfo.time_report == 0 || new Date(list[j].reportInfo.time_report) == "Invalid Date"){
  718.                                 // let list_errors = JSON.parse(await readFileDropbox(filename_errors_reports))
  719.                                 // list_errors.push(htmlDoc.getElementsByClassName("nopad")[0].innerHTML)
  720.                                 // await uploadFile(JSON.stringify(list_errors),filename_errors_reports,dropboxToken)
  721.                                
  722.                                 let serverTime=htmlDoc.getElementById("serverTime").innerText
  723.                                 let serverDate=htmlDoc.getElementById("serverDate").innerText.split("/")
  724.                                 serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  725.                                 let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  726.                                 list[j].reportInfo.time_report = `${months[parseInt(serverDate[1])]} ${serverDate[0]}, ${serverTime}`
  727.                             }
  728.                         }
  729.                         // document.getElementById("progress_reports").innerText=nr_reports+"/"+nr_reports_total+" reports";
  730.                         UI.SuccessMessage(nr_reports+"/"+nr_reports_total+" reports")
  731.                         // document.getElementById("progress_reports").innerText=nr_reports+"/"+nr_reports_total+" reports"
  732.  
  733.  
  734.                         nr_reports++;
  735.                         let idReport= parseInt(current_url.match(/view=(\d+)/)[1]);
  736.                         let currentDate=new Date().getFullYear()+"-"+(new Date().getMonth()+1)+"-"+new Date().getDate();
  737.                      
  738.                         if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>0){
  739.                             var time_report=htmlDoc.getElementsByClassName("vis")[3].firstElementChild.children[1].children[1].innerText.trim();
  740.                             map_history_upload.set(idReport,{
  741.                                 date:time_report,
  742.                                 playerId:game_data.player.id.toString()
  743.                             })
  744.                         }
  745.                         else{
  746.                             map_history_upload.set(idReport,{
  747.                                 date:currentDate,
  748.                                 playerId:game_data.player.id.toString()
  749.                             })
  750.                         }
  751.                     }
  752.                     // console.log("map_history_upload size "+map_history_upload.size)
  753.  
  754.                    
  755.                     ///save type of attack nuke/fang/fake
  756.                     let objTypeAttack=getDataReportTypeAttack(tribemates,htmlDoc);
  757.                     if(objTypeAttack==null ){
  758.                         console.log("recaptcha, upload again")
  759.                         UI.ErrorMessage("recaptcha, upload again","slow")
  760.                         // addWindow();
  761.                         document.getElementById("progress_reports").innerText="recaptcha";
  762.                         list_href=[]
  763.    
  764.                     }
  765.                     else{
  766.                         if(objTypeAttack.length>0){
  767.                             objTypeAttack = objTypeAttack.pop()
  768.                             list_data_typeAttack.push(objTypeAttack)
  769.                         }
  770.                     }
  771.  
  772.  
  773.  
  774.                     var stop_ajax=new Date();
  775.                     var dif_time=stop_ajax.getTime()-start_ajax.getTime();
  776.                     // console.log("dif_time "+dif_time+" wait "+(200-dif_time))
  777.                     window.setTimeout(function(){
  778.                         let next_ajax = new Date();
  779.                         let duration_ajax=next_ajax.getTime()-start_ajax.getTime();
  780.                         console.log("delay between requests is: "+duration_ajax+" ms")
  781.                        
  782.                         ajaxRequest(list_href);
  783.  
  784.                     },200-dif_time)
  785.                 });
  786.            
  787.             }
  788.             else
  789.             {
  790.  
  791.                 UI.SuccessMessage("compressing database, wait few seconds",5000)
  792.  
  793.  
  794.                 ////////////////////////////////////extract data from dropbox/////////////////////////////////////////
  795.                 console.log("before reading map from dropbox")
  796.                 let [map_dropbox, mapStatus,infoVillages,map_incomings]=await Promise.all([readFileDropbox(filename_reports) ,readFileDropbox(filename_status_upload),getInfoVillages(),readFileDropbox(filename_incomings)]).catch(err=>{alert(err)})
  797.  
  798.                 try {
  799.                     let decompressedData = await decompress(await map_dropbox.arrayBuffer() , 'gzip');  
  800.                     map_dropbox=new Map( JSON.parse(decompressedData));
  801.                 } catch (error) {
  802.                     console.log("erorrrrrrrrrrrrrrrr map report from dropbox")
  803.                     map_dropbox=new Map()
  804.                 }
  805.  
  806.                 //if  database is stored locally
  807.                 if(await localBase.getItem(game_data.world+"reports")!=undefined){
  808.                     try {
  809.                         let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "reports"))
  810.                         let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  811.                         let map_localBase=new Map( JSON.parse(decompressedData));
  812.    
  813.                         console.log("map_localBase",map_localBase)
  814.                         map_dropbox=new Map([...map_localBase, ...map_dropbox])
  815.                     } catch (error) {
  816.                         let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "reports"))));
  817.                         map_dropbox=new Map([...map_localBase, ...map_dropbox])
  818.                     }
  819.                 }
  820.  
  821.  
  822.                 try {
  823.                     let decompressedData = await decompress(await map_incomings.arrayBuffer() , 'gzip');  
  824.                     map_incomings=new Map( JSON.parse(decompressedData));
  825.                 } catch (error) {
  826.                     map_incomings=new Map()
  827.                 }
  828.  
  829.                 //if  database incomings is stored locally
  830.                 if(await localBase.getItem(game_data.world+"incomings")!=undefined){
  831.                     try {
  832.                         let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "incomings"))
  833.                         let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  834.                         let map_localBase=new Map( JSON.parse(decompressedData));
  835.    
  836.                         map_incomings=new Map([...map_localBase, ...map_incomings])
  837.                     } catch (error) {
  838.                         let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "incomings"))));
  839.                         map_incomings=new Map([...map_localBase, ...map_incomings])
  840.                     }
  841.                 }
  842.    
  843.                 try {
  844.                     let decompressedData = await decompress(await mapStatus.arrayBuffer() , 'gzip');  
  845.                     mapStatus=new Map( JSON.parse(decompressedData));
  846.                 } catch (error) {
  847.                     console.log("erorrr map report from dropbox")
  848.                     mapStatus=new Map()
  849.                 }
  850.  
  851.                
  852.                 // addWindow();
  853.                 let nr_update=0;
  854.                 let nr_write=0;
  855.                 list_data_reports.forEach(function(el){
  856.                     if(map_dropbox.has(el.coord)){//update   el[0]=key
  857.                         let obj_dropbox=map_dropbox.get(el.coord)
  858.                        
  859.                         if(el.coord==el.reportInfo.coordAttacker ){
  860.                             console.log("update for offensive" && el.reportInfo.typeAttacker!="?")
  861.                             delete el.reportInfo["troopsAtHome_"+el.coord]
  862.                             delete el.reportInfo["time_report_home_"+el.coord]
  863.  
  864.  
  865.                             if(el.reportInfo.typeAttacker=="new_off"){
  866.                                 console.log("new_off, don't do anything")
  867.                             }else{
  868.                                 console.log("coord exists in dropbox already")
  869.                                 let time_prev=new Date(obj_dropbox.time_report);
  870.                                 let time_current=new Date(el.reportInfo.time_report);
  871.                                 console.log(time_current-time_prev)
  872.                                 if(time_current-time_prev<48*3600*1000 && (el.reportInfo.typeAttacker=="def" )){//48 hours
  873.                                     console.log("it was def_cat")
  874.                                     map_dropbox.set(el.coord,{...obj_dropbox, ...el.reportInfo})//merge old info with new info
  875.                                     nr_update++;
  876.                                 }
  877.                                 else if(time_current-time_prev>=0 ){
  878.                                     console.log("update coord: "+el.coord+" in dropbox")
  879.                                     map_dropbox.set(el.coord,{...obj_dropbox, ...el.reportInfo})//merge old info with new info
  880.                                     nr_update++;
  881.                                 }
  882.                             }
  883.  
  884.                         }
  885.                         if(el.coord==el.reportInfo.coordDefender && el.reportInfo.typeDefender!="?"){
  886.                             console.log("update for defensive")
  887.                             if(el.reportInfo.typeDefender=="new_off" || el.reportInfo.typeDefender=="home_seen"){
  888.                                 console.log(`defend type:${el.reportInfo.typeDefender} update troops home`)
  889.  
  890.                                 let time_prev=new Date(obj_dropbox.time_report);
  891.                                 let time_current=new Date(el.reportInfo.time_report);
  892.  
  893.                                 if(time_current-time_prev>=0 ){
  894.                                     console.log("update coord: "+el.coord+" in dropbox")
  895.  
  896.                                     obj_dropbox["troopsAtHome_"+el.coord]=el.reportInfo["troopsAtHome_"+el.coord]
  897.                                     obj_dropbox["time_report_home_"+el.coord]=el.reportInfo["time_report_home_"+el.coord]
  898.  
  899.                                     map_dropbox.set(el.coord,obj_dropbox)
  900.                                     nr_update++;
  901.                                 }
  902.                                
  903.                             }else{
  904.                                 console.log("coord exists in dropbox already")
  905.                                 let time_prev=new Date(obj_dropbox.time_report);
  906.                                 let time_current=new Date(el.reportInfo.time_report);
  907.                                 console.log(time_current-time_prev)
  908.                                 if(time_current-time_prev<48*3600*1000 && (el.reportInfo.typeDefender=="def" )){//48 hours
  909.                                     console.log("it was def_cat")
  910.                                     map_dropbox.set(el.coord,{...obj_dropbox, ...el.reportInfo})
  911.                                     nr_update++;
  912.                                 }
  913.                                 else if(time_current-time_prev>=0 ){
  914.                                     console.log("update coord: "+el.coord+" in dropbox")
  915.                                     map_dropbox.set(el.coord,{...obj_dropbox, ...el.reportInfo})
  916.                                     nr_update++;
  917.                                 }
  918.                             }
  919.                         }
  920.                     }
  921.                     else{//write
  922.                         if(el.coord==el.reportInfo.coordAttacker && el.reportInfo.typeAttacker!="?"){
  923.                             delete el.reportInfo["troopsAtHome_"+el.coord]
  924.                             delete el.reportInfo["time_report_home_"+el.coord]
  925.  
  926.                             console.log("write coord in dropbox")
  927.                             map_dropbox.set(el.coord,el.reportInfo)
  928.                             nr_write++;
  929.                         }
  930.                         else if(el.coord==el.reportInfo.coordDefender && el.reportInfo.typeDefender!="?"){
  931.                             console.log("write coord in dropbox")
  932.                             if(el.reportInfo.typeDefender=="home_seen"){
  933.                                 el.reportInfo.typeDefender="?"
  934.                             }
  935.                            
  936.                             map_dropbox.set(el.coord,el.reportInfo)
  937.                             nr_write++;
  938.                         }
  939.                     }
  940.                 })
  941.  
  942.  
  943.  
  944.                 console.log("map_dropbox before",map_dropbox)
  945.    
  946.                 //clear map if contains data on tribe mates
  947.                 let counterAttacker=0;
  948.                 let counterDefender=0;
  949.                 let counterTypAttacker=0;
  950.                 let counterTypeDefender=0;
  951.                 Array.from(map_dropbox.keys()).forEach(key=>{
  952.                     try {
  953.                         let obj=map_dropbox.get(key)
  954.                         let obj_village=mapVillages.get(key)
  955.                         // console.log("key=> "+obj.time_report)
  956.  
  957.                         //if time reports is 0
  958.                         if(obj.time_report == 0){
  959.                             let serverTime=document.getElementById("serverTime").innerText
  960.                             let serverDate=document.getElementById("serverDate").innerText.split("/")
  961.                             let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  962.                             obj.time_report = months[parseInt(serverDate[1])-1]+" "+serverDate[0]+", "+serverDate[2]+" "+serverTime+ ":000";
  963.                             map_dropbox.set(key,obj)
  964.                         }
  965.                         let nameKey="time_report_home_"
  966.                         nameKey = nameKey.toLowerCase();// normalize both to lowercase to make it case insensitive
  967.                         const keys = Object.keys(obj);
  968.                         const wantedKey = keys.find(key => key.toLowerCase().includes(nameKey));
  969.                         //if time report return is 0
  970.                         if(obj[wantedKey] == 0){
  971.                             let serverTime=document.getElementById("serverTime").innerText
  972.                             let serverDate=document.getElementById("serverDate").innerText.split("/")
  973.                             let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  974.                             obj[wantedKey] = months[parseInt(serverDate[1])-1]+" "+serverDate[0]+", "+serverDate[2]+" "+serverTime+ ":000";
  975.                             map_dropbox.set(key,obj)
  976.                         }
  977.  
  978.  
  979.                         //remove non existent villages
  980.                         if(infoVillages.get(key) == undefined){
  981.                             map_dropbox.delete(key)
  982.  
  983.                         }
  984.  
  985.                         if(key == obj.coordAttacker){
  986.                             if(tribemates.includes(obj.nameAttacker.toLowerCase()) || obj.nameAttacker.toLowerCase() != obj_village.playerName.toLowerCase()  ){
  987.                                 map_dropbox.delete(key)
  988.                                 console.log(`delete coord ${key} old owner:${obj.nameAttacker.toLowerCase()} != new owner:${obj_village.playerName.toLowerCase()} (off report)`)
  989.                                 counterAttacker++
  990.                             }
  991.                             else if(obj.typeAttacker=="?"){
  992.                                 map_dropbox.delete(key)
  993.                                 counterTypAttacker++
  994.                             }
  995.                         }
  996.                         else if(key == obj.coordDefender){
  997.                             if(tribemates.includes(obj.nameDefender.toLowerCase()) || obj.nameDefender.toLowerCase() != obj_village.playerName.toLowerCase() ){
  998.                                 map_dropbox.delete(key)
  999.                                 counterDefender++
  1000.                                 console.log(`delete coord ${key} old owner:${obj.nameDefender.toLowerCase()} != new owner:${obj_village.playerName.toLowerCase()} (def report)`)
  1001.  
  1002.                             }
  1003.                             else if(obj.typeDefender=="?"){
  1004.                                 map_dropbox.delete(key)
  1005.                                 counterTypeDefender++
  1006.                             }                        
  1007.                         }
  1008.                        
  1009.                     } catch (error) {
  1010.                        
  1011.                     }
  1012.  
  1013.  
  1014.  
  1015.                 })  
  1016.                 console.log("remove counterAttacker",counterAttacker)
  1017.                 console.log("remove counterDefender",counterDefender)
  1018.                 console.log("remove counterTypAttacker",counterTypAttacker)
  1019.                 console.log("remove counterTypeDefender",counterTypeDefender)
  1020.            
  1021.  
  1022.                 console.log("map_dropbox after")
  1023.                 console.log(map_dropbox);
  1024.                 console.log("list_data_reports")
  1025.                 console.log(list_data_reports);
  1026.  
  1027.                 console.log("list_data_typeAttack",list_data_typeAttack)
  1028.                 //update attacks landed
  1029.                 list_data_typeAttack.forEach(el=>{
  1030.                     console.log(el.coord_off)
  1031.                     if(map_incomings.has(el.coord_off)){//add type attack for landed attack if still exists
  1032.                         let list_incs = map_incomings.get(el.coord_off)
  1033.                         for(let i=0;i<list_incs.length;i++){//find incomings
  1034.                             // console.log(el.coord_off+" == "+list_incs[i].coord_off+", "+list_incs[i].id_player_off+" == "+
  1035.                             // el.attackingPlayerId+", "+el.date_launch+" == "+list_incs[i].date_launch)
  1036.  
  1037.                             if(list_incs[i].coord_off.trim() == el.coord_off.trim()  &&
  1038.                                 list_incs[i].id_player_off.trim() == el.attackingPlayerId.trim()  &&
  1039.                                 el.date_launch.trim() == list_incs[i].date_launch.trim()
  1040.                                 ){
  1041.                                 console.log("inside breee")
  1042.                                 list_incs[i].type_attack_landed = el.typeAttack
  1043.                                 map_incomings.set(el.coord_off,list_incs)
  1044.                                 console.log("read report and update incoming")
  1045.                                 break;
  1046.                             }
  1047.                         }
  1048.                     }
  1049.                 })
  1050.  
  1051.  
  1052.  
  1053.                 let serverTime=document.getElementById("serverTime").innerText
  1054.                 let serverDate=document.getElementById("serverDate").innerText.split("/")
  1055.                 serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  1056.                 let date_current=serverDate+" "+serverTime
  1057.                 console.log(date_current)
  1058.                 //update status map
  1059.                 let obj_status={
  1060.                     name:game_data.player.name,
  1061.                     report_date:date_current,
  1062.                 }
  1063.  
  1064.  
  1065.                 if(mapStatus.has(game_data.player.id.toString())){
  1066.                     let obj_update=mapStatus.get(game_data.player.id.toString())
  1067.                     mapStatus.set(game_data.player.id.toString(), {...obj_update, ...obj_status} )
  1068.                 }
  1069.                 else{
  1070.                     mapStatus.set(game_data.player.id.toString(),obj_status)
  1071.                 }
  1072.  
  1073.                 let timeStartUpload = new Date().getTime();
  1074.                 var nr_start=new Date().getTime()
  1075.  
  1076.                 //upload reports
  1077.                 var data=JSON.stringify(Array.from(map_dropbox.entries()))
  1078.                 var length_data = data.length
  1079.                 let sizeReportsDB = formatBytes(new TextEncoder().encode(data).length)
  1080.  
  1081.                 let compressedData = await compress(data,'gzip')
  1082.                 let compressedDataBase64 = await blobToBase64(compressedData);
  1083.                 var length_data_compressed=compressedData.size;
  1084.    
  1085.                 var nr_stop=new Date().getTime()
  1086.                 console.log("after")
  1087.                 console.log(map_dropbox)
  1088.                 console.log("compressing data Reports: "+(nr_stop-nr_start))
  1089.                 console.log("length before: "+length_data+" length after compression: "+length_data_compressed)
  1090.                 console.log("compression factor: "+(length_data/length_data_compressed))
  1091.    
  1092.                        
  1093.  
  1094.  
  1095.                 let data_status=JSON.stringify(Array.from(mapStatus.entries()))
  1096.                 let dataCompressed = await compress(data_status, "gzip")
  1097.  
  1098.                 await localBase.setItem(game_data.world + "reports",compressedDataBase64)
  1099.                 let result=await uploadFile(compressedData, filename_reports, dropboxToken).catch(err=>alert(err))
  1100.                 let resultStatus=await uploadFile(dataCompressed, filename_status_upload, dropboxToken).catch(err=>alert(err))
  1101.  
  1102.  
  1103.                 //upload incomings
  1104.                 var nr_start=new Date().getTime()
  1105.                 data=JSON.stringify(Array.from(map_incomings.entries()))
  1106.                 compressedData = await compress(data, 'gzip')
  1107.                 compressedDataBase64 = await blobToBase64(compressedData);
  1108.                 var nr_stop=new Date().getTime()
  1109.                 console.log("compressing data Incomings: "+(nr_stop-nr_start))
  1110.  
  1111.  
  1112.                 await localBase.setItem(game_data.world + "incomings", compressedDataBase64)
  1113.                 result = await uploadFile(compressedData, filename_incomings, dropboxToken)
  1114.  
  1115.  
  1116.                
  1117.                 //save history
  1118.                 if(result=="succes"){
  1119.                     let data = JSON.stringify(Array.from(map_history_upload.entries()))
  1120.                     let compressedData = await compress(data, 'gzip')
  1121.                     let compressedDataBase64 = await blobToBase64(compressedData);
  1122.  
  1123.                     await localBase.setItem(game_data.world + "history_upload", compressedDataBase64)
  1124.                     await uploadFile(compressedData, filename_history_upload, dropboxToken).catch(err=>alert(err))
  1125.                     let timeStopUpload = new Date().getTime();
  1126.                     let totalTimeUpload =  Math.round(((timeStopUpload - timeStartUpload) / 1000) * 100) / 100
  1127.                     document.getElementById("progress_reports").innerText = nr_reports_total+" reports";
  1128.                     UI.SuccessMessage(`<b>Upload reports done</b> <br> <br>
  1129.                                         Upload time: <b>${totalTimeUpload} sec</b> <br>
  1130.                                         Reports Updated: <b>${nr_update}</b> <br>
  1131.                                         Reports Added: <b>${nr_write} </b> <br>
  1132.                                         Total Reports: <b>${map_dropbox.size} </b> <br>
  1133.                                         Size DB: <b>${sizeReportsDB} </b>`, 10000)
  1134.                     resolve({
  1135.                         totalTimeUpload:totalTimeUpload,
  1136.                         status: "success"
  1137.                     })
  1138.  
  1139.                 }
  1140.                 else
  1141.                      reject("error upload reports")
  1142.        
  1143.             }
  1144.         }
  1145.         ajaxRequest(list_href);
  1146.     })
  1147.  
  1148.    
  1149. }
  1150.  
  1151.  
  1152.  
  1153. function compress(string, encoding) {
  1154.     const byteArray = new TextEncoder().encode(string);
  1155.     const cs = new CompressionStream(encoding);
  1156.     const writer = cs.writable.getWriter();
  1157.     writer.write(byteArray);
  1158.     writer.close();
  1159.     return new Response(cs.readable).blob();
  1160.   }
  1161.  
  1162. function decompress(byteArray, encoding) {
  1163.     const cs = new DecompressionStream(encoding);
  1164.     const writer = cs.writable.getWriter();
  1165.     writer.write(byteArray);
  1166.     writer.close();
  1167.     return new Response(cs.readable).arrayBuffer().then(function (arrayBuffer) {
  1168.       return new TextDecoder().decode(arrayBuffer);
  1169.     });
  1170. }
  1171.  
  1172.  
  1173. function blobToBase64(blob) {
  1174.     return new Promise((resolve, reject) => {
  1175.         const reader = new FileReader();
  1176.         reader.onload = () => {
  1177.             const base64String = reader.result.split(',')[1];
  1178.             resolve(base64String);
  1179.         };
  1180.         reader.onerror = reject;
  1181.         reader.readAsDataURL(blob);
  1182.     });
  1183. }
  1184.  
  1185. function formatBytes(bytes, decimals = 2) {
  1186.     if (!+bytes) return '0 Bytes'
  1187.  
  1188.     const k = 1024
  1189.     const dm = decimals < 0 ? 0 : decimals
  1190.     const sizes = ['Bytes', 'KB', 'MB', 'GB', 'Tb', 'Pb', 'Eb', 'Zb', 'Yb']
  1191.  
  1192.     const i = Math.floor(Math.log(bytes) / Math.log(k))
  1193.  
  1194.     return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`
  1195. }
  1196.  
  1197. function base64ToBlob(base64String, type = 'application/octet-stream') {
  1198.     const byteCharacters = atob(base64String);
  1199.     const byteNumbers = new Array(byteCharacters.length);
  1200.     for (let i = 0; i < byteCharacters.length; i++) {
  1201.         byteNumbers[i] = byteCharacters.charCodeAt(i);
  1202.     }
  1203.     const byteArray = new Uint8Array(byteNumbers);
  1204.     return new Blob([byteArray], { type: type });
  1205. }
  1206.  
  1207.  
  1208.  
  1209. ///////////////////////////////////////////////////////////////////get all links////////////////////////////////////////////////////////////////
  1210. function getLinks(all,map_idReports){
  1211.  
  1212.     // var currentPage=document.body.innerHTML;
  1213.     return new Promise(async(resolve,reject)=>{
  1214.         let link_reports=window.location.href;
  1215.         if(link_reports.includes("screen=report"))// upload only reports from current folder
  1216.             all=false;
  1217.         if(all){// all pages from all folders
  1218.             link_reports = game_data.link_base_pure+"report&mode=all&group_id=-1";
  1219.         }
  1220.         let datePage = await ajaxGet(link_reports)
  1221.         const parser = new DOMParser();
  1222.         const htmlDoc = parser.parseFromString(datePage, 'text/html');
  1223.  
  1224.  
  1225.         let list_pages=[]
  1226.    
  1227.         if($(htmlDoc).find(".paged-nav-item").parent().find("select").length>0){
  1228.             Array.from($(htmlDoc).find(".paged-nav-item").parent().find("select").find("option")).forEach(function(item){
  1229.                 list_pages.push(item.value)
  1230.             })
  1231.             list_pages.pop();
  1232.         }
  1233.         else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){//all pages from the current folder
  1234.             let nr=0;
  1235.             let pageSize = parseInt($(htmlDoc).find("[name='page_size']").val())
  1236.             let length = htmlDoc.getElementsByClassName("paged-nav-item").length+1
  1237.             for(let i=0;i<length;i++){
  1238.                 let page = game_data.link_base_pure+"report&mode=all&from="+nr
  1239.                 list_pages.push(page)
  1240.                 nr += pageSize;
  1241.             }
  1242.  
  1243.    
  1244.         }
  1245.         else{
  1246.             list_pages.push(link_reports);
  1247.         }
  1248.         list_pages=list_pages.reverse();
  1249.         console.log(list_pages)
  1250.  
  1251.  
  1252.    
  1253.         let list_href=[];
  1254.        
  1255.         const run = async () => {
  1256.             console.log("Starting...");
  1257.             for (let i = 0; i < list_pages.length; i++) {
  1258.                 let pageHTML= await ajaxGet(list_pages[i])
  1259.                 const parser = new DOMParser();
  1260.                 const htmlDoc = parser.parseFromString(pageHTML, 'text/html');
  1261.  
  1262.                 let table_report= htmlDoc.getElementById("report_list").firstElementChild.children;
  1263.                 let year=htmlDoc.getElementById("serverDate").innerText.split("/")[2];
  1264.  
  1265.                 for(let i=1;i<table_report.length-1;i++){
  1266.                     let month_day=table_report[i].children[2].innerText;
  1267.                     if(month_day.includes("Jan"))
  1268.                         month_day = month_day.replace("Jan","01")
  1269.  
  1270.                     let date_report=new Date(year+" "+month_day)
  1271.                     let current_date=new Date();
  1272.                     if(Math.abs(current_date-date_report)<7*24*3600*1000){//old
  1273.        
  1274.                         let img_icon=table_report[i].children[1].children[0].children.length;
  1275.                         if(img_icon>0){//wordsTranslate[0]=supports ///// || table_report[i].innerText.includes(wordsTranslate[0])
  1276.                             let obj={
  1277.                                 id:table_report[i].getElementsByTagName("a")[0].getAttribute("data-id"),
  1278.                                 href:table_report[i].getElementsByTagName("a")[0].href
  1279.                             }
  1280.                             if(!map_idReports.has(parseInt(obj.id)))
  1281.                                 list_href.push(obj)
  1282.                         }
  1283.                     }
  1284.                 }
  1285.                 UI.SuccessMessage(`get link page ${i+1}/${list_pages.length}`)
  1286.             }  
  1287.         }
  1288.         await run();
  1289.         console.log("Done!");
  1290.         resolve(list_href)
  1291.  
  1292.              
  1293.              
  1294.            
  1295.  
  1296.  
  1297.     })
  1298.    
  1299. }
  1300.  
  1301.  
  1302. function ajaxGet(theUrl){
  1303.     return new Promise((resolve,reject)=>{
  1304.         let units=game_data.units.slice()
  1305.         if(units.includes("militia")){
  1306.             units.pop()
  1307.         }
  1308.  
  1309.         let startAjax=new Date().getTime()
  1310.         $.ajax({
  1311.             url: theUrl,
  1312.             method: 'get',
  1313.             success: (data) => {
  1314.                
  1315.                 let stopAjax=new Date().getTime()
  1316.                 let difAjax=stopAjax-startAjax
  1317.                 console.log("wait ",difAjax)
  1318.                 window.setTimeout(()=>{
  1319.                     resolve(data)
  1320.                 },200-difAjax)
  1321.  
  1322.             },error:(data)=>{
  1323.                 reject(data)
  1324.             }
  1325.  
  1326.         })
  1327.     })
  1328. }
  1329.  
  1330.  
  1331.  
  1332. ////////////////////////////////////////////////////////////get data from report////////////////////////////////////////////////////////////////////
  1333.  
  1334. function getDataReport(tribemates,htmlDoc){
  1335.     var mapObject={};
  1336.     var listObject=[];
  1337.     var popOff=10000;
  1338.     // tribemates=[]
  1339.     var reportInfo={};
  1340.     try{
  1341.     if($(htmlDoc).find("#attack_info_att").length>0){
  1342.         var attackInfo=$(htmlDoc).find("#attack_info_att");
  1343.         if(attackInfo.text().includes("deleted") || attackInfo.text().includes("---")){
  1344.             console.log("error upload")
  1345.             return 0;
  1346.         }
  1347.         var defenseInfo = $(htmlDoc).find("#attack_info_def");
  1348.         if(defenseInfo.text().includes("deleted") || defenseInfo.text().includes("---")){
  1349.             console.log("error upload")
  1350.             return 0;
  1351.         }
  1352.        
  1353.         var attackingPlayer = attackInfo.find('a[href*=info_player]');
  1354.         var defendingPlayer = defenseInfo.find('a[href*=info_player]');
  1355.         var attackingPlayerId=attackingPlayer.prop('href').match(/id=(\w+)/)[1];
  1356.         var defendingPlayerId=defendingPlayer.prop('href').match(/id=(\w+)/)[1];
  1357.         reportInfo.attackingPlayerId=attackingPlayerId;
  1358.         reportInfo.defendingPlayerId=defendingPlayerId;
  1359.     }
  1360.     ///////////////////////////////////////////////////////////////////////////
  1361.    
  1362.    
  1363.     if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>1)
  1364.     {
  1365.         var time_report=htmlDoc.getElementsByClassName("small grey")[0].parentElement.innerText.trim()
  1366.         // if(new Date()-new Date(time_report)>14*24*3600*1000)//report too old
  1367.         //     return listObject;
  1368.         reportInfo.attackingArmy = attackInfo.find('#attack_info_att_units tr:nth-of-type(2) .unit-item').get().map((el) => { return { type: $(el).prop('class').match(/unit-item-([\w\-]+)/)[1], count: parseInt($(el).text().trim()) } })
  1369.         reportInfo.attackingArmyLosses = attackInfo.find('#attack_info_att_units tr:nth-of-type(3) .unit-item').get().map((el) => { return { type: $(el).prop('class').match(/unit-item-([\w\-]+)/)[1], count: parseInt($(el).text().trim()) } })
  1370.  
  1371.         reportInfo.time_report=time_report
  1372.         var report=htmlDoc.getElementsByClassName("vis")[3].innerHTML;
  1373.         var index=report.indexOf('<div class="no-preview">');
  1374.         report=report.substring(0,index);
  1375.         // report=lzw_encode(report);
  1376.         // reportInfo.report=report;
  1377.  
  1378.  
  1379.         //if time reports is 0
  1380.         if(reportInfo.time_report == 0){
  1381.             let serverTime=htmlDoc.getElementById("serverTime").innerText
  1382.             let serverDate=htmlDoc.getElementById("serverDate").innerText.split("/")
  1383.             let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  1384.             time_report = months[parseInt(serverDate[1])-1]+" "+serverDate[0]+", "+serverDate[2]+" "+serverTime+ ":000";
  1385.             reportInfo.time_report = time_report
  1386.         }
  1387.  
  1388.    
  1389.  
  1390.  
  1391.  
  1392.  
  1393.         ///////////////////////////defender date////////////////////
  1394.         var nameAttacker=htmlDoc.getElementById("attack_info_att").children[0].children[0].children[1].innerText;
  1395.         var coordAttacker=htmlDoc.getElementsByClassName("village_anchor")[0].innerText.match(/\d+\|\d+/)[0];
  1396.         var nameDefender=htmlDoc.getElementById("attack_info_def").children[0].children[0].children[1].innerText;
  1397.         var coordDefender=htmlDoc.getElementsByClassName("village_anchor")[1].innerText.match(/\d+\|\d+/)[0];
  1398.        
  1399.  
  1400.         reportInfo.nameAttacker=nameAttacker;
  1401.         reportInfo.coordAttacker=coordAttacker;
  1402.         reportInfo.nameDefender=nameDefender;
  1403.         reportInfo.coordDefender=coordDefender;
  1404.  
  1405.         if(reportInfo.attackingArmy[3].type=="archer"){
  1406.             var spear_atac_total =reportInfo.attackingArmy[0].count
  1407.             var sword_atac_total =reportInfo.attackingArmy[1].count
  1408.             var axe_atac_total   =reportInfo.attackingArmy[2].count
  1409.             var archer_atac_total=reportInfo.attackingArmy[3].count
  1410.             var spy_atac_total   =reportInfo.attackingArmy[4].count*2
  1411.             var light_atac_total =reportInfo.attackingArmy[5].count*4
  1412.             var heavy_atac_total =reportInfo.attackingArmy[7].count*6
  1413.             var ram_atac_total   =reportInfo.attackingArmy[8].count*5
  1414.             var cat_atac_total   =reportInfo.attackingArmy[9].count*8
  1415.             var noble=parseInt(htmlDoc.getElementsByClassName("unit-item unit-item-snob")[0].innerText)*100;
  1416.  
  1417.             var spear_atac_pierderi =reportInfo.attackingArmyLosses[0].count
  1418.             var sword_atac_pierderi =reportInfo.attackingArmyLosses[1].count
  1419.             var axe_atac_pierderi   =reportInfo.attackingArmyLosses[2].count
  1420.             var archer_atac_pierderi=reportInfo.attackingArmyLosses[3].count
  1421.             var spy_atac_pierderi   =reportInfo.attackingArmyLosses[4].count*2
  1422.             var light_atac_pierderi =reportInfo.attackingArmyLosses[5].count*4
  1423.             var heavy_atac_pierderi =reportInfo.attackingArmyLosses[7].count*6
  1424.             var ram_atac_pierderi   =reportInfo.attackingArmyLosses[8].count*5
  1425.             var cat_atac_pierderi   =reportInfo.attackingArmyLosses[9].count*8
  1426.         }
  1427.         else{
  1428.             var spear_atac_total=reportInfo.attackingArmy[0].count
  1429.             var sword_atac_total=reportInfo.attackingArmy[1].count
  1430.             var axe_atac_total  =reportInfo.attackingArmy[2].count
  1431.             var spy_atac_total  =reportInfo.attackingArmy[3].count*2
  1432.             var light_atac_total=reportInfo.attackingArmy[4].count*4
  1433.             var heavy_atac_total=reportInfo.attackingArmy[5].count*6
  1434.             var ram_atac_total  =reportInfo.attackingArmy[6].count*5
  1435.             var cat_atac_total  =reportInfo.attackingArmy[7].count*8
  1436.             var noble=parseInt(htmlDoc.getElementsByClassName("unit-item unit-item-snob")[0].innerText)*100;
  1437.             var archer_atac_total=0;
  1438.  
  1439.             var spear_atac_pierderi=reportInfo.attackingArmyLosses[0].count
  1440.             var sword_atac_pierderi=reportInfo.attackingArmyLosses[1].count
  1441.             var axe_atac_pierderi  =reportInfo.attackingArmyLosses[2].count
  1442.             var spy_atac_pierderi  =reportInfo.attackingArmyLosses[3].count*2
  1443.             var light_atac_pierderi=reportInfo.attackingArmyLosses[4].count*4
  1444.             var heavy_atac_pierderi=reportInfo.attackingArmyLosses[5].count*6
  1445.             var ram_atac_pierderi  =reportInfo.attackingArmyLosses[6].count*5
  1446.             var cat_atac_pierderi  =reportInfo.attackingArmyLosses[7].count*8
  1447.  
  1448.         }
  1449.  
  1450.  
  1451.  
  1452.         var typeAttacker="?";
  1453.         var nrTroupesAttacker=0;
  1454.         var nrTroupesAttackerTotal=0;
  1455.         var time_return=0;
  1456.  
  1457.         if(axe_atac_total+light_atac_total+ram_atac_total + cat_atac_total >=popOff)//&& axe_atac_total>=2500
  1458.         {
  1459.            
  1460.             typeAttacker="off";
  1461.             nrTroupesAttacker=(axe_atac_total-axe_atac_pierderi)+(light_atac_total-light_atac_pierderi) + (ram_atac_total-ram_atac_pierderi);
  1462.             if(ram_atac_total>0 && noble==0 && axe_atac_total>=0){
  1463.                 nrTroupesAttackerTotal=axe_atac_total+light_atac_total+ram_atac_total
  1464.                 let time_attack=ramSpeed*calcDistance(coordAttacker,coordDefender)
  1465.                 time_return=new Date(time_report).getTime()+time_attack;
  1466.                 time_return=new Date(time_return)
  1467.                 let date=new Date(time_return).toDateString().split(" ").slice(1).join(" ")
  1468.                 time_return=date+" "+new Date(time_return).toTimeString().split(" ")[0]
  1469.                
  1470.             }else if(axe_atac_total>=0 && noble==0 ){
  1471.                 nrTroupesAttackerTotal=axe_atac_total+light_atac_total
  1472.                 time_attack=axeSpeed*calcDistance(coordAttacker,coordDefender)
  1473.                 time_return=new Date(time_report).getTime()+time_attack;
  1474.                 time_return=new Date(time_return)
  1475.                 let date=new Date(time_return).toDateString().split(" ").slice(1).join(" ")
  1476.                 time_return=date+" "+new Date(time_return).toTimeString().split(" ")[0]    
  1477.  
  1478.             }else if(axe_atac_total>=0 && noble>0){
  1479.                 nrTroupesAttackerTotal=axe_atac_total+light_atac_total+ram_atac_total
  1480.                 time_attack=axeSpeed*calcDistance(coordAttacker,coordDefender)
  1481.                 time_return=new Date(time_report).getTime()+time_attack;
  1482.                 time_return=new Date(time_return)
  1483.                 let date=new Date(time_return).toDateString().split(" ").slice(1).join(" ")
  1484.                 time_return=date+" "+new Date(time_return).toTimeString().split(" ")[0]    
  1485.             }
  1486.         }
  1487.         else if(spy_atac_total>4000){
  1488.             typeAttacker="spy";
  1489.             nrTroupesAttacker=spy_atac_total-spy_atac_pierderi;
  1490.         }
  1491.         else if(axe_atac_total+light_atac_total+ram_atac_total >20 && spear_atac_total+sword_atac_total+archer_atac_total+heavy_atac_total<15)
  1492.         {
  1493.             typeAttacker="new_off";
  1494.         }
  1495.         else if(axe_atac_total+light_atac_total+ram_atac_total <15 && spear_atac_total+sword_atac_total+archer_atac_total+heavy_atac_total>15){
  1496.             typeAttacker="def";
  1497.         }
  1498.         else if(spy_atac_total>=800 && axe_atac_total+light_atac_total+ram_atac_total<500 && spear_atac_total+sword_atac_total+archer_atac_total+heavy_atac_total<40){
  1499.             typeAttacker="def_spy";
  1500.         }
  1501.         else if(spear_atac_total + sword_atac_total + archer_atac_total > 1000){
  1502.             typeAttacker="def";
  1503.         }
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.         if((cat_atac_total>=50*8 && typeAttacker=="def") || (cat_atac_total>=50*8 && axe_atac_total+light_atac_total+ram_atac_total<20)){
  1510.        
  1511.             typeAttacker="def_cat";
  1512.             nrTroupesAttacker=cat_atac_total-cat_atac_pierderi;
  1513.             if(noble==0){
  1514.                 nrTroupesAttackerTotal=heavy_atac_total+cat_atac_total
  1515.                 time_attack=ramSpeed*calcDistance(coordAttacker,coordDefender)
  1516.                 time_return=new Date(time_report).getTime()+time_attack;
  1517.                 time_return=new Date(time_return)
  1518.                 let date=new Date(time_return).toDateString().split(" ").slice(1).join(" ")
  1519.                 time_return=date+" "+new Date(time_return).toTimeString().split(" ")[0]              
  1520.             }
  1521.         }
  1522.  
  1523.  
  1524.  
  1525.         reportInfo.time_return=time_return
  1526.         reportInfo.nrTroupesAttackerTotal=nrTroupesAttackerTotal
  1527.         reportInfo.typeAttacker=typeAttacker;
  1528.         reportInfo.nrTroupesAttacker=nrTroupesAttacker;
  1529.        
  1530.  
  1531.        
  1532.         /////////////////////////////////////////////////defender date/////////////////////
  1533.         var nrTroupesDefender=0;
  1534.         var typeDefender="?";
  1535.         if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>2){
  1536.            
  1537.             reportInfo.defendingArmy = defenseInfo.find('#attack_info_def_units tr:nth-of-type(2) .unit-item').get().map((el) => { return { type: $(el).prop('class').match(/unit-item-([\w\-]+)/)[1], count: parseInt($(el).text().trim()) } })
  1538.             reportInfo.defendingArmyLosses = defenseInfo.find('#attack_info_def_units tr:nth-of-type(3) .unit-item').get().map((el) => { return { type: $(el).prop('class').match(/unit-item-([\w\-]+)/)[1], count: parseInt($(el).text().trim()) } })
  1539.  
  1540.             let armyAtHome=[]
  1541.  
  1542.             for(let i=0;i<reportInfo.defendingArmy.length;i++){
  1543.                 armyAtHome.push({
  1544.                     type:reportInfo.defendingArmy[i].type,
  1545.                     count:reportInfo.defendingArmy[i].count-reportInfo.defendingArmyLosses[i].count
  1546.                 })
  1547.             }
  1548.             if(!tribemates.includes(nameDefender.toLowerCase())){
  1549.                 reportInfo["troopsAtHome_"+coordDefender]=armyAtHome
  1550.                 reportInfo["time_report_home_"+coordDefender]=time_report
  1551.             }
  1552.  
  1553.  
  1554.             if(reportInfo.defendingArmy[3].type=="archer"){
  1555.                 var spear_aparare_total =reportInfo.defendingArmy[0].count
  1556.                 var sword_aparare_total =reportInfo.defendingArmy[1].count
  1557.                 var axe_aparare_total   =reportInfo.defendingArmy[2].count
  1558.                 var archer_aparare_total=reportInfo.defendingArmy[3].count
  1559.                 var spy_aparare_total   =reportInfo.defendingArmy[4].count*2
  1560.                 var light_aparare_total =reportInfo.defendingArmy[5].count*4
  1561.                 var heavy_aparare_total =reportInfo.defendingArmy[7].count*6
  1562.                 var ram_aparare_total   =reportInfo.defendingArmy[8].count*5
  1563.                 var cat_aparare_total   =reportInfo.defendingArmy[9].count*8
  1564.  
  1565.                 var spear_aparare_pierderi =reportInfo.defendingArmyLosses[0].count
  1566.                 var sword_aparare_pierderi =reportInfo.defendingArmyLosses[1].count
  1567.                 var axe_aparare_pierderi   =reportInfo.defendingArmyLosses[2].count
  1568.                 var archer_aparare_pierderi=reportInfo.defendingArmyLosses[3].count
  1569.                 var spy_aparare_pierderi   =reportInfo.defendingArmyLosses[4].count*2
  1570.                 var light_aparare_pierderi =reportInfo.defendingArmyLosses[5].count*4
  1571.                 var heavy_aparare_pierderi =reportInfo.defendingArmyLosses[7].count*6
  1572.                 var ram_aparare_pierderi   =reportInfo.defendingArmyLosses[8].count*5
  1573.                 var cat_aparare_pierderi   =reportInfo.defendingArmyLosses[9].count*8
  1574.  
  1575.             }
  1576.             else{
  1577.                 var spear_aaparare_total=reportInfo.defendingArmy[0].count
  1578.                 var sword_aparare_total =reportInfo.defendingArmy[1].count
  1579.                 var axe_aparare_total   =reportInfo.defendingArmy[2].count
  1580.                 var spy_aparare_total   =reportInfo.defendingArmy[3].count*2
  1581.                 var light_aparare_total =reportInfo.defendingArmy[4].count*4
  1582.                 var heavy_aparare_total =reportInfo.defendingArmy[5].count*6
  1583.                 var ram_aparare_total   =reportInfo.defendingArmy[6].count*5
  1584.                 var cat_aparare_total   =reportInfo.defendingArmy[7].count*8
  1585.                 var archer_aparare_total=0;
  1586.  
  1587.                 var spear_aaparare_pierderi=reportInfo.defendingArmyLosses[0].count
  1588.                 var sword_aparare_pierderi =reportInfo.defendingArmyLosses[1].count
  1589.                 var axe_aparare_pierderi   =reportInfo.defendingArmyLosses[2].count
  1590.                 var spy_aparare_pierderi   =reportInfo.defendingArmyLosses[3].count*2
  1591.                 var light_aparare_pierderi =reportInfo.defendingArmyLosses[4].count*4
  1592.                 var heavy_aparare_pierderi =reportInfo.defendingArmyLosses[5].count*6
  1593.                 var ram_aparare_pierderi   =reportInfo.defendingArmyLosses[6].count*5
  1594.                 var cat_aparare_pierderi   =reportInfo.defendingArmyLosses[7].count*8
  1595.                 var archer_aparare_pierderi=0;
  1596.  
  1597.             }
  1598.  
  1599.  
  1600.  
  1601.             nrTroupesDefender=(axe_aparare_total-axe_aparare_pierderi)+(light_aparare_total-light_aparare_pierderi) + (ram_aparare_total-ram_aparare_pierderi);
  1602.             if(axe_aparare_total+light_aparare_total+ram_aparare_total +cat_aparare_total >=popOff ){//axe_aparare_total>=2500
  1603.                 typeDefender="off";
  1604.             }
  1605.             else if(axe_aparare_total+light_aparare_total+ram_aparare_total +cat_aparare_total >=500 ){//axe_aparare_total>=2500
  1606.                 typeDefender="new_off";
  1607.             }
  1608.             else{
  1609.                 typeDefender="home_seen";
  1610.  
  1611.             }
  1612.  
  1613.  
  1614.         }
  1615.  
  1616.         if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>4){
  1617.             let travelingTroopsContainer = $(htmlDoc).find('#attack_spy_away');
  1618.             if (travelingTroopsContainer.length)
  1619.             {
  1620.                 reportInfo.travelingTroops = {};
  1621.        
  1622.                 travelingTroopsContainer.find('.unit-item').each((i, el) => {
  1623.                     let $el = $(el);
  1624.                     let cls = $el.prop('class');
  1625.                     let unitType = cls.match(/unit\-item\-(\w+)/)[1];
  1626.                     reportInfo.travelingTroops[unitType] = parseInt($el.text().trim());
  1627.                 });
  1628.            
  1629.                 var axe_aparare_spy=reportInfo.travelingTroops.axe
  1630.                 var light_aparare_spy=reportInfo.travelingTroops.light*4;
  1631.                 var ram_aparare_spy=reportInfo.travelingTroops.ram*5;
  1632.                 nrTroupesDefender+=axe_aparare_spy+(light_aparare_spy) + (ram_aparare_spy)
  1633.    
  1634.                 if(nrTroupesDefender >= popOff )
  1635.                     typeDefender="off";
  1636.  
  1637.                 else{
  1638.                     var spear_aparare_spy=reportInfo.travelingTroops.spear
  1639.                     var sword_aparare_spy=reportInfo.travelingTroops.sword
  1640.                     if(htmlDoc.getElementsByClassName("unit-item unit-item-archer").length>0)
  1641.                         var archer_aparare_spy=reportInfo.travelingTroops.archer
  1642.                     else
  1643.                         var archer_aparare_spy=0
  1644.    
  1645.                     var heavy_aparare_spy=reportInfo.travelingTroops.heavy*6;
  1646.                     var trupe_aparare_total=spear_aparare_total+sword_aparare_total+archer_aparare_total+heavy_aparare_total;
  1647.                     var total_aparare_spy=spear_aparare_spy+sword_aparare_spy+archer_aparare_spy+heavy_aparare_spy;
  1648.        
  1649.                     if(total_aparare_spy>1000){
  1650.                         typeDefender="def";
  1651.                         nrTroupesDefender=total_aparare_spy;
  1652.                     }
  1653.                     else if(axe_aparare_spy+light_aparare_spy <10 &&  axe_aparare_total+light_aparare_total<100 &&  trupe_aparare_total>5000 && total_aparare_spy<=1000){
  1654.                         typeDefender="def??";
  1655.                     }
  1656.                 }
  1657.             }
  1658.  
  1659.         }
  1660.         reportInfo.typeDefender=typeDefender;
  1661.         reportInfo.nrTroupesDefender=nrTroupesDefender;
  1662.  
  1663.         if(!tribemates.includes(nameAttacker.toLowerCase())){
  1664.             try {
  1665.                 let label = $(".rename-icon").parent().text()
  1666.                 if(label.includes("pred: fake")){
  1667.                     if(nrTroupesAttacker < 150){// true fake
  1668.                         let countApiKey = "fake_true";
  1669.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1670.                             console.log(`nr fake true:${response.count} times`);
  1671.                         });
  1672.                     }
  1673.                     else{
  1674.                         let countApiKey = "fake_false";
  1675.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1676.                             console.log(`nr fake false: ${response.count} times`);
  1677.                         });
  1678.                     }
  1679.                 }
  1680.                 else if(label.includes("pred: nuke")){
  1681.                     if(nrTroupesAttacker > 150 && typeAttacker == "off"){// true fake
  1682.                         let countApiKey = "nuke_true";
  1683.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1684.                             console.log(`nr nuke true: ${response.count} times`);
  1685.                         });
  1686.                     }
  1687.                     else{
  1688.                         let countApiKey = "nuke_false";
  1689.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1690.                             console.log(`nr nuke false: ${response.count} times`);
  1691.                         });
  1692.                     }
  1693.                 }
  1694.                 else if(label.includes("pred: fang")){
  1695.                     if(nrTroupesAttacker > 150 && typeAttacker == "def_cat"){// true fake
  1696.                         let countApiKey = "fang_true";
  1697.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1698.                             console.log(`nr fang true: ${response.count} times`);
  1699.                         });
  1700.                     }
  1701.                     else{
  1702.                         let countApiKey = "fang_false";
  1703.                         $.getJSON(`https://api.counterapi.dev/v1/${countNameSpace}/${countApiKey}/up`, response=>{
  1704.                             console.log(`nr fang false: ${response.count} times`);
  1705.                         });
  1706.                     }
  1707.                 }
  1708.                
  1709.             } catch (error) {
  1710.                
  1711.             }
  1712.         }
  1713.  
  1714.         if(!tribemates.includes(nameAttacker.toLowerCase()) && !reportInfo.typeAttacker.includes("?")){//!reportInfo.typeAttacker.includes("?")
  1715.             // console.log("attacker")
  1716.             mapObject.coord=coordAttacker;
  1717.             mapObject.reportInfo=reportInfo;
  1718.             listObject.push(mapObject);
  1719.             mapObject={};
  1720.         }
  1721.         if(!tribemates.includes(nameDefender.toLowerCase()) && !reportInfo.typeDefender.includes("?")){
  1722.             // console.log("defender")
  1723.             mapObject.coord=coordDefender;
  1724.             mapObject.reportInfo=reportInfo;
  1725.             listObject.push(mapObject);
  1726.         }
  1727.     }
  1728.     else if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length==0 || htmlDoc.getElementsByClassName("g-recaptcha").length>0
  1729.         ||htmlDoc.getElementsByClassName("unit-item unit-item-axe")==undefined ||  checkContainsCaptcha(htmlDoc)==true){//recaptcha
  1730.         console.log("recapthca")
  1731.         return null;
  1732.     }
  1733.    
  1734.     return listObject;
  1735.     }
  1736.     catch(e){
  1737.         console.log("erorr in upload")
  1738.         console.log(e)
  1739.         return 0;
  1740.     }
  1741.  
  1742. }
  1743.  
  1744. function getDataReportTypeAttack(tribemates,htmlDoc){
  1745.     var listObject=[];
  1746.     var popOff=1000;
  1747.     // tribemates=[]
  1748.     try{
  1749.     if($(htmlDoc).find("#attack_info_att").length>0){
  1750.         var attackInfo=$(htmlDoc).find("#attack_info_att");
  1751.         if(attackInfo.text().includes("deleted") || attackInfo.text().includes("---")){
  1752.             console.log("error upload")
  1753.             return 0;
  1754.         }
  1755.         var defenseInfo = $(htmlDoc).find("#attack_info_def");
  1756.         if(defenseInfo.text().includes("deleted") || defenseInfo.text().includes("---")){
  1757.             console.log("error upload")
  1758.             return 0;
  1759.         }
  1760.        
  1761.         var attackingPlayer = attackInfo.find('a[href*=info_player]');
  1762.         var defendingPlayer = defenseInfo.find('a[href*=info_player]');
  1763.         var attackingPlayerId=attackingPlayer.prop('href').match(/id=(\w+)/)[1];
  1764.         var defendingPlayerId=defendingPlayer.prop('href').match(/id=(\w+)/)[1];
  1765.  
  1766.     }
  1767.     ///////////////////////////////////////////////////////////////////////////
  1768.    
  1769.    
  1770.     if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length>1)
  1771.     {
  1772.         var time_report=htmlDoc.getElementsByClassName("small grey")[0].parentElement.innerText.trim()
  1773.         let attackingArmy = attackInfo.find('#attack_info_att_units tr:nth-of-type(2) .unit-item').get().map((el) => { return { type: $(el).prop('class').match(/unit-item-([\w\-]+)/)[1], count: parseInt($(el).text().trim()) } })
  1774.         //if time reports is 0
  1775.         if(time_report == 0){
  1776.             let serverTime=htmlDoc.getElementById("serverTime").innerText
  1777.             let serverDate=htmlDoc.getElementById("serverDate").innerText.split("/")
  1778.             let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  1779.             time_report = months[parseInt(serverDate[1])-1]+" "+serverDate[0]+", "+serverDate[2]+" "+serverTime+ ":000";
  1780.         }
  1781.         let millis=parseInt( time_report.split(":").pop());
  1782.  
  1783.  
  1784.         ///////////////////////////defender date////////////////////
  1785.         var nameAttacker=htmlDoc.getElementById("attack_info_att").children[0].children[0].children[1].innerText;
  1786.         var coordAttacker=htmlDoc.getElementsByClassName("village_anchor")[0].innerText.match(/\d+\|\d+/)[0];
  1787.         var nameDefender=htmlDoc.getElementById("attack_info_def").children[0].children[0].children[1].innerText;
  1788.         var coordDefender=htmlDoc.getElementsByClassName("village_anchor")[1].innerText.match(/\d+\|\d+/)[0];
  1789.        
  1790.  
  1791.         if(attackingArmy[3].type=="archer"){
  1792.             var spear_atac_total =attackingArmy[0].count
  1793.             var sword_atac_total =attackingArmy[1].count
  1794.             var axe_atac_total   =attackingArmy[2].count
  1795.             var archer_atac_total=attackingArmy[3].count
  1796.             var light_atac_total =attackingArmy[5].count*4
  1797.             var heavy_atac_total =attackingArmy[7].count*6
  1798.             var ram_atac_total   =attackingArmy[8].count*5
  1799.             var cat_atac_total   =attackingArmy[9].count*8
  1800.         }
  1801.         else{
  1802.             var spear_atac_total=attackingArmy[0].count
  1803.             var sword_atac_total=attackingArmy[1].count
  1804.             var axe_atac_total  =attackingArmy[2].count
  1805.             var light_atac_total=attackingArmy[4].count*4
  1806.             var heavy_atac_total=attackingArmy[5].count*6
  1807.             var ram_atac_total  =attackingArmy[6].count*5
  1808.             var cat_atac_total  =attackingArmy[7].count*8
  1809.             var archer_atac_total=0;
  1810.  
  1811.         }
  1812.  
  1813.  
  1814.         let typeAttack = "?"
  1815.  
  1816.         if(axe_atac_total+light_atac_total+ram_atac_total + cat_atac_total >=popOff)//&& axe_atac_total>=2500
  1817.         {
  1818.             if(ram_atac_total>0 || cat_atac_total>0)
  1819.                 typeAttack="nuke"      
  1820.         }
  1821.         else if( cat_atac_total>=50*8 && axe_atac_total+light_atac_total+ram_atac_total<20){
  1822.             if(ram_atac_total>0 || cat_atac_total>0)
  1823.                 typeAttack="fang"
  1824.         }
  1825.         else if(axe_atac_total+light_atac_total+ram_atac_total+spear_atac_total+
  1826.                 sword_atac_total+archer_atac_total+heavy_atac_total +cat_atac_total + ram_atac_total < 150){
  1827.             if(ram_atac_total>0 || cat_atac_total>0)
  1828.                 typeAttack="fake"
  1829.  
  1830.         }  
  1831.  
  1832.         if(!tribemates.includes(nameAttacker.toLowerCase()) && !typeAttack.includes("?")){
  1833.             let distance = calcDistance(coordAttacker,coordDefender)
  1834.  
  1835.             let durationAttack = ramSpeed*distance //mm
  1836.             durationAttack=Math.round(durationAttack/1000)*1000
  1837.             let date_launch = new Date(time_report).getTime() - durationAttack ;
  1838.             date_launch = new Date(date_launch).getTime()
  1839.             date_launch = parseDate(date_launch)+":"+millis;
  1840.  
  1841.  
  1842.             listObject.push({
  1843.                 date_launch:date_launch,
  1844.                 typeAttack:typeAttack,
  1845.                 attackingPlayerId:attackingPlayerId,
  1846.                 coord_off:coordAttacker
  1847.             });
  1848.             // console.log("listObject2")
  1849.             // console.log(listObject)
  1850.         }
  1851.        
  1852.  
  1853.     }
  1854.     else if(htmlDoc.getElementsByClassName("unit-item unit-item-axe").length==0 || htmlDoc.getElementsByClassName("g-recaptcha").length>0
  1855.         ||htmlDoc.getElementsByClassName("unit-item unit-item-axe")==undefined ||  checkContainsCaptcha(htmlDoc)==true){//recaptcha
  1856.         console.log("recapthca")
  1857.         return null;
  1858.     }
  1859.     // console.log("listObject")
  1860.     // console.log(listObject)
  1861.     return listObject;
  1862.     }
  1863.     catch(e){
  1864.         console.log("erorr in upload")
  1865.         console.log(e)
  1866.         return 0;
  1867.     }
  1868.  
  1869. }
  1870. function checkContainsCaptcha(docOrHtml) {
  1871.     var foundCaptcha = false;
  1872.     if (typeof docOrHtml == 'string') {
  1873.         foundCaptcha = !!docOrHtml.match(/data\-bot\-protect=/);
  1874.     } else {
  1875.         let $doc = $(docOrHtml);
  1876.         let $body = $doc.find('#ds_body');
  1877.         foundCaptcha = $body.length && !!$body.data('bot-protect')
  1878.     }
  1879.  
  1880.     if (foundCaptcha) console.log('Found captcha!');
  1881.     return foundCaptcha;
  1882. }
  1883.  
  1884. function calcDistance(coord1,coord2){
  1885.     let x1=parseInt(coord1.split("|")[0])
  1886.     let y1=parseInt(coord1.split("|")[1])
  1887.     let x2=parseInt(coord2.split("|")[0])
  1888.     let y2=parseInt(coord2.split("|")[1])
  1889.  
  1890.     return Math.sqrt( (x1-x2)*(x1-x2) +  (y1-y2)*(y1-y2) );
  1891. }
  1892.  
  1893. ////////////////////////////////////////////////data compression////////////////////////////////////////////////////////////////////////////
  1894. function lzw_encode (s) {
  1895.     if (!s) return s;
  1896.     var dict = new Map(); // Use a Map!
  1897.     var data = (s + "").split("");
  1898.     var out = [];
  1899.     var currChar;
  1900.     var phrase = data[0];
  1901.     var code = 256;
  1902.     for (var i = 1; i < data.length; i++) {
  1903.         currChar = data[i];
  1904.         if (dict.has(phrase + currChar)) {
  1905.             phrase += currChar;
  1906.         } else {
  1907.             out.push (phrase.length > 1 ? dict.get(phrase) : phrase.codePointAt(0));
  1908.             dict.set(phrase + currChar, code);
  1909.             code++;
  1910.             if (code === 0xd800) { code = 0xe000; }
  1911.             phrase = currChar;
  1912.         }
  1913.     }
  1914.     out.push (phrase.length > 1 ? dict.get(phrase) : phrase.codePointAt(0));
  1915.     for (var i = 0; i < out.length; i++) {
  1916.         out[i] = String.fromCodePoint(out[i]);
  1917.     }
  1918.     //console.log ("LZW MAP SIZE", dict.size, out.slice (-50), out.length, out.join("").length);
  1919.     return out.join("");
  1920. }
  1921. ////////////////////////////////////////////////data decompression////////////////////////////////////////////////////////////////////////////
  1922. function lzw_decode (s) {
  1923.     var dict = new Map(); // Use a Map!
  1924.     var data = Array.from(s + "");
  1925.     //var data = (s + "").split("");
  1926.     var currChar = data[0];
  1927.     var oldPhrase = currChar;
  1928.     var out = [currChar];
  1929.     var code = 256;
  1930.     var phrase;
  1931.     for (var i = 1; i < data.length; i++) {
  1932.         var currCode = data[i].codePointAt(0);
  1933.         if (currCode < 256) {
  1934.             phrase = data[i];
  1935.         } else {
  1936.             phrase = dict.has(currCode) ? dict.get(currCode) : (oldPhrase + currChar);
  1937.         }
  1938.         out.push(phrase);
  1939.         var cp = phrase.codePointAt(0);
  1940.         currChar = String.fromCodePoint(cp); //phrase.charAt(0);
  1941.         dict.set(code, oldPhrase + currChar);
  1942.         code++;
  1943.         if (code === 0xd800) { code = 0xe000; }
  1944.         oldPhrase = phrase;
  1945.     }
  1946.     return out.join("");
  1947. }
  1948. ///////////////////////////////////////////////////////get request//////////////////////////////////////////////////////////////////////////
  1949. function httpGet(theUrl){
  1950.     var xmlHttp = new XMLHttpRequest();
  1951.     xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
  1952.     xmlHttp.send( null );
  1953.     return xmlHttp.responseText;
  1954. }
  1955.  
  1956.  
  1957. ///////////////////////////////////////////////////////get speed//////////////////////////////////////////////////////////////////////////
  1958.  
  1959.  
  1960. ///////////////////////////////////////////////////////get all incomings//////////////////////////////////////////////////////////////////////////
  1961.  
  1962. function getIncomings(){
  1963.     return new Promise( async(resolve,reject)=>{
  1964.         if($('[id="incomings_amount"]:visible').length == 0){
  1965.             document.getElementById("progress_incomings").innerText="No incs";
  1966.             resolve(new Map())
  1967.         }
  1968.         else{
  1969.             console.log("herere")
  1970.             if(document.getElementsByClassName("info").length>0)
  1971.                 $(".info").remove()
  1972.  
  1973.             document.getElementById("progress_incomings").innerText="Getting data...";
  1974.             let incomings_href= game_data.link_base_pure+"overview_villages&mode=incomings&type=all&subtype=attacks&group=0&page=-1";
  1975.    
  1976.             console.log("currentLink")
  1977.             console.log(incomings_href)
  1978.             let data = await ajaxGet(incomings_href);
  1979.             const parser = new DOMParser();
  1980.             const htmlDoc = parser.parseFromString(data, 'text/html');
  1981.  
  1982.             let list_href=[];
  1983.             if(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  1984.                 Array.from(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select")[0].options).forEach(el=>{
  1985.                     list_href.push(el.value);
  1986.                 })
  1987.                 list_href.pop();
  1988.             }
  1989.             else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){
  1990.                 let arr=Array.from(htmlDoc.getElementsByClassName("paged-nav-item"));
  1991.                 for(let i=0;i<arr.length;i++)
  1992.                 list_href.push(arr[i].getAttribute("href"))
  1993.             }
  1994.             else{
  1995.                 list_href.push(incomings_href)
  1996.        
  1997.             }
  1998.    
  1999.    
  2000.             console.log(list_href)
  2001.             let incomings_data=new Map();
  2002.        
  2003.    
  2004.             var indexIncoming=1;
  2005.             var url_length=list_href.length
  2006.             function ajaxRequest (urls) {
  2007.                 let current_url
  2008.                 if(urls.length>0){
  2009.                     current_url=urls.pop()
  2010.                 }
  2011.                 else{
  2012.                     current_url="stop"
  2013.                 }
  2014.                 console.log("in functie in plm "+urls.length)
  2015.                 // console.log(current_url)
  2016.                
  2017.                 var start_ajax=new Date();
  2018.                 if (urls.length >= 0 && current_url!="stop") {
  2019.                     $.ajax({
  2020.                         url: current_url,
  2021.                         method: 'get',
  2022.                         success: (data) => {
  2023.                             const parser = new DOMParser();
  2024.                             const htmlDoc = parser.parseFromString(data, 'text/html');
  2025.  
  2026.                             if(htmlDoc.getElementById("incomings_table")==null)
  2027.                                 alert("turn off the filters");
  2028.                             let table_incomings=htmlDoc.getElementById("incomings_table").getElementsByTagName("tbody")[0].children
  2029.                             for(let i=1;i<table_incomings.length-1;i++){
  2030.                                 if(table_incomings[i].children[0].innerText!="--"){
  2031.                                     let coord_def=table_incomings[i].children[1].innerText.match(/\d+\|\d+/)[0]
  2032.                                     let coord_off=table_incomings[i].children[2].innerText.match(/\d+\|\d+/)[0]
  2033.                                     let length_tr=table_incomings[i].children.length
  2034.                                     let time_land=table_incomings[i].children[length_tr-2].innerText
  2035.                                     let milliseconds = time_land.split(":").pop();
  2036.                                     var nameTroupe=table_incomings[i].children[0].innerText.trim().split(/\s+/)[0].toLowerCase();
  2037.  
  2038.                                     let player_off=table_incomings[i].children[length_tr-4].innerText.trim()
  2039.                                     let player_def=game_data.player.name
  2040.    
  2041.                                     let id_player_def=game_data.player.id.toString()
  2042.                                     let id_player_off=table_incomings[i].children[length_tr-4].getElementsByTagName("a")[0].href.split("id=")[1]
  2043.                                    
  2044.                                     let id_coord_def=table_incomings[i].children[2].getElementsByTagName("a")[0].href.split("village=")[1].split("&")[0]
  2045.                                     let id_coord_off=table_incomings[i].children[2].getElementsByTagName("a")[0].href.split("id=")[1]
  2046.    
  2047.                                     let distance=calcDistance(coord_off,coord_def);
  2048.  
  2049.                                     let server_date=htmlDoc.getElementById("serverDate").innerText.split("/")
  2050.                                     let date_land=getLandTime(time_land)
  2051.                                     let labelName="none"
  2052.                                     let type_attack=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[0].src.split("command/")[1]
  2053.                                     if(table_incomings[i].children[0].getElementsByTagName("img").length==2){
  2054.                                         labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src.split("tiny/")[1]
  2055.                                         if(labelName==undefined)
  2056.                                             labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src.split("command/")[1]
  2057.    
  2058.                                     }
  2059.  
  2060.                                     let date_launch = "none";
  2061.                                     if(table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img").length==2){
  2062.                                         let labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src
  2063.                                         let time_attack=0;
  2064.                                         if(labelName.includes("snob.png")){
  2065.                                             time_attack=nobleSpeed*distance
  2066.                                         }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  2067.                                             time_attack=ramSpeed*distance
  2068.                                         }else if(labelName.includes("sword.png")){
  2069.                                             time_attack=swordSpeed*distance
  2070.                                         }else if(labelName.includes("axe.png")){
  2071.                                             time_attack=axeSpeed *distance
  2072.                                         }
  2073.                                        
  2074.                                         time_attack=Math.round(time_attack/1000)*1000
  2075.                                         date_launch = parseDate(new Date(date_land).getTime()-time_attack)+":"+milliseconds
  2076.                                     }else if(nameTroupe == lang["dcfafcb4323b102c7e204555d313ba0a"].toLowerCase()){
  2077.                                         let timeInMM=table_incomings[i].children[length_tr-1].innerText.split(":")
  2078.                                         timeInMM=timeInMM[0]*3600*1000+timeInMM[1]*60*1000+timeInMM[2]*1000;
  2079.                                         let time_attack=0;
  2080.                                         if(timeInMM > ramSpeed*distance){
  2081.                                             time_attack=nobleSpeed*distance
  2082.                                         }
  2083.                                         else if(timeInMM > swordSpeed*distance){
  2084.                                             time_attack=ramSpeed*distance
  2085.                                         }
  2086.                                         else if(timeInMM > axeSpeed*distance){
  2087.                                             time_attack=swordSpeed*distance
  2088.                                         }
  2089.                                         else if(timeInMM > heavySpeed*distance){
  2090.                                             time_attack=heavySpeed*distance
  2091.                                         }
  2092.                                         else if(timeInMM > lightSpeed*distance){
  2093.                                             time_attack=lightSpeed*distance
  2094.                                         }
  2095.                                         else if(timeInMM > spySpeed*distance){
  2096.                                             time_attack=spySpeed*distance
  2097.                                         }      
  2098.  
  2099.                                         if(time_attack>0){
  2100.                                             time_attack=Math.round(time_attack/1000)*1000
  2101.                                             date_launch = parseDate(new Date(date_land).getTime()-time_attack)+":"+milliseconds
  2102.                                         }
  2103.                                        
  2104.                                     }
  2105.                                     // console.log(table_incomings[i])
  2106.                                     // console.log(date_land)
  2107.                                     if(new Date(date_land)=="Invalid Date"){
  2108.                                         throw new Error("new date doesnt working(use opera or chrome)")
  2109.                                     }
  2110.    
  2111.                                     // console.log(date_land)
  2112.                                     if(!incomings_data.has(coord_off)){
  2113.                                         let list=[{
  2114.                                                     date_land:date_land,
  2115.                                                     date_launch:date_launch.trim(),
  2116.                                                     coord_def:coord_def,
  2117.                                                     coord_off:coord_off,
  2118.                                                     player_off:player_off,
  2119.                                                     player_def:player_def,
  2120.                                                     labelName:labelName,
  2121.                                                     type_attack:type_attack,
  2122.                                                     id_player_def:id_player_def,
  2123.                                                     id_player_off:id_player_off,
  2124.                                                     id_coord_def:id_coord_def,
  2125.                                                     id_coord_off:id_coord_off
  2126.                                                 }]
  2127.                                         incomings_data.set(coord_off,list)
  2128.                    
  2129.                                     }else{
  2130.                                         let list=incomings_data.get(coord_off)
  2131.                                         list.push({
  2132.                                             date_land:date_land,
  2133.                                             date_launch:date_launch,
  2134.                                             coord_def:coord_def,
  2135.                                             coord_off:coord_off,
  2136.                                             player_off:player_off,
  2137.                                             player_def:player_def,
  2138.                                             labelName:labelName,
  2139.                                             type_attack:type_attack,
  2140.                                             id_player_def:id_player_def,
  2141.                                             id_player_off:id_player_off,
  2142.                                             id_coord_def:id_coord_def,
  2143.                                             id_coord_off:id_coord_off
  2144.                                             })
  2145.                                         incomings_data.set(coord_off,list)
  2146.                                     }
  2147.                                 }
  2148.                             }
  2149.    
  2150.                             UI.SuccessMessage(indexIncoming+"/"+url_length)
  2151.                             indexIncoming++;
  2152.                             var stop_ajax=new Date();
  2153.                             var dif_time=stop_ajax.getTime()-start_ajax.getTime()
  2154.                             window.setTimeout(function(){
  2155.                                 ajaxRequest (list_href)
  2156.                             },dif_time)
  2157.                         }
  2158.                     })
  2159.                
  2160.                 }
  2161.                 else
  2162.                 {
  2163.  
  2164.                
  2165.                     if( htmlDoc.getElementsByClassName("g-recaptcha").length>0){//recaptcha
  2166.                         console.log("recapthca")
  2167.                         UI.ErrorMessage("recapthca, upload again")
  2168.                         document.getElementById("progress_incomings").innerText="Recaptcha..";
  2169.  
  2170.                         resolve(null);
  2171.                     }
  2172.    
  2173.                     window.setTimeout(function(){
  2174.                         console.log(incomings_data)
  2175.                         resolve(incomings_data)
  2176.                     },1000+Math.random()*500)
  2177.    
  2178.    
  2179.    
  2180.                 }
  2181.             }
  2182.             if(list_href.length>0)
  2183.                 ajaxRequest(list_href);
  2184.             else
  2185.                 reject("error on incomings")
  2186.         }
  2187.        
  2188.     })
  2189. }
  2190. ///////////////////////////////////////////////////////upload all incomings//////////////////////////////////////////////////////////////////////////
  2191.  
  2192. async function uploadIncomings(){
  2193.    
  2194.     var [incomings_data, map_incomings_dropbox,mapStatus,status]=await Promise.all([getIncomings(), readFileDropbox(filename_incomings),readFileDropbox(filename_status_upload),insertlibraryLocalBase()]).catch(err=>{alert(err)})
  2195.     console.log(status)
  2196.  
  2197.  
  2198.    
  2199.     return new Promise(async(resolve,reject)=>{
  2200.         UI.SuccessMessage("compressing database, wait few seconds",5000)
  2201.  
  2202.         //merge map dropbox with map locabase
  2203.         try {
  2204.             let decompressedData = await decompress(await map_incomings_dropbox.arrayBuffer() , 'gzip');  
  2205.             map_incomings_dropbox=new Map( JSON.parse(decompressedData));
  2206.         } catch (error) {
  2207.             console.log("erorrr map report from dropbox")
  2208.             map_incomings_dropbox=new Map()
  2209.         }
  2210.  
  2211.         //if there database is stored locally
  2212.         if(await localBase.getItem(game_data.world+"incomings")!=undefined){
  2213.             try{
  2214.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "incomings"))
  2215.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  2216.        
  2217.                 let map_localBase=new Map( JSON.parse(decompressedData));
  2218.                 console.log("map_localBase history upload",map_localBase)
  2219.                 map_incomings_dropbox=new Map([...map_localBase, ...map_incomings_dropbox])
  2220.  
  2221.             } catch (error) {
  2222.                 let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "incomings"))));
  2223.                 map_incomings_dropbox=new Map([...map_localBase, ...map_incomings_dropbox])
  2224.             }
  2225.         }
  2226.  
  2227.  
  2228.         try {
  2229.             let decompressedData = await decompress(await mapStatus.arrayBuffer() , 'gzip');  
  2230.             mapStatus=new Map( JSON.parse(decompressedData));
  2231.         } catch (error) {
  2232.             console.log("erorrr map report from dropbox")
  2233.             mapStatus=new Map()
  2234.         }
  2235.  
  2236.  
  2237.            
  2238.         let server_date=document.getElementById("serverDate").innerText.split("/")
  2239.         let server_time=document.getElementById("serverTime").innerText
  2240.         let current_date=new Date(server_date[1]+"/"+server_date[0]+"/"+server_date[2]+" "+server_time);
  2241.  
  2242.  
  2243.  
  2244.         console.log(map_incomings_dropbox)
  2245.         /////////////////////////////////eliminate old incomings from dropbox////////////////////////////////////
  2246.         let start=new Date();
  2247.         Array.from(map_incomings_dropbox.keys()).forEach(el=>{
  2248.             let list=map_incomings_dropbox.get(el);
  2249.             let update=false;
  2250.             for(let i=0;i<list.length;i++){
  2251.  
  2252.                 let date_incomings=new Date(list[i].date_land).getTime();
  2253.                 let two_days=50*3600*1000;
  2254.  
  2255.                 if(date_incomings + two_days < current_date || list[i].date_land == ""){
  2256.                     list.splice(i,1);
  2257.                     i--;
  2258.                     update=true;
  2259.                 }
  2260.  
  2261.                 if(list[i]==""){
  2262.                     list.splice(i,1);
  2263.                     update=true;
  2264.                 }
  2265.             }
  2266.             if(update==true || list.length==0){
  2267.                 if(list.length==0)
  2268.                     map_incomings_dropbox.delete(el);
  2269.                 else{
  2270.                     map_incomings_dropbox.set(el,list);
  2271.                 }
  2272.             }
  2273.  
  2274.  
  2275.         })
  2276.         console.log(map_incomings_dropbox)
  2277.         let stop=new Date();
  2278.         console.log(stop-start)
  2279.        
  2280.         let newIncs = 0;
  2281.         Array.from(incomings_data.keys()).forEach(el=>{
  2282.             let list=incomings_data.get(el)
  2283.             if(map_incomings_dropbox.has(el)){//update
  2284.                 let list_dropbox=map_incomings_dropbox.get(el)
  2285.                 list_dropbox=list_dropbox.concat(list);
  2286.                 var list_concat =[...new Map(list_dropbox.map(item => [item["date_land"], item])).values()].sort((o1,o2)=>{
  2287.                     return (new Date(o1.date_land).getTime() > new Date(o2.date_land).getTime()) ? 1 :
  2288.                              (new Date(o1.date_land).getTime() << new Date(o2.date_land).getTime()) ? -1 : 0
  2289.                 })
  2290.                 console.log(list_concat)
  2291.                 map_incomings_dropbox.set(el,list_concat);
  2292.             }
  2293.             else{//add
  2294.                 map_incomings_dropbox.set(el,list);
  2295.                 newIncs += list.length
  2296.             }
  2297.         })
  2298.         let totalIncs = 0;
  2299.         Array.from(map_incomings_dropbox.keys()).forEach(el=>{
  2300.             let list=map_incomings_dropbox.get(el);
  2301.             totalIncs += list.length
  2302.         })
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.         let serverTime=document.getElementById("serverTime").innerText
  2309.         let serverDate=document.getElementById("serverDate").innerText.split("/")
  2310.         serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  2311.         let date_current=serverDate+" "+serverTime
  2312.  
  2313.         //update status map
  2314.         let obj_status={
  2315.             name:game_data.player.name,
  2316.             incoming_date:date_current,
  2317.         }
  2318.  
  2319.  
  2320.         if(mapStatus.has(game_data.player.id.toString())){
  2321.             let obj_update=mapStatus.get(game_data.player.id.toString())
  2322.             mapStatus.set(game_data.player.id.toString(), {...obj_update, ...obj_status} )
  2323.         }
  2324.         else{
  2325.             mapStatus.set(game_data.player.id.toString(),obj_status)
  2326.         }
  2327.  
  2328.  
  2329.         // console.log(map_incomings_dropbox)
  2330.         let timeStartUpload = new Date().getTime();
  2331.  
  2332.         // UI.SuccessMessage("compressing database, wait few seconds",2000)
  2333.         var data=JSON.stringify(Array.from(map_incomings_dropbox.entries()))
  2334.         let sizeIncomingsDB = formatBytes(new TextEncoder().encode(data).length)
  2335.  
  2336.         let compressedData = await compress(data, 'gzip')
  2337.         let compressedDataBase64 = await blobToBase64(compressedData);
  2338.  
  2339.  
  2340.         try {
  2341.             document.getElementById("progress_incomings").innerText=incomings_data.size+" coords";
  2342.             document.getElementById("progress_all").innerText="done";
  2343.         } catch (error) {
  2344.            
  2345.         }
  2346.         UI.SuccessMessage("upload incomings done","slow")
  2347.  
  2348.  
  2349.  
  2350.         let data_status=JSON.stringify(Array.from(mapStatus.entries()))
  2351.         let dataCompressed = await compress(data_status, "gzip")
  2352.         let resultStatus=await uploadFile(dataCompressed,filename_status_upload,dropboxToken).catch(err=>alert(err))
  2353.  
  2354.  
  2355.         await localBase.setItem(game_data.world+"incomings", compressedDataBase64)
  2356.         let result=await uploadFile(compressedData, filename_incomings, dropboxToken)
  2357.         if(result=="succes"){
  2358.             let timeStopUpload = new Date().getTime();
  2359.             let totalTimeUpload =  Math.round(((timeStopUpload - timeStartUpload) / 1000) * 100) / 100
  2360.             UI.SuccessMessage(`<b>Upload incomings done</b> <br><br>
  2361.                                 Upload time: <b>${totalTimeUpload} sec</b>  <br>
  2362.                                 New incomings: <b>${newIncs} </b> <br>
  2363.                                 Total incomings: <b>${totalIncs} </b> <br>
  2364.                                 Size DB: <b>${sizeIncomingsDB}</b>
  2365.                                 `, 10000)
  2366.             resolve({
  2367.                 totalTimeUpload: totalTimeUpload,
  2368.                 status: "success"
  2369.             })
  2370.     }
  2371.         else
  2372.             reject("error upload incomings")
  2373.          
  2374.     })
  2375. }
  2376.  
  2377. //////////////////////////////////////////////////////upload all data to dropbox/////////////////////////////////////////////////////////////////
  2378.  
  2379. function uploadFile(data,filename,dropboxToken){
  2380.     return new Promise((resolve,reject)=>{
  2381.         // var file = new Blob([data], {type: "plain/text"});
  2382.         var file = data
  2383.         var nr_start1=new Date().getTime();
  2384.         file.name=filename;
  2385.  
  2386.         //stop refreshing the page
  2387.         $(document).bind("keydown", disableF5);
  2388.         window.onbeforeunload = function (e) {
  2389.             console.log("is uploading");
  2390.             return "are you sure?";
  2391.         };
  2392.  
  2393.         var xhr = new XMLHttpRequest();
  2394.         xhr.upload.onprogress = function(evt) {
  2395.             console.log(evt)
  2396.             var percentComplete = parseInt(100.0 * evt.loaded / evt.total);
  2397.             console.log(percentComplete)
  2398.             UI.SuccessMessage("progress upload: "+percentComplete+"%")
  2399.         };
  2400.  
  2401.         xhr.onload = function() {
  2402.             if (xhr.status === 200) {
  2403.                 var fileInfo = JSON.parse(xhr.response);
  2404.                 // Upload succeeded. Do something here with the file info.
  2405.                 UI.SuccessMessage("upload succes")
  2406.                 var nr_stop1=new Date().getTime();
  2407.                 console.log("time upload: "+(nr_stop1-nr_start1))
  2408.  
  2409.                 //enable refresh page
  2410.                 window.onbeforeunload = function (e) {
  2411.                     console.log("done");
  2412.                 };
  2413.                 $(document).unbind("keydown", disableF5);
  2414.                 // if(typeof(TWMap) !="undefined" ){
  2415.                 //     console.log("init map")
  2416.                 //     TWMap.init();
  2417.                 // }
  2418.                 resolve("succes")
  2419.  
  2420.             }
  2421.             else {
  2422.                 var errorMessage = xhr.response || 'Unable to upload file';
  2423.                 // Upload failed. Do something here with the error.
  2424.                 UI.SuccessMessage("upload failed")
  2425.                 reject(errorMessage)
  2426.             }
  2427.         };
  2428.  
  2429.         xhr.open('POST', 'https://content.dropboxapi.com/2/files/upload',false);
  2430.         xhr.setRequestHeader('Authorization', 'Bearer ' + dropboxToken);
  2431.         xhr.setRequestHeader('Content-Type', 'application/octet-stream');
  2432.         xhr.setRequestHeader('Dropbox-API-Arg', JSON.stringify({
  2433.             path: '/' +  file.name,
  2434.             autorename: true,
  2435.             mode:'overwrite',
  2436.             mute: false
  2437.         }));
  2438.  
  2439.         xhr.send(file)
  2440.     })
  2441. }
  2442.  
  2443. function readFileDropbox(filename){
  2444.     return new Promise(async(resolve,reject)=>{
  2445.         const rawResponse = await fetch('https://content.dropboxapi.com/2/files/download', {
  2446.             method: 'POST',
  2447.             headers: {
  2448.                 'Authorization': 'Bearer ' + dropboxToken,
  2449.                 'Dropbox-API-Arg': JSON.stringify({path: "/"+filename}),
  2450.             },
  2451.           });
  2452.         if(rawResponse.ok == true){
  2453.             const content = rawResponse.blob();
  2454.             resolve(content)
  2455.         }
  2456.         else{
  2457.             reject("error-> file doesnt exists")
  2458.         }
  2459.     })
  2460. }
  2461.  
  2462.  
  2463.  
  2464. function replaceSpecialCaracters(data) {
  2465.     let result = ""
  2466.     for (let i = 0; i < data.length; i++) {
  2467.         if (data[i] == "È›")
  2468.             result += 't'
  2469.         else if (data[i] == "Å£")
  2470.             result += 't'
  2471.         else if (data[i] == "Èš")
  2472.             result += "T"
  2473.         else if (data[i] == "Ä‚")
  2474.             result += "A"
  2475.         else if (data[i] == "ă")
  2476.             result += "a"
  2477.         else if (data[i] == "Â")
  2478.             result += "A"
  2479.         else if (data[i] == "Ș")
  2480.             result += "S"
  2481.         else if (data[i] == "È™")
  2482.             result += "s"
  2483.         else if (data[i] == "ÃŽ")
  2484.             result += "I"
  2485.         else if (data[i] == "î")
  2486.             result += "i"
  2487.         else
  2488.             result += data[i]
  2489.     }
  2490.     return result
  2491.  
  2492.  
  2493.  
  2494.  
  2495. }
  2496.  
  2497. function disableF5(e) { if ((e.which || e.keyCode) == 116 || (e.which || e.keyCode) == 82) e.preventDefault(); };
  2498.  
  2499.  
  2500. //////////////////////////////////////////////////////buttons in incomings page/////////////////////////////////////////////////////////////////
  2501.  
  2502.            
  2503. function showButtons(){
  2504.     if(document.getElementById("incomings_table")!=null){
  2505.         $("#table_incomings").remove();
  2506.         var incomingshtml=`
  2507.    
  2508.         <table id="table_incomings" class="" border="1" style="width: 50%;">    
  2509.             <tbody>
  2510.             <tr>
  2511.                 <td style="text-align:center; width:auto;">
  2512.                     <center style="margin:10px"><input class="btn" type="button" onclick="addWindow()"value="Open Upload"></center>
  2513.                 </td>            
  2514.            
  2515.                 <td style="text-align:center; width:auto;">
  2516.                         <center style="margin:10px"><input id="moreInfo" class="btn" type="button" onclick="moreInfo()" value="More Info"></center>
  2517.                         <table>
  2518.                             <tr>
  2519.                                 <td>gap[sec]:</td>
  2520.                                 <td><input type="number" id="input_gap" value="5" min="0" max="1000"  placeholder="5" style="text-align:center"></td>
  2521.                                 <td><a href="#" onclick="UI.InfoMessage('This value is to find launch series of the enemy <br> It can predict if an incoming is fake/nuke/fang <br> The lower the value is set the more likely the prediction is true ',8000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a></td>
  2522.                             </tr>
  2523.                         </table>
  2524.                 </td>            
  2525.                 <td style="text-align:center; width:auto;">
  2526.                         <center style="margin:10px"><input class="btn" id="btn_tag" type="button" onclick="tagIncomings()" value="Tag"><a href="#" onclick="UI.InfoMessage('You can tag incs directly without pressing on More Info button',10000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a> </center>
  2527.                         <center style="margin:10px"><input class="btn" id="btn_backtime" type="button"  value="back time"></center>
  2528.                         <center style="margin:10px"><input class="btn" id="btn_senttime" type="button"  value="sent time"></center>
  2529.                         <center style="margin:10px"><input class="btn" id="btn_stacks" type="button"  value="stacks"></center>
  2530.                 </td>            
  2531.                 <td style="text-align:center; width:auto;" >        
  2532.                         <table>
  2533.                             <tr>
  2534.                                 <td colspan = "2"><input class="btn" type="button" onclick="setIntervalIncomings()" value="Get Incomings"></td>
  2535.                                 <td><a href="#" onclick="UI.InfoMessage(\`
  2536.                                    Get all incomings from a datetime range when <b>Get Only Fakes</b> and <b>Get Def Vills</b> are red <br><br>
  2537.                                    Get only fake incomings from a datetime range when <b>Get Only Fakes</b> is green and <b> Get Def Vills </b> is red, it's calculated based on <b>Current pop</b> and remaining troops that are traveling back home<br><br>
  2538.                                    Get only def vills incomings from a datetime range when <b>Get Only Fakes</b> is red and <b>Get Def Vills</b> is green <br><br>
  2539.                                    Get only def vills and fakes incomings from a datetime range when <b>Get Only Fakes</b> is green and <b>Get Def Vills</b> is green <br><br>
  2540.                                \`,50000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a></td>
  2541.                             </tr>
  2542.                             <tr>
  2543.                                 <td colspan = "2"> <input class="btn" type="button" id="btn_get_fakes" value="Get Only Fakes"></td>
  2544.                                 <td><a href="#" onclick="UI.InfoMessage('Keep all the fakes  based on remaining troops<br> that are returning back home from last report <br> and the value of <b>Current pop</b> <br>It is used when <b>Get Incomings</b> is pressed ',20000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a></td>
  2545.                             </tr>
  2546.                             <tr>
  2547.                                 <td colspan = "2"> <input class="btn" type="button" id="btn_get_def" value="Get Def Vills"></td>
  2548.                                 <td><a href="#" onclick="UI.InfoMessage('Keep all incs tagged as <b>DEF</b>  <br>It is used when <b>Get Incomings</b> is pressed ',10000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a></td>
  2549.                             </tr>
  2550.                             <tr>
  2551.                                 <td>Current pop[%]:</td>
  2552.                                 <td><input type="number" id="input_pop_fake2" value="30" min="0" max="1000"  placeholder="[0-100]%" style="text-align:center"></td>
  2553.                                 <td><a href="#" onclick="UI.InfoMessage('Incomings tagged as (fake)if it has a lower pop[%] than the value set ',10000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a></td>
  2554.                             </tr>
  2555.                             <tr hidden>
  2556.                                 <td>nr duplicates:</td>
  2557.                                 <td><input type="number" id="input_duplicates" value="50" min="0" max="1000"  placeholder="50" style="text-align:center"></td>
  2558.                             </tr>
  2559.                         </table>
  2560.      
  2561.                 </td>            
  2562.                 <td style="text-align:center; width:auto;">
  2563.                         <center style="margin:10px"><input id="btn_highlight" class="btn" type="button" onclick="toggleHighLight()" value="highlight"></center>
  2564.                 </td>  
  2565.                 <td hidden style="text-align:center; width:auto;" id="td_show_incomings">
  2566.                     <center style="margin:10px">
  2567.                             <input class="btn" type="button"  value="Show Incomings" id="btn_show_incs">
  2568.                             <select style="margin:10px" id="id_select_incs">
  2569.                             </select></td>
  2570.                     </center>
  2571.                    
  2572.             </td>            
  2573.             </tr>                
  2574.             </tbody>
  2575.         </table>
  2576.         </div>`
  2577.             // $(".vis").eq(3).append(incomingshtml)
  2578.         $(".overview_filters").before(incomingshtml)
  2579.  
  2580.     var link  = document.createElement('link');
  2581.     link.id   = "style_popup";
  2582.     link.rel  = 'stylesheet';
  2583.     link.type = 'text/css';
  2584.     link.href = 'https://dl.dropboxusercontent.com/s/ki0zhogjf0705c3/style_popup.css';
  2585.     link.media = 'all';
  2586.     document.getElementsByTagName('head')[0].appendChild(link);
  2587.     }
  2588.    
  2589.  
  2590.     if(document.getElementById("incomings_table")!=null){
  2591.  
  2592.        //////////////////////////initialize button stacks colours
  2593.         if(localStorage.getItem(game_data.world+"addStacks")!=null){
  2594.             let isHighLight=localStorage.getItem(game_data.world+"addStacks")
  2595.             if(isHighLight=="true"){
  2596.                 document.getElementById("btn_stacks").classList.add("btn-confirm-yes")
  2597.             }
  2598.             else{
  2599.                 document.getElementById("btn_stacks").classList.add("btn-confirm-no")
  2600.             }
  2601.  
  2602.         }
  2603.         else{
  2604.             localStorage.setItem(game_data.world+"addStacks","false")
  2605.             document.getElementById("btn_stacks").classList.remove("btn-confirm-yes")
  2606.             document.getElementById("btn_stacks").classList.add("btn-confirm-no")
  2607.         }  
  2608.  
  2609.  
  2610.         //////////////////////////////add event for button stacks
  2611.         $("#btn_stacks").off("click")
  2612.         $("#btn_stacks").on("click",()=>{
  2613.             if(document.getElementById("btn_stacks").classList.contains("btn-confirm-yes")){
  2614.                 localStorage.setItem(game_data.world+"addStacks","false")
  2615.                 document.getElementById("btn_stacks").classList.remove("btn-confirm-yes")
  2616.                 document.getElementById("btn_stacks").classList.add("btn-confirm-no")
  2617.             }
  2618.             else{
  2619.                 localStorage.setItem(game_data.world+"addStacks","true")
  2620.                 document.getElementById("btn_stacks").classList.remove("btn-confirm-no")
  2621.                 document.getElementById("btn_stacks").classList.add("btn-confirm-yes")
  2622.             }
  2623.            
  2624.         })
  2625.  
  2626.  
  2627.        
  2628.         //////////////////////////initialize button back time colours
  2629.         if(localStorage.getItem(game_data.world+"addBacktime")!=null){
  2630.             let isHighLight=localStorage.getItem(game_data.world+"addBacktime")
  2631.             if(isHighLight=="true"){
  2632.                 document.getElementById("btn_backtime").classList.add("btn-confirm-yes")
  2633.             }
  2634.             else{
  2635.                 document.getElementById("btn_backtime").classList.add("btn-confirm-no")
  2636.             }
  2637.    
  2638.         }
  2639.         else{
  2640.             localStorage.setItem(game_data.world+"addBacktime","false")
  2641.             document.getElementById("btn_backtime").classList.remove("btn-confirm-yes")
  2642.             document.getElementById("btn_backtime").classList.add("btn-confirm-no")
  2643.         }  
  2644.  
  2645.  
  2646.         //////////////////////////////add event for button back time
  2647.         $("#btn_backtime").off("click")
  2648.         $("#btn_backtime").on("click",()=>{
  2649.             if(document.getElementById("btn_backtime").classList.contains("btn-confirm-yes")){
  2650.                 localStorage.setItem(game_data.world+"addBacktime","false")
  2651.                 document.getElementById("btn_backtime").classList.remove("btn-confirm-yes")
  2652.                 document.getElementById("btn_backtime").classList.add("btn-confirm-no")
  2653.             }
  2654.             else{
  2655.                 localStorage.setItem(game_data.world+"addBacktime","true")
  2656.                 document.getElementById("btn_backtime").classList.remove("btn-confirm-no")
  2657.                 document.getElementById("btn_backtime").classList.add("btn-confirm-yes")
  2658.             }
  2659.            
  2660.         })
  2661.  
  2662.  
  2663.  
  2664.         /////////////////////////////initialize button sent time colours
  2665.         if(localStorage.getItem(game_data.world+"addSentTime")!=null){
  2666.             let isHighLight=localStorage.getItem(game_data.world+"addSentTime")
  2667.             if(isHighLight=="true"){
  2668.                 document.getElementById("btn_senttime").classList.add("btn-confirm-yes")
  2669.             }
  2670.             else{
  2671.                 document.getElementById("btn_senttime").classList.add("btn-confirm-no")
  2672.             }
  2673.    
  2674.         }
  2675.         else{
  2676.             localStorage.setItem(game_data.world+"addSentTime","false")
  2677.             document.getElementById("btn_senttime").classList.remove("btn-confirm-yes")
  2678.             document.getElementById("btn_senttime").classList.add("btn-confirm-no")
  2679.         }  
  2680.         ///////////////////////////////////add event for button sent time
  2681.         $("#btn_senttime").off("click")
  2682.         $("#btn_senttime").on("click",()=>{
  2683.             if(document.getElementById("btn_senttime").classList.contains("btn-confirm-yes")){
  2684.                 localStorage.setItem(game_data.world+"addSentTime","false")
  2685.                 document.getElementById("btn_senttime").classList.remove("btn-confirm-yes")
  2686.                 document.getElementById("btn_senttime").classList.add("btn-confirm-no")
  2687.             }
  2688.             else{
  2689.                 localStorage.setItem(game_data.world+"addSentTime","true")
  2690.                 document.getElementById("btn_senttime").classList.remove("btn-confirm-no")
  2691.                 document.getElementById("btn_senttime").classList.add("btn-confirm-yes")
  2692.             }
  2693.            
  2694.  
  2695.         })
  2696.         /////////////////////////////initialize button get def village colours
  2697.         if(localStorage.getItem(game_data.world+"get_def_vills")!=null){
  2698.             let isHighLight=localStorage.getItem(game_data.world+"get_def_vills")
  2699.             if(isHighLight=="true"){
  2700.                 document.getElementById("btn_get_def").classList.add("btn-confirm-yes")
  2701.             }
  2702.             else{
  2703.                 document.getElementById("btn_get_def").classList.add("btn-confirm-no")
  2704.             }
  2705.    
  2706.         }
  2707.         else{
  2708.             localStorage.setItem(game_data.world+"get_def_vills","false")
  2709.             document.getElementById("btn_get_def").classList.remove("btn-confirm-yes")
  2710.             document.getElementById("btn_get_def").classList.add("btn-confirm-no")
  2711.         }  
  2712.         ///////////////////////////////////add event for button get def
  2713.         $("#btn_get_def").off("click")
  2714.         $("#btn_get_def").on("click",()=>{
  2715.             if(document.getElementById("btn_get_def").classList.contains("btn-confirm-yes")){
  2716.                 localStorage.setItem(game_data.world+"get_def_vills","false")
  2717.                 document.getElementById("btn_get_def").classList.remove("btn-confirm-yes")
  2718.                 document.getElementById("btn_get_def").classList.add("btn-confirm-no")
  2719.             }
  2720.             else{
  2721.                 localStorage.setItem(game_data.world+"get_def_vills","true")
  2722.                 document.getElementById("btn_get_def").classList.remove("btn-confirm-no")
  2723.                 document.getElementById("btn_get_def").classList.add("btn-confirm-yes")
  2724.             }
  2725.            
  2726.         })
  2727.    
  2728.    
  2729.         //////////////////////////initialize button get only fakes colours
  2730.         if(localStorage.getItem(game_data.world+"get_only_fakes")!=null){
  2731.             let isHighLight=localStorage.getItem(game_data.world+"get_only_fakes")
  2732.             if(isHighLight=="true"){
  2733.                 document.getElementById("btn_get_fakes").classList.add("btn-confirm-yes")
  2734.             }
  2735.             else{
  2736.                 document.getElementById("btn_get_fakes").classList.add("btn-confirm-no")
  2737.             }
  2738.    
  2739.         }
  2740.         else{
  2741.             localStorage.setItem(game_data.world+"get_only_fakes","false")
  2742.             document.getElementById("btn_get_fakes").classList.remove("btn-confirm-yes")
  2743.             document.getElementById("btn_get_fakes").classList.add("btn-confirm-no")
  2744.         }  
  2745.         //////////////////////////////////add event for button get only fakes
  2746.         $("#btn_get_fakes").off("click")
  2747.         $("#btn_get_fakes").on("click",()=>{
  2748.             if(document.getElementById("btn_get_fakes").classList.contains("btn-confirm-yes")){
  2749.                 localStorage.setItem(game_data.world+"get_only_fakes","false")
  2750.                 document.getElementById("btn_get_fakes").classList.remove("btn-confirm-yes")
  2751.                 document.getElementById("btn_get_fakes").classList.add("btn-confirm-no")
  2752.             }
  2753.             else{
  2754.                 localStorage.setItem(game_data.world+"get_only_fakes","true")
  2755.                 document.getElementById("btn_get_fakes").classList.remove("btn-confirm-no")
  2756.                 document.getElementById("btn_get_fakes").classList.add("btn-confirm-yes")
  2757.             }
  2758.            
  2759.         })
  2760.    
  2761.         let value=localStorage.getItem(game_data.world+"pop_fake_tagging2")
  2762.         if(value!=null){
  2763.             document.getElementById("input_pop_fake2").value=parseFloat(value)
  2764.         }
  2765.         $("#input_pop_fake2").on("mouseout",()=>{
  2766.             localStorage.setItem(game_data.world+"pop_fake_tagging2", document.getElementById("input_pop_fake2").value)
  2767.         })
  2768.  
  2769.  
  2770.         value=localStorage.getItem(game_data.world+"duplicates_fake_tagging")
  2771.         if(value!=null){
  2772.             document.getElementById("input_duplicates").value=parseFloat(value)
  2773.         }
  2774.         $("#input_duplicates").on("mouseout",()=>{
  2775.             localStorage.setItem(game_data.world+"duplicates_fake_tagging", document.getElementById("input_duplicates").value)
  2776.         })
  2777.  
  2778.         value=localStorage.getItem(game_data.world+"gap_predict")
  2779.         if(value!=null){
  2780.             document.getElementById("input_gap").value=parseFloat(value)
  2781.         }
  2782.         $("#input_gap").on("mouseout",()=>{
  2783.             localStorage.setItem(game_data.world+"gap_predict", document.getElementById("input_gap").value)
  2784.         })
  2785.  
  2786.     }
  2787.  
  2788.  
  2789.    
  2790. }
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.        
  2797. //////////////////////////////////////////////////////show info in incomings page/////////////////////////////////////////////////////////////////
  2798.  
  2799. function removeLandedIncomings(incomings){
  2800.     let serverTime=document.getElementById("serverTime").innerText
  2801.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  2802.  
  2803.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]+" "+serverTime
  2804.     Array.from(incomings.keys()).forEach(key=>{
  2805.         let list= incomings.get(key);
  2806.         for(let i=0;i<list.length;i++){
  2807.             if(new Date(serverDate).getTime() > new Date(list[i].date_land).getTime()){
  2808.                 list.splice(i,1)
  2809.                 i--
  2810.             }
  2811.         }
  2812.         incomings.set(key,list)
  2813.     })
  2814.     return incomings
  2815.  
  2816. }
  2817.  
  2818.  
  2819. async function moreInfo(){
  2820.     $("#div_container").remove();
  2821.     $(".deleteTh").remove();
  2822.     $('#id_select_incs option').remove()
  2823.     console.log("inainte")
  2824.     var [map_reports_dropbox, map_incomings_dropbox, data_support, status]=await Promise.all([
  2825.         readFileDropbox(filename_reports),
  2826.         readFileDropbox(filename_incomings),
  2827.         readFileDropbox(filename_support),
  2828.         insertlibraryLocalBase()]).catch(err=>{alert(err)})
  2829.     console.log(status)
  2830.     let data_support_batch = await Promise.all(supportPromises).catch(err=>{alert(err)})
  2831.  
  2832.     //extract data from dropbox, update and then upload
  2833.     let map_support_dropbox,map_troops_home_dropbox
  2834.     try {
  2835.         let decompressedData = await decompress(await data_support.arrayBuffer() , 'gzip');  
  2836.         map_support_dropbox=new Map(JSON.parse(decompressedData)[0])
  2837.         map_troops_home_dropbox =new Map(JSON.parse(decompressedData)[1])  
  2838.     } catch (error) {
  2839.         console.log("erorrrrrrrrrrrrrrrr map report from dropbox")
  2840.         console.log(error)
  2841.         map_support_dropbox=new Map()
  2842.         map_troops_home_dropbox=new Map()
  2843.     }
  2844.  
  2845.     //merge batch commands attacks (EXTRA files)
  2846.     for(let i=0;i<data_support_batch.length;i++){
  2847.         let decompressedData = await decompress(await data_support_batch[i].arrayBuffer() , 'gzip');  
  2848.         if(decompressedData != "[]"){
  2849.             let map_support_batch = new Map(JSON.parse(decompressedData)[0])
  2850.             let map_troops_home_batch = new Map(JSON.parse(decompressedData)[1])
  2851.  
  2852.             map_support_dropbox = new Map([...map_support_dropbox, ...map_support_batch])
  2853.             map_troops_home_dropbox = new Map([...map_troops_home_dropbox, ...map_troops_home_batch])
  2854.         }      
  2855.  
  2856.         let fileName = `${databaseName}/Support${i}.txt`
  2857.         if(await localBase.getItem(fileName) != undefined){
  2858.             try {
  2859.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(fileName))
  2860.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  2861.                 let map_localBase=new Map( JSON.parse(decompressedData));
  2862.    
  2863.                 // console.log("map_localBase_support",map_localBase)
  2864.                 map_support_dropbox=new Map([...map_localBase, ...map_support_dropbox])
  2865.             } catch (error) {
  2866.                
  2867.             }
  2868.         }
  2869.         fileName = `${databaseName}/Support${i}.txtHome`
  2870.         if(await localBase.getItem(fileName) != undefined){
  2871.             try {
  2872.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(fileName))
  2873.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  2874.                 let map_localBase=new Map( JSON.parse(decompressedData));
  2875.    
  2876.                 // console.log("map_localBase_troops home",map_localBase)
  2877.                 map_troops_home_dropbox=new Map([...map_localBase, ...map_troops_home_dropbox])
  2878.             } catch (error) {
  2879.                
  2880.             }
  2881.         }
  2882.     }
  2883.    
  2884.     // console.log("hererer")
  2885.     // console.log(map_support_dropbox)
  2886.     // console.log(map_troops_home_dropbox)
  2887.     //get support coming for each coord
  2888.    
  2889.  
  2890.  
  2891.  
  2892.     /////////merge maps for reports
  2893.     try {
  2894.         let decompressedData = await decompress(await map_reports_dropbox.arrayBuffer() , 'gzip');  
  2895.         map_reports_dropbox=new Map( JSON.parse(decompressedData));
  2896.     } catch (error) {
  2897.         console.log("erorrrrrrrrrrrrrrrr map report from dropbox")
  2898.         map_reports_dropbox=new Map()
  2899.     }
  2900.  
  2901.     //if  database is stored locally
  2902.     if(await localBase.getItem(game_data.world+"reports")!=undefined){
  2903.         try {
  2904.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "reports"))
  2905.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  2906.             let map_localBase=new Map( JSON.parse(decompressedData));
  2907.  
  2908.             console.log("map_localBase",map_localBase)
  2909.             map_reports_dropbox=new Map([...map_localBase, ...map_reports_dropbox])
  2910.         } catch (error) {}
  2911.     }
  2912.  
  2913.  
  2914.  
  2915.  
  2916.     /////////merge maps for incomings
  2917.     try {
  2918.         let decompressedData = await decompress(await map_incomings_dropbox.arrayBuffer() , 'gzip');  
  2919.         map_incomings_dropbox=new Map( JSON.parse(decompressedData));
  2920.     } catch (error) {
  2921.         console.log("erorrr map report from dropbox")
  2922.         map_incomings_dropbox=new Map()
  2923.     }
  2924.  
  2925.     //if there database is stored locally
  2926.     if(await localBase.getItem(game_data.world+"incomings")!=undefined){
  2927.         try{
  2928.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "incomings"))
  2929.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  2930.    
  2931.             let map_localBase=new Map( JSON.parse(decompressedData));
  2932.             console.log("map_localBase history upload",map_localBase)
  2933.             map_incomings_dropbox=new Map([...map_localBase, ...map_incomings_dropbox])
  2934.  
  2935.         } catch (error) {}
  2936.     }
  2937.  
  2938.  
  2939.  
  2940.  
  2941.  
  2942.  
  2943.     let mapPredict=new Map()
  2944.     let list_incomingsAll=[]
  2945.     Array.from(map_incomings_dropbox.keys()).forEach(key=>{
  2946.         let list_dropbox= map_incomings_dropbox.get(key);
  2947.         list_incomingsAll = [...list_incomingsAll, ...list_dropbox];
  2948.     })
  2949.     let map_player_inc=new Map()
  2950.     for(let i=0;i<list_incomingsAll.length;i++){
  2951.         if(list_incomingsAll[i].date_launch !=undefined){
  2952.             if(map_player_inc.has(list_incomingsAll[i].id_player_off)){//update
  2953.                 let list_incomings = map_player_inc.get(list_incomingsAll[i].id_player_off)
  2954.                 list_incomings.push(list_incomingsAll[i])
  2955.                 map_player_inc.set(list_incomingsAll[i].id_player_off,list_incomings)
  2956.                
  2957.             }else{
  2958.                 let list_incomings = []
  2959.                 list_incomings.push(list_incomingsAll[i])
  2960.                 map_player_inc.set(list_incomingsAll[i].id_player_off,list_incomings)
  2961.             }
  2962.         }
  2963.     }
  2964.  
  2965.     console.log("list_incomingsAll",list_incomingsAll)
  2966.     console.log("map_player_inc",map_player_inc)
  2967.  
  2968.     //calculate troops comming
  2969.     let troopsComming = new Map()
  2970.     Array.from(map_support_dropbox.keys()).forEach(key=>{
  2971.         let listIncomings = map_support_dropbox.get(key)
  2972.         let totalPop = 0;
  2973.         for(let i=0;i<listIncomings.length;i++){
  2974.             if(listIncomings[i].troops != undefined ){
  2975.                 Object.keys(listIncomings[i].troops).forEach(key=>{
  2976.                     if(key == "archer" || key == "spear" || key == "sword" || key == "heavy"){
  2977.                         totalPop += troopsPop[key] * listIncomings[i].troops[key]
  2978.                     }
  2979.                 });
  2980.             }
  2981.         }
  2982.         if(totalPop > 1000)
  2983.         troopsComming.set(key,totalPop)
  2984.     })
  2985.  
  2986.     //calculate troops home
  2987.     let troopsHome = new Map()
  2988.     Array.from(map_troops_home_dropbox.keys()).forEach(key=>{
  2989.         let obj = map_troops_home_dropbox.get(key)
  2990.         let totalPop = 0;
  2991.         if(obj.obj_troops != undefined ){
  2992.             Object.keys(obj.obj_troops).forEach(key=>{
  2993.                 if(key == "archer" || key == "spear" || key == "sword" || key == "heavy"){
  2994.                     totalPop += troopsPop[key] * obj.obj_troops[key]
  2995.                 }
  2996.             });
  2997.         }
  2998.         if(totalPop > 1000)
  2999.             troopsHome.set(key,totalPop)
  3000.     })
  3001.     console.log("troopsComming",troopsComming)
  3002.     console.log("troopsHome",troopsHome)
  3003.  
  3004.  
  3005.     let serverTime=document.getElementById("serverTime").innerText
  3006.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  3007.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]+" "+serverTime
  3008.  
  3009.     let list_players=[]
  3010.     let gap_serie= document.getElementById("input_gap").value*1000;
  3011.     Array.from(map_player_inc.keys()).forEach(key=>{
  3012.         let list_incomings= map_player_inc.get(key);
  3013.         list_incomings.sort((o1,o2)=>{
  3014.             return (new Date(o1.date_launch).getTime() > new Date(o2.date_launch).getTime())?1:
  3015.             (new Date(o1.date_launch).getTime() < new Date(o2.date_launch).getTime())?-1:0;
  3016.         })
  3017.  
  3018.  
  3019.         let new_list_incomings=[]
  3020.         let color=true;
  3021.         for(let i=0;i<list_incomings.length-1;i++){
  3022.    
  3023.             let serieLaunches = new Set();
  3024.             let currentDate=new Date(list_incomings[i].date_launch).getTime();
  3025.             let nextDate=new Date(list_incomings[i+1].date_launch).getTime();
  3026.             if(Math.abs(currentDate-nextDate) <= gap_serie){
  3027.                 for(let j=i;j<list_incomings.length-1;j++){
  3028.  
  3029.                     let currentDate=new Date(list_incomings[j].date_launch).getTime();
  3030.                     let nextDate=new Date(list_incomings[j+1].date_launch).getTime();
  3031.                     if(Math.abs(currentDate-nextDate) <= gap_serie){
  3032.                         list_incomings[j].colorRow=color
  3033.                         list_incomings[j+1].colorRow=color
  3034.  
  3035.                         serieLaunches.add(list_incomings[j])
  3036.                         serieLaunches.add(list_incomings[j+1])
  3037.                         i++
  3038.                     }
  3039.                     else{
  3040.                         if(color== true)
  3041.                             color= false
  3042.                         else
  3043.                             color =true
  3044.                         break;
  3045.                     }
  3046.                 }
  3047.             }
  3048.            
  3049.             // console.log("serieLaunches",serieLaunches)
  3050.             // console.log(Array.from(serieLaunches))
  3051.             let nr_fangs=0,nr_nukes=0,nr_fakes=0
  3052.             Array.from(serieLaunches).forEach(key=>{
  3053.        
  3054.                 if(key.type_attack_landed != undefined){
  3055.  
  3056.                     if(key.type_attack_landed =="fake")
  3057.                         nr_fakes++
  3058.                     if(key.type_attack_landed =="nuke")
  3059.                         nr_nukes++
  3060.                     if(key.type_attack_landed =="fang")
  3061.                         nr_fangs++
  3062.                 }
  3063.             })
  3064.  
  3065.             let max=Math.max(nr_fakes,nr_nukes,nr_fakes)
  3066.             let predict_type="?"
  3067.             if(max>0){
  3068.                 if(nr_fakes == max){
  3069.                     predict_type="pred_fake"
  3070.                 }
  3071.                 else if(nr_nukes == max){
  3072.                     predict_type="pred_nuke"
  3073.                 }
  3074.                 else if(nr_fangs == max){
  3075.                     predict_type="pred_fang"
  3076.                 }
  3077.             }
  3078.  
  3079.             let serieLaunchesFinal=new Set()
  3080.             Array.from(serieLaunches.values()).forEach(key=>{
  3081.                 if(key.type_attack_landed == undefined && predict_type!="?"){
  3082.                     key.type_attack_landed=predict_type
  3083.                     serieLaunchesFinal.add(key)
  3084.                     if(new Date(key.date_land).getTime() > new Date(serverDate).getTime()){
  3085.                         mapPredict.set(key.date_launch+"_"+key.player_off,predict_type)
  3086.                         // console.log(key.date_land+"   "+key.player_off);
  3087.                     }
  3088.                 }
  3089.                 else{
  3090.                     serieLaunchesFinal.add(key)
  3091.                 }
  3092.  
  3093.             })
  3094.             new_list_incomings= [...new_list_incomings, ...serieLaunchesFinal]
  3095.             // if(serieLaunches.size>0)
  3096.             //     console.log("serieLaunchesFinal",serieLaunchesFinal)
  3097.         }
  3098.  
  3099.  
  3100.         map_player_inc.set(key,new_list_incomings)
  3101.        
  3102.         if(new_list_incomings.length>0){
  3103.             list_players.push({
  3104.                 name_player_off:new_list_incomings[0].player_off+" ("+ new_list_incomings.length +")",
  3105.                 id_player_off:new_list_incomings[0].id_player_off,
  3106.                 nr_incs:new_list_incomings.length,
  3107.             })
  3108.         }
  3109.     })
  3110.  
  3111.  
  3112.     console.log("mapPredict",mapPredict)
  3113.  
  3114.  
  3115.  
  3116.     list_players.sort((o1,o2)=>{
  3117.         return (o1.nr_incs > o2.nr_incs)?-1:(o1.nr_incs < o2.nr_incs)?1:0;
  3118.     })
  3119.  
  3120.     console.log("list_players",list_players)
  3121.     console.log("map_player_inc",map_player_inc)
  3122.  
  3123.     for(let i=0;i<list_players.length;i++){
  3124.         $('#id_select_incs').append($('<option>', {
  3125.             value: list_players[i].id_player_off,
  3126.             text: list_players[i].name_player_off
  3127.         }));
  3128.  
  3129.     }
  3130.     $("#btn_show_incs").off("click")
  3131.     $("#btn_show_incs").on("click",()=>{
  3132.         let id_player_off = $("#id_select_incs").val()
  3133.         console.log(map_player_inc.get(id_player_off))
  3134.         showIncomings(map_player_inc.get(id_player_off))
  3135.     })
  3136.  
  3137.  
  3138.     UI.SuccessMessage("get data",1000)
  3139.     console.log("get incomings")
  3140.     $(".tr_delimitator").remove();
  3141.     console.log(map_incomings_dropbox)
  3142.     if(document.getElementsByClassName("info").length>0){
  3143.         $(".info").remove()
  3144.         $('#td_show_incomings').hide()
  3145.     }
  3146.     else{
  3147.         $("#td_show_incomings").show()
  3148.         let start=new Date();
  3149.         map_incomings_dropbox = removeLandedIncomings(map_incomings_dropbox)
  3150.  
  3151.        
  3152.         // let table=document.getElementById("incomings_table").lastElementChild.children
  3153.         let incomings_table=document.getElementById("incomings_table").cloneNode(true)
  3154.         let table=incomings_table.lastElementChild.children
  3155.         let list=[];
  3156.         let map_nr_atacuri=new Map();
  3157.         let map_nr_destination=new Map();
  3158.        
  3159.         //adaugare o noua coloana
  3160.         let coloana_nr=table[0].insertCell(3);
  3161.         coloana_nr.outerHTML="<th class='deleteTh'><a href=# id='id_nr'> nr</a></th>";
  3162.         coloana_nr.className="info"
  3163.        
  3164.         let coloana_tribe=table[0].insertCell(4);
  3165.         coloana_tribe.outerHTML="<th class='deleteTh'><a href=# id='id_nr_tr'> nr_tribe</a></th>";
  3166.         coloana_tribe.className="info"
  3167.        
  3168.         let coloana_type=table[0].insertCell(5);
  3169.         coloana_type.outerHTML="<th class='deleteTh'><a href=# id='id_type'> type</a></th>";
  3170.         coloana_type.className="info"    
  3171.        
  3172.         let coloana_pop=table[0].insertCell(6);
  3173.         coloana_pop.outerHTML="<th class='deleteTh'><a href=# id='id_pop'>pop</a></th>";
  3174.         coloana_pop.className="info"
  3175.        
  3176.         let coloana_time=table[0].insertCell(7);
  3177.         coloana_time.outerHTML="<th class='deleteTh'><a href=# id='id_time'>time</a></th>";
  3178.         coloana_time.className="info"
  3179.        
  3180.         let coloana_report=table[0].insertCell(8);
  3181.         coloana_report.outerHTML="<th class='deleteTh'><a href=# id='id_report'>report</a></th>";
  3182.         coloana_report.className="info"
  3183.  
  3184.         let coloana_launch=table[0].insertCell(9);
  3185.         coloana_launch.outerHTML="<th class='deleteTh'><a href=# id='id_launch_time'>launch time</a></th>";
  3186.         coloana_launch.className="info"
  3187.  
  3188.         let coloana_predict=table[0].insertCell(10);
  3189.         coloana_predict.outerHTML="<th class='deleteTh'><a href=# id='id_predict'>predict</a></th>";
  3190.         coloana_predict.className="info"
  3191.  
  3192.         let coloana_home=table[0].insertCell(11);
  3193.         coloana_home.outerHTML="<th class='deleteTh'><a href=# id='id_home'>stacks\nhome</a></th>";
  3194.         coloana_home.className="info"
  3195.  
  3196.         let coloana_comming=table[0].insertCell(12);
  3197.         coloana_comming.outerHTML="<th class='deleteTh'><a href=# id='id_predict'>stacks\ncomming</a></th>";
  3198.         coloana_comming.className="info"
  3199.  
  3200.  
  3201.         var list_coord_player=[]
  3202.         for(let i=1;i<table.length-1;i++){
  3203.             let coord=table[i].children[2].innerText.match(/\d+\|\d+/)[0];
  3204.             let coord_destination=table[i].children[1].innerText.match(/\d+\|\d+/)[0];
  3205.             let nameLabel=table[i].children[0].innerText.trim().split(/\s+/)[0].toLowerCase();
  3206.            
  3207.             let player_name_off
  3208.             let player_id
  3209.  
  3210.             if(game_data.device == "desktop"){
  3211.                 player_id=table[i].children[table[i].children.length-4].children[0].href.split("player&id=")[1]
  3212.                 player_name_off=table[i].children[table[i].children.length-4].children[0].innerText
  3213.  
  3214.             }
  3215.             else{
  3216.                 player_id=table[i].children[table[i].children.length-3].children[0].href.split("player&id=")[1]
  3217.                 player_name_off=table[i].children[table[i].children.length-3].children[0].innerText
  3218.            }
  3219.  
  3220.             list_coord_player.push({
  3221.                 coord:coord,
  3222.                 player_id:player_id,
  3223.                 player_name_off:player_name_off,
  3224.                 nameLabel:nameLabel,
  3225.             })
  3226.             //origin coord
  3227.             if(map_nr_atacuri.has(coord))
  3228.                 map_nr_atacuri.set(coord,parseInt(map_nr_atacuri.get(coord)) +1);
  3229.             else
  3230.                 map_nr_atacuri.set(coord,1);
  3231.             //destination coord
  3232.             if(map_nr_destination.has(coord_destination))
  3233.                 map_nr_destination.set(coord_destination,parseInt(map_nr_destination.get(coord_destination)) +1);
  3234.             else
  3235.                 map_nr_destination.set(coord_destination,1);
  3236.         }
  3237.         var stop=new Date();
  3238.         console.log("add info: "+(stop-start))
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.         for(let i=1;i<table.length-1;i++){
  3245.             var html_nr="?"
  3246.             var html_nr_tribe="<center>0</center>"
  3247.             var html_type="?"
  3248.             var html_pop="?"
  3249.             var html_time="?"
  3250.             var html_report="?"
  3251.             var html_launch="?"
  3252.             var html_predict="?"
  3253.             var html_home="?"
  3254.             var html_comming="?"
  3255.            
  3256.             var length_tr=table[i].children.length
  3257.             let coord=list_coord_player[i-1].coord
  3258.             let player_id=list_coord_player[i-1].player_id
  3259.             let player_name_off=list_coord_player[i-1].player_name_off
  3260.             let nameLabel=list_coord_player[i-1].nameLabel
  3261.  
  3262.             let coord_destination=table[i].children[1].innerText.match(/\d+\|\d+/)[0];
  3263.             let coord_origin=table[i].children[2].innerText.match(/\d+\|\d+/)[0];
  3264.            
  3265.             let duplicate_destination=map_nr_destination.get(coord_destination)
  3266.             table[i].children[1].setAttribute("data-nr",duplicate_destination)
  3267.  
  3268.             html_nr="<h4>"+map_nr_atacuri.get(coord)+"</h4>";
  3269.  
  3270.             let time_land
  3271.             if(game_data.device == "desktop"){
  3272.                 time_land=table[i].children[length_tr-2].innerText
  3273.             }
  3274.             else{
  3275.                 time_land=table[i].children[length_tr-1].innerText
  3276.             }
  3277.             let milliseconds = time_land.split(":").pop();
  3278.             let date_land=getLandTime(time_land)
  3279.  
  3280.  
  3281.             if(table[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img").length==2){
  3282.                 let distance= calcDistance(coord_destination,coord_origin)
  3283.                 let labelName=table[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src
  3284.                 let time_attack=0;
  3285.                 if(labelName.includes("snob.png")){
  3286.                     time_attack=nobleSpeed*distance
  3287.                 }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  3288.                     time_attack=ramSpeed*distance
  3289.                 }else if(labelName.includes("sword.png")){
  3290.                     time_attack=swordSpeed*distance
  3291.                 }else if(labelName.includes("axe.png")){
  3292.                     time_attack=axeSpeed *distance
  3293.                 }
  3294.                
  3295.                 if(time_attack>0){
  3296.                     time_attack=Math.round(time_attack/1000)*1000
  3297.                     let time_launch=(parseDate(new Date(date_land).getTime()-time_attack)+":"+milliseconds).trim()
  3298.                     html_launch=`<h4>${time_launch}</h4>`
  3299.  
  3300.                     if(mapPredict.has(time_launch+"_"+player_name_off))
  3301.                         html_predict=`<h4>${mapPredict.get(time_launch+"_"+player_name_off).replace("pred_","")}</h4>`
  3302.                 }
  3303.                
  3304.            
  3305.             }else if(nameLabel == lang["dcfafcb4323b102c7e204555d313ba0a"].toLowerCase()){
  3306.                 let timeInMM=table[i].children[length_tr-1].innerText.split(":")
  3307.                 timeInMM=timeInMM[0]*3600*1000+timeInMM[1]*60*1000+timeInMM[2]*1000;
  3308.                 let distance= calcDistance(coord_destination,coord_origin)
  3309.                 let time_attack=0;
  3310.                 if(timeInMM > ramSpeed*distance){
  3311.                     time_attack=nobleSpeed*distance
  3312.                 }
  3313.                 else if(timeInMM > swordSpeed*distance){
  3314.                     time_attack=ramSpeed*distance
  3315.                 }
  3316.                 else if(timeInMM > axeSpeed*distance){
  3317.                     time_attack=swordSpeed*distance
  3318.                 }
  3319.                 else if(timeInMM > heavySpeed*distance){
  3320.                     time_attack=heavySpeed*distance
  3321.                 }
  3322.                 else if(timeInMM > lightSpeed*distance){
  3323.                     time_attack=lightSpeed*distance
  3324.                 }
  3325.                 else if(timeInMM > spySpeed*distance){
  3326.                     time_attack=spySpeed*distance
  3327.                 }      
  3328.  
  3329.                 if(time_attack>0){
  3330.                     time_attack=Math.round(time_attack/1000)*1000
  3331.                     let time_launch=(parseDate(new Date(date_land).getTime()-time_attack)+":"+milliseconds).trim()
  3332.                     html_launch=`<h4>${time_launch}</h4>`
  3333.  
  3334.                     if(mapPredict.has(time_launch+"_"+player_name_off))
  3335.                         html_predict=`<h4>${mapPredict.get(time_launch+"_"+player_name_off).replace("pred_","")}</h4>`
  3336.                 }
  3337.                
  3338.             }
  3339.  
  3340.  
  3341.  
  3342.            
  3343.             if(map_incomings_dropbox.has(coord)){
  3344.                 let list_incomings=map_incomings_dropbox.get(coord)
  3345.                 // html_nr_tribe=" <center><h4 style='color:black'>"+list_incomings.length+"</h4></center>";
  3346.                 // console.log(list_incomings)
  3347.                 list_incomings.sort((o1,o2)=>{
  3348.                     return (new Date(o1.date_land).getTime()<new Date(o2.date_land).getTime())?1:
  3349.                     (new Date(o1.date_land).getTime()>new Date(o2.date_land).getTime())?-1:0
  3350.                 })
  3351.                 html_nr_tribe=`
  3352.                     <div class="popup"  onclick='var popup = document.getElementById("tableInc`+i+`");popup.classList.toggle("show")'><center><h4 style='color:black'>${list_incomings.length}</h4></center>
  3353.                     <table class="popuptext" border="1" style="background-color:#f4e4bc;border-color:#c1a264" id="tableInc`+i+'"'+
  3354.                    createTableIncomings(list_incomings)+
  3355.                '</table></div>';
  3356.  
  3357.  
  3358.  
  3359.  
  3360.            }
  3361.            if(map_reports_dropbox.has(coord) )
  3362.            {
  3363.                let idPlayer_dropbox
  3364.                let type_dropbox
  3365.                let nr_troupes_dropbox
  3366.  
  3367.                var obj=map_reports_dropbox.get(coord);
  3368.                var traveling=false
  3369.                if(coord == obj.coordAttacker){
  3370.                    idPlayer_dropbox=obj.attackingPlayerId;
  3371.                    type_dropbox=obj.typeAttacker;
  3372.                    nr_troupes_dropbox=obj.nrTroupesAttacker
  3373.                    traveling=true;
  3374.                }
  3375.                else if(coord == obj.coordDefender){
  3376.                    idPlayer_dropbox=obj.defendingPlayerId;
  3377.                    type_dropbox=obj.typeDefender;
  3378.                    nr_troupes_dropbox=obj.nrTroupesDefender
  3379.                    traveling=false;
  3380.                }
  3381.                else{
  3382.                    idPlayer_dropbox=obj.supporterPlayerId
  3383.                    type_dropbox=obj.typeSupporter;
  3384.                    nr_troupes_dropbox=obj.nrTroupesSupporter
  3385.                }
  3386.  
  3387.                if(idPlayer_dropbox == player_id)
  3388.                {
  3389.                    let serverTime=document.getElementById("serverTime").innerText
  3390.                    let serverDate=document.getElementById("serverDate").innerText.split("/")
  3391.                    serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  3392.                    let date_current=new Date(serverDate+" "+serverTime).getTime()
  3393.                    
  3394.                    //calculate population
  3395.                    let date_landing_report=new Date(obj.time_report)
  3396.                    let distance
  3397.                    if(game_data.device == "desktop")
  3398.                        distance=parseFloat(table[i].children[length_tr-3].innerText);
  3399.                    else
  3400.                        distance=parseFloat(table[i].children[length_tr-2].innerText);
  3401.  
  3402.                    let time_attack=0;
  3403.                    let time_land
  3404.                    if(game_data.device == "desktop"){
  3405.                        time_land=table[i].children[length_tr-2].innerText
  3406.                    }
  3407.                    else{
  3408.                        time_land=table[i].children[length_tr-1].innerText
  3409.                    }
  3410.                    let date_land=new Date(getLandTime(time_land))
  3411.                    let labelName=""
  3412.                    if(table[i].children[0].getElementsByTagName("img")[1]==undefined || table[i].children[0].getElementsByTagName("img")[1]==null )
  3413.                        labelName="ram.png"
  3414.                    else
  3415.                        labelName=table[i].children[0].getElementsByTagName("img")[1].src
  3416.  
  3417.                    if(labelName.includes("snob.png")){
  3418.                        time_attack=nobleSpeed*distance
  3419.                    }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  3420.                        time_attack=ramSpeed*distance
  3421.                    }else if(labelName.includes("sword.png")){
  3422.                        time_attack=swordSpeed*distance
  3423.                    }else if(labelName.includes("axe.png")){
  3424.                        time_attack=axeSpeed *distance
  3425.                    }
  3426.                    date_current-=time_attack
  3427.  
  3428.                    if(traveling==false)
  3429.                        time_attack=0;
  3430.  
  3431.                    if(type_dropbox=="off"){
  3432.                        // console.log(date_land.getTime())
  3433.                        // console.log(time_attack)
  3434.                        // console.log(date_landing_report.getTime())
  3435.                        let timeForRecruiting = (date_land.getTime()-time_attack)-date_landing_report.getTime()
  3436.                        nr_troupes_dropbox=calcProductionTroupes(timeForRecruiting,nr_troupes_dropbox)                            
  3437.                        nr_troupes_dropbox=Math.round(nr_troupes_dropbox*10)/10+"%"
  3438.                        // console.log("final "+nr_troupes_dropbox)
  3439.                    }
  3440.                    else{
  3441.                        nr_troupes_dropbox="?"
  3442.                    }
  3443.  
  3444.  
  3445.  
  3446.                    let date_start=new Date(obj.time_report);
  3447.                    let date_stop=new Date(date_current);
  3448.                    let diffTime=date_stop-date_start
  3449.                    if(diffTime<=0)
  3450.                        diffTime=0
  3451.  
  3452.                    let days=("00"+parseInt((diffTime)/(24*3600*1000))).slice(-3);
  3453.                    let hours=("0"+parseInt((diffTime)/(3600*1000)%24)).slice(-2);
  3454.                    let minutes=("0"+parseInt(((diffTime)/(60*1000)%60))).slice(-2);
  3455.                    let seconds=( "0"+parseInt((((diffTime)/1000)%60))).slice(-2);
  3456.  
  3457.  
  3458.                    html_type=" <h4 class='cls_type'>"+type_dropbox+"</h4>"
  3459.                    html_pop=" <h4 class='cls_pop'>"+nr_troupes_dropbox+"</h4>"
  3460.                    if(obj.time_return==0 || obj.time_return==undefined){
  3461.                        html_time=" <h4>"+days+":"+hours+":"+minutes+":"+seconds+"</h4>";
  3462.                    }
  3463.                    else{
  3464.                        html_time=" <h4 class='possible_fake' date-fake='"+obj.time_return+"'>"+days+":"+hours+":"+minutes+":"+seconds+"</h4>";
  3465.                    }
  3466.  
  3467.                    // createTableIncomings
  3468.                    // console.log(obj)
  3469.                    html_report=`
  3470.                        <div class="popup" onclick='var popup = document.getElementById("table`+i+`");popup.classList.toggle("show")'><h4>show</h4>
  3471.                        <table class="popuptext" style="background-color:#f4e4bc" id="table`+i+'"'+
  3472.                        createReport(obj)+
  3473.                    '</table></div>';
  3474.                }
  3475.            }
  3476.  
  3477.  
  3478.            //set troops home and comming
  3479.            if(troopsHome.has(coord_destination)){
  3480.                html_home = `<h4>${(troopsHome.get(coord_destination)/1000).toFixed(1)}k</h4>`
  3481.            }
  3482.            if(troopsComming.has(coord_destination)){
  3483.                html_comming = `<h4>${(troopsComming.get(coord_destination)/1000).toFixed(1)}k</h4>`
  3484.            }
  3485.  
  3486.  
  3487.            coloana_nr=table[i].insertCell(3);
  3488.            coloana_nr.innerHTML=html_nr
  3489.            coloana_nr.className="info test"
  3490.  
  3491.            coloana_tribe=table[i].insertCell(4);
  3492.            coloana_tribe.innerHTML=html_nr_tribe
  3493.            coloana_tribe.className="info"
  3494.        
  3495.            coloana_type=table[i].insertCell(5);
  3496.            coloana_type.innerHTML=html_type
  3497.            coloana_type.className="info"
  3498.        
  3499.            coloana_pop=table[i].insertCell(6);
  3500.            coloana_pop.innerHTML=html_pop
  3501.            coloana_pop.className="info"
  3502.        
  3503.            coloana_time=table[i].insertCell(7);
  3504.            coloana_time.innerHTML=html_time
  3505.            coloana_time.className="info"
  3506.        
  3507.            coloana_report=table[i].insertCell(8);
  3508.            coloana_report.innerHTML=html_report
  3509.            coloana_report.className="info"
  3510.  
  3511.            coloana_launch=table[i].insertCell(9);
  3512.            coloana_launch.innerHTML=html_launch
  3513.            coloana_launch.className="info"
  3514.  
  3515.            coloana_predict=table[i].insertCell(10);
  3516.            coloana_predict.innerHTML=html_predict
  3517.            coloana_predict.className="info"
  3518.  
  3519.            coloana_home=table[i].insertCell(11);
  3520.            coloana_home.innerHTML= html_home
  3521.            coloana_home.className="info"
  3522.  
  3523.            coloana_comming=table[i].insertCell(12);
  3524.            coloana_comming.innerHTML=html_comming
  3525.            coloana_comming.className="info"
  3526.        }
  3527.        // console.log(incomings_table)
  3528.        $("#incomings_table tbody tr").remove()
  3529.        $("#incomings_table tbody").append(table)
  3530.        sortIncomings();
  3531.        highLightIncomings();
  3532.        counterTime();
  3533.        var stop=new Date();
  3534.        console.log("add inf final: "+(stop-start))
  3535.  
  3536.  
  3537.        $('document').ready(function() {
  3538.            CommandsOverview.init();
  3539.            UI.ToolTip('.icon_village_notes');
  3540.  
  3541.            $('.quickedit').QuickEdit({url: TribalWars.buildURL('POST', 'info_command', {ajaxaction: 'edit_other_comment', id: '__ID__'})});
  3542.            Command.init();
  3543.        });
  3544.  
  3545.  
  3546.    }
  3547.  
  3548.  
  3549. }
  3550.    
  3551. //////////////////////////////////////////////////////sort incomings by.. /////////////////////////////////////////////////////////////////
  3552.  
  3553. function sortIncomings()
  3554. {
  3555.    var table=document.getElementById("incomings_table").lastElementChild.children;
  3556.    var new_table=document.getElementById("incomings_table").lastElementChild;
  3557.    var last_row=table[table.length-1];
  3558.    var list=[];
  3559.    var list_info=[]
  3560.    for(let i=1;i<table.length-1;i++){
  3561.        if(table[i].classList.contains("row_a")){
  3562.            table[i].classList.remove("row_a")
  3563.            table[i].classList.add("row_b")
  3564.        }
  3565.        if(table[i].classList.contains("selected")){
  3566.            table[i].classList.remove("selected")
  3567.        }
  3568.  
  3569.        list.push(table[i]);
  3570.    }
  3571.    var length_table=1
  3572.    if(table.length>2){
  3573.        length_table=table[1].children.length
  3574.    }
  3575.  
  3576.  
  3577.    //sort by nr
  3578.    document.getElementById("id_nr").addEventListener("click",function()
  3579.    {
  3580.        var start=new Date();
  3581.        $(".tr_delimitator").remove();
  3582.        list.sort( (a,b)=>{
  3583.            return (parseInt(a.children[3].innerText)<parseInt(b.children[3].innerText))?1:(parseInt(a.children[3].innerText)>parseInt(b.children[3].innerText))?-1:
  3584.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3585.    });
  3586.  
  3587.  
  3588.        //add new table in page
  3589.        for(let i=0;i<list.length;i++)
  3590.        {
  3591.            new_table.appendChild(list[i]);
  3592.        }
  3593.        new_table.appendChild(last_row);
  3594.  
  3595.        for(let i=0;i<list.length;i++)
  3596.        {
  3597.            list_info.push({
  3598.                coord_attacker:list[i].children[2].innerText,
  3599.                nr:parseInt(list[i].children[3].innerText),
  3600.            })
  3601.        }
  3602.        var pozitie=2;
  3603.        for(let i=0;i<list.length-1;i++)
  3604.        {
  3605.            let nr_atacuri=list_info[i].nr
  3606.            if(nr_atacuri>1 && list_info[i].coord_attacker !=list_info[i+1].coord_attacker)
  3607.            {
  3608.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3609.                var newRow   = tableRef.insertRow(pozitie);
  3610.                newRow.className="tr_delimitator"
  3611.                for(let i=0; i<1;i++){
  3612.                    let cell  = newRow.insertCell();
  3613.                    cell.setAttribute("colspan",length_table)
  3614.                    cell.classList.add("selected")
  3615.                    var delimitator  = document.createTextNode('--');
  3616.                    cell.appendChild(delimitator);
  3617.                
  3618.                }
  3619.            pozitie++;
  3620.            }
  3621.            else if(nr_atacuri==1){
  3622.                break;
  3623.            }
  3624.            pozitie++;
  3625.        }
  3626.        list_info=[]
  3627.        var stop=new Date();
  3628.        console.log(stop-start)
  3629.    })
  3630.  
  3631.    //sort by nr tribe
  3632.    document.getElementById("id_nr_tr").addEventListener("click",function()
  3633.    {
  3634.        var start=new Date();
  3635.        
  3636.        $(".tr_delimitator").remove();
  3637.        list.sort( (a,b)=>{
  3638.            return (parseInt(a.children[4].innerText)<parseInt(b.children[4].innerText))?1:(parseInt(a.children[4].innerText)>parseInt(b.children[4].innerText))?-1:
  3639.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3640.    });
  3641.  
  3642.  
  3643.        //add new table in page
  3644.        for(let i=0;i<list.length;i++)
  3645.        {
  3646.            new_table.appendChild(list[i]);
  3647.        }
  3648.        new_table.appendChild(last_row);
  3649.  
  3650.        for(let i=0;i<list.length;i++)
  3651.        {
  3652.            list_info.push({
  3653.                coord_attacker:list[i].children[2].innerText,
  3654.                nr:parseInt(list[i].children[4].innerText),
  3655.            })
  3656.        }
  3657.        var pozitie=2;
  3658.        for(let i=0;i<list.length-1;i++)
  3659.        {
  3660.            let nr_atacuri=list_info[i].nr
  3661.            if(nr_atacuri>1 && list_info[i].coord_attacker !=list_info[i+1].coord_attacker)
  3662.            {
  3663.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3664.                var newRow   = tableRef.insertRow(pozitie);
  3665.                newRow.className="tr_delimitator"
  3666.                for(let i=0; i<1;i++){
  3667.                    let cell  = newRow.insertCell();
  3668.                    cell.setAttribute("colspan",length_table)
  3669.                    cell.classList.add("selected")
  3670.                    var delimitator  = document.createTextNode('--');
  3671.                    cell.appendChild(delimitator);
  3672.                
  3673.                }
  3674.            pozitie++;
  3675.            }
  3676.            else if(nr_atacuri==1){
  3677.                break;
  3678.            }
  3679.            pozitie++;
  3680.        }
  3681.        list_info=[]
  3682.        var stop=new Date();
  3683.        console.log(stop-start)
  3684.    })
  3685.  
  3686.  
  3687.    //sort by type
  3688.    document.getElementById("id_type").addEventListener("click",function()
  3689.    {
  3690.        var start=new Date();
  3691.        $(".tr_delimitator").remove();
  3692.        list.sort( (a,b)=>{
  3693.            return (a.children[5].innerText<b.children[5].innerText)?1:(a.children[5].innerText>b.children[5].innerText)?-1:
  3694.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3695.        });
  3696.  
  3697.        //add new table in page
  3698.        for(let i=0;i<list.length;i++)
  3699.        {
  3700.            new_table.appendChild(list[i]);
  3701.        }
  3702.        new_table.appendChild(last_row);
  3703.  
  3704.        var pozitie=2;
  3705.        for(let i=0;i<list.length-1;i++)
  3706.        {
  3707.            let type=list[i].children[5].innerText;
  3708.            if(type!="?" && list[i].children[5].innerText !=list[i+1].children[5].innerText)
  3709.            {
  3710.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3711.                var newRow   = tableRef.insertRow(pozitie);
  3712.                newRow.className="tr_delimitator"
  3713.                for(let i=0; i<1;i++){
  3714.                    let cell  = newRow.insertCell();
  3715.                    cell.setAttribute("colspan",length_table)
  3716.                    cell.classList.add("selected")
  3717.                    var delimitator  = document.createTextNode('--');
  3718.                    cell.appendChild(delimitator);
  3719.                }
  3720.            pozitie++;
  3721.            }
  3722.            pozitie++;
  3723.        }
  3724.        list_info=[]
  3725.        var stop=new Date();
  3726.        console.log(stop-start)
  3727.    })
  3728.    
  3729.    //sort by nr pop
  3730.    document.getElementById("id_pop").addEventListener("click",function()
  3731.    {
  3732.        var start=new Date();
  3733.        console.log("aici baaaa")
  3734.        console.log($(".tr_delimitator"))
  3735.        $(".tr_delimitator").remove();
  3736.        list.sort( (a,b)=>{
  3737.            if(a.children[6].innerText=="?")
  3738.                var a_comp=2000000;
  3739.            else    
  3740.                var a_comp=parseFloat(a.children[6].innerText);
  3741.  
  3742.            if(b.children[6].innerText=="?")
  3743.                var b_comp=2000000;
  3744.            else    
  3745.                var b_comp=parseFloat(b.children[6].innerText);
  3746.  
  3747.            return (a_comp>b_comp)?1:(a_comp<b_comp)?-1:
  3748.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3749.        });
  3750.  
  3751.        //add new table in page
  3752.        for(let i=0;i<list.length;i++)
  3753.        {
  3754.            new_table.appendChild(list[i]);
  3755.        }
  3756.        list_info=[]
  3757.        new_table.appendChild(last_row);
  3758.  
  3759.        let pozitie=1
  3760.        for(let i=0;i<list.length;i++)
  3761.        {
  3762.            console.log(i)
  3763.            if(i%4==0 && i>0){
  3764.                console.log("inside "+i)
  3765.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3766.                var newRow   = tableRef.insertRow(pozitie);
  3767.                newRow.className="tr_delimitator"
  3768.                for(let i=0; i<1;i++){
  3769.                    let cell  = newRow.insertCell();
  3770.                    cell.setAttribute("colspan",length_table)
  3771.                    cell.classList.add("selected")
  3772.                    var delimitator  = document.createTextNode('--');
  3773.                    cell.appendChild(delimitator);
  3774.                }
  3775.                pozitie++;
  3776.  
  3777.            }
  3778.            pozitie++;
  3779.        }
  3780.  
  3781.  
  3782.  
  3783.  
  3784.        var stop=new Date();
  3785.        console.log(stop-start)
  3786.    })
  3787.  
  3788.    //sort by time
  3789.    document.getElementById("id_time").addEventListener("click",function()
  3790.    {
  3791.        var start=new Date();
  3792.  
  3793.        $(".tr_delimitator").remove();
  3794.  
  3795.        list.sort( (a,b)=>{
  3796.            if(a.children[7].innerText=="?")
  3797.                var a_comp=10000000000;
  3798.            else{
  3799.                var v=a.children[7].innerText.split(":");
  3800.                var a_comp=parseInt(v[0])*24*3600+parseInt(v[1])*3600 +parseInt(v[2])*60 +parseInt(v[3]);
  3801.            }
  3802.  
  3803.            if(b.children[7].innerText=="?")
  3804.                var b_comp=10000000000;
  3805.            else{
  3806.                var v=b.children[7].innerText.split(":");
  3807.                var b_comp=parseInt(v[0])*24*3600+parseInt(v[1])*3600 +parseInt(v[2])*60 +parseInt(v[3]);
  3808.            }
  3809.  
  3810.            return (a_comp>b_comp)?1:(a_comp<b_comp)?-1:
  3811.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3812.        });
  3813.  
  3814.        //add new table in page
  3815.        for(let i=0;i<list.length;i++)
  3816.        {
  3817.            new_table.appendChild(list[i]);
  3818.        }
  3819.        list_info=[]
  3820.        new_table.appendChild(last_row);
  3821.        
  3822.        let pozitie=1
  3823.        for(let i=0;i<list.length;i++)
  3824.        {
  3825.            console.log(i)
  3826.            if(i%4==0 && i>0){
  3827.                console.log("inside "+i)
  3828.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3829.                var newRow   = tableRef.insertRow(pozitie);
  3830.                newRow.className="tr_delimitator"
  3831.                for(let i=0; i<1;i++){
  3832.                    let cell  = newRow.insertCell();
  3833.                    cell.setAttribute("colspan",length_table)
  3834.                    cell.classList.add("selected")
  3835.                    var delimitator  = document.createTextNode('--');
  3836.                    cell.appendChild(delimitator);
  3837.                }
  3838.                pozitie++;
  3839.  
  3840.            }
  3841.            pozitie++;
  3842.        }
  3843.  
  3844.  
  3845.        var stop=new Date();
  3846.        console.log(stop-start)
  3847.    })
  3848.  
  3849.    //sort by launch time
  3850.    document.getElementById("id_launch_time").addEventListener("click",function()
  3851.    {
  3852.        var start=new Date();
  3853.  
  3854.        $(".tr_delimitator").remove();
  3855.  
  3856.        list.sort( (a,b)=>{
  3857.            if(a.children[9].innerText=="?")
  3858.                var a_comp=0;
  3859.            else{
  3860.                var v=a.children[9].innerText
  3861.                var a_comp=new Date(v).getTime();
  3862.            }
  3863.  
  3864.            if(b.children[9].innerText=="?")
  3865.                var b_comp=0
  3866.            else{
  3867.                var v=b.children[9].innerText
  3868.                var b_comp=new Date(v).getTime();
  3869.            }
  3870.  
  3871.            return (a_comp>b_comp)?1:(a_comp<b_comp)?-1:
  3872.            (a.children[2].innerText<b.children[2].innerText) ? 1: (a.children[2].innerText>b.children[2].innerText)?-1:0;
  3873.        });
  3874.  
  3875.        //add new table in page
  3876.        for(let i=0;i<list.length;i++)
  3877.        {
  3878.            new_table.appendChild(list[i]);
  3879.        }
  3880.        list_info=[]
  3881.        new_table.appendChild(last_row);
  3882.        
  3883.        let pozitie=2
  3884.        for(let i=0;i<list.length-1;i++)
  3885.        {
  3886.            // console.log(i)
  3887.            if(list[i].children[11].innerText != list[i+1].children[11].innerText  && i>0){
  3888.                // console.log("inside "+i)
  3889.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3890.                var newRow   = tableRef.insertRow(pozitie);
  3891.                newRow.className="tr_delimitator"
  3892.                for(let i=0; i<1;i++){
  3893.                    let cell  = newRow.insertCell();
  3894.                    cell.setAttribute("colspan",length_table)
  3895.                    cell.classList.add("selected")
  3896.                    var delimitator  = document.createTextNode('--');
  3897.                    cell.appendChild(delimitator);
  3898.                }
  3899.                pozitie++;
  3900.  
  3901.            }
  3902.            pozitie++;
  3903.        }
  3904.  
  3905.  
  3906.        var stop=new Date();
  3907.        console.log(stop-start)
  3908.    })
  3909.  
  3910.  
  3911.  
  3912.  
  3913.    //sort by coord destination
  3914.    var destination_th=document.getElementById("incomings_table").lastElementChild.children[0].children[1]
  3915.    destination_th=destination_th.getElementsByTagName("a")[0]
  3916.    destination_th.outerHTML="<a href='#' id='nr_dest'>"+destination_th.innerHTML+"</a>"
  3917.  
  3918.    document.getElementById("nr_dest").addEventListener("click",function()
  3919.    {
  3920.        console.log("aici")
  3921.        var start=new Date();
  3922.        let lengthTr=list[0].children.length
  3923.        $(".tr_delimitator").remove();
  3924.        list.sort( (a,b)=>{
  3925.            return (new Date(getLandTime(a.children[lengthTr-2].innerText)).getTime()>new Date(getLandTime(b.children[lengthTr-2].innerText)).getTime())?1:
  3926.            (new Date(getLandTime(a.children[lengthTr-2].innerText)).getTime()<new Date(getLandTime(b.children[lengthTr-2].innerText)).getTime())?-1:0
  3927.        })
  3928.        list.sort( (a,b)=>{
  3929.            return (parseInt(a.children[1].getAttribute("data-nr"))<parseInt(b.children[1].getAttribute("data-nr")))?1:
  3930.            (parseInt(a.children[1].getAttribute("data-nr"))>parseInt(b.children[1].getAttribute("data-nr")))?-1:
  3931.            (a.children[1].innerText<b.children[1].innerText) ? 1: (a.children[1].innerText>b.children[1].innerText)?-1:0;
  3932.        });
  3933.  
  3934.  
  3935.        //add new table in page
  3936.        for(let i=0;i<list.length;i++)
  3937.        {
  3938.            new_table.appendChild(list[i]);
  3939.        }
  3940.        new_table.appendChild(last_row);
  3941.        //
  3942.        for(let i=0;i<list.length;i++)
  3943.        {
  3944.            list_info.push({
  3945.                coord_deff:list[i].children[1].innerText.match(/\d+\|\d+/)[0],
  3946.                nr:parseInt(list[i].children[1].getAttribute("data-nr")),
  3947.                id_coord:list[i].children[1].children[0].href.split("village=")[1].split("&")[0]
  3948.            })
  3949.        }
  3950.        console.log(list_info)
  3951.  
  3952.        //add delimiter on the first row
  3953.        var tableRef = document.getElementById("incomings_table").lastElementChild;
  3954.        var newRow   = tableRef.insertRow(1);
  3955.        newRow.className="tr_delimitator"
  3956.        let cell  = newRow.insertCell();
  3957.        
  3958.        cell.setAttribute("colspan",length_table)
  3959.        cell.classList.add("selected")
  3960.        var delimitator  = document.createElement("button")
  3961.        delimitator.innerText="load: ("+list_info[0].coord_deff+")"
  3962.        delimitator.setAttribute("data-id",list_info[0].id_coord)
  3963.        delimitator.setAttribute("data-nr",list_info[0].nr)
  3964.        delimitator.style.margin="10px"
  3965.        delimitator.classList.add("btn","load_troops")
  3966.        cell.appendChild(delimitator);
  3967.  
  3968.        //add delimiter after each village destination
  3969.        var pozitie=3;
  3970.        for(let i=0;i<list.length-1;i++)
  3971.        {
  3972.            if(list_info[i].coord_deff !=list_info[i+1].coord_deff)
  3973.            {
  3974.                var tableRef = document.getElementById("incomings_table").lastElementChild;
  3975.                var newRow   = tableRef.insertRow(pozitie);
  3976.                newRow.className="tr_delimitator"
  3977.                let cell  = newRow.insertCell();
  3978.  
  3979.                cell.setAttribute("colspan",length_table)
  3980.                cell.classList.add("selected")
  3981.                var delimitator  = document.createElement("button")
  3982.                delimitator.innerText="load: ("+list_info[i+1].coord_deff+")"
  3983.                delimitator.setAttribute("data-id",list_info[i+1].id_coord)
  3984.                delimitator.setAttribute("data-nr",list_info[i+1].nr)
  3985.                delimitator.style.margin="10px"
  3986.                delimitator.classList.add("btn","load_troops")
  3987.                cell.appendChild(delimitator);
  3988.                
  3989.                
  3990.            pozitie++;
  3991.            }
  3992.            pozitie++;
  3993.        }
  3994.        
  3995.        list_info=[]
  3996.        var stop=new Date();
  3997.        console.log(stop-start)
  3998.        eventGetTroops();
  3999.    })
  4000.  
  4001.  
  4002. }
  4003.        
  4004. //////////////////////////////////////////////////////tag incomings /////////////////////////////////////////////////////////////////
  4005. async function tagIncomings(){
  4006.    
  4007.    if(document.getElementsByClassName("info").length==0){
  4008.        document.getElementById("moreInfo").click();
  4009.        await waitForElm(".info")
  4010.        tagIncomings()
  4011.    }
  4012.    else{
  4013.    $("#btn_tag").attr('disabled', true);
  4014.    $(".tr_delimitator").remove();
  4015.  
  4016.    let nameTroops= await getNameTroops()
  4017.    let csrf = window.csrf_token;
  4018.    var list_incomings_href=[]
  4019.    var indexIncoming=1;
  4020.    var table_incomings=document.querySelectorAll(".row_a, .row_b")
  4021.  
  4022.    var nobleSpeed=2100*1000/(speedWorld*speedTroupes)//ms
  4023.    var ramSpeed=1800*1000/(speedWorld*speedTroupes)//ms
  4024.    var swordSpeed=1260*1000/(speedWorld*speedTroupes)//ms
  4025.    var axeSpeed=1080*1000/(speedWorld*speedTroupes)//ms
  4026.    console.log("constant world",speedWorld*speedTroupes)
  4027.    
  4028.  
  4029.    
  4030.    let list_incomingId=[]
  4031.    let listTdRename=[]
  4032.    for(let i=0;i<table_incomings.length;i++){
  4033.        let incomingId=table_incomings[i].children[0].children[2].getAttribute("data-id");
  4034.        let coordDest=table_incomings[i].children[1].innerText.match(/\d+\|\d+/)[0];
  4035.        let coordOrigin=table_incomings[i].children[2].innerText.match(/\d+\|\d+/)[0];
  4036.        var nameTroupe=table_incomings[i].children[0].innerText.trim().split(/\s+/)[0].toLowerCase();
  4037.  
  4038.        let href=window.location.href.split("&")[0]+`&screen=info_command&ajaxaction=edit_other_comment&id=${incomingId}&h=${csrf}`
  4039.        let current_tag=table_incomings[i].children[0].innerText.trim()
  4040.        let nr=parseInt(table_incomings[i].children[3].innerText);
  4041.        let nr_tribe=table_incomings[i].children[4].innerText;
  4042.        let type=table_incomings[i].children[5].innerText;
  4043.        let pop= (table_incomings[i].children[6].innerText !="?") ? parseInt(table_incomings[i].children[6].innerText):"?"
  4044.        let time=table_incomings[i].children[7].innerText;
  4045.        let predict=table_incomings[i].children[10].innerText;
  4046.        let stacksHome=table_incomings[i].children[11].innerText;
  4047.        let stacksComming=table_incomings[i].children[12].innerText;
  4048.        let length_tr=table_incomings[i].children.length
  4049.  
  4050.        let nameAttacker
  4051.        if(game_data.device == "desktop"){
  4052.            nameAttacker=table_incomings[i].children[length_tr-4].innerText
  4053.        }
  4054.        else{
  4055.            nameAttacker=table_incomings[i].children[length_tr-3].innerText
  4056.        }
  4057.  
  4058.        ////////////////////////////////get land time///////////////////////////////
  4059.        let time_land
  4060.        let timeInMM
  4061.  
  4062.        if(game_data.device == "desktop"){
  4063.            time_land=table_incomings[i].children[length_tr-2].innerText
  4064.            timeInMM=table_incomings[i].children[length_tr-1].innerText.split(":")
  4065.        }
  4066.        else{
  4067.            time_land=table_incomings[i].children[length_tr-1].innerText
  4068.            timeInMM=table_incomings[i].children[length_tr-1].innerText.split("\n")[1].split(":")
  4069.            console.log("comoon: " +timeInMM)
  4070.  
  4071.        }
  4072.        let date_land=getLandTime(time_land)
  4073.        let fake=false;
  4074.        let distance=calcDistance(coordOrigin,coordDest);
  4075.  
  4076.        timeInMM = Array.from(timeInMM).map(e=>parseInt(e))
  4077.        timeInMM=timeInMM[0]*3600*1000+ timeInMM[1]*60*1000+timeInMM[2]*1000;
  4078.        // console.log("timeInMM",timeInMM)
  4079.        list_incomingId.push(incomingId)
  4080.        
  4081.        let backtime="none"
  4082.        let sentTime="none"
  4083.        if(table_incomings[i].getElementsByClassName("possible_fake").length>0 && table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img").length==2){
  4084.            let date_home=new Date(table_incomings[i].getElementsByClassName("possible_fake")[0].getAttribute("date-fake"))
  4085.            let labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src
  4086.            let time_attack=0;
  4087.            if(labelName.includes("snob.png")){
  4088.                time_attack=nobleSpeed*distance
  4089.            }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  4090.                time_attack=ramSpeed*distance
  4091.            }else if(labelName.includes("sword.png")){
  4092.                time_attack=swordSpeed*distance
  4093.            }else if(labelName.includes("axe.png")){
  4094.                time_attack=axeSpeed *distance
  4095.            }
  4096.            
  4097.            let dateLand=new Date(date_land)
  4098.            
  4099.            time_attack=Math.round(time_attack/1000)*1000
  4100.            backtime = parseDate(dateLand.getTime()+time_attack)
  4101.            sentTime = parseDate(dateLand.getTime()-time_attack)
  4102.  
  4103.  
  4104.            console.log("time_attack",time_attack)
  4105.            if(time_attack + date_home.getTime() > dateLand.getTime() ){
  4106.                fake=true;
  4107.                console.log("fake from "+coordOrigin)
  4108.            }
  4109.            var days=parseInt(time.split(":")[0])*24*3600*1000
  4110.            var hours=parseInt(time.split(":")[1])*3600*1000
  4111.            var min=parseInt(time.split(":")[2])*60*1000
  4112.            var sec=parseInt(time.split(":")[3])*1000
  4113.            var total_time=days+hours+min+sec-time_attack
  4114.            if(fake==true){
  4115.                time=total_time/(24*3600*1000)
  4116.                time+=":00:00:00"
  4117.            }
  4118.        }
  4119.        else if(table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img").length==2){
  4120.            let labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src
  4121.            let time_attack=0;
  4122.            
  4123.            if(labelName.includes("snob.png")){
  4124.                time_attack=nobleSpeed*distance
  4125.            }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  4126.                time_attack=ramSpeed*distance
  4127.                // console.log("distance",distance)
  4128.                // console.log("ramSpeed",ramSpeed)
  4129.            }else if(labelName.includes("sword.png")){
  4130.                time_attack=swordSpeed*distance
  4131.            }else if(labelName.includes("axe.png")){
  4132.                time_attack=axeSpeed *distance
  4133.            }
  4134.            time_attack=Math.round(time_attack/1000)*1000
  4135.            // console.log("time_attack",time_attack)
  4136.  
  4137.            let dateLand=new Date(date_land)
  4138.            backtime = parseDate(dateLand.getTime()+time_attack)
  4139.            sentTime = parseDate(dateLand.getTime()-time_attack)
  4140.            console.log("backtime",backtime)
  4141.        }
  4142.        
  4143.  
  4144.        let obj={
  4145.            incomingId:incomingId,
  4146.            coordOrigin:coordOrigin,
  4147.            href:href,
  4148.            nameTroupe:nameTroupe,
  4149.            nr:nr,
  4150.            nr_tribe:nr_tribe,
  4151.            type:type,
  4152.            pop:pop,
  4153.            time:time,
  4154.            nameAttacker:nameAttacker,
  4155.            fake:fake,
  4156.            current_tag:current_tag,
  4157.            backtime:backtime,
  4158.            sentTime:sentTime,
  4159.            predict:predict,
  4160.            stacksHome:stacksHome,
  4161.            stacksComming:stacksComming
  4162.        }
  4163.  
  4164.        if(nameTroupe == lang["dcfafcb4323b102c7e204555d313ba0a"].toLowerCase()){
  4165.            let time_attack=0;
  4166.            // console.log(timeInMM +" > "+(axeSpeed*distance))
  4167.            if(timeInMM > ramSpeed*distance){
  4168.                nameTroupe=nameTroops['snob']
  4169.                time_attack=nobleSpeed*distance
  4170.            }
  4171.            else if(timeInMM > swordSpeed*distance){
  4172.                nameTroupe=nameTroops['ram']
  4173.                time_attack=ramSpeed*distance
  4174.            }
  4175.            else if(timeInMM > axeSpeed*distance){
  4176.                nameTroupe=nameTroops['sword']
  4177.                time_attack=swordSpeed*distance
  4178.            }
  4179.            else if(timeInMM > heavySpeed*distance){
  4180.                nameTroupe=nameTroops['axe']
  4181.                time_attack=axeSpeed *distance
  4182.            }
  4183.            else if(timeInMM > lightSpeed*distance){
  4184.                nameTroupe=nameTroops['heavy']
  4185.            }
  4186.            else if(timeInMM > spySpeed*distance){
  4187.                nameTroupe=nameTroops['light']
  4188.            }
  4189.            else{
  4190.                nameTroupe=nameTroops['spy']
  4191.            }
  4192.            obj.nameTroupe=nameTroupe.toLowerCase()
  4193.            if(time_attack > 0){
  4194.                time_attack=Math.round(time_attack/1000)*1000
  4195.                // console.log("time_attack",time_attack)
  4196.    
  4197.                let dateLand=new Date(date_land)
  4198.                backtime = parseDate(dateLand.getTime()+time_attack)
  4199.                sentTime = parseDate(dateLand.getTime()-time_attack)
  4200.                // console.log("backtime",backtime)
  4201.                obj.backtime=backtime
  4202.                obj.sentTime=sentTime
  4203.            }
  4204.        }
  4205.        console.log(obj)
  4206.        
  4207.  
  4208.        if(!table_incomings[i].children[0].innerText.toLowerCase().includes('"')){
  4209.            list_incomings_href.push(obj)
  4210.        }
  4211.  
  4212.        listTdRename.push(table_incomings[i].children[0])
  4213.      
  4214.    }
  4215.  
  4216.    
  4217.    console.log(listTdRename)
  4218.    let table_commands=document.getElementById("incomings_table")
  4219.    let length_columns=table_commands.getElementsByTagName("tbody")[0].children[0].children.length
  4220.    let lastRow=table_commands.getElementsByTagName("tbody")[0].children[listTdRename.length+1]
  4221.    $(table_commands).find(".row_a, .row_b").remove()
  4222.  
  4223.    for(let i=0;i<listTdRename.length;i++){
  4224.        $(table_commands).append(`<tr class="nowrap row_ax"><td colspan="${length_columns}"> ${listTdRename[i].innerHTML} </td></tr>`)
  4225.        
  4226.    }
  4227.    $(table_commands).append(lastRow)
  4228.  
  4229.  
  4230.    list_incomings_href=list_incomings_href.reverse();
  4231.  
  4232.  
  4233.    let checkPop = Number.isNaN(parseInt($("#input_pop_fake2").val())) ? 50 : parseInt($("#input_pop_fake2").val())
  4234.    var url_length=list_incomings_href.length
  4235.    var start_tagging=new Date()
  4236.    function ajaxRequest (urls) {
  4237.        let current_url
  4238.        let labelInfo=""
  4239.        let current_tag
  4240.        let obj=null
  4241.        if(urls.length>0){
  4242.            obj=urls.pop()
  4243.            current_url=obj.href;
  4244.            labelInfo=obj.nameTroupe;
  4245.            current_tag=obj.current_tag;
  4246.            let nr
  4247.            if(obj.nr_tribe=="?")
  4248.                nr=parseInt(obj.nr)
  4249.            else{
  4250.                nr=Math.max(parseInt(obj.nr), parseInt(obj.nr_tribe) )
  4251.            }
  4252.  
  4253.            let backtimeLabel=", [BT]: "+ convertDate(obj.backtime)
  4254.            if(localStorage.getItem(game_data.world+"addBacktime")=="false"){
  4255.                backtimeLabel=""
  4256.            }
  4257.  
  4258.            let sentTimeLabel=", [SENT]: "+ convertDate(obj.sentTime)
  4259.            if(localStorage.getItem(game_data.world+"addSentTime")=="false"){
  4260.                sentTimeLabel=""
  4261.            }
  4262.            let stacksLabel = `, [STACKED: H:${obj.stacksHome}, I:${obj.stacksComming}]`
  4263.            if(localStorage.getItem(game_data.world+"addStacks")=="false"){
  4264.                stacksLabel=""
  4265.            }
  4266.  
  4267.  
  4268.            if(obj.type!="?"){
  4269.                obj.time=parseInt(obj.time.split(":")[0]);
  4270.  
  4271.                if(obj.nr==20000)
  4272.                    labelInfo=labelInfo+" "+obj.nameAttacker+", "+nr+", "+obj.type +backtimeLabel+sentTimeLabel + stacksLabel;
  4273.                else if(obj.type=="new_off")
  4274.                    labelInfo=labelInfo+" "+obj.nameAttacker+", "+nr+", off"+backtimeLabel+sentTimeLabel + stacksLabel;
  4275.                else if(obj.type.includes("def"))
  4276.                    labelInfo=labelInfo+" "+obj.nameAttacker+", "+nr+", "+obj.type+", "+obj.time+"d"+backtimeLabel+sentTimeLabel + stacksLabel;
  4277.                else
  4278.                    labelInfo=labelInfo+" "+obj.nameAttacker+", "+nr+", "+obj.type+", "+obj.pop+"%, "+obj.time+"d"+backtimeLabel+sentTimeLabel + stacksLabel;
  4279.  
  4280.            }
  4281.            else{
  4282.                labelInfo=labelInfo+" "+obj.nameAttacker+", "+nr+backtimeLabel+sentTimeLabel + stacksLabel;
  4283.            }
  4284.  
  4285.            if(obj.fake==true && obj.type.toLowerCase() == "off" && parseInt(obj.pop) < checkPop){
  4286.                labelInfo+=' ("fake")';
  4287.            }
  4288.            else if(obj.fake==true && obj.type.toLowerCase().includes("def_cat")){
  4289.                labelInfo+=' ("fake")';
  4290.            }
  4291.            // if(!obj.predict.includes("?")){
  4292.            //     labelInfo+=` [pred: ${obj.predict}]`;
  4293.            // }
  4294.  
  4295.  
  4296.            console.log(labelInfo)
  4297.        }
  4298.        else{
  4299.            current_url="stop"
  4300.        }
  4301.        console.log("in functie in plm "+urls.length)
  4302.        // console.log(current_url)
  4303.        var start_ajax=new Date();
  4304.        if (urls.length >= 0 && current_url!="stop") {
  4305.  
  4306.            let commandId=current_url.split("id=")[1].split("&")[0]
  4307.            if(current_tag!=labelInfo)
  4308.            {
  4309.  
  4310.                $.ajax({
  4311.                    url: current_url,
  4312.                    method: 'POST',
  4313.                    dataType: "json",
  4314.                    data: { text: labelInfo },
  4315.                    headers: { 'TribalWars-Ajax': 1 },
  4316.                    success: (data) => {
  4317.                        $("span[data-id="+obj.incomingId+"]").find(".quickedit-label").text(labelInfo)
  4318.                        $("span[data-id="+obj.incomingId+"]").parent().css("background-color","#ff8080");
  4319.                        UI.SuccessMessage(indexIncoming+"/"+url_length)
  4320.                        indexIncoming++;
  4321.                        var stop_ajax=new Date();
  4322.                        var dif_time=stop_ajax.getTime()-start_ajax.getTime();
  4323.                        console.log("dif_time "+dif_time+" wait "+(200-dif_time))
  4324.                        window.setTimeout(function(){
  4325.                            ajaxRequest (list_incomings_href)
  4326.    
  4327.                        },200-dif_time)
  4328.                    }
  4329.                })
  4330.            }
  4331.            else{
  4332.                console.log("id: "+commandId+" already tagged")
  4333.                ajaxRequest (list_incomings_href)
  4334.                indexIncoming++;
  4335.            }
  4336.  
  4337.  
  4338.        
  4339.        }
  4340.        else
  4341.        {
  4342.            UI.SuccessMessage("done",2000)
  4343.            var stop_tagging=new Date();
  4344.            console.log("total time "+stop_tagging.getTime()-start_tagging.getTime())
  4345.  
  4346.        }
  4347.    }
  4348.    ajaxRequest(list_incomings_href);
  4349.    
  4350.    }
  4351.        
  4352.  
  4353. }
  4354.    
  4355. function parseDate(time){
  4356.    let date=new Date(time)
  4357.    
  4358.    let year=date.getFullYear();
  4359.    let month=("00"+(date.getMonth()+1)).slice(-2)
  4360.    let day=("00"+date.getDate()).slice(-2)
  4361.    let hours=("00"+date.getHours()).slice(-2)
  4362.    let minutes=("00"+date.getMinutes()).slice(-2)
  4363.    let seconds=("00"+date.getSeconds()).slice(-2)
  4364.    let result=`${month}/${day}/${year} ${hours}:${minutes}:${seconds}`
  4365.    return result
  4366. }
  4367.  
  4368.  
  4369. function getLandTime(time_land){
  4370.    var date_land=""
  4371.    let server_date=document.getElementById("serverDate").innerText.split("/")
  4372.    if(time_land.includes(lang["aea2b0aa9ae1534226518faaefffdaad"].replace(" %s",""))){    //today
  4373.        // console.log("here")
  4374.        date_land=server_date[1]+"/"+server_date[0]+"/"+server_date[2]+" "+time_land.match(/\d+:\d+:\d+:\d+/)[0]
  4375.    }
  4376.    else if(time_land.includes(lang["57d28d1b211fddbb7a499ead5bf23079"].replace(" %s",""))){    //tomorrow
  4377.        var tomorrow_date=new Date(server_date[1]+"/"+server_date[0]+"/"+server_date[2]);
  4378.        tomorrow_date.setDate(tomorrow_date.getDate()+1);
  4379.        date_land= ("0"+(tomorrow_date.getMonth()+1)).slice(-2)+"/"+("0"+tomorrow_date.getDate()).slice(-2)+"/"+tomorrow_date.getFullYear()+" "+time_land.match(/\d+:\d+:\d+:\d+/)[0];
  4380.    }else if(time_land.includes(lang["0cb274c906d622fa8ce524bcfbb7552d"].split(" ")[0])){  //on
  4381.        var on=time_land.match(/\d+.\d+/)[0].split(".");
  4382.        date_land=on[1]+"/"+on[0]+"/"+server_date[2]+" "+time_land.match(/\d+:\d+:\d+:\d+/)[0];
  4383.    }
  4384.    else if(time_land.includes("pÃ¥")){//special case for swedish
  4385.        var on=time_land.match(/\d+.\d+/)[0].split(".");
  4386.        date_land=on[1]+"/"+on[0]+"/"+server_date[2]+" "+time_land.match(/\d+:\d+:\d+:\d+/)[0];
  4387.    }
  4388.    return date_land;
  4389. }
  4390.  
  4391. function waitForElm(selector) {
  4392.    return new Promise(resolve => {
  4393.        if (document.querySelector(selector)) {
  4394.            return resolve(document.querySelector(selector));
  4395.        }
  4396.  
  4397.        const observer = new MutationObserver(mutations => {
  4398.            if (document.querySelector(selector)) {
  4399.                observer.disconnect();
  4400.                resolve(document.querySelector(selector));
  4401.            }
  4402.        });
  4403.  
  4404.        // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
  4405.        observer.observe(document.body, {
  4406.            childList: true,
  4407.            subtree: true
  4408.        });
  4409.    });
  4410. }
  4411.  
  4412.  
  4413. function calcProductionTroupes(time,popReport){
  4414.    var maxPop=popReport;
  4415.    let nrAxemax=6000,nrLcMax=3000,nrRamMax=400;
  4416.    let countAxe=0,countLc=0,countRam=0;
  4417.    let time_temp=time
  4418.    while(maxPop<20000  && time_temp>0){
  4419.        if(countAxe<nrAxemax){
  4420.            countAxe++;
  4421.            time_temp-=axeTime;
  4422.            maxPop+=1
  4423.        }
  4424.        else break;
  4425.    }
  4426.    time_temp=time
  4427.    while(maxPop<20000  && time_temp>0){
  4428.        if(countLc<nrLcMax){
  4429.            countLc++;
  4430.            time_temp-=lhTime;
  4431.            maxPop+=4
  4432.        }
  4433.        else break;
  4434.    }
  4435.    time_temp=time
  4436.    while(maxPop<20000  && time_temp>0){  
  4437.        if(countRam<nrRamMax){
  4438.            countRam++;
  4439.            time_temp-=ramTime;
  4440.            maxPop+=5
  4441.        }
  4442.        else break;
  4443.    }
  4444.  
  4445.    // console.log("axe "+countAxe+" lc "+countLc+" ram "+countRam)
  4446.    // console.log(maxPop)
  4447.    maxPop=(maxPop/20000)*100
  4448.    return maxPop
  4449. }
  4450.    //////////////////////////////////////////////////////search reports /////////////////////////////////////////////////////////////////
  4451. var map_search
  4452. async function loadReports(){
  4453.  
  4454.    [map_search, status,infoVillages]=await Promise.all([readFileDropbox(filename_reports),insertlibraryLocalBase(),getInfoVillages()]).catch(err=>{alert(err)})
  4455.    console.log(status)
  4456.  
  4457.    /////////merge maps for reports
  4458.    try {
  4459.        let decompressedData = await decompress(await map_search.arrayBuffer() , 'gzip');  
  4460.        map_search=new Map( JSON.parse(decompressedData));
  4461.    } catch (error) {
  4462.        console.log("erorrrrrrrrrrrrrrrr map report from dropbox")
  4463.        map_search=new Map()
  4464.    }
  4465.  
  4466.    //if  database is stored locally
  4467.    if(await localBase.getItem(game_data.world+"reports")!=undefined){
  4468.        try {
  4469.            let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "reports"))
  4470.            let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  4471.            let map_localBase=new Map( JSON.parse(decompressedData));
  4472.  
  4473.            console.log("map_localBase",map_localBase)
  4474.            map_search=new Map([...map_localBase, ...map_search])
  4475.        } catch (error) {}
  4476.    }
  4477.  
  4478.  
  4479.  
  4480.    UI.SuccessMessage("Reports loaded", "slow")
  4481.    console.log(map_search)
  4482.    loadReportsOk=true;
  4483.    $("#input_search").on("input",function(){
  4484.        let current_value=$("#input_search").val()
  4485.        if(current_value.match(/\d+\|\d+/)!=null){
  4486.            coords=current_value.match(/\d+\|\d+/g)
  4487.            console.log(coords)
  4488.            $("#report_view").empty()
  4489.            let contentHtml=""
  4490.            let nr_found=0;
  4491.            for(let i=0;i<coords.length;i++){
  4492.                if(map_search.has(coords[i])){
  4493.                    let obj=map_search.get(coords[i]);
  4494.                    console.log(coords[i])
  4495.                    contentHtml+= `<div>
  4496.                    <center style="margin:10px"><input class="btn evt-confirm-btn btn-confirm-yes" type="button"onclick="$('#table`+i+`').toggle('slow')" value="`+coords[i]+`"></center>    
  4497.    
  4498.                    <table  class="table_hide" id="table`+i+'"'+
  4499.                    createReport(obj)+
  4500.                    `</table></div>`;
  4501.                    nr_found++;
  4502.                }
  4503.            }
  4504.            $("#report_view").append(contentHtml)
  4505.            $(".table_hide").hide();
  4506.            $("#progress_search").text("found: "+nr_found)
  4507.        }else{
  4508.        $("#report_view").empty()
  4509.        }
  4510.    
  4511.    })
  4512.    $("#input_search").mouseout(function(){
  4513.        let current_value=$("#input_search").val()
  4514.        if(current_value.match(/\d+\|\d+/)!=null){
  4515.                let coords=current_value.match(/\d+\|\d+/g)
  4516.                $("#input_search").val(Array.from(coords).join(","))
  4517.        }
  4518.    })
  4519.    console.log("infoVillages",infoVillages)
  4520.    $("#btn_off_coord").on("click",function(){
  4521.        let tribes=Array.from(document.getElementById("input_filter_tribe").value.split(",")).map(e=>e.trim().toLowerCase()).filter(element => {
  4522.            return element !== '';
  4523.          });
  4524.        
  4525.        let list_output=[]
  4526.        console.log("tribes",tribes)
  4527.  
  4528.        Array.from(map_search.keys()).forEach(key=>{
  4529.            try {
  4530.                let obj=map_search.get(key)
  4531.                let troop_at_home=obj["troopsAtHome_"+key]
  4532.                let pop=0;
  4533.                let time_report_home=obj["time_report_home_"+key]
  4534.                // console.log("troopsAtHome_"+key)
  4535.    
  4536.    
  4537.            
  4538.    
  4539.                if(troop_at_home!=undefined){
  4540.                    for(let i=0;i<troop_at_home.length;i++){
  4541.                        if(troop_at_home[i].type=="spear" || troop_at_home[i].type=="sword" || troop_at_home[i].type=="archer" || troop_at_home[i].type=="heavy"){
  4542.                            pop+=troop_at_home[i].count*troopsPop[troop_at_home[i].type]
  4543.                        }
  4544.                    }
  4545.                }
  4546.                else{
  4547.                    pop=-1
  4548.                    time_report_home="none"
  4549.                }  
  4550.                // console.log("coord: "+obj.coordAttacker)
  4551.                // console.log(infoVillages.get(obj.coordAttacker))
  4552.                if( tribemates.includes(obj.nameAttacker.toLowerCase())==false && obj.typeAttacker.includes("off")  && key.includes(obj.coordAttacker) &&
  4553.                    (tribes.includes(infoVillages.get(obj.coordAttacker).tribeName.toLowerCase()) || tribes.length == 0  )){
  4554.                    list_output.push({
  4555.                        type:"off",
  4556.                        coord:obj.coordAttacker,
  4557.                        name:obj.nameAttacker,
  4558.                        date:time_report_home,
  4559.                        pop:pop
  4560.                    })
  4561.                }
  4562.                else if( tribemates.includes(obj.nameDefender.toLowerCase())==false && obj.typeDefender.includes("off") &&  key.includes(obj.coordDefender) &&
  4563.                       (tribes.includes(infoVillages.get(obj.coordDefender).tribeName.toLowerCase()) || tribes.length == 0 )){
  4564.                        
  4565.                    list_output.push({
  4566.                        type:"off",
  4567.                        coord:obj.coordDefender,
  4568.                        name:obj.nameDefender,
  4569.                        date:time_report_home,
  4570.                        pop:pop
  4571.                    })
  4572.                }
  4573.            } catch (error) {
  4574.                console.log("key: "+ key+ "not found")
  4575.            }
  4576.    
  4577.  
  4578.        })
  4579.        list_output.sort((o1,o2)=>{
  4580.            return (o1.name>o2.name)?1:(o1.name<o2.name)?-1:(o1.pop>o2.pop)?-1:(o1.pop<o2.pop)?1:0
  4581.        })
  4582.        // console.log(list_output)
  4583.        let text_output=""
  4584.        for(let i=0;i<list_output.length;i++){
  4585.            text_output+=`${list_output[i].type}, ${list_output[i].coord}, k${getContinent(list_output[i].coord)}, ${list_output[i].name}, ${list_output[i].pop}, ${list_output[i].date.trim()}\n`
  4586.        
  4587.            if(i<list_output.length-1){
  4588.                if(list_output[i].name!=list_output[i+1].name){
  4589.                    text_output+="\n\n"
  4590.                }
  4591.            }
  4592.        
  4593.        }
  4594.        // console.log(text_output)
  4595.  
  4596.        let html_result=`
  4597.        <center><div id="table_results" style="height:700px;width:700px;overflow:auto">
  4598.            <textarea cols="80" rows="80">${text_output}</textarea>
  4599.        </div></center>
  4600.        `
  4601.  
  4602.        Dialog.show("content",html_result)
  4603.  
  4604.    })
  4605.    
  4606.    $("#btn_def_coord").on("click",function(){
  4607.        let tribes=Array.from(document.getElementById("input_filter_tribe").value.split(",")).map(e=>e.trim().toLowerCase()).filter(element => {
  4608.            return element !== '';
  4609.          });
  4610.        
  4611.        let list_output=[]
  4612.        console.log("tribes",tribes)
  4613.  
  4614.        Array.from(map_search.keys()).forEach(key=>{
  4615.            try {
  4616.                let obj=map_search.get(key)
  4617.                let troop_at_home=obj["troopsAtHome_"+key]
  4618.                let pop=0;
  4619.                let time_report_home=obj["time_report_home_"+key]
  4620.                // console.log("troopsAtHome_"+key)
  4621.    
  4622.    
  4623.            
  4624.    
  4625.                if(troop_at_home!=undefined){
  4626.                    for(let i=0;i<troop_at_home.length;i++){
  4627.                        if(troop_at_home[i].type=="spear" || troop_at_home[i].type=="sword" || troop_at_home[i].type=="archer" || troop_at_home[i].type=="heavy"){
  4628.                            pop+=troop_at_home[i].count*troopsPop[troop_at_home[i].type]
  4629.                        }
  4630.                    }
  4631.                }
  4632.                else{
  4633.                    pop=-1
  4634.                    time_report_home="none"
  4635.                }  
  4636.                // console.log("coord: "+obj.coordAttacker)
  4637.                // console.log(infoVillages.get(obj.coordAttacker))
  4638.                if( tribemates.includes(obj.nameAttacker.toLowerCase())==false && obj.typeAttacker.includes("def")  && key.includes(obj.coordAttacker) &&
  4639.                    (tribes.includes(infoVillages.get(obj.coordAttacker).tribeName.toLowerCase()) || tribes.length == 0  )){
  4640.                    list_output.push({
  4641.                        type:"def",
  4642.                        coord:obj.coordAttacker,
  4643.                        name:obj.nameAttacker,
  4644.                        date:time_report_home,
  4645.                        pop:pop
  4646.                    })
  4647.                }
  4648.                else if( tribemates.includes(obj.nameDefender.toLowerCase())==false && obj.typeDefender.includes("def") && key.includes(obj.coordDefender) &&
  4649.                        (tribes.includes(infoVillages.get(obj.coordDefender).tribeName.toLowerCase()) || tribes.length == 0 )){
  4650.                          
  4651.                    list_output.push({
  4652.                        type:"def",
  4653.                        coord:obj.coordDefender,
  4654.                        name:obj.nameDefender,
  4655.                        date:time_report_home,
  4656.                        pop:pop
  4657.                    })
  4658.                }
  4659.            } catch (error) {
  4660.                console.log("key: "+ key+ "not found")
  4661.            }
  4662.    
  4663.  
  4664.        })
  4665.        list_output.sort((o1,o2)=>{
  4666.            return (o1.name>o2.name)?1:(o1.name<o2.name)?-1:(o1.pop>o2.pop)?-1:(o1.pop<o2.pop)?1:0
  4667.        })
  4668.        // console.log(list_output)
  4669.        let text_output=""
  4670.        for(let i=0;i<list_output.length;i++){
  4671.            text_output+=`${list_output[i].type}, ${list_output[i].coord}, k${getContinent(list_output[i].coord)}, ${list_output[i].name}, ${list_output[i].pop}, ${list_output[i].date.trim()}\n`
  4672.        
  4673.            if(i<list_output.length-1){
  4674.                if(list_output[i].name!=list_output[i+1].name){
  4675.                    text_output+="\n\n"
  4676.                }
  4677.            }
  4678.        
  4679.        }
  4680.        // console.log(text_output)
  4681.  
  4682.        let html_result=`
  4683.        <center><div id="table_results" style="height:700px;width:700px;overflow:auto">
  4684.            <textarea cols="80" rows="80">${text_output}</textarea>
  4685.        </div></center>
  4686.        `
  4687.  
  4688.        Dialog.show("content",html_result)
  4689.  
  4690.    })
  4691.    
  4692.  
  4693.  
  4694.  
  4695.  
  4696.    $("#btn_stack_coord").on("click",function(){
  4697.        let list_output=[]
  4698.        let thresholdStack=parseInt(document.getElementById("input_stacked").value)
  4699.        thresholdStack=(Number.isNaN(thresholdStack)==true || thresholdStack<0)?0:thresholdStack
  4700.        console.log(thresholdStack)
  4701.  
  4702.        Array.from(map_search.keys()).forEach(key=>{
  4703.            let tribes=Array.from(document.getElementById("input_filter_tribe").value.split(",")).map(e=>e.trim().toLowerCase()).filter(element => {
  4704.                return element !== '';
  4705.            });
  4706.              
  4707.            try {
  4708.                let obj=map_search.get(key)
  4709.                let troop_at_home=obj["troopsAtHome_"+key]
  4710.                let pop=0;
  4711.                let time_report_home=obj["time_report_home_"+key]
  4712.                console.log("troopsAtHome_"+key)
  4713.    
  4714.                if(troop_at_home!=undefined){
  4715.                    for(let i=0;i<troop_at_home.length;i++){
  4716.                        if(troop_at_home[i].type=="spear" || troop_at_home[i].type=="sword" || troop_at_home[i].type=="archer" || troop_at_home[i].type=="heavy"){
  4717.                            pop+=troop_at_home[i].count*troopsPop[troop_at_home[i].type]
  4718.                        }
  4719.                    }
  4720.                }
  4721.                else{
  4722.                    pop=-1
  4723.                    time_report_home="none"
  4724.                }
  4725.                    
  4726.                if( tribemates.includes(obj.nameAttacker.toLowerCase())==false && pop>thresholdStack && key.includes(obj.coordAttacker) &&
  4727.                    (tribes.includes(infoVillages.get(obj.coordAttacker).tribeName.toLowerCase()) || tribes.length == 0)){
  4728.                    list_output.push({
  4729.                        type:obj.typeAttacker,
  4730.                        coord:obj.coordAttacker,
  4731.                        name:obj.nameAttacker,
  4732.                        date:time_report_home,
  4733.                        pop:pop
  4734.                    })
  4735.                }
  4736.                else if( tribemates.includes(obj.nameDefender.toLowerCase())==false && pop>thresholdStack && key.includes(obj.coordDefender) &&
  4737.                    (tribes.includes(infoVillages.get(obj.coordDefender).tribeName.toLowerCase()) || tribes.length == 0)){
  4738.                    list_output.push({
  4739.                        type:obj.typeDefender,
  4740.                        coord:obj.coordDefender,
  4741.                        name:obj.nameDefender,
  4742.                        date:time_report_home,
  4743.                        pop:pop
  4744.                    })
  4745.                }
  4746.            } catch (error) {
  4747.                
  4748.            }
  4749.  
  4750.        })
  4751.        list_output.sort((o1,o2)=>{
  4752.            return (o1.name>o2.name)?1:(o1.name<o2.name)?-1:(o1.pop>o2.pop)?-1:(o1.pop<o2.pop)?1:0
  4753.        })
  4754.        console.log(list_output)
  4755.        let text_output=""
  4756.        for(let i=0;i<list_output.length;i++){
  4757.            text_output+=`${list_output[i].type}, ${list_output[i].coord}, k${getContinent(list_output[i].coord)}, ${list_output[i].name}, ${list_output[i].pop}, ${list_output[i].date.trim()}\n`
  4758.        
  4759.            if(i<list_output.length-1){
  4760.                if(list_output[i].name!=list_output[i+1].name){
  4761.                    text_output+="\n\n"
  4762.                }
  4763.            }
  4764.        
  4765.        }
  4766.        console.log(text_output)
  4767.  
  4768.        let html_result=`
  4769.        <center><div id="table_results" style="height:800px;width:800px;overflow:auto">
  4770.            <textarea cols="80" rows="80">${text_output}</textarea>
  4771.        </div></center>
  4772.        `
  4773.  
  4774.        Dialog.show("content",html_result)
  4775.  
  4776.    })
  4777.  
  4778.  
  4779.  
  4780.  
  4781. }
  4782.    
  4783.  
  4784. //////////////////////////////////////////////////////search reports /////////////////////////////////////////////////////////////////
  4785. async function databaseDetails(){
  4786.    [
  4787.        mapReports,
  4788.        mapHistoryUpload,
  4789.        mapIncomings,
  4790.        mapSupport,
  4791.        mapAttack,
  4792.        troopsHome,
  4793.    
  4794.    ]=await Promise.all([
  4795.        readFileDropbox(filename_reports),
  4796.        readFileDropbox(filename_history_upload),
  4797.        readFileDropbox(filename_incomings),
  4798.        readFileDropbox(filename_support),
  4799.        readFileDropbox(filename_commands_attack),
  4800.        readFileDropbox(filename_troops_home),
  4801.  
  4802.    
  4803.    ]).catch(err=>{alert(err)})
  4804.  
  4805.    let data_attack_batch = await Promise.all(commandsAttacksPromises).catch(err=>{alert(err)})
  4806.    let data_support_batch = await Promise.all(supportPromises).catch(err=>{alert(err)})
  4807.  
  4808.  
  4809.    ////////////////////////////REPORTS DATA/////////////////////////////////////////////////
  4810.    let sizeReportsCompressedDB = formatBytes(new TextEncoder().encode(await mapReports.text()).length)
  4811.    let sizeReportDecompressedDB
  4812.    try {
  4813.        let decompressedData = await decompress(await mapReports.arrayBuffer() , 'gzip');  
  4814.        sizeReportDecompressedDB = formatBytes(new TextEncoder().encode(decompressedData).length)
  4815.        mapReports=new Map( JSON.parse(decompressedData));
  4816.    } catch (error) {
  4817.        console.log("erorrr map report from dropbox")
  4818.        mapReports=new Map()
  4819.    }
  4820.  
  4821.  
  4822.    ////////////////////////////REPORTS HISTORY DATA/////////////////////////////////////////////////
  4823.    let sizeReportsHistoryCompressedDB = formatBytes(new TextEncoder().encode(await mapHistoryUpload.text()).length)
  4824.    let sizeReportHistoryDecompressedDB
  4825.    try {
  4826.        let decompressedData = await decompress(await mapHistoryUpload.arrayBuffer() , 'gzip');  
  4827.        sizeReportHistoryDecompressedDB = formatBytes(new TextEncoder().encode(decompressedData).length)
  4828.        mapHistoryUpload=new Map( JSON.parse(decompressedData));
  4829.    } catch (error) {
  4830.        console.log("erorr map history upload from dropbox")
  4831.        mapHistoryUpload=new Map()
  4832.    }
  4833.  
  4834.    ////////////////////////////INCOMINGS DATA/////////////////////////////////////////////////
  4835.    let sizeIncomingsCompressedDB = formatBytes(new TextEncoder().encode(await mapIncomings.text()).length)
  4836.    let sizeIncomingsDecompressedDB
  4837.    try {
  4838.        let decompressedData = await decompress(await mapIncomings.arrayBuffer() , 'gzip');  
  4839.        sizeIncomingsDecompressedDB = formatBytes(new TextEncoder().encode(decompressedData).length)
  4840.        mapIncomings=new Map( JSON.parse(decompressedData));
  4841.    } catch (error) {
  4842.        console.log("erorrr map report from dropbox")
  4843.        mapIncomings=new Map()
  4844.    }
  4845.  
  4846.    ////////////////////////////TROOPS HOME DATA/////////////////////////////////////////////////
  4847.    let sizeTroopsHomeCompressedDB = formatBytes(new TextEncoder().encode(await troopsHome.text()).length)
  4848.    let sizeTroopsHomeDecompressedDB
  4849.    try {
  4850.        let decompressedData = await decompress(await troopsHome.arrayBuffer() , 'gzip');  
  4851.        sizeTroopsHomeDecompressedDB = formatBytes(new TextEncoder().encode(decompressedData).length)
  4852.        troopsHome=new Map( JSON.parse(decompressedData));
  4853.    } catch (error) {
  4854.        console.log("erorr map history upload from dropbox")
  4855.        troopsHome=new Map()
  4856.    }
  4857.  
  4858.  
  4859.    ////////////////////////////SUPPORT DATA/////////////////////////////////////////////////
  4860.    let map_support_dropbox, map_troops_home_dropbox
  4861.    let sizeSupportCompressedDB, sizeSupportDecompressedDB
  4862.    let countSupportCompressed = 0, countSupportDecompressed = 0
  4863.  
  4864.    try {
  4865.        let decompressedData = await decompress(await mapSupport.arrayBuffer() , 'gzip');  
  4866.        map_support_dropbox=new Map(JSON.parse(decompressedData)[0])
  4867.        map_troops_home_dropbox =new Map(JSON.parse(decompressedData)[1])  
  4868.  
  4869.        countSupportCompressed += new TextEncoder().encode(await mapSupport.text()).length
  4870.        countSupportDecompressed += new TextEncoder().encode(decompressedData).length
  4871.    } catch (error) {
  4872.        console.log("erorr map report from dropbox")
  4873.        map_support_dropbox=new Map()
  4874.        map_troops_home_dropbox=new Map()
  4875.    }
  4876.  
  4877.    for(let i=0;i<data_support_batch.length;i++){
  4878.        let decompressedData = await decompress(await data_support_batch[i].arrayBuffer() , 'gzip');  
  4879.  
  4880.        if(decompressedData != "[]"){
  4881.            let map_support_batch = new Map(JSON.parse(decompressedData)[0])
  4882.            let map_troops_home_batch = new Map(JSON.parse(decompressedData)[1])
  4883.  
  4884.            map_support_dropbox = new Map([...map_support_dropbox, ...map_support_batch])
  4885.            map_troops_home_dropbox = new Map([...map_troops_home_dropbox, ...map_troops_home_batch])
  4886.  
  4887.            countSupportCompressed += new TextEncoder().encode(await data_support_batch[i].text()).length
  4888.            countSupportDecompressed += new TextEncoder().encode(decompressedData).length
  4889.        }      
  4890.  
  4891.    }
  4892.    sizeSupportCompressedDB = formatBytes(countSupportCompressed)
  4893.    sizeSupportDecompressedDB = formatBytes(countSupportDecompressed)
  4894.  
  4895.  
  4896.  
  4897.    ////////////////////////////ATTACKS DATA/////////////////////////////////////////////////
  4898.    let sizeAttackCompressedDB, sizeAttackDecompressedDB
  4899.    let countAttackCompressed = 0, countAttackDecompressed = 0
  4900.    try {
  4901.        let decompressedData = await decompress(await data_attack.arrayBuffer() , 'gzip');  
  4902.        mapAttack=new Map(JSON.parse(decompressedData))
  4903.  
  4904.        countAttackCompressed += new TextEncoder().encode(await mapAttack.text()).length
  4905.        countAttackDecompressed += new TextEncoder().encode(decompressedData).length
  4906.  
  4907.    } catch (error) {
  4908.        console.log("erorr map attack from dropbox")
  4909.        mapAttack=new Map()
  4910.    }
  4911.  
  4912.    for(let i=0;i<data_attack_batch.length;i++){
  4913.        let decompressedData = await decompress(await data_attack_batch[i].arrayBuffer() , 'gzip');  
  4914.  
  4915.        if(data_attack_batch[i] != "[]"){
  4916.            let map_attacks_batch = new Map(JSON.parse(decompressedData))
  4917.            mapAttack = new Map([...mapAttack, ...map_attacks_batch])
  4918.  
  4919.            countAttackCompressed += new TextEncoder().encode(await data_attack_batch[i].text()).length
  4920.            countAttackDecompressed += new TextEncoder().encode(decompressedData).length
  4921.        }  
  4922.    }
  4923.    sizeAttackCompressedDB = formatBytes(countAttackCompressed)
  4924.    sizeAttackDecompressedDB = formatBytes(countAttackDecompressed)
  4925.  
  4926.  
  4927.  
  4928.  
  4929.  
  4930.  
  4931.  
  4932.  
  4933.  
  4934.  
  4935.    // console.log(`sizeReportsCompressedDB: ${sizeReportsCompressedDB}`)
  4936.    // console.log(`sizeReportDecompressedDB: ${sizeReportDecompressedDB}`)
  4937.  
  4938.    // console.log(`sizeReportsHistoryCompressedDB: ${sizeReportsHistoryCompressedDB}`)
  4939.    // console.log(`sizeReportHistoryDecompressedDB: ${sizeReportHistoryDecompressedDB}`)
  4940.  
  4941.    // console.log(`sizeIncomingsCompressedDB: ${sizeIncomingsCompressedDB}`)
  4942.    // console.log(`sizeIncomingsDecompressedDB: ${sizeIncomingsDecompressedDB}`)
  4943.  
  4944.    // console.log(`sizeSupportCompressedDB: ${sizeSupportCompressedDB}`)
  4945.    // console.log(`sizeSupportDecompressedDB: ${sizeSupportDecompressedDB}`)
  4946.  
  4947.    // console.log(`sizeAttackCompressedDB: ${sizeAttackCompressedDB}`)
  4948.    // console.log(`sizeAttackDecompressedDB: ${sizeAttackDecompressedDB}`)
  4949.  
  4950.    // console.log(`sizeTroopsHomeCompressedDB: ${sizeTroopsHomeCompressedDB}`)
  4951.    // console.log(`sizeTroopsHomeDecompressedDB: ${sizeTroopsHomeDecompressedDB}`)
  4952.  
  4953.    let listResult = [
  4954.        {
  4955.            name: "Reports",
  4956.            compressed: sizeReportsCompressedDB,
  4957.            decompresed: sizeReportDecompressedDB,
  4958.        },
  4959.        {
  4960.            name: "ReportsHistory",
  4961.            compressed: sizeReportsHistoryCompressedDB,
  4962.            decompresed: sizeReportHistoryDecompressedDB,
  4963.        },
  4964.        {
  4965.            name: "Incomings",
  4966.            compressed: sizeIncomingsCompressedDB,
  4967.            decompresed: sizeIncomingsDecompressedDB,
  4968.        },
  4969.        {
  4970.            name: "Supports",
  4971.            compressed: sizeSupportCompressedDB,
  4972.            decompresed: sizeSupportDecompressedDB,
  4973.        },
  4974.        {
  4975.            name: "Attacks",
  4976.            compressed: sizeAttackCompressedDB,
  4977.            decompresed: sizeAttackDecompressedDB,
  4978.        },
  4979.        {
  4980.            name: "Troops",
  4981.            compressed: sizeTroopsHomeCompressedDB,
  4982.            decompresed: sizeTroopsHomeDecompressedDB,
  4983.        },
  4984.    ]
  4985.  
  4986.  
  4987.    let html_result=`
  4988.    <center>
  4989.        <h2 style="margin-top: 20px"> Database size details </h2>
  4990.    </center>
  4991.    <div id="table_database_details" style="height:300px;width:400px;display: flex;justify-content: center;margin-top: -50px">
  4992.        <table style ="border: 1px solid black;border-collapse: collapse;align-self: center">
  4993.        <tr>
  4994.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;font-weight: bold;padding:10px">Name</td>
  4995.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;font-weight: bold;padding:10px">Compressed size</td>
  4996.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;font-weight: bold;padding:10px">Decompressed size</td>
  4997.        </tr>`
  4998.  
  4999.    for(let i=0;i<listResult.length;i++){
  5000.        html_result += `
  5001.        <tr>
  5002.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${listResult[i].name}</td>
  5003.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${listResult[i].compressed}</td>
  5004.            <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${listResult[i].decompresed}</td>
  5005.        </tr>
  5006.        `
  5007.    }
  5008.  
  5009.    html_result +=
  5010.        `</table>
  5011.    </div>
  5012.    `
  5013.  
  5014.    Dialog.show("content",html_result)
  5015.  
  5016. }
  5017.  
  5018.  
  5019.  
  5020. ///////////////////////////////////////////////////////create table for view report//////////////////////////////////////////////////////
  5021. function createReport(obj){
  5022.    var tableHTML=``;
  5023.    if(obj.attackingArmy!=undefined){    
  5024.        tableHTML=`
  5025.        <tbody>
  5026.            <tr>
  5027.                <td>Battle time </td>
  5028.                <td>`+ obj.time_report +`</td>
  5029.            </tr>
  5030.            <tr>
  5031.                <td colspan="2" valign="top" height="160" style="border: solid 1px ; padding 4px;" class="report_ReportAttack">
  5032.                    <table id="attack_info_att" width=100% style="border: 1px solid #DED3B9">
  5033.                        <tbody>
  5034.                            <tr>
  5035.                                <th style="width:20%">Attacker:</th>
  5036.                                <th >`+obj.nameAttacker+`</th>
  5037.                            </tr>
  5038.                            <tr>
  5039.                                <td >Origin:</td>
  5040.                                <td >`+obj.coordAttacker+`</td>
  5041.                            </tr>
  5042.                            <tr>
  5043.                                <td colspan="2" style="padding:0px">`+
  5044.                                createTableTroupes(obj.attackingArmy,obj.attackingArmyLosses)+
  5045.                                `</td>
  5046.                            </tr>
  5047.                        </tbody>
  5048.                    </table>
  5049.                </td>
  5050.            </tr>`
  5051.    }
  5052.    if(obj.defendingArmy!=undefined){
  5053.        tableHTML+= `
  5054.                <tr>
  5055.                    <td colspan="2" valign="top" height="160" style="border: solid 1px ; padding 4px;"  >
  5056.                        <table id="attack_info_def" width=100% style="border: 1px solid #DED3B9">
  5057.                            <tbody>
  5058.                                <tr>
  5059.                                    <th style="width:20%">Defender:</th>
  5060.                                    <th >`+obj.nameDefender+`</th>
  5061.                                </tr>
  5062.                                <tr>
  5063.                                    <td >Origin:</td>
  5064.                                    <td >`+obj.coordDefender+`</td>
  5065.                                </tr>
  5066.                                <tr>
  5067.                                    <td colspan="2" style="padding:0px">`+
  5068.                                    createTableTroupes(obj.defendingArmy,obj.defendingArmyLosses)+
  5069.                                    `</td>
  5070.                                </tr>
  5071.                            </tbody>
  5072.                        </table>
  5073.                    </td>
  5074.                </tr>
  5075.                    `
  5076.    }
  5077.  
  5078.    if(obj.travelingTroops!=undefined){
  5079.        tableHTML+= `
  5080.                <tr>  
  5081.                    <td colspan="2" valign="top" height="160" style="border: solid 1px ; padding 4px;">
  5082.                        <table id="attack_spy_away" width=100% style="border: 1px solid #DED3B9; width:100%; margin-top:5px;">
  5083.                            <tbody>
  5084.                                <tr>
  5085.                                    <th colspan="2">Units outside of village:</th>
  5086.                                </tr>
  5087.  
  5088.                                <tr>
  5089.                                    <td colspan="2" >`+
  5090.                                    createTableTroupesAway(obj.travelingTroops)+
  5091.                                    `</td>
  5092.                                </tr>
  5093.                            </tbody>
  5094.                        </table>
  5095.                    </td>
  5096.                </tr>
  5097.                    `
  5098.    }  
  5099.    if(obj.attackingArmy!=undefined){
  5100.        tableHTML+="</tbody>"
  5101.    }
  5102.  
  5103.    return tableHTML
  5104. }
  5105.  
  5106. function createTableTroupes(totalArmy,lostArmy){
  5107.    let tableHTML=`
  5108.    <table class="vis" >
  5109.        <tbody>
  5110.            <tr class="center">
  5111.                <td width="20"></td>`
  5112.  
  5113.        let units=game_data.units
  5114.        for(let i=0;i<totalArmy.length;i++){
  5115.            if(units[i]!="militia"){
  5116.                if(totalArmy[i].count==0 )
  5117.                    tableHTML+=`<td width="35"><img src="https://dsen.innogamescdn.com/asset/3ec301e5/graphic/unit/unit_`+units[i]+`.png" alt class="faded"</td>`
  5118.                 else
  5119.                     tableHTML+=`<td width="35"><img src="https://dsen.innogamescdn.com/asset/3ec301e5/graphic/unit/unit_`+units[i]+`.png"</td>`
  5120.             }
  5121.         }
  5122.         tableHTML+="</tr>"
  5123.         tableHTML+=`
  5124.         <tr>
  5125.             <td width="20">Quantity:</td>`
  5126.         for(let i=0;i<totalArmy.length;i++){
  5127.             if(units[i]!="militia"){
  5128.                 if(totalArmy[i].count==0)
  5129.                     tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+units[i]+` hidden">`+totalArmy[i].count+"</td>"
  5130.                 else
  5131.                     tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+units[i]+`">`+totalArmy[i].count+"</td>"
  5132.             }
  5133.         }
  5134.         tableHTML+="</tr>"
  5135.         tableHTML+=`
  5136.         <tr>
  5137.             <td width="20">Losses:</td>`
  5138.         for(let i=0;i<lostArmy.length;i++){
  5139.             if(units[i]!="militia"){
  5140.                 if(lostArmy[i].count==0)
  5141.                     tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+units[i]+` hidden">`+lostArmy[i].count+"</td>"
  5142.                 else
  5143.                     tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+units[i]+`">`+lostArmy[i].count+"</td>"
  5144.             }
  5145.         }
  5146.         tableHTML+="</tr>"
  5147.  
  5148.  
  5149.  
  5150.  
  5151.         tableHTML+="</tr></tbody></table>"
  5152.         return tableHTML
  5153. }
  5154.  
  5155.  
  5156. function createTableTroupesAway(totalArmy){
  5157.     let tableHTML=`
  5158.     <table class="vis">
  5159.         <tbody>
  5160.             <tr class="center">`
  5161.  
  5162.         let units=game_data.units
  5163.         Object.keys(totalArmy).forEach(key=>{
  5164.             if(totalArmy[key]==0)
  5165.                 tableHTML+=`<th width="35"><img src="https://dsen.innogamescdn.com/asset/3ec301e5/graphic/unit/unit_`+key+`.png" alt class="faded"</th>`
  5166.             else
  5167.                 tableHTML+=`<th width="35"><img src="https://dsen.innogamescdn.com/asset/3ec301e5/graphic/unit/unit_`+key+`.png"</th>`
  5168.  
  5169.         })
  5170.  
  5171.        
  5172.         tableHTML+="</tr>"
  5173.         tableHTML+=`<tr>`
  5174.         Object.keys(totalArmy).forEach(key=>{
  5175.             if(totalArmy[key]==0)
  5176.                 tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+key+` hidden">`+totalArmy[key]+"</td>"
  5177.             else
  5178.                 tableHTML+=`<td style="text-align:center" class="unit-item unit-item-`+key+`">`+totalArmy[key]+"</td>"
  5179.  
  5180.         })
  5181.         tableHTML+="</tr>"
  5182.  
  5183.         tableHTML+="</tr></tbody></table>"
  5184.         return tableHTML
  5185. }
  5186.  
  5187. function createTableIncomings(list){
  5188.     let serverTime=document.getElementById("serverTime").innerText
  5189.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  5190.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  5191.     let date_current=new Date(serverDate+" "+serverTime).getTime()
  5192.     let html_incomings=`
  5193.         <tbody>
  5194.         <tr>
  5195.             <th><img src="https://dsen.innogamescdn.com/asset/056b9c0b/graphic/unit/att.png"></<th>
  5196.             <th >speed</th>
  5197.             <th colspan="2">destination</th>
  5198.             <th colspan="2">origin</th>
  5199.             <th >Arrival time</th>
  5200.             <th >Arrives in</th>
  5201.         </tr>`
  5202.        
  5203.         for(let i=0;i<list.length;i++){
  5204.             // console.log(list[i])
  5205.             let labelName
  5206.             // console.log(list[i].labelName)
  5207.             if(list[i].labelName=="none")
  5208.                 labelName="https://dsen.innogamescdn.com/asset/056b9c0b/graphic/delete.png"
  5209.             else
  5210.                 labelName=`https://dsen.innogamescdn.com/asset/a9e85669/graphic/unit/tiny/${list[i].labelName}`
  5211.  
  5212.             // console.log(list[i].labelName)
  5213.             let arrived=new Date(list[i].date_land).getTime()  
  5214.             if(arrived>date_current){
  5215.                 html_incomings+=`
  5216.                     <tr>
  5217.                         <td><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/${list[i].type_attack}"> </td>
  5218.                         <td><img src="${labelName}"> </td>
  5219.                         <td><a href="${game_data.link_base_pure}info_village&id=${list[i].id_coord_def}"> (${list[i].coord_def})</a>  </td>
  5220.                         <td><a href="${game_data.link_base_pure}info_player&id=${list[i].id_player_def}"> ${list[i].player_def}</a>  </td>
  5221.                         <td><a href="${game_data.link_base_pure}info_village&id=${list[i].id_coord_off}">(${list[i].coord_off}) </a> </td>
  5222.                         <td><a href="${game_data.link_base_pure}info_player&id=${list[i].id_player_off}">${list[i].player_off} </a> </td>
  5223.                         <td>${list[i].date_land.split(" ")[0]} <b>${list[i].date_land.split(" ")[1]}</b></td>
  5224.                         <td date-time=${arrived} class="counterTime"></td>
  5225.                     </tr>
  5226.                 `
  5227.             }
  5228.         }
  5229.         html_incomings+="</tbody>"
  5230.         return html_incomings
  5231. }
  5232.  
  5233. function counterTime(){
  5234.    
  5235.     window.setInterval(()=>{
  5236.  
  5237.         $(".counterTime").each((index,item)=>{
  5238.             let serverTime=document.getElementById("serverTime").innerText
  5239.             let serverDate=document.getElementById("serverDate").innerText.split("/")
  5240.             serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  5241.             let date_current=new Date(serverDate+" "+serverTime).getTime()
  5242.             // console.log(date_current)
  5243.            
  5244.             let time=parseInt(item.getAttribute("date-time"))
  5245.             let hours=("0"+parseInt((time-date_current)/(3600*1000))).slice(-3);
  5246.             let minutes=("0"+parseInt(((time-date_current)/(60*1000)%60))).slice(-2);
  5247.             let seconds=( "0"+parseInt((((time-date_current)/1000)%60))).slice(-2);
  5248.             result=hours+":"+minutes+":"+seconds
  5249.             item.innerText=result
  5250.         })
  5251.     },5000)
  5252.    
  5253.  
  5254. }
  5255.  
  5256.  
  5257. ////////////////////////////////////////////////////////get speed world///////////////////////////////////////////////////
  5258.  
  5259.  
  5260. function getSpeedConstant() { //Get speed constant (world speed * unit speed) for world
  5261.     if (localStorage.getItem(game_data.world+"speedWorld") !== null) {
  5262.         let obj=JSON.parse(localStorage.getItem(game_data.world+"speedWorld"))
  5263.         console.log("speed world already exist")
  5264.         return obj
  5265.     }
  5266.     else { //Get data from xml and save it in localStorage to avoid excessive XML requests to server
  5267.             let currentHtml=document.body.innerHTML
  5268.             document.body.innerHTML = httpGet("/interface.php?func=get_config") //Load world data
  5269.             let obj={}
  5270.             let worldSpeed = Number(document.getElementsByTagName("speed")[0].innerHTML)
  5271.             let unitSpeed = Number(document.getElementsByTagName("unit_speed")[0].innerHTML);
  5272.             obj.unitSpeed=unitSpeed
  5273.             obj.worldSpeed=worldSpeed
  5274.             document.body.innerHTML=currentHtml
  5275.             localStorage.setItem(game_data.world+"speedWorld",JSON.stringify(obj));
  5276.             console.log("save speed world")
  5277.         return obj
  5278.     }
  5279. }
  5280.  
  5281.  
  5282. /////////////////////////////////////////////////////// interface for get all tr from incomings page/////////////////////////////////////////
  5283. function setIntervalIncomings(){
  5284.     htmlInc = `
  5285.     <div id="div_container" class="ui-widget-content div_remove" style="width:600px;background-color:${backgroundColor};cursor:move;z-index:50;">
  5286.         <div class="close-btn" btn_close="btn_close" onclick="closeWindow()" style="position:absolute;top:10px;right: 10px;"><b><a href=#><font color="${titleColor}">X</font></b></a></div>
  5287.         <h2><center style="margin:10px"><u><font color="${titleColor}">Get all incomings</font></u></center></h2>
  5288.         <table id="table_upload" class="" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor}">
  5289.         <tr>
  5290.         <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5291.             <p><center style="margin:10px"><font color="${titleColor}">Between hours   </font></center></p>
  5292.         </td>
  5293.         <td style="text-align:center; width:auto; background-color:${headerColor}">
  5294.         <p><center style=""><input type="number" id="id_start" size="5" style="text-align:center" class=" input-nicer show" value="0"><br><br></center></p>
  5295.         </td>
  5296.         <td style="text-align:center; width:auto; background-color:${headerColor}">
  5297.         <p><center style=""><input type="number" id="id_stop" size="5" style="text-align:center" class=" input-nicer show" value="100"><br><br></center></p>
  5298.         </td>
  5299.  
  5300.         </tr>      
  5301.         </table>
  5302.         <center style="margin:10px"><u><input class="btn" type="button" id="btn_village" onclick="getTrIncomings()" value="Start"></center>
  5303.    
  5304.  
  5305.    
  5306.     </div>
  5307.     `;
  5308.     ////////////////////////////////////////add and remove window from page/////////////////////////////////////////////////////////////////
  5309.     $("#div_container").remove()
  5310.     $("#contentContainer").eq(0).prepend(htmlInc);
  5311.     $("#mobileContent").eq(0).prepend(htmlInc);
  5312.  
  5313.     if(game_data.device=="desktop"){
  5314.         $("#div_container").css("position","fixed");
  5315.         $("#div_container").draggable();
  5316.     }
  5317.     $('#id_start').on('input',function(e){
  5318.         let value=this.value;
  5319.         localStorage.setItem(game_data.world+"startInc",value)
  5320.     });
  5321.     $('#id_stop').on('input',function(e){
  5322.         let value=this.value;
  5323.         localStorage.setItem(game_data.world+"stopInc",value)
  5324.     });
  5325.     if(localStorage.getItem(game_data.world+"startInc")!=null)
  5326.         $('#id_start').val(localStorage.getItem(game_data.world+"startInc"))
  5327.     if(localStorage.getItem(game_data.world+"stopInc")!=null)
  5328.         $('#id_stop').val(localStorage.getItem(game_data.world+"stopInc"))
  5329.  
  5330.  
  5331. }
  5332.  
  5333. //////////////////////////////////////////////get a list with all tr ///////////////////////////////////////////////////////////////////
  5334. async function getTrIncomings(){
  5335.  
  5336.     let map_reports_dropbox
  5337.     if(localStorage.getItem(game_data.world+"get_only_fakes")=="true" || localStorage.getItem(game_data.world+"get_def_vills")=="true"){
  5338.         [map_reports_dropbox,status]=await Promise.all([readFileDropbox(filename_reports),insertlibraryLocalBase()]).catch(err=>{alert(err)})
  5339.  
  5340.     /////////merge maps for reports
  5341.     try {
  5342.         let decompressedData = await decompress(await map_reports_dropbox.arrayBuffer() , 'gzip');  
  5343.         map_reports_dropbox=new Map( JSON.parse(decompressedData));
  5344.     } catch (error) {
  5345.         console.log("erorrr map report from dropbox")
  5346.         map_reports_dropbox=new Map()
  5347.     }
  5348.  
  5349.     //if there database is stored locally
  5350.     if(await localBase.getItem(game_data.world+"reports")!=undefined){
  5351.         try{
  5352.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "reports"))
  5353.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  5354.    
  5355.             let map_localBase=new Map( JSON.parse(decompressedData));
  5356.             console.log("map_localBase history upload",map_localBase)
  5357.             map_reports_dropbox=new Map([...map_localBase, ...map_reports_dropbox])
  5358.  
  5359.         } catch (error) {}
  5360.     }
  5361.  
  5362.  
  5363.  
  5364.     }
  5365.  
  5366.     let limitPopFake=parseInt(document.getElementById("input_pop_fake2").value)
  5367.     limitPopFake=(Number.isNaN(limitPopFake)  || limitPopFake < 0 )? 0:limitPopFake
  5368.  
  5369.     //get pages for all incoming
  5370.     let list_pages=[]
  5371.     let start=parseInt(document.getElementById("id_start").value)
  5372.     let stop=parseInt(document.getElementById("id_stop").value)
  5373.  
  5374.     if(document.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  5375.         Array.from(document.getElementsByClassName("vis")[1].getElementsByTagName("select")[0]).forEach(function(item){
  5376.             list_pages.push(item.value)
  5377.         })
  5378.         list_pages.pop();
  5379.     }
  5380.     else if(document.getElementsByClassName("paged-nav-item").length>0){//all pages from the current folder
  5381.         let nr=0;
  5382.         Array.from(document.getElementsByClassName("paged-nav-item")).forEach(function(item){
  5383.             let current=item.href;
  5384.             current=current.split("page=")[0]+"page="+nr
  5385.             nr++;
  5386.             list_pages.push(current);
  5387.         })
  5388.     }
  5389.     else{
  5390.         let current_link=window.location.href;
  5391.         list_pages.push(current_link);
  5392.     }
  5393.     list_pages=list_pages.reverse();
  5394.     console.log(list_pages)
  5395.  
  5396.     // go to every page and get incoming
  5397.     let rows=[]
  5398.     function ajaxRequest (urls) {
  5399.         let current_url
  5400.         let startAjax=new Date().getTime();
  5401.         if(urls.length>0){
  5402.             current_url=urls.pop()
  5403.         }
  5404.         else{
  5405.             current_url="stop"
  5406.         }
  5407.         console.log(current_url)
  5408.         if (urls.length >= 0 && current_url!="stop") {
  5409.             $.ajax({
  5410.                 url: current_url,
  5411.                 method: 'get',
  5412.                 success: (data) => {
  5413.                     document.body.innerHTML=data
  5414.                     var table_incomings=document.querySelectorAll(".row_a, .row_b")
  5415.                     for(let i=0;i<table_incomings.length;i++){
  5416.                         rows.push(table_incomings[i])
  5417.                     }
  5418.                     let stopAjax=new Date().getTime();
  5419.                     let diff=stopAjax-startAjax
  5420.                     console.log("wait inc: "+(200-diff))
  5421.                     window.setTimeout(function(){
  5422.                         ajaxRequest (list_pages)
  5423.                     },200-diff)
  5424.                 }
  5425.             })
  5426.            
  5427.         }
  5428.         else
  5429.         {
  5430.  
  5431.             $(".row_a").remove();
  5432.             $(".row_b").remove();
  5433.             let table_incomings=document.getElementById("incomings_table")
  5434.             let lastRow=table_incomings.children[0].children[1];
  5435.             table_incomings.children[0].children[1].remove();
  5436.             let nr_row=0;
  5437.             for(let i=0;i<rows.length;i++){
  5438.                 let hours=rows[i].children[  rows[i].children.length-1  ].innerText.split(":")[0]
  5439.                 let isFakeDef = false, isFakePop = false, isFakeReturning = false;
  5440.                 if(hours>=start && hours< stop){
  5441.                     if(localStorage.getItem(game_data.world+"get_only_fakes")=="true" || localStorage.getItem(game_data.world+"get_def_vills")=="true"){
  5442.                         let length_tr=rows[i].children.length
  5443.  
  5444.                         let coordDest=rows[i].children[1].innerText.match(/\d+\|\d+/)[0];
  5445.                         let coordOrigin=rows[i].children[2].innerText.match(/\d+\|\d+/)[0];
  5446.                         let player_id=rows[i].children[length_tr-4].children[0].href.split("player&id=")[1]//attacker's id
  5447.                         ////////////////////////////////get land time attack///////////////////////////////
  5448.  
  5449.                         //only if destination coord exist in database
  5450.                         if(map_reports_dropbox.has(coordOrigin) )
  5451.                         {
  5452.                             let idPlayer_dropbox
  5453.                             let type_dropbox
  5454.                             let nr_troupes_dropbox
  5455.            
  5456.                             var obj=map_reports_dropbox.get(coordOrigin);
  5457.                             var traveling=false
  5458.                             if(coordOrigin == obj.coordAttacker){
  5459.                                 idPlayer_dropbox=obj.attackingPlayerId;
  5460.                                 type_dropbox=obj.typeAttacker;
  5461.                                 nr_troupes_dropbox=obj.nrTroupesAttacker
  5462.                                 traveling=true;
  5463.                             }
  5464.                             else if(coordOrigin == obj.coordDefender){
  5465.                                 idPlayer_dropbox=obj.defendingPlayerId;
  5466.                                 type_dropbox=obj.typeDefender;
  5467.                                 nr_troupes_dropbox=obj.nrTroupesDefender
  5468.                                 traveling=false;
  5469.                             }
  5470.                             else{
  5471.                                 idPlayer_dropbox=obj.supporterPlayerId
  5472.                                 type_dropbox=obj.typeSupporter;
  5473.                                 nr_troupes_dropbox=obj.nrTroupesSupporter
  5474.                             }
  5475.            
  5476.                             if(idPlayer_dropbox == player_id && rows[i].children[0].getElementsByTagName("img").length==2)
  5477.                             {
  5478.  
  5479.  
  5480.                                 //calculate population
  5481.                                 let date_landing_report=new Date(obj.time_report)
  5482.                                 let distance=calcDistance(coordOrigin,coordDest);
  5483.                                 let time_attack=0;
  5484.                                 let time_land=rows[i].children[length_tr-2].innerText
  5485.                                 let date_land=new Date(getLandTime(time_land))
  5486.                                 let labelName=""
  5487.                                 if(rows[i].children[0].getElementsByTagName("img")[1]==undefined || rows[i].children[0].getElementsByTagName("img")[1]==null )
  5488.                                     labelName="ram.png"
  5489.                                 else
  5490.                                     labelName=rows[i].children[0].getElementsByTagName("img")[1].src
  5491.        
  5492.                                 if(labelName.includes("snob.png")){
  5493.                                     time_attack=nobleSpeed*distance
  5494.                                 }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  5495.                                     time_attack=ramSpeed*distance
  5496.                                 }else if(labelName.includes("sword.png")){
  5497.                                     time_attack=swordSpeed*distance
  5498.                                 }else if(labelName.includes("axe.png")){
  5499.                                     time_attack=axeSpeed *distance
  5500.                                 }
  5501.                                 if(traveling==false)
  5502.                                     time_attack=0;
  5503.        
  5504.                                 if(type_dropbox=="off"){// do something with pop
  5505.                                     // console.log(date_land.getTime())
  5506.                                     // console.log(time_attack)
  5507.                                     // console.log(date_landing_report.getTime())
  5508.                                     let timeForRecruiting = (date_land.getTime()-time_attack)-date_landing_report.getTime()
  5509.                                     nr_troupes_dropbox=calcProductionTroupes(timeForRecruiting, nr_troupes_dropbox)                            
  5510.                                     nr_troupes_dropbox=Math.round(nr_troupes_dropbox * 10 )/ 10
  5511.                                     // console.log("final "+nr_troupes_dropbox)
  5512.  
  5513.                                     if(nr_troupes_dropbox < limitPopFake)
  5514.                                         isFakePop=true
  5515.                                 }
  5516.  
  5517.                                 if(type_dropbox.includes("def") && localStorage.getItem(game_data.world+"get_def_vills")=="true"){
  5518.                                     isFakeDef=true
  5519.                                 }
  5520.                            
  5521.  
  5522.  
  5523.                                  
  5524.                                 console.log(obj.time_return)
  5525.            
  5526.                                 if(obj.time_return!=0 ){//do something if the attack is returning home
  5527.  
  5528.                                     let date_home=new Date(obj.time_return)
  5529.                                     let distance=calcDistance(coordOrigin,coordDest);
  5530.                                     let labelName=rows[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src
  5531.                                     let time_attack=0;
  5532.                                     if(labelName.includes("snob.png")){
  5533.                                         time_attack=nobleSpeed*distance
  5534.                                     }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  5535.                                         time_attack=ramSpeed*distance
  5536.                                     }else if(labelName.includes("sword.png")){
  5537.                                         time_attack=swordSpeed*distance
  5538.                                     }else if(labelName.includes("axe.png")){
  5539.                                         time_attack=axeSpeed *distance
  5540.                                     }
  5541.                                    
  5542.                                     let time_land=rows[i].children[length_tr-2].innerText
  5543.                                     let dateLand=new Date(getLandTime(time_land))
  5544.                                    
  5545.                                     time_attack=Math.round(time_attack/1000) * 1000
  5546.                        
  5547.                                     console.log("time_attack",time_attack)
  5548.  
  5549.                                     if(time_attack + date_home.getTime()>dateLand.getTime() ){
  5550.                                         isFakeReturning=true;
  5551.                                         console.log("fake from "+coordOrigin)
  5552.                                     }
  5553.                            
  5554.                                    
  5555.  
  5556.                                 }
  5557.                                
  5558.                                 if(isFakePop == true && isFakeReturning == true && localStorage.getItem(game_data.world+"get_only_fakes")=="true"){
  5559.                                     $(table_incomings).append(rows[i])
  5560.                                     nr_row++;
  5561.                                 }
  5562.                                 else if(isFakeDef == true && isFakeReturning == true && localStorage.getItem(game_data.world+"get_only_fakes")=="true"){
  5563.                                     $(table_incomings).append(rows[i])
  5564.                                     nr_row++;
  5565.                                 }
  5566.                                 else if(isFakeDef == true && localStorage.getItem(game_data.world+"get_def_vills")=="true"){
  5567.                                     $(table_incomings).append(rows[i])
  5568.                                     nr_row++;
  5569.                                 }
  5570.                              
  5571.                                
  5572.                             }
  5573.                         }
  5574.  
  5575.                        
  5576.                     }
  5577.                     else{
  5578.                         $(table_incomings).append(rows[i])
  5579.                         nr_row++;
  5580.                     }
  5581.                 }
  5582.                
  5583.  
  5584.             }
  5585.             table_incomings.children[0].children[0].children[0].innerText="Command ("+nr_row+")"
  5586.             $(table_incomings).append(lastRow)
  5587.  
  5588.             //activate renaming
  5589.             $('document').ready(function() {
  5590.                 CommandsOverview.init();
  5591.                 UI.ToolTip('.icon_village_notes');
  5592.  
  5593.                 $('.quickedit').QuickEdit({url: TribalWars.buildURL('POST', 'info_command', {ajaxaction: 'edit_other_comment', id: '__ID__'})});
  5594.                 Command.init();
  5595.             });
  5596.             UI.SuccessMessage("done")
  5597.             console.log(rows)
  5598.             showButtons();
  5599.  
  5600.         }
  5601.     }
  5602.     ajaxRequest(list_pages);
  5603.  
  5604. }
  5605.  
  5606. /////////////////////////////////////////////highlight trains->yellow, nobles->red, nukes-> green////////////////////////////////////////
  5607. function highLightIncomings(){
  5608.     try {
  5609.         let table=document.querySelectorAll(".row_a,.row_b")
  5610.         if(localStorage.getItem(game_data.world+"highlight")=="true"){
  5611.             let colors = {
  5612.                 yellow: '#ffff66',
  5613.                 red: '#ff8080',
  5614.                 green: '#4dff4d',
  5615.                 orange: '#FF5B00'
  5616.             };
  5617.             document.getElementById("btn_highlight").classList.remove("btn-confirm-no")
  5618.             document.getElementById("btn_highlight").classList.add("btn-confirm-yes")
  5619.             for(let i=0;i<table.length;i++){
  5620.                 let length_tr=table[i].children.length
  5621.                 table[i].classList.remove("selected")
  5622.                 //highlight nukes if has more than 70% pop
  5623.  
  5624.                 if(document.getElementById("id_type")!=null && table[i].firstElementChild.style.backgroundColor!="rgb(255, 255, 102)"){//is different then yellow
  5625.                     let watchTower=table[i].children[0].getElementsByTagName("img")[0].src.includes("attack_large.png")
  5626.                     let watchTowerSmall=table[i].children[0].getElementsByTagName("img")[0].src.includes("attack_small.png")
  5627.                     let hasNuke=false
  5628.                     if(table[i].getElementsByClassName("cls_type").length>0){
  5629.                         let type=table[i].getElementsByClassName("cls_type")[0].innerText
  5630.                         let pop=parseFloat(table[i].getElementsByClassName("cls_pop")[0].innerText)
  5631.                         if(((type=="off" && pop>70)|| watchTower==true) && watchTowerSmall==false){//must be tested
  5632.                             hasNuke=true;
  5633.                         }    
  5634.                     }
  5635.                     if(hasNuke==true || watchTower==true ){
  5636.                         $(table[i]).children().each(function(){
  5637.                             console.log("color")
  5638.                             $(this).css('background-color', colors.orange);
  5639.                         });
  5640.                     }
  5641.                 }
  5642.        
  5643.                 //highlight all possible trains
  5644.                 for(let j=i+1;j<table.length;j++){
  5645.  
  5646.                     //normal worlds
  5647.                     let tr1=table[i].children[length_tr-2].innerText.match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{3}/)[0]
  5648.                     let tr2=table[j].children[length_tr-2].innerText.match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{3}/)[0]
  5649.                     let time1=parseInt(tr1.split(":")[0])*3600*1000+parseInt(tr1.split(":")[1])*60*1000+parseInt(tr1.split(":")[2])*1000+parseInt(tr1.split(":")[3])
  5650.                     let time2=parseInt(tr2.split(":")[0])*3600*1000+parseInt(tr2.split(":")[1])*60*1000+parseInt(tr2.split(":")[2])*1000+parseInt(tr2.split(":")[3])
  5651.        
  5652.                     // let tr1=table[i].children[length_tr-2].innerText.match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}/)[0]
  5653.                     // let tr2=table[j].children[length_tr-2].innerText.match(/[0-9]{2}\:[0-9]{2}\:[0-9]{2}/)[0]
  5654.                     // let time1=parseInt(tr1.split(":")[0])*3600*1000+parseInt(tr1.split(":")[1])*60*1000+parseInt(tr1.split(":")[2])*1000
  5655.                     // let time2=parseInt(tr2.split(":")[0])*3600*1000+parseInt(tr2.split(":")[1])*60*1000+parseInt(tr2.split(":")[2])*1000
  5656.        
  5657.  
  5658.                     if(table[i].children[2].innerHTML==table[j].children[2].innerHTML){//if origin coord is the same
  5659.                         if(Math.abs(time1-time2)==50 || Math.abs(time1-time2)==100 || Math.abs(time1-time2)==150 || Math.abs(time1-time2)==0 ){
  5660.                             console.log(tr1+" === "+tr2)
  5661.                             console.log(time1+" === "+time2)
  5662.                             console.log("diference tr: "+(time2-time1))
  5663.        
  5664.                             $(table[i]).children().each(function(){
  5665.                                 console.log("color i")
  5666.                                 $(this).css('background-color', colors.yellow);
  5667.                             });
  5668.                             console.log(table[j])
  5669.                             $(table[j]).children().each(function(){
  5670.                                 console.log("color j")
  5671.                                 $(this).css('background-color', colors.yellow);
  5672.                             });
  5673.                             console.log(table[j])
  5674.                             break;
  5675.                         }
  5676.                     }
  5677.                     if(Math.abs(time1-time2)>200)
  5678.                         break;
  5679.                 }
  5680.  
  5681.  
  5682.  
  5683.  
  5684.  
  5685.                
  5686.                 // highlist if it is tagged as noble
  5687.                 if(table[i].children[0].getElementsByTagName("img").length==2){
  5688.                     let hasNoble=table[i].children[0].getElementsByTagName("img")[1].src.includes("snob.png")
  5689.                     if(hasNoble==true){
  5690.                         $(table[i]).children().each(function(){
  5691.                             $(this).css('background-color', colors.red);
  5692.                         });
  5693.                     }
  5694.                 }
  5695.        
  5696.             }
  5697.         }
  5698.         else{
  5699.             for(let i=0;i<table.length;i++){
  5700.                 $(table[i]).children().each(function(){
  5701.                     $(this).css('background-color', "");
  5702.                 });  
  5703.             }
  5704.             document.getElementById("btn_highlight").classList.remove("btn-confirm-yes")
  5705.             document.getElementById("btn_highlight").classList.add("btn-confirm-no")
  5706.         }
  5707.    
  5708.     } catch (error) {
  5709.        
  5710.     }
  5711.  
  5712.  
  5713. }
  5714. if(window.location.href.includes("mode=incomings"))
  5715.     highLightIncomings();
  5716.  
  5717.  
  5718.  
  5719.    
  5720.  
  5721. function toggleHighLight(){
  5722.  
  5723.     if(localStorage.getItem(game_data.world+"highlight")!=null){
  5724.         let isHighLight=localStorage.getItem(game_data.world+"highlight")
  5725.         if(isHighLight=="true"){
  5726.             localStorage.setItem(game_data.world+"highlight","false")
  5727.             UI.ErrorMessage("highlight off",500)
  5728.             highLightIncomings();
  5729.         }
  5730.         else{
  5731.             localStorage.setItem(game_data.world+"highlight","true")
  5732.             UI.SuccessMessage("highlight on",500)
  5733.             highLightIncomings();
  5734.         }
  5735.  
  5736.     }
  5737.     else{
  5738.         localStorage.setItem(game_data.world+"highlight","true")
  5739.         highLightIncomings();
  5740.     }
  5741. }
  5742.  
  5743. /////////////////////////////////////////////get and add troops on incoming page for each village////////////////////////////////////////////
  5744. function eventGetTroops(){
  5745.     var units=game_data.units
  5746.  
  5747.  
  5748.     $(".load_troops").on("click",function(event){
  5749.         event.preventDefault()
  5750.         $(".load_troops").attr("disabled", true)
  5751.         let villageId=this.getAttribute("data-id")
  5752.         let nrAttacks=this.getAttribute("data-nr")
  5753.         let link_home_troops=game_data.link_base_pure + `map&ajax=map_info&source=${villageId}&target=${villageId}&`
  5754.         let link_coming_troops=window.location.href.split("village=")[0]+`village=${villageId}&screen=place&mode=call&target=${villageId}`
  5755.         let coord=this.innerText.match(/\d+\|\d+/)[0]
  5756.         let button=this
  5757.         console.log(link_home_troops)
  5758.         this.parentElement.classList.remove("selected")
  5759.  
  5760.  
  5761.  
  5762.         let time_start=new Date().getTime();
  5763.         $.get(link_home_troops,function(response){
  5764.             console.log(response)
  5765.             let obj_troops={}
  5766.             for(let i=0;i<units.length-1;i++){
  5767.                 obj_troops[units[i]]=parseInt(response.units[units[i]].count.home)+parseInt(response.units[units[i]].count.foreign)
  5768.             }
  5769.             let wallLevel,farmLevel,flagName,LoyaltyLevel
  5770.             wallLevel=response.buildings.wall
  5771.             farmLevel=response.buildings.farm
  5772.             LoyaltyLevel=response.mood
  5773.             console.log(response.flag)
  5774.             if(response.flag!=undefined)
  5775.                 if(response.flag.toLowerCase().includes("defense"))
  5776.                     flagName =response.flag.short_desc
  5777.             else
  5778.                 flagName="none"
  5779.             console.log(obj_troops)
  5780.             console.log("wallLevel: "+wallLevel)
  5781.             console.log("farmLevel: "+farmLevel)
  5782.             console.log("flagName: "+flagName)
  5783.             console.log("LoyaltyLevel: "+LoyaltyLevel)
  5784.  
  5785.  
  5786.  
  5787.             let htmlDiv=`<div id="div_coming_troops" hidden></div>`
  5788.             $("#contentContainer").eq(0).prepend(htmlDiv)
  5789.             console.log(link_coming_troops)
  5790.  
  5791.             $.get(link_coming_troops,function(data){
  5792.                 document.getElementById("div_coming_troops").innerHTML=data
  5793.                
  5794.                 let obj_troops_coming={snob:0}
  5795.                 let troops_coming=document.getElementById("div_coming_troops").querySelectorAll("#support_sum td")
  5796.                 console.log(troops_coming)
  5797.                 for(let i=0;i<troops_coming.length-1;i++){
  5798.                     let name=troops_coming[i].getAttribute("data-unit")
  5799.                     let value=parseInt(troops_coming[i].innerText)
  5800.                     obj_troops_coming[name]=value
  5801.                 }
  5802.                 document.getElementById("div_coming_troops").remove()
  5803.  
  5804.  
  5805.  
  5806.  
  5807.                 let html=`
  5808.                 <div  style="width:600px;background-color:${backgroundColor};cursor:move;width:50%;margin:10px auto">
  5809.        
  5810.                 <table class="" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor}">
  5811.                 <tr>
  5812.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5813.                         <p><center style="margin:10px"><font color="${titleColor}">coord </font></center></p>
  5814.                     </td>    
  5815.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5816.                         <p><center style="margin:10px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/unit/att.png"> </font></center></p>
  5817.                     </td>    
  5818.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5819.                         <p><center style="margin:10px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/flags/small/3.png"> </font></center></p>
  5820.                     </td>    
  5821.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5822.                         <p><center style="margin:10px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/snob.png"> </font></center></p>
  5823.                     </td>    
  5824.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5825.                         <p><center style="margin:10px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/wall.png"> </font></center></p>
  5826.                     </td>    
  5827.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5828.                         <p><center style="margin:10px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/farm.png"> </font></center></p>
  5829.                     </td>  
  5830.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5831.                         <p><center style="margin:10px"><font color="${titleColor}">troops </font></center></p>
  5832.                     </td>  
  5833.                    
  5834.                 `;
  5835.                 for(let i=0;i<units.length-1;i++){
  5836.                     html+=`<td class="fm_unit" style="width:30px;text-align:center;width:auto; background-color:${headerColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/unit/unit_${units[i]}.png"></td>`
  5837.                 }
  5838.                 html+=`
  5839.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5840.                         <p><center style="margin:10px"><font color="${titleColor}">pop</font></center></p>
  5841.                     </td>`
  5842.                 html+=`</tr>
  5843.                         <tr>`
  5844.                
  5845.                 html+=`
  5846.                     <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">${coord}</td>
  5847.                     <td rowspan="3" class="" style="width:70px;height:30px;text-align:center; background-color:${headerColor};color:white">${nrAttacks}</td>
  5848.                     <td rowspan="3" class="" style="width:70px;height:30px;text-align:center; background-color:${headerColor};color:white">${flagName}</td>
  5849.                     <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">${LoyaltyLevel}</td>
  5850.                     <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">${wallLevel}</td>
  5851.                     <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">${farmLevel}</td>
  5852.                     <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5853.                         <p><center style="margin:10px"><font color="${titleColor}">home</font></center></p>
  5854.                     </td>
  5855.                 `
  5856.                 //home troops
  5857.                 let total_pop=0;
  5858.                 for(let i=0;i<units.length-1;i++){
  5859.                     let value_troop=obj_troops[units[i]]
  5860.                     let name_troop=units[i]
  5861.                     if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  5862.                         total_pop+=value_troop*troopsPop[name_troop]
  5863.                     }
  5864.                     html+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">`+value_troop+"</td>"
  5865.                 }
  5866.                 html+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColor};color:white">`+total_pop+"</td>"
  5867.                 html+=`</tr>
  5868.                         <tr>
  5869.                             <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5870.                                 <p><center style="margin:10px"><font color="${titleColor}">coming</font></center></p>
  5871.                             </td>`
  5872.                 //coming troops
  5873.                 total_pop=0;
  5874.                 for(let i=0;i<units.length-1;i++){
  5875.                     let value_troop_coming=obj_troops_coming[units[i]]
  5876.                     let name_troop=units[i]
  5877.                     if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  5878.                         total_pop+=value_troop_coming*troopsPop[name_troop]
  5879.                     }
  5880.                     html+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">`+value_troop_coming+"</td>"
  5881.                 }
  5882.                 html+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColor};color:white">`+total_pop+"</td>"
  5883.  
  5884.                 html+=`</tr>
  5885.                         <tr>
  5886.                             <td  style="text-align:center; width:auto; background-color:${headerColor}">
  5887.                                 <p><center style="margin:10px"><font color="${titleColor}">total </font></center></p>
  5888.                             </td>`
  5889.                 //total troops
  5890.                 total_pop=0;
  5891.                 for(let i=0;i<units.length-1;i++){
  5892.                     let value_troop=obj_troops[units[i]]+obj_troops_coming[units[i]]
  5893.                     let name_troop=units[i]
  5894.                     if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  5895.                         total_pop+=value_troop*troopsPop[name_troop]
  5896.                     }
  5897.                     html+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColor};color:white">`+value_troop+"</td>"
  5898.                 }
  5899.                 html+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColor};color:white">`+total_pop+"</td>"
  5900.  
  5901.                 html+=`</tr></table></div>`
  5902.        
  5903.                 button.outerHTML=html
  5904.  
  5905.  
  5906.                 let time_stop=new Date().getTime()
  5907.                 console.log("load troops: "+(time_stop-time_start))
  5908.                 $(".load_troops").attr("disabled", false)
  5909.  
  5910.  
  5911.  
  5912.  
  5913.  
  5914.  
  5915.             })
  5916.  
  5917.  
  5918.         })
  5919.  
  5920.  
  5921.     })
  5922. }
  5923. eventGetTroops();
  5924.        
  5925.      
  5926.  
  5927. //////////////////////////////////////////////////////get data from /map/player.txt and /mapVillages.txt/////////////////////////////////////
  5928.  
  5929. async function getInfoVillages(){
  5930.    
  5931.     return new Promise(async(resolve,reject)=>{
  5932.         let filename_innoDB=game_data.world+"infoVillages"
  5933.         await insertlibraryLocalBase().catch(err=>{alert(err)})
  5934.         let data = await localBase.getItem(filename_innoDB).catch(err=>{alert(err)})
  5935.        
  5936.  
  5937.         console.log("get info VIllages")
  5938.         let mapVillages=new Map();
  5939.         let obj={};
  5940.         let server_date=document.getElementById("serverDate").innerText.split("/")
  5941.         let server_time=document.getElementById("serverTime").innerText
  5942.         let current_date=new Date(server_date[1]+"/"+server_date[0]+"/"+server_date[2]+" "+server_time);
  5943.         let url=window.location.href.split("/game.php")[0]
  5944.         let mapPlayer=new Map();
  5945.         let mapAlly=new Map();
  5946.  
  5947.  
  5948.         if(data==undefined){
  5949.  
  5950.             let dataVillage = httpGet(url+"/map/village.txt").split(/\r?\n/);
  5951.             let dataPlayer = httpGet(url+"/map/player.txt").split(/\r?\n/);
  5952.             let dataAlly = httpGet(url+"/map/ally.txt").split(/\r?\n/);
  5953.  
  5954.             for(let i=0;i<dataAlly.length-1;i++){
  5955.                 // console.log(dataPlayer[i].split(",")[1])
  5956.                 let tribeName=innoReplaceSpecialCaracters(dataAlly[i].split(",")[1])
  5957.                 mapAlly.set(dataAlly[i].split(",")[0],tribeName)
  5958.             }
  5959.             for(let i=0;i<dataPlayer.length-1;i++){
  5960.                 // console.log(dataPlayer[i].split(",")[1])
  5961.                 let playerName=innoReplaceSpecialCaracters(dataPlayer[i].split(",")[1])
  5962.                 let tribeName= (mapAlly.get(dataPlayer[i].split(",")[2]) == undefined)? "none":mapAlly.get(dataPlayer[i].split(",")[2])
  5963.                 mapPlayer.set(dataPlayer[i].split(",")[0],{
  5964.                     allyId:dataPlayer[i].split(",")[2],
  5965.                     playerName:playerName,
  5966.                     tribeName: tribeName
  5967.                 })
  5968.             }
  5969.  
  5970.    
  5971.             for(let i=0;i<dataVillage.length;i++){
  5972.                 if(mapPlayer.get(dataVillage[i].split(",")[4])!=undefined){
  5973.                     mapVillages.set(dataVillage[i].split(",")[2]+"|"+dataVillage[i].split(",")[3],{
  5974.                         villageId:dataVillage[i].split(",")[0],
  5975.                         playerId:dataVillage[i].split(",")[4],
  5976.                         points:dataVillage[i].split(",")[5],
  5977.                         allyId:mapPlayer.get(dataVillage[i].split(",")[4]).allyId,
  5978.                         playerName:mapPlayer.get(dataVillage[i].split(",")[4]).playerName,
  5979.                         tribeName:mapPlayer.get(dataVillage[i].split(",")[4]).tribeName
  5980.                     })
  5981.                 }
  5982.             }
  5983.             obj.datetime=current_date
  5984.             obj.data=Array.from(mapVillages.entries())
  5985.  
  5986.             let data=JSON.stringify(obj)
  5987.             data=replaceSpecialCaracters(data)
  5988.        
  5989.             await localBase.setItem(filename_innoDB,data)
  5990.        
  5991.         }else{
  5992.            
  5993.             let ino_db= JSON.parse(data)
  5994.             let db_date=ino_db.datetime
  5995.             mapVillages=new Map(ino_db.data)
  5996.  
  5997.             // console.log("mapVillages",mapVillages)
  5998.            
  5999.  
  6000.  
  6001.  
  6002.             // console.log(mapVillages)
  6003.             if(new Date(current_date).getTime()-new Date(db_date)>3600*1000){
  6004.                 console.log("update database inno")
  6005.  
  6006.                 let dataVillage = httpGet(url+"/map/village.txt").split(/\r?\n/);
  6007.                 let dataPlayer = httpGet(url+"/map/player.txt").split(/\r?\n/);
  6008.                 let dataAlly = httpGet(url+"/map/ally.txt").split(/\r?\n/);
  6009.    
  6010.                 for(let i=0;i<dataAlly.length-1;i++){
  6011.                     // console.log(dataPlayer[i].split(",")[1])
  6012.                     let tribeName=innoReplaceSpecialCaracters(dataAlly[i].split(",")[1])
  6013.                     mapAlly.set(dataAlly[i].split(",")[0],tribeName)
  6014.                 }
  6015.    
  6016.                 for(let i=0;i<dataPlayer.length-1;i++){
  6017.                     // console.log(dataPlayer[i].split(",")[1])
  6018.                     let playerName=innoReplaceSpecialCaracters(dataPlayer[i].split(",")[1])
  6019.                     let tribeName= (mapAlly.get(dataPlayer[i].split(",")[2]) == undefined)? "none":mapAlly.get(dataPlayer[i].split(",")[2])
  6020.  
  6021.                     mapPlayer.set(dataPlayer[i].split(",")[0],{
  6022.                         allyId:dataPlayer[i].split(",")[2],
  6023.                         playerName:playerName,
  6024.                         tribeName:tribeName
  6025.                     })
  6026.                 }
  6027.    
  6028.    
  6029.        
  6030.                 for(let i=0;i<dataVillage.length;i++){
  6031.                     if(mapPlayer.get(dataVillage[i].split(",")[4])!=undefined){
  6032.                         mapVillages.set(dataVillage[i].split(",")[2]+"|"+dataVillage[i].split(",")[3],{
  6033.                             villageId:dataVillage[i].split(",")[0],
  6034.                             playerId:dataVillage[i].split(",")[4],
  6035.                             points:dataVillage[i].split(",")[5],
  6036.                             allyId:mapPlayer.get(dataVillage[i].split(",")[4]).allyId,
  6037.                             playerName:mapPlayer.get(dataVillage[i].split(",")[4]).playerName,
  6038.                             tribeName:mapPlayer.get(dataVillage[i].split(",")[4]).tribeName
  6039.                         })
  6040.                     }
  6041.                 }
  6042.                 obj.datetime=current_date
  6043.                 obj.data=Array.from(mapVillages.entries())
  6044.                
  6045.                 let data=JSON.stringify(obj)
  6046.                 data=replaceSpecialCaracters(data)
  6047.                 await localBase.setItem(filename_innoDB,data)
  6048.  
  6049.                 console.log("upload new data")
  6050.  
  6051.             }
  6052.             else{
  6053.                 console.log("already exist")
  6054.             }
  6055.         }
  6056.         resolve(mapVillages)
  6057.  
  6058.  
  6059.     })
  6060.  
  6061.  
  6062. }
  6063.  
  6064. function innoReplaceSpecialCaracters(text){
  6065.     // text=text.replaceAll("+"," ")
  6066.     // text=text.replaceAll("%21","!")
  6067.     // text=text.replaceAll("%23","#")
  6068.     // text=text.replaceAll("%24","$")
  6069.     // text=text.replaceAll("%25","%")
  6070.  
  6071.     // text=text.replaceAll("%28","(")
  6072.     // text=text.replaceAll("%29",")")
  6073.     // text=text.replaceAll("%2A","*")
  6074.     // text=text.replaceAll("%2B","+")
  6075.     // text=text.replaceAll("%2C",",")
  6076.     // text=text.replaceAll("%2F","/")
  6077.  
  6078.  
  6079.     // text=text.replaceAll("%3A",":")
  6080.     // text=text.replaceAll("%3D","=")
  6081.     // text=text.replaceAll("%3F","?")
  6082.  
  6083.     // text=text.replaceAll("%40","@")
  6084.  
  6085.     // text=text.replaceAll("%5B","[")
  6086.     // text=text.replaceAll("%5D","]")
  6087.  
  6088.     // text = text.replaceAll("%7B", "{")
  6089.     // text = text.replaceAll("%7D", "}")
  6090.  
  6091.     // text=text.replaceAll("%7C","|")
  6092.     // text=text.replaceAll("%7E","~")
  6093.  
  6094.     // text=text.replaceAll("%C3%84","Ä")
  6095.     // text=text.replaceAll("%C3%85","Ã…")
  6096.     // text=text.replaceAll("%C3%86","Æ")
  6097.     // text=text.replaceAll("%C3%A2","â")
  6098.     // text=text.replaceAll("%C3%A4","ä")
  6099.     // text=text.replaceAll("%C3%A5","Ã¥")
  6100.     // text=text.replaceAll("%C3%A6","æ")
  6101.     // text=text.replaceAll("%C3%B6","ö")
  6102.     // text=text.replaceAll("%C3%B8","ø")
  6103.     // text=text.replaceAll("%C3%BC","ü")
  6104.     // text=text.replaceAll("%C4%8","ÄŒ")
  6105.     // text=text.replaceAll("%C5%BD","Ž")
  6106.     // text=text.replaceAll("%C5%A0","Å ")
  6107.     // text=text.replaceAll("%C5%A1","Å¡")
  6108.  
  6109.     // text=text.replaceAll("%C4%83","ă")
  6110.  
  6111.     // text=text.replaceAll("%C8%99","È™")
  6112.     // text=text.replaceAll("%C5%A3","Å£")
  6113.     // text=text.replaceAll("%C8%9B","È›")
  6114.     // return text
  6115.  
  6116.     try {
  6117.         return decodeURIComponent(text).replace(/\+/g, ' ');
  6118.     } catch (error) {
  6119.         console.error(error, text);
  6120.         return text;
  6121.     }
  6122.  
  6123. }
  6124.    
  6125. function replaceSpecialCaracters(data) {
  6126.     let result = ""
  6127.     for (let i = 0; i < data.length; i++) {
  6128.         if (data[i] == "È›")
  6129.             result += 't'
  6130.         else if (data[i] == "Å£")
  6131.             result += 't'
  6132.         else if (data[i] == "Èš")
  6133.             result += "T"
  6134.         else if (data[i] == "Ä‚")
  6135.             result += "A"
  6136.         else if (data[i] == "ă")
  6137.             result += "a"
  6138.         else if (data[i] == "Â")
  6139.             result += "A"
  6140.         else if (data[i] == "Ș")
  6141.             result += "S"
  6142.         else if (data[i] == "È™")
  6143.             result += "s"
  6144.         else if (data[i] == "ÃŽ")
  6145.             result += "I"
  6146.         else if (data[i] == "î")
  6147.             result += "i"
  6148.         else
  6149.             result += data[i]
  6150.     }
  6151.     return result
  6152.  
  6153.  
  6154.  
  6155.  
  6156. }
  6157.  
  6158.  
  6159. function insertlibraryLocalBase(){
  6160.     return new Promise((resolve,reject)=>{
  6161.  
  6162.         let start=new Date().getTime()
  6163.         let script = document.createElement('script');
  6164.         script.type="text/javascript"
  6165.         script.src="https://dl.dropboxusercontent.com/s/22qgnhyxnyono68/libraryIndexedDB.js?dl=0"
  6166.         script.onload = function () {
  6167.             let stop=new Date().getTime()
  6168.             console.log(`insert idb library in ${stop-start} ms`)
  6169.             resolve("insert library")
  6170.         };
  6171.         document.getElementsByTagName("head")[0].appendChild(script);
  6172.     })
  6173. }
  6174.  
  6175.  
  6176.  
  6177. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  6178.  
  6179.  
  6180. ////////////////////////////////////////////// get supports out going from command/support page ///////////////////////////////////////
  6181.  
  6182. function getCommandsGoing(){
  6183.  
  6184.     return new Promise(async(resolve,reject)=>{
  6185.     //create link
  6186.     let linkCommand=game_data.link_base_pure+"overview_villages&mode=commands&type=all&&group=0"
  6187.     // console.log(linkCommand)
  6188.     let datePage = await ajaxGet(linkCommand)
  6189.     const parser = new DOMParser();
  6190.     const htmlDoc = parser.parseFromString(datePage, 'text/html');
  6191.    
  6192.     //get pages for all incoming
  6193.     let list_pages=[]
  6194.     var map_outgoing_support=new Map()
  6195.     var map_outgoing_attack=new Map()
  6196.  
  6197.     if(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  6198.         Array.from(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select")[0]).forEach(function(item){
  6199.             list_pages.push(item.value)
  6200.         })
  6201.         list_pages.pop();
  6202.     }
  6203.     else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){//all pages from the current folder
  6204.         let nr=0;
  6205.         Array.from(htmlDoc.getElementsByClassName("paged-nav-item")).forEach(function(item){
  6206.             let current=item.href;
  6207.             current=current.split("page=")[0]+"page="+nr
  6208.             nr++;
  6209.             list_pages.push(current);
  6210.         })
  6211.     }
  6212.     else{
  6213.         list_pages.push(linkCommand);
  6214.     }
  6215.     list_pages=list_pages.reverse();
  6216.     console.log(list_pages)
  6217.  
  6218.    
  6219.     //for each page
  6220.     function ajaxRequest (urls) {
  6221.         let current_url
  6222.         if(urls.length>0){
  6223.             current_url=urls.pop()
  6224.         }
  6225.         else{
  6226.             current_url="stop"
  6227.         }
  6228.         // console.log(current_url)
  6229.         if (urls.length >= 0 && current_url!="stop") {// go to every page and get all rows
  6230.             $.ajax({
  6231.                 url: current_url,
  6232.                 method: 'get',
  6233.                 success: (data) => {
  6234.                     const parser = new DOMParser();
  6235.                     const htmlDoc = parser.parseFromString(data, 'text/html');
  6236.  
  6237.                     if(htmlDoc.getElementById("commands_table")==null){//commands outgoing none
  6238.                         resolve(map_outgoing_support)
  6239.                     }else{
  6240.                         var table_commands=htmlDoc.getElementById("commands_table").getElementsByTagName("tbody")[0].children
  6241.                         for(let i=1;i<table_commands.length-1;i++){
  6242.                             if(table_commands[i].children[0].innerText.match(/\d+\|\d+/)!=null){//destination must contains coord destination
  6243.  
  6244.                                 let commandId=table_commands[i].getElementsByClassName("own_command")[0].getAttribute("data-command-id")
  6245.                                 let coord_destination=table_commands[i].getElementsByClassName("quickedit-label")[0].innerText.match(/\d+\|\d+/)[0]
  6246.                                 let coord_origin=table_commands[i].children[1].innerText.match(/\d+\|\d+/)[0]
  6247.                                 let coord_origin_id=table_commands[i].children[1].getElementsByTagName("a")[0].href.split("id=")[1]
  6248.                                 let landing_time=getLandTime(table_commands[i].children[2].innerText)
  6249.                                 let troops={}
  6250.                                 let player_origin_name=game_data.player.name
  6251.                                 let player_origin_id=game_data.player.id.toString()
  6252.                                 Array.from(table_commands[i].getElementsByClassName("unit-item")).forEach((elem,index)=>{
  6253.                                     troops[game_data.units[index]]=parseInt(elem.innerText)
  6254.                                 })
  6255.                            
  6256.                                 //add data for the current command into a map
  6257.                                 let type_attack=table_commands[i].getElementsByTagName("img")[0].src.split("command/")[1]
  6258.                                 if(type_attack.includes("support")){
  6259.                                     delete troops["snob"]
  6260.                                     map_outgoing_support.set(commandId,{
  6261.                                         coord_destination:coord_destination,
  6262.                                         coord_origin:coord_origin,
  6263.                                         landing_time:landing_time,
  6264.                                         troops:troops,
  6265.                                         player_origin_name:player_origin_name,
  6266.                                         player_origin_id:player_origin_id,
  6267.                                         commandId:commandId,
  6268.                                         coord_origin_id:coord_origin_id,
  6269.                                         type_attack:type_attack,
  6270.                                         labelName:"none"
  6271.  
  6272.                                     })
  6273.                                 }
  6274.                                 else if(type_attack=="attack_small.png" || type_attack=="attack_medium.png" || type_attack=="attack_large.png"){
  6275.                                 // console.log("is an attack")
  6276.                                     let serverTime=htmlDoc.getElementById("serverTime").innerText
  6277.                                     let serverDate=htmlDoc.getElementById("serverDate").innerText.split("/")
  6278.                                     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  6279.                                     let date_current=new Date(serverDate+" "+serverTime)
  6280.                                     date_current.setDate(date_current.getDate()+7)
  6281.                
  6282.  
  6283.                                     map_outgoing_attack.set(commandId,{
  6284.                                         coord_destination:coord_destination,
  6285.                                         coord_origin:coord_origin,
  6286.                                         landing_time:landing_time,
  6287.                                         troops:troops,
  6288.                                         player_origin_name:player_origin_name,
  6289.                                         player_origin_id:player_origin_id,
  6290.                                         commandId:commandId,
  6291.                                         coord_origin_id:coord_origin_id,
  6292.                                         type_attack:type_attack,
  6293.                                         labelName:"none",
  6294.                                         uploadTime:date_current.getTime()
  6295.  
  6296.                                     })
  6297.                                 }
  6298.                             }
  6299.                         }
  6300.                         UI.SuccessMessage("get page: "+urls.length)
  6301.                         window.setTimeout(function(){
  6302.                             ajaxRequest (list_pages)
  6303.                         },200)
  6304.  
  6305.                     }
  6306.                 }
  6307.             })
  6308.            
  6309.         }
  6310.         else//append all rows into table
  6311.         {
  6312.             UI.SuccessMessage("done")
  6313.             resolve([map_outgoing_support,map_outgoing_attack])
  6314.         }
  6315.     }
  6316.     ajaxRequest(list_pages);
  6317.     })
  6318.  
  6319. }
  6320.  
  6321. ////////////////////////////////////////////// get coming supports and attacks from incoming page ///////////////////////////////////////
  6322.  
  6323. function getSupportsAndAttacks(){
  6324.     return new Promise(async(resolve,reject)=>{
  6325.         if($('[id="incomings_amount"]:visible').length == 0 && $('[id="supports_amount"]:visible').length == 0){
  6326.             resolve({
  6327.                 map_outgoing_support:new Map(),
  6328.                 map_exist_support:new Map()
  6329.             })
  6330.         }
  6331.         else{
  6332.             if(document.getElementsByClassName("info").length>0)
  6333.             $(".info").remove()
  6334.         var current_href_incomings=window.location.href;
  6335.         ////////////////////////////////////////////////unIgnored attacks/supports....................................
  6336.         let incomings_href=game_data.link_base_pure+"overview_villages&mode=incomings&type=unignored&subtype=all&group=0&page=-1";
  6337.  
  6338.  
  6339.         let datePage = await ajaxGet(incomings_href)
  6340.         const parser = new DOMParser();
  6341.         const htmlDoc = parser.parseFromString(datePage, 'text/html');
  6342.  
  6343.  
  6344.  
  6345.         if(htmlDoc.getElementsByClassName("overview_filters_delete").length>0){
  6346.             reject("turn off filters on incomings page")
  6347.         }
  6348.         let list_href=[];
  6349.         if(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  6350.             Array.from(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select")[0].options).forEach(el=>{
  6351.                 list_href.push({
  6352.                     href:el.value,
  6353.                     unignored:true
  6354.                 });
  6355.             })
  6356.             list_href.pop();
  6357.         }
  6358.         else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){
  6359.             let arr=Array.from(htmlDoc.getElementsByClassName("paged-nav-item"));
  6360.             for(let i=0;i<arr.length;i++)
  6361.             list_href.push({
  6362.                 href:arr[i].getAttribute("href"),
  6363.                 unignored:true
  6364.             })
  6365.         }
  6366.         else if(htmlDoc.getElementById("incomings_table")!=null){
  6367.                 list_href.push({
  6368.                     href:incomings_href,
  6369.                     unignored:true
  6370.                 })
  6371.         }
  6372.  
  6373.  
  6374.     ///////////////////////////////////////////////////////////ignored attacks/support////////////////////////////////////////
  6375.         incomings_href=game_data.link_base_pure+"overview_villages&mode=incomings&type=ignored&subtype=all&group=0&page=-1";
  6376.  
  6377.         console.log("currentLink")
  6378.         console.log(incomings_href)
  6379.         let datePage2 = await ajaxGet(incomings_href)
  6380.         const parser2 = new DOMParser();
  6381.         const htmlDoc2 = parser2.parseFromString(datePage2, 'text/html');
  6382.          
  6383.  
  6384.         if(htmlDoc2.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  6385.             Array.from(htmlDoc2.getElementsByClassName("vis")[1].getElementsByTagName("select")[0].options).forEach(el=>{
  6386.                 list_href.push({
  6387.                     href:el.value,
  6388.                     unignored:false
  6389.                 });
  6390.             })
  6391.             list_href.pop();
  6392.         }
  6393.         else if(htmlDoc2.getElementsByClassName("paged-nav-item").length>0){
  6394.             let arr=Array.from(htmlDoc2.getElementsByClassName("paged-nav-item"));
  6395.             for(let i=0;i<arr.length;i++)
  6396.             list_href.push({
  6397.                 href:arr[i].getAttribute("href"),
  6398.                 unignored:false
  6399.             })
  6400.         }
  6401.         else if(htmlDoc2.getElementById("incomings_table")!=null){
  6402.             list_href.push({
  6403.                 href:incomings_href,
  6404.                 unignored:false
  6405.             })
  6406.         }
  6407.  
  6408.  
  6409.  
  6410.  
  6411.  
  6412.  
  6413.  
  6414.         console.log(list_href)
  6415.    
  6416.  
  6417.         var indexIncoming=1;
  6418.         var url_length=list_href.length
  6419.         var map_outgoing_support=new Map()
  6420.  
  6421.         var list_incomingId=[]
  6422.         var map_exist_support=localStorage.getItem(game_data.world+"map_exist_support")
  6423.         if(map_exist_support!=undefined)
  6424.             map_exist_support=new Map(JSON.parse(map_exist_support))
  6425.         else
  6426.             map_exist_support=new Map()
  6427.  
  6428.  
  6429.         function ajaxRequest (urls) {
  6430.             let current_url,unignored
  6431.             var time=0
  6432.             if(urls.length>0){
  6433.                 let obj=urls.pop();
  6434.                 current_url=obj.href
  6435.                 unignored=obj.unignored
  6436.             }
  6437.             else{
  6438.                 current_url="stop"
  6439.             }
  6440.             console.log("get url "+urls.length)
  6441.             // console.log(current_url)
  6442.  
  6443.             if (urls.length >= 0 && current_url!="stop") {
  6444.                 var start_ajax=new Date();
  6445.                 $.ajax({
  6446.                     url: current_url,
  6447.                     method: 'get',
  6448.                     success: (data) => {
  6449.                         const parser = new DOMParser();
  6450.                         const htmlDoc = parser.parseFromString(data, 'text/html');
  6451.  
  6452.                         if(htmlDoc.getElementById("incomings_table")==null)
  6453.                             alert("turn off the filters");
  6454.                         let table_incomings=htmlDoc.getElementById("incomings_table").getElementsByTagName("tbody")[0].children
  6455.                         for(let i=1;i<table_incomings.length-1;i++){
  6456.                            
  6457.                             if(table_incomings[i].children[0].innerText!="--"){
  6458.                                 let commandId=table_incomings[i].getElementsByClassName("quickedit")[0].getAttribute("data-id")
  6459.                                
  6460.                                 // console.log(commandId)
  6461.                                 list_incomingId.push(commandId)
  6462.                                 let coord_destination=table_incomings[i].children[1].innerText.match(/\d+\|\d+/)[0]
  6463.                                 let coord_origin=table_incomings[i].children[2].innerText.match(/\d+\|\d+/)[0]
  6464.                                 let coord_origin_id=table_incomings[i].children[2].getElementsByTagName("a")[0].href.split("id=")[1]
  6465.                                 let length_tr=table_incomings[i].children.length
  6466.                                 let landing_time=getLandTime(table_incomings[i].children[length_tr-2].innerText)
  6467.                                 let troops={}
  6468.                                 let player_origin_name=table_incomings[i].children[length_tr-4].innerText.trim()
  6469.                                 let player_origin_id=table_incomings[i].children[length_tr-4].getElementsByTagName("a")[0].href.split("id=")[1]
  6470.                                
  6471.  
  6472.                                 let labelName="none"
  6473.                                 let type_attack=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[0].src.split("command/")[1]
  6474.                                 if(table_incomings[i].children[0].getElementsByTagName("img").length==2){
  6475.                                     labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src.split("tiny/")[1]
  6476.                                     if(labelName==undefined)
  6477.                                         labelName=table_incomings[i].getElementsByClassName("quickedit")[0].getElementsByTagName("img")[1].src.split("command/")[1]
  6478.  
  6479.                                 }
  6480.  
  6481.  
  6482.                                 //check if an attack was ignored or unignored
  6483.                                 if(map_exist_support.has(commandId)){
  6484.                                     if(map_exist_support.get(commandId)!=unignored)
  6485.                                         map_exist_support.delete(commandId)
  6486.                                 }
  6487.  
  6488.  
  6489.                                 // console.log(coord_destination)
  6490.                                 //add new command id to localstorage and save data to map_going_support
  6491.                                 if(!map_exist_support.has(commandId)){
  6492.  
  6493.                                    
  6494.                                     if(!map_outgoing_support.has(coord_destination)){
  6495.                                         map_outgoing_support.set(coord_destination,[{
  6496.                                             coord_destination:coord_destination,
  6497.                                             coord_origin:coord_origin,
  6498.                                             landing_time:landing_time,
  6499.                                             troops:troops,
  6500.                                             player_origin_name:player_origin_name,
  6501.                                             player_origin_id:player_origin_id,
  6502.                                             type_attack:type_attack,
  6503.                                             commandId:commandId,
  6504.                                             labelName:labelName,
  6505.                                             coord_origin_id:coord_origin_id,
  6506.                                             unignored:unignored
  6507.                                         }])
  6508.                                         // console.log("list support doesn't exist")
  6509.                                     }
  6510.                                     else{
  6511.                                         let list_support=map_outgoing_support.get(coord_destination)
  6512.                                         list_support.push({
  6513.                                             coord_destination:coord_destination,
  6514.                                             coord_origin:coord_origin,
  6515.                                             landing_time:landing_time,
  6516.                                             troops:troops,
  6517.                                             player_origin_name:player_origin_name,
  6518.                                             player_origin_id:player_origin_id,
  6519.                                             type_attack:type_attack,
  6520.                                             commandId:commandId,
  6521.                                             labelName:labelName,
  6522.                                             coord_origin_id:coord_origin_id,
  6523.                                             unignored:unignored
  6524.                                         })
  6525.                                         map_outgoing_support.set(coord_destination,list_support)
  6526.                                         // console.log("list support updated")
  6527.  
  6528.                                     }
  6529.                                     map_exist_support.set(commandId,{
  6530.                                         unignored:unignored,
  6531.                                         playerId:game_data.player.id.toString()
  6532.                                     })
  6533.                                 }
  6534.                                
  6535.                                
  6536.                             }
  6537.                         }
  6538.  
  6539.                         UI.SuccessMessage(indexIncoming+"/"+url_length)
  6540.                         indexIncoming++;
  6541.                         var stop_ajax=new Date();
  6542.                         var dif_time=stop_ajax.getTime()-start_ajax.getTime()
  6543.                         console.log("wait: "+dif_time)
  6544.                         window.setTimeout(function(){
  6545.                             ajaxRequest (list_href)
  6546.                         },200-dif_time)
  6547.                     }
  6548.                 })
  6549.            
  6550.             }
  6551.             else
  6552.             {
  6553.                 if(htmlDoc.getElementById("incomings_table")!=null){
  6554.                     // showButtons();
  6555.                 }
  6556.            
  6557.                 if( htmlDoc.getElementsByClassName("g-recaptcha").length>0){//recaptcha
  6558.                     console.log("recapthca")
  6559.                     UI.ErrorMessage("recapthca, upload again")
  6560.                     resolve("recapthca, upload again");
  6561.                     throw new Error("recapthca, upload again");
  6562.                 }
  6563.  
  6564.                 window.setTimeout(function(){
  6565.  
  6566.  
  6567.                     Array.from(map_exist_support.keys()).forEach((key)=>{
  6568.                         if(!list_incomingId.includes(key)){
  6569.                             map_exist_support.delete(key)
  6570.                             console.log("delete id: "+key)
  6571.                         }
  6572.                     })
  6573.                     // console.log("adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadaadad")
  6574.                     // console.log("map_outgoing_support",map_outgoing_support)
  6575.                     // console.log("map_exist_support",map_exist_support)
  6576.                     // console.log("adadadadadadadadadadadadadadadadadadadadadadadadadadadadadadaadad")
  6577.  
  6578.                     resolve({
  6579.                         map_outgoing_support:map_outgoing_support,
  6580.                         map_exist_support:map_exist_support
  6581.                     })
  6582.                 },200)
  6583.  
  6584.  
  6585.  
  6586.             }
  6587.         }
  6588.         if(list_href.length>0)
  6589.             ajaxRequest(list_href);
  6590.         else
  6591.             reject("error on incomings")
  6592.         }
  6593.        
  6594.     })
  6595. }
  6596.  
  6597.  
  6598. /////////////////////////////////////////////main function for getting all supports and attacks//////////////////////////////////////////
  6599.  
  6600. async function uploadSupports(){
  6601.     document.getElementById("progress_support").innerText="Getting data...";
  6602.  
  6603.     var mapCommandsSharing = await getCommandsSharing()
  6604.     var [mapVillages, data_support,data_attack,mapStatus]=await Promise.all([
  6605.         getInfoVillages(),
  6606.         readFileDropbox(filename_support),
  6607.         readFileDropbox(filename_commands_attack),
  6608.         readFileDropbox(filename_status_upload),
  6609.     ]).catch(err=>{alert(err)})
  6610.  
  6611.     let data_attack_batch = await Promise.all(commandsAttacksPromises).catch(err=>{alert(err)})
  6612.     let data_support_batch = await Promise.all(supportPromises).catch(err=>{alert(err)})
  6613.  
  6614.     var result_commands=await getCommandsGoing().catch(err=>{alert(err);throw err})
  6615.     // console.log("result_commands",result_commands)
  6616.     var map_going=result_commands[0]
  6617.     var map_going_attacks=result_commands[1]
  6618.  
  6619.     let map_support_dropbox,map_troops_home_dropbox
  6620.     try {
  6621.         let decompressedData = await decompress(await data_support.arrayBuffer() , 'gzip');  
  6622.         map_support_dropbox=new Map(JSON.parse(decompressedData)[0])
  6623.         map_troops_home_dropbox =new Map(JSON.parse(decompressedData)[1])  
  6624.     } catch (error) {
  6625.         console.log("erorrrrrrrrrrrrrrrr map report from dropbox")
  6626.         map_support_dropbox=new Map()
  6627.         map_troops_home_dropbox=new Map()
  6628.     }
  6629.  
  6630.     //merge batch commands attacks (EXTRA files)
  6631.     for(let i=0;i<data_support_batch.length;i++){
  6632.         let decompressedData = await decompress(await data_support_batch[i].arrayBuffer() , 'gzip');  
  6633.  
  6634.         if(decompressedData != "[]"){
  6635.             let map_support_batch = new Map(JSON.parse(decompressedData)[0])
  6636.             let map_troops_home_batch = new Map(JSON.parse(decompressedData)[1])
  6637.  
  6638.             map_support_dropbox = new Map([...map_support_dropbox, ...map_support_batch])
  6639.             map_troops_home_dropbox = new Map([...map_troops_home_dropbox, ...map_troops_home_batch])
  6640.         }      
  6641.  
  6642.         let fileName = `${databaseName}/Support${i}.txt`
  6643.         if(await localBase.getItem(fileName) != undefined){
  6644.             try {
  6645.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(fileName))
  6646.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6647.                 let map_localBase=new Map( JSON.parse(decompressedData));
  6648.    
  6649.                 // console.log("map_localBase_support",map_localBase)
  6650.                 map_support_dropbox=new Map([...map_localBase, ...map_support_dropbox])
  6651.             } catch (error) {
  6652.                
  6653.             }
  6654.         }
  6655.         fileName = `${databaseName}/Support${i}.txtHome`
  6656.         if(await localBase.getItem(fileName) != undefined){
  6657.             try {
  6658.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(fileName))
  6659.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6660.                 let map_localBase=new Map( JSON.parse(decompressedData));
  6661.    
  6662.                 // console.log("map_localBase_troops home",map_localBase)
  6663.                 map_troops_home_dropbox=new Map([...map_localBase, ...map_troops_home_dropbox])
  6664.             } catch (error) {
  6665.                
  6666.             }
  6667.         }
  6668.     }
  6669.  
  6670.     // console.log("first: map_support_dropbox", map_support_dropbox)
  6671.  
  6672.  
  6673.     //if  database is stored locally
  6674.     if(await localBase.getItem(game_data.world+"map_support_dropbox")!=undefined){
  6675.         try{
  6676.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "map_support_dropbox"))
  6677.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6678.    
  6679.             let map_localBase=new Map( JSON.parse(decompressedData));
  6680.             // console.log("map_support_dropbox history upload",map_localBase)
  6681.             map_support_dropbox=new Map([...map_localBase, ...map_support_dropbox])
  6682.         } catch (error) {
  6683.             let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "map_support_dropbox"))));
  6684.             map_support_dropbox=new Map([...map_localBase, ...map_support_dropbox])
  6685.         }
  6686.  
  6687.     }
  6688.     if(await localBase.getItem(game_data.world+"map_troops_home_dropbox")!=undefined){
  6689.         try{
  6690.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "map_troops_home_dropbox"))
  6691.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6692.    
  6693.             let map_localBase=new Map( JSON.parse(decompressedData));
  6694.             // console.log("map_troops_home_dropbox history upload",map_localBase)
  6695.             map_troops_home_dropbox=new Map([...map_localBase, ...map_troops_home_dropbox])
  6696.         } catch (error) {
  6697.             let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "map_troops_home_dropbox"))));
  6698.             map_troops_home_dropbox=new Map([...map_localBase, ...map_troops_home_dropbox])
  6699.         }
  6700.     }
  6701.  
  6702.     try {
  6703.         let decompressedData = await decompress(await mapStatus.arrayBuffer() , 'gzip');  
  6704.         mapStatus=new Map( JSON.parse(decompressedData));
  6705.     } catch (error) {
  6706.         console.log("erorrr map report from dropbox")
  6707.         mapStatus=new Map()
  6708.     }
  6709.  
  6710.     let map_support_uploaded=new Map()
  6711.     Array.from(map_support_dropbox.keys()).forEach(key=>{
  6712.         let list_coming=map_support_dropbox.get(key)
  6713.         for(let i=0;i<list_coming.length;i++){
  6714.             if(list_coming[i].type_attack.includes("support")){
  6715.                 map_support_uploaded.set(list_coming[i].commandId,list_coming[i].troops)
  6716.             }
  6717.         }
  6718.     })
  6719.     // console.log("map_support_uploaded", map_support_uploaded)
  6720.  
  6721.     // console.log("getSupportAndAttacks")
  6722.     var resultSupport = await getSupportsAndAttacks().catch(err=>{alert(err);throw err})
  6723.     // console.log(" finish getSupportAndAttacks")
  6724.     // console.log("map_going: " + map_going)
  6725.     // console.log("resultSupport", resultSupport)
  6726.  
  6727.     // console.log("second: map_support_dropbox", map_support_dropbox)
  6728.  
  6729.  
  6730.     var map_coming = resultSupport.map_outgoing_support
  6731.     var map_troops_home=new Map()
  6732.     // console.log("map_coming",map_coming)
  6733.     // console.log("map_support_dropbox",map_support_dropbox)
  6734.  
  6735.     //for each support coming get all troops
  6736.     var keys=Array.from(map_coming.keys())
  6737.     let start_get_troops=new Date().getTime()
  6738.  
  6739.     // console.log(keys)
  6740.     // console.log("mapCommandsSharing", mapCommandsSharing)
  6741.     const run = async () => {
  6742.         console.log("Starting...");
  6743.         for (let i = 0; i < keys.length; i++) {
  6744.             let list_support=map_coming.get(keys[i])
  6745.             console.log(list_support)
  6746.             for(let j=0;j<list_support.length;j++){
  6747.                 console.log(list_support[j].player_origin_name.trim())
  6748.  
  6749.                 //get troops coming
  6750.                 if(list_support[j].type_attack.includes("support") &&  
  6751.                     !map_support_uploaded.has(list_support[j].commandId) &&
  6752.                     !map_going.has(list_support[j].commandId) &&
  6753.                     (mapCommandsSharing.has(list_support[j].player_origin_name.trim()))
  6754.                  ){
  6755.                     let troops = await ajaxTroopsComing(list_support[j].commandId)
  6756.                     console.log("troops comming")
  6757.                     console.log(troops)
  6758.                     list_support[j].troops = troops
  6759.                     UI.SuccessMessage("info coord: "+(keys.length-i)+" , get troops coming "+(list_support.length-j))
  6760.                 }
  6761.                 else if(list_support[j].type_attack.includes("support") &&
  6762.                         map_support_uploaded.has(list_support[j].commandId)
  6763.                 ){//update support comming if already exists in dropbox
  6764.                     console.log("update troops coming")
  6765.                     let objTroops = map_support_uploaded.get(list_support[j].commandId)
  6766.                     list_support[j].troops = objTroops
  6767.  
  6768.                 }
  6769.                 else if (list_support[j].type_attack.includes("attack")) {//type_attack=="attack"
  6770.                     try {//in case a barb is taken and tw database is not yet updated will throw an error
  6771.                         let villageId=mapVillages.get(list_support[j].coord_destination).villageId
  6772.                         if(!map_troops_home.has(list_support[j].coord_destination)){
  6773.                             let obj = await ajaxTroopsStationed(villageId)
  6774.                             console.log("troops home")
  6775.                             console.log(obj)
  6776.        
  6777.                             let serverTime=document.getElementById("serverTime").innerText
  6778.                             let serverDate=document.getElementById("serverDate").innerText.split("/")
  6779.                             serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  6780.                             let date_current=new Date(serverDate+" "+serverTime)
  6781.                             date_current.setDate(date_current.getDate()+7)
  6782.        
  6783.                             obj.uploadTime=date_current.getTime()
  6784.                             map_troops_home.set(list_support[j].coord_destination,obj)
  6785.                             UI.SuccessMessage("info coord: "+(keys.length-i)+" , get troops home "+(list_support.length-j))
  6786.        
  6787.                         }  
  6788.                     } catch (error) {
  6789.                         console.log(error)
  6790.                     }
  6791.  
  6792.                 }
  6793.             }
  6794.             map_coming.set(keys[i],list_support)
  6795.            
  6796.         }
  6797.         console.log("Done!");
  6798.     };
  6799.     await run();
  6800.     var stop_get_troops=new Date().getTime()
  6801.     console.log("time get troops "+(stop_get_troops-start_get_troops))
  6802.  
  6803.     console.log("support outgoing")
  6804.     console.log(map_going)
  6805.     console.log("support coming")
  6806.     console.log(map_coming)
  6807.     console.log("troops home")
  6808.     console.log(map_troops_home)
  6809.  
  6810.     //merge map_going and map_coming
  6811.     if(map_going !=undefined){// no commands going
  6812.         Array.from(map_going.keys()).forEach(key=>{
  6813.             let obj_going=map_going.get(key)
  6814.             if(map_coming.has(obj_going.coord_destination)){
  6815.                 // console.log("map coming update coord")
  6816.                 let list_coming=map_coming.get(obj_going.coord_destination)
  6817.                 for(let i=0;i<list_coming.length;i++){
  6818.                     if(key==list_coming[i].commandId){
  6819.                         list_coming[i].troops = obj_going.troops
  6820.                         map_coming.set(obj_going.coord_destination, list_coming)
  6821.                         break;
  6822.                     }
  6823.                 }
  6824.             }else{
  6825.                 map_coming.set(obj_going.coord_destination,[obj_going])
  6826.                 // console.log("map coming add coord")
  6827.    
  6828.             }
  6829.            
  6830.         })
  6831.         console.log("support coming after merge")
  6832.         // console.log(map_coming)
  6833.  
  6834.     }
  6835.  
  6836.  
  6837.  
  6838.     let map_attack_dropbox = new Map()
  6839.     /////////////////////////////////////////////////////////////////////////get and prelucrate  map commands attacks//////////////
  6840.     try {
  6841.         let decompressedData = await decompress(await data_attack.arrayBuffer() , 'gzip');  
  6842.         map_attack_dropbox=new Map(JSON.parse(decompressedData))
  6843.  
  6844.     } catch (error) {
  6845.         console.log("erorrrrr map attack from dropbox")
  6846.         map_attack_dropbox=new Map()
  6847.     }
  6848.  
  6849.     //if  database is stored locally
  6850.     if(await localBase.getItem(game_data.world+"map_attack_dropbox")!=undefined){
  6851.         try{
  6852.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "map_attack_dropbox"))
  6853.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6854.    
  6855.             let map_localBase=new Map( JSON.parse(decompressedData));
  6856.             // console.log("map_attack_dropbox upload",map_localBase)
  6857.             map_attack_dropbox=new Map([...map_localBase, ...map_attack_dropbox])
  6858.         } catch (error) {
  6859.             let map_localBase=new Map( JSON.parse(lzw_decode(await localBase.getItem(game_data.world + "map_attack_dropbox"))));
  6860.             map_attack_dropbox=new Map([...map_localBase, ...map_attack_dropbox])
  6861.         }
  6862.     }
  6863.     console.log("map_attack_dropbox", map_attack_dropbox)
  6864.  
  6865.  
  6866.     // console.log(data_attack_batch.length)
  6867.     //merge batch commands attacks
  6868.     for(let i=0;i<data_attack_batch.length;i++){
  6869.         let decompressedData = await decompress(await data_attack_batch[i].arrayBuffer() , 'gzip');  
  6870.  
  6871.         if(data_attack_batch[i] != "[]"){
  6872.             let map_attacks_batch = new Map(JSON.parse(decompressedData))
  6873.             map_attack_dropbox = new Map([...map_attack_dropbox, ...map_attacks_batch])
  6874.         }  
  6875.  
  6876.         let fileName = `${databaseName}/Commands_attack${i}.txt`
  6877.         if(await localBase.getItem(fileName) != undefined){
  6878.             try {
  6879.                 let decompressedDataBase64 = base64ToBlob(await localBase.getItem(fileName))
  6880.                 let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  6881.                 let map_localBase=new Map( JSON.parse(decompressedData));
  6882.                 // console.log("map_localBase_attacks",map_localBase)
  6883.                 map_attack_dropbox=new Map([...map_localBase, ...map_attack_dropbox])
  6884.             } catch (error) {
  6885.             }
  6886.         }
  6887.     }
  6888.     // console.log("map_attack_dropbox", map_attack_dropbox)
  6889.  
  6890.  
  6891.  
  6892.     console.log("map_going_attacks",map_going_attacks)
  6893.  
  6894.     if(map_going_attacks !=undefined){// no commands going
  6895.         Array.from(map_going_attacks.keys()).forEach(key=>{
  6896.             try {
  6897.                 let obj=map_going_attacks.get(key)
  6898.                 obj.coord_destination_id=mapVillages.get(obj.coord_destination).villageId
  6899.                 obj.player_destination_name=mapVillages.get(obj.coord_destination).playerName
  6900.                 obj.player_destination_id=mapVillages.get(obj.coord_destination).playerId
  6901.                 map_attack_dropbox.set(key,obj)
  6902.             } catch (error) {
  6903.                 console.log("command attack to barb")
  6904.                 console.log(error)
  6905.             }
  6906.         })
  6907.     }
  6908.    
  6909.  
  6910.  
  6911.  
  6912.  
  6913.    
  6914.  
  6915.  
  6916.     return new Promise(async(resolve,reject)=>{
  6917.  
  6918.         // console.log("map_dropbox_coming")
  6919.         // console.log(map_support_dropbox)
  6920.         // console.log("map_dropbox_home")
  6921.         // console.log(map_troops_home_dropbox)
  6922.  
  6923.        
  6924.         let serverTime=document.getElementById("serverTime").innerText
  6925.         let serverDate=document.getElementById("serverDate").innerText.split("/")
  6926.         serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  6927.         let date_current=new Date(serverDate+" "+serverTime).getTime()
  6928.         let date_current_commands=serverDate+" "+serverTime
  6929.  
  6930.  
  6931.  
  6932.         map_troops_home_dropbox=new Map([...map_troops_home_dropbox, ...map_troops_home])
  6933.         // console.log("map_troops_home_dropbox merge")
  6934.         // console.log(map_troops_home_dropbox)
  6935.         //delete from map troops home if it's older than a week
  6936.         Array.from(map_troops_home_dropbox.keys()).forEach(key=>{
  6937.             if(date_current>map_troops_home_dropbox.get(key).uploadTime){
  6938.                 map_troops_home_dropbox.delete(key)
  6939.             }
  6940.         })
  6941.  
  6942.  
  6943.         // update map from dropbox with the new data
  6944.         Array.from(map_coming.keys()).forEach(key=>{
  6945.             let list_coming=map_coming.get(key)
  6946.             if(map_support_dropbox.has(key)){
  6947.                 let list_dropbox=map_support_dropbox.get(key)
  6948.                 list_dropbox=list_dropbox.concat(list_coming)
  6949.                 console.log(list_dropbox)
  6950.                 var list_concat =[...new Map(list_dropbox.map(item => [item["commandId"], item])).values()]
  6951.                 // console.log("list concat")
  6952.                 list_concat.sort((o1,o2)=>{
  6953.                     return (new Date(o1.landing_time).getTime()>new Date(o2.landing_time).getTime())?1:
  6954.                     (new Date(o1.landing_time).getTime()<new Date(o2.landing_time).getTime())?-1:0
  6955.                 })
  6956.                 // console.log(list_concat)
  6957.                 if(list_concat.length==0){
  6958.                     map_support_dropbox.delete(key)
  6959.                     console.log("list is empty, removed")
  6960.                 }  
  6961.                 else
  6962.                     map_support_dropbox.set(key,list_concat)
  6963.             }
  6964.             else{
  6965.                 console.log("list coming")
  6966.                 list_coming.sort((o1,o2)=>{
  6967.                     return (new Date(o1.landing_time).getTime()>new Date(o2.landing_time).getTime())?1:
  6968.                     (new Date(o1.landing_time).getTime()<new Date(o2.landing_time).getTime())?-1:0
  6969.                 })
  6970.                 // console.log(list_coming)
  6971.                 map_support_dropbox.set(key,list_coming)
  6972.             }
  6973.         })
  6974.         // console.log("map_support_dropbox", map_support_dropbox)
  6975.  
  6976.         //if a command arrived  delete from map
  6977.         Array.from(map_support_dropbox.keys()).forEach(key=>{
  6978.             let list_support=map_support_dropbox.get(key)
  6979.             // console.log(list_support)
  6980.             if(list_support.length==0){
  6981.                 console.log(map_support_dropbox.has(key))
  6982.                 map_support_dropbox.delete(key)
  6983.                 // console.log(map_support_dropbox.has(key))
  6984.  
  6985.                 console.log(key)
  6986.                 console.log("delete coord from map support dropbox")
  6987.             }
  6988.             else{
  6989.                 for(let i=0;i<list_support.length;i++){
  6990.                     let date_land=new Date(list_support[i].landing_time).getTime()
  6991.                     if(date_current>date_land || list_support[i].landing_time == ""){
  6992.                         list_support.splice(i,1)
  6993.                         i--;
  6994.                     }
  6995.                  
  6996.                 }
  6997.                 map_support_dropbox.set(key,list_support)
  6998.             }
  6999.  
  7000.         })
  7001.         // console.log(map_support_dropbox)
  7002.         //delete  map commands attacks if it's older than 1 week
  7003.         Array.from(map_attack_dropbox.keys()).forEach(key=>{
  7004.             let obj=map_attack_dropbox.get(key)
  7005.             let date_upload=new Date(obj.uploadTime).getTime()
  7006.  
  7007.             if(date_current > date_upload)
  7008.                 map_attack_dropbox.delete(key)
  7009.         })
  7010.  
  7011.         //update status map
  7012.         let obj_status={
  7013.             name:game_data.player.name,
  7014.             command_date:date_current_commands,
  7015.         }
  7016.        
  7017.  
  7018.         if(mapStatus.has(game_data.player.id.toString())){
  7019.             let obj_update=mapStatus.get(game_data.player.id.toString())
  7020.             mapStatus.set(game_data.player.id.toString(), {...obj_update, ...obj_status} )
  7021.         }
  7022.         else{
  7023.             mapStatus.set(game_data.player.id.toString(),obj_status)
  7024.         }
  7025.  
  7026.  
  7027.         UI.SuccessMessage("compressing database, wait few seconds",2000)
  7028.        
  7029.         let timeStartUpload = new Date().getTime()
  7030.         let data_status=JSON.stringify(Array.from(mapStatus.entries()))
  7031.  
  7032.         let commandsAttacks = Array.from(map_attack_dropbox.entries())
  7033.         let commandsSupport = Array.from(map_support_dropbox.entries())
  7034.         let troopsHome = Array.from(map_troops_home_dropbox.entries())
  7035.  
  7036.         let sizeCommandsAttacksDB = formatBytes(new TextEncoder().encode(JSON.stringify(commandsAttacks)).length)
  7037.         let sizeCommandsSupportDB = formatBytes(new TextEncoder().encode(JSON.stringify(commandsSupport)).length)
  7038.         let sizeTroopsHomeDB = formatBytes(new TextEncoder().encode(JSON.stringify(troopsHome)).length)
  7039.  
  7040.  
  7041.         console.log("----------------------------------------------------")
  7042.         // console.log(commandsSupport)
  7043.         let splitByAttacks = Math.ceil(commandsAttacks.length /nrFiles)
  7044.         let splitBySupport = Math.ceil(commandsSupport.length /nrFiles)
  7045.         let splitByTroopsHome = Math.ceil(troopsHome.length /nrFiles)
  7046.  
  7047.  
  7048.         const run = async () => {
  7049.             console.log("Starting...");
  7050.             for (let i = 0; i < nrFiles; i++) {
  7051.                 //save command attacks
  7052.                 let subList = commandsAttacks.slice(i * splitByAttacks, (i+1) * splitByAttacks)
  7053.  
  7054.                 let compressedData = await compress(JSON.stringify(subList), 'gzip')
  7055.                 let base64CompressedData = await blobToBase64(compressedData)
  7056.  
  7057.                 let fileName = `${databaseName}/Commands_attack${i}.gz`
  7058.                 let fileNameLocal = `${databaseName}/Commands_attack${i}.txt`
  7059.  
  7060.                 await Promise.all([
  7061.                     uploadFile(compressedData,fileName,dropboxToken).catch(err=>alert(err)),
  7062.                     localBase.setItem(fileNameLocal, base64CompressedData)
  7063.                 ])
  7064.  
  7065.                 //save support
  7066.                 let subListSupport = commandsSupport.slice(i * splitBySupport, (i+1) *splitBySupport)
  7067.                 let subListTroopsHome = troopsHome.slice(i * splitByTroopsHome, (i+1) *splitByTroopsHome)
  7068.  
  7069.                 let data_list=[subListSupport,subListTroopsHome]
  7070.  
  7071.                 compressedData =  await compress(JSON.stringify(data_list), 'gzip')
  7072.                 base64CompressedData = await blobToBase64(compressedData)
  7073.                 fileName = `${databaseName}/Support${i}.gz`
  7074.                 fileNameLocal = `${databaseName}/Support${i}.txt`
  7075.  
  7076.                 let base64CompressedDataSupport = await blobToBase64(await compress(JSON.stringify(subListSupport), 'gzip'))
  7077.                 let base64CompressedDataSupportHome = await blobToBase64(await compress(JSON.stringify(subListTroopsHome), 'gzip'))
  7078.                 await Promise.all([
  7079.                     uploadFile(compressedData,fileName,dropboxToken).catch(err=>alert(err)),
  7080.                     localBase.setItem(fileNameLocal, base64CompressedDataSupport),
  7081.                     localBase.setItem(fileNameLocal+"Home", base64CompressedDataSupportHome),
  7082.  
  7083.                 ])
  7084.             }  
  7085.         }
  7086.         await run();
  7087.  
  7088.  
  7089.  
  7090.         let compressedData = await compress(data_status, 'gzip')
  7091.         let result_Status=await uploadFile(compressedData, filename_status_upload,dropboxToken).catch(err=>alert(err))
  7092.  
  7093.         if(result_Status=="succes"){
  7094.             console.log("here save status")
  7095.             document.getElementById("progress_support").innerText=map_coming.size+" coords"
  7096.             document.getElementById("progress_all").innerText="done";
  7097.             var data=JSON.stringify(Array.from(resultSupport.map_exist_support.entries()))
  7098.             localStorage.setItem(game_data.world+"map_exist_support",data)
  7099.  
  7100.             let timeStopUpload = new Date().getTime();
  7101.             let totalTimeUpload =  Math.round(((timeStopUpload - timeStartUpload) / 1000) * 100) / 100
  7102.             UI.SuccessMessage(`<b>Upload commands done </b> <br> <br>
  7103.                                 Upload time: ${totalTimeUpload} sec <br>
  7104.  
  7105.                                 <center>
  7106.                                     <table style ="border: 1px solid black;border-collapse: collapse">
  7107.                                         <tr>
  7108.                                             <td colspan="3" style = "text-align: center;border: 1px solid black;border-collapse: collaps;font-weight: bold;padding:10px">
  7109.                                                 Database details
  7110.                                             </td>
  7111.                                         </tr>
  7112.                                         <tr>
  7113.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Type</td>
  7114.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Total Number</td>
  7115.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Size DB</td>
  7116.                                         </tr>
  7117.                                         <tr>
  7118.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Commands attack</td>
  7119.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${commandsAttacks.length}</td>
  7120.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collaps;padding:5px">${sizeCommandsAttacksDB}</td>
  7121.                                         </tr>
  7122.                                         <tr>
  7123.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Commands support</td>
  7124.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${commandsSupport.length}</td>
  7125.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${sizeCommandsSupportDB}</td>
  7126.                                         </tr>
  7127.                                         <tr>
  7128.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">Troops Home</td>
  7129.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${troopsHome.length}</td>
  7130.                                             <td style = "text-align: center;border: 1px solid black;border-collapse: collapse;padding:5px">${sizeTroopsHomeDB}</td>
  7131.                                         </tr>
  7132.                                 </table>
  7133.                               </center>
  7134.  
  7135.                                 `,10000)
  7136.  
  7137.             resolve({
  7138.                 totalTimeUpload:totalTimeUpload,
  7139.                 status: "success"
  7140.             })
  7141.         }
  7142.         else{
  7143.             reject("error upload commands")
  7144.         }
  7145.     })
  7146.  
  7147. }
  7148.  
  7149.  
  7150. /////////////////////////////////////////////get troops coming from each village on incomings page//////////////////////////////////////////
  7151.  
  7152. function ajaxTroopsComing(commandId){
  7153.     return new Promise((resolve,reject)=>{
  7154.         let units=game_data.units.slice()
  7155.         if(units.includes("militia")){
  7156.             units.pop()
  7157.         }
  7158.  
  7159.         let startAjax=new Date().getTime()
  7160.         $.ajax({
  7161.             url: game_data.link_base_pure+`info_command&ajax=details&id=${commandId}`,
  7162.             method: 'get',
  7163.             success: (data) => {
  7164.                 let troops={}
  7165.                 if(data.units!=undefined){
  7166.                     troops=data.units
  7167.                     Object.keys(troops).forEach(key=>{
  7168.                         troops[key]=parseInt(troops[key].count)
  7169.                     })
  7170.                 }
  7171.                 else{
  7172.                     Object.keys(units).forEach(key=>{
  7173.                         troops[units[key]]=0
  7174.                     })
  7175.                 }
  7176.                 let stopAjax=new Date().getTime()
  7177.                 let difAjax=stopAjax-startAjax
  7178.                 console.log("wait ",difAjax)
  7179.                 window.setTimeout(()=>{
  7180.                     resolve(troops)
  7181.                 },200-difAjax)
  7182.  
  7183.             },error:(data)=>{
  7184.                 reject(data)
  7185.             }
  7186.  
  7187.         })
  7188.     })
  7189. }
  7190.  
  7191.  
  7192. /////////////////////////////////////////////get troops at home from each village on incomings page//////////////////////////////////////////
  7193.  
  7194. function ajaxTroopsStationed(villageId){
  7195.     return new Promise((resolve,reject)=>{
  7196.  
  7197.         let startAjax=new Date().getTime()
  7198.         $.ajax({
  7199.             url:game_data.link_base_pure + `map&ajax=map_info&source=${villageId}&target=${villageId}&`,
  7200.             method: 'get',
  7201.             success: (response) => {
  7202.                 // console.log(response)
  7203.                 let units=game_data.units
  7204.                 let obj_troops={}
  7205.                 let obj_result={}
  7206.                 for(let i=0;i<units.length-1;i++){
  7207.                     obj_troops[units[i]]=parseInt(response.units[units[i]].count.home)+parseInt(response.units[units[i]].count.foreign)
  7208.                 }
  7209.                 let wallLevel,farmLevel,flagName,LoyaltyLevel
  7210.                 wallLevel=response.buildings.wall
  7211.                 farmLevel=response.buildings.farm
  7212.                 LoyaltyLevel=response.mood
  7213.                 // console.log(response.flag)
  7214.                 if(response.flag!=undefined)
  7215.                     flagName =response.flag.short_desc
  7216.                 else
  7217.                     flagName="none"
  7218.                 // console.log(obj_troops)
  7219.                 // console.log("wallLevel: "+wallLevel)
  7220.                 // console.log("farmLevel: "+farmLevel)
  7221.                 // console.log("flagName: "+flagName)
  7222.                 // console.log("LoyaltyLevel: "+LoyaltyLevel)
  7223.  
  7224.                 obj_result.obj_troops=obj_troops
  7225.                 obj_result.wallLevel=wallLevel
  7226.                 obj_result.farmLevel=farmLevel
  7227.                 obj_result.flagName=flagName
  7228.                 obj_result.LoyaltyLevel=LoyaltyLevel
  7229.  
  7230.    
  7231.                 let stopAjax=new Date().getTime()
  7232.                 let difAjax=stopAjax-startAjax
  7233.                 console.log("wait ",difAjax)
  7234.                 window.setTimeout(()=>{
  7235.                     resolve(obj_result)
  7236.                 },200-difAjax)
  7237.  
  7238.             },error:(data)=>{
  7239.                 reject(data)
  7240.             }
  7241.  
  7242.         })
  7243.  
  7244.     })
  7245. }
  7246.  
  7247.  
  7248.  
  7249.  
  7250. //////////////////////////////////////////////main table + all the logic for creating main table///////////////////////////////////////////////
  7251. var mapAttacksVillageId=new Map()
  7252.  
  7253. async function viewSupport(){
  7254.     if(document.getElementById("div_container")!=null)
  7255.         document.getElementById("div_container").remove();
  7256.     ///////////////////////////////////////////////////////////////////main table//////////////////////////////////////////////////////////
  7257.     let html_info=`
  7258.         <div id="div_container_view" class="ui-widget-content div_remove" style="height:auto;background-color:${backgroundColor};cursor:move;z-index:50;width:${widthInterfaceOverview}px">
  7259.         <div class="scriptHeader">
  7260.             <div style=" margin-top:10px;text-decoration: underline;text-decoration-color: ${titleColor}"><h2 >Overview Data</h2></div>
  7261.             <div style="position:absolute;top:10px;right: 10px;"><a href="#" ><img src="https://img.icons8.com/emoji/24/000000/cross-mark-button-emoji.png"/></a></div>
  7262.             <div style="position:absolute;top:8px;right: 35px;" id="div_minimize"><a href="#"><img src="https://img.icons8.com/plasticine/28/000000/minimize-window.png"/></a></div>
  7263.             <div style="position:absolute;top:10px;right: 92%;" id="page_upload" ><a href="#" onclick="$('#div_container_view').remove();getInterface()"><img src="https://img.icons8.com/officel/30/000000/long-arrow-left.png"/></a></div>
  7264.         </div>
  7265.  
  7266.         <div id="div_body">
  7267.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" onclick="createTableSettings()" style="margin:10px" value="Settings">
  7268.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_rank_attacker" style="margin:10px" value="Rank Attackers">
  7269.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_rank_defender" style="margin:10px" value="Rank Defenders">
  7270.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_upload_time" style="margin:10px" value="Upload Time">
  7271.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_get_coords" style="margin:10px" value="Get Coords">
  7272.             <input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_op_spotter" style="margin:10px" value="Tribe OP Spotter">
  7273.             <div id="div_settings" style="margin:10px" hidden> </div>
  7274.             <div id="div_rank" style="margin:10px" hidden> </div>
  7275.             <div id="div_rank_attacker" style="margin:10px" hidden> </div>
  7276.             <div id="div_rank_defender" style="margin:10px" hidden> </div>
  7277.             <div id="div_upload_time" style="margin:10px" hidden> </div>
  7278.             <div id="div_get_coords" style="margin:10px" hidden> </div>
  7279.    
  7280.             <div style="display:flex;justify-content: center;width:100%">
  7281.                 <div style="width: 45%;margin:15px">
  7282.                     <table id="table_search"  border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};">
  7283.                         <tr>
  7284.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7285.                                 <center style="margin:5px"><font color="${titleColor}"><p>search by coord</p></font></center>
  7286.                             </td>
  7287.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7288.                                 <center style="margin:5px"> <input id="input_search" type="text"  style="margin:10px" placeholder="coord"></center>
  7289.                             </td>
  7290.                         </tr>
  7291.                     </table>
  7292.                 </div>
  7293.                 <div style="width: 45%;margin:15px" >
  7294.                     <table id="table_select_info"  border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};" hidden>
  7295.                         <tr>
  7296.                             <td style="text-align:center; width:auto; background-color:${headerColor};text-align:center">
  7297.                                 <input type="checkbox"   id="checkbox_my_info">
  7298.                             </td>
  7299.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7300.                                 <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7301.                                     <font color="${titleColor}" style="margin-top:8px;margin-right:5px"><p>My Info</p></font>
  7302.                                     <a href="#" onclick="UI.InfoMessage('Show information on the map for only your own villages',5000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7303.                                 </div>
  7304.                             </td>
  7305.                             <td rowspan="4" style="text-align:center; width:auto; background-color:${headerColor}">
  7306.                                 <center><input class="btn evt-confirm-btn btn-confirm-yes" type="button" id="btn_show_info" style="margin:10px" value="Show Map"></center>
  7307.                             </td>                        
  7308.                         </tr>
  7309.                         <tr>
  7310.                             <td style="text-align:center; width:auto; background-color:${headerColor};text-align:center">
  7311.                                 <input type="checkbox"   id="checkbox_tribe_info">
  7312.                             </td>
  7313.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7314.                                 <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7315.                                     <font color="${titleColor}" style="margin-top:8px;margin-right:5px"><p>Tribe Info</p></font>
  7316.                                     <a href="#" onclick="UI.InfoMessage('Show information on the map for all tribe villages, except yours',5000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7317.                                 </div>
  7318.                             </td>                    
  7319.                         </tr>
  7320.                         <tr>
  7321.                             <td style="text-align:center; width:auto; background-color:${headerColor};text-align:center">
  7322.                                 <input type="checkbox"   id="checkbox_enemy_info">
  7323.                             </td>
  7324.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7325.                                 <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7326.                                     <font color="${titleColor}" style="margin-top:8px;margin-right:5px"><p>Enemy Info</p></font>
  7327.                                     <a href="#" onclick="UI.InfoMessage('Show information on the map for all enemy villages',5000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7328.                                 </div>
  7329.                             </td>                    
  7330.                         </tr>
  7331.                         <tr>
  7332.                             <td style="text-align:center; width:auto; background-color:${headerColor};text-align:center">
  7333.                                 <input type="checkbox"   id="checkbox_all_info">
  7334.                             </td>
  7335.                             <td style="text-align:center; width:auto; background-color:${headerColor}">
  7336.                                 <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7337.                                     <font color="${titleColor}" style="margin-top:8px;margin-right:5px"><p>All Info</p></font>
  7338.                                     <a href="#" onclick="UI.InfoMessage('Show information on the map for all villages (allies + enemies)',5000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7339.                                 </div>
  7340.                             </td>                    
  7341.                         </tr>
  7342.                     </table>
  7343.                 </div>
  7344.             </div>
  7345.  
  7346.             <br>
  7347.  
  7348.             <table id="table_view" class="" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;">
  7349.             <thead>
  7350.             <tr>
  7351.                 <td style="text-align:center; width:auto; background-color:${headerColor}" colspan="2">
  7352.                 <center style="margin:1px"><font color="${titleColor}">total</font></center>
  7353.                 </td>
  7354.                 <td style="text-align:center; width:auto; background-color:${headerColor}">
  7355.                     <center style="margin:1px;font-size:16px"><font color="${titleColor}"><a href="#"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/unit/att.png" id="sort_by_attacks"></a><p id="header_attacks">(0)</p></font></center>
  7356.                 </td>
  7357.                 <td style="text-align:center; width:auto; background-color:${headerColor}">
  7358.                         <center style="margin:1px;font-size:16px"><font color="${titleColor}"><a href="#"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/support.png" id="sort_by_supports"></a><p id="header_supports">(0)</p></font></center>
  7359.                 </td>
  7360.                 <td style="text-align:center; width:auto; background-color:${headerColor}">
  7361.                     <center style="margin:1px;font-size:16px"><font color="${titleColor}"><a href="#"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/snob.png" id="sort_by_nobles"></a><p id="header_nobles">(0)</p></font></center>
  7362.                 </td>
  7363.                 <td style="text-align:center; width:auto; background-color:${headerColor}">
  7364.                     <center style="margin:1px;font-size:16px">
  7365.                         <font color="${titleColor}">
  7366.                             <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7367.                                 <a href="#" style="margin-right:10px"><img src="https://img.icons8.com/office/20/000000/sniper-rifle.png" id="sort_by_snipes"></a>
  7368.                                 <a href="#" onclick="UI.InfoMessage('List of snipes <br> <b>red</b> -> snipe is needed <br> <b>green</b> -> village is already sniped',8000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7369.                             </div>
  7370.                             <p id="header_snipes">(0/0)</p>
  7371.                             </font>
  7372.                         </center>
  7373.                    
  7374.                 </td>
  7375.                 <td style="text-align:center; width:auto; background-color:${headerColor}">
  7376.                     <center style="margin:1px;font-size:16px">
  7377.                         <font color="${titleColor}">
  7378.                             <div style="display:flex; flex-direction: row; justify-content: center; align-items: center">
  7379.                                 <a href="#" style="margin-right:10px"><img src="https://img.icons8.com/ultraviolet/20/000000/horror.png" id="sort_by_recaps"></a>
  7380.                                 <a href="#" onclick="UI.InfoMessage('List of recaps <br> <b>red</b> -> recap is needed  <br> <b>green</b> -> village is already recapped <br><br> recap is needed if nr nobles >=4 and it is not a train',8000)"><img src="https://dsen.innogamescdn.com/asset/dbeaf8db/graphic/questionmark.png" style="width: 13px; height: 13px"/></a>
  7381.                             </div>
  7382.                             <p id="header_recaps">(0/0)</p>
  7383.                         </font>
  7384.                     </center>
  7385.                 </td>
  7386.             </tr>
  7387.             </thead>
  7388.             </table>
  7389.         </div>
  7390.         </div>
  7391.        
  7392.         `;
  7393.    
  7394.  
  7395.  
  7396.    ////////////////////////////////////// //delete/////////////////////////////////////////////////////////////////////
  7397.     // $("#table_search").hide()
  7398.     // $("#table_view").hide()
  7399.  
  7400.     // $(".btn-confirm-yes").eq(0).hide()
  7401.     // $(".btn-confirm-yes").eq(1).hide()
  7402.     // $(".btn-confirm-yes").eq(2).hide()
  7403.  
  7404.  
  7405.  
  7406.  
  7407.     ////////////////////////////////////////add and remove window from page///////////////////////////////////////////
  7408.     $("#div_container_view").remove()
  7409.     $("#contentContainer").eq(0).prepend(html_info);
  7410.     $("#mobileContent").eq(0).prepend(html_info);
  7411.  
  7412.    
  7413.     $("#div_minimize").on("click",()=>{
  7414.         if($('#div_container_view').width() == widthInterfaceOverview){
  7415.             $('#div_container_view').css({'width' : '120px'});
  7416.             $('#div_body').hide();
  7417.             $("#page_upload").hide()
  7418.         }
  7419.         else{
  7420.             $('#div_container_view').css({'width' : `${widthInterfaceOverview}px`});
  7421.             $('#div_body').show();
  7422.             $("#page_upload").show()
  7423.  
  7424.         }
  7425.     })
  7426.  
  7427.     if(game_data.device == "desktop"){
  7428.         $("#div_container_view").draggable();
  7429.         $("#div_container_view").css("position","fixed");
  7430.     }
  7431.  
  7432.  
  7433.  
  7434.  
  7435.     if(typeof(TWMap)!="undefined"){
  7436.         $("#table_select_info").show()
  7437.     }
  7438.  
  7439.     UI.SuccessMessage("Loading data..", 5000)
  7440.  
  7441.  
  7442.     let timeDownloadStart = new Date().getTime()
  7443.     var [mapVillages, map_reports, map_incomings,data_support, map_attacks,map_status, map_history_upload, map_troops_home ,status_chart]=await Promise.all([
  7444.             getInfoVillages(),
  7445.             readFileDropbox(filename_reports),
  7446.             readFileDropbox(filename_incomings),
  7447.             readFileDropbox(filename_support),
  7448.             readFileDropbox(filename_commands_attack),
  7449.             readFileDropbox(filename_status_upload),
  7450.             readFileDropbox(filename_history_upload),
  7451.             readFileDropbox(filename_troops_home),
  7452.             insertChartLibrary()])
  7453.         .catch(err=>{alert(err)})
  7454.  
  7455.        
  7456.         var [map_reports, map_incomings, map_attacks, map_status, map_history_upload, data_support, map_troops_home] = await Promise.all([
  7457.             decompress(await map_reports.arrayBuffer(), 'gzip'),
  7458.             decompress(await map_incomings.arrayBuffer(), 'gzip'),
  7459.             decompress(await map_attacks.arrayBuffer(), 'gzip'),
  7460.             decompress(await map_status.arrayBuffer(), 'gzip'),
  7461.             decompress(await map_history_upload.arrayBuffer(), 'gzip'),
  7462.             decompress(await data_support.arrayBuffer(), 'gzip'),
  7463.             decompress(await map_troops_home.arrayBuffer(), 'gzip'),
  7464.         ]).catch(err=>{alert(err)})    
  7465.  
  7466.  
  7467.         map_reports=new Map(JSON.parse(map_reports))
  7468.         map_incomings=new Map(JSON.parse(map_incomings))
  7469.         map_attacks=new Map(JSON.parse(map_attacks))
  7470.         map_status=new Map(JSON.parse(map_status))
  7471.         map_history_upload=new Map(JSON.parse(map_history_upload))
  7472.  
  7473.         map_troops_home=new Map(JSON.parse(map_troops_home))
  7474.  
  7475.         let map_coming=new Map(JSON.parse(data_support)[0])
  7476.         let map_home=new Map(JSON.parse(data_support)[1])
  7477.  
  7478.         console.log(mapVillages)
  7479.         console.log(map_troops_home)
  7480.  
  7481.     let map_playerId=new Map()
  7482.     // console.log("first",map_home);
  7483.     let commandAttacksBatch = await Promise.all(commandsAttacksPromises).catch(err=>{alert(err)})
  7484.     let supportBatch = await Promise.all(supportPromises).catch(err=>{alert(err)})
  7485.  
  7486.     const run = async () => {
  7487.         console.log("Starting...");
  7488.         for (let i = 0; i < commandAttacksBatch.length; i++) {
  7489.             let [decompressedAttackBatch, decompressedSupportBatch]=await Promise.all([
  7490.                     decompress(await commandAttacksBatch[i].arrayBuffer(), 'gzip'),
  7491.                     decompress(await supportBatch[i].arrayBuffer(), 'gzip'),
  7492.                 ]).catch(err=>{alert(err)})
  7493.  
  7494.             let map_attacks_batch = new Map(JSON.parse(decompressedAttackBatch))
  7495.             map_attacks = new Map([...map_attacks, ...map_attacks_batch])
  7496.  
  7497.             let map_support_batch = new Map(JSON.parse(decompressedSupportBatch)[0])
  7498.             let map_troops_home_batch = new Map(JSON.parse(decompressedSupportBatch)[1])
  7499.    
  7500.  
  7501.             map_coming = new Map([...map_coming, ...map_support_batch])
  7502.             map_home = new Map([...map_home, ...map_troops_home_batch])
  7503.  
  7504.  
  7505.         }  
  7506.     }
  7507.     await run();
  7508.  
  7509.  
  7510.  
  7511.     let timeDownloadStop = new Date().getTime()
  7512.     console.log("time download DB: " + (timeDownloadStop - timeDownloadStart))
  7513.  
  7514.  
  7515.     let timeProcessingStart = new Date().getTime()
  7516.  
  7517.  
  7518.  
  7519.     map_incomings = removeLandedIncomings(map_incomings)
  7520.  
  7521.     // console.log("mapVillages",mapVillages)
  7522.     // console.log("map_coming",map_coming)
  7523.     // console.log("map_home",map_home)
  7524.     // console.log("map_reports",map_reports)
  7525.     // console.log("map_incomings",map_incomings)
  7526.     // console.log("map_attacks",map_attacks)
  7527.  
  7528.  
  7529.  
  7530.     let serverTime=document.getElementById("serverTime").innerText
  7531.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  7532.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  7533.     let date_current=new Date(serverDate+" "+serverTime).getTime()
  7534.     createTableSettings()
  7535.     $("#div_settings").hide()
  7536.  
  7537.     let pop_snipe=parseInt(document.getElementById("settings_pop").value)
  7538.     if(Number.isNaN(pop_snipe))
  7539.         pop_snipe=1000
  7540.  
  7541.  
  7542.     //filters
  7543.     let list_filters=[]
  7544.     $('#div_settings input[type=checkbox]:checked').each(function (index,elem) {
  7545.        
  7546.         list_filters.push(elem.value)
  7547.         // console.log(elem.value)
  7548.        
  7549.     });
  7550.     // console.log("list_filters",list_filters)
  7551.  
  7552.     Array.from(map_coming.keys()).forEach(key=>{
  7553.         try {
  7554.             let obj_output={}
  7555.             let playerId=mapVillages.get(key).playerId
  7556.             // console.log(playerId)
  7557.             let villageId=mapVillages.get(key).villageId
  7558.             let playerName=mapVillages.get(key).playerName
  7559.            
  7560.             let list_coming=map_coming.get(key)
  7561.             let hasAttacks=false
  7562.             let nrAttacks=0,nr_supports=0,nrNobles=0;
  7563.             let snipe=false,sniped=false,recap=false,recaped=false;
  7564.  
  7565.             if(tribemates.includes(playerName.toLowerCase())){
  7566.                 // console.log("list_coming",list_coming)
  7567.                 //filter incomings
  7568.                 for(let i=0;i<list_coming.length;i++){
  7569.                     let landing_time=new Date(list_coming[i].landing_time).getTime()
  7570.                     let deleteIncoming=false
  7571.                     //remove if there is an ignored attack/support
  7572.                     if(list_filters.includes("hide_ignored") && list_coming[i].unignored==false){
  7573.                         deleteIncoming=true
  7574.                         console.log("delete ignored attack")
  7575.                     }
  7576.                     //remove if there is a support
  7577.                     if(list_filters.includes("hide_supports") && list_coming[i].type_attack.includes("support")){
  7578.  
  7579.                         let landing_time_current=new Date(list_coming[i].landing_time).getTime()
  7580.                         for(let j=i+1;j<list_coming.length-1;j++){
  7581.                             let landing_time_next=new Date(list_coming[j].landing_time).getTime()//that means there a support which lands with no more than 600 ms before an attack
  7582.                             if(landing_time_next-landing_time_current>600){
  7583.                                 deleteIncoming=true
  7584.                                 console.log("delete support")
  7585.                                 break
  7586.                             }
  7587.                             else
  7588.                                 break;
  7589.                         }
  7590.  
  7591.                         if(i==list_coming.length-1){//if last incoming is a support then delete
  7592.                             deleteIncoming=true
  7593.                             console.log("delete support")
  7594.                         }
  7595.                        
  7596.  
  7597.  
  7598.                     }  
  7599.                     // remove if there is an attack/support further than x hours away
  7600.                     if(list_filters.includes("hide_further_attacks")){
  7601.                         let hours=parseInt(document.getElementById("settings_further").value)*3600*1000
  7602.                         if(Number.isNaN(hours))
  7603.                             hours=100*3600*1000
  7604.                         if((landing_time-date_current)>hours){
  7605.                             deleteIncoming=true
  7606.                             console.log("delete further attacks")
  7607.                         }
  7608.                     }  
  7609.                     // remove if there is an attack/support closer than x hours away
  7610.                     if(list_filters.includes("hide_closer_attacks")){
  7611.                         let hours=parseInt(document.getElementById("settings_closer").value)*3600*1000
  7612.                         if(Number.isNaN(hours))
  7613.                             hours=10*3600*1000
  7614.                         if((landing_time-date_current)<hours){
  7615.                             deleteIncoming=true
  7616.                             console.log("delete closer attacks")
  7617.                         }
  7618.                     }  
  7619.                    
  7620.                     //remove if an attack/def was sent and uploaded to dropbox but then the attacker withdrawn his command
  7621.                     if(playerId==game_data.player.id.toString()){
  7622.                         let map_exist_command=new Map(JSON.parse(localStorage.getItem(game_data.world+"map_exist_support")))
  7623.                         let keys_commandId=Array.from(map_exist_command.keys())
  7624.                         if(!keys_commandId.includes(list_coming[i].commandId)){// it means there is a command and in localstorage it is not
  7625.                             deleteIncoming=true
  7626.                             console.log("delete withdrawn command")
  7627.  
  7628.                         }
  7629.                     }
  7630.  
  7631.                        
  7632.                         //check if is a small/medium/big attack or a support
  7633.                         let coord_origin=list_coming[i].coord_origin
  7634.                         let playerId_origin=list_coming[i].player_origin_id
  7635.                         if(map_reports.has(coord_origin) && list_coming[i].type_attack.includes("attack") )
  7636.                         {
  7637.                             let idPlayer_dropbox
  7638.                             let type_dropbox
  7639.                             let nr_troupes_dropbox
  7640.            
  7641.                             let obj_report=map_reports.get(coord_origin);
  7642.                             var traveling=false
  7643.                             if(coord_origin == obj_report.coordAttacker){
  7644.                                 idPlayer_dropbox=obj_report.attackingPlayerId;
  7645.                                 type_dropbox=obj_report.typeAttacker;
  7646.                                 nr_troupes_dropbox=obj_report.nrTroupesAttacker
  7647.                                 traveling=true;
  7648.                             }
  7649.                             else if(coord_origin == obj_report.coordDefender){
  7650.                                 idPlayer_dropbox=obj_report.defendingPlayerId;
  7651.                                 type_dropbox=obj_report.typeDefender;
  7652.                                 nr_troupes_dropbox=obj_report.nrTroupesDefender
  7653.                                 traveling=false;
  7654.                             }
  7655.                             else{
  7656.                                 idPlayer_dropbox=obj_report.supporterPlayerId
  7657.                                 type_dropbox=obj_report.typeSupporter;
  7658.                                 nr_troupes_dropbox=obj_report.nrTroupesSupporter
  7659.                             }
  7660.            
  7661.                             if(idPlayer_dropbox == playerId_origin)
  7662.                             {
  7663.                    
  7664.                                 //calculate population
  7665.                                 let date_landing_report=new Date(obj_report.time_report)
  7666.                                 let distance=calcDistance(coord_origin,list_coming[i].coord_destination)
  7667.                                 let time_attack=0;
  7668.  
  7669.                                 let date_land=new Date(landing_time)
  7670.                                 // console.log(date_land)
  7671.                                 let labelName=list_coming[i].labelName
  7672.  
  7673.  
  7674.                                 if(labelName.includes("snob.png")){
  7675.                                     time_attack=nobleSpeed*distance
  7676.                                 }else if(labelName.includes("ram.png") || labelName.includes("catapult.png")){
  7677.                                     time_attack=ramSpeed*distance
  7678.                                 }else if(labelName.includes("sword.png")){
  7679.                                     time_attack=swordSpeed*distance
  7680.                                 }else if(labelName.includes("axe.png")){
  7681.                                     time_attack=axeSpeed *distance
  7682.                                 }
  7683.                                 if(traveling==false)
  7684.                                     time_attack=0;
  7685.  
  7686.                                 let newTypeAttack=list_coming[i].type_attack
  7687.                                 if(type_dropbox=="off"){
  7688.                                     let timeForRecruiting = (date_land.getTime()-time_attack)-date_landing_report.getTime()
  7689.                                     let pop_small_attack=(parseInt(document.getElementById("settings_small_attack").value)/20000)*100
  7690.                                     let pop_medium_attack=(parseInt(document.getElementById("settings_medium_attack").value)/20000)*100
  7691.                                    
  7692.                                     if(pop_medium_attack<pop_small_attack)
  7693.                                         alert("pop for medium attacks must be higher than pop for small attacks")
  7694.                                     if(Number.isNaN(pop_small_attack))
  7695.                                         pop_small_attack=(5000/20000)*100
  7696.                                     if(Number.isNaN(pop_medium_attack))
  7697.                                         pop_small_attack=(10000/20000)*100
  7698.  
  7699.                                     // console.log("time for recruiting",timeForRecruiting)
  7700.                                     // console.log("nr_troupes_dropbox",nr_troupes_dropbox)
  7701.                                     nr_troupes_dropbox=calcProductionTroupes(timeForRecruiting,nr_troupes_dropbox)    
  7702.                                     // console.log("nr_troupes_dropbox",nr_troupes_dropbox)
  7703.                                     // console.log(list_coming[i])
  7704.                                     if(nr_troupes_dropbox <= pop_small_attack)              
  7705.                                         newTypeAttack="attack_small.png"
  7706.                                     else if(nr_troupes_dropbox >pop_small_attack && nr_troupes_dropbox <= pop_medium_attack )
  7707.                                         newTypeAttack="attack_medium.png"
  7708.                                     else
  7709.                                         newTypeAttack="attack_large.png"
  7710.  
  7711.                                 }
  7712.                                 else if(type_dropbox.includes("def")){
  7713.                                     newTypeAttack="def"
  7714.                                 }
  7715.                                 list_coming[i].type_attack=newTypeAttack
  7716.                             }
  7717.                         }
  7718.  
  7719.  
  7720.  
  7721.                     //delete if filters is on
  7722.                     if(deleteIncoming==true){
  7723.                         list_coming.splice(i,1);
  7724.                         i--;
  7725.                     }
  7726.  
  7727.                 }
  7728.  
  7729.  
  7730.                 //counting attacks,supports, nobles, snipes, recaps
  7731.    
  7732.                 for(let i=0;i<list_coming.length;i++){
  7733.              
  7734.  
  7735.                     let landing_time=new Date(list_coming[i].landing_time).getTime()
  7736.                     if(landing_time>date_current){
  7737.                         if(list_coming[i].type_attack.includes("attack") || list_coming[i].type_attack.includes("def")){
  7738.                             nrAttacks++
  7739.                             hasAttacks=true
  7740.                         }
  7741.                         else{
  7742.                             nr_supports++  
  7743.                         }
  7744.                         if(list_coming[i].labelName.includes("snob")){
  7745.                             nrNobles++
  7746.  
  7747.                             //check for train and if exist check for snipe
  7748.                             for(let j=i+1;j<list_coming.length;j++){
  7749.                                 let landing_time_next=new Date(list_coming[j].landing_time).getTime()
  7750.                                 if(landing_time_next-landing_time==50 ||landing_time_next-landing_time==100 || landing_time_next-landing_time==150)
  7751.                                 {
  7752.                                     if(list_coming[i].coord_origin==list_coming[j].coord_origin )//there is a train
  7753.                                     {
  7754.                                         // if(list_coming[j].coord_destination == "391|447"){
  7755.                                         //     console.log(`train i: ${i}, j: ${j}`)
  7756.                                         //     console.log(list_coming[i])
  7757.                                         //     console.log(list_coming[j])
  7758.                                         // }
  7759.                                         let pop=0;
  7760.                                         let list_snipe_support=[]
  7761.                                         for(let k=j-1;k>=0;k--){
  7762.                                             // if(list_coming[j].coord_destination == "391|447"){
  7763.                                             //     console.log("search snipe")
  7764.                                             //     console.log(list_coming[k])
  7765.                                             // }
  7766.                                             if(list_coming[k].type_attack.includes("support")){//there is a snipe(support before second noble),check every support from left
  7767.                                                 let troops=list_coming[k].troops
  7768.                                                 Object.keys(troops).forEach(key=>{
  7769.                                                     pop+=troops[key]*troopsPop[key]
  7770.                                                 })
  7771.                                                 list_snipe_support.push(k)
  7772.                                             }
  7773.                                             else{
  7774.                                                 break
  7775.                                             }
  7776.                                         }
  7777.                                         // if(list_coming[k].coord_destination == "391|447"){
  7778.                                         //     console.log(list_snipe_support)
  7779.                                         // }
  7780.                                         if(pop>pop_snipe){
  7781.                                             sniped=true
  7782.                                             //this support is used for sniping and will be colored later
  7783.                                             for(let k=0;k<list_snipe_support.length;k++){
  7784.                                                 list_coming[list_snipe_support[k]].hasSupportSnipe=true
  7785.                                             }
  7786.                                         }
  7787.                                         snipe=true
  7788.                                     }
  7789.                                 }
  7790.                             }
  7791.                             //check if needs to be recaped
  7792.                             if(snipe==false && nrNobles>=4){
  7793.                                 recap=true
  7794.                             }
  7795.                             //check if it recaped buy someone from your tribe
  7796.                             if(snipe==false && nrNobles>=4 && tribemates.includes(list_coming[i].player_origin_name)){
  7797.                                 recaped=true
  7798.                             }
  7799.                         }
  7800.                     }
  7801.  
  7802.  
  7803.                 }
  7804.  
  7805.                 if(hasAttacks==true){
  7806.                     obj_output.homeInfo=map_home.get(key)
  7807.                     // nrAttacks++
  7808.                 }
  7809.                 let nrSnipes=(snipe==true)?1:0
  7810.                 let nrSniped=(sniped==true)?1:0
  7811.                 let nrRecaps=(recap==true)?1:0
  7812.                 let nrRecaped=(recaped==true)?1:0
  7813.  
  7814.                 obj_output.coord_destination_id=villageId
  7815.                 obj_output.list_coming=list_coming
  7816.  
  7817.                 obj_output.nrAttacks=nrAttacks
  7818.  
  7819.                 obj_output.nr_supports=nr_supports
  7820.                 obj_output.nrNobles=nrNobles
  7821.                
  7822.                 obj_output.nrSnipes=nrSnipes
  7823.                 obj_output.nrSniped=nrSniped
  7824.                 obj_output.nrRecaps=nrRecaps
  7825.                 obj_output.nrRecaped=nrRecaped
  7826.                 // console.log("for real: "+nrAttacks)
  7827.                 // console.log("hope so: "+obj_output.nrAttacks)
  7828.                 // console.log(obj_output)
  7829.                 // console.log("status snipe/recap")
  7830.                 // console.log(key)
  7831.                 // console.log(nrSnipes,nrSniped,nrRecaps,nrRecaped)
  7832.  
  7833.                 if(!map_playerId.has(playerId) && (nrAttacks>0 || nr_supports>0)){
  7834.                     map_playerId.set(playerId,{
  7835.                         nr_attacks_total:nrAttacks,
  7836.                         nr_supports_total:nr_supports,
  7837.                         nr_nobles_total:nrNobles,
  7838.                         list_coords:[obj_output],
  7839.                         player_destination_name:playerName,
  7840.                         player_destination_id:playerId,
  7841.                         nr_snipe_total:nrSnipes,
  7842.                         nr_sniped_total:nrSniped,
  7843.                         nr_recap_total:nrRecaps,
  7844.                         nr_recaped_total:nrRecaped
  7845.                     })
  7846.                 }
  7847.                 else{
  7848.                     let obj_update=map_playerId.get(playerId)
  7849.                     let list=obj_update.list_coords
  7850.                     list.push(obj_output)
  7851.                    
  7852.                     obj_update.list_coords=list
  7853.                     obj_update.nr_attacks_total+=nrAttacks
  7854.                     obj_update.nr_supports_total+=nr_supports
  7855.                     obj_update.nr_nobles_total+=nrNobles
  7856.                     obj_update.nr_snipe_total+=nrSnipes,
  7857.                     obj_update.nr_sniped_total+=nrSniped,
  7858.                     obj_update.nr_recap_total+=nrRecaps,
  7859.                     obj_update.nr_recaped_total+=nrRecaped
  7860.  
  7861.                     map_playerId.set(playerId,obj_update)
  7862.  
  7863.                 }
  7864.        
  7865.             }
  7866.         } catch (error) {
  7867.             console.log(error)
  7868.         }
  7869.  
  7870.            
  7871.        
  7872.     })
  7873.     // console.log(map_playerId)
  7874.    
  7875.  
  7876.  
  7877.  
  7878.     //sort table players by attacks
  7879.     map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  7880.         return (o1[1].nr_attacks_total>o2[1].nr_attacks_total)?-1:(o1[1].nr_attacks_total<o2[1].nr_attacks_total)?1:0;
  7881.     }))
  7882.     //sort tables for each coord by attacks
  7883.     Array.from(map_playerId.keys()).forEach(key=>{
  7884.         let obj=map_playerId.get(key)
  7885.         obj.list_coords.sort((o1,o2)=>{
  7886.             return (o1.nrAttacks>o2.nrAttacks)?-1:(o1.nrAttacks<o2.nrAttacks)?1:0
  7887.         })
  7888.         map_playerId.set(key,obj)
  7889.     })
  7890.  
  7891.  
  7892.  
  7893.     Array.from(map_playerId.keys()).forEach(key=>{
  7894.         let playerId = game_data.player.id + ""
  7895.         if(key != playerId){
  7896.             map_playerId.delete(key)
  7897.         }
  7898.     })
  7899.    
  7900.  
  7901.  
  7902.  
  7903.     /////////////////////////////////////////////////////////////////////////////////players table//////////////////////////////////////////////////////////
  7904.     createTablePlayers(map_playerId,mapVillages)
  7905.     sortInfoIncomings(map_playerId,mapVillages)
  7906.  
  7907.  
  7908.     //add event for search input
  7909.     $("#input_search").on("input",(event)=>{
  7910.         let text_input=event.target
  7911.         if(text_input.value!=undefined){
  7912.             if(text_input.value.match(/\d+\|\d+/)!=null){
  7913.                 let coord=text_input.value.match(/\d+\|\d+/)[0]
  7914.                 text_input.value=coord
  7915.                 // console.log(coord)
  7916.                 let playerId=mapVillages.get(coord).playerId
  7917.                 let villageId=mapVillages.get(coord).villageId
  7918.  
  7919.                 if($(`.table_player img[coord-id=${villageId}]`).is(":visible")==false)
  7920.                     $(`#table_view img[player-id=${playerId}]`).click();
  7921.  
  7922.                 if($(`.table_coord img[coord-id=${villageId}]`).is(":visible")==false)
  7923.                     $(`.table_player img[coord-id=${villageId}]`).click();
  7924.  
  7925.  
  7926.             }
  7927.         }
  7928.     })
  7929.  
  7930.  
  7931.  
  7932.     ///////////////////////////////////////////////////////////on map page///////////////////////////////////////////////////////////////////////////////////
  7933.  
  7934.     let fangs_cat=parseInt(document.getElementById("settings_fang_cat").value)
  7935.     let pop_small_attack=parseInt(document.getElementById("settings_small_attack").value)
  7936.     let pop_medium_attack=parseInt(document.getElementById("settings_medium_attack").value)
  7937.     pop_small_attack=(!Number.isNaN(pop_medium_attack))?pop_medium_attack:5000
  7938.     pop_medium_attack=(!Number.isNaN(pop_medium_attack))?pop_medium_attack:10000
  7939.     fangs_cat=(!Number.isNaN(fangs_cat))?fangs_cat:50
  7940.  
  7941.     //create a map with commands attacks, every coord has number of fangs,nukes,nobles
  7942.     //this part is for Enemy Info
  7943.    
  7944.    
  7945.     let mapVillageByIdFinal=new Map()
  7946.     let mapAttacksPlayersIdFinal=new Map()
  7947.  
  7948.     Array.from(map_reports.keys()).forEach(key=>{
  7949.  
  7950.         try {//if a village become a barb
  7951.             let obj_report=map_reports.get(key)
  7952.  
  7953.             let villageId=mapVillages.get(key).villageId
  7954.             let player_destination_name=mapVillages.get(key).playerName
  7955.             let player_destination_id=mapVillages.get(key).playerId
  7956.             let time_report=obj_report.time_report
  7957.  
  7958.             //get troops at home
  7959.             let troopsAtHome=null,time_report_home=null
  7960.             if(obj_report["troopsAtHome_"+key]!=undefined){
  7961.                 troopsAtHome=obj_report["troopsAtHome_"+key]
  7962.                 time_report_home=obj_report["time_report_home_"+key]
  7963.  
  7964.             }
  7965.        
  7966.            
  7967.             //get troops away
  7968.             let troopsAway=[]
  7969.             let type_village=null
  7970.             if(key==obj_report.coordAttacker){
  7971.                 for(let i=0;i<obj_report.attackingArmy.length;i++){
  7972.                     troopsAway.push({
  7973.                         type:obj_report.attackingArmy[i].type,
  7974.                         count:obj_report.attackingArmy[i].count - obj_report.attackingArmyLosses[i].count
  7975.                     })
  7976.                 }  
  7977.                 //type_village
  7978.                 if(obj_report.typeAttacker.includes("off")){
  7979.                     type_village="light"
  7980.                 }
  7981.                 else if(obj_report.typeAttacker=="spy"){
  7982.                     type_village="spy"
  7983.                 }
  7984.                 else if(obj_report.typeAttacker.includes("def")){
  7985.                     type_village="sword"
  7986.                 }
  7987.  
  7988.             }
  7989.             else if(key==obj_report.coordDefender){
  7990.                 if(obj_report.travelingTroops != undefined){/////???????????????????//////
  7991.                     Object.keys(obj_report.travelingTroops).forEach(key=>{
  7992.                         troopsAway.push({
  7993.                             type:key,
  7994.                             count:obj_report.travelingTroops[key]
  7995.                         })
  7996.                     })
  7997.  
  7998.                 }
  7999.  
  8000.                 //type_village
  8001.                 if(obj_report.typeDefender.includes("off")){
  8002.                     type_village="light"
  8003.                 }
  8004.                 else if(obj_report.typeDefender=="spy"){
  8005.                     type_village="spy"
  8006.                 }
  8007.                 else if(obj_report.typeDefender.includes("def")){
  8008.                     type_village="sword"
  8009.                 }
  8010.             }
  8011.    
  8012.  
  8013.             mapVillageByIdFinal.set(villageId,{
  8014.                 nr_fangs:0,
  8015.                 nrNobles:0,
  8016.                 nr_nukes:0,
  8017.                 player_destination_id:player_destination_id,
  8018.                 player_destination_name:player_destination_name,
  8019.                 time_report:time_report,
  8020.                 time_report_home:time_report_home,
  8021.                 troopsAtHome:troopsAtHome,
  8022.                 troopsAway:troopsAway,
  8023.                 type_village:type_village,
  8024.                 villageId:villageId,
  8025.             })
  8026.  
  8027.             mapAttacksPlayersIdFinal.set(player_destination_id,player_destination_name)
  8028.         } catch (error) {
  8029.  
  8030.             console.log(error)
  8031.         }
  8032.        
  8033.  
  8034.     })
  8035.    
  8036.     let map_ranking_attacker=new Map()
  8037.     let map_ranking_defender=new Map()
  8038.     // let mapAttacksVillageId=new Map()
  8039.     let mapAttacksPlayersId=new Map()
  8040.     Array.from(map_attacks.keys()).forEach(key=>{//go through each command attack
  8041.         let obj=map_attacks.get(key)
  8042.         let date_landing=new Date(obj.landing_time).getTime()
  8043.         let type_attack=obj.type_attack
  8044.        
  8045.         let coord=obj.coord_destination
  8046.         let villageId=obj.coord_destination_id
  8047.  
  8048.         let player_destination_id=obj.player_destination_id
  8049.         let player_destination_name=obj.player_destination_name
  8050.  
  8051.         let player_origin_name=obj.player_origin_name
  8052.         let player_origin_id=obj.player_origin_id
  8053.  
  8054.         let troops = obj.troops
  8055.         let fang=0,nuke=0,noble=0,fake=0
  8056.  
  8057.        
  8058.         let troopsAtHome=null,time_report_home=null
  8059.         let troopsAway=null, time_report=null
  8060.         let type_village=null
  8061.         if(map_reports.has(coord)){
  8062.             let obj_report=map_reports.get(coord)
  8063.             // console.log("obj_report",obj_report)
  8064.  
  8065.  
  8066.             //troops at home
  8067.             if(obj_report["troopsAtHome_"+coord]!=undefined){
  8068.                 troopsAtHome=obj_report["troopsAtHome_"+coord]
  8069.                 time_report_home=obj_report["time_report_home_"+coord]
  8070.             }
  8071.  
  8072.            
  8073.             //troops away
  8074.             time_report=obj_report.time_report
  8075.             if(coord==obj_report.coordAttacker){//get troops attack
  8076.                 troopsAway=[]
  8077.                 for(let i=0;i<obj_report.attackingArmy.length;i++){
  8078.                     troopsAway.push({
  8079.                         type:obj_report.attackingArmy[i].type,
  8080.                         count:obj_report.attackingArmy[i].count - obj_report.attackingArmyLosses[i].count
  8081.                     })
  8082.                 }
  8083.                 //type_village
  8084.                 if(obj_report.typeAttacker.includes("off")){
  8085.                     type_village="light"
  8086.                 }
  8087.                 else if(obj_report.typeAttacker=="spy"){
  8088.                     type_village="spy"
  8089.                 }
  8090.                 else if(obj_report.typeAttacker.includes("def")){
  8091.                     type_village="sword"
  8092.                 }
  8093.                
  8094.             }else if(coord==obj_report.coordDefender){//get troops away if it's defensive
  8095.                 troopsAway=[]
  8096.                 if(obj_report.travelingTroops != undefined){
  8097.                     Object.keys(obj_report.travelingTroops).forEach(key=>{
  8098.                         troopsAway.push({
  8099.                             type:key,
  8100.                             count:obj_report.travelingTroops[key]
  8101.                         })
  8102.                     })
  8103.                 }
  8104.                 //type_village
  8105.                 if(obj_report.typeDefender.includes("off")){
  8106.                     type_village="light"
  8107.                 }
  8108.                 else if(obj_report.typeDefender=="spy"){
  8109.                     type_village="spy"
  8110.                 }
  8111.                 else if(obj_report.typeDefender.includes("def")){
  8112.                     type_village="sword"
  8113.                 }
  8114.  
  8115.             }
  8116.            
  8117.         }
  8118.  
  8119.         // fangs_cat=30;
  8120.    
  8121.         if(troops.axe + troops.light*4 + troops.ram*5 + troops.catapult*8 > pop_medium_attack)     //check for nuke
  8122.             nuke=1
  8123.         else if(troops.axe + troops.light*4 < pop_small_attack && troops.catapult >= fangs_cat )        //check for fang
  8124.             fang=1
  8125.  
  8126.        
  8127.         //check for noble
  8128.         if(troops.snob>0)
  8129.             noble=1
  8130.  
  8131.         //check for fake
  8132.         let popFake=0
  8133.         Object.keys(troops).forEach(key=>{
  8134.             popFake+= troops[key] * troopsPop[key]
  8135.         })
  8136.         if(popFake<200)
  8137.             fake=1
  8138.  
  8139.  
  8140.  
  8141.        
  8142.         ////map for show info on the map
  8143.         if(!tribemates.includes(player_destination_name)){
  8144.  
  8145.             if(date_landing>date_current){
  8146.                 if(mapAttacksVillageId.has(villageId)){
  8147.                     let obj_update=mapAttacksVillageId.get(villageId)
  8148.                     obj_update.nr_nukes+=nuke
  8149.                     obj_update.nrNobles+=noble
  8150.                     obj_update.nr_fangs+=fang
  8151.                     mapAttacksVillageId.set(villageId,obj_update)
  8152.  
  8153.                 }
  8154.                 else{
  8155.                     mapAttacksVillageId.set(villageId,{
  8156.                         villageId:villageId,
  8157.                         player_destination_name:player_destination_name,
  8158.                         player_destination_id:player_destination_id,
  8159.                         troopsAtHome:troopsAtHome,
  8160.                         time_report_home:time_report_home,
  8161.                         troopsAway:troopsAway,
  8162.                         time_report:time_report,
  8163.                         type_village:type_village,
  8164.                         nr_nukes:nuke,
  8165.                         nrNobles:noble,
  8166.                         nr_fangs:fang,
  8167.                     })
  8168.                 }
  8169.                 //map for selecting player
  8170.                 if(type_attack.includes("attack"))
  8171.                     mapAttacksPlayersId.set(player_destination_id,player_destination_name)
  8172.             }
  8173.  
  8174.            
  8175.             //map for show ranking attackers with fangs/nukes/fakes
  8176.             player_origin_id = player_origin_id.toString()
  8177.  
  8178.             if(map_ranking_attacker.has(player_origin_id)){
  8179.                 let obj_update=map_ranking_attacker.get(player_origin_id)
  8180.                 obj_update.nr_nukes+=nuke
  8181.                 obj_update.nrNobles+=noble
  8182.                 obj_update.nr_fangs+=fang
  8183.                 obj_update.nr_fakes+=fake
  8184.                 map_ranking_attacker.set(player_origin_id,obj_update)
  8185.  
  8186.          
  8187.  
  8188.             }
  8189.             else{
  8190.                 map_ranking_attacker.set(player_origin_id,{
  8191.                     player_origin_name:player_origin_name,
  8192.                     nr_nukes:nuke,
  8193.                     nrNobles:noble,
  8194.                     nr_fangs:fang,
  8195.                     nr_fakes:fake
  8196.                 })
  8197.             }
  8198.             player_destination_id = player_destination_id.toString()
  8199.             //map for show ranking defenders with fangs/nukes/fakes
  8200.             if(map_ranking_defender.has(player_destination_id)){
  8201.                 let obj_update=map_ranking_defender.get(player_destination_id)
  8202.                 obj_update.nr_nukes+=nuke
  8203.                 obj_update.nrNobles+=noble
  8204.                 obj_update.nr_fangs+=fang
  8205.                 obj_update.nr_fakes+=fake
  8206.                 map_ranking_defender.set(player_destination_id,obj_update)
  8207.             }
  8208.             else{
  8209.                 map_ranking_defender.set(player_destination_id,{
  8210.                     player_origin_name:player_destination_name,
  8211.                     nr_nukes:nuke,
  8212.                     nrNobles:noble,
  8213.                     nr_fangs:fang,
  8214.                     nr_fakes:fake
  8215.                 })
  8216.             }
  8217.  
  8218.  
  8219.  
  8220.         }
  8221.        
  8222.  
  8223.  
  8224.     })
  8225.  
  8226.  
  8227.  
  8228.  
  8229.     // console.log("mapVillageByIdFinal",mapVillageByIdFinal)
  8230.     // console.log("mapAttacksVillageId",mapAttacksVillageId)
  8231.  
  8232.     mapAttacksVillageId= new Map([...mapVillageByIdFinal, ...mapAttacksVillageId])
  8233.     // console.log("mapAttacksVillageIdMerged",mapAttacksVillageId)
  8234.  
  8235.     mapAttacksPlayersId= new Map([...mapAttacksPlayersIdFinal, ...mapAttacksPlayersId])
  8236.     // console.log("mapAttacksPlayersIdMerged",mapAttacksPlayersId)
  8237.  
  8238.  
  8239.  
  8240.  
  8241.     // console.log("map_ranking_attacker",map_ranking_attacker)
  8242.  
  8243.  
  8244.     //this part is for Ally Info
  8245.     let mapVillageById=new Map()
  8246.     Array.from(map_playerId.keys()).forEach(key=>{
  8247.         let list_coords = map_playerId.get(key).list_coords
  8248.  
  8249.         for(let i=0;i<list_coords.length;i++){
  8250.             let list_coming=list_coords[i].list_coming
  8251.             let obj_result={}
  8252.             let pop=0
  8253.             let wallLevel = 20
  8254.             let LoyaltyLevel = 100
  8255.             let farmLevel = 30
  8256.             //calc pop for support coming
  8257.             for(let j=0;j<list_coming.length;j++){
  8258.                 if(list_coming[j].type_attack.includes("support")){
  8259.                     if(list_coming[j].troops["spear"]!=undefined)
  8260.                         pop += list_coming[j].troops["spear"] * troopsPop["spear"]
  8261.  
  8262.                     if(list_coming[j].troops["sword"] != undefined)
  8263.                         pop += list_coming[j].troops["sword"] * troopsPop["sword"]
  8264.  
  8265.                     if(list_coming[j].troops["heavy"]!=undefined)
  8266.                         pop += list_coming[j].troops["heavy"] * troopsPop["heavy"]
  8267.  
  8268.                     if(game_data.units.includes("archer"))
  8269.                         if(list_coming[j].troops["heavy"] != undefined)
  8270.                             pop+=list_coming[j].troops["archer"] * troopsPop["archer"]
  8271.                 }
  8272.                 else if(list_coming[j].type_attack.includes("attack_small.png")){
  8273.                     // list_coords[i].nrAttacks = list_coords[i].nrAttacks-1 // eliminate fakes
  8274.                 }
  8275.             }
  8276.             //calc pop for troops home
  8277.  
  8278.             if(list_coords[i].homeInfo != undefined){
  8279.                 let troops_home = list_coords[i].homeInfo.obj_troops
  8280.                 wallLevel = list_coords[i].homeInfo.wallLevel
  8281.                 farmLevel = list_coords[i].homeInfo.farmLevel
  8282.                 LoyaltyLevel = list_coords[i].homeInfo.LoyaltyLevel
  8283.  
  8284.                 pop += troops_home["spear"]*troopsPop["spear"]
  8285.                 pop += troops_home["sword"]*troopsPop["sword"]
  8286.                 pop += troops_home["heavy"]*troopsPop["heavy"]
  8287.                 if(game_data.units.includes("archer"))
  8288.                     pop += troops_home["archer"]*troopsPop["archer"]
  8289.  
  8290.             }
  8291.             pop = parseInt(pop/1000)
  8292.  
  8293.             obj_result.villageId = list_coords[i].coord_destination_id
  8294.             obj_result.playerId=key
  8295.  
  8296.             obj_result.nrAttacks = list_coords[i].nrAttacks
  8297.             obj_result.nrNobles = list_coords[i].nrNobles
  8298.  
  8299.             obj_result.nrSnipes = list_coords[i].nrSnipes
  8300.             obj_result.nrSniped = list_coords[i].nrSniped
  8301.            
  8302.             obj_result.nrRecaps = list_coords[i].nrRecaps
  8303.             obj_result.nrRecaped = list_coords[i].nrRecaped
  8304.  
  8305.             obj_result.pop = pop
  8306.             obj_result.wallLevel = wallLevel
  8307.             obj_result.farmLevel = farmLevel
  8308.             obj_result.LoyaltyLevel = LoyaltyLevel
  8309.  
  8310.             mapVillageById.set(list_coords[i].coord_destination_id,obj_result)
  8311.         }
  8312.     })
  8313.  
  8314.     console.log("mapVillageById",mapVillageById)
  8315.  
  8316.  
  8317.     //add troops home for own villages that don't have incomings
  8318.     Array.from(map_troops_home.keys()).forEach(coord=>{
  8319.         let villageDetails = mapVillages.get(coord)
  8320.         let troopsHomeDetails = map_troops_home.get(coord)
  8321.         let totalPop = 0, totalPopOff = 0, totalPopDef = 0
  8322.  
  8323.  
  8324.         Object.keys(troopsHomeDetails.troopInVillage).forEach(troopName=>{
  8325.             if(["spear", "sword", "archer", "heavy"].includes(troopName)){
  8326.                 totalPop += troopsHomeDetails.troopInVillage[troopName] * troopsPop[troopName]
  8327.                 totalPopDef += troopsHomeDetails.troopsOwn[troopName] * troopsPop[troopName]
  8328.             }
  8329.             if(["axe", "light", "marcher", "ram", "catapult"].includes(troopName)){
  8330.                 totalPopOff += troopsHomeDetails.troopsOwn[troopName] * troopsPop[troopName]
  8331.             }
  8332.  
  8333.         })
  8334.         let typeVillage = (totalPopDef > totalPopOff) ? "def" : "off"
  8335.         typeVillage = (troopsHomeDetails.troopsOwn['spy'] > 4000) ? "spy" : typeVillage
  8336.  
  8337.         let hasNoble = (troopsHomeDetails.troopsOwn['snob'] > 0) ? true : false
  8338.        
  8339.         totalPop = Math.round( totalPop / 1000)
  8340.         totalPopOff = Math.round( totalPopOff / 1000)
  8341.         totalPopDef = Math.round( totalPopDef / 1000)
  8342.  
  8343.         if(!mapVillageById.has(villageDetails.villageId)){
  8344.             mapVillageById.set(villageDetails.villageId + "", {
  8345.                 "villageId": villageDetails.villageId,
  8346.                 "playerId": villageDetails.playerId,
  8347.                 // "nrAttacks": randomIntFromInterval(0,30),
  8348.                 // "nrNobles": randomIntFromInterval(0,4),
  8349.                 "nrAttacks": 0,
  8350.                 "nrNobles": 0,
  8351.                 "nrSnipes": 0,
  8352.                 "nrSniped": 0,
  8353.                 "nrRecaps": 0,
  8354.                 "nrRecaped": 0,
  8355.                 "pop": totalPop,
  8356.                 "typeVillage": typeVillage,
  8357.                 "wallLevel": troopsHomeDetails.wallLvl,
  8358.                 "farmLevel": troopsHomeDetails.farmLvl,
  8359.                 "totalPopOff": totalPopOff,
  8360.                 "totalPopDef": totalPopDef,
  8361.                 "hasNoble": hasNoble
  8362.             })
  8363.         }
  8364.         else{
  8365.             let updateObj = mapVillageById.get(villageDetails.villageId)
  8366.             updateObj["typeVillage"] = typeVillage
  8367.             updateObj["totalPopOff"] = totalPopOff
  8368.             updateObj["totalPopDef"] = totalPopDef
  8369.             updateObj["hasNoble"] = hasNoble
  8370.             mapVillageById.set(villageDetails.villageId, updateObj)
  8371.  
  8372.         }
  8373.  
  8374.     })
  8375.     console.log("mapVillageByIdAfter",mapVillageById)
  8376.  
  8377.  
  8378.  
  8379.  
  8380.     //btn show info on the map
  8381.     document.getElementById("btn_show_info").addEventListener("click",()=>{
  8382.         let myInfo = document.getElementById("checkbox_my_info").checked
  8383.         let tribeInfo = document.getElementById("checkbox_tribe_info").checked
  8384.         let enemyInfo = document.getElementById("checkbox_enemy_info").checked
  8385.         let allInfo = document.getElementById("checkbox_all_info").checked
  8386.  
  8387.         if(myInfo == false && tribeInfo == false && enemyInfo == false && allInfo == false){
  8388.             UI.ErrorMessage("Select at least one of the checkboxes to view data on the map",2000)
  8389.         }
  8390.         //filter information
  8391.        
  8392.         if(enemyInfo == true || allInfo == true ){
  8393.             // console.log("mapAttacksVillageId",mapAttacksVillageId)
  8394.             let drawInfo=true
  8395.             let originalSpawnSector = TWMap.mapHandler.spawnSector;
  8396.  
  8397.             TWMap.mapHandler.spawnSector = function (data, sector) {
  8398.                 originalSpawnSector.call(TWMap.mapHandler, data, sector);
  8399.                 enemyInfo = document.getElementById("checkbox_enemy_info").checked
  8400.                 allInfo = document.getElementById("checkbox_all_info").checked
  8401.  
  8402.                 if(drawInfo == true && (enemyInfo == true || allInfo == true)){
  8403.                     drawInfo = false
  8404.                     window.setTimeout(() => {
  8405.  
  8406.                         let visibleSectors=TWMap.map._visibleSectors
  8407.                         Object.keys(visibleSectors).forEach(key=>{
  8408.                             let elements=visibleSectors[key]._elements
  8409.                             Object.keys(elements).forEach(key=>{
  8410.                                 let villageId=elements[key].id.match(/\d+/)
  8411.                                 // console.log(villageId)
  8412.                                 if(villageId!=null){
  8413.                                     if(mapAttacksVillageId.has(villageId[0])){
  8414.                                         let obj=mapAttacksVillageId.get(villageId[0])
  8415.                                         createMapInfoOffensiveSmall(obj)
  8416.                                         console.log("draw offensive for every player")
  8417.                                        
  8418.  
  8419.                                     }
  8420.                                 }
  8421.                             })
  8422.                         })
  8423.                         drawInfo=true
  8424.                     }, 200);
  8425.                 }
  8426.             };
  8427.  
  8428.             showPopupInfo(mapAttacksVillageId)
  8429.  
  8430.         }
  8431.  
  8432.         if(myInfo == true || tribeInfo == true || allInfo == true){
  8433.            
  8434.             // console.log("mapVillageById",mapVillageById)
  8435.             let drawInfo=true
  8436.             let originalSpawnSector = TWMap.mapHandler.spawnSector;
  8437.  
  8438.             TWMap.mapHandler.spawnSector = function (data, sector) {
  8439.                 originalSpawnSector.call(TWMap.mapHandler, data, sector);
  8440.                 myInfo = document.getElementById("checkbox_my_info").checked
  8441.                 tribeInfo = document.getElementById("checkbox_tribe_info").checked
  8442.                 allInfo = document.getElementById("checkbox_all_info").checked
  8443.                 // console.log(`myInfo: ${myInfo} tribeInfo: ${tribeInfo} allInfo: ${allInfo}`)
  8444.                 if(drawInfo==true && (myInfo == true || tribeInfo == true || allInfo == true)){
  8445.                     drawInfo=false
  8446.                     window.setTimeout(() => {
  8447.  
  8448.                         let visibleSectors=TWMap.map._visibleSectors
  8449.                         Object.keys(visibleSectors).forEach(key=>{
  8450.                             let elements=visibleSectors[key]._elements
  8451.                             Object.keys(elements).forEach(key=>{
  8452.                                 let villageId=elements[key].id.match(/\d+/)
  8453.                                 // console.log(villageId)
  8454.                                 if(villageId!=null){
  8455.                                     if(mapVillageById.has(villageId[0])){
  8456.                                         let obj=mapVillageById.get(villageId[0])
  8457.                                         // console.log(obj)
  8458.                                         if(allInfo == true || (myInfo == true && tribeInfo == true)){
  8459.                                             console.log("draw defensive for all players")
  8460.                                             createMapInfoDefensiveSmall(obj)
  8461.                                         }
  8462.                                         else if(myInfo == true){
  8463.                                             if(obj.playerId == game_data.player.id){
  8464.                                                 console.log("draw defensive only for my own villages")
  8465.                                                 createMapInfoDefensiveSmall(obj)
  8466.                                             }
  8467.                                         }
  8468.                                         else if(tribeInfo == true){
  8469.                                             if(obj.playerId != game_data.player.id){
  8470.                                                 console.log("draw defensive only for my tribe, except mine")
  8471.                                                 createMapInfoDefensiveSmall(obj)
  8472.                                             }
  8473.                                         }
  8474.                                     }
  8475.                                 }
  8476.                             })
  8477.                         })
  8478.  
  8479.                         drawInfo=true
  8480.                     }, 200);
  8481.                 }
  8482.             };
  8483.         }
  8484.  
  8485.         if(myInfo == true || tribeInfo == true || enemyInfo == true || allInfo == true){
  8486.             UI.SuccessMessage("The map is ready,move/drag the map to see the data", 2000)
  8487.         }
  8488.     })
  8489.  
  8490.     //add number of reports for each player
  8491.     console.log("map_status",map_status)
  8492.     console.log("map_history_upload",map_history_upload)
  8493.     let map_counter_reports=new Map()
  8494.     Array.from(map_history_upload.keys()).forEach(key=>{
  8495.         let obj=map_history_upload.get(key)
  8496.         if(map_counter_reports.has(obj.playerId)){
  8497.             let currentValue=map_counter_reports.get(obj.playerId)+1
  8498.             map_counter_reports.set(obj.playerId,currentValue)
  8499.         }
  8500.         else{
  8501.             map_counter_reports.set(obj.playerId,1)
  8502.         }
  8503.     })
  8504.     console.log("map_counter_reports",map_counter_reports)
  8505.  
  8506.     //update nr reports on for each player
  8507.     Array.from(map_status.keys()).forEach(key=>{
  8508.         let obj=map_status.get(key)
  8509.         let nrReports=map_counter_reports.get(key)
  8510.         if(nrReports==undefined)
  8511.             nrReports=0
  8512.            
  8513.         obj.name=obj.name+` (${nrReports})`
  8514.     })
  8515.  
  8516.  
  8517.     //merge all incomings
  8518.     let list_incomings_merge=[]
  8519.     Array.from(map_incomings.keys()).forEach(key=>{
  8520.         let list_incomings=map_incomings.get(key)
  8521.         list_incomings_merge=list_incomings_merge.concat(list_incomings)
  8522.     })
  8523.     //calculate launch time for every incoming
  8524.     for(let i=0;i<list_incomings_merge.length;i++){
  8525.         list_incomings_merge[i].date_launch=calculateDateLaunch(list_incomings_merge[i])
  8526.     }
  8527.  
  8528.     //sort by attackers name and then launch time
  8529.     list_incomings_merge.sort((o1,o2)=>{
  8530.         return (o1.player_off > o2.player_off)?1:(o1.player_off < o2.player_off)?-1:
  8531.         o1.date_launch < o2.date_launch?-1:(o1.date_launch > o2.date_launch)?1:0
  8532.     })
  8533.  
  8534.     let gapIncomings=10000//ms
  8535.     //filter our all incoming sent in a short period of time
  8536.     for(let i=0;i<list_incomings_merge.length-1;i++){
  8537.         if(list_incomings_merge[i].player_off == list_incomings_merge[i+1].player_off){
  8538.             if(Math.abs(list_incomings_merge[i].date_launch - list_incomings_merge[i+1].date_launch) < gapIncomings ){
  8539.                 list_incomings_merge.splice(i,1)
  8540.                 i--
  8541.             }
  8542.         }
  8543.     }
  8544.  
  8545.  
  8546.     list_incomings_merge.sort((o1,o2)=>{
  8547.         return new Date(o1.date_land).getTime() < new Date(o2.date_land).getTime()?-1:(new Date(o1.date_land).getTime() > new Date(o2.date_land).getTime())?1:0
  8548.     })
  8549.  
  8550.  
  8551.     console.log("list_incomings_merge",list_incomings_merge)
  8552.  
  8553.     //Tribe OP spotter
  8554.     let map_nr_incs_hour=new Map()
  8555.     for(let i=0;i<list_incomings_merge.length;i++){
  8556.         let date=list_incomings_merge[i].date_land
  8557.  
  8558.         if(date!=""){
  8559.             let newDate= date.substring(0,5)+", "+date.split(" ")[1].split(":")[0]+"h"
  8560.  
  8561.             if(map_nr_incs_hour.has(newDate)){
  8562.                 map_nr_incs_hour.set(newDate, map_nr_incs_hour.get(newDate)+1)
  8563.             }
  8564.             else{
  8565.                 map_nr_incs_hour.set(newDate,1)
  8566.             }
  8567.         }
  8568.         else{
  8569.             console.log("error")
  8570.             console.log(list_incomings_merge[i])
  8571.         }
  8572.     }
  8573.  
  8574.  
  8575.  
  8576.  
  8577.  
  8578.  
  8579.     // console.log("map_nr_incs_hour",map_nr_incs_hour)
  8580.     let list_spotter=Array.from(map_nr_incs_hour.entries())
  8581.    
  8582.  
  8583.  
  8584.  
  8585.  
  8586.     //sort by fakes map ranking
  8587.     map_ranking_attacker = new Map([...map_ranking_attacker.entries()].sort((o1,o2)=>{
  8588.         return (o1[1].nr_fakes>o2[1].nr_fakes)?-1:(o1[1].nr_fakes<o2[1].nr_fakes)?1:0
  8589.     }))
  8590.     map_ranking_defender = new Map([...map_ranking_defender.entries()].sort((o1,o2)=>{
  8591.         return (o1[1].nr_fakes>o2[1].nr_fakes)?-1:(o1[1].nr_fakes<o2[1].nr_fakes)?1:0
  8592.     }))
  8593.     map_status = new Map([...map_status.entries()].sort((o1,o2)=>{
  8594.         return (new Date(o1[1].report_date).getTime()>new Date(o2[1].report_date).getTime())?-1:(new Date(o1[1].report_date).getTime()<new Date(o2[1].report_date).getTime())?1:0
  8595.     }))
  8596.  
  8597.     //create tabels and add event btn for each tabel
  8598.     createTableRankingAttackers(map_ranking_attacker)
  8599.     createTableRankingDefenders(map_ranking_defender)
  8600.     createTableUploadTime(map_status)
  8601.     createTableGetCoords(mapVillages)
  8602.  
  8603.     document.getElementById("btn_rank_attacker").addEventListener("click",()=>{
  8604.         createTableRankingAttackers(map_ranking_attacker)
  8605.     })
  8606.     document.getElementById("btn_rank_defender").addEventListener("click",()=>{
  8607.         createTableRankingDefenders(map_ranking_defender)
  8608.     })
  8609.     document.getElementById("btn_upload_time").addEventListener("click",()=>{
  8610.         createTableUploadTime(map_status)  
  8611.     })
  8612.     document.getElementById("btn_get_coords").addEventListener("click",()=>{
  8613.         createTableGetCoords(mapVillages)
  8614.     })
  8615.     document.getElementById("btn_op_spotter").addEventListener("click",()=>{
  8616.         let html_spotter=`<div id="div_op_spotter" style="height:500px;width:800px;overflow:auto" > </div>`
  8617.         Dialog.show("content",html_spotter)
  8618.    
  8619.         createChart(list_spotter,"div_op_spotter")
  8620.     })
  8621.  
  8622.  
  8623.     let timeProcessingEnd = new Date().getTime()
  8624.     console.log("time processing data: " + (timeProcessingEnd - timeProcessingStart))
  8625.     let timeProcessed = (timeProcessingEnd - timeProcessingStart) / 1000
  8626.     timeProcessed = parseInt(timeProcessed * 100) / 100
  8627.  
  8628.     let timeDownload = (timeDownloadStop - timeDownloadStart) / 1000
  8629.     timeDownload = parseInt(timeDownload * 100) / 100
  8630.     UI.SuccessMessage(`
  8631.             Time loading data: <b>${timeDownload} s </b> <br>
  8632.             Time processing data: <b>${timeProcessed} s </b>
  8633.     `, 3000)
  8634.    
  8635.  
  8636. }
  8637.  
  8638.  
  8639. function randomIntFromInterval(min, max) { // min and max included
  8640.     return Math.floor(Math.random() * (max - min + 1) + min)
  8641.   }
  8642.  
  8643. function calculateDateLaunch(obj){
  8644.     let distance=calcDistance(obj.coord_def,obj.coord_off)
  8645.     let time_travel=0
  8646.     if(obj.labelName.includes("snob"))
  8647.         time_travel=distance*nobleSpeed
  8648.     else if(obj.labelName.includes("ram"))
  8649.         time_travel=distance*ramSpeed
  8650.     else if(obj.labelName.includes("sword"))
  8651.         time_travel=distance*swordSpeed
  8652.     else if(obj.labelName.includes("axe"))
  8653.         time_travel=distance*axeSpeed
  8654.     else
  8655.         time_travel=distance*heavySpeed
  8656.  
  8657.     let date_launch=new Date(obj.date_land).getTime()-time_travel
  8658.     // date_launch=parseDate(date_launch)
  8659.     return date_launch
  8660. }
  8661.  
  8662.  
  8663.  
  8664. function createMapInfoDefensiveSmall(obj){
  8665.     // console.log("herere")
  8666.     // console.log(obj)
  8667.     try {
  8668.         if(document.getElementById(`info_extra${obj.villageId}`)==null){
  8669.             let greenColor = "#026440"//green
  8670.             let darkGreenColor = "#011910"//green
  8671.             let lightGreenColor = "#137f13"
  8672.             let lighterGreenColor = "#1dc246"
  8673.             let redColor = "#E80000"//red
  8674.             let lightRedColor = "#ff83a1"//red
  8675.             let blueLightColor ="#157de5";//blueLightColor
  8676.             let orangeColor = "#cc8400"
  8677.             let pinkColor = "#d1afed"
  8678.             let whiteColor="#ececec";
  8679.             let yellowColor = "#ffd500"
  8680.  
  8681.             let villageImg=document.getElementById(`map_village_${obj.villageId}`)
  8682.  
  8683.             let parent=document.getElementById(`map_village_${obj.villageId}`).parentElement
  8684.             let leftImg=villageImg.style.left
  8685.             let topImg=villageImg.style.top
  8686.  
  8687.             let colorBorder="background-color:rgba(20, 20, 20, 0.34)"//no border
  8688.  
  8689.             if(obj.nrSnipes==1)
  8690.                 colorBorder=`background-color:rgba(255, 10, 10, 0.14);outline:rgba(255, 51, 0, 0.7) solid 1px`// red border
  8691.            
  8692.             if(obj.nrRecaps==1)
  8693.                 colorBorder=`background-color:rgba(127,5,5, 0.14);outline:rgba(127,5,5, 0.7) solid 1px`// dark red border
  8694.            
  8695.             if(obj.nrSniped==1 || obj.nrRecaped==1)
  8696.                 colorBorder=`background-color:rgba(155, 252, 10, 0.14);outline:rgba(51, 255, 0, 0.7) solid 1px`// green border
  8697.  
  8698.  
  8699.             let colorType=""
  8700.             if(obj.typeVillage!=null){
  8701.                 if(obj.typeVillage == "def")
  8702.                     colorType = (obj.totalPopDef < 5) ? redColor : (obj.totalPopDef < 10) ? orangeColor : (obj.totalPopDef < 15) ? yellowColor : (obj.totalPopDef < 20) ? lightGreenColor : darkGreenColor
  8703.                 else if(obj.typeVillage == "off"){
  8704.                     colorType = (obj.totalPopOff < 5) ? redColor : (obj.totalPopOff < 10) ? orangeColor : (obj.totalPopOff < 15) ? yellowColor : (obj.totalPopOff < 20) ? lightGreenColor : darkGreenColor
  8705.                 }
  8706.                 else if(obj.typeVillage == "spy")
  8707.                     colorType="#d8d8d8"
  8708.  
  8709.             }
  8710.             let typeVillage = (obj.typeVillage == "off") ? "axe" : (obj.typeVillage == "def") ? "spear" : "spy"
  8711.             // let colorBackgroundType = (obj.hasNoble == true) ? yellowColor : colorType
  8712.  
  8713.             let colorIncomings = (obj.nrAttacks <= 5) ? lightGreenColor : (obj.nrAttacks <= 10) ? lighterGreenColor : (obj.nrAttacks <= 15) ? yellowColor : (obj.nrAttacks <= 20) ? orangeColor : (obj.nrAttacks <= 25) ? lightRedColor : redColor
  8714.             let colorLoyalty= (obj.LoyaltyLevel < 25) ? redColor : (obj.LoyaltyLevel < 50) ? orangeColor : (obj.LoyaltyLevel < 75) ? yellowColor : lightGreenColor
  8715.  
  8716.  
  8717.  
  8718.             while(document.getElementById(`map_icons_${obj.villageId}`)!=null){
  8719.                 document.getElementById(`map_icons_${obj.villageId}`).remove()
  8720.             }
  8721.             if(document.getElementById(`map_cmdicons_${obj.villageId}_0`)!=null)
  8722.                 document.getElementById(`map_cmdicons_${obj.villageId}_0`).remove()
  8723.             if(document.getElementById(`map_cmdicons_${obj.villageId}_1`)!=null)
  8724.                 document.getElementById(`map_cmdicons_${obj.villageId}_1`).remove()
  8725.  
  8726.             let html_info = ""
  8727.             // console.log(obj)
  8728.             //draw square area
  8729.             if(obj.pop > 0 || obj.nrAttacks > 0 || obj.nrNobles > 0 || obj.totalPopOff > 0 || obj.typeVillage != undefined || obj.LoyaltyLevel < 100 || obj.wallLevel < 20){
  8730.                 html_info +=`<div id="info_extra${obj.villageId}" style="position:absolute;left:${leftImg};top:${topImg};width:51px;height:36px;z-index:3; ${colorBorder}"></div>`
  8731.             }
  8732.             if(obj.pop > 0){
  8733.                 html_info += `<center><font color="${whiteColor}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:25px;height:15px;z-index:4;margin-top:23px;font-size: 11px">${obj.pop}k</font></center>`
  8734.             }
  8735.  
  8736.             if(obj.nrAttacks > 0){
  8737.                 html_info += `<img style="position:absolute;left:${leftImg};top:${topImg};width:13px;height:13px;z-index:4;margin-left:7px;"  src="https://dsen.innogamescdn.com/asset/c2dee33a/graphic//map/incoming_attack.png">
  8738.                     <center><font color="${colorIncomings}"  class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-left:18px; font-size: 11px">${obj.nrAttacks}</font></center>`
  8739.             }
  8740.  
  8741.             //nobles coming as incs
  8742.             if(obj.nrNobles > 0){
  8743.                 html_info+=`<center><font color="${redColor}"  class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;;margin-left:7px;margin-top:11px; font-size: 11px">${obj.nrNobles}</font></center>`
  8744.             }
  8745.  
  8746.             //containing own noble in village
  8747.             if(obj.hasNoble == true){
  8748.                 html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:10px;height:10px;z-index:4;margin-top:15px;margin-left:40px;background-color:white"  src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/snob.png">`
  8749.             }
  8750.  
  8751.             //add either loyaly or wall down
  8752.             if(obj.LoyaltyLevel < 100){
  8753.                 html_info+=`<center><font color="${colorLoyalty}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-top:23px;margin-left:34px;font-size: 11px;">${obj.LoyaltyLevel}</font></center>`
  8754.             }
  8755.            
  8756.             if((obj.LoyaltyLevel == 100 || obj.LoyaltyLevel == undefined || obj.LoyaltyLevel == 'none') && obj.wallLevel < 20){
  8757.                 html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:10px;height:10px;z-index:4;margin-top:26px;margin-left:41px;background-color:#471212"  src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/wall.png">`
  8758.             }
  8759.             if((obj.LoyaltyLevel == 100 || obj.LoyaltyLevel == undefined || obj.LoyaltyLevel == 'none') && obj.farmLevel < 30){
  8760.                 html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:10px;height:10px;z-index:4;margin-top:26px;margin-left:31px;background-color:#471212"  src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/farm.png">`
  8761.             }
  8762.  
  8763.             if(obj.typeVillage){
  8764.                 html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-left:37px;background-color:${colorType}"  src="https://dsen.innogamescdn.com/asset/c2dee33a/graphic/unit/unit_${typeVillage}.png">`
  8765.             }
  8766.  
  8767.            
  8768.             $(html_info).appendTo(parent);
  8769.         }
  8770.  
  8771.     } catch (error) {
  8772.         console.log(error)
  8773.     }
  8774. }
  8775.  
  8776. function createMapInfoOffensiveSmall(obj){
  8777.  
  8778.     try {
  8779.         if(document.getElementById(`info_extra${obj.villageId}`) == null ){
  8780.             let greenColor="#026440"//green
  8781.             let redColor="#E80000"//red
  8782.             let blueLightColor ="#157de5";//blueLightColor
  8783.             let brownColor="#a06a34"
  8784.             let whiteColor="#ececec";
  8785.  
  8786.             let villageImg=document.getElementById(`map_village_${obj.villageId}`)
  8787.  
  8788.             let parent=document.getElementById(`map_village_${obj.villageId}`).parentElement
  8789.             let leftImg=villageImg.style.left
  8790.             let topImg=villageImg.style.top
  8791.  
  8792.             let greenBorder=`background-color:rgba(155, 252, 10, 0.14);outline:rgba(51, 255, 0, 0.7) solid 1px`//green
  8793.             let redBorder=`background-color:rgba(255, 10, 10, 0.14);outline:rgba(255, 51, 0, 0.7) solid 1px`//red
  8794.             let lighBlueBorder=`background-color:rgba(149, 245, 232, 0.14);outline:rgba(149, 245, 232, 0.7) solid 1px`//red
  8795.             let blueBorder=`background-color:rgba(0, 10, 255, 0.2);outline:rgba(0, 10, 255, 0.7) solid 1px`// blue border
  8796.             let colorBorder="background-color:rgba(20, 20, 20, 0.34)"//no border
  8797.  
  8798.             var noBorder=`background-color:rgba(40, 40, 40, 0.34)`
  8799.            
  8800.             while(document.getElementById(`map_icons_${obj.villageId}`)!=null){
  8801.                 document.getElementById(`map_icons_${obj.villageId}`).remove()
  8802.             }
  8803.  
  8804.             if(document.getElementById(`map_cmdicons_${obj.villageId}_0`)!=null)
  8805.                 document.getElementById(`map_cmdicons_${obj.villageId}_0`).remove()
  8806.             if(document.getElementById(`map_cmdicons_${obj.villageId}_1`)!=null)
  8807.                 document.getElementById(`map_cmdicons_${obj.villageId}_1`).remove()
  8808.  
  8809.  
  8810.             Array.from($(".church_radius_display").parent().find("img"))
  8811.                 .filter(e=>e.src.includes("reserved"))
  8812.                 .forEach(e=>$(e).remove())
  8813.  
  8814.             let colorTypeAttack=""
  8815.             if(obj.type_village!=null){
  8816.                 if(obj.type_village=="sword")
  8817.                     colorTypeAttack="background-color:rgb(0,255,255)"
  8818.                 else if(obj.type_village=="light")
  8819.                     colorTypeAttack="background-color:rgb(255, 132, 5)"
  8820.                 else if(obj.type_village=="spy")
  8821.                     colorTypeAttack="background-color:rgb(255,255,255)"
  8822.                
  8823.  
  8824.             }
  8825.  
  8826.             let stacks_home=0
  8827.             let has_noble=false
  8828.             if(obj.troopsAtHome!=null && obj.troopsAtHome!=undefined){
  8829.                 for(let i=0;i<obj.troopsAtHome.length;i++){
  8830.                     let type=obj.troopsAtHome[i].type
  8831.                     let count=obj.troopsAtHome[i].count
  8832.                     if(type=="spear" || type=="sword" || type=="archer" || type=="heavy" ){
  8833.                         stacks_home+=troopsPop[type] * count
  8834.                     }
  8835.                     if(type =="snob" && count > 0){
  8836.                         has_noble=true
  8837.                     }
  8838.                 }
  8839.                 stacks_home=parseInt(Math.round(stacks_home/1000))
  8840.             }
  8841.             else{
  8842.                 stacks_home=-1
  8843.             }
  8844.  
  8845.             if(has_noble==false && obj.troopsAway!=null && obj.troopsAway!=undefined){
  8846.                 if(obj.troopsAway.length>0){
  8847.                     let nobleInfo=obj.troopsAway.slice(-1)[0]
  8848.                     if(nobleInfo.type=="snob" && nobleInfo.count>0){
  8849.                         has_noble=true
  8850.                     }
  8851.                 }
  8852.             }
  8853.  
  8854.  
  8855.             let html_info
  8856.             //info for small img village  on the map
  8857.          
  8858.  
  8859.             if(obj.nr_nukes>0 || obj.nrNobles>0 || obj.nr_fangs >0 ){
  8860.                 if(obj.type_village!=null){
  8861.                     let border = (has_noble==true)?"background-color:rgb(255,255,0)" : colorTypeAttack
  8862.                     let borderMain=(obj.type_village=="light") ? blueBorder : lighBlueBorder
  8863.                     html_info=`
  8864.                         <div id="info_extra${obj.villageId}" style="position:absolute;left:${leftImg};top:${topImg};width:51px;height:36px;z-index:3; ${borderMain}"></div>`
  8865.                    
  8866.                     html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:16px;height:16px;z-index:4;margin-left:35px;${border}"  src="https://dsen.innogamescdn.com/asset/c2dee33a/graphic/unit/unit_${obj.type_village}.png">`
  8867.                    
  8868.                     if(stacks_home>=0){
  8869.                         html_info+=`<center><font color="${"#FFFFF1"}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:16px;height:16px;z-index:4;margin-left:8px;font-size: 10px;">${stacks_home}k</font></center>`
  8870.  
  8871.                     }
  8872.                 }else{
  8873.                     html_info=`
  8874.                     <div id="info_extra${obj.villageId}" style="position:absolute;left:${leftImg};top:${topImg};width:51px;height:36px;z-index:3; ${noBorder}"></div>`
  8875.                 }
  8876.                 if(obj.nr_fangs>0){
  8877.                     html_info+=`
  8878.                     <center><font color="${brownColor}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-top:22px;margin-left:0px;font-size: 12px;background-color:black;">${obj.nr_fangs}</font></center>`
  8879.                 }
  8880.                 if(obj.nr_nukes>0){
  8881.                     html_info+=`
  8882.                     <center><font color="${greenColor}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-top:22px;margin-left:17px;font-size: 12px;background-color:black;">${obj.nr_nukes}</font></center>`
  8883.                 }
  8884.                 if(obj.nrNobles>0){
  8885.                     html_info+=`
  8886.                     <center><font color="${redColor}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:14px;height:14px;z-index:4;margin-top:22px;margin-left:34px;font-size: 12px;background-color:black;">${obj.nrNobles}</font></center>`
  8887.                 }
  8888.          
  8889.  
  8890.             }
  8891.             else{
  8892.          
  8893.  
  8894.  
  8895.                 if(obj.type_village!=null){
  8896.                     let border= (has_noble==true)?"background-color:rgb(255,255,0)":colorTypeAttack
  8897.                     let borderMain=(obj.type_village=="light")?blueBorder : lighBlueBorder
  8898.                     html_info=`
  8899.                         <div id="info_extra${obj.villageId}" style="position:absolute;left:${leftImg};top:${topImg};width:51px;height:36px;z-index:3; ${borderMain}"></div>`
  8900.                    
  8901.                     html_info+=`<img style="position:absolute;left:${leftImg};top:${topImg};width:16px;height:16px;z-index:4;margin-left:35px;${border}"  src="https://dsen.innogamescdn.com/asset/c2dee33a/graphic/unit/unit_${obj.type_village}.png">`
  8902.                    
  8903.                     if(stacks_home>=0){
  8904.                         html_info+=`<center><font color="${"#FFFFF1"}" class="shadow20" style="position:absolute;left:${leftImg};top:${topImg};width:16px;height:16px;z-index:4;margin-left:8px;font-size: 10px;">${stacks_home}k</font></center>`
  8905.  
  8906.                     }
  8907.  
  8908.                 }
  8909.             }
  8910.             $(html_info).appendTo(parent);
  8911.  
  8912.  
  8913.             //info for the popup window for each village
  8914.         }
  8915.  
  8916.     } catch (error) {
  8917.         console.log(error)
  8918.     }
  8919. }
  8920.  
  8921. function showPopupInfo(mapAttacksVillageId){
  8922.     let originalDisplayForVillage = TWMap.popup.displayForVillage;
  8923.  
  8924.     TWMap.popup.displayForVillage = function (e, a, t) {
  8925.         console.log('intercepted displayForVillage');
  8926.         originalDisplayForVillage.call(TWMap.popup, e, a, t);
  8927.         let villageInfo = e;
  8928.         // console.log(villageInfo)
  8929.  
  8930.         let obj=mapAttacksVillageId.get(villageInfo.id)
  8931.  
  8932.  
  8933.  
  8934.         let units=game_data.units
  8935.         //first row
  8936.         let militia=0
  8937.         let drawPopup=false
  8938.         if(units.includes("militia"))
  8939.             militia=1
  8940.  
  8941.         let html_popup=`
  8942.             <table  class="vis popup_info_extra" border="1" style="width: 100%;border-collapse: collapse">
  8943.                 <tr>
  8944.                     <td style="text-align:center; width:auto;background-color:#c1a264" >
  8945.                         <center style="margin:0px;"></center>
  8946.                     </td>
  8947.                     <td style="text-align:center; width:auto;background-color:#c1a264" >
  8948.                         <center style="margin:0px;"><b>seen</b></center>
  8949.                     </td>`
  8950.                
  8951.  
  8952.             for(let i=0;i<units.length-militia;i++){
  8953.                 html_popup+=`
  8954.                     <td style="text-align:center; width:auto;background-color:#c1a264" >
  8955.                         <center style="margin-top:0px;"><img src="https://dsen.innogamescdn.com/asset/c2dee33a/graphic/unit/unit_${units[i]}.png"></center>
  8956.                     </td>`
  8957.             }
  8958.             html_popup+="</tr>"
  8959.  
  8960.  
  8961.         if(obj!=undefined){
  8962.             if(obj.troopsAtHome!=null ){
  8963.                 drawPopup=true
  8964.                 html_popup+=`
  8965.                     <tr>
  8966.                         <td style="text-align:center; width:auto;" >
  8967.                             <center style="margin:0px;"><b>at home</b></center>
  8968.                         </td>
  8969.                         <td style="text-align:center; width:auto;" >
  8970.                             <center style="margin:0px;"><b>${obj.time_report_home}</b></center>
  8971.                         </td>
  8972.                     `
  8973.  
  8974.                 for(let i=0;i<obj.troopsAtHome.length-militia;i++){
  8975.                     html_popup+=`
  8976.                         <td style="text-align:center; width:auto;" >
  8977.                             <center style="margin:0px;">${obj.troopsAtHome[i].count}</center>
  8978.                         </td>`
  8979.                 }
  8980.                 html_popup+=`</tr>`
  8981.             }
  8982.         }
  8983.  
  8984.         if(obj!=undefined){
  8985.             if(obj.troopsAway!=null){
  8986.                 drawPopup=true
  8987.                 html_popup+=`
  8988.                 <tr>
  8989.                     <td style="text-align:center; width:auto;" >
  8990.                         <center style="margin:0px;"><b>away</b></center>
  8991.                     </td>
  8992.                     <td style="text-align:center; width:auto;" >
  8993.                         <center style="margin:0px;"><b>${obj.time_report}</b></center>
  8994.                     </td>`
  8995.  
  8996.                 for(let i=0;i<obj.troopsAway.length;i++){
  8997.                     html_popup+=`
  8998.                         <td style="text-align:center; width:auto;" >
  8999.                             <center style="margin:0px;">${obj.troopsAway[i].count}</center>
  9000.                         </td>`
  9001.                 }
  9002.                 html_popup+=`</tr>`
  9003.             }
  9004.         }
  9005.  
  9006.         html_popup+=`</table>`
  9007.  
  9008.         if(drawPopup==true){
  9009.             // console.log(document.getElementById("map_popup"))
  9010.             $(".popup_info_extra").remove()
  9011.             $('#info_content').prepend(`<tr><td colspan="3">${html_popup}</td></tr>`)
  9012.  
  9013.         }
  9014.  
  9015.  
  9016.     }
  9017.  
  9018.  
  9019. }
  9020.  
  9021.  
  9022.     ////////////////////////////////////////////////////////////////// create table for players/////////////////////////////////////////////////////
  9023.  
  9024. function createTablePlayers(map_playerId,mapVillages){
  9025.     let html_tr_player="<tbody id='tbody_player'>"
  9026.     let counterPlayer=0;
  9027.     let nr_attacks_total=0,nr_supports_total=0,nr_nobles_total=0;
  9028.     let nr_snipe_total=0,nr_sniped_total=0,nr_recap_total=0,nr_recaped_total=0;
  9029.     Array.from(map_playerId.keys()).forEach(key=>{
  9030.         let obj=map_playerId.get(key)
  9031.         counterPlayer++;
  9032.         nr_attacks_total +=obj.nr_attacks_total
  9033.         nr_supports_total+=obj.nr_supports_total
  9034.         nr_nobles_total  +=obj.nr_nobles_total
  9035.         nr_snipe_total   +=obj.nr_snipe_total
  9036.         nr_sniped_total  +=obj.nr_sniped_total
  9037.         nr_recap_total   +=obj.nr_recap_total
  9038.         nr_recaped_total +=obj.nr_recaped_total
  9039.  
  9040.         html_tr_player+=
  9041.         `<tr>
  9042.  
  9043.             <td style="text-align:center; width:40px; background-color:${headerColor}">
  9044.                 <a href="#"  ><center style="margin:5px"><font color="${titleColor}"><img player-id="${key}" number-tr="${counterPlayer}" class="infoPlayer" src="https://img.icons8.com/clouds/30/000000/more.png"/></font></center></a>
  9045.             </td>
  9046.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9047.             <a href="${game_data.link_base_pure}info_player&id=${key}"><center style="margin:5px"><font color="${titleColor}">${obj.player_destination_name}</font></center></a>
  9048.             </td>
  9049.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9050.                 <center style="margin:5px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/unit/att.png">(${obj.nr_attacks_total})</font></center>
  9051.             </td>
  9052.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9053.                     <center style="margin:5px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/support.png">(${obj.nr_supports_total})</font></center>
  9054.             </td>
  9055.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9056.                 <center style="margin:5px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/snob.png">(${obj.nr_nobles_total})</font></center>
  9057.             </td>
  9058.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9059.                 <center style="margin:5px;font-size:16px"><font color="${titleColor}"><img src="https://img.icons8.com/office/20/000000/sniper-rifle.png"/>(${obj.nr_sniped_total}/${obj.nr_snipe_total})</font></center>
  9060.             </td>
  9061.             <td style="text-align:center; width:auto; background-color:${headerColor}">
  9062.                 <center style="margin:5px;font-size:16px"><font color="${titleColor}"><img src="https://img.icons8.com/ultraviolet/20/000000/horror.png"/>(${obj.nr_recaped_total}/${obj.nr_recap_total})</font></center>
  9063.             </td>
  9064.            
  9065.         </tr>
  9066.         `
  9067.  
  9068.     })
  9069.     html_tr_player+="</tbody>"
  9070.     if(document.getElementById("tbody_player")!=null)
  9071.         document.getElementById("tbody_player").remove()
  9072.     document.getElementById("table_view").innerHTML+=html_tr_player
  9073.     $("#table_view").hide()
  9074.     $("#table_view").toggle(500)
  9075.  
  9076.     document.getElementById("header_attacks").innerText=`(${nr_attacks_total})`
  9077.     document.getElementById("header_supports").innerText=`(${nr_supports_total})`
  9078.     document.getElementById("header_nobles").innerText=`(${nr_nobles_total})`
  9079.     document.getElementById("header_snipes").innerText=`(${nr_sniped_total}/${nr_snipe_total})`
  9080.     document.getElementById("header_recaps").innerText=`(${nr_recaped_total}/${nr_recap_total})`
  9081.  
  9082.     $(".infoPlayer").on("click",(event)=>{
  9083.         let playerId=event.target.getAttribute("player-id")
  9084.         let numberTr=event.target.getAttribute("number-tr")
  9085.         // console.log(event.target)
  9086.         let list_coords=map_playerId.get(playerId).list_coords
  9087.  
  9088.     /////////// ///////////////////////////////////////////////////////////////////coords table//////////////////////////////////////////////////////////
  9089.     // red: '#ff8080',
  9090.     // green: '#4dff4d'
  9091.         let html_table_player=`
  9092.         <tr >
  9093.             <td >
  9094.                 <div style="height:700px;overflow:auto;" id="div_incomingsInfo">
  9095.                 <table  class="table_player" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;">
  9096.                 `
  9097.         let counterVillage=0;
  9098.         console.log("------------------------------------------------------------")
  9099.         console.log("list_coord",list_coords)
  9100.         console.log(list_coords.length)
  9101.         for(let i=0;i<list_coords.length;i++){
  9102.             let obj=list_coords[i]
  9103.             console.log(list_coords[i].nrAttacks)
  9104.             if(list_coords[i].nrAttacks>0 || list_coords[i].nr_supports>0){//show attacks and supports, i might delete supports
  9105.                 counterVillage++
  9106.  
  9107.                 let headColorSnipe=(obj.nrSniped==1)?"#4dff4d":(obj.nrSnipes==1)?"#ff8080":headerColor
  9108.                 let headColorRecap=(obj.nrRecaped==1)?"#4dff4d":(obj.nrRecaps==1)?"#ff8080":headerColor
  9109.  
  9110.                 html_table_player+=`
  9111.                 <tr>
  9112.                     <td style="text-align:center; width:40px; background-color:${headerColorPlayers}">
  9113.                         <a href="#" style="margin:0px" ><center ><font color="${titleColor}"><img coord-id="${obj.coord_destination_id}" number-tr-coord="${counterVillage}" class="infoCoord" src="https://img.icons8.com/bubbles/20/000000/more.png"/></font></center></a>
  9114.                     </td>
  9115.                     <td style="text-align:center; width:auto; background-color:${headerColorPlayers}">
  9116.                         <a href="${game_data.link_base_pure}info_village&id=${obj.coord_destination_id}" style="margin:0px"><center><font color="${titleColor}">${obj.list_coming[0].coord_destination}</font></center></a>
  9117.                     </td>
  9118.                     <td style="text-align:center; width:auto; background-color:${headerColorPlayers}">
  9119.                         <center style="margin:0px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/unit/att.png">(${obj.nrAttacks})</font></center>
  9120.                     </td>
  9121.                     <td style="text-align:center; width:auto; background-color:${headerColorPlayers}">
  9122.                         <center style="margin:2px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/support.png">(${obj.nr_supports})</font></center>
  9123.                     </td>
  9124.                     <td style="text-align:center; width:auto; background-color:${headerColorPlayers}">
  9125.                         <center style="margin:2px;font-size:16px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/snob.png">(${obj.nrNobles})</font></center>
  9126.                     </td>
  9127.                         <td style="text-align:center; width:auto; background-color:${headColorSnipe}">
  9128.                     <center style="margin:2px;font-size:16px"><font color="${titleColor}"><img src="https://img.icons8.com/office/20/000000/sniper-rifle.png"/></font></center>
  9129.                     </td>
  9130.                     <td style="text-align:center; width:auto; background-color:${headColorRecap}">
  9131.                         <center style="margin:2px;font-size:16px"><font color="${titleColor}"><img src="https://img.icons8.com/ultraviolet/20/000000/horror.png"/></font></center>
  9132.                     </td>            
  9133.                 </tr>
  9134.                 `
  9135.             }
  9136.         }
  9137.  
  9138.  
  9139.  
  9140.         html_table_player+=`
  9141.                 </div>
  9142.                 </table>
  9143.             <td>
  9144.         </tr>
  9145.         `
  9146.         let delay=500
  9147.         // console.log(document.getElementById(`table_player${numberTr}`))
  9148.         if(document.getElementById(`table_player${numberTr}`)!=null){
  9149.             $(".tr_table_coord").hide(delay)
  9150.             window.setTimeout(()=>{
  9151.                 $(".tr_table_coord").remove()
  9152.             },delay+10)
  9153.            
  9154.         }
  9155.         else{
  9156.  
  9157.             $(".tr_table_coord").remove()
  9158.             // console.log(html_table_player)
  9159.             var table_support = document.getElementById("table_view").getElementsByTagName("tbody")[0]
  9160.             var newRow   = table_support.insertRow(numberTr);
  9161.             newRow.className="tr_table_coord"
  9162.             newRow.id=`table_player${numberTr}`
  9163.  
  9164.             let cell  = newRow.insertCell();
  9165.             cell.setAttribute("colspan",7)
  9166.             var div  = document.createElement("div")
  9167.             div.innerHTML=html_table_player
  9168.             $(cell).append(div)
  9169.             $(cell).hide()
  9170.             $(cell).show(delay)
  9171.            
  9172.             createEventCoord(map_playerId,mapVillages,playerId)
  9173.  
  9174.         }
  9175.     })
  9176.     sortInfoIncomings(map_playerId,mapVillages)
  9177.  
  9178. }
  9179.  
  9180. ////////////////////////////////////////////////////////////////// create table with troops and info for each coord////////////////////////////////
  9181.  
  9182. function createTableCoordTroops(obj,admin){
  9183.     admin=true
  9184.     let units=game_data.units
  9185.     let troopsSupportComing={}
  9186.     for(let i=0;i<units.length-1;i++){
  9187.         troopsSupportComing[units[i]]=0
  9188.     }
  9189.     // console.log(troopsSupportComing)
  9190.     for(let i=0;i<obj.list_coming.length;i++){
  9191.         if(obj.list_coming[i].type_attack.includes("support")){
  9192.             Object.keys(troopsSupportComing).forEach(key=>{
  9193.                 if(obj.list_coming[i].troops[key]!=undefined)
  9194.                     troopsSupportComing[key]+=obj.list_coming[i].troops[key]
  9195.             })
  9196.         }
  9197.        
  9198.     }
  9199.     troopsSupportComing.snob=0;
  9200.  
  9201.     if(obj.homeInfo==undefined){
  9202.         obj.homeInfo={
  9203.             flagName:"none",
  9204.             LoyaltyLevel:"none",
  9205.             wallLevel:"none",
  9206.             farmLevel:"none",
  9207.         }
  9208.     }
  9209.  
  9210.  
  9211.  
  9212.     let html_table_coord=""
  9213.     ///////////////////////////////////////////////////////////////////info coord table//////////////////////////////////////////////////////////
  9214.     if(admin==true){
  9215.         html_table_coord+=`
  9216.         <tbody>
  9217.         <tr>
  9218.  
  9219.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9220.                 <center style="margin:5px"><font color="${titleColor}">coord </font></center>
  9221.             </td>    
  9222.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9223.                 <center style="margin:5px;padding;"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/unit/att.png"> </font></center>
  9224.             </td>    
  9225.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9226.                 <center style="margin:5px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/4ba99e83/graphic/flags/small/3.png"> </font></center>
  9227.             </td>    
  9228.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9229.                 <center style="margin:5px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/snob.png"> </font></center>
  9230.             </td>    
  9231.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9232.                 <center style="margin:5x"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/wall.png"> </font></center>
  9233.             </td>    
  9234.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9235.                 <center style="margin:5px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/buildings/farm.png"> </font></center>
  9236.             </td>  
  9237.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9238.                 <center style="margin:5px"><font color="${titleColor}">troops </font></center></p>
  9239.             </td>  
  9240.            
  9241.         `;
  9242.     /////////////////////////////////////////////////////////////////////////////Add info village//////////////////////////////////////////////////
  9243.  
  9244.         for(let i=0;i<units.length-1;i++){
  9245.             html_table_coord+=`<td class="fm_unit" style="width:30px;text-align:center;width:auto; background-color:${headerColorFirstRow}"><img src="https://dsen.innogamescdn.com/asset/1d2499b/graphic/unit/unit_${units[i]}.png"></td>`
  9246.         }
  9247.         html_table_coord+=`
  9248.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9249.                 <center style="margin:1px"><font color="${titleColor}">pop</font></center>
  9250.             </td>`
  9251.         html_table_coord+=`</tr>
  9252.                 <tr>`
  9253.        
  9254.         html_table_coord+=`
  9255.             <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.list_coming[0].coord_destination}</td>
  9256.             <td rowspan="3" class="" style="width:70px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.nrAttacks}</td>
  9257.             <td rowspan="3" class="" style="width:70px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.homeInfo.flagName}</td>
  9258.             <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.homeInfo.LoyaltyLevel}</td>
  9259.             <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.homeInfo.wallLevel}</td>
  9260.             <td rowspan="3" class="" style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">${obj.homeInfo.farmLevel}</td>
  9261.             <td  style="text-align:center; width:auto; background-color:${headerColorCoords}">
  9262.                 <center style="margin:1px"><font color="${titleColor}">home</font></center>
  9263.             </td>
  9264.         `
  9265.     /////////////////////////////////////////////////////////////////////////////////////////home troops//////////////////////////////////////////////////
  9266.         let total_pop=0;
  9267.         for(let i=0;i<units.length-1;i++){
  9268.             let value_troop=(obj.homeInfo.obj_troops!=undefined)?obj.homeInfo.obj_troops[units[i]]:0
  9269.             let name_troop=units[i]
  9270.             if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  9271.                 total_pop+=value_troop*troopsPop[name_troop]
  9272.             }
  9273.             html_table_coord+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+value_troop+"</td>"
  9274.         }
  9275.         html_table_coord+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+total_pop+"</td>"
  9276.         html_table_coord+=`</tr>
  9277.                 <tr>
  9278.                     <td  style="text-align:center; width:auto; background-color:${headerColorCoords}">
  9279.                         <center style="margin:1px"><font color="${titleColor}">coming</font></center>
  9280.                     </td>`
  9281.  
  9282.     ////////////////////////////////////////////////////////////////////////////////////////coming troops//////////////////////////////////////////////////
  9283.         total_pop=0;
  9284.         for(let i=0;i<units.length-1;i++){
  9285.             let value_troop_coming=troopsSupportComing[units[i]]
  9286.             let name_troop=units[i]
  9287.             if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  9288.                 total_pop+=value_troop_coming*troopsPop[name_troop]
  9289.             }
  9290.             html_table_coord+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+value_troop_coming+"</td>"
  9291.         }
  9292.         html_table_coord+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+total_pop+"</td>"
  9293.  
  9294.         html_table_coord+=`</tr>
  9295.                 <tr>
  9296.                     <td  style="text-align:center; width:auto; background-color:${headerColorCoords}">
  9297.                         <center style="margin:1px"><font color="${titleColor}">total </font></center>
  9298.                     </td>`
  9299.     ////////////////////////////////////////////////////////////////////////////////////////total troops//////////////////////////////////////////////////
  9300.         total_pop=0;
  9301.         for(let i=0;i<units.length-1;i++){
  9302.             let value_home=(obj.homeInfo.obj_troops!=undefined)?obj.homeInfo.obj_troops[units[i]]:0
  9303.             let value_troop=troopsSupportComing[units[i]]+value_home
  9304.             let name_troop=units[i]
  9305.             if(name_troop!="spy" && name_troop!="light" && name_troop!="marcher" && name_troop!="ram"&& name_troop!="catapult" && name_troop!="axe"){
  9306.                 total_pop+=value_troop*troopsPop[name_troop]
  9307.             }
  9308.             html_table_coord+=`<td style="width:30px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+value_troop+"</td>"
  9309.         }
  9310.         html_table_coord+=`<td style="width:60px;height:30px;text-align:center; background-color:${headerColorCoords};color:white">`+total_pop+"</td>"
  9311.         html_table_coord+="</tr></tbody>"
  9312.         return html_table_coord
  9313.     }
  9314. }
  9315.  
  9316. //////////////////////////////////////////add click event for coord and when it's pressed show table with troops and incomings////////////////////
  9317.  
  9318. function createEventCoord(map_playerId,mapVillages,playerId){
  9319.     $(".infoCoord").on("click",(event)=>{
  9320.        
  9321.         // console.log(this.parentElement)
  9322.         // console.log($(this).parent())
  9323.  
  9324.         // console.log("event infoCoord")
  9325.         let coordId=event.target.getAttribute("coord-id")
  9326.         let numberTrCoord=event.target.getAttribute("number-tr-coord")
  9327.         let obj={}
  9328.         let list_coords=map_playerId.get(playerId).list_coords
  9329.         // console.log(playerId)
  9330.         // console.log(list_coords)
  9331.         for(let i=0;i<list_coords.length;i++){
  9332.             if(coordId==list_coords[i].coord_destination_id){
  9333.                 obj=list_coords[i]
  9334.                 break;
  9335.             }
  9336.         }
  9337.         console.log("obj",obj)
  9338.         console.log("mapVillages",mapVillages)
  9339.  
  9340.         // console.log(obj)
  9341.         // console.log(coordId)
  9342.         // console.log(numberTrCoord)
  9343.         // console.log(event.target)
  9344.        
  9345.         console.log("objbaaa",obj)
  9346.         let admin=true
  9347.         let html_table_coord=`<tr><td >`
  9348.         if(obj.hasOwnProperty("homeInfo")==true){
  9349.             html_table_coord=`<table class="table_coord" border="1" coord-id="${coordId}" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;"> `
  9350.             html_table_coord+=createTableCoordTroops(obj,admin)
  9351.             html_table_coord+="</table>"
  9352.         }
  9353.  
  9354.         html_table_coord+=`
  9355.         <div style="height:400px;overflow:auto;" id="div_incomingsInfo">
  9356.         <table class="table_coord" border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;"></div> `
  9357.         html_table_coord+=createTableCoordIncomings(obj.list_coming,mapVillages)
  9358.  
  9359.  
  9360.  
  9361.         html_table_coord+=`</table><td></tr>`
  9362.  
  9363.  
  9364.  
  9365.  
  9366.         let delay=500
  9367.         // console.log(document.getElementById(`table_coord${numberTrCoord}`))
  9368.         if(document.getElementById(`table_coord${numberTrCoord}`)!=null){
  9369.             $(".tr_table_coord_info").hide(delay)
  9370.             // $("#div_incomingsInfo").hide(delay)
  9371.             window.setTimeout(()=>{
  9372.                 $(".tr_table_coord_info").remove()
  9373.                 // $("#div_incomingsInfo").remove()
  9374.             },delay+10)
  9375.            
  9376.         }
  9377.         else{
  9378.  
  9379.             $(".tr_table_coord_info").remove()
  9380.             // console.log(html_table_player)
  9381.             var table_coord = document.getElementsByClassName("table_player")[0].getElementsByTagName("tbody")[0]
  9382.             var newRow   = table_coord.insertRow(numberTrCoord);
  9383.             newRow.className="tr_table_coord_info"
  9384.             newRow.id=`table_coord${numberTrCoord}`
  9385.  
  9386.             let cell  = newRow.insertCell();
  9387.             cell.setAttribute("colspan",7)
  9388.             var div  = document.createElement("div")
  9389.             div.innerHTML=html_table_coord
  9390.             $(cell).append(div)
  9391.             $(cell).hide()
  9392.             $(cell).show(delay)
  9393.             counterTime()
  9394.         }
  9395.  
  9396.  
  9397.     })
  9398. }
  9399.  
  9400. ////////////////////////////////////////////////////////////////// create table for incomings////////////////////////////////////////////////////////
  9401.  
  9402. function createTableCoordIncomings(list,mapVillages){
  9403.     let serverTime=document.getElementById("serverTime").innerText
  9404.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  9405.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  9406.     let date_current=new Date(serverDate+" "+serverTime).getTime()
  9407.     // console.log("create table coord")
  9408.     console.log("createTableCoordIncomings")
  9409.     // console.log(list)
  9410.     // console.log(mapVillages)
  9411.     let html_incomings=`
  9412.         <tbody >
  9413.         <tr>
  9414.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9415.                 <center style="margin:5px"><font color="${titleColor}"><img src="https://dsen.innogamescdn.com/asset/056b9c0b/graphic/unit/att.png"> </font></center>
  9416.             </td>  
  9417.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9418.                 <center style="margin:0px"><font color="${titleColor}">speed/pop </font></center>
  9419.             </td>    
  9420.             <td colspan="2" style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9421.                <center style="margin:0px"><font color="${titleColor}">destination </font></center>
  9422.             </td>    
  9423.             <td colspan="2" style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9424.                 <center style="margin:0px"><font color="${titleColor}">origin </font></center>
  9425.             </td>    
  9426.             <td  style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9427.                 <center style="margin:0px"><font color="${titleColor}">Arrival time </font></center>
  9428.             </td>    
  9429.             <td style="text-align:center; width:auto; background-color:${headerColorFirstRow}">
  9430.                 <center style="margin:0px"><font color="${titleColor}">Arrives in </font></center>
  9431.             </td>    
  9432.  
  9433.  
  9434.         </tr>`
  9435.        
  9436.         for(let i=0;i<list.length;i++){
  9437.             // console.log("aici baa")
  9438.             // console.log(list[i])
  9439.             let labelName
  9440.             let villageId=mapVillages.get(list[i].coord_destination).villageId
  9441.             let playerId=mapVillages.get(list[i].coord_destination).playerId
  9442.             let playerName=mapVillages.get(list[i].coord_destination).playerName
  9443.             let headerNoble=headerColorCoords
  9444.             let titleColorNoble=titleColor
  9445.             let type_attack=list[i].type_attack
  9446.  
  9447.             if(list[i].labelName=="none")
  9448.                 labelName=`<img src="https://dsen.innogamescdn.com/asset/056b9c0b/graphic/delete.png">`
  9449.             else
  9450.                 labelName=`<img src="https://dsen.innogamescdn.com/asset/a9e85669/graphic/unit/tiny/${list[i].labelName}">`
  9451.  
  9452.             if(type_attack.includes("support")){
  9453.                 let troops=list[i].troops
  9454.                 let pop=0
  9455.                 Object.keys(troops).forEach(key=>{
  9456.                     pop+=troops[key]*troopsPop[key]
  9457.                 })
  9458.                 labelName=pop
  9459.                 if(list[i].hasSupportSnipe==true){
  9460.                     headerNoble="#034a2f"
  9461.                 }
  9462.                 type_attack=`https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/${type_attack}`
  9463.  
  9464.  
  9465.             }else{
  9466.                 //colore nobles
  9467.                 if(labelName.includes("snob")){
  9468.                     headerNoble="#3f0000"//red
  9469.                     titleColorNoble="#4dff4d"//green
  9470.                 }
  9471.                 if(labelName.includes("snob") && tribemates.includes(list[i].player_origin_name)){
  9472.                     headerNoble="#720000"//lighter red
  9473.                     titleColorNoble="#4dff4d"//green
  9474.                 }
  9475.  
  9476.                 //modify type_attack, small,medium,large
  9477.                 if(type_attack=="def"){
  9478.                     type_attack=`https://img.icons8.com/fluent/16/000000/d.png`
  9479.                 }
  9480.                 else{
  9481.                     type_attack=`https://dsen.innogamescdn.com/asset/a9e85669/graphic/command/${type_attack}`
  9482.                 }
  9483.  
  9484.  
  9485.             }
  9486.  
  9487.             // console.log(list[i].labelName)
  9488.             let arrived=new Date(list[i].landing_time).getTime()  
  9489.             if(arrived>date_current){
  9490.                 let date=list[i].landing_time.split(" ")[0]
  9491.                 let time=list[i].landing_time.split(" ")[1].split(":")
  9492.                 let milisec=time.pop()
  9493.                 time=time.join(":")
  9494.  
  9495.                 html_incomings+=`
  9496.                     <tr style="white-space:nowrap;" >
  9497.                         <td  style="text-align:center; width:auto; background-color:${headerNoble}">
  9498.                             <center style="margin:0px;padding:0px"><font color="${titleColor}"><img src="${type_attack}"> </font></center>
  9499.                         </td>
  9500.                         <td  style="text-align:center; width:auto; background-color:${headerNoble}">
  9501.                            <center style="margin:0px;padding:0px"><font color="${titleColor}">${labelName}</font></center>
  9502.                         </td>
  9503.                         <td style="text-align:center; width:auto; background-color:${headerNoble}">
  9504.                             <a href="${game_data.link_base_pure}info_village&id=${villageId}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].coord_destination}</font></center></a>
  9505.                         </td>
  9506.                         <td style="text-align:center; width:auto; background-color:${headerNoble}">
  9507.                             <a href="${game_data.link_base_pure}info_player&id=${playerId}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${playerName}</font></center></a>
  9508.                         </td>
  9509.                         <td style="text-align:center; width:auto; background-color:${headerNoble}">
  9510.                             <a href="${game_data.link_base_pure}info_village&id=${list[i].coord_origin_id}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].coord_origin}</font></center></a>
  9511.                         </td>
  9512.                         <td style="text-align:center; width:auto; background-color:${headerNoble}">
  9513.                             <a href="${game_data.link_base_pure}info_player&id=${list[i].player_origin_id}" style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].player_origin_name}</font></center></a>
  9514.                         </td>
  9515.                         <td style="text-align:center; width:auto; background-color:${headerNoble}">
  9516.                             <center style="margin:0px;padding:0px"><font color="${titleColor}">${date} <b>${time} <font color="${titleColorNoble}"> ${milisec}</font></b> </font></center>
  9517.                         </td>  
  9518.                         <td style="text-align:center; width:auto; background-color:${headerNoble}" >
  9519.                             <center style="margin:0px;padding:0px"><font color="${titleColor}" >${convertBuildTime(arrived-date_current)}</font></center>
  9520.                         </td>    
  9521.                        
  9522.                     </tr>
  9523.                 `
  9524.             }
  9525.         }
  9526.         html_incomings+="</tbody>"
  9527.         // console.log(html_incomings)
  9528.         return html_incomings
  9529. }
  9530. {/* <td date-time=${arrived} class="counterTime"></td> */}
  9531.  
  9532.  
  9533. /////////////////////////////////////////////////////////////////create table for settings//////////////////////////////////////////////////////
  9534. function createTableSettings(){
  9535.     let html_table=`
  9536.     <center>
  9537.     <table id="table_settings"  border="1" style="width: 40%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;">
  9538.         <tr>
  9539.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9540.                 <input type="checkbox"   value="hide_ignored">
  9541.             </td>
  9542.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9543.                 <font style="margin:5px" color="${titleColor}">hide ignored attacks/support</font>
  9544.             </td>
  9545.         </tr>
  9546.         <tr>
  9547.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9548.                 <input type="checkbox"   value="hide_supports">
  9549.             </td>
  9550.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9551.                 <font style="margin:5px" color="${titleColor}">hide supports</font>
  9552.             </td>
  9553.         </tr>
  9554.         <tr>
  9555.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9556.                 <input type="checkbox"   value="hide_further_attacks">
  9557.             </td>
  9558.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9559.                 <font style="margin:5px" color="${titleColor}">hide attacks further than(hours) </font>
  9560.             </td>
  9561.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9562.                 <input type="number" style="text-align:center;" id="settings_further" min="0" max="200" placeholder="100">
  9563.             </td>
  9564.         </tr>
  9565.         <tr>
  9566.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9567.                 <input type="checkbox"  value="hide_closer_attacks">
  9568.             </td>
  9569.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9570.                 <font style="margin:5px" color="${titleColor}">hide attacks closer than(hours) </font>
  9571.             </td>
  9572.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9573.                 <input type="number" style="text-align:center;" id="settings_closer" min="0" max="200" placeholder="20">
  9574.             </td>
  9575.         </tr>
  9576.         <tr>
  9577.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9578.                 <font style="margin:5px" color="${titleColor}">snipe has(pop) </font>
  9579.             </td>
  9580.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9581.                 <input type="number" style="text-align:center;" id="settings_pop" min="0" max="20000" value="1000" placeholder="1000">
  9582.             </td>
  9583.         </tr>
  9584.         <tr>
  9585.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9586.                 <font style="margin:5px" color="${titleColor}">small attack has less than(pop) </font>
  9587.             </td>
  9588.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9589.                 <input type="number" style="text-align:center;" id="settings_small_attack" min="0" max="20000" value="5000" placeholder="5000">
  9590.             </td>
  9591.         </tr>
  9592.         <tr>
  9593.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9594.                 <font style="margin:5px" color="${titleColor}">medium attack has less than(pop) </font>
  9595.             </td>
  9596.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9597.                 <input type="number" style="text-align:center;" id="settings_medium_attack" min="0" max="20000" value="10000" placeholder="10000">
  9598.             </td>
  9599.         </tr>
  9600.         <tr>
  9601.             <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  9602.                 <font style="margin:5px" color="${titleColor}">fangs has(catapults) </font>
  9603.             </td>
  9604.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  9605.                 <input type="number" style="text-align:center;" id="settings_fang_cat" min="0" max="20000"  value="50" placeholder="100" disabled>
  9606.             </td>
  9607.         </tr>
  9608.  
  9609.  
  9610.  
  9611.     </table>
  9612.  
  9613.     </div></center>
  9614.     `
  9615.  
  9616.     if(document.getElementById("table_settings")==null)
  9617.         document.getElementById("div_settings").innerHTML=html_table
  9618.     else{
  9619.         $("#div_rank_attacker").hide()
  9620.         $("#div_rank_defender").hide()
  9621.         $("#div_upload_time").hide()
  9622.         $("#div_get_coords").hide(500)
  9623.         $("#div_settings").toggle(500)
  9624.     }    
  9625.  
  9626.  
  9627.     //initialize settings only if it's visible
  9628.  
  9629.     if(localStorage.getItem(game_data.world+"save_settings")!=null ){
  9630.         let list_checkbox=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[0]
  9631.  
  9632.         $('#div_settings input[type=checkbox], #table_select_info input[type=checkbox]').each(function (index,elem) {
  9633.             this.checked=list_checkbox[index]
  9634.             // console.log(elem.value)
  9635.         });
  9636.  
  9637.         let list_input=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[1]
  9638.         $('#div_settings input[type=number]').each(function (index,elem) {
  9639.             // var checked = this.checked
  9640.             this.value=list_input[index]
  9641.         });
  9642.  
  9643.         let value_radio=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[2]
  9644.         $(`input[name='type_info'][value='${value_radio}'`).attr("checked",true)
  9645.  
  9646.     }
  9647.  
  9648.  
  9649.  
  9650.     //save settings
  9651.     $("#div_settings input[type=checkbox],#div_settings input[type=number], input[name='type_info'],#table_select_info input[type=checkbox]").on("mouseup input",()=>{
  9652.         console.log("save")
  9653.         let list_checkbox=[]
  9654.         let list_input=[]
  9655.         //save checkbox
  9656.         $('#div_settings input[type=checkbox], #table_select_info input[type=checkbox]').each(function () {
  9657.             var checked = this.checked
  9658.             list_checkbox.push(checked)
  9659.         });
  9660.         //save inputs
  9661.         $('#div_settings input[type=number] ').each(function () {
  9662.             // var checked = this.checked
  9663.             var value=this.value
  9664.             // console.log(value)
  9665.             list_input.push(value)
  9666.         });
  9667.         //save radio button
  9668.         let value_radio=$("input[name='type_info']:checked").val()
  9669.  
  9670.  
  9671.  
  9672.         let list_final=[list_checkbox,list_input,value_radio]
  9673.         localStorage.setItem(game_data.world+"save_settings",JSON.stringify(list_final))
  9674.  
  9675.     })
  9676.  
  9677.  
  9678.     $("#btn_apply").on("click",()=>{
  9679.         $("#div_container_view").remove();
  9680.         viewSupport()
  9681.     })
  9682.     $("#btn_clear_memory").on("click",()=>{
  9683.         localStorage.removeItem(game_data.world+"map_exist_support")
  9684.         UI.SuccessMessage("local storage is cleared",1000)
  9685.     })
  9686.    
  9687. }
  9688.  
  9689. /////////////////////////////////////////////////////////////////create table ranking atackers//////////////////////////////////////////////////////
  9690.  
  9691. function createTableRankingAttackers(map_ranking){
  9692.  
  9693.    
  9694.     let html=`
  9695.     <center>
  9696.     <div style="height:400px;overflow: auto">
  9697.                 <table id="table_rank"  border="1" style="width: 60%;background-color:${backgroundColor};border-color:${borderColor}">
  9698.                 <tr>
  9699.                     <td colspan = "6" style="text-align:left; width:auto; background-color:${headerColor};color:${titleColor};padding:5px">
  9700.                         Using data from last 7 days
  9701.                     </td>
  9702.                 </tr>
  9703.                 <tr>
  9704.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9705.                         <center style="margin:10px" ><font  color="${titleColor}">nr</font></center>
  9706.                     </td>
  9707.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9708.                         <center style="margin:10px" ><font  color="${titleColor}">player name</font></center>
  9709.                     </td>
  9710.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9711.                         <center style="margin:10px" ><a href="#" id="sort_fakes_att"><font  color="${titleColor}">fakes</font><a/></center>
  9712.                     </td>
  9713.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9714.                         <center style="margin:10px" ><a href="#" id="sort_nukes_att"><font color="${titleColor}">nukes</font><a/></center>
  9715.                     </td>
  9716.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9717.                         <center style="margin:10px" ><a href="#" id="sort_fangs_att"><font  color="${titleColor}">fangs</font><a/></center>
  9718.                     </td>
  9719.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9720.                         <center style="margin:10px" ><a href="#" id="sort_nobles_att"><font  color="${titleColor}">nobles</font><a/></center>
  9721.                     </td>
  9722.                 </tr>`
  9723.  
  9724.     Array.from(map_ranking.keys()).forEach((key,index)=>{
  9725.         let obj_attacks=map_ranking.get(key)
  9726.         html+=`
  9727.             <tr>
  9728.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9729.                     <center><font style="margin:0px" color="${titleColor}">${index+1}</font></center>
  9730.                 </td>
  9731.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9732.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.player_origin_name}</font></center>
  9733.                 </td>
  9734.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9735.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_fakes}</font></center>
  9736.                 </td>
  9737.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9738.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_nukes}</font></center>
  9739.                 </td>
  9740.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9741.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_fangs}</font></center>
  9742.                 </td>
  9743.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9744.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nrNobles}</font></center>
  9745.                 </td>
  9746.             </tr>
  9747.        
  9748.         `
  9749.     })
  9750.     html+=`
  9751.     </table></div></center>`
  9752.     if(document.getElementById("div_rank_attacker").children.length==0 ){
  9753.         document.getElementById("div_rank_attacker").innerHTML=html
  9754.         console.log("initialize rank attacker")
  9755.     }
  9756.     else{
  9757.         $("#div_settings").hide()
  9758.         $("#div_rank_defender").hide()
  9759.         $("#div_upload_time").hide()
  9760.         $("#div_get_coords").hide(500)
  9761.         $("#div_rank_attacker").toggle(500)
  9762.     }
  9763.  
  9764.  
  9765.  
  9766.     $("#sort_fakes_att").off("click")
  9767.     $("#sort_nukes_att").off("click")
  9768.     $("#sort_fangs_att").off("click")
  9769.     $("#sort_nobles_att").off("click")
  9770.  
  9771.     //sort by nr fakes
  9772.     $("#sort_fakes_att").on("click",()=>{
  9773.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9774.             return (o1[1].nr_fakes>o2[1].nr_fakes)?-1:(o1[1].nr_fakes<o2[1].nr_fakes)?1:0
  9775.         }))
  9776.         document.getElementById("div_rank_attacker").innerHTML=""
  9777.         createTableRankingAttackers(map_ranking)
  9778.     })
  9779.     //sort by nr nukes
  9780.     $("#sort_nukes_att").on("click",()=>{
  9781.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9782.             return (o1[1].nr_nukes>o2[1].nr_nukes)?-1:(o1[1].nr_nukes<o2[1].nr_nukes)?1:0
  9783.         }))
  9784.         console.log("sort by nukes")
  9785.         document.getElementById("div_rank_attacker").innerHTML=""
  9786.         createTableRankingAttackers(map_ranking)
  9787.     })
  9788.     //sort by nr fangs
  9789.     $("#sort_fangs_att").on("click",()=>{
  9790.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9791.             return (o1[1].nr_fangs>o2[1].nr_fangs)?-1:(o1[1].nr_fangs<o2[1].nr_fangs)?1:0
  9792.         }))
  9793.         console.log("sort by fangs")
  9794.         document.getElementById("div_rank_attacker").innerHTML=""
  9795.         createTableRankingAttackers(map_ranking)
  9796.     })
  9797.     //sort by nr nobles
  9798.     $("#sort_nobles_att").on("click",()=>{
  9799.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9800.             return (o1[1].nrNobles>o2[1].nrNobles)?-1:(o1[1].nrNobles<o2[1].nrNobles)?1:0
  9801.         }))
  9802.         console.log("sort by nobles")
  9803.         document.getElementById("div_rank_attacker").innerHTML=""
  9804.         createTableRankingAttackers(map_ranking)
  9805.     })
  9806.  
  9807.  
  9808. }
  9809.  
  9810.  
  9811. /////////////////////////////////////////////////////////////////create table ranking defenders//////////////////////////////////////////////////////
  9812.  
  9813. function createTableRankingDefenders(map_ranking){
  9814.  
  9815.    
  9816.     let html=`
  9817.         <center>
  9818.             <div style="height:400px;overflow: auto">
  9819.                 <table id="table_rank"  border="1" style="width: 60%;background-color:${backgroundColor};border-color:${borderColor}">
  9820.                 <tr>
  9821.                     <td colspan = "6" style="text-align:left; width:auto; background-color:${headerColor};color:${titleColor};padding:5px">
  9822.                         Using data from last 7 days
  9823.                     </td>
  9824.                 </tr>
  9825.                 <tr>
  9826.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9827.                         <center style="margin:10px" ><font  color="${titleColor}">nr</font></center>
  9828.                     </td>
  9829.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9830.                         <center style="margin:10px" ><font  color="${titleColor}">player name</font></center>
  9831.                     </td>
  9832.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9833.                         <center style="margin:10px" ><a href="#" id="sort_fakes_def"><font  color="${titleColor}">fakes</font><a/></center>
  9834.                     </td>
  9835.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9836.                         <center style="margin:10px" ><a href="#" id="sort_nukes_def"><font color="${titleColor}">nukes</font><a/></center>
  9837.                     </td>
  9838.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9839.                         <center style="margin:10px" ><a href="#" id="sort_fangs_def"><font  color="${titleColor}">fangs</font><a/></center>
  9840.                     </td>
  9841.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9842.                         <center style="margin:10px" ><a href="#" id="sort_nobles_def"><font  color="${titleColor}">nobles</font><a/></center>
  9843.                     </td>
  9844.                 </tr>`
  9845.  
  9846.     Array.from(map_ranking.keys()).forEach((key,index)=>{
  9847.         let obj_attacks=map_ranking.get(key)
  9848.         html+=`
  9849.             <tr>
  9850.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9851.                     <center><font style="margin:0px" color="${titleColor}">${index+1}</font></center>
  9852.                 </td>
  9853.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9854.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.player_origin_name}</font></center>
  9855.                 </td>
  9856.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9857.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_fakes}</font></center>
  9858.                 </td>
  9859.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9860.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_nukes}</font></center>
  9861.                 </td>
  9862.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9863.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nr_fangs}</font></center>
  9864.                 </td>
  9865.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9866.                     <center><font style="margin:0px" color="${titleColor}">${obj_attacks.nrNobles}</font></center>
  9867.                 </td>
  9868.             </tr>
  9869.        
  9870.         `
  9871.     })
  9872.     html+=`
  9873.     </table></div></center>`
  9874.     if(document.getElementById("div_rank_defender").children.length==0 ){
  9875.         document.getElementById("div_rank_defender").innerHTML=html
  9876.         console.log("initialize rank defender")
  9877.     }
  9878.     else{
  9879.         $("#div_settings").hide()
  9880.         $("#div_rank_attacker").hide()
  9881.         $("#div_upload_time").hide()
  9882.         $("#div_get_coords").hide(500)
  9883.         $("#div_rank_defender").toggle(500)
  9884.     }
  9885.  
  9886.  
  9887.  
  9888.     $("#sort_fakes_def").off("click")
  9889.     $("#sort_nukes_def").off("click")
  9890.     $("#sort_fangs_def").off("click")
  9891.     $("#sort_nobles_def").off("click")
  9892.  
  9893.     //sort by nr fakes
  9894.     $("#sort_fakes_def").on("click",()=>{
  9895.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9896.             return (o1[1].nr_fakes>o2[1].nr_fakes)?-1:(o1[1].nr_fakes<o2[1].nr_fakes)?1:0
  9897.         }))
  9898.         document.getElementById("div_rank_defender").innerHTML=""
  9899.         createTableRankingDefenders(map_ranking)
  9900.     })
  9901.     //sort by nr nukes
  9902.     $("#sort_nukes_def").on("click",()=>{
  9903.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9904.             return (o1[1].nr_nukes>o2[1].nr_nukes)?-1:(o1[1].nr_nukes<o2[1].nr_nukes)?1:0
  9905.         }))
  9906.         console.log("sort by nukes")
  9907.         document.getElementById("div_rank_defender").innerHTML=""
  9908.         createTableRankingDefenders(map_ranking)
  9909.     })
  9910.     //sort by nr fangs
  9911.     $("#sort_fangs_def").on("click",()=>{
  9912.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9913.             return (o1[1].nr_fangs>o2[1].nr_fangs)?-1:(o1[1].nr_fangs<o2[1].nr_fangs)?1:0
  9914.         }))
  9915.         console.log("sort by fangs")
  9916.         document.getElementById("div_rank_defender").innerHTML=""
  9917.         createTableRankingDefenders(map_ranking)
  9918.     })
  9919.     //sort by nr nobles
  9920.     $("#sort_nobles_def").on("click",()=>{
  9921.         map_ranking = new Map([...map_ranking.entries()].sort((o1,o2)=>{
  9922.             return (o1[1].nrNobles>o2[1].nrNobles)?-1:(o1[1].nrNobles<o2[1].nrNobles)?1:0
  9923.         }))
  9924.         console.log("sort by nobles")
  9925.         document.getElementById("div_rank_defender").innerHTML=""
  9926.         createTableRankingDefenders(map_ranking)
  9927.     })
  9928.  
  9929.  
  9930. }
  9931.  
  9932.  
  9933. /////////////////////////////////////////////////////////////////create table upload time//////////////////////////////////////////////////////
  9934.  
  9935. function createTableUploadTime(map_upload_time){
  9936.  
  9937.    
  9938.     let html=`
  9939.         <center>
  9940.             <div style="height:400px;overflow: auto">
  9941.                 <table id="table_rank"  border="1" style="width: 80%;background-color:${backgroundColor};border-color:${borderColor}">
  9942.                 <tr>
  9943.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9944.                         <center style="margin:10px" ><font  color="${titleColor}">nr</font></center>
  9945.                     </td>
  9946.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9947.                         <center style="margin:10px" ><font  color="${titleColor}">player name</font></center>
  9948.                     </td>
  9949.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9950.                         <center style="margin:10px" ><a href="#" id="sort_reports"><font  color="${titleColor}">Reports</font><a/></center>
  9951.                     </td>
  9952.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9953.                         <center style="margin:10px" ><a href="#" id="sort_incomings"><font color="${titleColor}">Incomings</font><a/></center>
  9954.                     </td>
  9955.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9956.                         <center style="margin:10px" ><a href="#" id="sort_commands"><font  color="${titleColor}">Commands</font><a/></center>
  9957.                     </td>
  9958.                     <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9959.                         <center style="margin:10px" ><a href="#" id="sort_troops"><font  color="${titleColor}">Troops</font><a/></center>
  9960.                     </td>
  9961.  
  9962.                 </tr>`
  9963.  
  9964.     Array.from(map_upload_time.keys()).forEach((key,index)=>{
  9965.         let obj_upload=map_upload_time.get(key)
  9966.         html+=`
  9967.             <tr>
  9968.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9969.                     <center><font style="margin:0px" color="${titleColor}">${index+1}</font></center>
  9970.                 </td>
  9971.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9972.                     <center><font style="margin:0px" color="${titleColor}">${obj_upload.name}</font></center>
  9973.                 </td>
  9974.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9975.                     <center><font style="margin:0px" color="${titleColor}">${convertDate(obj_upload.report_date)}</font></center>
  9976.                 </td>
  9977.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9978.                     <center><font style="margin:0px" color="${titleColor}">${convertDate(obj_upload.incoming_date)}</font></center>
  9979.                 </td>
  9980.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9981.                     <center><font style="margin:0px" color="${titleColor}">${convertDate(obj_upload.command_date)}</font></center>
  9982.                 </td>
  9983.                 <td style="text-align:left; width:auto; background-color:${headerColor}" >
  9984.                     <center><font style="margin:0px" color="${titleColor}">${convertDate(obj_upload.troops_date)}</font></center>
  9985.                 </td>
  9986.             </tr>
  9987.        
  9988.         `
  9989.     })
  9990.     html+=`
  9991.     </table></div></center>`
  9992.     if(document.getElementById("div_upload_time").children.length==0 ){
  9993.         document.getElementById("div_upload_time").innerHTML=html
  9994.         console.log("initialize table upload time")
  9995.     }
  9996.     else{
  9997.         $("#div_settings").hide()
  9998.         $("#div_rank_defender").hide()
  9999.         $("#div_rank_attacker").hide()
  10000.         $("#div_get_coords").hide(500)
  10001.         $("#div_upload_time").toggle(500)
  10002.         console.log("rank attacker")
  10003.     }
  10004.  
  10005.  
  10006.     $("#sort_reports").off("click")
  10007.     $("#sort_incomings").off("click")
  10008.     $("#sort_commands").off("click")
  10009.  
  10010.     //sort by nr date upload reports
  10011.     $("#sort_reports").on("click",()=>{
  10012.         map_upload_time = new Map([...map_upload_time.entries()].sort((o1,o2)=>{
  10013.             return (new Date(o1[1].report_date).getTime() > new Date(o2[1].report_date).getTime())?-1:
  10014.             (new Date(o1[1].report_date).getTime() < new Date(o2[1].report_date).getTime())?1:0
  10015.         }))
  10016.         console.log("sort by report")
  10017.         document.getElementById("div_upload_time").innerHTML=""
  10018.         createTableUploadTime(map_upload_time)
  10019.     })
  10020.     //sort by nr date upload incomings
  10021.     $("#sort_incomings").on("click",()=>{
  10022.         map_upload_time = new Map([...map_upload_time.entries()].sort((o1,o2)=>{
  10023.             return (new Date(o1[1].incoming_date).getTime() > new Date(o2[1].incoming_date).getTime())?-1:
  10024.             (new Date(o1[1].incoming_date).getTime() < new Date(o2[1].incoming_date).getTime())?1:0
  10025.         }))
  10026.         console.log("sort by incomings")
  10027.         document.getElementById("div_upload_time").innerHTML=""
  10028.         createTableUploadTime(map_upload_time)
  10029.     })
  10030.     //sort by nr date upload commands
  10031.     $("#sort_commands").on("click",()=>{
  10032.         map_upload_time = new Map([...map_upload_time.entries()].sort((o1,o2)=>{
  10033.             return (new Date(o1[1].command_date).getTime() > new Date(o2[1].command_date).getTime())?-1:
  10034.             (new Date(o1[1].command_date).getTime() < new Date(o2[1].command_date).getTime())?1:0
  10035.         }))
  10036.         console.log("sort by commands")
  10037.         document.getElementById("div_upload_time").innerHTML=""
  10038.         createTableUploadTime(map_upload_time)
  10039.     })
  10040.  
  10041.     $("#sort_troops").on("click",()=>{
  10042.         map_upload_time = new Map([...map_upload_time.entries()].sort((o1,o2)=>{
  10043.             return (new Date(o1[1].troops_date).getTime() > new Date(o2[1].troops_date).getTime())?-1:
  10044.             (new Date(o1[1].troops_date).getTime() < new Date(o2[1].troops_date).getTime())?1:0
  10045.         }))
  10046.         console.log("sort by troops")
  10047.         document.getElementById("div_upload_time").innerHTML=""
  10048.         createTableUploadTime(map_upload_time)
  10049.     })
  10050.  
  10051. }
  10052.  
  10053. function parseDate(time){
  10054.     let date=new Date(time)
  10055.  
  10056.     let year=date.getFullYear();
  10057.     let month=("00"+(date.getMonth()+1)).slice(-2)
  10058.     let day=("00"+date.getDate()).slice(-2)
  10059.     let hours=("00"+date.getHours()).slice(-2)
  10060.     let minutes=("00"+date.getMinutes()).slice(-2)
  10061.     let seconds=("00"+date.getSeconds()).slice(-2)
  10062.     let result=`${month}/${day}/${year} ${hours}:${minutes}:${seconds}`
  10063.     return result
  10064. }
  10065.  
  10066. ////////////////////////////////////////////////sort by attacks,supports,nobles,snipes,recaps////////////////////////////////////////////////////////
  10067.  
  10068. function sortInfoIncomings(map_playerId,mapVillages){
  10069.     //////////////////////////////////////////////////////////////sort by attacks///////////////////////////////////////////
  10070.     document.getElementById("sort_by_attacks").addEventListener("click",()=>{
  10071.         map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  10072.             return (o1[1].nr_attacks_total>o2[1].nr_attacks_total)?-1:(o1[1].nr_attacks_total<o2[1].nr_attacks_total)?1:0;
  10073.         }))
  10074.         Array.from(map_playerId.keys()).forEach(key=>{
  10075.             let obj=map_playerId.get(key)
  10076.             obj.list_coords.sort((o1,o2)=>{
  10077.                 return (o1.nrAttacks>o2.nrAttacks)?-1:(o1.nrAttacks<o2.nrAttacks)?1:0
  10078.             })
  10079.             map_playerId.set(key,obj)
  10080.         })
  10081.         document.getElementById("tbody_player").remove()
  10082.         createTablePlayers(map_playerId,mapVillages)
  10083.     })
  10084.     //////////////////////////////////////////////////////////////sort by supports///////////////////////////////////////////
  10085.  
  10086.     document.getElementById("sort_by_supports").addEventListener("click",()=>{
  10087.         map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  10088.             return (o1[1].nr_supports_total>o2[1].nr_supports_total)?-1:(o1[1].nr_supports_total<o2[1].nr_supports_total)?1:0;
  10089.         }))
  10090.         Array.from(map_playerId.keys()).forEach(key=>{
  10091.             let obj=map_playerId.get(key)
  10092.             obj.list_coords.sort((o1,o2)=>{
  10093.                 return (o1.nr_supports>o2.nr_supports)?-1:(o1.nr_supports<o2.nr_supports)?1:0
  10094.             })
  10095.             map_playerId.set(key,obj)
  10096.         })
  10097.         document.getElementById("tbody_player").remove()
  10098.         createTablePlayers(map_playerId,mapVillages)
  10099.  
  10100.     })
  10101.     //////////////////////////////////////////////////////////////sort by nobles///////////////////////////////////////////
  10102.     document.getElementById("sort_by_nobles").addEventListener("click",()=>{
  10103.         map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  10104.             return (o1[1].nr_nobles_total>o2[1].nr_nobles_total)?-1:(o1[1].nr_nobles_total<o2[1].nr_nobles_total)?1:0;
  10105.         }))
  10106.         Array.from(map_playerId.keys()).forEach(key=>{
  10107.             let obj=map_playerId.get(key)
  10108.             obj.list_coords.sort((o1,o2)=>{
  10109.                 return (o1.nrNobles>o2.nrNobles)?-1:(o1.nrNobles<o2.nrNobles)?1:0
  10110.             })
  10111.             map_playerId.set(key,obj)
  10112.         })
  10113.         document.getElementById("tbody_player").remove()
  10114.         createTablePlayers(map_playerId,mapVillages)
  10115.     })
  10116.     //////////////////////////////////////////////////////////////sort by snipes///////////////////////////////////////////
  10117.    
  10118.     document.getElementById("sort_by_snipes").addEventListener("click",()=>{
  10119.         map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  10120.             return (o1[1].nr_snipe_total>o2[1].nr_snipe_total)?-1:(o1[1].nr_snipe_total<o2[1].nr_snipe_total)?1:0;
  10121.         }))
  10122.         Array.from(map_playerId.keys()).forEach(key=>{
  10123.             let obj=map_playerId.get(key)
  10124.             obj.list_coords.sort((o1,o2)=>{
  10125.                 return (o1.nrSnipes>o2.nrSnipes)?-1:(o1.nrSnipes<o2.nrSnipes)?1:(o1.nrSniped>o2.nrSniped)?-1:(o1.nrSniped<o2.nrSniped)?1:0;
  10126.             })
  10127.             map_playerId.set(key,obj)
  10128.         })
  10129.         document.getElementById("tbody_player").remove()
  10130.         createTablePlayers(map_playerId,mapVillages)
  10131.     })
  10132.     //////////////////////////////////////////////////////////////sort by recaps///////////////////////////////////////////
  10133.     document.getElementById("sort_by_recaps").addEventListener("click",()=>{
  10134.         map_playerId= new Map([...map_playerId.entries()].sort((o1,o2) =>{
  10135.             return (o1[1].nr_recap_total>o2[1].nr_recap_total)?-1:(o1[1].nr_recap_total<o2[1].nr_recap_total)?1:0;
  10136.         }))
  10137.         Array.from(map_playerId.keys()).forEach(key=>{
  10138.             let obj=map_playerId.get(key)
  10139.             obj.list_coords.sort((o1,o2)=>{
  10140.                 return (o1.nrRecaps>o2.nrRecaps)?-1:(o1.nrRecaps<o2.nrRecaps)?1:(o1.nrRecaped>o2.nrRecaped)?-1:(o1.nrRecaped<o2.nrRecaped)?1:0
  10141.             })
  10142.             map_playerId.set(key,obj)
  10143.         })
  10144.         document.getElementById("tbody_player").remove()
  10145.         createTablePlayers(map_playerId,mapVillages)
  10146.     })
  10147.  
  10148. }
  10149.  
  10150.  
  10151.  
  10152. /////////////////////////////////////////////////////////////////create table for settings//////////////////////////////////////////////////////
  10153. function createTableGetCoords(mapVillages){
  10154.     let html_table=`
  10155.     <center>
  10156.     <table id="table_get_coords"  border="1" style="width: 70%;background-color:${backgroundColor};border-color:${borderColor};border-spacing:2px;border-collapse:separate;">
  10157.         <tr>
  10158.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  10159.                 <center><font style="margin:5px" color="${titleColor}">Players:</font></center>
  10160.             </td>
  10161.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10162.                 <input type="text" style="text-align:left;width:98%;font-size:18px" id="input_players"  placeholder="name player1, name player2, name player3">
  10163.             </td>
  10164.         </tr>
  10165.         <tr>
  10166.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  10167.                 <center><font style="margin:5px" color="${titleColor}">Tribes:</font></center>
  10168.             </td>
  10169.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10170.                 <input type="text" style="text-align:left;width:98%;font-size:18px" id="input_tribes"  placeholder="name tribe1, name tribe2, name tribe3">
  10171.             </td>
  10172.         </tr>
  10173.         <tr>
  10174.             <td style="text-align:left; width:auto; background-color:${headerColor}" >
  10175.                 <center><font style="margin:5px" color="${titleColor}">Continents:</font></center>
  10176.             </td>
  10177.             <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10178.                 <input type="text" style="text-align:left;width:98%;font-size:18px" id="input_continents"  placeholder="54,55,65">
  10179.             </td>
  10180.         </tr>
  10181.         <tr>
  10182.             <td style="text-align:left; width:auto; background-color:${headerColor}" ">
  10183.                <center><font style="margin:5px" color="${titleColor}">Min coord:</font></center>
  10184.            </td>
  10185.            <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10186.                <div style="display:flex">
  10187.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_x_min" min="0" max="1000" placeholder="X"></div>
  10188.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_y_min" min="0" max="1000" placeholder="Y"></div>
  10189.                </div>
  10190.            </td>
  10191.        </tr>
  10192.        <tr>
  10193.            <td style="text-align:left; width:auto; background-color:${headerColor}" >
  10194.                <center><font style="margin:5px" color="${titleColor}">Max coord:</font></center>
  10195.            </td>
  10196.            <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10197.                <div style="display:flex">
  10198.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_x_max" min="0" max="1000" placeholder="X"></div>
  10199.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_y_max" min="0" max="1000" placeholder="Y"></div>
  10200.                </div>
  10201.            </td>
  10202.        </tr>
  10203.        <tr>
  10204.            <td style="text-align:left; width:auto; background-color:${headerColor}" >
  10205.                <center><font style="margin:5px" color="${titleColor}">Dist from center:</font></center>
  10206.            </td>
  10207.            <td style="text-align:center; width:auto; background-color:${headerColor}" >
  10208.                <div style="display:flex">
  10209.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_radius" min="0" max="1000" placeholder="R"></div>
  10210.                    <div> <font style="margin:5px" color="${titleColor}">fields from:</font></div>
  10211.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_center_x" min="0" max="1000" placeholder="X"></div>
  10212.                    <div> <input type="number" style="text-align:center;font-size:18px" id="input_center_y" min="0" max="1000" placeholder="Y"></div>
  10213.                </div>
  10214.            </td>
  10215.        </tr>
  10216.        <tr>
  10217.            <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  10218.                <center style="margin:10px"><input class="btn" type="button" id="btn_extract_coord"  value="extract_coords"></center>
  10219.            </td>
  10220.        </tr>
  10221.        <tr>
  10222.            <td style="text-align:left; width:auto; background-color:${headerColor}" colspan="2">
  10223.                <font id="nr_coords" style="margin:10px;margin-left:100px;font-size:15px" color="${titleColor}">nr coords:(0)</font>
  10224.                <center style="margin:10px"><textarea id="input_get_coords" cols="60" rows="20" ></textarea><center>
  10225.            </td>
  10226.        </tr>
  10227.  
  10228.    </table>
  10229.  
  10230.    </div></center>
  10231.    `
  10232.  
  10233.    if(document.getElementById("table_get_coords")==null)
  10234.        document.getElementById("div_get_coords").innerHTML=html_table
  10235.    else{
  10236.        $("#div_rank_attacker").hide()
  10237.        $("#div_rank_defender").hide()
  10238.        $("#div_upload_time").hide()
  10239.        $("#div_settings").hide(500)
  10240.        $("#div_get_coords").toggle(500)
  10241.    }    
  10242.  
  10243.  
  10244.    // //initialize settings only if it's visible
  10245.  
  10246.    if(localStorage.getItem(game_data.world+"save_settings")!=null ){
  10247.        let list_checkbox=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[0]
  10248.  
  10249.        $('#div_settings input[type=checkbox], #div_get_coords input[type=checkbox]').each(function (index,elem) {
  10250.            this.checked=list_checkbox[index]
  10251.            // console.log(elem.value)
  10252.        });
  10253.  
  10254.        let list_input=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[1]
  10255.        $('#div_settings input[type=number], #div_get_coords input[type=text],#div_get_coords input[type=number]').each(function (index,elem) {
  10256.            // var checked = this.checked
  10257.            this.value=list_input[index]
  10258.        });
  10259.  
  10260.        let value_radio=JSON.parse(localStorage.getItem(game_data.world+"save_settings"))[2]
  10261.        $(`input[name='type_info'][value='${value_radio}'`).attr("checked",true)
  10262.  
  10263.    }
  10264.  
  10265.  
  10266.  
  10267.    //save settings
  10268.    $("#div_settings input[type=checkbox],#div_settings input[type=number], input[name='type_info'], #div_get_coords input[type=checkbox], #div_get_coords input[type=text], #div_get_coords input[type=number]").on("mouseup input",()=>{
  10269.        console.log("save")
  10270.        let list_checkbox=[]
  10271.        let list_input=[]
  10272.        //save checkbox
  10273.        $('#div_settings input[type=checkbox], #div_get_coords input[type=checkbox]').each(function () {
  10274.            var checked = this.checked
  10275.            list_checkbox.push(checked)
  10276.        });
  10277.        //save inputs
  10278.        $('#div_settings input[type=number], #div_get_coords input[type=text], #div_get_coords input[type=number]').each(function () {
  10279.            // var checked = this.checked
  10280.            var value=this.value
  10281.            // console.log(value)
  10282.            list_input.push(value)
  10283.        });
  10284.        //save radio button
  10285.        let value_radio=$("input[name='type_info']:checked").val()
  10286.  
  10287.  
  10288.  
  10289.        let list_final=[list_checkbox,list_input,value_radio]
  10290.        localStorage.setItem(game_data.world+"save_settings",JSON.stringify(list_final))
  10291.  
  10292.    })
  10293.  
  10294.  
  10295.    $("#btn_extract_coord").off("click")
  10296.    $("#btn_extract_coord").on("click",()=>{
  10297.        //create the logic for extracting coords
  10298.        let playersName= Array.from(document.getElementById("input_players").value.toLowerCase().split(",")).filter(item => item);
  10299.        let tribesName= Array.from(document.getElementById("input_tribes").value.toLowerCase().split(",")).filter(item => item)
  10300.        let continents= Array.from(document.getElementById("input_continents").value.split(",")).filter(item => item)
  10301.        let xMin= parseInt(document.getElementById("input_x_min").value)
  10302.        let yMin= parseInt(document.getElementById("input_y_min").value)
  10303.        let xMax= parseInt(document.getElementById("input_x_max").value)
  10304.        let yMax= parseInt(document.getElementById("input_y_max").value)
  10305.  
  10306.        let radius= parseInt(document.getElementById("input_radius").value)
  10307.        let xCenter= parseInt(document.getElementById("input_center_x").value)
  10308.        let yCenter= parseInt(document.getElementById("input_center_y").value)
  10309.  
  10310.  
  10311.        console.log(mapVillages)
  10312.  
  10313.        let result_coords=[]
  10314.  
  10315.  
  10316.        Array.from(mapVillages.keys()).forEach(coord=>{
  10317.            try {
  10318.                let obj=mapVillages.get(coord)
  10319.                let isValid=true
  10320.  
  10321.  
  10322.  
  10323.                // console.log(obj)
  10324.                //check for players names
  10325.                if(playersName.length>0){
  10326.                    let found=false
  10327.                    for(let j=0;j<playersName.length;j++){
  10328.                        if(playersName[j].trim() == obj.playerName.toLowerCase()){//let coord get through next filter
  10329.                            found=true
  10330.                            break;
  10331.                        }
  10332.                    }
  10333.                    if(found==false)
  10334.                        isValid=false
  10335.                }
  10336.                
  10337.                //check for tribes names
  10338.                if(tribesName.length>0){
  10339.                    let found=false
  10340.                    for(let j=0;j<tribesName.length;j++){
  10341.                        if(tribesName[j].trim() == obj.tribeName.toLowerCase()){//let coord get through next filter
  10342.                            found=true
  10343.                            break;
  10344.                        }
  10345.                    }
  10346.                    if(found==false)
  10347.                        isValid=false
  10348.                }
  10349.                
  10350.                //check for continents
  10351.                if(continents.length>0){
  10352.                    let found=false
  10353.                    for(let j=0;j<continents.length;j++){
  10354.                        if(continents[j].trim() == getContinent(coord)){//let coord get through next filter
  10355.                            found=true
  10356.                            break;
  10357.                        }
  10358.                    }
  10359.                    if(found==false)
  10360.                        isValid=false
  10361.                }
  10362.                
  10363.  
  10364.                let[x,y]=coord.split("|")
  10365.                //for x min
  10366.                if(Number.isNaN(xMin)==false && isValid==true){
  10367.                    isValid = (x >= xMin)?true:false
  10368.                }
  10369.                //for y min
  10370.                if(Number.isNaN(yMin)==false && isValid==true){
  10371.                    isValid = (y >= yMin)?true:false
  10372.                }
  10373.                //for x max
  10374.                if(Number.isNaN(xMax)==false && isValid==true){
  10375.                    isValid = (x <= xMax)?true:false
  10376.                }
  10377.                //for y max
  10378.                if(Number.isNaN(yMax)==false && isValid==true){
  10379.                    isValid = (y <= yMax)?true:false
  10380.                }
  10381.  
  10382.  
  10383.                if(Number.isNaN(radius)==false && Number.isNaN(xCenter)==false && Number.isNaN(yCenter)==false && isValid==true){
  10384.                    isValid=(calcDistance( xCenter+"|"+yCenter, coord)<radius)?true:false
  10385.                }
  10386.  
  10387.  
  10388.  
  10389.                if(isValid==true){
  10390.                    result_coords.push(coord)
  10391.                }
  10392.  
  10393.            } catch (error) {}
  10394.            
  10395.        })
  10396.        console.log(result_coords)
  10397.        document.getElementById("input_get_coords").value=result_coords.join(" ")
  10398.        document.getElementById("nr_coords").innerHTML=`nr coords:(${result_coords.length})`
  10399.  
  10400.    })
  10401.  
  10402.    
  10403.  
  10404.  
  10405.    // console.log(mapVillages)
  10406. }
  10407.  
  10408. function getContinent(coord){
  10409.    let [x,y]=Array.from(coord.split("|")).map(e=>parseInt(e))
  10410.    for(let i=0;i<2000;i+=100){//x axes
  10411.        for(let j=0;j<2000;j+=100){//y axes
  10412.            if(i>=x && x<i+100   &&    j>=y && y<j+100){
  10413.                let nr_continent= parseInt(y/100)+""+parseInt(x/100)
  10414.                return nr_continent
  10415.            }
  10416.        }
  10417.    }
  10418. }
  10419.  
  10420.  
  10421.  
  10422. function insertChartLibrary(){
  10423.    return new Promise((resolve,reject)=>{
  10424.  
  10425.  
  10426.        let start=new Date().getTime()
  10427.        let script = document.createElement('script');
  10428.        script.type="text/javascript"
  10429.        script.src="https://cdn.anychart.com/releases/8.9.0/js/anychart-base.min.js"
  10430.         script.onload = function () {
  10431.             let stop=new Date().getTime()
  10432.             console.log(`insert chart library in ${stop-start} ms`)
  10433.             resolve("done")
  10434.         };
  10435.         document.head.appendChild(script);
  10436.     })
  10437. }
  10438.  
  10439.  
  10440. function createChart(list_points,name_container){
  10441.     // create a chart
  10442.     let chart = anychart.area();
  10443.  
  10444.         // create a line series and set the data
  10445.     let series = chart.column(list_points);
  10446.  
  10447.  
  10448.  
  10449.     // set the container id
  10450.     chart.container(name_container);
  10451.     chart.tooltip().format("incs: {%value}");
  10452.  
  10453.     chart.xAxis().labels().rotation(-45);
  10454.     chart.yAxis().labels().format(function() {
  10455.     let value = this.value;
  10456.         // limit the number of symbols to 3
  10457.         value = value+" incs";
  10458.         return value
  10459.     })
  10460.  
  10461.  
  10462.     // initiate drawing the chart
  10463.     chart.draw();
  10464.     document.getElementsByClassName("anychart-credits")[0].remove()
  10465.  
  10466.  
  10467. }
  10468.  
  10469. function getNameTroops() { //Get troops name
  10470.     return new Promise(async(resolve,reject)=>{
  10471.         let obj
  10472.         if (localStorage.getItem(game_data.world+"nameTroops") !== null) {
  10473.             obj=JSON.parse(localStorage.getItem(game_data.world+"nameTroops"))
  10474.             console.log("nameTroops already exist")
  10475.             resolve(obj)
  10476.         }
  10477.         else { //Get data from xml and save it in localStorage to avoid excessive XML requests to server
  10478.                 let currentHtml=document.body.innerHTML
  10479.                 document.body.innerHTML = await ajaxGet(game_data.link_base_pure+"place") //go to rally point
  10480.                
  10481.                 let obj={}
  10482.                 Array.from($("#command-data-form .unit_link")).forEach(elem=>{
  10483.                     let value=$(elem).find("img").attr("title")
  10484.                     let name=$(elem).attr("data-unit")
  10485.                     obj[name]=value
  10486.                 })
  10487.                 document.body.innerHTML=currentHtml
  10488.                 localStorage.setItem(game_data.world+"nameTroops",JSON.stringify(obj));
  10489.                 console.log("save nameTroops")
  10490.             resolve(obj)
  10491.         }
  10492.     })
  10493. }
  10494.  
  10495.  
  10496. function showIncomings(list){
  10497.  
  10498.     let serverTime=document.getElementById("serverTime").innerText
  10499.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  10500.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  10501.     let date_current=new Date(serverDate+" "+serverTime).getTime()
  10502.  
  10503.  
  10504.     let html_incomings=`
  10505.     <div id="div_container_incs" class="ui-widget-content div_remove" style="width:900px;background-color:${backgroundColor};cursor:move;z-index:50;">
  10506.     <div style="position:relative;top:10px;left: 860px;display:flex">
  10507.         <div  class="close-btn"   ><a href="#" onclick="closeWindow()"><b><font color="${titleColor}">X</font></b></a></div>
  10508.     </div>
  10509.     <br>
  10510.     <center><div id="table_results" style="height:800px;width:900px;overflow:auto">
  10511.     <table id="table_stats"  border="1" style="width: 100%;background-color:${backgroundColor};border-color:${borderColor};">
  10512.         <tr style=" position: sticky;top: 0;z-index: 10;">
  10513.             <td colspan="2" style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10514.                 <center style="margin:10px"><font color="${titleColor}">destination</font></center>
  10515.             </td>    
  10516.             <td colspan="2" style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10517.                <center style="margin:10px"><font color="${titleColor}">origin </font></center>
  10518.             </td>    
  10519.             <td  style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10520.                 <center style="margin:10px"><font color="${titleColor}">Launch time </font></center>
  10521.             </td>    
  10522.             <td  style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10523.                 <center style="margin:10px"><font color="${titleColor}">arrival time </font></center>
  10524.             </td>    
  10525.             <td style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10526.                 <center style="margin:10px"><font color="${titleColor}">type </font></center>
  10527.             </td>    
  10528.             <td style="text-align:center; width:auto; background-color:${headerColorCoords}">
  10529.                 <center style="margin:10px"><font color="${titleColor}">arrives in </font></center>
  10530.             </td>    
  10531.  
  10532.  
  10533.  
  10534.         </tr>`
  10535.  
  10536.  
  10537.         for(let i=0;i<list.length;i++){
  10538.  
  10539.             let arrived=new Date(list[i].date_land).getTime()  
  10540.             let type_attack_landed= (list[i].type_attack_landed !=undefined)?list[i].type_attack_landed:"?"
  10541.  
  10542.             let headerColorIncs= (list[i].colorRow == true)?headerColor:getColorDarker(headerColor,50)
  10543.                
  10544.            
  10545.                 html_incomings+=`
  10546.                     <tr style="white-space:nowrap;" >
  10547.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10548.                             <a href="${game_data.link_base_pure}info_village&id=${list[i].id_coord_def}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].coord_def}</font></center></a>
  10549.                         </td>
  10550.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10551.                             <a href="${game_data.link_base_pure}info_player&id=${list[i].id_player_def}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].player_def}</font></center></a>
  10552.                         </td>
  10553.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10554.                             <a href="${game_data.link_base_pure}info_village&id=${list[i].id_coord_off}"style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].coord_off}</font></center></a>
  10555.                         </td>
  10556.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10557.                             <a href="${game_data.link_base_pure}info_player&id=${list[i].id_player_off}" style="margin:0px;padding:0px"><center><font color="${titleColor}">${list[i].player_off}</font></center></a>
  10558.                         </td>
  10559.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10560.                             <center style="margin:3px;padding:0px"><font color="${titleColor}"> ${list[i].date_launch.split(" ")[0]} <b>${list[i].date_launch.split(" ")[1]}</b>  </font> </center>
  10561.                         </td>  
  10562.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10563.                             <center style="margin:3px;padding:0px"><font color="${titleColor}"> ${list[i].date_land.split(" ")[0]} <b>${list[i].date_land.split(" ")[1]}</b>  </font> </center>
  10564.                         </td>  
  10565.                         <td style="text-align:center; width:auto; background-color:${headerColorIncs}">
  10566.                             <center style="margin:3px;padding:0px"><font color="${titleColor}">${type_attack_landed} </font> </center>
  10567.                         </td>`  
  10568.                
  10569.                     if(arrived>date_current){
  10570.                         html_incomings+=
  10571.                         `<td style="text-align:center; width:auto; background-color:${headerColorIncs}" >
  10572.                             <center style="margin:3px;padding:0px"><font color="${titleColor}" date-time=${arrived} class="counterTime1">${convertBuildTime(arrived-date_current)}</font></center>
  10573.                         </td>`    
  10574.                     }else{
  10575.                         html_incomings+=
  10576.                         `<td style="text-align:center; width:auto; background-color:${headerColorIncs}" >
  10577.                             <center style="margin:3px;padding:0px"><font color="${titleColor}">landed</font></center>
  10578.                         </td>`    
  10579.                     }  
  10580.                     html_incomings+=`</tr>`
  10581.                
  10582.            
  10583.         }
  10584.         html_incomings+=`</table></div></center></div>`
  10585.         // Dialog.show("content",html_incomings)
  10586.         $("#div_container_incs").remove()
  10587.         $("#contentContainer").eq(0).prepend(html_incomings);
  10588.         $("#mobileContent").eq(0).prepend(html_incomings);
  10589.    
  10590.        
  10591.         $("#div_container_incs").css("position","fixed");
  10592.         $("#div_container_incs").draggable();
  10593. }
  10594.  
  10595.  
  10596. function getColorDarker(hexInput, percent) {
  10597.     let hex = hexInput;
  10598.  
  10599.     // strip the leading # if it's there
  10600.     hex = hex.replace(/^\s*#|\s*$/g, "");
  10601.  
  10602.     // convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
  10603.     if (hex.length === 3) {
  10604.         hex = hex.replace(/(.)/g, "$1$1");
  10605.     }
  10606.  
  10607.     let r = parseInt(hex.substr(0, 2), 16);
  10608.     let g = parseInt(hex.substr(2, 2), 16);
  10609.     let b = parseInt(hex.substr(4, 2), 16);
  10610.  
  10611.     const calculatedPercent = (100 + percent) / 100;
  10612.  
  10613.     r = Math.round(Math.min(255, Math.max(0, r * calculatedPercent)));
  10614.     g = Math.round(Math.min(255, Math.max(0, g * calculatedPercent)));
  10615.     b = Math.round(Math.min(255, Math.max(0, b * calculatedPercent)));
  10616.  
  10617.     return `#${("00"+r.toString(16)).slice(-2).toUpperCase()}${("00"+g.toString(16)).slice(-2).toUpperCase()}${("00"+b.toString(16)).slice(-2).toUpperCase()}`
  10618. }
  10619.  
  10620. function convertBuildTime(milliseconds){
  10621.     let seconds =  parseInt((milliseconds / 1000)) % 60 ;
  10622.     let minutes = parseInt(((milliseconds / (1000*60))) % 60);
  10623.     let hours   = parseInt(((milliseconds / (1000*60*60))));
  10624.     seconds = ("00"+seconds).slice(-2)
  10625.     minutes = ("00"+minutes).slice(-2)
  10626.     hours = ("000"+hours).slice(-3)
  10627.  
  10628.     return hours+":"+minutes+":"+seconds
  10629. }
  10630.  
  10631.    
  10632.  
  10633. function convertDate(date){
  10634.     let months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
  10635.     let monthIndex = date.split("/")[0]-1
  10636.     let dayIndex = date.split("/")[1]
  10637.     let time = date.split(" ")[1]
  10638.     console.log(date)  
  10639.     console.log(`${months[monthIndex]} ${dayIndex} ${time}` )
  10640.  
  10641.     if (months[monthIndex] == undefined)
  10642.         return ""
  10643.     else
  10644.         return `${months[monthIndex]} ${dayIndex} ${time}`
  10645.  
  10646.  
  10647. }
  10648.  
  10649. ////////////////////////////////////////////// get commands sharing settings ///////////////////////////////////////
  10650.  
  10651. async function getCommandsSharing(){
  10652.     return new Promise(async(resolve, reject)=>{
  10653.         let savedData = JSON.parse(localStorage.getItem(game_data.world + "commandSharing"))
  10654.         let mapResult = null
  10655.         if(savedData){
  10656.             if(Math.abs(new Date(savedData.timestamp).getTime() - new Date().getTime()) > 48 * 3600 * 1000){
  10657.                 mapResult = new Map(savedData.mapResult)
  10658.             }
  10659.  
  10660.         }
  10661.         if (mapResult == null){
  10662.            
  10663.             let commandsSharingHref= game_data.link_base_pure + "settings&mode=command_sharing";
  10664.             let data = await ajaxGet(commandsSharingHref);
  10665.        
  10666.        
  10667.             const parser = new DOMParser();
  10668.             const htmlDoc = parser.parseFromString(data, 'text/html');
  10669.        
  10670.             mapResult = new Map()
  10671.             Array.from($(htmlDoc).find("form table tr")).forEach(elem=>{
  10672.                 let tds = elem.getElementsByTagName("td")
  10673.            
  10674.                 if(tds.length > 0){
  10675.                     let playerName = tds[0].innerText
  10676.                     let viewCommands = (tds[2].getElementsByTagName("input")[0].checked == true) ? true : false
  10677.                     let sharedCommands = false
  10678.                     if(tds[2].getElementsByTagName("img").length > 0){
  10679.                         if(tds[2].getElementsByTagName("img")[0].src.includes("confirm.png")){
  10680.                             sharedCommands = true
  10681.                         }
  10682.                     }
  10683.            
  10684.                     if(viewCommands == true && sharedCommands == true){
  10685.                         mapResult.set(playerName, true)
  10686.                     }
  10687.                 }
  10688.             })
  10689.    
  10690.             let saveMapResult = Array.from(mapResult.entries())
  10691.             localStorage.setItem(game_data.world + "commandSharing",JSON.stringify({
  10692.                 mapResult: saveMapResult,
  10693.                 timestamp: new Date()
  10694.             }))
  10695.         }
  10696.         resolve(mapResult)
  10697.  
  10698.  
  10699.  
  10700.  
  10701.     })
  10702.  
  10703. }
  10704.  
  10705. ////////////////////////////////////////////// get own info ///////////////////////////////////////
  10706.  
  10707.  
  10708. async function getOwnTroopsInfo(){
  10709.     return new Promise(async(resolve, reject)=>{
  10710.         if(document.getElementsByClassName("info").length>0)
  10711.         $(".info").remove()
  10712.    
  10713.         let troopsHref= game_data.link_base_pure+"overview_villages&mode=units&group=0&page=-1";
  10714.    
  10715.         console.log(troopsHref)
  10716.         let data = await ajaxGet(troopsHref);
  10717.    
  10718.    
  10719.         const parser = new DOMParser();
  10720.         const htmlDoc = parser.parseFromString(data, 'text/html');
  10721.    
  10722.         let listHref=[];
  10723.         if(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  10724.             Array.from(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select")[0].options).forEach(el=>{
  10725.                 listHref.push(el.value);
  10726.             })
  10727.             listHref.pop();
  10728.         }
  10729.         else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){
  10730.             let arr=Array.from(htmlDoc.getElementsByClassName("paged-nav-item"));
  10731.             for(let i=0;i<arr.length;i++)
  10732.             listHref.push(arr[i].getAttribute("href"))
  10733.         }
  10734.         else{
  10735.             listHref.push(troopsHref)
  10736.    
  10737.         }
  10738.         console.log(listHref)
  10739.         let mapResult = new Map();
  10740.         const run = async () => {
  10741.             console.log("Starting...");
  10742.             for (let i = 0; i < listHref.length; i++) {
  10743.                 let pageHTML= await ajaxGet(listHref[i])
  10744.                 const parser = new DOMParser();
  10745.                 const htmlDoc = parser.parseFromString(pageHTML, 'text/html');
  10746.    
  10747.                 let tableTroops = Array.from($(htmlDoc).find(".row_a, .row_b"))
  10748.    
  10749.                 //each village has 5 rows with different type of troops
  10750.                 for(let j=0;j<tableTroops.length;j++){
  10751.                     let rows = Array.from($(tableTroops[j]).find("tr"))
  10752.                     let coord = $(rows[0]).find(".quickedit-label").text().match(/\d+\|\d+/)[0]
  10753.  
  10754.                     let troopsOwn = {}, troopInVillage = {}, troopsOutWards = {},  troopsInTransit = {}, troopsTotal = {}
  10755.                     Array.from($(rows[0]).find(".unit-item")).map(elem=> parseInt(elem.innerText)).forEach((elem, index)=>{
  10756.                         troopsOwn[game_data.units[index]] = elem
  10757.                     })
  10758.                     Array.from($(rows[1]).find(".unit-item")).map(elem=> parseInt(elem.innerText)).forEach((elem, index)=>{
  10759.                         troopInVillage[game_data.units[index]] = elem
  10760.                     })
  10761.                     Array.from($(rows[2]).find(".unit-item")).map(elem=> parseInt(elem.innerText)).forEach((elem, index)=>{
  10762.                         troopsOutWards[game_data.units[index]] = elem
  10763.                     })
  10764.                     Array.from($(rows[3]).find(".unit-item")).map(elem=> parseInt(elem.innerText)).forEach((elem, index)=>{
  10765.                         troopsInTransit[game_data.units[index]] = elem
  10766.                     })
  10767.                     Array.from($(rows[4]).find(".unit-item")).map(elem=> parseInt(elem.innerText)).forEach((elem, index)=>{
  10768.                         troopsTotal[game_data.units[index]] = elem
  10769.                     })
  10770.                     // console.log("troopsOwn",troopsOwn)
  10771.                     // console.log("troopInVillage",troopInVillage)
  10772.                     // console.log("troopsOutWards",troopsOutWards)
  10773.                     // console.log("troopsInTransit",troopsInTransit)
  10774.                     // console.log("troopsTotal",troopsTotal)
  10775.    
  10776.                     mapResult.set(coord,{
  10777.                         troopsOwn: troopsOwn,
  10778.                         troopInVillage: troopInVillage,
  10779.                         troopsOutWards: troopsOutWards,
  10780.                         troopsInTransit: troopsInTransit,
  10781.                         troopsTotal: troopsTotal,
  10782.                         playerId: game_data.player.id
  10783.                     })
  10784.                 }
  10785.                 UI.SuccessMessage(`get link page ${i+1}/${listHref.length}`)
  10786.             }  
  10787.         }
  10788.         await run();
  10789.  
  10790.         resolve(mapResult)
  10791.  
  10792.  
  10793.     })
  10794.  
  10795. }
  10796.  
  10797. async function getVillagesBuildings(){
  10798.     return new Promise(async(resolve, reject)=>{
  10799.         if(document.getElementsByClassName("info").length>0)
  10800.         $(".info").remove()
  10801.    
  10802.         let buildingHref= game_data.link_base_pure+"overview_villages&mode=buildings&group=0&page=-1";
  10803.    
  10804.         console.log(buildingHref)
  10805.         let data = await ajaxGet(buildingHref);
  10806.    
  10807.    
  10808.         const parser = new DOMParser();
  10809.         const htmlDoc = parser.parseFromString(data, 'text/html');
  10810.    
  10811.         let listHref=[];
  10812.         if(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select").length>0){
  10813.             Array.from(htmlDoc.getElementsByClassName("vis")[1].getElementsByTagName("select")[0].options).forEach(el=>{
  10814.                 listHref.push(el.value);
  10815.             })
  10816.             listHref.pop();
  10817.         }
  10818.         else if(htmlDoc.getElementsByClassName("paged-nav-item").length>0){
  10819.             let arr=Array.from(htmlDoc.getElementsByClassName("paged-nav-item"));
  10820.             for(let i=0;i<arr.length;i++)
  10821.             listHref.push(arr[i].getAttribute("href"))
  10822.         }
  10823.         else{
  10824.             listHref.push(buildingHref)
  10825.    
  10826.         }
  10827.         console.log(listHref)
  10828.         let mapResult = new Map();
  10829.         const run = async () => {
  10830.             console.log("Starting...");
  10831.             for (let i = 0; i < listHref.length; i++) {
  10832.                 let pageHTML= await ajaxGet(listHref[i])
  10833.                 const parser = new DOMParser();
  10834.                 const htmlDoc = parser.parseFromString(pageHTML, 'text/html');
  10835.    
  10836.                 let rows = Array.from($(htmlDoc).find(".row_a, .row_b"))
  10837.    
  10838.                 for(let j=0;j<rows.length;j++){
  10839.                     let coord = $(rows[j]).find(".quickedit-label").text().match(/\d+\|\d+/)[0]
  10840.                     let wallLvl = parseInt($(rows[j]).find(".b_wall").text())
  10841.                     let farmLvl = parseInt($(rows[j]).find(".b_farm").text())
  10842.                     wallLvl = (!Number.isNaN(wallLvl)) ? wallLvl : 0
  10843.                     farmLvl = (!Number.isNaN(farmLvl)) ? farmLvl : 0
  10844.  
  10845.                     mapResult.set(coord,{
  10846.                         wallLvl: wallLvl,
  10847.                         farmLvl: farmLvl
  10848.                     })
  10849.                 }
  10850.                 UI.SuccessMessage(`get link page ${i+1}/${listHref.length}`)
  10851.             }  
  10852.         }
  10853.         await run();
  10854.  
  10855.         resolve(mapResult)
  10856.  
  10857.  
  10858.     })
  10859.  
  10860. }
  10861.  
  10862. async function uploadOwnTroops(){
  10863.     document.getElementById("progress_troops_home").innerText="Getting data...";
  10864.    
  10865.     let [mapVillages, troopsHomeData, statusUploadData,status]=await Promise.all([
  10866.         getInfoVillages(),
  10867.         readFileDropbox(filename_troops_home),
  10868.         readFileDropbox(filename_status_upload),
  10869.         insertlibraryLocalBase()
  10870.     ]).catch(err=>{alert(err)})
  10871.  
  10872.  
  10873.  
  10874.     /////////////////////////////////////////////////////////////////////////Get current troops home from dropbox database/////////////////////////
  10875.     let mapTroopsHomeDropbox = new Map()
  10876.     try {
  10877.         let decompressedData = await decompress(await troopsHomeData.arrayBuffer() , 'gzip');  
  10878.         mapTroopsHomeDropbox=new Map(JSON.parse(decompressedData))
  10879.  
  10880.     } catch (error) {
  10881.         console.log("erorr map troops home from dropbox: " + error)
  10882.     }
  10883.  
  10884.     //if  database is stored locally
  10885.     if(await localBase.getItem(game_data.world+"troops_home")!=undefined){
  10886.         try{
  10887.             let decompressedDataBase64 = base64ToBlob(await localBase.getItem(game_data.world + "troops_home"))
  10888.             let decompressedData = await decompress(await decompressedDataBase64.arrayBuffer(), 'gzip')
  10889.    
  10890.             let map_localBase=new Map( JSON.parse(decompressedData));
  10891.             mapTroopsHomeDropbox=new Map([...map_localBase, ...mapTroopsHomeDropbox])
  10892.         } catch (error) {
  10893.             console.log("erorr map troops home from localbase: " + error)
  10894.         }
  10895.     }
  10896.  
  10897.     /////////////////////////////////////////////////////////////////////////Get map status from dropbox database/////////////////////////
  10898.     let mapStatus = new Map();
  10899.     try {
  10900.         let decompressedData = await decompress(await statusUploadData.arrayBuffer() , 'gzip');  
  10901.         mapStatus=new Map( JSON.parse(decompressedData));
  10902.     } catch (error) {
  10903.         console.log("erorr map status from dropbox: " + error)
  10904.     }
  10905.  
  10906.  
  10907.     // console.log(mapTroopsHomeDropbox)
  10908.     // console.log(mapStatus)
  10909.     /////////////////////////////////////////////////////////////////////////Get current troops home for all villages/////////////////////////
  10910.  
  10911.     let troopsHome=await getOwnTroopsInfo().catch(err=>{alert(err);throw err})
  10912.     let mapVillagesWall=await getVillagesBuildings().catch(err=>{alert(err);throw err})
  10913.  
  10914.     console.log(troopsHome)
  10915.     //add villages wall
  10916.     Array.from(troopsHome.keys()).forEach(coord=>{
  10917.         if(mapVillagesWall.has(coord)){
  10918.             let updateObj = troopsHome.get(coord);
  10919.             updateObj.wallLvl = mapVillagesWall.get(coord).wallLvl
  10920.             updateObj.farmLvl = mapVillagesWall.get(coord).farmLvl
  10921.             troopsHome.set(coord, updateObj)
  10922.         }
  10923.     })
  10924.  
  10925.     // console.log(mapVillages)
  10926.     // console.log(mapTroopsHomeDropbox)
  10927.  
  10928.     //update map from dropbox
  10929.     mapTroopsHomeDropbox=new Map([...mapTroopsHomeDropbox, ...troopsHome])
  10930.  
  10931.     //remove old coords
  10932.     Array.from(mapTroopsHomeDropbox.keys()).forEach(coord=>{
  10933.         if(mapVillages.has(coord)){
  10934.             if(mapVillages.get(coord).playerId != mapTroopsHomeDropbox.get(coord).playerId){//old information-> needs to be removed
  10935.                 mapTroopsHomeDropbox.delete(coord)
  10936.             }
  10937.         }
  10938.     })
  10939.  
  10940.  
  10941.  
  10942.  
  10943.  
  10944.  
  10945.    
  10946.  
  10947.     //update status troops home
  10948.     let serverTime=document.getElementById("serverTime").innerText
  10949.     let serverDate=document.getElementById("serverDate").innerText.split("/")
  10950.     serverDate=serverDate[1]+"/"+serverDate[0]+"/"+serverDate[2]
  10951.     let date_current=serverDate+" "+serverTime
  10952.     console.log(date_current)
  10953.     let obj_status={
  10954.         name:game_data.player.name,
  10955.         troops_date:date_current,
  10956.     }
  10957.     if(mapStatus.has(game_data.player.id.toString())){
  10958.         let obj_update=mapStatus.get(game_data.player.id.toString())
  10959.         mapStatus.set(game_data.player.id.toString(), {...obj_update, ...obj_status} )
  10960.     }
  10961.     else{
  10962.         mapStatus.set(game_data.player.id.toString(),obj_status)
  10963.     }
  10964.  
  10965.  
  10966.     return new Promise(async(resolve, reject)=>{
  10967.         let timeStartUpload = new Date().getTime();
  10968.         let nr_start=new Date().getTime()
  10969.    
  10970.         //upload troops home
  10971.         let data=JSON.stringify(Array.from(mapTroopsHomeDropbox.entries()))
  10972.         let length_data = data.length
  10973.         let sizeTroopsHomeDB = formatBytes(new TextEncoder().encode(data).length)
  10974.    
  10975.         let compressedData = await compress(data,'gzip')
  10976.         let compressedDataBase64 = await blobToBase64(compressedData);
  10977.         let length_data_compressed=compressedData.size;
  10978.    
  10979.         let nr_stop=new Date().getTime()
  10980.    
  10981.         console.log("compressing data Troops home: "+(nr_stop-nr_start))
  10982.         console.log("length before: "+length_data+" length after compression: "+length_data_compressed)
  10983.         console.log("compression factor: "+(length_data/length_data_compressed))
  10984.    
  10985.                
  10986.         await localBase.setItem(game_data.world + "troops_home",compressedDataBase64)
  10987.         let result=await uploadFile(compressedData, filename_troops_home, dropboxToken).catch(err=>alert(err))
  10988.    
  10989.    
  10990.    
  10991.         let data_status=JSON.stringify(Array.from(mapStatus.entries()))
  10992.         let dataCompressed = await compress(data_status, "gzip")
  10993.         let resultStatus=await uploadFile(dataCompressed, filename_status_upload, dropboxToken).catch(err=>alert(err))
  10994.    
  10995.         console.log(resultStatus)
  10996.         if(resultStatus == "succes"){
  10997.             let timeStopUpload = new Date().getTime();
  10998.             let totalTimeUpload =  Math.round(((timeStopUpload - timeStartUpload) / 1000) * 100) / 100
  10999.             let nrCoord = mapTroopsHomeDropbox.size
  11000.             document.getElementById("progress_troops_home").innerText = `${nrCoord} coords`;
  11001.             UI.SuccessMessage(`Troops home done <br>
  11002.                                 Upload time: <b>${totalTimeUpload} sec</b> <br>
  11003.                                 Size DB: <b>${sizeTroopsHomeDB} </b>`, 10000)
  11004.             resolve({
  11005.                 totalTimeUpload: totalTimeUpload,
  11006.                 status: "success"
  11007.             })
  11008.         }
  11009.         else{
  11010.             reject("error upload troops info")
  11011.         }
  11012.     })
  11013.  
  11014. }
Add Comment
Please, Sign In to add comment