Travian ModKit 2.0

By HikariWS Last update Apr 27, 2010 — Installed 18,575 times.

There are 2 previous versions of this script.

the source is over 100KB, syntax highlighting in the browser is too slow

// ==UserScript==
// @name           Travian ModKit 2.0
// @author		Hikari (http://Hikari.ws)
// @version 	1.00.03
// @description	http://hikari.ws/dev/javascript/677/travian-modkit-20/
// @source 	http://userscripts.org/scripts/show/57667
// @license 	Creative Commons Attribution-Noncommercial-Share Alike 3.0
// @namespace      travmodkit
// @include        *travian*
// ==/UserScript==

/**
* The author of original Travian ModKit is IRoll11!~s from http://userscripts.org/users/IRoll11s
* Original code as fixed for Travian 3.5 by  underke from http://userscripts.org/users/91268
*
* I, Hikari, rebuild the whole code, using some code and resources from original one and adding
* a lot of new features, with the help of underke to understand some parts
*
* Travian ModKit 2.0  is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0
* To view a copy of this license, please visit http://creativecommons.org/licenses/by-nc-sa/3.0/
*
/*****************************************************************************
*© Copyright Hikari (http://Hikari.ws), 2009
* If you want to redistribute this script, please leave a link to
* http://hikari.ws/dev/javascript/677/travian-modkit-20/
*
*Parts of this code are provided or based on ideas and/or code written by others
*Translations to different languages are provided by users of this script
*IMPORTANT CONTRIBUTIONS TO THIS SCRIPT (listed in alphabetical order):
* IRoll11!~s, underke
*Please send a message to the address specified on the page of the script, for credits
*
* Other contributors' (nick)names may be provided in the header of (or inside) the functions
* SPECIAL THANKS to all contributors and translators of this script !
*****************************************************************************/





 //alert("begin ok");

//=================================
// global variables definitions

// villagesTableLeftCoord global variable stores villages table X coord, its default is for 1680x1050 monitor, change it as needed
var villagesTableLeftCoord = '1515px';
var debugMode=true;

var Prefs = '';


var vInfo = new VillagesData();

var core = new Core();
var getReferenceData = new GetReferenceData();
var getResourceInfo = new GetResourceInfo();
var showTotalProduction = new ShowTotalProduction();
var getBuildInfo = new GetBuildInfo();
var addListener = new AddListener();
var allVillagesEvents;
var showEvents = new ShowEvents();
var showCPSuggestions;
var createMenu = new CreateMenu();
var cps = new Array();
var cpSkipList = new CPSkipList();


// xLang is based on Travian Beyond code, it is used by CP Buildings Suggestions
// it is defined on the end of the fice
var xLang = new Array();



// images

var Xnull = "data:image/gif,GIF89a%0A%00%0A%00%E6R%00%07.f%F5%F6%F9%EF%F1%F5Zt%99)K%7F%0B2i%89%9C%B7%0B1i%0E4k%0A0i%09%2Fg%5Bu%9B%1DBy%138p%EE%F0%F4%0E3k%20Dx7Z%8E%03%2Bd%08.g%85%98%B4%138o'M%85%F8%FA%FB.S%89%5Bt%9ATr%9E%08%2Fg%B1%BC%CF%0E4l%3B_%94%3Fb%97%F7%F8%FA%19%3DrNo%9F%C2%CE%DD%0B1h%AC%BB%D2%080i3U%88%88%9E%BD%AC%B9%CC%C3%CE%DC%07-f'L%82%1DBw%BC%C8%D9%05-e%00%25_%24Hy%AD%BA%CD%0F5k%1A%3Ft%06.hCe%96%3Ea%95%116l'L%81%00'a%0A1i3W%8C%137nCd%952V%8C4Y%8F%0E3j%06-f%091h%18%3Ds%AB%B8%CC%B2%BD%D0Mn%9Dx%90%B2%07.g%0D3j%20E%7C%24Gy(L%81%03)c%1B%40wz%92%B3%5Ey%A1%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00R%00%2C%00%00%00%00%0A%00%0A%00%00%07e%80R%20*(QGH.%0ER%17%25%1A%3E%1E%3FK%10%06%01%23%22%1F7%3CM-%07%3D)P%40%11%189O%1D%000%036%16%2C%0C%15%26%2B%13%1BL'4%0D%095%00%0A%3B%071%03%3A%00B%0AC%05%08%2F%0BEAN%24%05J3%09!2%01%148%12%0F%08ID%94R%02%1C%19%04%04%0BF%02R%81%00%3B";
var Xdone = "data:image/gif,GIF89a%0A%00%0A%00%E6W%00%DD%C5%24%D8%BB%06%D8%BC%07%FD%FB%EC%D8%BC%06%E5%D3Z%FE%FC%F5%F2%EB%B2%D9%BE%0F%FC%F6%CE%D7%BB%04%FD%F6%CB%FD%E6N%FE%E48%FA%EA%7F%D6%BA%03%FD%E7R%D8%BC%0A%D8%BB%04%DA%BE%12%F7%DD-%FE%FD%F5%D6%B9%00%D8%BB%03%F1%D5%1F%D9%BD%0E%E5%D3X%D8%BC%08%F2%E9%AA%FE%E47%D7%BA%07%E3%C6%07%E7%CE.%DD%C0%06%D7%BB%03%D9%BC%00%D7%BB%02%FE%E7I%FF%FE%F9%FB%E0*%D9%BB%00%DA%BF%12%E4%C8%0D%D9%BC%01%D7%B9%00%F2%E9%AE%D8%BD%09%FD%E47%F2%D6!%D9%BD%0B%EE%DF%7F%EE%E1%83%E6%C9%0D%F4%ED%B5%D5%B8%00%FD%FB%EB%DD%C5%23%F2%E9%AD%EA%D9j%DD%C1%05%ED%DF~%D8%BA%03%E5%D3%5B%F0%D4%1F%DD%C0%04%D8%BC%0E%E5%D3Y%FE%FD%F3%F7%E1N%F4%D9%25%F1%DB%3D%E2%C9)%D8%BD%0A%EF%D2%1B%DA%BD%03%E5%C9%12%DA%BC%01%E2%C9%1E%F7%DD%2B%FD%EF%8C%FC%E35%F0%D81%E5%CB%22%FD%E5%3C%FD%F3%AB%E7%CC%14%D8%BD%0B%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00W%00%2C%00%00%00%00%0A%00%0A%00%00%07e%80W%15%09O%10D%3A5%03W%26T%0C%1D%2FQRG3%06%0B%25S%0DN%18M%1E%199%0E'P%14%3FU!%0F6%1AFE0I4%3B%23%22%178%20K*%1F%40L%12%04%02%00B(J%2B%0A%01%1BH%24%3E%1CA%16%BB.1%01%13-C2%08%2C%11V%3D)%3C%06W%03%07%05%00%00%05%077W%81%00%3B";
var Xon = "data:image/gif,GIF89a%0A%00%0A%00%E6%00%00%FF%FF%FF%F5%FA%F5%EF%F6%EF%13%87%13U%AAV%B1%D7%B1%01~%01%0A%82%0A%25%93%25%00%7B%00%02~%02%04~%04%2F%9C%2F%EE%F6%EE%10%85%10%04%84%04%02~%01.%A4.w%C2w%15%8F%156%AA6%AC%D5%AC%2B%A2%2B%0F%8A%0F%06%80%05%06%81%06%AB%D4%AB%06%80%07%10%84%10%07%81%09S%B6Su%BFu1%A11%83%C0%83W%AAW%3F%AF%3F%C0%E4%C0%01%7D%01%C3%E5%C3%19%8D%193%A93%1D%91%1D%04%7F%04%0B%81%0CV%AAWV%ABW%1E%8F%1E%86%CC%86%3C%A8%3C%F7%FB%F7%03~%03%0F%8C%0F%05%7F%06%06%7F%06%07%81%08P%AAP%86%C1%86%1B%8D%1B%13%91%13%07%80%08%1D%8F%1D%1F%99%1F%06%80%06%07%81%07%AB%D5%AB%00y%00%19%94%19%84%C1%84%26%9D%26%00%7D%00%01%7F%01%03%81%03%3C%AC%3C%1C%97%1C%02%81%02%F9%FC%F9%3C%AE%3C%AC%DC%AC.%A2.(%9B(I%B3I%BB%DF%BBM%B5M%0A%82%0B%0A%84%0A%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%00%00%00%00%00%2C%00%00%00%00%0A%00%0A%00%00%07f%80%001%26%2F%1E7%1FQ%0D%00KMR%23H%20)9C%01%24PL%14NO'%19%1C%40%12%11(%16I%3AT%0AA%040D%3DB3G%062%0B%3C%0C%13%17%0FJ%06*5%1B.%04EF%10%0B4%3B%07%25-%1A%2B%09%3E%3F%1DS%18%03%15%01!%0E%096%07%0A%038%01%00%02%05%2C%08%08%22%05%02%00%81%00%3B";
var XonX = "data:image/gif,GIF89a%0A%00%0A%00%E6%00%00%00%00%00%FF%FF%FF%F5%FA%F5%EF%F6%EF%25%93%25U%AAV%B1%D7%B1%13%87%13%04~%04%0A%82%0A%00%7B%00%02~%02%04%7F%04%BB%DF%BB%2F%9C%2F%10%85%10%3C%A8%3CS%B6S%0A%82%0B%0A%84%0A%86%CC%86%07%81%09%06%7F%06%00y%00%06%80%07%AC%DC%AC%19%8D%19%06%81%06%1E%8F%1E%10%84%10V%ABW%86%C1%86%07%81%08%02~%01%AB%D4%AB%C0%E4%C0%AB%D5%AB%00%7D%00M%B5M%3F%AF%3Fw%C2w1%A11(%9B(%01%7F%01P%AAP%EE%F6%EE%1F%99%1F%03~%03%13%91%133%A936%AA6%04%84%04%1C%97%1C%05%7F%06%07%80%08%0B%81%0CV%AAW%84%C1%84%06%80%05u%BFu%3C%AE%3CW%AAW%06%80%06%1B%8D%1B%07%81%07%1D%8F%1D%01~%01%AC%D5%AC%0F%8A%0F%19%94%19%1D%91%1D%15%8F%15%83%C0%83%C3%E5%C3%3C%AC%3C%26%9D%26I%B3I.%A4.%F7%FB%F7%F9%FC%F9%01%7D%01.%A2.%2B%A2%2B%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%00%00%00%00%00%2C%00%00%00%00%0A%00%0A%00%00%07e%80%01NI%14%11%2C%3B%0D-%01O%19%26'J)F%3F9%02%23L%3C2Q*%1A%1B%1D%24(M1R40%13%0B%17%05%10K.E%00%00B%2F%08A%0EGD3%AE%0C%16%18%1C%05%25%2B!%0856%09P%1E%227%0A%3E%40%15%12%3A%07C%02H%0F%0A%20%09%0B%07%1F%02%01%03%068%04%04%3D%06%03%01%81%00%3B";
var XRed = "data:image/gif,GIF89a%0A%00%0A%00%E6S%00%C4%04%04%FD%F5%F5%E5..%C8%15%15%FB%EF%EF%C4%01%01%C5%0D%0D%C4%06%06%D8ZZ%C2%00%00%EDJJ%D7%17%17%C4%07%07%D3%14%14%C6%0A%0A%D1((%F3%88%88%C6%02%02%C4%00%00%C3%02%02%E1%82%83%C5%09%09%EA%40%40%C5%07%07%CF%26%26%CC%22%22%DC%26%26%CF%1B%1B%D8Z%5B%E6%8A%8A%C4%08%08%EBNN%F9%C5%C5%F6%AC%AC%C6%0E%0E%D2%10%10%C5%08%08%C1%00%00%FE%F9%F9%EE%B1%B1%CA%05%05%CB%09%09%EC%AB%AC%EDSS%ECyy%DA%1F%1F%E4nn%C9%02%02%EC%AE%AE%EE%B2%B2%CC%04%04%C5%0B%0B%EA%3C%3C%E9%3A%3A%FC%EF%EF%D8%1D%1D%DA%2C%2C%D7UU%C4%05%05%CB%20%20%D1%18%18%D0%1A%1A%C5%06%06%C5%01%01%C5%0A%0A%C3%01%01%C4%03%03%C4%02%02%EF%B3%B3%E877%E8AA%E2..%C3%06%06%D7%25%25%ECMM%FA%C3%C3%D2%0D%0D%EC%AC%AC%FD%F6%F6%D6YY%CC!%22%E7%2C%2C%E3%89%89%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00S%00%2C%00%00%00%00%0A%00%0A%00%00%07f%80SN%20%10%2B%1F.D6S%26!J%164%02%3D%0F%1D%01K%0A5EGI%1BH%06M%2CQ%02%027%3C)C%259F%1A-%0BL(%05B%00%3B8%0D%232%2F%05%00%3E%17PO%12%3F%11%00%07%1E%0EA%1C*%06%09%07%0C%153%3A%030%01%14%22%09%24%40%13%03R%01S%04'%08%19%18%081%04S%81%00%3B";
var Xarrow = "data:image/gif,GIF89a%07%00%0A%00%D5%00%00%FF%FF%FFG%3E%3ERIIC99E%3C%3C%3E55JBB%F4%F4%F4%F4%F3%F3%BE%BA%BA%FB%FB%FBB88%84~~g__ULL%E7%E6%E6%B5%B2%B2%FD%FD%FDMDDvppC%3A%3AF%3D%3D%DE%DC%DC%4066G%3D%3DaYYKBB%97%92%92%C9%C8%C8%E6%E5%E5%BC%B8%B8%A2%9D%9Dyrr%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%00%00%00%00%00%2C%00%00%00%00%07%00%0A%00%00%060%40%80p%08%98p%0ED%03%05%F4%88%08%05%95%81a%D3%01%08%02%01%C2%C5%01%B9%060%8B%02%E3J%18d%3C%0AIA%93%40%08%1B%1F%0Bq.%0C%02%00%3B";
var XarrowUp = "data:image/gif,R0lGODlhCwAHAPcAAP///0c+PlJJSUM5OUU8PD41NUpCQvT09PTz8766uvv7+0I4OIR+fmdfX1VMTOfm5rWysv39/U1ERHZwcEM6OkY9Pd7c3EA2Nkc9PWFZWUtCQpeSksnIyObl5by4uKKdnXlycgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAACwAHAAAIPwABCBQIgYGCgQg7OCjgAaHACBsuLMiAwOEDAwQwDEiA8ACIAQECENBgYSAHChVCBijwYeAEAwJiCpDQAEBAAAA7";
var Xg0 = "data:image/gif,GIF89a%2F%00%3F%00%B3%00%00%19%16%0D%FB%F4%C9%9E%9D%7F%CF%CB%AA%83%84m%DB%F5%FD%FA%FA%E3%E3%EE%D1%CC%D4%C3fdR%AE%AE%94%C0%BF%A4GC0%A8%B8%B9%CE%E6%F7%E2%E3%C4!%F9%04%00%00%00%00%00%2C%00%00%00%00%2F%00%3F%00%00%04%FF%90%9D9%CD%23H%09%13%BA%7F%09!2D%970%1A%C1%00%8Ca%01%40%E2%22%0C%93TK%96%08G%C0%05%0FO%87%90(%92%024%80F%A1H%00z%83gb!%C0%3CxD%81f%23%F4u%2F%A7%C4c%E1D%09%B4E%97%80%81%98%0A%06%88%C1%E0%BA%F0%BA%82%1D%7C7px%0CB%08%04J%5BE%08%02%2C%22D*%04%03%5Ez%7B%90%01%03%3C%08%07%06%0B%88%0A%0B%2B0%83%18%0A%93%0Fx%8F%91%5D%07%3B%14%96%2B6N1dl%06%07%04%06%08%08%3F%A5%90%1A%0F%A9%13%0E6%0A*Jj%12T%8C6g%7B%A4x%0B%A7%3C%BC%7D%00%04K%00%0B.%0Dl%22U%06%0A5%90ck%99%04%3D%7D%CF%07%00gZ%D1%96%022%02%08%D5%07%0CU%5DU%ABD06%CC%BC%BB%07%08%D1L%87f%19(%82I%01%ADh%EC%3C%18%88%02C%DA%82%05%03%80%C1%A8Dn%02%3Fyg%14%9C%8Bu.%83%80%071%FF%0E%B0%D3%A3%B1F'y'%60l%B0H%B1%D6%0Et%1B%0550%10L%DC%95)%1EFV%E9%C4%A2%01%26%19%7D%1E%D4%82%B3i%07%95%1A%9C0%C0P%D0o%80%08%05%1E%88%3C%94%E3%C4%9D%8F%15%8Cj1ar%AD%A1%A0%18%06%0E%ADp'g%00F%0FE%06%2C%00u%82%C3%01L%8A%D6n%91%88%CF%89%8C%00%0DXhy(%60%93%08%20%01lD%84%D8%F6%C1%25%00%B6%E2l9S%A3A%93%15%D5%0E%13%C88%D9A%B4%12%1DH%C8yh%C3B%00L%8D.%60%04%C7%C0%B0F%00%A2D%FD%AB%22%C0A%81%CB%1E%1A%82%FA3%CB%07%E8%0E%11%D9%7D%8D%91%12%B5%0B%8DU%084pmy%CD%94%92%0D%C9%18%3C%C0%0D5%10%3F%0B%26%2B!%C2%F4%1A%01%A15D4(%C0%FD%F5%BD%86%11W%9D%23%93%3C%CF%F3%82%93BX%A8%A9%A0%01%82%02%AE%B9%B38%81%B4%06%FD%22!B%B0%0A%A2%C7%A8Z%15%06%BD%B2%1D%FF%7C%DD%BD%96%1F~%F5%25%D8I%11%98y%20%0F0%9A%90%91%80-*%08P%20w%BF%A0%A3%E1%86U%EC%A0%DF-%0F%A0%90H_N%C9CK!%DD9%F0%CAe%22%E0%87%60J%F6%85%80G%19%2C%20%02%D1%1FS%9CH%80%03%AE%FD1%96%10D%D8%97%C7%7C%B3%B0%B3%06%09'h%A2%C2%2F%93%1CQ%C0%1AJ%D1%07%C2%25%3BpS%83%0B*L%A1%02%02!*qB%03%D2%D4%13%C6%1B'T%23%1A%11meiKQ2%FC4Ex%E2h4%99tZ%B0%A1%03%03k%A18%13%7D%16p%A9%89Xl4%E7%10a%0C%CC%01%60%02%06%B1S%83%16%B4%95X%1B%9F%7D%240%D3n-%80%C4H%84M%16%89h%90%D2d)RZ%12%3EV%DA%40%1B%0C%14%02b%071R%96Z%DC%DC%00%02%01%0B40!%0D%8A%86%85%A8S%F4%8D%AA%00%974%E5%17%8B%3Fh2%F8F%89%03%F4%FA%9D%04%17%B8%03%60%B1H%F9%40%84%FFa%FA%01%05W%08-%DA%00%2B7%B3%B4%E1F%11%60%1E%B3%89AH%A5%F6F%60%C6%DD%11%CD%3B%0D%A4%0Bf%85%3EN%EAa1%EFl%80%ADI%16p%10%0B%09%9D%25q%ADc%02%A8%DB%AAS%60%91%C1)%06R%AD%B2B%99%5C%C6%03%E5!%E7%A0%D3%9Ec%EA%CAz%5C%0D%95%C4%20%C8%819%1C)O%22.p%92It%FC%BA%17q%BA*%3Ct%C2%1A%D5%E4U%0D%AC%1D_y%ED%05%D14%16%08%11%3C%D6%8C%00%C4%EA.%DB%84W%1D-b%80Ic%C8%02C%03%7D%C0%91B%02%DC%11%C7%E3%C8%DD%3ED%9EI%D1%E1i%0B%BD%25%7D%24%14%AB%EF%EDx!%7C7%8F%5C%B2%1CY%BA%A2%89A%16c%C5%A5%1F%11!%EA%1A%03%5B'%5D%CB%C8%F2%A8%85%89%7D%BB%C2%20K%18%13%40%14%A1p%3C%16%C06%01%5B%DB%1C%F1%1AJ%FE%FD%D1%09%99Vc%C8%1B~%B4%D6%B7%2F*%14%18%1F%7CL%EFP%22MK%1AF%8D%FF(ji%81%40%DF%F0%D5%CCZ%E0n%3B%D0u%C9D%0C%14%12%10%5C%82%1D%C2%02%F1%D5%5Cs%DBI'%BDt%D7x%A6q%04%60h%B3%F6y%E8%B2%138y%DB%B2%AB%AB%9F8%85%DE%22%87%06%EF%01%3F%3B%ED%A4%DB%DC%17%BE%0A%84%F8H%15%ED%C9%FE%3C%F4%17%C6%CE%A3!'%A80Fi%40%0E%A7%FD%F0%DC%A7%98%A2%E93%DB%C0%C6%1A%8F(%0Dz%FA%F4%3F%C0%04%E0_%D9%20D%10%A1%D3O%3Fq%E0s%C6%3Bb%60%98.p%CF%05%B6%A3%DF%CD%F6%C2%8FX%AC%25%16%06%AC%1D%F1%E6G%BB~%00%C3%19%E5p%8A%00%3E%80%BE%02%18%C0%83%C0%E3%5E%11%82%A3%89%7DP%C0~%A0%F8H%00%B6%F6%C1%DAu%B0%3BaP%82%3BxQ%8B%B3Q%80J%06%B9P%0B%B5%B7%B5%E3%05cB'L%85P(B%81%0C(%A0%3B-t%5E%DBh%B0%24%064%C083%E1%87%10%CB%F1%0E%10%DA%8E%82%F1%A9E%3DxS%06'x%92C%8A%E5%90%E2%15%B7%D7%9D6%D4%C0%01%B2%B2%D6*%F0%F3%0C~%B81%15%3C%94%5Cw%60%80%20%1B%98%B1%06%1A(%0D%18%CB%01G%0A%B6-%1A%D4%1A%C1%A2.%16%BE%8ALq%1F%F3Kb%8A%EAa%9F%EC%7C%C9C%2C%F0%22%0D%17%B0%C7%03%80%10%81%92%ABE%B5%843%96E!%C5b6%F9b%0D%F5qC%2Bv%E7%00%E9%E2L%90%60d%04%24%8D%A5%0D%7B%E4%07%11'%10%01%00%3B";
var Xg1 = "data:image/gif,GIF89a%2F%00%3F%00%B3%00%00x%AA%3E%F9%F8%C9%94%CFK%D9%E6%C8Is%1D6Z%11%9F%A7%8A%60%863%16.%06%BF%CD%A8%89%60%1Bfo%AA%7C%84b-D%105%3ClR%604!%F9%04%00%00%00%00%00%2C%00%00%00%00%2F%00%3F%00%00%04%FFPI9F%08%CC%06k%A6W%CD%C3%18%86e%26Y%B5UCb0%DE%C3%0E%C6u6%D3%A30L%92%5C%AB%84%25%F1%B0%B16%24%18(%F4%5B%D14%06%9FP%B5%09%F8%9C%1CY%25%B3%1A%F1%24%A5%20%23%D4c%3C%1E%B5j%EB2Ro%1E%0E%5BC%95%2Ci%A8%8CC%01%40h%1C%08gBl%0C%17%0Bi3%0DsV%08C(a%2B%5D%0D%00%93%05%07%93%00%05%22%16%0B%84%03%0D%0E%15%82%9E%0D%19%06%0DB5%23-w-%0F%04%97%B0%972%01g%1B%89%15%0E%3F%06%08%0D%8C%A6%255%03%0FD4%0E)%0C%B1%B1%07s%03%99-%BDQ%08%3F%0C%08%05%08%22!%03%5C-%80%C3%1Ay%C9%B02%09%BC%DA%BC%0F%CB5%D6%89%08%D5%0D%01%2Fl%7Fh%2F%CB%96%93%96%AF%94%84%0C%05%0D%06%0F%D8U%EB%C1%CB_%AF%3E5H%60%00%A0'%0A%BA%7B%94zY%D2C(%11%01%5E%0D%D6%CDs%D7%AB%80G%04%09%FF%851D%87%02%22%AC%89%7D2d%F4W%B0%9A%1E%8E%1D%09%F4)be%0FE%0C%95%18bZVi%D9%B8%95%EDx!%90%B9.cA%02%1E%1B%2C%D0%26%E9%E6%86%03.1%06%CC%E6%A9%80L%81%0Dd%22%C5X%ADO%D6%5E%092%1E8p%26%8AC%11Jx%A8%08k%D5%DF%C7JH%2F%F6%1A*w%EB%83%B6%01%85%3A%B0c%E5%13%8F1%242%12%DD*S%8F%CC%A0I%ABYC%F0gn%08%AF%3Fh%DC%FDz%C0A%A2%B6D%ADj%D5%DA%CE%EA%C1DY%E7%11%18K%14%CD%5D%01%02%00%A4%C6%D4%15s%D7%3FZ%AD%11%EDu9%ABV%D8%A3%2F%1E%40%CD%FB%D2E%C5%9E%BB%C6%5Efq%5DA%DB%B0%FFlT%DD%5BV%88%80g%EE%BA%3AL%40%C0%E8v%97y!%0D%1D%82tc%E6%BC%F5d%E2q%08%C5%19%7D%BBQ%03%A0%1D%B3%A8%F6%D1d%11%80%9F%14%3D%0D%90%FB%06%C82%40%3D%96%3F%BB%B8%D6%D8%04%D7%FF%03%ED%A47%DA%19%5C%DC%A7%A0%15f%B4%25%DFz%B4%B9uQu%17e%D2Y%5C%DD%24%B8%A0%82%DA%044V%01%02%B0d%94U%0F6%E6%D1XzH%12%C8%86%2C%12%F1%00C%08%84%88%5DF%2B%5D%02%D5%1E%93%A46%16%1A%2C%F6H%84%25%7B%B0%E3Qf%BEeb%23Cc%F5%A8%A4%02%1F%CA%98%95GC%DA%A8%C7%3D)%8A%A0d%8F%F9%01%E0JGm%7D%24%25%8E%E24q%E5%82Dh%89%DDl%A9%95%88TN%E2h0%A6%82D%D0%D6N%5CCQ%C2%D35H%5D%92%C9%9B%2C%DE%15%94%3BV%F1%E6N%8E%EBU%92%C90%7Cr%F8%40%9A%D8Y%93%9E%001%CE%C7PV%7C%88%99%A8%15%8BZ%C7%CB%8E9%09%D0%40o%EA%AD%A7%DA%01%F6%5Dj%06suN%E2%07Q%EA%05%AA%E3D%07%5C%0A%C4%18%A8%F9%01%E6%1E!%EE%86%E4h%7C%F4%A7e%A9o%02%84%CEh%D6M%12%97%00%E91%87%0Ffc%F5%90h%FF%9CI%A1F%94%7C%BCU%BB%EC%2B%CA%E9%E7%A6%92((%40%A0a!N%05js%80(%A3%A5%02%96nh%1Et%5D%3D%87B%22zT%3BS2%D6%B8B*%96dEG%E9z%08dp%06)%E8%2C%BB%AF%8D%F0%F1%A0C%0F'%C0p%06l%DA%8DD%8D%B02%10h%11%1F%60%E2%23%09%C1%F9Fw%E8C%17%05%FC%CF%00%BC%00%E6%22%92%C6%CAdc%C5%BC%E2C%96%AD%7D%5C%F7%22%00%D7%8C%81%80%03%20%11%A8%8F%8D%8A%E5S%B12S%19iU%40%99%10%A7%F05%961p3%3E%2F%F6%F1!D%C9%F5%23VO%86JL%CA'8x%0B%92'%E1PR%F1%90%83%F9alcwY%03F%40%12P%83.9T%C2%82%2C%98%D8%EAy%10%3E%98%24b%A6%B7.%80%20%C10%3Ex%DD%F2%D1l%A6%3Ci%D0%B0X%88%24%18B%E8%B0C%0B%09%1C%89%14DV%E1%93r%8AG%97%8C4%1A-(%81w%E2%CA%98%04%E6%FFX%A0e%E2%D1I'%E3%80%B0%C2%19%F8p%12n%0CU%92Zu%3AY%92Z%E3%A9%A3%F7o%01%3E%C0%90%8D%E9%8EK8%1A%8D6%2B%7B%F2%CD9%7D%C8D%B7%A4%AC%A2%B2Uc%AD%C7.%81%AE%F2%84%92o%AB%06%22D%B7%87W%B0%AB%DF%A3%D9%F4%C7%18%AAIn%B2%94%7F%D0.%85%E1)%24%90%5BF%99%AB%2C%5Es0%1A%E98YR%8Cq7%0D%EE0%E6%16%2C%DF%93V%5D%B5%CB%D4%D9Sn%3D%A8%DD%0B%A6%F7%AF%3F%F4%8AM%A4%F9%1Fcz%B38%5E%E9%06l%AB0%C1%10%3Ea%12%E2%9C%A40%C7%B2%8EW%08%D6%8Dk%CC%60%06(p%C0%02t%B2%AC%9D%A9%ECb%9FK%9E%D6%A0%82%14o%84%C2%0C4%13%E1%02%16%87%8Fk%84%23%7B(%BA%A1%60%F0A%9EO8%E0%87%0B%10a~%A6%04!%AF%1D%A91%AF3%D7%A4xU%80%05%04Q%86Ntb%09%F4%94%40%CD%B0%0EE%AFx%DD%FF%FA%C6%18%B2%208%11%88%0B%F0%C6%050%F7%3E%A8%D4%88%0F%87%E1O%EA%D0G)%AD%60b%04S%B0B%EDF%10%01%00%3B";
var Xg4 = "data:image/gif,GIF89a%2F%00%3F%00%B3%00%00%F1%F5%D3%E7%98Z%8EP%0E%FA%EB%8D%3F!%0B%B6%8BQ%9D%A0x%D2%DF%BF%E7%BB_JT%83%8EyD%99%A0%E7%C9j%14rZ0%B9%BF%9Eov%BA!%F9%04%00%00%00%00%00%2C%00%00%00%00%2F%00%3F%00%00%04%FFp%18%A3*%ADV%CD%8CkQ%85%11~%88%81%0Ch%AAJ%A0%88Q%8D%F6*%F1L%15%DF-%2B%E7%9A%82-YcB!%3A%1C%86%A3%82%D0%18%C6%8A2%5C%CE%E4%03~%5E%C9%A3%E3%C0%EDj%89%3B%DD%C8%A5%E9%A1d%97%EC%B6%CBn%7B'%CE4%D03%E9%01'%C76%60%CF%EF%1F%00l%0Eh%19W%1E%16!%1A%06l~%7F%80%7C%07H%5B%7BoI%83%2F%1F%05CI%5D%80%7F%8D%93%5C%06MM%04%0E%8E%9DZh5s%14y%5C%7D%A8%174%02%0A%02%0C%0C%0D%A6%B0%5CG%1BO%87%15%AF~%0D%09%A3%02%C7%B7%C7%B6%B4%0D%BCy%93%B1%1B%1D%0A%8E%C2K%0D%B7%C9%B4%CB%CB%0C%04%0F%0B%09%E2%04%E2%0A%09%1A%BC%D2%18%D0%7B%0B%04%08%05%CA%DB%C81%CB%0D%E0%E2%0F%09%04%FC%E2%E3%5Dph%C0r%C0%04%01%82%06%CAj-S%C8%C0V%B3G%E9%16%3C%D0%97%A0%13%A4%23%09%8E%2CpP%CC%20%82Z%08%FF%132%A8%D5p%24%ADH%00%264%92(%0E%E2%1E%7F%E3%02xD%90pa%B2%0A%B6%08%80%F8%20%A0%C9%16%03%E0%C8%AD%E9%A2o%22%81%023i*%E4Fk%24%81%9E%B6%02%04X%A6S%01Gp%14a2%F9%40%40%A6L%83%F1%14%8C4%26%80%DF%BB%06R%03%94%2C%8B%C1A%D6%AC%09%0A%A4%05%A2%D3%E3%D3%06f%F1%06%C0%DB%E0%A3%DC%A9%D9%CAf2%00hB%82%07%13%1EH%ADu%14%AF%00%B08%CC%9A%3D%C8d%80%00%B9%24%93%F1%0BP%0A%16%9F%00%05%9E%5E%BE%E6Q%01%E7%C9%04D%C4%98*%D5V%E0%86RDh%894%F5i%D5%BA%F0%22%F3%C3%FB%EE%04%CD%9E%8E%B5!K%2B%15%93%87%BD%F5%96%3CF%A0%16%C1d%03G%CB%22%2C%19O%DE-%E2%D8%8B%13%07%DE%00%E9G%E8%FC%80%2BW%88%16%BB%DC%BF%D9%D3%A2%07%0DO%A1%07%B3%0E%0EJ1Oc%D4(%1C%E9%F3%17%97%97%17avQOH%02%00%FF%12M%80%20%15l%FA1%80%DD%12G%C9G%5C%26V%C12%00%1F%82%D4%D0%DD1%FAa%C7%1BN%0Fv%F7%09%00%13%EE%02aq%E5eH%A2N%990p%DE%10%8D%84%C8G%88%13%1E%40%83%14%F1%98(%CFe%99%D8%93%CB%1E.%BA%B8K%05*%C6%B3%5Eu%CAd%D3Pc%AE%0D%C1%A3g%13%C2%B8%87%03%DD%15%B7%5E%91F%26%83T%3C%0DQ%E3%23%88%12%C2%12ezU%BE%C6%0FN%0D%11%B6%A4%8F%5Br)JzX%26sdx%3C%84%D6%13%02%5CvYg%9D%03%1CP%E2%83%E1%95%D5%A7%9F1%DC%F5a%9AK%F61%C0%9E%C4yc%D6%8D%C70%07%1C%A1N%1A%CAGy%F8%11%C7%98m%FC%5D%26(%97%91%F6(%E9%9E%EB%A9%17%8Fh%FC%C8%C5%17%9D%9E%A5z'%94%26%AA'%D9%AB1H%DA%E5%96%1F%80%C9%A6%9F%AF2Q%E8%99%B3%02P%01%9B%26Vw%97%92%2F29%D0%97l%86%9A%DD_%C1%DC%E9l%FF%9Dz%22%DA%AA~%99%14%80%E6%AE%3C%D2%60%E0%B4%AD%0E%06)%972%C6%A0%A0v%A0%E5G%23%0E*%9A%F7%04%A1%03j%BB%60!%E7a%A7%60%01A*%FBA%801%12%D8%84%B2%D5x%E2%40%A5%A2%8E%DA%D5%B28%D9W%60~%1F6r%40~k%09%C0mu%CA%06PM%1F%BF%9A%87%0C%5B%0F3%7CJ%23%ACfWRC%18r%CB%265%1B%03%22-%60%C2%95*%B2y~%F0%F1%40%81-%B4%A9%CDn%2Bcw%0A%3B%80%20%F1%076U%22C%C0%B85%07p%C0%02%9E%E0%CC%87%01%AE%85yLW%00s%FB%A4%C2%9D8%E2%40%D2a%DE%A2%13%80%D3J%A1%EA%23%82T%7D%23%3A%82%B4%DA%C1.%8FL%22%8AX%20%ABX%B0%22%5Clk%DE%15I(Bv%D9o%CC%B6H%D4n%17W%C1P%5BO%5C%B6gP%1F%DD%C4-W%E8%D2%F2%D6D%B7%1C8%D4%0A%23a%C09%86%17%DD%F7%93%25O%2C%B9%AA%9F0.L%1F%DF%89%F7%5D%F4%2B%97%07%3E9%E07%83n9%E9%93%ACq%F3%E8%A0l%FE%E1%E1%9F%EB%01%40%04%00%3B";
var Xg2 = "data:image/gif,GIF89a%2F%00%3F%00%B3%00%00%FE%FE%FE%23%3E%10%9D%A2%A3%FD%F8%C2%D6%DF%B0%CD%D2%D7%D7%DB%E3%3Ei%11%B0%B3%B9%8A%8F%8CX%5DY%E5%E9%ED%B8%C0%99%BF%C3%C9%E5%EE%D3szs!%F9%04%00%00%00%00%00%2C%00%00%00%00%2F%00%3F%00%00%04%FF%F0%C8%13%AA%0C%13'%C0%81r%5D(%8Ed%86a%13Um%5C%11%14d%2C%03We%A5(%0B%08%01%D3-%82%C5Lf%BA%14)B%DAA%F7H(%0C%C9a%A8F%AD%06%0C%80%82D!4%24%0A%0A%81tdEQ2%20%C1E%9C%40%14%9C%D11%C0%96%CA%D4%15%CA%09%E2%E1%15%3C%F0r%1Ct8*F%01%0Fv%2F%40%0F%02%0A%0D%81%00%0F%888%83T%09%13%7F%0B%0B%7B%7B0%81%97f%85G7%14%08%9A%0D%09%09%8C%90%A4Gug%07%88%05%9A%5EN%01%08%9Ft%16%AD%86fP%9A%02%7B%0A%0F%81%93('%A1f7%C4%B4%0D%05%8C%5Cr%B1%B0E%15%0A%CA%18%A6%B4%06%B5%0Fq3%12%0F%A15%8E%CF%C8%87%9A%E9%0D%06%02pr%93F%26A%0D%08%D76%08P%BF%EB%08%8D%815%AD%01%B8%BC%F1c%E3%09%B7_%05%F6y%7Bw%E6D%06%01%DC%F6%F0%A0%10dA%01%7Dn%F6%3C%1A%C3%2BC%03Mo%FF%10%D8h%82%EF%E26%04%09%C4p%ECx%E0%C9%02%03%09%EB)%90%F9%E0%E2An%0D%FC%C8%A9%94!%C1%CB%97%A8%04%5C%94%E8%86%5B%81%8B%09%89%8D%11g%A3i%00%88%10%8F%B6%B18%B0%E8M%03%0D%94J%91%A4%E0%DA5I_%5E%C2l%B0%0E%E6%A6%07%08%CA%3A%C1g%A0I%B4%19b%1C%A4j%E7%20%EB%D1%83%1F%C5%0EE%80%2F%AB%93%8F%22%D1%0E%09%E3%A0%B0%03%02%87%7D%E2%FBi%F1*%BDg%09%82rK%A95%86%9F%26%AA%1E0%40k%60q%BE%C66%B1%D6%23%9Bsl%A3o%22%140%20%C0%60%F5%00%02%DE%C4%DE%0C%3D%B9%09%DA%B4lQ)%F0%14c%F30F%0C%DA%CC%A2j%F1%8FO(%0D%BA%06%7C%40%F6%CBQ%3F%3AH8%18p%98%BA%9F%C67%DB%25o%E7'-%D7%20%FC%16%D0%DB3%C3%B0a%E6%DBp%CE%7C%13%B0%02sz%92%B0%AEK%A8%AA%BC%F9g%B4%C5%87%C9%D9%F5%0F*%DC%8D%945T%FF%7D2%98%B7%03Dfe5LZ%0B8%91%09%3F%05%08%D0NIF5Q%DE%02%048S%13%5E%8C%A8RTf%3E%DD%85%9BUdI%12D%0C%0E%3CsM%10w%05%C3M0%FCt%25%E30)%F1%E3%CCE%1A%AA%06%82ta%5C%87%14%3D%07%F9A%A3%1B%87%B1%F6%07%23%19%B5AOW%3E%90%D0%0E%10%02%16%E0%C6%3A%9710%C0%95Xb%E9%5B%020EF%96%8C%04%90%C0%07%3F%B3%D9%D4H%02%04d%A9%E6%95%048%81%60L%8C%B4%89%1A%97%ED%5C%15%91%02h%AE%A9g%9B%1Dz%99%C0!%0C%14%B0c%07%10%E54%DCMM%A4%A9%E7%9EM%00IO%23%AA%250(%00%A6D%F8%CBA%F5X%B9%E8%A2%0C%A8%26%803%7C5%D2Z%93Y%7C%84J%3E%07%A92%DD%A6%8B2%E2b%84%999%C0%C0%23%0DB%81R%3AG-%A0%19%AB%9Bn%26%DB%1E%AA%10%00%1B%03%B5%C2%A4%0DV%82%AA%C6%2B%A7%5Cp%A8%CA%FFj%AC%ED%91N%17Xi%A2%C0%B2%9B~%F0%92T%8D%08%BBY%7C%D3%8E%B5%80%03%D7b%AB%A7%B68%A5t%00%B4%0C%04%C0ez%DC%BC%A4%80%A2%E6bI%C0n%DB%8Aw%99%B0%7F%F2%A1%D7l%CA%D6%AB%E5n%07%1D%C5%CF%01%02%B4%2B%01%AA%B4%B5%25%80%C0X%AA%82%23%14p%0Es%02%C3W%A9%02%F1%95%92%E4%0A%13N%F5%DC%60%D4%5D%05w%AAi%BDjD%F51L%09M%B4%F0UwI%D9%15%BD%CB%F2Y%94M%5D%7D*%CE%04%CE%18%15%AFhg%D2%BC%A9%03%7F%F0e%D4%22%0E*%90Ah%B3%7C%9C%10%3B%89%F2J%40%23B%B1%C5M%A3%7F%86%C22RN%24%B4%CE%22%9A%09%AD%E5%1F%81v%C5%25L%12B%83%C3x%25%FE%F6%E7%BB%C1%D1%E8%1AkBj%06F%1BaXDO*%7F%A6pd%8C%7C%05%E4%87I%60%0C3%A3%DC%B3%98%D8%9F%B1%25%8Ad%C60B%CD%84%CA-%C9%DD%84g%3B%05%10p%F4%97K%7Btf%F8%C49%A9%7B%82%B0S%7B%A3%9Bw%95%B6%95%0A%1F%2BK%F8F%88%5C%B1%C5yZ%3C%04%E4-%C1%BA%D5%C4H%3E%26~%91%AA%8C%1BF(%89g%8C%F3%C7%C0%01%C3%D2%92JZN%40%F1%87%8C%C7u'L%3E%7Bp%06RR%B6M%EDk%3A(%C5%D4%23s%B6%F0%91%15i%92%A8%A3JEF9%F1%15%03DW%04%94Pd%F1%B0%DB%97%01%E1F%95%60%9C%DB%F6%13L%B7%0D%D3ZM%E9%18%0B%5E%CA%C1%88%23%7D%CD%00u%F1%C6%C7P%A1%8Am%B1%8C%1Fd%8B%00%00%3B";
var Xg3 = "data:image/gif,GIF89a%2F%00%3F%00%B3%00%00%FD%ED%8B%FD%F9%C2%E4%D6%7F%A8%9BW%F4%E7%9DS%3D%12%C9%B3_xe-%F1%E1%83%CC%DA%AF%A9%AE%7F%DC%C8p%B6%C5%9C%E0%ED%CF%8F%83I%C5%C0%85!%F9%04%00%00%00%00%00%2C%00%00%00%00%2F%00%3F%00%00%04%FF%B0%B1F%93M%8C%BD%E1%FA8%07%93Pd%83)%0E%CA%7D%DD%E1%1C%DF%A1%1CRP%DE%26%A3(%838%8E7K%26%93%F28%06%ACO%C3%05%C4%05%2F%D0f%053%CC%CCV%83%99m%D7P4%BF%89%DDQ%E3%B5%3C%2C%26%92%90*F%CD%12%01%5BW%A7%A8%3C%18%03%82%80%80%40%00%04%02%00%08%02Y%0AC%86%88%3B%18P%192pq%01a%3B%0B%0B%00%96~%96%99%9A%99%02%08%0B%04%0F%80%0F%1B)R%5D%0E%3A%22%A1%7C%9B%AD%AE%9B%98%96z%3Ca%3A%25%09%0F%04%99%B1%AF%BA%AE%BC%9B%01%3B%1Cu%24%0C%82%AF%BB%C9%C8%9A%C0%08%04%03%15%12%0A%C0%CB%9A%9D%BE%D6%9A%0B)u%0F%06%DA%AF%06%06%9D%E1%99%04%5E%0D%04%AC%D5%C9%BA%04%0B%7B%EB%F3%E1%0B%18%E6%00%F3%FA%FB%FC%D6%08(%EDd%F1%1BHP%19%2CK%0F%1C%1C%CC%F7%8E%A0%C3u%98%0C%0C%08%E4%8A%D2%9Fj%0F3%0A%0A%00%00I%C0A%D0%FF%02%F1%12%60%60%C1%B3%8C%EBz%25C%40%CE%405%03%A3%1E%F6%E9%23(%E0%2B%04%03%FE%B4Z%A0%40%1E%C1%04z%F8%CC%B4%D9%0C%40%00%8A%CCj~%9A'o%03%88%A7.%1C%18%E0%D3%89W%ACX%84z%3D%93'%20%A1%0BC%C6P%B8xP%93%A8%25%A4%CDf%EE%110%23%05%A4%B76%BCN%BCH3)%A6jC%B1%7D%18%F0%08.%24%13%7B%FB%88%1CJ%B8%DDP%02%06%3A4%F0%CB%B8A%07j%85%23%AF%EC%F3b1%E3%C6%1D%3Ai%8E%5Cn%D9%83%10%97C%7FVPv%90%E9%AAu%05%98%DC%C4!th%C7%A4%FDD%9Ey%B6C%A5%5Dn%5D_%06xi%F6%5Dr%AD%0E%3C%D0%7D9%C1%81%DE%85%AB%22%C3%F4.%1F%0D%E2%8C%09%1C%F0%A5%D6%B4%E9M)%E7%1D%80%DE%F88r%C9%07%B5%F7%E5%1EG%FA%D5%D9*%A5%8F'%CF%C0%7BRm4)%2B%20%FF%16%85.%C3%BF%04%0F%FA%40%1F%D2%11%7C%DF%F5%01%0A%FFh%F4%CD%90%CB%25%00%9ED%40%02%1D%AC%E7%1A%83%D3%01%88%1D%20%03F%E3%1A%01q0X%40%01%F3%F9%E3%0Ab%DF%00r%C5p%AE%25T%00%08%05%F8%91%0D%2C%B7%ED%E2%C9%00%E3%98%04%0D%0C%0FX%E6%D7%0CP%15%A0%D0%8A%08%EA%04%0B%3C%A8%F5%C1%C0%0B4%C2%01%CA%07'B%E5%40%01-%86%23%5Ba%82H%E7%C2%01I%26%09U%8EdI(%CED%25%09%B0!THZY%00ZZnB%C9%02%25%19%20%E6%86%2F%B4%09NQeZ%82%26%95%0E%A0%F9%A5%0B0%C6(%91%8F%AD%98%B5%93%9A%1B%26%96g%8C%03l8'%12%9D%5D%E3%A4j%12%15j%A8T%0B%7C%C9%CD%860%9E%88%E8%2F%DA%90D%24%8A%05HT%D2%97%E3%B0%F9%02%12%03%B4C%A6%2B%24%C1%04%A3%A3%E3%1CA%E7%11c%B2T%89Mu%F2%08%CB%20%F1%C4%23%C0%A80H%14%15%0Ch%D9j%C9%01%06%04%40%94leI%A4Z%3E%0B%20%01%A6%AEA%ADdv%9BM%C8%D6%D4%23bW%3E%40T%07%0E%24%1Ag%3EH%BCpb%B7%C9pK%AE%9F7%5D%23%AE%8E%09%BC%C2-%0C%C2j%E9%C7%1D_%8E%89Z%26%ED%81%F0%C2%A9%D0%F6%B6%89f%9F%200V%AF%25%C5%A2C%9B%2F%AC%D6gi%7D%E4%1A%CF%5E%0B%84%E8%8B%B0%18l%FA%C1%B4%B2%08%06%08%25%84%8C%E31%8C%B4i%23%02%8E%FA%8Er%09%20%8Cz%5C%92%AEfM%9CO%269%EC%40e%92H%8C3%A8%AE%F7%F6%CBPC%FB%00P%C1%C1K%CA%B0lYp%F6%82%D2%3Aj%E8%E0lN%3D%E2%F3%10P%FA%DC%A2%C83%DF%3A%F4M.%10E%00%00%3B";
var Bulldozer1 = "data:image/gif;base64,R0lGODlhMgAuAMQfAPPcGgUEA2peDIp1Dv%2F%2F%2F7KcFdW8GI2amGqfzk10lY6EVeXki1xdXvDgTMfHyFQ0CH%2FA8ffxvefn45i704GFgvr44LWtWLm1oNra28nf9e3t8Dw8O%2Fr59wtjvqTBogAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2BQQFZAAfACwAAAAAMgAuAAAF%2FyAhjmRpnmiqrmzrvnAsz3Rt33hecvrMLY1gYxHh9VgSgwGwBDgBxKPqQLEomU9nI1KR7hJgxMF6zTa6rugLA26Lrc%2FhYvFSFBZoVAaRIUwYbW4eAEMZEBATLxcPAwARKQgdiQeBgQhzh4eJLhUbDwIGZyeRiRSVgR4emYgwCg%2BvA1smB5ILBQqnCQgeExAIvxAwDq%2BvoKIjtBRPBriWE8C%2FBzAaAg%2BesI4iCwwdCllMzboHvggUFAYLRi0MxMTGCwYF599OzAlj5gVKS48uFp%2FXiOn71qRJHCb79vVroUCAQ08BBxisRy9LQiV5WFgY4LBdwIEVCS27aECdCg4YCv8M4NiR2LVGZkTWI2lgAAUJLSwU2LmyY0BPAujVfKBvX4FqAZIGuHlyp9OePtvBXPaqAJOjSrMmlYbCVjyeUD9ZsyYApBJYSLWq1XCCg9OvYB1Wk7qk6Cu1eJNeOOEV7lOWcz9JtArgQd6s1jYkxWCCg1GjTlXKnTuAsOHDAwwrOMAgwAaTI8jA9bsSsMOzhwME%2FUThgOK9JzTsTKgvskrTKg8Tq9xaMQMVKZXUjge3tNzcWjMzMteagm%2B2wIsK9wt2ZU21AxQwN9c5wO8WF4oOr%2F1X4gClhgVYMEel%2BwYHMMLTpv5WgNKd69srpQCaBQf5xIkXGWqebcZdUhscgNNkDBroNB95RWXFAAOKJcXfDQ2KFyBxAKyn1gYUMNafDBg4uCFIEmBwgFIbXMDBiDUE99gVdLwogQOMeSGCA9JxCEBGOpbA40VQBJnCf9I5AaORBCDZxEJMxgZHA1GuoAEGRRwRAgAh%2BQQFCgAfACwEAAsAGAAjAAAF%2F%2BD3WU0knmiqfpdQLNUqo9r3DIA5Z5xKKDZXIzZbXU43g66IkmyQQiLz07M9bQPDYipSCD5f0UMI4H4fnyvWwD0JBGixq1gpfAZg8Ca%2BXhGOdnh5YXIrHHYqcGFoYypbKIgiilcubCIcFpYiiHiLcDcoj2yagZJhYWwVBpofpHdukgVsEYiWsimCpiIGVSert5siuR%2BRGK3BBsDBgsMfDr4ynK%2BRzimjx8Eyva2y3ZDEhirJq6wfAHwnGpm7t9QnASsSMqOrAO4oxpaj3ZZHMw7AxmFrUKPIMxTJzH2Q0maXiAUEuHDwd6IMQyYFRZSB2PCDOoUNInb8IOHIkJE0OASIRBECACH5BAUKAB8ALAQACgAaACQAAAX%2F4PdFSyWeaKqezmBEa7xqn1A0pqwT1Pe4C46MILuIHrYGTLeSCE5IA46Z4jyfvkfhRT0RFDXkUSDtogTiJ9JlPgnQKGSByhkMzlefgC1bfOZ3alhjBjEcFiKAIlhvYzFLiR93NW5hfCeHHwaFiZNhg54nC3MinKSTb2lbiRqbppx%2FkpU1pAAfDSibq5GBlLkfF7Clu7GoKQEfNCcGc5ymIqEFyCIOv5rXJ4qRbc%2BywlTMsHOkMbDm2LEAgygaFt%2Bvyx%2FT4H%2BbmpsA5CocGejo5OtWVCv3AUCDgW3Q2YoghEnDFJwaEOnCwUgKWznMKDtha8HENhKu2ZKY8AQGbJBKDX44WeKjyg8cCLhMEQIAIfkEBQoAHwAsAwAJABsAJQAABf%2FgJ37VaJ5oyhVNmb6qIhiLC9%2Fc8QiDEd1Ah0ggYP2AKQnxs%2BvVkCfOUMAsAo7QD0ExWj4GrAoi%2B6EKHuVqz5KgIC3D8u68NCA5ikGXmi73PgB2ACgRBQUDel07TDsFgHYocCOJZmVEjS8VjiKOiX19MykWBqScH4hxJkUoC6UFkCKoaUtFsCSlH7aGp4p8I3aSv7kjnV0pFbYiBq%2FEp54oHAspdrCdz8sjGCfJxNbPIlI3uB%2FFKijUKI6bKRrD0%2B7kN%2B3n28pMLxgXMOgGgTfa9HKt84VPHKAPDICECzhIWkIcH4KZGNSAAAEo81AMwoIR3sEFF8l8kCBiEEUbIrUYFRj0gaNIKfpahhQ5goMEDBxm0jShM0UIACH5BAUKAB8ALAMACQAbACQAAAX%2F4Cd%2By8KNaKqmxDEY0SqvxPUIRRPPPCEJN4GhUeHNOALgR%2FBaGGmMJTCZ2z1FBIXgE7wNcsXrx7LdLqUFgyVxtYySZy7OYHgqPoN3ivmpzyQFeHkicEpUHwB9KRxOH4GDhGdTeYmLgY4iA5BmSzeXKQ19fo%2BQnWZpKRGXqJh4kWV4fokcfoqjpCqlHKEqtZmDnH2BC74otbgjeXUFVil1x7%2BuIoE1iDJ008jSRn7FI95ulSvHgd4aY9cio60rF0%2B1BgDBIxIj4t%2FfzwFi6ewy7jPqJNrHw4GIeygSueG3IhERDE%2FOHVwR44SYhYkAJDKB5Uq9hB%2BIMBQBceKHCARGE36w6GdBSpUoFqCEiUIDh5cyQgAAIfkEBQoAHwAsAwAIABsAJQAABf%2FgJ4rVaJ5oihVNmb6qMBiLC9%2BV8MhGxN0wjkIgErAiJwjwQ1B8iE9jAzmaLC2PYnFWW44O2me0YLAklN4TVEa2eAcDtVj2Mdw4hTjcBB3bX0gFInFyW3YAKG4ignCEWkR0KAsGfwWCH458mH8jEpQilYOOfQMFAA2IHJ91Jpd7dwspnK6ZH2Qikyh2lbSioLcws76ZBhIfiC%2Bzrig%2FIsiyI8tiHxwOQAbAlrZAz7qtrDfdoODOtR8SDm7iJ5R%2FWSgYIwbr5PQv9scf7ynN3NtLF0aIQxYQiAYUyJAt6JdGYL4GBBoac8bpQ4WIDTGkO4YsAsaGzRR9WPCxoQk3JE0LqtBQUqUIAjCBhAAAIfkEBQoAHwAsAgAIABwAJAAABf%2FgJ4rcEo1oqq7cMDTnKq%2BEIgwFPO9iLXw3Q6PCkxEsqOCCWExdVDhDhNMkXX6pWw5ZfQ5WWgum%2BnWpBIKCwVD9lMFp9kzyKaDM54F8tRDZ3V9ueXsoEWojf4KBSYcoHHJ7f2aLiIQlKXKJkyoADSJ9mIiSb1%2BNHxGEKJEjbykVcgArqyJ4fgYanrEfuqqZkimJBryyKIkfexojwrvEiDNPO2yrbA8zy8PKhMacx9FrbbHYKOIpDkgAqSuUKVQOIujhKboBTefjzLRFySLCy%2B8iDdw1wQAtlr8PQ9rQgbbLX4w23D4sIDCCCkQUEy%2BiEIjQosYRDi5EoPgRhQQNJGcChAAAIfkEBQoAHwAsAgAIABsAJAAABf%2FgJ4rEZSxjqq4qYQmFEbH0yl2fMBTNXP84kY5X%2BdEcKp2hUfwgjCLMZ5ASKBeHTwaKmnqFO0MW6qWKzLkdoEE2D9CjIflMh08HBpqvQK9X8SwWIwV8dyNwMCsLeXkihV9UbnY%2BIo0fj25nAioVliONhIeGlSKdLJ4pAzqcbB8AriqWoVOrlT4AqJ8pj44fjbivIsEpsjQaFsA0nny8IhI0w7qX0zXRsMQq1h84BtorjN7bI8Hanptk3dexAWThsOc1gt3zr%2FW9RkjJpNcMZA4F%2BqJ1gYIEYB59CwjM%2BSCFj70PDRQulMItWAMOC1UEKZVxhQkmEjumyIBRpAoOIWkChAAAIfkEBQoAHwAsAgAHABsAJQAABf%2FgJ45cNJ5oqmKDYaqw6nxD0bxxTGCiUN%2B5GO%2F0qwRTvMGAaGgYj6OBgEYVtSwIyDFJ7NUKC05wEV1avQWDAdpdmmmFmLgQt%2Fp85%2BkbRRbVz2dveyIVajFKeFQtKBYja35dgB9pI32OI3%2BKVnuWMZmSIn0AH6OOj5mDHxFrAGsGpZeYoB9kraOwJ6c1KhwLr7%2B2KY%2BTcZkSH8AjuCLDu2cYM6%2B5y8go1My3McPVIxpDrSnU2yfH4dIqow8wF8LBypNspNbyH%2BoqBCfgMVNQ59kjDTawsSAt2YcG5aA4IFgKVgUxbBxEQ4Ej3jsRFS3ygahxhIMLEfB1PIFBg8iRIggEnIwRAgAh%2BQQFCgAfACwBAAcAHAAkAAAF8OAnjl%2B1VGSqrmlxsrAqiYPxxrE0jPWNy7vdyIb6kXQfgVDwKdiMI4lyoFQmm4ZD5kf4CINT2scQga6sQbNKOGLW1F5SWlRYcVopNnOoKo9HdSsDbIEjFQYshTR7IogjHI4kkU15kiIcDSIAKZMsbJiSmysFiikcCx%2BiqZ1wIwAGm6qNdCSllrCsKgVsIhqurrCWgLwkFo2ir7KzyykOmpO5f6kBzc6ryddmvpTJuMpGGNzBY9hqF%2BSIyOQj1Cx3H%2BepnKoPcLiarfP5LK8jDQRdoGwzlqKImhkOCjWoEDCfA2MNIjTc98HBDIok3sEIAQAh%2BQQFMgAfACwCAAcAHAAkAAAFvOAnjtwXjWiqrmNzsrA6CF%2FRxPhq56wm8yvfZzCajRxAEVFAnBFRmKSIxqR9rJ%2FFQTpUVkUFXnjlVFlY43HKyI01r%2B0V7WmIK2EVXOGpA4iEAAZ%2BaDoiAHkigh91LANqKHU3hiODI4xDjygvi5ApmWF8KpUfoz%2BZEpZSmTGXMKswg6UGBa0kqYG4tUl1gr2BbUiUiqJ3UsOkQAQ4v3G%2BiSNnbX7HCxpRbccfJUJ2H5J20d0siOIiJeUiyjghACH5BAUKAB8ALAEABwAdACQAAAX%2F4CeOYkSQaKqmhrm%2BqiMMRePCOCaM9Y2rus9OVKucfqigcDQwNCoZ5AizrM4%2BBgsCguRUUTvaZ8GhSElD0bBgkA5Su1n4UwB8FC%2BL6K0eDdN2KkdMYGoDc4EoFUSEKn9YiSIEeip8figFKAQLKZl7cCNtI5tYpTwklioNH6QfAAaRKG%2BpI3YEEaVtsKKnRLQknCKvrzB8vyvDvCoFxyu7JJ6fL6LEwsqMOBcisKF215mZBg8oGhja1duu1zgSZ%2B656cnpdD96w%2BmivOP18ytpUrFIrHrXjVcDCQ4IqgBQgYMXKe3okQCAiyCVC7woPlT4AaMrMhxRXKgYkoSGHyEAACH5BAUKAB8ALAIABwAbACUAAAX%2F4CeOBDGeaJpyS1SqsMoNQ%2BOacf4p31DYL52KJxoYGpWgcGT5CARFwyJpgiwvUKfTZ4hwEJ2J8OKEmns%2FSxgXw5bPUJ8FsygIs0%2F4p2AwAGImNFp6Wnx%2FKhJFA1pljXF%2BKQR1iiJPjpVGhyMRdgV2PYuDZmaGIxwnnpSiZ58iLCmfNKGjWYeSHwa4I56xI2cnBBG6Irm7sYK%2FHwAVw83GRT0nuQUaDSN%2BucXPoIuh19%2FEuyJ2od52GmQA2uGo5NHrKNns2zIOTTDwvPAfGh%2F3uvJQhfOG4p%2BIPwHDAXiwpE88XLkInjjVTJ06gAfHfFuXC4BEGBeKYRsGwNoSDCE3KYpAsmREyIvFAAhr%2BSHRvZgLaBYcASCnzoIASlL8OcLBhZlETUnolyMEACH5BAUKAB8ALAIACAAaACUAAAX%2F4CeKRDmeaIouC2eqMHoMRlQScX49X9HYrxxKIuB9DI3KTXjiCD5G2uKGYxIYI6MPiGB%2BFJ%2BiiDfwVQ6dCfMpeEJFBYMlQQEI2%2BzxO24A2FUECmyDbyI0fX9DHwMDYW0iT0Y9fgAGTQsFhgN4eTxklCMEHAWki4yOeXoFfiQEDZk9maechT1IJBGwmbCMm3hhwH0foiqlpqjARwCiDUcnu7KznLAEC87XI6TRvo8jESKWxT3HmyN2VeDY2byLbo0EGBY50KaMmQEwluHPxo0x%2Byh2xYoDa4SGC%2FqcAYRDypKbExIQzhthYCGJDxfSJTxRcRwgjRwVfkikgsMHeZWwP3UEIC8HBwctwyUEkISJhpMUj1gC8M3LTXApR7a4KCSivp01vVy8AMtPT6UnEPqxBhUFhgsLnlYdwUGDSRghAAAh%2BQQFCgAfACwDAAkAGwAlAAAF%2F%2BAnfkQ5nmiKRktlqnDqDEZUEnH%2BacJXNK7XCaH7UB4P2oIjHGV0F%2BTD17A1ixIB8jM1AG9FEUfLlRZqpUMnrJi6kQLvgtFRhD%2Fkt4BWoHwAOQQWAoRlUg8CBQCLBjAEHAMDhD0iejSMKgQLIgN4hG9SHwaLKhwWBQUfkZNcla2LgCcEEag%2BqpKFW26XIo2PpyK1qpN5U7wiJQuptraRnj1uIwAGBQQaKKnCq7nBtgYEDSnZy9uFlKInjSfjqeWU0yPX6yPL7Z2sy8jeKqjkksyyANrK1i2Ss0wO8mHzQe5MpxQcRqhjVq8fgHMoNFiIwW5UDo3iuqFTqOIJOnEGRkBhzAQjVUoADRz4CbQv3Z8IdyIua5RyVLgPEYvolDgKQIU78Xql%2FLMJKTIJvf78dKrPQlGcVEcQwHChRVaIOkIAACH5BAUKAB8ALAQACgAaACQAAAX%2F4PcRpGieaGpaTUSosHp9xVK9MBR%2F2vMNABcuNdkpRIJC47aDXXyigUHYREk2H2hyOaxyBNkNVLroVrMCn28LOJ8eD6xJ2m4SFGATPPtJAuowFT99fGIndDAEM4N5UIZ9gCgch4R8ImoCfygECzQFc3locjQpHBYmn4OVcGk%2FBnUGnAWpBqmMelEGIrqCqAW1c4RqKG0RtiK%2FtgOrKD6TqLqpqcuVu1AfGCfSpMGh1G7TSNzgwFGqMLbp48sG3yccF8fc5aTXTZ%2B1n7O%2FuokS4%2BP6AVSRDd2HV4vcIDOhq4GGKmYWfgDQC6KDFLo6KXzGcGJFNw%2FxTdSoUERIEQ1KDFo5uEQlCg0aOKYIAQA7";
var Bulldozer0 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1wITDBAoje5u6QAAAAh0RVh0Q29tbWVudAD2zJa%2FAAAADUlEQVR42mNgYGBgAAAABQABeqhXUAAAAABJRU5ErkJggg%3D%3D";
var Xadd = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn%2FAACA6AAAdTAAAOpgAAA6lwAAF2%2BXqZnUAAABFElEQVR4nGL8%2F%2F8%2FAzJI2FiDIrDAv4URmQ8QQEwMWECj6WswxgYAAogFXeDvn38Mv%2F4ALQGa%2Bw%2FIRgcAAYRhw5%2Fff%2BDs30hsGAAIIMbQRYX%2FQf5gBEKQ42usPqEoaDnGh8IHCCCW3z9%2BM5TafIHw%2FjMyfP0FcQ6IDTKiyPQ9AywUuo7wMAAEEMuvn38YXnz8DdXwH6SOgRGkghFiIyMDItB%2B%2F%2FzNABBALL9%2B%2FGKYcYQDqoqBIdrkG8QCqKKlZ7ggHEaQ6B8GgABiRI8Hx7b4%2F2Em38FmrzrDwbC%2FaiFKPAAEEEaw%2FgE68ftvkCH%2FgE7ADCWAAMIM1j9%2F4ey%2Fv%2F%2BiSzMABBCWiPvLsOIQAwMkqDA1AAQYAACIahTU1BszAAAAAElFTkSuQmCC";
var XCancel = "data:image/gif;base64,R0lGODlhDgAOAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb//5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplmmZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///yH5BAEAABAALAAAAAAOAA4AAAhUAP8JHEiwYDFcxgoq9PVO3K+Fvgb+Sofr4UBcEQuqQyjwl0WF/zBWBDlw40eQ4xD+yqhQnS+LIwume0kwpkB16H5tKohL3EBi4iiBxDUwJcmjIAMCADs=";




 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  
 
 
  
 
 
 
 
 
 
 //alert("global variables ok");
 
 
//=================================
// Controller  (core/logic)


//General Classses definitions


/* better merging/splitting way

	var merger = '|sepA|';

	var arrayThree = new Array( "John", "Paul", "George", "Ringo" );
	var lineUp=arrayThree.join( merger );
	var members=lineUp.split( merger );

	document.write( "|"+merger+"|" + "<br><br>" );
	document.write( arrayThree + "<br>" );
	document.write( lineUp + "<br>" );
	document.write( members + "<br>" );

*/


function Village(){
	this.id = 0;
	this.name = "raw village";
	this.link = "#";
	this.coords = "(0|0)";
	this.coordX = 0;
	this.coordY = 0;
	
	this.lastUpdated=getCurrentTime();
	
	this.resProduction = new Resources();
	this.resStock = new Resources();
	this.resCapacity = new ResourcesCapacity();
	this.resFilled = new Resources();
	this.resLeft = new Resources();
	this.resFull = new ResourcesFull();
	
	
	this.getLastUpdatedAgo = function(formatString){
		var seconds = getCurrentTime()-this.lastUpdated;
		if(formatString) return formatTime(seconds);
		return seconds;
	}
	
	
	this.getCurrentStockWood = function(formatString){
		var updatedStock = this.resStock.wood + Math.floor( this.resProduction.wood * (this.getLastUpdatedAgo(false)/60/60) );
		if(formatString) return addSeparatorsNF(updatedStock,",",",",".");
		return updatedStock;
	}
	this.getCurrentStockClay = function(formatString){
		var updatedStock = this.resStock.clay + Math.floor( this.resProduction.clay * (this.getLastUpdatedAgo(false)/60/60) );
		if(formatString) return addSeparatorsNF(updatedStock,",",",",".");
		return updatedStock;
	}
	this.getCurrentStockIron = function(formatString){
		var updatedStock = this.resStock.iron + Math.floor( this.resProduction.iron * (this.getLastUpdatedAgo(false)/60/60) );
		if(formatString) return addSeparatorsNF(updatedStock,",",",",".");
		return updatedStock;
	}
	this.getCurrentStockCrop = function(formatString){
		var updatedStock = this.resStock.crop + Math.floor( this.resProduction.crop * (this.getLastUpdatedAgo(false)/60/60) );
		if(formatString) return addSeparatorsNF(updatedStock,",",",",".");
		return updatedStock;
	}
	
	
	
	this.toString = function() {
	
		var output = "Village '"+this.name+"'\ncoords "+this.coords+"\nLast updated: "+this.getLastUpdatedAgo(true)+" ago";
		output += "\n"+this.id;
		output += "\n\nProduction: "+this.resProduction;
		output += "\nCurr Stock: "+this.resStock;
		output += "\n"+this.resCapacity;
	
		return output;
	}
	
	this.storeData = function() {
	
		var persistence = this.resProduction.merge()+":"+this.resStock.merge()+":"+this.resCapacity.merge()+":"+this.lastUpdated;
	
	
		GM_setValue(this.id + '.Resources',persistence);
		return persistence;
	
	}

	this.loadData = function(){
	
 //alert("Village before parsing data:\n"+this.toString());
 
		// loads GreaseMonkey persistent data about this village
		 var rawGMValue = GM_getValue(this.id + '.Resources');
  //alert("rawGMValue:\n"+rawGMValue);
  
  
		// if it wasn't found, store raw data and move on
		// if it was found, parse the string
		if(!rawGMValue){
			this.storeData();
		}else{
			var rawData = rawGMValue.split(":");
 //alert("rawData:\n"+rawData);
		
			this.resProduction.parseRes(rawData[0]);
			this.resStock.parseRes(rawData[1]);
			this.resCapacity.parseRes(rawData[2]);
			this.lastUpdated=rawData[3];
		}
 //alert("Village after parsing data:\n"+this.toString());
		
		
		this.resFilled.wood = this.getCurrentStockWood(false) / this.resCapacity.warehouse * 100;
		this.resFilled.clay = this.getCurrentStockClay(false) / this.resCapacity.warehouse * 100;
		this.resFilled.iron = this.getCurrentStockIron(false) / this.resCapacity.warehouse * 100;
		this.resFilled.crop = this.getCurrentStockCrop(false) / this.resCapacity.granary * 100;
		
		this.resLeft.wood = this.resCapacity.warehouse - this.getCurrentStockWood(false);
		this.resLeft.clay = this.resCapacity.warehouse - this.getCurrentStockClay(false);
		this.resLeft.iron = this.resCapacity.warehouse - this.getCurrentStockIron(false);
		this.resLeft.crop = this.resCapacity.granary   - this.getCurrentStockCrop(false);
		
		
		this.resFull.wood = this.resFilled.wood > vInfo.maxcap;
		this.resFull.clay = this.resFilled.clay > vInfo.maxcap;
		this.resFull.iron = this.resFilled.iron > vInfo.maxcap;
		if(this.resProduction.crop >=0)
			this.resFull.crop = this.resFilled.crop > vInfo.maxcap;
		else
			this.resFull.crop = this.resFilled.crop < 100-vInfo.maxcap;
 //alert("resFull.crop: "+this.resFull.crop+"\n\nresProduction.crop: "+this.resProduction.crop+"   resFilled.crop: "+this.resFilled.crop);
		
		this.resFull.any = false;
		if(this.resFull.wood) this.resFull.any=true;
		if(this.resFull.clay) this.resFull.any=true;
		if(this.resFull.iron) this.resFull.any=true;
		//if(this.resFull.crop) this.resFull.any=true;

 //alert(this.toString());
 //alert("Village after parsing data:\n"+this.toString());


	}
	

}

function VillagesData(){
	this.count=0;
	this.productionFactorBase = 1000000000;
	this.maxcap=75;
	
	//deprecated
	this.vTableStatus = 1;
	
	this.totalProduction = new Resources();
	this.totalStock = new Resources();
	this.totalCapacity = new ResourcesCapacity();
	this.totalFilled = new Resources();
	this.productionFactor = new Resources();
	
	this.vList = new Village(125);
	
	
	// general data related to current page
	
	//unique ID, used to differentiate user & server accounts
	this.uniqueID = 0;
	//array with all villages ID, it is different from vInfo.vList[].id
	this.rawVillageIDs = new Array();
	//active village raw ID
	this.activeVillageID=0;
	//active village's position (index) among villages list, that's necessary in some places to relate active village with villages array
	this.activeVillageIndex=0;
	
	// default language is br
	this.serverLang="br";
	

	
	
	this.setTableStatus = function(status){
		GM_setValue(vInfo.uniqueID+"TableStatus",status);
		return status;
	}
	this.getTableStatus = function(){
		var statusRaw = GM_getValue(vInfo.uniqueID+"TableStatus");
		if(statusRaw){
			return parseInt(statusRaw);
		}else{
			this.setTableStatus(2);
			return 2;
		}
	}

	
	this.toString = function(){
	
		var output = "[VillagesData] count: "+this.count;
		output += "\nTotal Production: "+this.totalProduction;
		output += "\nTotal Stock: "+this.totalStock;
		output += "\nTotal Capacity: "+this.totalCapacity;
		
		
		for(var i=0;i<this.count;i++){
			output += "\n\n"+this.vList[i];
		}
	
	
		return output;
	}
	
	this.reloadData = function(){

		this.resetTotals();
		
  //alert("before villages loadData()");
		for(var i=0;i<this.count;i++){
			this.vList[i].loadData();
			this.sumTotals(i);
		}
  //alert("after villages loadData()");
  
		this.totalFilled.wood = this.totalStock.wood / this.totalCapacity.warehouse * 100;
		this.totalFilled.clay = this.totalStock.clay / this.totalCapacity.warehouse * 100;
		this.totalFilled.iron = this.totalStock.iron / this.totalCapacity.warehouse * 100;
		this.totalFilled.crop = this.totalStock.crop / this.totalCapacity.granary * 100;
		
		this.productionFactor.wood = 1/(this.totalProduction.wood*this.totalFilled.wood)*this.productionFactorBase;
		this.productionFactor.clay = 1/(this.totalProduction.clay*this.totalFilled.clay)*this.productionFactorBase;
		this.productionFactor.iron = 1/(this.totalProduction.iron*this.totalFilled.iron)*this.productionFactorBase;
		this.productionFactor.crop = 1/(this.totalProduction.crop*this.totalFilled.crop)*this.productionFactorBase;
	
	}
	
	this.resetTotals = function(){
		this.totalProduction.resetValues();
		this.totalStock.resetValues();
		this.totalCapacity.resetValues();
	}
	
	this.sumTotals = function(index){
	
		this.totalProduction.wood += this.vList[index].resProduction.wood;
		this.totalProduction.clay += this.vList[index].resProduction.clay;
		this.totalProduction.iron += this.vList[index].resProduction.iron;
		this.totalProduction.crop += this.vList[index].resProduction.crop;
		
		this.totalStock.wood += this.vList[index].getCurrentStockWood(false);
		this.totalStock.clay += this.vList[index].getCurrentStockClay(false);
		this.totalStock.iron += this.vList[index].getCurrentStockIron(false);
		this.totalStock.crop += this.vList[index].getCurrentStockCrop(false);
		
		this.totalCapacity.warehouse += this.vList[index].resCapacity.warehouse;
		this.totalCapacity.granary += this.vList[index].resCapacity.granary;
	
	}
	
}



//Resources class stores and deals with the 4 basic resources, its objects are used in many places
function Resources(){
	this.wood = 1;
	this.clay = 1;
	this.iron = 1;
	this.crop = 1;
	
	this.woodf = function(){
		return addSeparatorsNF(this.wood.toFixed(0),",",",",".");
	}
	this.clayf = function(){
		return addSeparatorsNF(this.clay.toFixed(0),",",",",".");
	}
	this.ironf = function(){
		return addSeparatorsNF(this.iron.toFixed(0),",",",",".");
	}
	this.cropf = function(){
		return addSeparatorsNF(this.crop.toFixed(0),",",",",".");
	}
	
	this.toString = function() {
	
		var output = "Resources [wood: "+this.wood+"; clay: "+this.clay+"; iron: "+this.iron+"; crop: "+this.crop+"]";
	
		return output;
	}
	
	this.merge = function() {
	
		var output = this.wood+"/"+this.clay+"/"+this.iron+"/"+this.crop;
	
		return output;
	}
	
	this.parseRes = function(rawString) {

		var data = rawString.split("/");
	
		this.wood = parseInt(data[0]);
		this.clay = parseInt(data[1]);
		this.iron = parseInt(data[2]);
		this.crop = parseInt(data[3]);

	}

	this.resetValues = function(){
		this.wood = 0;
		this.clay = 0;
		this.iron = 0;
		this.crop = 0;
	}
	
	
}

//ResourcesCapacity class stores and deals with Warehouse and Granary capacities, its objects are used in many places
function ResourcesCapacity(){
	this.warehouse = 800;
	this.granary = 800;
	
	this.toString = function() {
	
		var output = "Capacity [warehouse: "+this.warehouse+"; granary: "+this.granary+"]";
	
		return output;
	}

	this.merge = function() {
	
		var output = this.warehouse+"/"+this.granary;
	
		return output;
	}
	
	this.parseRes = function(rawString) {

		var data = rawString.split("/");
	
		this.warehouse = parseInt(data[0]);
		this.granary = parseInt(data[1]);

	}

	this.resetValues = function(){
		this.warehouse = 800;
		this.granary = 800;
	}
	
	
	this.warehousef = function(){
		return addSeparatorsNF(this.warehouse.toFixed(0),",",",",".");
	}
	this.granaryf = function(){
		return addSeparatorsNF(this.granary.toFixed(0),",",",",".");
	}
}

//ResourcesFull class stores boolean values, reporting if each resource is near to be full; if any of them is full this.any sould be true
function ResourcesFull(){
	this.wood = true;
	this.clay = true;
	this.iron = true;
	this.crop = true;
	this.any = true;
}

//ResourceField class stores info about 1 construction (resource field or building) of 1 village
function Construction(){

	//construction
	//from 0 to 17: resource field
	// > 17: building
	this.position=0;
	
	/* resource type:
	* g0: raw data
	* g1: wood
	* g2: clay
	* g3: iron
	* g4: crop
	* g9: building
	*/
	this.type='g0';

	// field level
	this.lvl=0;
	
	// field name string
	this.name="";
	
	//tag used to separate elements for merging then into a unique string
	this.merger='|ctrtmerge|';
	
	this.setLvl = function(source){
	
		var lvlString = ""+source;
		var parsedString = parseInt(lvlString);
		if(parsedString == "NaN"){
			this.lvl=-1;
		}else{
			this.lvl=parsedString;
		}
	
	}
	
	
	
	this.merge = function(){
		var mergeArray = new Array(this.position,this.type,this.lvl,escape(this.name));
		var output = mergeArray.join(this.merger);
	
		//var output = this.position+'/'+this.type+'/'+this.lvl+'/'+escape(this.name);
		return output;
	}
	
	this.parse = function(rawString) {

		//var data = rawString.split("/");
		var data = rawString.split(this.merger);
	
		this.position = parseInt(data[0]);
		this.type = data[1];
		this.setLvl(data[2]);
		this.name = unescape(data[3]);

	}
	
	this.toString = function() {
		var output = "Ctruct [p: "+this.position+"; t: "+this.type+"; lvl: "+this.lvl+"; name: "+this.name+"]";
		return output;
	}
	

}


//VillageResourcesLayout class stores a village's resources fields layout
function VillageResourcesLayout(vIndex){

	this.count=18;
	
	//index of the village this object represents, relative to vInfo.vList[] array
	//when creating an object, if you want it to represent the active village, use vInfo.activeVillageIndex
	this.villageIndex=vIndex;

	// creates a ResourceField array and instantiates all objects
	this.list = new Array();
	for(var i=0;i<this.count;i++)
		this.list[i] = new Construction();
		
		
	
		
	
	this.getVillageResourcesLayoutID = function(){
		var output = vInfo.uniqueID+ this.villageIndex + '.Dorf1';
		return output;
	}
	
	this.merge = function(){
		var stringArr=new Array();
		for(var i=0;i<this.count;i++){
			stringArr[i] = this.list[i].merge();
		}
			
		var output=stringArr.join(':');
		return output;
	}
	
	this.parse = function(rawString) {

		var data = rawString.split(":");
	
		for(var i=0;i<this.count;i++){
			this.list[i].parse(data[i]);
		}

	}

	this.toString = function(){

		var output="[VillageResourcesLayout]: index="+this.villageIndex+"  name: "+vInfo.vList[this.villageIndex].name;
		for(var i=0;i<this.count;i++){
			output += "\n"+this.list[i].toString();
		}
			
		return output;

	}
	
	this.storeData = function(){
	
		var presistance = "";
		persistance = this.merge();
		
		GM_setValue(this.getVillageResourcesLayoutID(),persistance);
		return persistance;
	
	}
	
	this.loadData = function(){
		var rawData = GM_getValue(this.getVillageResourcesLayoutID());
		if(!rawData) return false;
		this.parse(rawData);
		return true;
	}
	
}


//VillageBuildingsLayout class stores a village's buildings layout
function VillageBuildingsLayout(vIndex){

	this.count=22;
	
	//index of the village this object represents, relative to vInfo.vList[] array
	//when creating an object, if you want it to represent the active village, use vInfo.activeVillageIndex
	this.villageIndex=vIndex;

	//creates a Building array and instantiates all objects
	this.list = new Array();
	for(var i=0;i<this.count;i++){
		this.list[i] = new Construction();
	}


	this.getVillageBuildingsLayoutID = function(){
		var output = vInfo.uniqueID+ this.villageIndex + '.Dorf2';
		return output;
	}

	this.merge = function(){
		var stringArr=new Array();
		for(var i=0;i<this.count;i++){
			stringArr[i] = this.list[i].merge();
		}
			
		var output=stringArr.join(':');
		return output;
	}

	this.parse = function(rawString) {

		var data = rawString.split(":");
	
		for(var i=0;i<this.count;i++){
			this.list[i].parse(data[i]);
		}

	}
	
	this.toString = function(){
	
		var output="[VillageBuildingsLayout]: index="+this.villageIndex+"  name: "+vInfo.vList[this.villageIndex].name;
		for(var i=0;i<this.count;i++){
			output += "\n"+this.list[i].toString();
		}
			
		return output;

	}
	
	this.storeData = function(){
	
		var presistance = "";
		persistance = this.merge();
		
		GM_setValue(this.getVillageBuildingsLayoutID(),persistance);
		return persistance;
	
	}
	
	this.loadData = function(){
		var rawData = GM_getValue(this.getVillageBuildingsLayoutID());
		if(!rawData) return false;
		this.parse(rawData);
		return true;
	}
	
	

}

// Miscelaneous element used for Events that are not based on Constructions
function MiscElement(){

	this.element="";
	
	//tag used to separate elements for merging then into a unique string
	this.merger='|mcemerge|';
	
	
	
	this.merge = function(){
		return escape(this.element);
	}
	
	this.parse = function(rawString) {

		this.element = unescape(rawString);

	}
	
	this.toString = function(){
		return "[MiscElement]: "+this.element;
	
	}


}




// Event structe, as Construction and MiscElement
// used for Barrack, Stable and Workshop trainings
function Training(){

	//string data to distinguish between buildings
	this.name="";

	this.troopName="";

	//tag used to separate elements for merging then into a unique string
	this.merger='|trainmerge|';
	
	
	
	this.merge = function(){
		var mergeArray = new Array(escape(this.name),escape(this.troopName));
		var output = mergeArray.join(this.merger);
	
		//var output = this.position+'/'+this.type+'/'+this.lvl+'/'+escape(this.name);
		return output;
	}
	
	this.parse = function(rawString) {

		//var data = rawString.split("/");
		var data = rawString.split(this.merger);
	
		this.name = unescape(data[0]);
		this.troopName = unescape(data[1]);

	}
	
	
	
	this.toString = function(){
		var output = "[Training] building: "+this.name+"  troopName: "+this.troopName;
		return output;
	}

}


/* old event + construction merging/parsing structure

0	type
1	duration
2	start

3	position
4	type (g2)
5	x.gif
6	lvl
7	name
*/

/* Event types:

1: resource field (Dorf1)
2: building (Dorf2)
3: Demolish
4: Blacksmith & Armoury upgrades & Town Hall celebrations
5: Barrack, Stable & Worksop troops training
6: troops & mercants movements


dots:
1: event 1
2: events 2, 3
3: event 4, 5
4: event 6


*/



// events are constructions, they may be of resource fields or buildings, construction of new structures or upgrading of existing ones
function Event(){

	// event type
	this.type=0;
	
	// when the construction started, in seconds
	this.start=getCurrentTime();
	
	// how much time it takes for the event finish, in seconds
	this.duration=0;
	
	//event info, if this.type=1 it is a ResourceField object, if this.type=2 it is a Building object
	this.structure = new Construction();


	//tag used to separate elements for merging then into a unique string
	this.merger='|evtmerge|';
	
	
	
	this.setUnformattedDuration = function(unformatted){
		this.duration=getSeconds(unformatted);
		return this.duration;
	}
	
	this.getTimeLeft = function(){
		var seconds=this.start+this.duration-getCurrentTime();
		return seconds;
	}
	
	this.getEndingTime = function(){
		var date=new Date();
		date.setTime((this.start+this.duration)*1000);
 //alert("date:  "+date);
		return date.getHours()+':'+date.getMinutes()+':'+date.getSeconds();
	}
	
	this.isConstructionEvent = function(){
		if(this.type==1 || this.type==2 || this.type==3) return true;
		else return false;
	}
	
	this.isTrainingEvent = function(){
		return this.type==5;
	}
	
	//events expire after their duration, this method tests if this event has expired or not
	// returns true if it is a valid event (green dot), false if it has expired (yellow dot)
	this.evaluateOldEvent = function(){
		return this.getTimeLeft() > 0;
	}
	
	
	this.merge = function(){
		var mergeArray = new Array(this.type,this.start,this.duration,this.structure.merge());
		var output = mergeArray.join(this.merger);
	
		//var output = this.type+'|'+this.start+'|'+this.duration+'|'+this.structure.merge();
		
		return output;
	}

	this.parse = function(rawString) {
 //alert(rawString);
		//var data = rawString.split("|");
		var data = rawString.split(this.merger);
 //alert(data);
		
		if(data.length==4){
			this.type = parseInt(data[0]);
			this.start = parseInt(data[1]);
			this.duration = parseInt(data[2]);
			
			if(this.type!=1 && this.type!=2 && this.type!=3 && this.type!=5) this.structure = new MiscElement();
			if(this.type==5) this.structure = new Training();
			
			this.structure.parse(data[3]);
		}else{
			alert("Error: Something went wrong. I was trying to parse an Event, and Event.parse.data should have 4 elements, but it has "+data.length);
			return false;
		}
 //alert("parsed event: "+this);
 
		return true;

	}
	
	this.toString = function() {
		var output = "Event [type: "+this.type+"; duration: "+formatTime(this.duration)+
				"; time left: "+formatTime(this.start+this.duration-getCurrentTime())+
		"]  "+this.structure;
		return output;
	}
	

}


// deals with all events of a village
// Note: 	valid and real data must always be persistently stored, these classes are only used to deal with data for a short period of time, so make sure to always reload before doint anything and re-storing after any change
//		loadData() automatically calls removeOldEvents(), so removeOldEvents() should not be needed to be used by code outside the class, if you feel it may be needed, give preference to realoding the data instead of using removeOldEvents()
function VillageEvents(){

	this.events = new Array();
	
	this.villageEventID=0;
	
	
	
	this.count = function(){
		return this.events.length;
	}
	
	this.sortEvents = function(){
		this.events.sort(function(eventA,eventB){
			return eventA.getTimeLeft() - eventB.getTimeLeft();
		});
	}
	
	this.purge = function(){
		this.events = new Array();
		this.storeData();
	}
	
	
	this.hasEventType = function(type){
		for(var i=0;i<this.count();i++){
			if(this.events[i].type==type) return true;
		}
		return false;
	}
	
	this.hasExpiredEventOfType = function(type){
		for(var i=0;i<this.count();i++){
			if(this.events[i].type==type && !this.events[i].evaluateOldEvent()) return true;
		}
		return false;
	}
	
	//returns an array storing requred events index
	this.getEventOfType = function(type){
		var indexes=new Array();
	
		for(var i=0;i<this.count();i++){
			if(this.events[i].type==type){
				indexes.push(i);
			}
		}
		
		return indexes;
	}
	
	
	this.storeData = function(){
	
		var presistance = "";
		persistance = this.merge();
		
		GM_setValue(this.getVillageEventID(),persistance);
		return persistance;
	
	}

	this.loadData = function(){
		var rawData = GM_getValue(this.getVillageEventID());
 //alert("VillageEvents.loadData.rawData:\n\n"+rawData);

		if(!rawData){
			this.events = new Array();
			return null;
		}

		if(!this.parse(rawData)){
			this.storeData();
		}

//		if(this.removeOldEvents()){
//			this.storeData();
//		}

		return this.count();
	}
	

	
	this.pushEvent = function(event){
 //alert("pushEvent: "+event);
		this.loadData();
		//if(event.evaluateOldEvent()){
			//this.events.push(event);
			this.events[this.count()]=event;
			this.sortEvents();
 			this.storeData();
		//}
	}
	
	// removes an event, must call loadData() just before call it!
	this.removeEvent = function(index){
		this.events.splice(index,1);
		this.storeData();
	}
	
	this.removeDemolishEvent = function(){
		this.loadData();
		var newEvents = new Array();
		var hadDemolish=false;
		
		for(var i=0;i<this.count();i++){
			if(this.events[i].type!=3){		// if it is a demolish event
				var nelength=newEvents.length;
				newEvents[nelength]=this.events[i];
			}else{
				hadDemolish=true;
			}
		}
		
		if(hadDemolish){
			this.events=newEvents;
			this.storeData();
		}
		
		return hadDemolish;
	
	}
	
	this.removeTrainingEvents = function(building){
		this.loadData();
		var newEvents = new Array();
		var hadTraining=false;
		
		for(var i=0;i<this.count();i++){
 //alert("event "+i+": "+this.events[i]);
		
			if(this.events[i].type==5 && this.events[i].structure.name==building){		// if it is a training event and its building matches
				hadTraining=true;
 //alert(i+"  removed");
			}else{
				var nelength=newEvents.length;
				newEvents[nelength]=this.events[i];
			}
			
		}
		
		if(hadTraining){
			this.events=newEvents;
			this.storeData();
		}
		
		return hadTraining;
	
	}
	
	this.findEvent = function(baseName){
		for(var i=0;i<this.count();i++){
			if(this.events[i].structure.name.slice(0,5)==baseName && this.events[i].isConstructionEvent()){
				return i;
			}
		}
		return -1;
	}
	
	
	// DEPRECATED!! this method should not be used
	//events expire after their duration, this method tests all events inside its object and updates events array
	// returns true if any event was removed and false if otherwise, if it returns true you SHOULD call storeData() immediately to update persistent data
	this.removeOldEvents = function(){
		var newEvents = new Array();
		var eventRemoved=false;
		
		for(var i=0;i<this.count();i++){
			if(this.events[i].evaluateOldEvent()){
				var nelength=newEvents.length;
				newEvents[nelength]=this.events[i];
			}else{
				eventRemoved=true;
			}
		}
 //alert("internal list: "+this.events.length+"\nnewEvents: "+newEvents.length+"\neventRemoved: "+eventRemoved);
		this.events=newEvents;
		return eventRemoved; 
	}

	this.getVillageEventID = function(){
		var output = vInfo.vList[this.villageEventID].id + '.TimedEvents';
		return output;
	}
	

	this.merge = function(){
		var stringArr=new Array();
		for(var i=0;i<this.count();i++){
			stringArr[i] = this.events[i].merge();
		}
			
		var output=stringArr.join(':');
		return output;
	}

	this.parse = function(rawString) {

		var data = rawString.split(":");
		var newEvents = new Array();

		for(var i=0;i<data.length;i++){
			var event = new Event();
			event.parse(data[i]);
			newEvents.push(event);
		}
		
		this.events=newEvents;
	}
	
	this.toString = function(){
		//this.loadData();
 
		var output="[VillageEvents]: "+this.getVillageEventID()+" "+vInfo.vList[this.villageEventID].name+"  "+this.count()+" events";
		for(var i=0;i<this.count();i++){
			output += "\n"+this.events[i].toString();
		}
			
		return output;

	}
	
	

}

// stores all events of all villages
// caution: //AllVillagesEvents requires vInfo data that are gathered inside getReferenceData.get() to be instantiated
function AllVillagesEvents(){

	this.villages = new Array();
		for(var i=0;i<vInfo.count;i++){
			this.villages[i]=new VillageEvents();
			this.villages[i].villageEventID=i;
 //alert("VillageEvent created:\n"+this.villages[i]);
		}
	
	
	this.count = function(){
		var counting=0;
		this.loadData();
		for(var i=0;i<vInfo.count;i++){
			counting+=this.villages[i].count();
		}
		return counting;
	}
	
	this.purge = function(){
		for(var i=0;i<vInfo.count;i++){
			this.villages[i].purge();
		}
	}
	
	this.addNewEvent = function(evt){
		this.villages[vInfo.activeVillageIndex].pushEvent(evt);
	}
	
	this.removeDemolishEvent = function(){
		this.villages[vInfo.activeVillageIndex].removeDemolishEvent();
	}
	
	this.getNextEvents = function(){
 //alert("entering AllVillagesEvents.getNextEvents()");
 
		var nextEvents = new Array();
		
		// i loops throu villages list, j loops throu each village's events list
		for(var i=0;i<vInfo.count;i++){
 //alert(vInfo.vList[i].name+" events: "+this.villages[i].count());
			for(var j=0;j<this.villages[i].count();j++){
 //alert("this.villages["+i+"].events["+j+"].evaluateOldEvent(): "+this.villages[i].events[j].evaluateOldEvent()+"\n\n"+vInfo.vList[i].name);
				
				// get current village (i) 's current event (j) and verify if it has expired
				if(this.villages[i].events[j].evaluateOldEvent()){
					
					// if it hasn't expired, add it to nextEvents and exit j loop
					//nextEvents.push(new NextEvent(i,villages[i].events[j]));
					nextEvents.push(new NextEvent(i,this.villages[i].events[j]));
					break;
					
				}else{
					// if it has expired, continue to next (j) event
					continue;
				}
				
			}
		}
		
		nextEvents.sort(sortNextEvents);
		return nextEvents;
	
	}
	
	
	this.storeData = function(){
		for(var i=0;i<vInfo.count;i++){
			this.villages[i].storeData();
		}
	}
	this.loadData = function(){
		var eventCount=0;
		for(var i=0;i<vInfo.count;i++){
			eventCount+=this.villages[i].loadData();
		}
		return eventCount;
	}
	
	
	// DEPRECATED!! this method should not be used
	// AllVillagesEvents.removeOldEvents() loops thru all VillageEvents and call their VillageEvents.removeOldEvents()
	// when an event is detected as expired on a VillageEvents, its storeData() is automatically called, making sure persistent data is kept valid
	// returns true if any event inside any VillageEvents had expired, false otherwise, but it is only an aditional info (loggin/debugging meant) since all measures had already been done
	// anyway, all removeOldEvents() methods are meant to be used only internally on event classes, if you feel any of them may be needed, give preference to realoding the data instead of using them
	this.removeOldEvents = function(){
		var eventRemoved=false;
	
		for(var i=0;i<vInfo.count;i++){
			if(this.villages[i].removeOldEvents()){
				eventRemoved=true;
				this.villages[i].storeData();
			}
		}
		
		return eventRemoved;
	}


	this.toString = function(){
		this.loadData();

		var output="[AllVillagesEvents]:   "+this.count()+" events";
		for(var i=0;i<vInfo.count;i++){
			output += "\n\n"+this.villages[i].toString();
		}
			
		return output;

	}


}

function NextEvent(village,evt){
	
	//village index according to vInfo.vList[index]
	this.village=village;
	
	// Event object
	this.event=evt;
	
	this.toString = function(){
		output = "[NextEvent] village:"+vInfo.vList[this.village].name+"   "+this.event;
		return output;
	}
}

function sortNextEvents(nxevt1,nxevt2){
	return nxevt1.event.getTimeLeft() - nxevt2.event.getTimeLeft();
}


function BmArmTable(){
	this.troopName="";
	this.lvl=-1;
	this.duration=0;
	this.upgradeLink="";
	
	
	
	this.setUnformattedDuration = function(unformatted){
		this.duration=getSeconds(unformatted);
		return this.duration;
	}
	
	this.toString = function(){
		output = "[BmArmTable] troopName: "+this.troopName+"; lvl: "+this.lvl+"; duration: "+formatTime(this.duration);
		return output;
	}
}

function TrainTable(){

	// train button's DOM element
	this.btnLink;
	
	// verifying flag
	// if true, this builging training event is being logged by user and should be updated
	// if false, user removed this building training and doesn't want it being logged, ignore it until he adds it back manually
	this.isTraining=false;
	
	//internal string data to distinguish between buildings
	this.building="";
	
	this.troopName="";
	this.duration=0;
	
	// DOM element where Xadd button is added
	this.addCell;
	
	
	this.setUnformattedDuration = function(unformatted){
		this.duration=getSeconds(unformatted);
		return this.duration;
	}

	
	this.toString = function(){
		var output = "[TrainTable] isTraining: "+this.isTraining+"; building: "+this.building+"; troop: "+this.troopName+
							"; duration: "+formatTime(this.duration);
		
		return output;
	}




}

function Movement(){

	this.name="";
	this.time="";
	this.cell;
	this.start=getCurrentTime();
	
	this.toString = function(){
		var output="[MercantMovement] name: "+this.name+"  time: "+this.time+"  cell: "+this.cell;
		return output;
	}

}




function CP(building,rank,lvl,cp,eff){
	this.rank		= rank;
	this.building	= building;
	this.lvl		= lvl;
	this.cp			= cp;
	this.eff		= eff;
	
	this.getFormattedEff = function(){
		return addSeparatorsNF(this.eff,",",",",".");
	}
	
	this.toString = function(){
		var output = "[Culture Point] rank: "+this.rank+"building: "+this.building+"; lvl: "+this.lvl+"; CP earn: "+this.cp+"; raw efficiency: "+this.getFormattedEff()+".";
		return output;
	}
}


function VillageCPRank(vIndex,cpIndex){
	this.vIndex=vIndex;
	this.cpIndex=cpIndex;

	this.toString = function(){
		var output = "[VillageCPRank] village: "+vInfo.vList[vIndex].name+";  building: "+cps[cpIndex].building
					+" "+cps[cpIndex].lvl+";  efficiency: "+cps[cpIndex].getFormattedEff();
		return output;
	}
}

function sortByEfficiency(up1,up2){
	return cps[up1.cpIndex].rank - cps[up2.cpIndex].rank;	//the one with higher efficiency goes up to the begin of the array
}
function sortByVillage(up1,up2){
	return up2.vIndex - up2.vIndex;
}

function VillagesCPArray(){
	this.list=new Array();
	
	this.count = function(){
		return this.list.length;
	}
	
	this.sortBy = function(sort){
		if(sort!="efficiency"){
			this.list.sort(sortByVillage);
		}else{
			this.list.sort(sortByEfficiency);
		}
		
		return this.list;
	}

	this.toString = function(){
		var output="[VillagesCPArray]: "+this.count()+" elements\n";
		for(var i=0;i<this.count();i++){
			output+="\n"+this.list[i];
		}
		return output;
	}
	
}

function getCPRank(pervillage){
 //alert("entering getCPRank()");

	var cpArray=new VillagesCPArray();
	var vbl;
	
	cpSkipList.loadData();

	// for every village...
	for(var vil=0;vil<vInfo.count;vil++){	// debug loop, replace it by vInfo.count
	
		vbl = new VillageBuildingsLayout(vil);
		vbl.loadData();
		
		var villageEntries=0;
	
		// look throu cps
		for(var cpsi=0;cpsi<cps.length;cpsi++){		// debug loop, replace it by cps.length
 //alert("vil="+vil+"   cpsi="+cpsi+"\n\n"+cps[cpsi].building+"  "+cps[cpsi].lvl);
	
			var buildingFound=false;
	
			// for every village building...
			for(var vbli=0;vbli<vbl.count;vbli++){
 //alert("vil="+vil+"   cpsi="+cpsi+"   building="+vbli+"\n\n"+cps[cpsi].building+"  "+cps[cpsi].lvl+"\n"+vbl.list[vbli].name+"  "+vbl.list[vbli].lvl);
 
 
				
			
				// do "it" until we have found a maixmum of 'pervillage' entries
			
			
				// if current cps rank building matches current village building
				if(cps[cpsi].building == vbl.list[vbli].name){
  //alert("building name matched!\n\nvil="+vil+"   cpsi="+cpsi+"   building="+vbli+"\n\n"+cps[cpsi].building+"  "+cps[cpsi].lvl+"\n"+vbl.list[vbli].name+"  "+vbl.list[vbli].lvl);
  
					buildingFound=true;
				
					// if it is <= it was already built, but if it is > then it wasn't built yet and it is  one of the most efficient upgrades to increase CP production
					if(cps[cpsi].lvl > vbl.list[vbli].lvl){
 //alert("lvl matched, this one wasn't built yet!\n\n vil="+vil+"   building="+vbli+"   cpsi="+cpsi+"\n\n"+cps[cpsi].building+"  "+cps[cpsi].lvl+"\n"+vbl.list[vbli].name+"  "+vbl.list[vbli].lvl);
 
						if(cpSkipList.canSuggest(vil,cpsi)){
							cpArray.list[cpArray.count()] = new VillageCPRank(vil,cpsi);
							villageEntries++;
 //alert("cpArray:\n\n"+cpArray);
						}
 
 
 
					}
					
					

				
				
 //alert("building found, no need to loop vbli anymore\n\nvil="+vil+"   cpsi="+cpsi+"   building="+vbli);
					break;	// continue not working? ;/
				}
			
			
			}
			
			
			if(!buildingFound){
			
				if(cpSkipList.canSuggest(vil,cpsi)){
					
					//cps building not found, it must not be built yet, add it to cpArray
					cpArray.list[cpArray.count()] = new VillageCPRank(vil,cpsi);
					villageEntries++;
						
 //alert("building not found, this one wasn't built yet!\n\n vil="+vil+"   cpsi="+cpsi+"\n\n"+cps[cpsi].building+"  "+cps[cpsi].lvl);
 //alert("cpArray:\n\n"+cpArray);
				}
 
			}
			
			
			if(villageEntries>=pervillage){
 //alert("pervillage was matched, this means that we have enought CP suggestions entries for this village, we can skip to next village now...");
 //alert("cpArray:\n\n"+cpArray);
				break;
			}
		
		}
		
	}
	
	
	// ok, we are done and our list is complete... almost
 //alert("Full cpArray:\n\n"+cpArray);
 
	// now we must sort it by efficiency
	//cpArray.sortByEfficiency();		// now it is sorted after getCPRank() returns
 //alert("Sorted cpArray:\n\n"+cpArray);
 
	return cpArray;
	


}


function CPSkip(){

	// vID must match vInfo.vList[].id
	this.vID="rawvillage";
	this.cpIndex=999;
	
	this.toString = function(){
		var output="[CPSkip] vID: "+this.vID+"   cpIndex:"+this.cpIndex+".";
		return output;
	}
	
	this.merge = function() {
	
		var output = this.vID+"/"+this.cpIndex;
	
		return output;
	}
	this.parse = function(rawString) {

		var data = rawString.split("/");
	
		this.vID 	 = data[0];
		this.cpIndex = parseInt(data[1]);

	}

}

function CPSkipList(){

	this.list=new Array();
	this.list[0]=new CPSkip();

	
	this.count = function(){
		return this.list.length;
	}

	this.add = function(cpskip){
 //alert("CPSkipList.add()\n\n"+cpskip);
 
		this.list[this.count()]=cpskip;
		this.storeData();
		return this.count();
	}
	
	this.resetSkips = function(){
		this.list=new Array();
		this.list[0]=new CPSkip();
		this.storeData();
		
 //alert("CPSkipList reseted:\n\n"+this);
	}
	
	this.canSuggest = function(vil,cpsi){
 //alert("entering CPSkipList.canSuggest()");
	
		for(var i=0;i<this.count();i++){
			if(vInfo.vList[vil].id == this.list[i].vID && cpsi==this.list[i].cpIndex) return false;
		}
		
		return true;
	}
	
	
	
	this.toString = function(){
		var output="[CPSkipList]: "+this.count()+" entries\n";
		
		for(var i=0;i<this.count();i++){
			output+="\n"+this.list[i];
		}
		
		return output;
	}
	
	this.storeData = function() {
 //alert("entering CPSkipList.storeData\n\n"+this);
 
		var persistence = this.list[0].merge();
		
		for(var i=1;i<this.count();i++){
			persistence += ":"+this.list[i].merge();
		}
		
		GM_setValue(vInfo.uniqueID + '.CPSkip',persistence);
		return persistence;
	
	}
	
	this.loadData = function(){
 //alert("CPSkipList before loading data:\n"+this.toString());
 
		// loads GreaseMonkey persistent data about this village
		 var rawGMValue = GM_getValue(vInfo.uniqueID + '.CPSkip');
  //alert("rawGMValue:\n"+rawGMValue);
  
  
		// if it wasn't found, store raw data and move on
		// if it was found, parse the string
		if(rawGMValue){
			var rawData = rawGMValue.split(":");
 
			this.list=new Array();
		
			for(var i=0;i<rawData.length;i++){
				this.list[i]=new CPSkip();
				this.list[i].parse(rawData[i]);
			
			}
		}
		
 //alert("CPSkipList after loading data:\n"+this.toString());
	}
	
	
}



//alert("classes definition ok");
 
 














 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 






















































































































































































































 
 
 
 


// ›› Event listener starts things off once the page is done loading.
window.addEventListener("load",init,false);


function init() {
 //alert("entering init()");

	if (GM_getValue("InActive")){
		inactivestub();
		return;
	}
 //alert("passed inactivestub()");

	if (!(/travian/.exec(document.domain))) {
		offsitestub();
		return;
	}
 //alert("passed offsitestub()");
	
	
	
	core.run();
	
	
	



}


function Core(){

	this.run = function(){
 //alert("entering Core.run()");
	
		//debug();

		
		getReferenceData.get();
 //alert("getReferenceData.get() ok");
		getResourceInfo.get();
 //alert("getResourceInfo.get() ok");
 
		makeDefaultCSS();
		
		showTotalProduction.show();
 //alert("showTotalProduction.show ok");
 
		getBuildInfo.get();
 //alert("getBuildInfo.get() ok");
 
		//these classes require vInfo data that are gathered inside getReferenceData.get() to be instantiated
		allVillagesEvents = new AllVillagesEvents();
	
		if (!GM_getValue(vInfo.uniqueID+"Prefs")){GM_setValue(vInfo.uniqueID+"Prefs",'0.1.1.0.0.T.S');}		
		Prefs = GM_getValue(vInfo.uniqueID+"Prefs").split('.');
 //alert("Prefs() ok");
	
		addListener.get();
 //alert("addListener.get() ok");
 
		createMenu.show();
 //alert("createMenu.show() ok");
	
		showEvents.show();
 //alert("showEvents.show() ok");
	
		setInterval(timerCooldown,1000);
 //alert("timerCooldown() ok");
 
		//addRemoveEvent();
 //alert("addRemoveEvent() ok");

		showCPSuggestions = new ShowCPSuggestions();
		showCPSuggestions.show();
 //alert("showCPSuggestions.show() ok");
 
 
 
 
		//getCPRank(5);
	
	
	
		debug();
 //alert("That's it, everything working!!");
	
	}


}




function timerCooldown(){
 //alert("entering timerCooldown()");

	var timers=TM_searchDOM('//span[@id="TMcooldown"]');
 //alert(timers.snapshotLength+" timers found");
 
	for(var i=0;i<timers.snapshotLength;i++){
	
		var timeleft=timers.snapshotItem(i).getAttribute("timeleft");
		var yellow=timers.snapshotItem(i).getAttribute("yellow");
 //alert("timeleft: "+timeleft);
 
		if(timeleft){	// if it was found
		
			timeleft=parseInt(timeleft);
			
			timeleft--;
			timers.snapshotItem(i).setAttribute("timeleft",timeleft);
			timers.snapshotItem(i).innerHTML=formatTime(timeleft);
			
			//if(timeleft>10 && timeleft<-30){
			if(timeleft<0){	// if it is negative
				timers.snapshotItem(i).setAttribute("yellow","true");
			
				if(yellow!="true"){
					showEvents.buildEventsTable(false);
 //alert("showEvents.buildEventsTable(false) was called, timeleft: "+timeleft+"   yellow: "+yellow);
				}
				
			}
		
		}
	
	}
 



}

function removeEvent(vlg,evt){
 //alert("village: "+vlg+";   event: "+evt);
	allVillagesEvents.villages[vlg].removeEvent(evt);
	//window.location.href=window.location.href;
	showEvents.buildEventsTable(false);

}

function addRemoveEvent(){
 //alert("entering addRemoveEvent()");

	var removeIcons=TM_searchDOM('//a[@id="TMRemoveEvent"]');
 //alert(removeIcons.snapshotLength+" icons found");
 
	for(var i=0;i<removeIcons.snapshotLength;i++){
	
		removeIcons.snapshotItem(i).style.cursor='pointer';
		removeIcons.snapshotItem(i).addEventListener('mousedown', function(){ 
				
				var village=parseInt(this.getAttribute("village"));
				var event=parseInt(this.getAttribute("event"));
 //alert("village: "+village+"; event: "+event);
				
				removeEvent(village,event);  
		}, true);
	
	}

}

function addResortCP(){
 //alert("entering addRemoveEvent()");

	var resortIcons=TM_searchDOM('//a[@id="TMResortCP"]');
 //alert(resortIcons.snapshotLength+" icons found");
 
	for(var i=0;i<resortIcons.snapshotLength;i++){
	
		resortIcons.snapshotItem(i).style.cursor='pointer';
		resortIcons.snapshotItem(i).addEventListener('mousedown', function(){ 
				
				var sort=this.getAttribute("sort");
 //alert("sort: "+sort);
				
				showCPSuggestions.resortCPTable(sort); 
		}, true);
	
	}
	
	
	
	var skipIcons=TM_searchDOM('//a[@id="TMSkipCPEntry"]');
 //alert(skipIcons.snapshotLength+" icons found");
 
	for(var i=0;i<skipIcons.snapshotLength;i++){
	
		skipIcons.snapshotItem(i).style.cursor='pointer';
		skipIcons.snapshotItem(i).addEventListener('mousedown', function(){ 
				
				var cpskip = new CPSkip();
				
				cpskip.vID=this.getAttribute("vid");
				cpskip.cpIndex=parseInt(this.getAttribute("cpsid"));
				
				cpSkipList.add(cpskip);
 
				showCPSuggestions.buildCPTable();
 
				
		}, true);
	
	}
	
	
	
	
	var resetIcons=TM_searchDOM('//a[@id="TMResetSkips"]');
 //alert(resetIcons.snapshotLength+" icons found");
 
	for(var i=0;i<resetIcons.snapshotLength;i++){
	
		resetIcons.snapshotItem(i).style.cursor='pointer';
		resetIcons.snapshotItem(i).addEventListener('mousedown', function(){ 
				
			cpSkipList.resetSkips();
			showCPSuggestions.buildCPTable();
			
		}, true);
	
	}

}
























































//=================================
// Model (gathers info from the game)


function GetReferenceData(){

	//refers to vlist table, it is the table on the right that lists all villages
	this.vlistTable;
	
	//refers to logout URL
	this.logoutLink;
	
	//logged user's ID
	this.userID;
	
	//server domain
	this.server;
	
	//current URL page (in address bar)
	this.page;
	
	
	
	
	
	
	this.get = function(){
 //alert("entering GetReferenceData.get()");
	
		// old SS1
		this.vlistTable = this.getVlistTable();
 //alert("GetReferenceData.vlistTable:   "+this.vlistTable.snapshotItem(0));

		//old SS2
		this.logoutLink = this.getLogoutLink();
 //alert("GetReferenceData.logoutLink:   "+this.logoutLink.snapshotItem(0));
		
		
		if (this.vlistTable.snapshotItem(0) && this.logoutLink.snapshotItem(0)){
	
			// old X1, X1b, X1PlaceEqual
			var tempuser1 = TM_searchDOM('//p/a[3]');
			var tempuser2 = tempuser1.snapshotItem(0).toString();			
			var tempuser3PlaceEqual = tempuser2.indexOf("=");

			// old User
			this.userID  = tempuser2.substring(tempuser3PlaceEqual,tempuser2.length);
 //alert('Active User ID:   '+ this.userID);
	
	
		
			//old X2, X2b, X2PlaceEqual
			var tempvillage1 = this.getActiveVillage();
 //alert("Active Village URL:\n"+tempvillage1.snapshotItem(0));
			var tempvillage2 = tempvillage1.snapshotItem(0).toString();			
			var tempvillage3PlaceEqual = tempvillage2.indexOf("=");						
 //alert('ok');
			// old ActiveVillage
			vInfo.activeVillageID = tempvillage2.substring(tempvillage3PlaceEqual+1,tempvillage2.length);
 //alert('Active Village ID: '+ vInfo.activeVillageID );
 
 
 			// now we find active village ID
			var tmpLocation = vInfo.activeVillageID.indexOf("&");	
			if (tmpLocation>2) {								//alert('cut village number voor:' + vInfo.activeVillageID);
				vInfo.activeVillageID = vInfo.activeVillageID.substring(0,tmpLocation);			//alert('cut village number na  :' + vInfo.activeVillageID); 
			}
 //alert('Active Village ID: '+ vInfo.activeVillageID );
 
 
 
			//now we must find out what's the active village's position (index) among villages list, that's necessary in some places to relate active village with villages array
			vInfo.activeVillageIndex = this.getActiveVillageIndex();
 //alert("vInfo.activeVillageIndex: "+vInfo.activeVillageIndex);
	
	




			this.server = document.domain;							
 //alert("Server domain: "+this.server);
 
			var splitDomain=this.server.split(".");
			vInfo.serverLang=splitDomain[splitDomain.length-1];
 //alert("vInfo.serverLang: "+vInfo.serverLang);
 
			vInfo.uniqueID = this.server + '.' + this.userID + '.';
 //alert("Unique ID:\n"+vInfo.uniqueID);
			this.page = window.location.href;
 //alert("Page URL (address bar):\n"+this.page);
 
			switchLanguage();
	
	
			//now let's count how many village this account has
			//old SS3
			var tempvillage10=this.getVillageCount();
			vInfo.count = tempvillage10.snapshotLength;
 //alert('You have '+vInfo.count+' villages' );
	
	
	
			//now let's loop thru all village table's tr and get some info from all villages
			for ( var i=0 ; i < vInfo.count; i++ ) {
	
				//old X3, X3b, X3PlaceEqual
				var tempvid1 = tempvillage10.snapshotItem(i).getAttribute("href");
 //alert('villageID:   ' + tempvid1);   				
				var tempvid2 = tempvid1.toString();			
				var tempvid3PlaceEqual = tempvid2.indexOf("=");
 //alert('tempvid3PlaceEqual: '+tempvid3PlaceEqual);

				// old X4
				var xcoord = this.getXcoord(i);
 //alert('xcoord = '+xcoord.snapshotItem(i).innerHTML);

				var ycoord = this.getYcoord(i);
 //alert('ycoord = ' + ycoord.snapshotItem(i).innerHTML);

				vInfo.rawVillageIDs[i] = tempvid2.substring(tempvid3PlaceEqual,tempvid2.length);					
 //alert('villageID:   ' + vInfo.rawVillageIDs[i]); 

				vInfo.rawVillageIDs[i] = vInfo.rawVillageIDs[i].substring(1,vInfo.rawVillageIDs[i].length); 
				var tmpLocation = vInfo.rawVillageIDs[i].indexOf("&");	
				if (tmpLocation>2) {
					vInfo.rawVillageIDs[i] = vInfo.rawVillageIDs[i].substring(0,tmpLocation); 
				}									
 //alert('vInfo.rawVillageIDs['+i+']:   ' + vInfo.rawVillageIDs[i]); 

	
	
	
	
				// The following 2 lines instantiates a Village object, stores it in vInfo.vList[i], then add the village ID to that object
				vInfo.vList[i]=new Village();
				vInfo.vList[i].id=vInfo.uniqueID+vInfo.rawVillageIDs[i];
 //alert("vInfo.vList["+i+"].id:\n"+vInfo.vList[i].id);
				
				vInfo.vList[i].link = tempvillage10.snapshotItem(i).getAttribute("href");
 //alert("vInfo.vList["+i+"].link = "+vInfo.vList[i].link);
				
				vInfo.vList[i].name = tempvillage10.snapshotItem(i).innerHTML;
 //alert("vInfo.vList["+i+"].name = "+vInfo.vList[i].name);
				
				vInfo.vList[i].coords = xcoord.snapshotItem(i).innerHTML + '|' +  ycoord.snapshotItem(i).innerHTML;
 //alert("vInfo.vList["+i+"].coords = "+vInfo.vList[i].coords);
 //alert("vInfo.vList["+i+"]info:\n\n"+vInfo.vList[i].toString());

			}
			
	
	
	
	
		}
	
	}


	
	this.getVlistTable = function(){
	
		var lVlistTable = null;

 //alert("GetReferenceData.getVlistTable()\nbrx, single village, Beyond 3.8.8.2 required");
		lVlistTable = TM_searchDOM('//table[@class="vlist"]');
		if(!lVlistTable){ return lVlistTable; }
		
 //alert("GetReferenceData.getVlistTable()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		lVlistTable = TM_searchDOM('//table[@id="vlist"]');
		if(!lVlistTable){ return lVlistTable; }
	
	
	
 //alert("GetReferenceData.getVlistTable()\nvlistTable not found");
		return lVlistTable;
	
	}
	
	this.getLogoutLink = function(){
	
		var lLogoutLink=null;
	
		lLogoutLink = TM_searchDOM('//a[@href="logout.php"]');
		if(lLogoutLink.snapshotItem(0)){ return lLogoutLink; }

		
 //alert("GetReferenceData.getLogoutLink()\n lLogoutLink not found");
		return lLogoutLink;
	}
	
	this.getActiveVillage = function(){
	
		var av = null;
		
 //alert("GetReferenceData.getActiveVillage()\n brx, single village, Beyond 3.8.8.2 required");
		av = TM_searchDOM("//td[@class='dot']/parent::tr/td[@class='text']/a[1]");
		if(av.snapshotItem(0)){ return av; }
		
 //alert("GetReferenceData.getActiveVillage()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		av = TM_searchDOM("//td[@class='dot hl']/parent::tr/td[@class='link']/a[1]");
		if(av.snapshotItem(0)){ return av; }
		
 //alert("GetReferenceData.getActiveVillage()\nbrx, multiple village, Beyond 3.8.8.2 supported, v2");
		av = TM_searchDOM("//td[@class='dot hl']/parent::tr/td[@class='link']//a[1]");
		if(av.snapshotItem(0)){ return av; }
		

		
 //alert("GetReferenceData.getActiveVillage()\n activeVillage not found");
		return lVlistTable;
	
	}
	
	this.getActiveVillageIndex = function(){
	
		var index=null;
		
		
 //alert("GetReferenceData.getActiveVillageIndex()\n brx, single village, Beyond 3.8.8.2 required");
		index = TM_searchDOM('//table[@class="vlist"]/tbody/tr');
		if(index.snapshotLength>0){
			for(var i=0;i<index.snapshotLength;i++){
				for(var j=0;j<index.snapshotItem(i).childNodes.length;j++){
 //alert("index.snapshotItem("+i+").childNodes["+j+"].innerHTML:\n"+index.snapshotItem(i).childNodes[j].innerHTML);
					if(index.snapshotItem(i).childNodes[j].className == "dot"){
						return j;
						break;
					}
				}
			}
		}
		
		
 //alert("GetReferenceData.getActiveVillageIndex()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		index = TM_searchDOM('//table[@id="vlist"]/tbody/tr');
		if(index.snapshotLength>0){
			for(var i=0;i<index.snapshotLength;i++){
				for(var j=0;j<index.snapshotItem(i).childNodes.length;j++){
 //alert("index.snapshotItem("+i+").childNodes["+j+"].innerHTML:\n"+index.snapshotItem(i).childNodes[j].innerHTML);
					if(index.snapshotItem(i).childNodes[j].className == "dot hl"){
						return i;
						break;
					}
				}
			}
		}

 
 
 //alert("Active Village Index not found");
		return 0;
	
	
	}
	
	this.getVillageCount = function(){
	
		var count=0;
		var villages;
		
 //alert("GetReferenceData.getActiveVillageIndex()\nbrx, single village, Beyond 3.8.8.2 required");
		villages=TM_searchDOM('//table[@class="vlist"]/tbody/tr/td[@class="text"]/a');
		count=villages.snapshotLength;
		if(count>0){ return villages; }
		

 //alert("GetReferenceData.getActiveVillageIndex()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		villages=TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="link"]/a');
		count=villages.snapshotLength;
		if(count>0){ return villages; }
		
		
 //alert("GetReferenceData.getActiveVillageIndex()\nbrx, multiple village, Beyond 3.8.8.2 supported v2");
		villages=TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="link"]//a');
		count=villages.snapshotLength;
		if(count>0){ return villages; }
	
	
	
 //alert("GetReferenceData.getActiveVillage()\n count not found");
		return villages;
	
	}
	
	this.getXcoord = function(i){
	
		var xcoord=null;
		
		
 //alert("GetReferenceData.getXcoord()\nbrx, single village, Beyond 3.8.8.2 required");
		xcoord = TM_searchDOM('//table[@class="vlist"]/tbody/tr/td[@class="x"]');
		if(xcoord.snapshotItem(i)){ return xcoord; }
			
 //alert("GetReferenceData.getXcoord()\n old T3 string");
		xcoord = TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="aligned_coords"]/div[@class="cox"]');
 		if(xcoord.snapshotItem(i)){ return xcoord; }
		
 //alert("GetReferenceData.getXcoord()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		xcoord = TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="aligned_coords"]//td[@class="cox"]');
 		if(xcoord.snapshotItem(i)){ return xcoord; }
	
	

 //alert("GetReferenceData.getXcoord()\nvlistTable not found");
		return xcoord;
	
	}
	
	this.getYcoord = function(i){
	
		var ycoord=null;
		
 //alert("GetReferenceData.getycoord()\nbrx, single village, Beyond 3.8.8.2 required");
		ycoord = TM_searchDOM('//table[@class="vlist"]/tbody/tr/td[@class="y"]');
		if(ycoord.snapshotItem(i)){ return ycoord; }
			
 //alert("GetReferenceData.getycoord()\n old T3 string");
		ycoord = TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="aligned_coords"]/div[@class="coy"]');
 		if(ycoord.snapshotItem(i)){ return ycoord; }
		
 //alert("GetReferenceData.getycoord()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		ycoord = TM_searchDOM('//table[@id="vlist"]/tbody/tr/td[@class="aligned_coords"]//td[@class="coy"]');
 		if(ycoord.snapshotItem(i)){ return ycoord; }
	
	

 //alert("GetReferenceData.getycoord()\nvlistTable not found");
		return ycoord;
	
	}
	
}


function GetResourceInfo(){

	//refers to resources table, it is the horizontal list
	this.resourcesTable;

	this.activeVillage = new Village();
	


	this.get = function(){
 //alert("entering GetResourceInfo.get()");
	
		var VillageResources = new Array();


		// browses DOM for resources table (below icons)
		// that path was the only one that worked, it goes directly to resources tds, but Travian Beyond brokes it, so we must browse back to the table and find the right one
		this.resourcesTable = TM_searchDOM('//div[@id="res"]//tr/td').snapshotItem(0).parentNode.parentNode;
 //alert("this.resourcesTable = "+this.resourcesTable);
		
		var resourcesRow;
		for(var i=0;i<5;i++){
			if(  (this.resourcesTable.childNodes[i].childNodes[3].getAttribute("title")) != null  ){
				//alert("it has, break");
				resourcesRow = this.resourcesTable.childNodes[i];
				break;
			}else{
				//alert("it doesnt have, continue");
			}
		}
		this.resourcesTable=resourcesRow;
 //alert("this.resourcesTable:\n\n\n"+this.resourcesTable.innerHTML);	
	
	
	
	//ok, now this.resourcesTable has the tr with all data we need, let's gather it! :D
	this.activeVillage.id = vInfo.uniqueID + vInfo.activeVillageID;
 //alert("Active Village ID:\n"+this.activeVillage.id);
	
	this.activeVillage.resProduction.wood = parseInt(this.resourcesTable.childNodes[3].getAttribute("title"));
 //alert("this.activeVillage.resProduction.wood = "+this.activeVillage.resProduction.wood);
	this.activeVillage.resProduction.clay = parseInt(this.resourcesTable.childNodes[7].getAttribute("title"));
 //alert("this.activeVillage.resProduction.clay = "+this.activeVillage.resProduction.clay);
	this.activeVillage.resProduction.iron = parseInt(this.resourcesTable.childNodes[11].getAttribute("title"));
 //alert("this.activeVillage.resProduction.iron = "+this.activeVillage.resProduction.iron);
	this.activeVillage.resProduction.crop = parseInt(this.resourcesTable.childNodes[15].getAttribute("title"));
 //alert("this.activeVillage.resProduction.crop = "+this.activeVillage.resProduction.crop);
	
	
	//production is ready, now let's go to stock and capacity
	var stockcapacityRaw = "";
	var stockcapacity = "";
	
	stockcapacityRaw = this.resourcesTable.childNodes[3].innerHTML;
	stockcapacity = stockcapacityRaw.split("/");
		this.activeVillage.resStock.wood = parseInt(stockcapacity[0]);
		this.activeVillage.resCapacity.warehouse = parseInt(stockcapacity[1]);
		
	stockcapacityRaw = this.resourcesTable.childNodes[7].innerHTML;
	stockcapacity = stockcapacityRaw.split("/");
		this.activeVillage.resStock.clay = parseInt(stockcapacity[0]);
		
	stockcapacityRaw = this.resourcesTable.childNodes[11].innerHTML;
	stockcapacity = stockcapacityRaw.split("/");
		this.activeVillage.resStock.iron = parseInt(stockcapacity[0]);
		
	stockcapacityRaw = this.resourcesTable.childNodes[15].innerHTML;
	stockcapacity = stockcapacityRaw.split("/");
		this.activeVillage.resStock.crop = parseInt(stockcapacity[0]);
		this.activeVillage.resCapacity.granary = parseInt(stockcapacity[1]);
  
	
	this.activeVillage.lastUpdated=getCurrentTime();
  
  //alert("Active village info:\n\n"+this.activeVillage);
	
	
	
	
	//we did it!! now we must store it inside GreaseMonkey to make it persistent
 //alert(vInfo.uniqueID);
	
 //alert(this.activeVillage);
	var tempdata = this.activeVillage.storeData();
 //alert(tempdata);
 //alert(this.activeVillage);
 //this.activeVillage.resStock.wood=-10; this.activeVillage.resProduction.wood=-10; this.activeVillage.resCapacity.warehouse=-10;
 //alert(this.activeVillage);
//	this.activeVillage.loadData();
 //alert(this.activeVillage);
	
	
	}



}


function GetBuildInfo(){

	this.villageResourcesLayout;// = new VillageResourcesLayout(vInfo.activeVillageIndex);
	this.villageBuildingsLayout;// = new VillageBuildingsLayoutvInfo.activeVillageIndex);
	
	////this.resourcesFieldMap stores resources map, which has each field name, level, URL, etc
	this.resourcesFieldMap;
	
	//this.buildingsMap stores buildings map, which has each buildings name, level, URL, etc
	this.buildingsMap;


	this.get = function(){
 //alert("entering GetBuildInfo.get()");
 //alert("vInfo.activeVillageIndex: "+vInfo.activeVillageIndex);
	
		this.villageResourcesLayout = new VillageResourcesLayout(vInfo.activeVillageIndex);
		this.villageBuildingsLayout = new VillageBuildingsLayout(vInfo.activeVillageIndex);
 		
		//var ResourceIdentifiers = [2,3,14,15]; // wood/iron/crop/clay These are the build spots that are always the same regardless of village fields (4446,5346,9,15 cropper etc.)
		var ResourceIdentifiers = [2,15,3,14]; // wood/clay/iron/crop These are the build spots that are always the same regardless of village fields (4446,5346,9,15 cropper etc.)
		
		//old SS1
		this.resourcesFieldMap = TM_searchDOM('//map[@name="rx"]//area');
 //alert('this.resourcesFieldMap.snapshotItem(0):\n'+this.resourcesFieldMap.snapshotItem(0));
 //alert('this.resourcesFieldMap.snapshotLength: '+this.resourcesFieldMap.snapshotLength);
	
		//if the map is found (if we are on dorf1.php page), browse it and gather all info
		if (this.resourcesFieldMap.snapshotItem(0)) {

		
			//this code searches each kind of resource field, its objective is get their names to be able, using the strings created here, to identify later which is the resource type of each field
			for (var i=0 ; i < this.resourcesFieldMap.snapshotLength - 1; i++) {	
				for (var j=0 ; j < ResourceIdentifiers.length; j++)  {	
					if(i == ResourceIdentifiers[j]){	
 //alert("i="+i+"  j="+j);
					
					//ResourceIdentifiers stores part of resource fields names
					ResourceIdentifiers[j] = this.resourcesFieldMap.snapshotItem(i).getAttribute("title").slice(0,8);
 //alert("ResourceIdentifiers["+j+"]: "+ResourceIdentifiers[j]);
					}
				}
			}
			// if iron is clay 4,5,3,6 village fix
			if(ResourceIdentifiers[2]==ResourceIdentifiers[1]){ResourceIdentifiers[2]=this.resourcesFieldMap.snapshotItem(10).getAttribute("title").slice(0,8);}
 //alert("ResourceIdentifiers ok");
 //alert("ResourceIdentifiers:\n"+ResourceIdentifiers);
			
			
			// here we will loop thru all resource fields, and get position, lvl, name and type of each one
			for (var i=0 ; i < this.resourcesFieldMap.snapshotLength - 1; i++) {
				this.villageResourcesLayout.list[i].position=i+1;
			
				var xTITLE = this.resourcesFieldMap.snapshotItem(i).getAttribute("title");
				var ResourceIdentifier = xTITLE.slice(0,8);
 //alert("i="+i+"    xTITLE: "+xTITLE);
 //alert("ResourceIdentifier: "+ResourceIdentifier);

				
				this.villageResourcesLayout.list[i].setLvl( /(\d+)/.exec(xTITLE)[0] );
 //alert("this.villageResourcesLayout.list["+i+"].lvl = "+this.villageResourcesLayout.list[i].lvl);
 //alert("raw title:\n"+/(\d+)/.exec(xTITLE));
				
				this.villageResourcesLayout.list[i].name = /([^]*)\s[^]+\s\d+$/.exec(xTITLE)[1];
 //alert("this.villageResourcesLayout.list["+i+"].name = "+this.villageResourcesLayout.list[i].name);

//				if (this.villageResourcesLayout.list[i].lvl){
					if(ResourceIdentifier == ResourceIdentifiers[0]){this.villageResourcesLayout.list[i].type = 'g1';}
					if(ResourceIdentifier == ResourceIdentifiers[1]){this.villageResourcesLayout.list[i].type = 'g2';}
					if(ResourceIdentifier == ResourceIdentifiers[2]){this.villageResourcesLayout.list[i].type = 'g3';}
					if(ResourceIdentifier == ResourceIdentifiers[3]){this.villageResourcesLayout.list[i].type = 'g4';}
/*				}else{
					//VillageLayout[i] = (i+1) + '/g00/0/NULL';
					this.villageResourcesLayout.list[i].position=i+1;
					this.villageResourcesLayout.list[i].setLvl(0);
					this.villageResourcesLayout.list[i].type='g00';
					this.villageResourcesLayout.list[i].name="NULL";
				}
*/
 //alert("this.villageResourcesLayout.list["+i+"]:\n"+this.villageResourcesLayout.list[i]+"\n\n\n"+this.villageResourcesLayout.list[i].merge());
				
			}
			
			//var GMvalue = this.villageResourcesLayout.merge();
			//GM_setValue(this.villageResourcesLayout.getVillageResourcesLayoutID(),this.villageResourcesLayout.merge());
			var GMvalue = this.villageResourcesLayout.storeData();
 //alert("GMvalue:\n"+this.villageResourcesLayout.getVillageResourcesLayoutID()+"\n\n\n"+GMvalue);
 //this.villageResourcesLayout.loadData();
 //alert("this.villageResourcesLayout:\n\n"+this.villageResourcesLayout);
 //alert("Village resource fields layout data stored on GreaseMonkey database");
 
/*
this.villageResourcesLayout.list[5].position=30;
this.villageResourcesLayout.list[5].setLvl(30);
this.villageResourcesLayout.list[5].type='g0';
this.villageResourcesLayout.list[5].name="fake field!!!";
alert("this.villageResourcesLayout changes:\n\n"+this.villageResourcesLayout);
//this.villageResourcesLayout.parse(GM_getValue(this.villageResourcesLayout.getVillageResourcesLayoutID()));
this.villageResourcesLayout.loadData();
alert("this.villageResourcesLayout fixed:\n\n"+this.villageResourcesLayout);
*/
			
		}

		
		
		
		//ok the code until here was related to dorf1.php to gather resource fields data, now we will go to dorf2.php and gather buildings data
		
		//old SS1 (the same variable as before, it was used twice in the function)
		this.buildingsMap = TM_searchDOM('//map[@name="map2"]//area');
 //alert("this.buildingsMap.snapshotItem(0): "+this.buildingsMap.snapshotItem(0));
 //alert('this.buildingsMap.snapshotLength: '+this.buildingsMap.snapshotLength);
	
		//same as before, if the map is found (inside dorf2.php), browse it and gather all info
		if (this.buildingsMap.snapshotItem(0)) {
			

		
			//here in the old plugin it used to have a code with variable SS2 to get buildings pictures, but it seems that at some point (probably with T3.5), everything started using the same path "img/x.gif" and this wasn't possible anymore
		
 //alert("this.buildingsMap.snapshotLength: "+this.buildingsMap.snapshotLength);
			for ( var i=0 ; i < this.buildingsMap.snapshotLength-2; i++ ) { //  -2 because of duplicate earth walls!! total 22 slots
			
				this.villageBuildingsLayout.list[i].position=i+19;
				this.villageBuildingsLayout.list[i].type="g9";

				//xTITLE receives each building title property, which stores their name and lvl
				var xTITLE = this.buildingsMap.snapshotItem(i).getAttribute("title");
 //alert('i='+i+'   xTITLE = '+xTITLE);
 
 
				var rawLvl = /(\d+)/.exec(xTITLE);
				if(rawLvl != null){
					this.villageBuildingsLayout.list[i].setLvl( rawLvl[1] );
				}else{
					this.villageBuildingsLayout.list[i].setLvl(0);
				}
 //alert('this.villageBuildingsLayout.list['+i+'].lvl = '+this.villageBuildingsLayout.list[i].lvl);
 
				if (this.villageBuildingsLayout.list[i].lvl>0){

					var buildingName = /([^]*)\s[^]+\s\d+$/.exec(xTITLE);	// still not quite right, but close
					if(buildingName==null){
						this.villageBuildingsLayout.list[i].name = xTITLE;
					}else{
						this.villageBuildingsLayout.list[i].name = buildingName[1];
					}
				
				}else{
					this.villageBuildingsLayout.list[i].type="g00";
					this.villageBuildingsLayout.list[i].name="NULL";
				}
 //alert('this.villageBuildingsLayout.list[i].name = '+this.villageBuildingsLayout.list[i].name);

 //alert('this.villageBuildingsLayout.list['+i+']:\n\n'+this.villageBuildingsLayout.list[i]);

			}
		
			var GMvalue=this.villageBuildingsLayout.storeData();
 //this.villageBuildingsLayout.loadData();
 //alert("this.villageBuildingsLayout:\n\n"+this.villageBuildingsLayout);
			
/*			
alert(GMvalue);
this.villageBuildingsLayout.list[5].position=30;
this.villageBuildingsLayout.list[5].setLvl(30);
this.villageBuildingsLayout.list[5].name="fake building!!";
alert("changed building:\n\n"+this.villageBuildingsLayout);
this.villageBuildingsLayout.loadData();
alert("fixed building:\n\n"+this.villageBuildingsLayout);
*/
		
		}
		
		
/*
alert("ok");		
 this.villageResourcesLayout.loadData();
alert(this.villageResourcesLayout);
 this.villageBuildingsLayout.loadData();
alert(this.villageBuildingsLayout);
 */
 
	}

	
	
}


function AddListener(){


	// this.clock refers to all images with a clock, this image is generally on upgrade pages
	// these pages are each resource field/building page, where we see its info and have the option to upgrade it
	// on these pages there is also this clock image and on its right we will have the upgrade duration time
	// a clock is necessary for any timed event addition. so far.
	this.clock;
	
	this.clockCount = 0;

	//this.links stores all links on the page
	this.links;
	
	// this.eventType stores if we are dealing with a resource field or a building
	// 1: resource field (Dorf1)
	// 2: building (Dorf2)
	this.eventType;
	
	// this.layout stores a resource field or a building layout, depending on the type of structure page we are on
	this.layout;
	
	//a construction info, got from Dorf layouts
	this.eventInfo;



	this.get = function(){
 //alert("entering AddListener.get()");
 //allVillagesEvents.purge();
 //alert(allVillagesEvents);
		
		this.clock = this.getClock();
 //alert("this.clock.snapshotItem(0):\n"+this.clock.snapshotItem(0));
 
		if(this.clock){
 
			var clockCount=0;
			var evt = new Event();
		
			//old SS1
			this.links = TM_searchDOM('//a[@href]');
 //alert("links: "+this.links.snapshotLength);
			
			for(var i=0;i<this.links.snapshotLength;i++){
				
				//old xA
				var currentLink = this.links.snapshotItem(i);
			
			
				// Upgrade existing building links.
				// these links are found when we enter on an existing construction's page, and we have enought resources to upgrade it
				// this will be the link to upgrade the construction
				// old X
				var upgradeLink = /\?a=(\d+)&c=/.exec(currentLink.getAttribute("href"));
			
				if(upgradeLink){
 //alert("i="+i+"    upgradeLink(case1)= "+upgradeLink);
				
					var buildSport = upgradeLink[1];
					
					if(buildSport<19){
						this.eventType = 1;
						this.layout = new VillageResourcesLayout(vInfo.activeVillageIndex);
					}else{
						this.eventType = 2;
						this.layout = new VillageBuildingsLayout(vInfo.activeVillageIndex);
					}
 //alert("this.eventType = "+this.eventType);
					
					var err = this.layout.loadData();
					if(!err){	// possibility this doesn't exist yet, if not give warning that event wil not be recorded
						var warn = addDiv('TMWarn' + i,'TMmain','I do not know this village yet.<br>' +
						'Please go to <a href="dorf1.php">your fields<a/> and <a href="dorf2.php"> your village</a> 1st.<br>' + 
						'You only need this once so I know what is built.',false);
						warn.style.right = '25px';
 //alert("this.layout with error:\n\n"+this.layout);
						return;
					}
 //alert("this.layout:\n\n"+this.layout);
 //alert("this.layout.count="+this.layout.count);
		 
					
					//the following code gets a whole resource field/building layout
					//it loops throu each structure looking for the structure whose position matches with BuildSpot
					//then it stores this structure data array into eventInfo

					for(var j=0;j<this.layout.count;j++){
						if(this.layout.list[j].position==buildSport){
							this.eventInfo=this.layout.list[j];
						}
					}
 //this.eventInfo.position=30;
 //alert("eventInfo:\n\n"+this.eventInfo);
	 
				
					
					evt = new Event();
					evt.type=this.eventType;
					evt.setUnformattedDuration(this.clock.snapshotItem(this.clock.snapshotLength-1).nextSibling.nodeValue);  // should be last clock on the page. maybe.
					evt.structure=this.eventInfo;
					
					
					function innerCreateUpgradeEvent(){
						evt.start=getCurrentTime()+5;
						allVillagesEvents.addNewEvent(evt);
					}

 //alert(evt);
 //innerCreateUpgradeEvent();
 //alert(allVillagesEvents);

					
					// upgrade link: the link to upgrade the building
					currentLink.addEventListener('click', innerCreateUpgradeEvent, true);
				
				}
			
			
				// Construct new building links.
				// these links are found when we enter on a unconstructed zone's page, available to construcing new buildings/fields
				//there may be many of these links on those pages, there is one link for each building available to be newly constructed
				// the following code loops thru all those links and add a listener to each of them, so that if the user decided to build a new building, modkit creates an event for it
				var newConstructionLink = /\?a=(\d+)&id=\d+&c=/.exec(currentLink.getAttribute("href"));
				if(newConstructionLink){
 //alert("i="+i+"    newConstructionLink= "+newConstructionLink);
				
					evt = new Event();
					evt.type=2;
					evt.setUnformattedDuration(this.clock.snapshotItem(clockCount).nextSibling.nodeValue);
					
					var constr = new Construction();
					constr.position=newConstructionLink[1];
					constr.type="g9";
					constr.lvl=0;
 //alert("building name:\n\n"+currentLink.parentNode.parentNode.parentNode.parentNode.previousSibling.previousSibling.innerHTML);
					constr.name=currentLink.parentNode.parentNode.parentNode.parentNode.previousSibling.previousSibling.innerHTML;

					evt.structure=constr;
					
					//we created the event that will be added to allVillagesEvents, but now we must pass it into innerCreateConstructionEvent
					//so we will merge it into a string and add it as a currentLink attribute, so that we can parse it back and get the event inside innerCreateConstructionEvent
					var strEvent=evt.merge();
 //alert("strEvent:\n"+strEvent);
					currentLink.setAttribute('TMEvent20',strEvent);
					
				
					function innerCreateConstructionEvent(){
					
						var localEvent=new Event();
						localEvent.parse(this.getAttribute('TMEvent20'));
 //alert("AddListener.get().innerCreateConstructionEvent() has run\ncurrentLink: "+currentLink+"\n\n"+localEvent);
						
						localEvent.start=getCurrentTime()+5;
						allVillagesEvents.addNewEvent(localEvent);
					
					}
					
					// upgrade link: the link to upgrade the building
					currentLink.addEventListener('click', innerCreateConstructionEvent, true);
					
				
					clockCount++;
				
				}
			
			}
		
			this.eventType=0;
 //alert("this.eventType: "+this.eventType);
		
			// The following snapshot appears on BARRACKS, STABLE, ARMORY, BLACKSMITH, ACADEMY, MARKET, TOWNHALL, and I assume Great Barracks and Great Stable
			// THIS CODE IS BUGGED INSIDE MARCKET
			this.links = TM_searchDOM('//input[@name="id"]');
 //alert(this.links.snapshotLength+" troops links found");
			if(this.links.snapshotItem(0)){
			
				// this holds our building spot
				var buildID = this.links.snapshotItem(0).getAttribute("value");
 //alert("buildID: "+buildID);	
			
				// we have a record of what is built there
				this.layout=new VillageBuildingsLayout(vInfo.activeVillageIndex);
				this.layout.loadData();						//this may return invalid data if we haven't read village layout yet
 //alert(this.layout);
				for(var i=0;i<this.layout.count;i++){
 					if(this.layout.list[i].position==buildID){
							if (this.layout.list[i].type == 'g19'){this.eventType = 3;} // g19 is barracks (not implemented yet)
							if (this.layout.list[i].type == 'g20'){this.eventType = 4;} // g20 is stable	 (not implemented yet)
					}
				}
 //alert("this.eventType: "+this.eventType);
				
				// only interested in barracks and stable at the moment
				// this is related to troops training
				if (this.eventType == 3 || this.eventType == 4){
				/*
					//this input is the button to train troops
					this.links = TM_searchDOM('//input[@name="s1"]');
					var xINPUT = this.links.snapshotItem(0);
				*/
					
					
				
				
				
				}
			
			
			
			}
		
	
		} //end clocks    if(this.clock)
 //alert("ok after clock");
		


		// special case demolish building, no timer until next page.
		var demolish=this.getDemolishTable();
		if(demolish.snapshotLength>0){
 //alert(allVillagesEvents);
			demolish=demolish.snapshotItem(0);
 //alert(demolish.innerHTML);

			
/* old code, it used to create a button to add demolish event manually, I left it as a code exemple
			var addBtn = addImg(false,false,Xadd,false);
			addBtn.style.cursor='pointer';
			
			addBtn.addEventListener('click', function() {
  
				var table=this.parentNode.parentNode.parentNode.firstChild;
				var buildingName = table.childNodes[3].innerHTML.replace(/^\s+|\s+$/g,"");	//replace is used to trim the string
				var timeleft = table.childNodes[5].childNodes[1].innerHTML;
				
				var evt=new Event();
				evt.type=5;
				evt.start=getCurrentTime();
				evt.setUnformattedDuration(timeleft);

				evt.structure.position=19;
				evt.structure.type="g9";
				evt.structure.setLvl(/(\d+)/.exec(buildingName)[1]);
				evt.structure.name=/([^]*)\s[^]+\s/.exec(buildingName)[1];
 //alert(evt);				
				allVillagesEvents.addNewEvent(evt);
 //alert(allVillagesEvents);
			
			}, true);
		
			var TR=document.createElement('TR');
			demolish.appendChild(TR);
			
			var TD=document.createElement('TD');
			TR.appendChild(TD);
			TD=document.createElement('TD');
			TR.appendChild(TD);
			TD=document.createElement('TD');
			TR.appendChild(TD);
			TD.appendChild(addBtn);
*/
			
 			
			// if demolish was found, it means there is something being demolished, so let's update it on event list
			// first we must remove it in case it is already there
			allVillagesEvents.removeDemolishEvent();
 //alert("demolish event removed");
 
			// now we can add it
			//var table=this.parentNode.parentNode.parentNode.firstChild;
			var table=demolish.firstChild;
			var buildingName = table.childNodes[3].innerHTML.replace(/^\s+|\s+$/g,"");	//replace is used to trim the string
			
			var timeleft = table.childNodes[5].childNodes[1].innerHTML;
			if(!timeleft) timeleft = table.childNodes[5].childNodes[0].innerHTML;
 //alert("variables gathered");
 //alert("table: "+table.innerHTML);
 //alert("buildingName: "+buildingName);
 //alert("timeleft: "+timeleft);
 //alert(table.childNodes[5].childNodes[1].innerHTML);
			
			var evt=new Event();
			evt.type=3;
			evt.start=getCurrentTime();
			evt.setUnformattedDuration(timeleft);
 //alert(evt);

			evt.structure.position=19;		//invalid data, to get correct position use <select class="dropdown" name="abriss"> values
			evt.structure.type="g9";
			evt.structure.setLvl(/(\d+)/.exec(buildingName)[1]);
			evt.structure.name="(demolish) "+/([^]*)\s[^]+\s/.exec(buildingName)[1];
 //alert(evt);			
			allVillagesEvents.addNewEvent(evt);
 //alert(allVillagesEvents);
			
		
		}
		
		
		demolish=this.getDemolishSelect();
		if(demolish.snapshotLength>0){
 //alert(demolish.snapshotItem(0).innerHTML);
 
		//if it was found, it means there is no demolition ocurring, meaning that or it was never initiated at all, or user just cancelled it
		//in any case, let's remove any demolition even there may exist for this village and move on
		allVillagesEvents.removeDemolishEvent();
 //alert(allVillagesEvents);
 
		}
	
	
	
/* Events refreshing

The following code is related to that + sign that is added on the side of construction on Dorf1 and Dorf1

Timers currently work this way:
- they are shared among troops movements and buildings
- all of them have that string showing its time left, and it is rounded by a span
- if there is only 1 of them (1 troop or 1 building), the span has id="timer1" regardless of what it is
- if there are 2 of them, with any combination, 1st building (the one that will complete fastest) will have id="timer1", and the other, being it another (roman) building or any troop, it will have id="timer2"
- if there are 2 roman buildings, the fastest will be timer1 and the other will be timer2, and any troop movement will have timer3 and so on

Here what we want is buildings, so we will look for timer1 and timer2
Since there may be 2 buildings and their code is the same, let's put it inside a method and call it twice

*/
	
		this.refreshEvent(1);
		this.refreshEvent(2);
	

	
	
	
		
		// now we go to brand new events, first one is Blacksmith and Armoury troops upgrades and Town Hall celebrations
		this.registerBmArm();
	
		// Barrack, Stable and Workshop trainings
		this.registerTrain();
	
		//troops & mercants movements
		this.registerMovements();
	
	
	
//if(allVillagesEvents.count()>0){
 //alert(allVillagesEvents);
//}
 //alert(allVillagesEvents.count()+"\n\n"+allVillagesEvents);
	
	}



	this.refreshEvent = function(timerNumber){
	
		var timerQuery='//table[@id="building_contract"]//span[@id="timer1"]';
		if(timerNumber==2) timerQuery='//table[@id="building_contract"]//span[@id="timer2"]';
	
		var buildingTimer = TM_searchDOM(timerQuery);
		if(buildingTimer.snapshotItem(0)){
 //alert(buildingTimer.snapshotItem(0).innerHTML);
 
			if (/dorf/.exec(window.location.href)){
 
				var fullName = buildingTimer.snapshotItem(0).parentNode.previousSibling.innerHTML;
				var constructName = /([^]*)\s[^]+\s/.exec(fullName)[1];
				var baseName = fullName.slice(0,5);
 //+alert("fullName: "+fullName+"\nconstructName: "+constructName+"\nbaseName: "+baseName);
				var level = parseInt(/(\d+)/.exec(buildingTimer.snapshotItem(0).parentNode.previousSibling.innerHTML)[1])-1;
 //alert("level: "+level);
 
 
 				function innerUpdateit(){
				
					allVillagesEvents.loadData();
					var eventIndex=allVillagesEvents.villages[vInfo.activeVillageIndex].findEvent(baseName);
 //alert("eventIndex: "+eventIndex);
 //alert("events BEFORE updating:\n\n"+allVillagesEvents);
 
					if(eventIndex>=0){	//event exists, let's update it
						allVillagesEvents.villages[vInfo.activeVillageIndex].events[eventIndex].structure.lvl=level;
						allVillagesEvents.villages[vInfo.activeVillageIndex].events[eventIndex].start=getCurrentTime();
						allVillagesEvents.villages[vInfo.activeVillageIndex].events[eventIndex].setUnformattedDuration(buildingTimer.snapshotItem(0).innerHTML);
						allVillagesEvents.villages[vInfo.activeVillageIndex].storeData();
 //alert(allVillagesEvents.villages[vInfo.activeVillageIndex]);
					}else{		// well, event is not known yet, we may have lost its creation, or it may be troops timer
						var evt=new Event();
						evt.start=getCurrentTime();
						evt.setUnformattedDuration(buildingTimer.snapshotItem(0).innerHTML);
						evt.structure.lvl=level;
						
						switch(constructName){
							case xLang['Wood Field']:
							
								evt.type=1;
								evt.structure.position=1;	//invalid data
								evt.structure.type="g1";
							
								break;
							case xLang['Clay Field']:
							
								evt.type=1;
								evt.structure.position=1;	//invalid data
								evt.structure.type="g2";
							
								break;
							case xLang['Iron Field']:
							
								evt.type=1;
								evt.structure.position=1;	//invalid data
								evt.structure.type="g3";
							
								break;
							case xLang['Crop Field']:
							
								evt.type=1;
								evt.structure.position=1;	//invalid data
								evt.structure.type="g4";
							
								break;
							default:
						
								evt.type=2;
								evt.structure.position=18;	//invalid data
								evt.structure.type="g9";
						
						}
						
						

						
 //alert(evt);
						evt.structure.name=constructName;
 //alert(evt);
						
						allVillagesEvents.addNewEvent(evt);

					}
					
					showEvents.buildEventsTable(false);
					//window.location.href = window.location.href;
				
 //allVillagesEvents.loadData();				
 //alert("events AFTER updating:\n\n"+allVillagesEvents);
 
				}
				
				
				var imgAdd = addImg(false,false,Xadd,false);
				imgAdd.style.cursor='pointer';
				imgAdd.style.left='3px';
				imgAdd.addEventListener('click', innerUpdateit, true);
				buildingTimer.snapshotItem(0).parentNode.appendChild(imgAdd);
				
			
			}
		}
	
	}
	
	
	// Blacksmith, Armoury, and also Town Hall celebrations
	// there is no way (it seems) to distinguish these 3 buildgings, so I'll leave them all sharing the same event type
	this.registerBmArm = function(){
 //alert("entering AddListener.registerBmArm()");
	
		var baUpgrades = this.getBmArmTable();
 //alert("baUpgrades: "+baUpgrades);
		if(baUpgrades){
 
			for(var i=0;i<baUpgrades.length;i++){
 //alert("baUpgrades["+i+"]: "+baUpgrades[i]);
		
				if(baUpgrades[i].upgradeLink){
					var evt = new Event();
					evt.type=4;
					evt.duration=baUpgrades[i].duration;

					var element = new MiscElement();
					element.element=baUpgrades[i].troopName+" (upgrd)";
					evt.structure=element;
 //alert("original event: "+evt+"\n\nmerged event: "+evt.merge());
				
					//we created the event that will be added to allVillagesEvents, but now we must pass it into innerCreateConstructionEvent
					//so we will merge it into a string and add it as a currentLink attribute, so that we can parse it back and get the event inside innerCreateConstructionEvent
					var strEvent=evt.merge();
 //alert("strEvent:\n"+strEvent);
					baUpgrades[i].upgradeLink.setAttribute('TMEvent20',strEvent);
					
				
					function innerBmArmEvent(){

						var localEvent=new Event();
						localEvent.parse(this.getAttribute('TMEvent20'));
 //alert("AddListener.registerBmArm().innerBmArmEvent() has run\nupgradeLink: "+baUpgrades[i].upgradeLink+"\n\n"+localEvent);
					
						localEvent.start=getCurrentTime()+5;
						allVillagesEvents.addNewEvent(localEvent);
						showEvents.buildEventsTable(false);

					}
				
					// upgrade link: the link to upgrade the building
					baUpgrades[i].upgradeLink.addEventListener('click', innerBmArmEvent, true);
				}
				
			
/*
//this code is to test the event, it simulates first link being clicked
if(i==0){
var localEvent=new Event();
localEvent.parse(baUpgrades[i].upgradeLink.getAttribute('TMEvent20'));
localEvent.start=getCurrentTime()+5;
allVillagesEvents.addNewEvent(localEvent);
alert(allVillagesEvents);
}
*/
		
		
			}
			
			
	
			var baProgress = this.getBmArmProgress();
 //alert("baProgress: "+baProgress);
			if(baProgress){
			
				function innerBaUpdate(){
 //alert("entering innerBaUpdate()");
			
					var evt = new Event();
					evt.type=4;
					evt.duration=baProgress.duration;
					evt.start=getCurrentTime();

					var element = new MiscElement();
					element.element=baProgress.troopName+" (upgrd)";
					evt.structure=element;
 //alert(evt);
 
					allVillagesEvents.addNewEvent(evt);
					showEvents.buildEventsTable(false);
				
				}
		
		
		
		
				var imgAdd = addImg(false,false,Xadd,false);
				imgAdd.style.cursor='pointer';
				imgAdd.style.left='3px';
				imgAdd.addEventListener('click', innerBaUpdate, true);
				baProgress.upgradeLink.appendChild(imgAdd);
			
			
			}
		
	
			
		}
	
	
	
	
		
		
		
		
		
	
	
	}
	
	// Barrack, Stable and Workshop trainings
	this.registerTrain = function(){
 //alert("entering AddListener.registerTrain()");
	
		var trainTable = this.getTrainTable();
 //alert("trainTable:\n\n"+trainTable);
  
		if(!trainTable) return;
	
	
		// verify if there is anything being trained
		// if nothing was found training, skip update and go on
		if(trainTable.isTraining){
 //alert("entering if(trainTable.isTraining)");
			
		
			// get all training events for current village
			allVillagesEvents.loadData();
/*
			var events=allVillagesEvents.villages[vInfo.activeVillageIndex].getEventOfType(5);
 //alert("events: "+events.length);
			
			// see if this building is logged
			var trainEvent=-1;
			for(var i=0;i<events.length;i++){
				if(allVillagesEvents.villages[vInfo.activeVillageIndex].events[events[i]].structure.name==trainTable.building){
					trainEvent=i;
					break;
				}
			}
 //alert("trainEvent: "+trainEvent);

			
		
			// if nothing was found, this building is training but user doesn't want it logged, go on
			// if building was found, update it without waiting for user intervation (automatically to user)
			if(trainEvent>-1){
				allVillagesEvents.villages[vInfo.activeVillageIndex].removeEvent(trainEvent);
 //alert(allVillagesEvents);
 */
 
 
			// if nothing was found, this building is training but user doesn't want it logged, go on
			// if building was found, update it without waiting for user intervation (automatically to user)
			var eventIsLogged = allVillagesEvents.villages[vInfo.activeVillageIndex].removeTrainingEvents(trainTable.building);
			
			if(eventIsLogged){
 
				
				var evt=new Event();
				evt.type=5;
				evt.start=getCurrentTime();
				evt.duration=trainTable.duration;
				
				var trainStructure=new Training();
				trainStructure.name=trainTable.building;
				trainStructure.troopName=trainTable.troopName;
				evt.structure=trainStructure;
 //alert("evt: "+evt);
 
				allVillagesEvents.addNewEvent(evt);
 //alert(allVillagesEvents);
				//showEvents.buildEventsTable(false);		// DON'T print events table now, showEvents is not ready yet!!
			}
		
		
		
		

			// now let's use a Xadd listerner
			// this listener must remove any event there may exist, create a new one and add it
			// user should need it only in case it removed this building event earlier and wants to add it again
			// but in case any bug happened, it can be used to flosh any training event from this building and add a brand new one
		
			function innerTrainingAdd(){
 //alert("entering AddListener.registerTrain().innerTrainingAdd()");

			
				allVillagesEvents.loadData();
/*
				var events=allVillagesEvents.villages[vInfo.activeVillageIndex].getEventOfType(5);
 //alert("events: "+events.length);
 
				var trainEvent=-1;
				for(var i=0;i<events.length;i++){
					if(allVillagesEvents.villages[vInfo.activeVillageIndex].events[events[i]].structure.name==trainTable.building){
						trainEvent=i;
						break;
					}
				}
 //alert("trainEvent: "+trainEvent);
 
				if(trainEvent>-1)
					allVillagesEvents.villages[vInfo.activeVillageIndex].removeEvent(trainEvent);
 //alert(allVillagesEvents);
*/

				allVillagesEvents.villages[vInfo.activeVillageIndex].removeTrainingEvents(trainTable.building);

				var evt=new Event();
				evt.type=5;
				evt.start=getCurrentTime();
				evt.duration=trainTable.duration;
				
				var trainStructure=new Training();
				trainStructure.name=trainTable.building;
				trainStructure.troopName=trainTable.troopName;
				evt.structure=trainStructure;
 //alert("evt: "+evt);
 
				allVillagesEvents.addNewEvent(evt);
 //alert(allVillagesEvents);
				showEvents.buildEventsTable(false);
				
		
		

			}
			
			var imgAdd = addImg(false,false,Xadd,false);
			imgAdd.style.cursor='pointer';
			imgAdd.style.left='3px';
			imgAdd.addEventListener('click', innerTrainingAdd, true);
			trainTable.addCell.appendChild(imgAdd);
		
		
		}else{	// if(trainTable.isTraining)
	
			// ok, we already dealt with any training that may have been found
			// now we'll deal with train button, adding a listener to track new trainings
		
			// tracking train button when there are troops being trained is not needed because they will be updated automatically anyway
			// but if there is nothing being trained and user clicks train button, it is probable that he added troops, so we must start logging it
			
			
			function innerTrainBtn(){
			
				allVillagesEvents.loadData();
/*
				var events=allVillagesEvents.villages[vInfo.activeVillageIndex].getEventOfType(5);
 //alert("events: "+events.length);
				
				var trainEvent=-1;
				for(var i=0;i<events.length;i++){
					if(allVillagesEvents.villages[vInfo.activeVillageIndex].events[events[i]].structure.name==trainTable.building){
						trainEvent=i;
						break;
					}
				}
 //alert("trainEvent: "+trainEvent);
 
				if(trainEvent>-1)
					allVillagesEvents.villages[vInfo.activeVillageIndex].removeEvent(trainEvent);
*/
				allVillagesEvents.villages[vInfo.activeVillageIndex].removeTrainingEvents(trainTable.building);

				var evt=new Event();
				evt.type=5;
				evt.start=getCurrentTime();
				evt.duration=-1;
				
				var trainStructure=new Training();
				trainStructure.name=trainTable.building;
				trainStructure.troopName=trainTable.troopName;
				evt.structure=trainStructure;
 //alert("evt: "+evt);
 
				allVillagesEvents.addNewEvent(evt);
 //alert(allVillagesEvents);
				//showEvents.buildEventsTable(false);
				
				
				// note that this added event is not a valid event, it has duration = -1
				// it is just a flag, to inform that a building that wasn't training (probably) started training now
				// with this flag, on next reload ModKit will update this invalid event to a valid one based on the under_progress table that will be available then
			
			}
			
			trainTable.btnLink.addEventListener('click', innerTrainBtn, true);
			
			
			
			// but this leaves us with an issues
			// if user clicks the train button without selecting any troop to be training and there is nothing being trained, this new event will be added,
			//		but on next reload there will be nothing being trained to update, and he will have a new and already expired event to remove
			
			// to avoid this, we must track train btn clicks that result in no trainings starting
			// the flag for this is the evt.duration = -1, if there is no training AND there is an event with negative duration, we just remove it automatically
			
			allVillagesEvents.loadData();
				var events=allVillagesEvents.villages[vInfo.activeVillageIndex].getEventOfType(5);
 //alert("events: "+events.length);
			
			var trainEvent=-1;
			for(var i=0;i<events.length;i++){
				if(allVillagesEvents.villages[vInfo.activeVillageIndex].events[events[i]].structure.name==trainTable.building
							&& allVillagesEvents.villages[vInfo.activeVillageIndex].events[events[i]].duration < 0){
					trainEvent=i;
					break;
				}
			}
 //alert("trainEvent: "+trainEvent);
 
			if(trainEvent>-1)
				allVillagesEvents.villages[vInfo.activeVillageIndex].removeEvent(trainEvent);
		
		
		}
		



		
		



	
	
	
	
	}
	
	this.registerMovements = function(){
 //alert("entering AddListener.registerMovements()");
 
	
				function innerMovement(){
 //alert("entering innerMovement()");
			
					var evt = new Event();
					evt.parse(this.getAttribute("TMEvent"));
 //alert(evt);
 
					allVillagesEvents.addNewEvent(evt);
					showEvents.buildEventsTable(false);
				
				}
	
	
	
		var mercant=this.getMercant();
 //alert("mercant:\n\n"+mercant);
 
		if(mercant){
			for(var i=0;i<mercant.length;i++){
			
				var element=new MiscElement();
				element.element=mercant[i].name;
				
				var evt=new Event();
				evt.type=6;
				evt.start=mercant[i].start;
				evt.setUnformattedDuration(mercant[i].time);
				evt.structure=element;
 //alert(evt);
			
				var imgAdd = addImg(false,false,Xadd,false);
				imgAdd.style.cursor='pointer';
				imgAdd.style.left='3px';
				imgAdd.setAttribute("TMEvent",evt.merge());
			
		
				imgAdd.addEventListener('click', innerMovement, true);
				mercant[i].cell.appendChild(imgAdd);
			
			}
		}
		
		
		
		
		
		var troops=this.getTroopMovement();
 //alert("troops:\n\n"+troops);
 
		if(troops){
			for(var i=0;i<troops.length;i++){
			
				var element=new MiscElement();
				element.element=troops[i].name;
				
				var evt=new Event();
				evt.type=6;
				evt.start=troops[i].start;
				evt.setUnformattedDuration(troops[i].time);
				evt.structure=element;
 //alert(evt);
			
				var imgAdd = addImg(false,false,Xadd,false);
				imgAdd.style.cursor='pointer';
				imgAdd.style.left='3px';
				imgAdd.setAttribute("TMEvent",evt.merge());
			
		
				imgAdd.addEventListener('click', innerMovement, true);
				troops[i].cell.appendChild(imgAdd);
			
			}
		}
	
	
	
	}
	
	
	

	// getClock() tries to find images with a clock, this image is generally on upgrade pages
	// these pages are each resource field/building page, where we see its info and have the option to upgrade it
	// on these pages there is also this clock image and on its right we will have the upgrade duration time
	this.getClock = function(){
	
		var clock=null;
		
		clock=TM_searchDOM('//img[@class="clock"]');
		if(clock.snapshotItem(0)){ return clock; }
		
		
		return clock;
	
	}
	
	this.getDemolishTable = function(){
 //alert("entering AddListener.getDemolishTable()");
	
		var demolish=null;
		
		demolish=TM_searchDOM('//table[@id="demolish"]/tbody');
		if(demolish.snapshotLength>0){ return demolish; }
	
	
		return demolish;
	
	}
	
	this.getDemolishSelect = function(){
	
		var demolish=null;
		
		demolish=TM_searchDOM('//select[@name="abriss"]');
		if(demolish.snapshotLength>0){ return demolish; }
	
	
		return demolish;
	
	}
	
	
	this.getBmArmTable = function(){
 //alert("entering AddListener.getBmArmTable()");
	
		// if a train button is found, we are inside a Barrack/Stable/Workshop page, and not inside BlackSmith/Armoury
		// both type of pages have the same HTML table structures, but only Barrack/Stable/Workshop pages have the train button
		// then, if the train button is found, we are on the wrong place, so let's just leave
		var trainBtn = TM_searchDOM('//input[@id="btn_train"]');
 //alert("trainBtn: "+trainBtn.snapshotLength);
		if(trainBtn.snapshotLength>0) return null;
	
	
		// ok, there is no train button, now we see if table is found
		// this page is used later, so we must check first if we are on the correct table, even if there is no upgrade link available
		// if we are on the wrong page (train button is found or table is not found), we return null
		// else, if we are on the right page but anything else is not found, we return an empty array, reporting it is the right page but no upgrade data was found
		var buildDetailsTable = TM_searchDOM('//table[@class="build_details"]');
 //alert("buildDetailsTable: "+buildDetailsTable.snapshotLength);
		if(buildDetailsTable.snapshotLength<=0) return null;
	
	
	
	
	
	
		// there are some rows that don't have upgrade links, this can be due of lack of resources for upgrading, because the buildings needs to be upgraded first or because this troop is fully upgraded
		// since we only want available upgrades, first we find these upgrade links, then we browse back to their tr node and gether the other stuff
	
		upgradeLink = TM_searchDOM('//table[@class="build_details"]/tbody/tr/td[@class="act"]/a');
 //alert("upgradeLink: "+upgradeLink.snapshotLength);
 //alert("upgradeLink: "+upgradeLink.snapshotItem(0).childNodes[0]);
		if(upgradeLink.snapshotLength<=0) return new Array();
	


	
	
	
		var bmArmList = new Array();
		
		for(var i=0;i<upgradeLink.snapshotLength;i++){
			var bmArm = new BmArmTable();

			bmArm.upgradeLink=upgradeLink.snapshotItem(i);
			
			var troopRow = bmArm.upgradeLink.parentNode.parentNode;
 //alert("troopRow i="+i+":\n\n"+troopRow.innerHTML);


 
			var troopName = TM_searchNode(troopRow,'td[@class="desc"]/div[@class="tit"]/a');
 //alert("troopName: "+troopName.snapshotLength);
 //alert("troopName: "+troopName.snapshotItem(0).innerHTML);
			if(troopName.snapshotLength<=0) return new Array();
			
			var lvl = TM_searchNode(troopRow,'td[@class="desc"]/div[@class="tit"]/span');
 //alert("lvl: "+lvl.snapshotLength);
 //alert("lvl: "+lvl.snapshotItem(0).innerHTML);
			if(lvl.snapshotLength<=0) return new Array();
	
	
			var duration = TM_searchNode(troopRow,'td[@class="desc"]/div[@class="details"]/span[5]');
 //alert("duration: "+duration.snapshotLength);
 //alert("duration: "+duration.snapshotItem(0).childNodes[1].nodeValue);
			if(duration.snapshotLength<=0) return new Array();
			
			
			
			
			
			bmArm.troopName=troopName.snapshotItem(0).innerHTML;
			bmArm.lvl=parseInt(/(\d+)/.exec(lvl.snapshotItem(0).innerHTML)[0])+1;
			bmArm.setUnformattedDuration(duration.snapshotItem(0).childNodes[1].nodeValue);

		
 //alert("bmArm: "+bmArm);
			bmArmList[bmArmList.length] = bmArm;
		
		}
		
 //alert("bmArmList:\n\n"+bmArmList);
	
	
	
		return bmArmList;
	
	
	
	
	}
	
	this.getBmArmProgress = function(){
 //alert("entering AddListener.getBmArmProgress()");
	
	
		var troopName = TM_searchDOM('//table[@class="under_progress"]/tbody/tr/td[@class="desc"]');
 //alert("troopName: "+troopName.snapshotLength);
 //alert("troopName: "+troopName.snapshotItem(0).innerHTML);
 //alert("troopName: "+trim(troopName.snapshotItem(0).childNodes[2].nodeValue));
		if(troopName.snapshotLength<=0) return null;
		
		
		
		var duration = TM_searchDOM('//table[@class="under_progress"]/tbody/tr/td[@class="dur"]/span');
 //alert("duration: "+duration.snapshotLength);
 //alert("duration: "+duration.snapshotItem(0).innerHTML);
		if(duration.snapshotLength<=0) return null;
		
		var upgradeLink = TM_searchDOM('//table[@class="under_progress"]/tbody/tr/td[@class="dur"]');
 //alert("upgradeLink: "+upgradeLink.snapshotLength);
 //alert("upgradeLink: "+upgradeLink.snapshotItem(0).innerHTML);
		if(upgradeLink.snapshotLength<=0) return null;
	
	
	
		var bmArm = new BmArmTable();
 //alert("raw bmArm: "+bmArm);

 		// although the under_progress table is the same for Blacksmith, Armoury and Town Hall,
		// BM and Arm shows a pic together with the name, while TH shows only a raw name
		// because of that we must deal with this detail separately
 
		// if we find more than 1 node inside troop cell, we skip pic node and get only the name
		// and if we don't find this extra node, so we are on TH, then we just get the only node available
		if(troopName.snapshotItem(0).childNodes[2]){
			bmArm.troopName=trim(troopName.snapshotItem(0).childNodes[2].nodeValue);
		}else{
			bmArm.troopName=troopName.snapshotItem(0).innerHTML;
		}
		//bmArm.troopName=trim(troopName.snapshotItem(0).childNodes[2].nodeValue);
		//bmArm.troopName=troopName.snapshotItem(0).innerHTML;
		
		
		bmArm.setUnformattedDuration(duration.snapshotItem(0).innerHTML);
		bmArm.upgradeLink=upgradeLink.snapshotItem(0);		// upgradeLink is being used to get the element (duration td) where Xadd will be added
	
 //alert("filled bmArm: "+bmArm);
		return bmArm;
	
	}
	
	

	// AddListener.getTrainTable() works inside Barrack, Stable and  Workshop buildings
	// it searches for the train button, if it is not found we are not on any of these buildings and it returns
	// if it is found, there are 2 possibilities: there is some troop being trained, or there is nothing being trained ATM
	
	// if there is nothing being trained, training.isTraining is set false and training is returned almost empty (and all empty values must be ignored)
	// if under_progress table is found, its last row t(he last training troop) is gathered and returned
	this.getTrainTable = function(){
 //alert("entering AddListener.getTrainTable()");
	
		var trainBtn = TM_searchDOM('//input[@id="btn_train"]');
 //alert("trainBtn: "+trainBtn.snapshotLength);
		if(trainBtn.snapshotLength<1) return null;
	
		var building = TM_searchDOM('//h1');
 //alert("building length: "+building.snapshotLength);
 //alert("building: "+building.snapshotItem(0).innerHTML);
 //alert("building final: "+/([^]*)\s[^]+\s\d+$/.exec(building.snapshotItem(0).innerHTML)[1]);
	
		var troopName = TM_searchDOM('//table[@class="under_progress"]/tbody/tr[last()-1]/td[@class="desc"]');
 //alert("troopName length: "+troopName.snapshotLength);
 //alert("troopName: "+troopName.snapshotItem(0).innerHTML);
	
		var duration = TM_searchDOM('//table[@class="under_progress"]/tbody/tr[last()-1]/td[@class="dur"]/span');
 //alert("duration length: "+duration.snapshotLength);
 //alert("duration: "+duration.snapshotItem(0).innerHTML);
		
		var finCell = TM_searchDOM('//table[@class="under_progress"]/tbody/tr[last()-1]/td[@class="fin"]');
 //alert("finCell length: "+finCell.snapshotLength);
 //alert("finCell: "+finCell.snapshotItem(0).innerHTML);
	
	
	
	
		var training = new TrainTable();
 //alert("raw training:\n\n"+training);
 
		training.btnLink = trainBtn.snapshotItem(0);
		training.building = /([^]*)\s[^]+\s\d+$/.exec(building.snapshotItem(0).innerHTML)[1];
		
		if(troopName.snapshotLength>0){
			training.isTraining=true;
			training.troopName = troopName.snapshotItem(0).innerHTML;
			training.setUnformattedDuration(duration.snapshotItem(0).innerHTML);
			training.addCell=finCell.snapshotItem(0);
		}else{
			training.isTraining=false;
		}
	

 //alert("filled training:\n\n"+training);
		return training;
	
	}
	
	
	this.getMercant = function(){
 //alert("entering AddListener.getMercant()");
 
 
	var mercantTime = TM_searchDOM('//table[@class="traders"]//div[@class="in"]/span');
 //alert("mercantTime: "+mercantTime.snapshotLength);
 //alert("mercantTime: "+mercantTime.snapshotItem(0).innerHTML);
		if(mercantTime.snapshotLength<1) return null;
		
	var mercantCell = TM_searchDOM('//table[@class="traders"]//div[@class="in"]');
 //alert("mercantCell: "+mercantCell.snapshotLength);
 //alert("mercantCell: "+mercantCell.snapshotItem(0).innerHTML);
		if(mercantCell.snapshotLength<1) return null;
		
	var mercantDesc = TM_searchDOM('//table[@class="traders"]/thead/tr/td[2]/a[1]');
 //alert("mercantDesc: "+mercantDesc.snapshotLength);
 //alert("mercantDesc: "+mercantDesc.snapshotItem(0).innerHTML);
		if(mercantDesc.snapshotLength<1) return null;
	
 
		
		var mercant = new Array();
		for(var i=0;i<mercantCell.snapshotLength;i++){
		
			var move=new Movement();
			
			move.name=mercantDesc.snapshotItem(i).innerHTML.substring(0,25);
			move.time=mercantTime.snapshotItem(i).innerHTML;
			move.cell=mercantCell.snapshotItem(i);
			move.start=getCurrentTime();
		
			mercant.push(move);
		}
 
 //alert("mercant:\n\n"+mercant);
 
		return mercant;
 
 
	
	
	
	}
	
	this.getTroopMovement = function(){
 //alert("entering AddListener.getTroopMovement()");
 
	// these tables are inside Rally Point page
	// they currently may have 2 class values: 'in small' for troops recently sent and that can still be brought back, and 'in' for troops that can't come back anymore
	// due to that we must make 2 searches
 
 
	var troopTime = TM_searchDOM('//table[@class="troop_details"]//div[@class="in"]/span');
 //alert("troopTime: "+troopTime.snapshotLength);
 //alert("troopTime: "+troopTime.snapshotItem(0).innerHTML);
 
	var troopTimeNew = TM_searchDOM('//table[@class="troop_details"]//div[@class="in small"]/span');
 //alert("troopTimeNew: "+troopTimeNew.snapshotLength);
 //alert("troopTimeNew: "+troopTimeNew.snapshotItem(0).innerHTML);
 
		if( (troopTime.snapshotLength + troopTimeNew.snapshotLength) <1) return null;
		
		
 		
		

	
 
		
		var troop = new Array();
		for(var i=0;i<troopTime.snapshotLength;i++){
			var move=new Movement();
			
			move.time=troopTime.snapshotItem(i).innerHTML;
			move.start=getCurrentTime();
			move.cell=troopTime.snapshotItem(i).parentNode;
			
			var table=troopTime.snapshotItem(i).parentNode.parentNode.parentNode.parentNode.parentNode;
 //alert("table i="+i+":\n\n\n"+table.innerHTML);
 
			var name=table.childNodes[1].childNodes[1].childNodes[2].childNodes[0];
 //alert("name:\n\n"+name.innerHTML);
 
			move.name=name.innerHTML;
			
 //alert(move);
			
			troop.push(move);
			
		}
		
		
		for(var i=0;i<troopTimeNew.snapshotLength;i++){
			var move=new Movement();
			
			move.time=troopTimeNew.snapshotItem(i).innerHTML;
			move.start=getCurrentTime();
			move.cell=troopTimeNew.snapshotItem(i).parentNode;
			
			var table=troopTimeNew.snapshotItem(i).parentNode.parentNode.parentNode.parentNode.parentNode;
 //alert("table i="+i+":\n\n\n"+table.innerHTML);
 
			var name=table.childNodes[1].childNodes[1].childNodes[2].childNodes[0];
 //alert("name:\n\n"+name.innerHTML);
 
			move.name=name.innerHTML;
			
 //alert(move);
			
			troop.push(move);
			
		}
		
		
		
		
 
 //alert("troop:\n\n"+troop);
 
		return troop;
 
 
	
	
	
	}
	
	
	
	
	
}











































































































































































































































































































































































































































































//=================================
// View (presents/prints info to the user)

// ›› Show total Village resource production, overlayed over left menu bar.
function ShowTotalProduction(){

	//div that stores left table with general resources info
	this.generalDiv;
	
	//div that stores villages table, on the right
	//this.villagesDiv;
	
	//villages table's HTML code
	this.villagesTable;

	//div where tables' divs are attached into
	this.attachDiv = 'side_navi';
	
	


	this.show = function(){
 //alert("entering ShowTotalProduction.show()");
	


		vInfo.reloadData();
 //alert(vInfo);



 //alert('ok after resources, before table');
		var generalProdHTML =  '<table width="100%" cellpadding="4" cellspacing="0" border="0">' +
					'<tr><td colspan=2 class="TTitle">' + vInfo.count + ' Villages</td></tr>';

				generalProdHTML += '<tr><td colspan=2 class="TTitle">++ Production</td></tr>' + 
				'<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.totalProduction.woodf() +  '</td></tr>' +
				'<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.totalProduction.clayf() +  '</td></tr>' +
				'<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.totalProduction.ironf() +  '</td></tr>' +
				'<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.totalProduction.cropf() +  '</td></tr>' +
				'<tr><td colspan=2 class="TTitle">++ Resources</td></tr>' + 
				'<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.totalStock.woodf() + '</td></tr>' +
				'<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.totalStock.clayf() + '</td></tr>' +
				'<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.totalStock.ironf() + '</td></tr>' +
				'<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.totalStock.cropf() + '</td></tr>' +
				'<tr><td colspan=2 class="TTitle">++ Storage</td></tr>' +
				'<tr class="TClayBack"><td><span style="font-size:0.8em;">Warehouse</span></td><td class="right">' + vInfo.totalCapacity.warehousef() + '</td></tr>' +
				'<tr class="TCropBack"><td>Granary</td><td class="right">' + vInfo.totalCapacity.granaryf() + '</td></tr>' +
				'<tr><td colspan=2 class="TTitle">++ Filled</td></tr>' + 
				'<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.totalFilled.wood.toFixed(0) + '%</td></tr>' +
				'<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.totalFilled.clay.toFixed(0) + '%</td></tr>' +
				'<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.totalFilled.iron.toFixed(0) + '%</td></tr>' +
				'<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.totalFilled.crop.toFixed(0) + '%</td></tr>' +
				'<tr><td colspan=2 class="TTitle">Production Factor</td></tr>' + 
				'<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.productionFactor.woodf() + '</td></tr>' +
				'<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.productionFactor.clayf() + '</td></tr>' +
				'<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.productionFactor.ironf() + '</td></tr>' +
				'<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.productionFactor.cropf() + '</td></tr>' +
				
				'</table>';

				
				
	var generalProdPosRaw=GM_getValue(vInfo.uniqueID+"DragWin.generalProd");
	var generalProdPosTop="95px";
	var generalProdPosLeft="0px";
	if(generalProdPosRaw){
		generalProdPosSplit=generalProdPosRaw.split(":");
		generalProdPosTop=generalProdPosSplit[0];
		generalProdPosLeft=generalProdPosSplit[1];
	}else{
		GM_setValue(vInfo.uniqueID+"DragWin.generalProd",generalProdPosTop+":"+generalProdPosLeft);
	}
				
	var body, generalProdWin, generalProdTitlebar, generalProdtiTlehead,generalProdContent,
				generalProdStatusbar, generalProdAclose, generalProdAhide, generalProdAminimax;
	body = document.getElementsByTagName('body')[0];
	
	generalProdWin = document.createElement('DIV');
	generalProdWin.id='generalProd';
	generalProdWin.className='DW_window';
	generalProdWin.style.width="140px";
	generalProdWin.style.top=generalProdPosTop;
	generalProdWin.style.left=generalProdPosLeft;
	
	generalProdTitlebar = document.createElement('DIV');
	generalProdTitlebar.className='titlebar';
	generalProdWin.appendChild(generalProdTitlebar);
	
	generalProdtiTlehead = document.createElement('H2');
	generalProdtiTlehead.innerHTML='General';
	generalProdTitlebar.appendChild(generalProdtiTlehead);
	
	generalProdAclose = document.createElement('A');
	generalProdAclose.title="Close";
	generalProdAclose.id="close";
	generalProdAclose.addEventListener('mouseup', function(){ DW_closeWindow(generalProdAclose);  }, false);
	generalProdAclose.innerHTML='x';
	generalProdTitlebar.appendChild(generalProdAclose);
/*
	generalProdAhide = document.createElement('A');
	generalProdAhide.title="Hide";
	generalProdAhide.id="hide";
	generalProdAhide.addEventListener('mouseup', function(){ DW_hideWindow(generalProdAhide);  }, false);
	generalProdAhide.innerHTML='^';
	generalProdTitlebar.appendChild(generalProdAhide);
*/
	generalProdAminimax = document.createElement('A');
	generalProdAminimax.title="Minimize";
	generalProdAminimax.id="minimax";
	generalProdAminimax.addEventListener('mouseup', function(){ DW_minimax(generalProdAminimax);  }, false);
	generalProdAminimax.innerHTML='-';
	generalProdTitlebar.appendChild(generalProdAminimax);
	
	
	
	
	generalProdContent = document.createElement('DIV');
	generalProdContent.className='content';
	generalProdWin.appendChild(generalProdContent);
	
	generalProdStatusbar = document.createElement('DIV');
	generalProdStatusbar.className='statusbar';
	generalProdStatusbar.innerHTML='statusbar .:';
	generalProdWin.appendChild(generalProdStatusbar);

	
	
	
	generalProdContent.innerHTML = generalProdHTML;
	body.appendChild(generalProdWin);
	generalProdWin.addEventListener('mousedown', function(){ DW_startDrag(generalProdWin);  }, false);
	generalProdWin.addEventListener('mouseup', DW_stopDrag, false);

	generalProdWin.addEventListener('mousemove', function(event) { DW_moving(event); }, false);
				
	
	// we just created the window, it is not minimized ATM
	// but if it should be, we call the function to minimize it
	if(DW_isMinimized(generalProdWin)){
		DW_setMinimized(generalProdAminimax,true);
	}
	
	// we also must check if it should be closed, closing it if that's the case
	if(DW_isClosed(generalProdWin)){
		DW_closeWindow(generalProdAclose);
	}
				
				
				
				
		//this.generalDiv = addDiv('TMleftmenu','TMleftmenu',HTML,this.attachDiv);
		//this.generalDiv.addEventListener('click', function() {
			//this.parentNode.removeChild(this);}, true);
			
 //alert("ok after table 1");
			
			
			
			
			
			
			
			
			
	var villagesDataPosRaw=GM_getValue(vInfo.uniqueID+"DragWin.villagesData");
	var villagesDataPosTop="29px";
	var villagesDataPosLeft=(document.body.clientWidth-164)+"px";
	if(villagesDataPosRaw){
		villagesDataPosSplit=villagesDataPosRaw.split(":");
		villagesDataPosTop=villagesDataPosSplit[0];
		villagesDataPosLeft=villagesDataPosSplit[1];
	}else{
		GM_setValue(vInfo.uniqueID+"DragWin.villagesData",villagesDataPosTop+":"+villagesDataPosLeft);
	}
				
	var body, villagesDataWin, villagesDataTitlebar, villagesDatatiTlehead,villagesDataContent,
				villagesDataStatusbar, villagesDataAclose, villagesDataAhide, villagesDataAminimax;
	body = document.getElementsByTagName('body')[0];
	
	villagesDataWin = document.createElement('DIV');
	villagesDataWin.id='villagesData';
	villagesDataWin.className='DW_window';
	villagesDataWin.style.width="160px";
	villagesDataWin.style.top=villagesDataPosTop;
	villagesDataWin.style.left=villagesDataPosLeft;
	
	villagesDataTitlebar = document.createElement('DIV');
	villagesDataTitlebar.className='titlebar';
	villagesDataWin.appendChild(villagesDataTitlebar);
	
	villagesDatatiTlehead = document.createElement('H2');
	villagesDatatiTlehead.innerHTML='Villages';
	villagesDataTitlebar.appendChild(villagesDatatiTlehead);
	
	villagesDataAclose = document.createElement('A');
	villagesDataAclose.title="Close";
	villagesDataAclose.id="close";
	villagesDataAclose.addEventListener('mouseup', function(){ DW_closeWindow(villagesDataAclose);  }, false);
	villagesDataAclose.innerHTML='x';
	villagesDataTitlebar.appendChild(villagesDataAclose);
/*
	villagesDataAhide = document.createElement('A');
	villagesDataAhide.title="Hide";
	villagesDataAhide.id="hide";
	villagesDataAhide.addEventListener('mouseup', function(){ DW_hideWindow(villagesDataAhide);  }, false);
	villagesDataAhide.innerHTML='^';
	villagesDataTitlebar.appendChild(villagesDataAhide);
*/
	villagesDataAminimax = document.createElement('A');
	villagesDataAminimax.title="Minimize";
	villagesDataAminimax.id="minimax";
	villagesDataAminimax.addEventListener('mouseup', function(){ DW_minimax(villagesDataAminimax);  }, false);
	villagesDataAminimax.innerHTML='-';
	villagesDataTitlebar.appendChild(villagesDataAminimax);
	
	
	
	
	villagesDataContent = document.createElement('DIV');
	villagesDataContent.className='content';
	villagesDataWin.appendChild(villagesDataContent);
	
	villagesDataStatusbar = document.createElement('DIV');
	villagesDataStatusbar.className='statusbar';
	villagesDataStatusbar.innerHTML='statusbar .:';
	villagesDataWin.appendChild(villagesDataStatusbar);
	
	


			

		//this.villagesDiv = addDiv('VillagesTable','TMleftmenu',this.villagesTable,this.attachDiv);
		//this.villagesDiv.style.left = villagesTableLeftCoord;
		//var villagesDiv;
		var villagesTable =  "";
		//villagesDiv = addDiv('HikariMenu','TMleftmenu',villagesTable,this.attachDiv);
		//villagesDiv.style.left = villagesTableLeftCoord;
 //alert("villagesTable instantiation ok");

		villagesDataContent.addEventListener('click', function() {
		
			switch(vInfo.getTableStatus()){
				case 1:

					vInfo.setTableStatus(2);
					editVillagesTable();
					break;
				case 2:
				
					vInfo.setTableStatus(3);
					editVillagesTable();
					break;
				case 3:
					
					vInfo.setTableStatus(4);
					editVillagesTable();
					break;
				case 4:
					
					vInfo.setTableStatus(8);
					editVillagesTable();
					break;
					
					
					
					
				case 8:
					if(debugMode){
						vInfo.setTableStatus(1);	// change to 9 if status 9 is desired
						editVillagesTable();
						break;
					}
				case 9:
					
					vInfo.setTableStatus(1);
					editVillagesTable();
					break;				
				default:
					vInfo.setTableStatus(1);
					editVillagesTable();
			}
		}, true);
		
	/*
		Status info:
		status 1: showns stock, but only if it is above vInfo.maxcap
		status 2: percentage filled
		status 3: free available space on warehouse/granary
		
		status 8: debug, last time each village was visited
		status 9: only table title shown
	*/

		
		
	function editVillagesTable(){
 //alert("entering ShowTotalProduction.show().editVillagesTable()");

			switch(vInfo.getTableStatus()){
				case 1:
					villagesDataStatusbar.innerHTML='overflowing .:1';
					break;
				case 2:
					villagesDataStatusbar.innerHTML='current stock .:2';
					break;
				case 3:
					villagesDataStatusbar.innerHTML='stock percentage .:3';
					break;
				case 4:
					villagesDataStatusbar.innerHTML='free available space .:4';
					break;
					
					
					
					
				case 8:
					villagesDataStatusbar.innerHTML='last visited .:8';
					break;
				case 9:
					villagesDataStatusbar.innerHTML='nothing shown .:9';
					break;				
				default:
					villagesDataStatusbar.innerHTML='statusbar .:';
			}
 
 
		villagesTable =  '<table width="100%" cellpadding="4" cellspacing="0" border="0">';
		//+ '<tr><td colspan="2" class="TTitle">&nbsp;</td></tr>';
 //alert(vInfo.getTableStatus());

 
 //villagesTable += '<tr><td colspan=2 class="TTitle">'+ 'testing' + '</td></tr>';

 
		for (var i = 0; i < vInfo.count; i++){

			if(vInfo.getTableStatus()!=9){


			
		//			villagesTable += '<tr><td colspan=2 class="TTitle">++ Village '+ (i+1) +'</td></tr>' +

				
				if(vInfo.getTableStatus()==3){
					villagesTable += '<tr><td colspan=2 class="TTitle">'+ vInfo.vList[i].name + '</td></tr>';
					villagesTable += '<tr style="background:#AAAAAA;"><td>Warehouse </td><td class="right">' + vInfo.vList[i].resCapacity.warehousef() + '</td></tr>';
					villagesTable += '<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.vList[i].resFilled.wood.toFixed(0) + '%</td></tr>';
					villagesTable += '<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.vList[i].resFilled.clay.toFixed(0) + '%</td></tr>';
					villagesTable += '<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.vList[i].resFilled.iron.toFixed(0) + '%</td></tr>';
					villagesTable += '<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.vList[i].resFilled.crop.toFixed(0) + '%</td></tr>';
				}else if(vInfo.getTableStatus()==4){
					villagesTable += '<tr><td colspan=2 class="TTitle">'+ vInfo.vList[i].name + '</td></tr>';
					villagesTable += '<tr style="background:#AAAAAA;"><td>Warehouse </td><td class="right">' + vInfo.vList[i].resCapacity.warehousef() + '</td></tr>';
					villagesTable += '<tr class="TWoodBack"><td>Wood</td><td class="right">-' + vInfo.vList[i].resLeft.woodf() + '</td></tr>';
					villagesTable += '<tr class="TClayBack"><td>Clay</td><td class="right">-' + vInfo.vList[i].resLeft.clayf() + '</td></tr>';
					villagesTable += '<tr class="TIronBack"><td>Iron</td><td class="right">-' + vInfo.vList[i].resLeft.ironf() + '</td></tr>';
					villagesTable += '<tr class="TCropBack"><td>Crop</td><td class="right">-' + vInfo.vList[i].resLeft.cropf() + '</td></tr>';
					villagesTable += '<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.vList[i].resFilled.crop.toFixed(0) + '%</td></tr>';
				}else if(vInfo.getTableStatus()==8){
					villagesTable += '<tr><td colspan=2 class="TTitle">'+ vInfo.vList[i].name + '</td></tr>';
					villagesTable += '<tr style="background:#AAAAAA;"><td class="center">'+vInfo.vList[i].getLastUpdatedAgo(true)+'</td></tr>';
				
				
				}else{	// if ==2
					if(vInfo.vList[i].resFull.any || vInfo.vList[i].resFull.crop || vInfo.getTableStatus()==2) villagesTable += '<tr><td colspan=2 class="TTitle">'+ vInfo.vList[i].name + '</td></tr>';
					if(vInfo.vList[i].resFull.any || vInfo.getTableStatus()==2) villagesTable += '<tr style="background:#AAAAAA;"><td>Warehouse </td><td class="right">' + vInfo.vList[i].resCapacity.warehousef() + '</td></tr>';
					if(vInfo.vList[i].resFull.wood || vInfo.getTableStatus()==2) villagesTable += '<tr class="TWoodBack"><td>Wood</td><td class="right">' + vInfo.vList[i].getCurrentStockWood(true) + '</td></tr>';
					if(vInfo.vList[i].resFull.clay || vInfo.getTableStatus()==2) villagesTable += '<tr class="TClayBack"><td>Clay</td><td class="right">' + vInfo.vList[i].getCurrentStockClay(true) + '</td></tr>';
					if(vInfo.vList[i].resFull.iron || vInfo.getTableStatus()==2) villagesTable += '<tr class="TIronBack"><td>Iron</td><td class="right">' + vInfo.vList[i].getCurrentStockIron(true) + '</td></tr>';
					if(vInfo.vList[i].resFull.crop || vInfo.getTableStatus()==2) villagesTable += '<tr class="TCropBack"><td>Crop</td><td class="right">' + vInfo.vList[i].getCurrentStockCrop(true) + '</td></tr>';
					if(vInfo.vList[i].resFull.crop || vInfo.getTableStatus()==2) villagesTable += '<tr class="TCropBack"><td>Granary</td><td class="right">' + vInfo.vList[i].resCapacity.granaryf() + '</td></tr>';
				}
			
					
					
			}

		}


		villagesTable += '<tr><td colspan=2 class="TTitle">&nbsp;</td></tr>';
		villagesTable += '</table>';
		
		villagesDataContent.innerHTML=villagesTable;

	}

	editVillagesTable();

	


	
	
	
	villagesDataContent.innerHTML = villagesTable;
	body.appendChild(villagesDataWin);
	villagesDataTitlebar.addEventListener('mousedown', function(){ DW_startDrag(villagesDataWin);  }, false);
	villagesDataTitlebar.addEventListener('mouseup', DW_stopDrag, false);

	villagesDataTitlebar.addEventListener('mousemove', function(event) { DW_moving(event); }, false);

			
			

	// we just created the window, it is not minimized ATM
	// but if it should be, we call the function to minimize it
	if(DW_isMinimized(villagesDataWin)){
		DW_setMinimized(villagesDataAminimax,true);
	}
	
	// we also must check if it should be closed, closing it if that's the case
	if(DW_isClosed(villagesDataWin)){
		DW_closeWindow(villagesDataAclose);
	}
			
			
 //alert('ok after table 2');
 //alert(addSeparatorsNF(100000,",",",","."));
 //alert(vInfo.vList[0].resCapacity.granaryf());



	
	
	
	
	
	
	}




}



// The new ShowEvents creates a brand new table to show events to the user

// I decided to take events showing off of villages table so that we have enough free space to print anything we want
// In original ModKit, events were added into TR rows that were inserted directly into original villages table... this was nicely done
// but when we started to have dens of villages, that table grew a lot in height and it started to be hard to view all of them, and probably users end up disabling the feature

// Now, on the other hand, we have 2 tables, the original villages table (on the right of the screen), and events table, that is added to a draggable window
// original villages table is still used to show Dorf1 and Dorf2 layout status, but everything else was ported to events table
function ShowEvents(){


	this.dwEventsContent;
	this.dwEventsStatusbar;
	this.dwEventsHTML="";

	
	//refers to vlist table, it is the table on the right that lists all villages
	this.vlistTable;
	
	// old IMG
	this.images=new Array();
	
	// vLink holds the anchor that has villages names and links, this anchor was already used alot throu ModKit :P
	this.vLink=new Array();
	
	// emptyVillages stores villages that have no constructions running
	this.emptyVillages = new Array();
	
	this.dotCell = new Array();
	



	this.show = function(){
 //alert("entering ShowEvents.show()");
	
		//first we create the draggable window that will hold our events table
		this.buildWindow();
 //alert("dwWindow ok");
	
		// this query gets villages table's row, it is a xPath with an arry with a village row in each snapshotItem
		this.vlistTable=this.getVlistTable();
 //alert("villages found: "+this.vlistTable.snapshotLength);
	
		this.buildEventsTable(true);
 //alert("this.vLink: "+this.vLink);
	
	}



	this.buildWindow = function(){
	
	var dwEventsPosRaw=GM_getValue(vInfo.uniqueID+"DragWin.dwEvents");
	var dwEventsPosTop="29px";
	var dwEventsPosLeft=(document.body.clientWidth-468)+"px";
	if(dwEventsPosRaw){
		dwEventsPosSplit=dwEventsPosRaw.split(":");
		dwEventsPosTop=dwEventsPosSplit[0];
		dwEventsPosLeft=dwEventsPosSplit[1];
	}else{
		GM_setValue(vInfo.uniqueID+"DragWin.dwEvents",dwEventsPosTop+":"+dwEventsPosLeft);
	}
				
	var body, dwEventsWin, dwEventsTitlebar, dwEventstiTlehead,
				dwEventsAclose, dwEventsAhide, dwEventsAminimax;
	body = document.getElementsByTagName('body')[0];
	
	if(!dwEventsWin){
	
		dwEventsWin = document.createElement('DIV');
		dwEventsWin.id='dwEvents';
		dwEventsWin.className='DW_window';
		dwEventsWin.style.width="300px";
		dwEventsWin.style.top=dwEventsPosTop;
		dwEventsWin.style.left=dwEventsPosLeft;
		
		dwEventsTitlebar = document.createElement('DIV');
		dwEventsTitlebar.className='titlebar';
		dwEventsWin.appendChild(dwEventsTitlebar);
		
		dwEventstiTlehead = document.createElement('H2');
		dwEventstiTlehead.innerHTML='Construction Events';
		dwEventsTitlebar.appendChild(dwEventstiTlehead);
		
		dwEventsAclose = document.createElement('A');
		dwEventsAclose.title="Close";
		dwEventsAclose.id="close";
		dwEventsAclose.addEventListener('mouseup', function(){ DW_closeWindow(dwEventsAclose);  }, false);
		dwEventsAclose.innerHTML='x';
		dwEventsTitlebar.appendChild(dwEventsAclose);
	/*
		dwEventsAhide = document.createElement('A');
		dwEventsAhide.title="Hide";
		dwEventsAhide.id="hide";
		dwEventsAhide.addEventListener('mouseup', function(){ DW_hideWindow(dwEventsAhide);  }, false);
		dwEventsAhide.innerHTML='^';
		dwEventsTitlebar.appendChild(dwEventsAhide);
	*/
		dwEventsAminimax = document.createElement('A');
		dwEventsAminimax.title="Minimize";
		dwEventsAminimax.id="minimax";
		dwEventsAminimax.addEventListener('mouseup', function(){ DW_minimax(dwEventsAminimax);  }, false);
		dwEventsAminimax.innerHTML='-';
		dwEventsTitlebar.appendChild(dwEventsAminimax);
		
		
		
		
		this.dwEventsContent = document.createElement('DIV');
		this.dwEventsContent.className='content';
		dwEventsWin.appendChild(this.dwEventsContent);
		
		this.dwEventsStatusbar = document.createElement('DIV');
		this.dwEventsStatusbar.className='statusbar';
		this.dwEventsStatusbar.innerHTML='statusbar .:';
		dwEventsWin.appendChild(this.dwEventsStatusbar);

		
		
		
		this.dwEventsContent.innerHTML = this.dwEventsHTML;
		body.appendChild(dwEventsWin);
		dwEventsTitlebar.addEventListener('mousedown', function(){ DW_startDrag(dwEventsWin);  }, false);
		dwEventsTitlebar.addEventListener('mouseup', DW_stopDrag, false);

		dwEventsWin.addEventListener('mousemove', function(event) { DW_moving(event); }, false);

	}
	
	
	// we just created the window, it is not minimized ATM
	// but if it should be, we call the function to minimize it
	if(DW_isMinimized(dwEventsWin)){
		DW_setMinimized(dwEventsAminimax,true);
	}
	
	// we also must check if it should be closed, closing it if that's the case
	if(DW_isClosed(dwEventsWin)){
		DW_closeWindow(dwEventsAclose);
	}
	
	
	}
	
	this.buildEventsTable = function(printVlist){
 //alert("entering ShowEvents.buildEventsTable(), printVlist: "+printVlist);
 //alert(allVillagesEvents);
	
	
		allVillagesEvents.loadData();
 //alert(allVillagesEvents);
	
		this.dwEventsContent.innerHTML="";
 //alert("dwEventsContent is clean");
	
		// this is the begining of our events table
		var dwEventsTable =  '<div class="TMEventsWindow">';
		
		
		// we will start the table with the most worthy information: next events to expire
		// this info is in the top because when we have a lot of villages and many of them have events, the window may go very long
		// next villages info is as a short resume of the full events list, that will be printed soon
		// adding it first assures that it will be promptly visible to user on every page reload, without him having to scroll down if the window goes down the screen
		//this list must have the exact same villages as the full events list
		
		var nextEvents = allVillagesEvents.getNextEvents();
 //alert("next events: "+nextEvents.length+"\n\n"+nextEvents);
		
		if(nextEvents.length>0){
		
			//nextEvents.sort(sortNextEvents);
	
			dwEventsTable += '<div class="nextExpire"><div class="villageInfo">Next events to expire</div>';
		
	
			for(var nxevt=0;nxevt<nextEvents.length;nxevt++){
			
				var villageResourcesLayout = new VillageResourcesLayout(nextEvents[nxevt].village);
				var villageBuildingsLayout = new VillageBuildingsLayout(nextEvents[nxevt].village);
				
				resLayoutOK 	= villageResourcesLayout.loadData();
				buildLayoutOK	= villageBuildingsLayout.loadData();
				
				resDot=this.getEventDot(resLayoutOK,nextEvents[nxevt].village,new Array(-1,1));
				buildDot=this.getEventDot(buildLayoutOK,nextEvents[nxevt].village,new Array(2,3));
				var troopDot=this.getEventDot(true,nextEvents[nxevt].village,new Array(4,5));
				var moveDot=this.getEventDot(true,nextEvents[nxevt].village,new Array(-1,6));
			
				dwEventsTable += '<div class="villageEvent"><span class="floatLeft">';
			
				if (vInfo.activeVillageIndex==nextEvents[nxevt].village){
					dwEventsTable += '<img src="'+Xarrow+'"> ';
				}

				var timeleft=nextEvents[nxevt].event.getTimeLeft();
				
				dwEventsTable += '<span id="TMcooldown" timeleft="'+timeleft+'">'+formatTime(timeleft)+'</span> ';
				
				dwEventsTable += '<span class="floatLeft">';
				
					dwEventsTable += '<a href="/dorf1.php?newdid='+vInfo.rawVillageIDs[nextEvents[nxevt].village]+'" title="Resources fields status"><img title="Resources fields status" alt="o" src="'+resDot+'" /></a><a href="/dorf2.php?newdid='+vInfo.rawVillageIDs[nextEvents[nxevt].village]+'" title="Buildings & Demolish status"><img title="Buildings & Demolish status" alt="o" src="'+buildDot+'" /></a><img title="Blacksmith & Armoury upgrades, Town Hall celebrations, and Barrack, Stable & Worksop troops training" alt="o" src="'+troopDot+'" /><img title="troops & mercants movements" alt="o" src="'+moveDot+'" /></span>';
				
					dwEventsTable += '<a href="'+vInfo.vList[nextEvents[nxevt].village].link+'">'+vInfo.vList[nextEvents[nxevt].village].name+'</a>';

				dwEventsTable += '</span></div>';
			
			}

		
			dwEventsTable += '</div>';
		
		}
		
		
		
		// now we go to the full events list
		dwEventsTable += '<div class="fullEvents">';
		dwEventsTable += '<div class="villageInfo">Full events list</div>';

	
		var villagesWithEvents=0;
		this.emptyVillages = new Array();
		//var nextEvents = new Array();
	
		// [--1--] For every table row.
		for ( var i=0 ; i < this.vlistTable.snapshotLength; i++ ) {
		
			// from the beginning of the loop until vLink we'll add a pretty arrow to point to Active Village, replacing those ugly dots, and add Dorf1 and Dorf2 dots
		
			var villageRow = this.vlistTable.snapshotItem(i);
 //alert("i="+i+"    villageRow:\n"+villageRow.innerHTML);
		

 
 			// adds an arrow pointing to active village
			if(printVlist){
			
				//original dot's cell
				this.dotCell[i] = this.vlistTable.snapshotItem(i).firstChild;
 //alert("this.dotCell[i]:\n"+this.dotCell[i].innerHTML);
			
				var arrowCell = document.createElement('TD');
				if (vInfo.activeVillageIndex==i){
					arrowCell.innerHTML = '<img src="'+Xarrow+'">';
				}
			
				villageRow.insertBefore(arrowCell,this.dotCell[i]); // replace it with the arrow
			}
 

			//if(printVlist)
				//this.dotCell[i].innerHTML="";
		
			var villageResourcesLayout = new VillageResourcesLayout(i);
			var villageBuildingsLayout = new VillageBuildingsLayout(i);
			
			var resLayoutOK 	= villageResourcesLayout.loadData();
			var buildLayoutOK	= villageBuildingsLayout.loadData();
 //alert("resLayoutOK: "+resLayoutOK+"   buildLayoutOK: "+buildLayoutOK);
 
			
			var resDot=this.getEventDot(resLayoutOK,i,new Array(-1,1));
			var buildDot=this.getEventDot(buildLayoutOK,i,new Array(2,3));
			var troopDot=this.getEventDot(true,i,new Array(4,5));
			var moveDot=this.getEventDot(true,i,new Array(-1,6));
			
			
			
			this.dotCell[i].innerHTML = '<a href="/dorf1.php?newdid='+vInfo.rawVillageIDs[i]+'" title="Resources fields status"><img src="'+resDot+'" alt="o" title="Resources fields status" /></a> <a href="/dorf2.php?newdid='+vInfo.rawVillageIDs[i]+'" title="Buildings status"><img src="'+buildDot+'" alt="o" title="Buildings status" /></a>';


		
		
			// vLink holds the anchor that has villages names and links, this anchor was already used alot throu ModKit :P
			//now we'll use it once more to add village's name and link to events table, that will start being built now
			if(printVlist){
				if(this.dotCell[i].nextSibling.innerHTML)
					this.vLink[i] = this.dotCell[i].nextSibling.innerHTML;	// old HTML version
				else
					this.vLink[i] = this.dotCell[i].nextSibling.nextSibling.firstChild.innerHTML;
			}
 //alert(vLink.innerHTML);
 //alert("old vLink: "+this.dotCell[i].nextSibling.innerHTML);
 //alert("new vLink: "+this.dotCell[i].nextSibling.nextSibling.firstChild.innerHTML);
 //alert("this.vLink[i]: "+this.vLink[i]);
		
		
			
			
			// ok, we're done with original villages table, now let's build our pretty events table
			
			
			// if this village has no events, we're done
			if(allVillagesEvents.villages[i].count()>0){
		
				// if layout is unknown, leave them red (layout is priority over events), else let's use them to show event status
			
			
				//var resEtDot=this.getEventDot(resLayoutOK,i,1);
				//var buildEtDot=this.getEventDot(buildLayoutOK,i,2);
			

				
			

			
				villagesWithEvents++;
		
				dwEventsTable += '<div class="village">';
			
			
				dwEventsTable += '<div class="villageInfo">';
				
					if (vInfo.activeVillageIndex==i){
						dwEventsTable += '<img src="'+Xarrow+'"> ';
					}
			
					dwEventsTable += '<span class="floatLeft">';
					
					dwEventsTable += '<a href="/dorf1.php?newdid='+vInfo.rawVillageIDs[i]+'" title="Resources fields status"><img title="Resources fields status" alt="o" src="'+resDot+'" /></a> <a href="/dorf2.php?newdid='+vInfo.rawVillageIDs[i]+'" title="Buildings & Demolish status"><img title="Buildings & Demolish status" alt="o" src="'+buildDot+'" /></a> <img title="Blacksmith & Armoury upgrades, Town Hall celebrations, and Barrack, Stable & Worksop troops training" alt="o" src="'+troopDot+'" /> <img title="troops & mercants movements" alt="o" src="'+moveDot+'" /></span>';
					
					dwEventsTable += '<span class="floatLeft"><a href="'+vInfo.vList[i].link+'">'+vInfo.vList[i].name+'</a></span>';
			
				dwEventsTable += '</div>';
				
				var gotNextEvent=false;
				
				for(var j=0;j<allVillagesEvents.villages[i].count();j++){
				
					var timeleft=allVillagesEvents.villages[i].events[j].getTimeLeft();
					//if(timeleft<0) timeleft=0;
					
/*					if(timeleft>0 && !gotNextEvent){
						nextEvents[nextEvents.length]=new NextEvent(i,allVillagesEvents.villages[i].events[j]);
						gotNextEvent=true;
					}
*/
 //alert("nextEvents count: "+nextEvents.length);
				
					dwEventsTable += '<div class="villageEvent';
					if(timeleft<0) 	dwEventsTable += ' ExpiredEvent';
					else 			dwEventsTable += ' RunningEvent';
					dwEventsTable += ' ">';

					if(timeleft<=0){
						dwEventsTable += '<span><a id="TMRemoveEvent" village="'+i+'" event="'+j+'"><img src="'+XCancel+'" alt="X" title="This construction has finished, click to remove it from the list" /></a> </span> ';
						}
					
					dwEventsTable += '<span class="floatLeft" id="TMcooldown" timeleft="'+timeleft+'"';
					if(timeleft<0) dwEventsTable += ' yellow="true"';
					dwEventsTable += '>'+formatTime(timeleft)+'</span>'
			
					if(allVillagesEvents.villages[i].events[j].isConstructionEvent()){
						dwEventsTable += '<span class="floatLeft">'+allVillagesEvents.villages[i].events[j].structure.name+' ' +
								(allVillagesEvents.villages[i].events[j].structure.lvl+1)+'</span>';
					}else if(allVillagesEvents.villages[i].events[j].isTrainingEvent()){
						dwEventsTable += '<span class="floatLeft">'+allVillagesEvents.villages[i].events[j].structure.name+' '+allVillagesEvents.villages[i].events[j].getEndingTime()+'</span>';
					}else{
						dwEventsTable += '<span class="floatLeft">'+allVillagesEvents.villages[i].events[j].structure.element+'</span>';
					}
							
					if(timeleft>0){
						dwEventsTable += '<span class="floatLeft"><a id="TMRemoveEvent" village="'+i+'" event="'+j+'"><img src="'+XCancel+'" alt="X" title="Remove this event from list" /></a></span>';
						}
				
					dwEventsTable += '</div>';

				}
			
				dwEventsTable += '</div>';
				
			}else{
				this.emptyVillages[this.emptyVillages.length]=i;
 //alert("this.emptyVillages.length: "+this.emptyVillages.length);
			}
		
		}
		
		dwEventsTable += '</div>';
		
		

		

		
		
		// all villages with events were added, now print empty villages to make it easy to the user to know which villages are not on previous lists and may be useful to set something to construct
		if(this.emptyVillages.length>0){
		
			dwEventsTable += '<div class="emptyVillages"><div class="villageInfo">Villages with no events</div>';
		
			for(var emptyVillage=0;emptyVillage<this.emptyVillages.length;emptyVillage++){
			
				//var resEtDot=this.getEventDot(resLayoutOK,this.emptyVillages[emptyVillage],1);
				//var buildEtDot=this.getEventDot(buildLayoutOK,this.emptyVillages[emptyVillage],2);
				
				var villageResourcesLayout = new VillageResourcesLayout(this.emptyVillages[emptyVillage]);
				var villageBuildingsLayout = new VillageBuildingsLayout(this.emptyVillages[emptyVillage]);
				
				resLayoutOK 	= villageResourcesLayout.loadData();
				buildLayoutOK	= villageBuildingsLayout.loadData();
				
				resDot=this.getEventDot(resLayoutOK,this.emptyVillages[emptyVillage],new Array(-1,1));
				buildDot=this.getEventDot(buildLayoutOK,this.emptyVillages[emptyVillage],new Array(2,3));
			
				dwEventsTable += '<div class="villageEvent"><span class="floatLeft">';
			
				if (vInfo.activeVillageIndex==this.emptyVillages[emptyVillage]){
					dwEventsTable += '<img src="'+Xarrow+'"> ';
				}
				
				dwEventsTable += '<a href="/dorf1.php?newdid='+vInfo.rawVillageIDs[this.emptyVillages[emptyVillage]]+'" title="Resources fields status"><img title="Resources fields status" alt="o" src="'+resDot+'" /></a> <a href="/dorf2.php?newdid='+vInfo.rawVillageIDs[this.emptyVillages[emptyVillage]]+'" title="Buildings & Demolish status"><img title="Buildings & Demolish status" alt="o" src="'+buildDot+'" /></a></span><span class="floatLeft">';
				
				dwEventsTable += '<a href="'+vInfo.vList[this.emptyVillages[emptyVillage]].link+'">'+vInfo.vList[this.emptyVillages[emptyVillage]].name+'</a></span></div>';
			
			}
		
			dwEventsTable += '</div>';
		
		}
		

		
		
		
		
		
		dwEventsTable += '</div>';
	
	
		this.dwEventsContent.innerHTML=dwEventsTable;
		this.dwEventsStatusbar.innerHTML=allVillagesEvents.count()+" events in "+villagesWithEvents+" villages  .: ";

		addRemoveEvent();
	
	
	}
	
	
	
	//there are some event types that share the same dot, because of that 'type' must be an array
	// for dots with only 1 event type, pass an array with 1 element
	
	// in the case you (as me) want to use Array constructor inside function parameters and add only 1 element, use '-1' as another element to have 2 elements for the Array constructor
	// exemple: new Array(-1,1) if you want to pass event type 1
	// any event type <0 will be discarded
	this.getEventDot = function(layout,vindex,type){
 //alert("entering ShowEvents.getEventDot()\ntype: "+type);
	
		var dot=Xnull;	// variable created, Xnull is default
	
		for(var i=0;i<type.length;i++){
			if(type[i]<0) continue;		// trick for invalid event types <0, used to create arrays with 1 parameter
	
			if(!layout){	// if layout is unknown, change it to XRed and return
				dot=XRed;
				return dot;
			}else{				// but if layout is known, let's move on...
				if(allVillagesEvents.villages[vindex].hasEventType(type[i])){		// if required village has an event of required type, change it to Xon and move on
 //alert(vInfo.vList[i].name+" has event type 1");
					dot=Xon;
					if(allVillagesEvents.villages[vindex].hasExpiredEventOfType(type[i])){	// but wait, if it has this type of event, but it has expired, then what we want is Xdone!!
 //alert(vInfo.vList[i].name+" has expired event of type 1");
						dot=Xdone;
						return dot;
					}
				}
			}
			
		}
	
		return dot;
	}
	
	this.getVlistTable = function(){
	
		var table=null;
	
 //alert("GetReferenceData.getVlistTable()\nbrx, multiple village, Beyond 3.8.8.2 supported");
		table = TM_searchDOM('//div[@id="side_info"]/table[@id="vlist"]/tbody/tr');  // village list
		if(table.snapshotLength>0){ return table; }
	
 //alert("old version");
		table = TM_searchDOM('//div[@id="sright"]/table[@id="vlist"]/tbody/tr');  // village list
		if(table.snapshotLength>0){ return table; }
	

		return table;
	
	}
	
	
	
	

}


function ShowCPSuggestions(){

	this.dwCPSuggContent;
	this.dwCPSuggStatusbar;
	this.dwCPSuggHTML="";
	
	this.CPList;
	
	
	// these are villages table's villages names links, gathered by ShowEvents.show()
	// I'm using it by comodity, what's needed is a list of villages names with their links
	// in the future it would be nice to add them to vInfo.vList[] and create anchors manually
	// but for now, since ShowCPSuggestions is using ShowEvents.show(), it must be run before ShowCPSuggestions can be instantiated
	this.vLink=showEvents.vLink;



	this.show = function(){
 //alert("entering ShowCPSuggestions.show()");
	
		//first we create the draggable window that will hold our events table
		this.buildWindow();
 //alert("dwWindow ok");
 
 //alert("this.vLink:\n\n"+this.vLink);
 
		this.buildCPTable();
 //alert("dwCPTable ok");

 
 
 }
	
	
	



	this.buildWindow = function(){
	
		var dwCPSuggPosRaw=GM_getValue(vInfo.uniqueID+"DragWin.dwCPSugg");
		var dwCPSuggPosTop="600px";
		var dwCPSuggPosLeft="700px";
		if(dwCPSuggPosRaw){
			dwCPSuggPosSplit=dwCPSuggPosRaw.split(":");
			dwCPSuggPosTop=dwCPSuggPosSplit[0];
			dwCPSuggPosLeft=dwCPSuggPosSplit[1];
		}else{
			GM_setValue(vInfo.uniqueID+"DragWin.dwCPSugg",dwCPSuggPosTop+":"+dwCPSuggPosLeft);
		}
					
		var body, dwCPSuggWin, dwCPSuggTitlebar, dwCPSuggtiTlehead,
					dwCPSuggAclose, dwCPSuggAhide, dwCPSuggAminimax;
		body = document.getElementsByTagName('body')[0];
		
		if(!dwCPSuggWin){
		
			dwCPSuggWin = document.createElement('DIV');
			dwCPSuggWin.id='dwCPSugg';
			dwCPSuggWin.className='DW_window';
			dwCPSuggWin.style.width="500px";
			dwCPSuggWin.style.top=dwCPSuggPosTop;
			dwCPSuggWin.style.left=dwCPSuggPosLeft;
			
			dwCPSuggTitlebar = document.createElement('DIV');
			dwCPSuggTitlebar.className='titlebar';
			dwCPSuggWin.appendChild(dwCPSuggTitlebar);
			
			dwCPSuggtiTlehead = document.createElement('H2');
			dwCPSuggtiTlehead.innerHTML='CP Buildings Suggestions';
			dwCPSuggTitlebar.appendChild(dwCPSuggtiTlehead);
			
			dwCPSuggAclose = document.createElement('A');
			dwCPSuggAclose.title="Close";
			dwCPSuggAclose.id="close";
			dwCPSuggAclose.addEventListener('mouseup', function(){ DW_closeWindow(dwCPSuggAclose);  }, false);
			dwCPSuggAclose.innerHTML='x';
			dwCPSuggTitlebar.appendChild(dwCPSuggAclose);
		/*
			dwCPSuggAhide = document.createElement('A');
			dwCPSuggAhide.title="Hide";
			dwCPSuggAhide.id="hide";
			dwCPSuggAhide.addEventListener('mouseup', function(){ DW_hideWindow(dwCPSuggAhide);  }, false);
			dwCPSuggAhide.innerHTML='^';
			dwCPSuggTitlebar.appendChild(dwCPSuggAhide);
		*/
			dwCPSuggAminimax = document.createElement('A');
			dwCPSuggAminimax.title="Minimize";
			dwCPSuggAminimax.id="minimax";
			dwCPSuggAminimax.addEventListener('mouseup', function(){ DW_minimax(dwCPSuggAminimax);  }, false);
			dwCPSuggAminimax.innerHTML='-';
			dwCPSuggTitlebar.appendChild(dwCPSuggAminimax);
			
			
			
			
			this.dwCPSuggContent = document.createElement('DIV');
			this.dwCPSuggContent.className='content';
			dwCPSuggWin.appendChild(this.dwCPSuggContent);
			
			this.dwCPSuggStatusbar = document.createElement('DIV');
			this.dwCPSuggStatusbar.className='statusbar';
			this.dwCPSuggStatusbar.innerHTML='statusbar .:';
			dwCPSuggWin.appendChild(this.dwCPSuggStatusbar);

			
			
			
			this.dwCPSuggContent.innerHTML = this.dwCPSuggHTML;
			body.appendChild(dwCPSuggWin);
			dwCPSuggTitlebar.addEventListener('mousedown', function(){ DW_startDrag(dwCPSuggWin);  }, false);
			dwCPSuggTitlebar.addEventListener('mouseup', DW_stopDrag, false);

			dwCPSuggWin.addEventListener('mousemove', function(event) { DW_moving(event); }, false);

		}
		
		
		// we just created the window, it is not minimized ATM
		// but if it should be, we call the function to minimize it
		if(DW_isMinimized(dwCPSuggWin)){
			DW_setMinimized(dwCPSuggAminimax,true);
		}
		
		// we also must check if it should be closed, closing it if that's the case
		if(DW_isClosed(dwCPSuggWin)){
			DW_closeWindow(dwCPSuggAclose);
		}
	
	}

	this.buildCPTable = function(){
	
		this.dwCPSuggContent.innerHTML="";
 //alert("dwEventsContent is clean");
 
		// its parameter defines how many entries will be used for each village
		this.CPList=getCPRank(5);
 //alert("this.CPList:\n\n"+this.CPList);
 
		var cpSort=	GM_getValue(vInfo.uniqueID+"DragWin.dwCPSugg.sort");
 //alert("cpSort: "+cpSort);
		if(!cpSort){
			cpSort="efficiency";
			GM_setValue(vInfo.uniqueID+"DragWin.dwCPSugg.sort",cpSort);
		}
		
		
		this.CPList.sortBy(cpSort);
	
		// this is the begining of our events table
		var dwCPTable =  '<table width="100%" border="0" class="TMCPWindow"><tr>';

		if(cpSort=="efficiency"){
			dwCPTable += '<th>Rank</th><th>Earn</th><th>Building</th><th><a id="TMResortCP" sort="village"><img src="'+Xarrow+'" alt=">" title="Sort by village" /></a> Village</th>';
			this.dwCPSuggStatusbar.innerHTML = "sorted by Efficiency .: ";
		}else{
			dwCPTable += '<th><a id="TMResortCP" sort="efficiency"><img src="'+Xarrow+'" alt=">" title="Sort by Efficiency Rank" /></a> Rank</th><th>Earn</th><th>Building</th><th>Village</th>';
			this.dwCPSuggStatusbar.innerHTML = "sorted by Village .: ";
		}
		
		dwCPTable += '</tr>';
	
	
		for(var i=0;i<this.CPList.count();i++){
		
			dwCPTable += '<tr>';
		
				dwCPTable += '<td>'+cps[this.CPList.list[i].cpIndex].rank+'</td>';
				dwCPTable += '<td>'+cps[this.CPList.list[i].cpIndex].cp+'</td>';
				dwCPTable += '<td>'+cps[this.CPList.list[i].cpIndex].building+' '+cps[this.CPList.list[i].cpIndex].lvl+
									' <a id="TMSkipCPEntry" vid="'+vInfo.vList[this.CPList.list[i].vIndex].id+'" cpsid="'+this.CPList.list[i].cpIndex+'" ><img src="'+XCancel+'" alt="X" title="Click if you want to skip this upgrade" /></a></td>';
				dwCPTable += '<td>'+this.vLink[this.CPList.list[i].vIndex]+'</td>';
		
		
		
		
			dwCPTable += '</tr>';
		
		
		}
		
	
	
	
	
	
		dwCPTable += '<tr><td colspan="4" class="right"><a id="TMResetSkips" title="Reset CP Suggestions Skips" >Reset Skips <img src="'+XCancel+'" alt="X" title="Reset CP Suggestions Skips" /></a></td></tr>';
	
	
		dwCPTable += '</table>';
		
		this.dwCPSuggContent.innerHTML=dwCPTable;
		
		addResortCP();
	
	}
	
	
	this.resortCPTable = function(sortBy){
		if(sortBy=="efficiency"){
			GM_setValue(vInfo.uniqueID+"DragWin.dwCPSugg.sort","efficiency");
		}else{
			GM_setValue(vInfo.uniqueID+"DragWin.dwCPSugg.sort","village");
		}
		
		showCPSuggestions.buildCPTable();
	}
	

}





/*
Prefs info: everything known about each option

- Prefs[0]:
	. it can be '0' or 'M'
	.  it is related to MM[0] menu, which has '[]' text
	. 0 makes it red background, M makes it green
	
- Prefs[ 1 to 4 ]:
	. they can be '0' or '1'
	. they are related to MM [ 1 to 4 ], which are 4 dots
	. 0 makes its dot green, 1 makes it red
	
- Prefs[5]:
	. it can be 0 or T
	. it is related to MM[5], which has '00:00:00', it seems this text never changes
	. 0 makes it red background, T makes it green
	
- Prefs[6]:
	. it exists, but I don't know much about it
	. it is related with villages layout not being known, when any of them is unknown it is set to '0'

*/


function CreateMenu(){



	this.show = function(){
 //alert(GM_getValue(vInfo.uniqueID+"Prefs"));
 
		var M,MENU,MM=new Array();
		M = addDiv('TMmenutrigger','TMmain','',false);
		

			M.style.backgroundColor = 'green';
			M.style.cursor = 'pointer';
			M.style.fontSize="0.5em";
			M.innerHTML="MK";
			M.addEventListener('click', function() {
 //alert("M.addEventListener");
				MENU = addDiv('TMmenu','TMmain','',false);
				MENU.style.right = "34px";
				
					MM[0] =addDiv('TMmm0','TMdisplay','Reopen Windows','TMmenu');
					MM[0].style.backgroundColor = 'green';
					MM[0].addEventListener('click', function() {
							DW_openWindows();
						}, true);
						

			
			}, true);

	
	}





}


































































































































































// Draggable Windows functions

var DW_mouseX, DW_mouseY, DW_offsetX, DW_offsetY;
var DW_id = "win1";
var DW_dragMode = false;
var DW_offsetMode = false;

function DW_selection(target, act){
	if (!act) {
		if (typeof target.onselectstart != "undefined") //IE route
			target.onselectstart = function() { return false; }
		else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
			target.style.MozUserSelect = "none";
		else //All other route (ie: Opera)
			target.onmousedown = function() { return false; }
	} else {
		if (typeof target.onselectstart != "undefined") //IE route
			target.onselectstart = function() { return true; }
		else if (typeof target.style.MozUserSelect != "undefined") //Firefox route
			target.style.MozUserSelect = "none";
		else //All other route (ie: Opera)
			target.onmousedown = function() { return true; }
	}
}

function DW_findPos(obj) {
	var left = 0;
	var top = 0;
	if (obj.offsetParent) {
		left = obj.offsetLeft;
		top = obj.offsetTop;
		while (obj = obj.offsetParent) {
			left += obj.offsetLeft;
			top += obj.offsetTop;
		}
	}
	DW_offsetX = left;
	DW_offsetY = top;
}

function DW_moving(event) {
	
	var alvo = document.getElementById(DW_id);
	
	if (document.all) {
		DW_mouseX = window.event.clientX;
		DW_mouseY = window.event.clientY;
	} else {
		DW_mouseX = event.pageX;
		DW_mouseY = event.pageY;
	}
	if (!DW_offsetMode) {
		DW_findPos(document.getElementById(DW_id));
		DW_offsetX = DW_mouseX - DW_offsetX;
		DW_offsetY = DW_mouseY - DW_offsetY;
	}
	
	 var debugPanel = document.getElementById("debug");
	if(debugPanel) debugPanel.innerHTML = "DW_mouseX: "+DW_mouseX+"<br />DW_mouseY: "+DW_mouseY+"<br />DW_offsetX: "+DW_offsetX+"<br />DW_offsetY: "+DW_offsetY+"<br />window: "+DW_id;
	
	var body = document.getElementsByTagName("body").item(0);
	if (DW_dragMode) {
		alvo.style.top = (DW_mouseY-DW_offsetY)+"px";
		alvo.style.left = (DW_mouseX-DW_offsetX)+"px";
		alvo.style.cursor = "move";
		alvo.style.opacity = 0.7;
		alvo.style.filter = "alpha(opacity=70)";
		DW_selection(body, false);
		
		GM_setValue(vInfo.uniqueID+"DragWin."+DW_id,alvo.style.top+":"+alvo.style.left);
		
	} else {
		alvo.style.cursor = "default";
		alvo.style.opacity = 1;
		alvo.style.filter = "alpha(opacity=100)";
		DW_selection(body, true);
	}
}

function DW_startDrag(domWindow) {
	DW_id=domWindow.getAttribute("id");

	DW_findPos(document.getElementById(DW_id));
	DW_offsetX = DW_mouseX - DW_offsetX;
	DW_offsetY = DW_mouseY - DW_offsetY;

	DW_dragMode = true; DW_offsetMode = true;
}
function DW_stopDrag() { DW_dragMode = false; DW_offsetMode = false; }

function DW_closeWindow(btn) {
	var window=btn.parentNode.parentNode;
	var id=window.getAttribute("id");
	
	window.style.visibility = "hidden";

	GM_setValue(vInfo.uniqueID+"DragWin."+id+".closed","true");
}
function DW_isClosed(window){
 
	var id=window.getAttribute("id");
	var closed=GM_getValue(vInfo.uniqueID+"DragWin."+id+".closed");
	return closed=="true";
}
	
function DW_openWindows() { 
	var windows=document.evaluate('//div[@class="DW_window"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
	for(var i=0;i<windows.snapshotLength;i++){
		windows.snapshotItem(i).style.visibility = "visible";
		var id=windows.snapshotItem(i).getAttribute("id");
		GM_setValue(vInfo.uniqueID+"DragWin."+id+".closed","false");
	}
}


function DW_isMinimized(window){
 
	var id=window.getAttribute("id");
	var minimized=GM_getValue(vInfo.uniqueID+"DragWin."+id+".minimized");
	return minimized=="true";

	//return window.getAttribute("minimized")=="true";
}

function DW_minimax(btn) {
 //alert("entering DW_minimax()");

	var window=btn.parentNode.parentNode;
	var id=window.getAttribute("id");
 //alert("id: "+id);


	var minimized=DW_isMinimized(window);
 //alert("minimized: "+minimized);
 
	if(minimized){	 // if it is minimized, let's restore it
		DW_setMinimized(btn,false);
	}else{		// but if it is not minimized, let's minimize it
		DW_setMinimized(btn,true);
	}
 
}

function DW_setMinimized(btn,value){

	var window=btn.parentNode.parentNode;
	var id=window.getAttribute("id");
	var content=document.evaluate('//div[@id="'+window.getAttribute("id")+'"]/div[@class="content"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0);
	var statusbar=document.evaluate('//div[@id="'+window.getAttribute("id")+'"]/div[@class="statusbar"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0);
	
	if(value){	// minimize it
		content.style.display = "none";
		btn.innerHTML = "+";
		btn.setAttribute("title", "Maximize");
		window.setAttribute("minimized",true);
		
		GM_setValue(vInfo.uniqueID+"DragWin."+id+".minimized","true");
	
	}else{		// restore it
		content.style.display = "block";
		btn.innerHTML = "-";
		btn.setAttribute("title", "Minimize");
		statusbar.style.display = "block";
		window.setAttribute("minimized",false);
		
		GM_setValue(vInfo.uniqueID+"DragWin."+id+".minimized","false");
	}

}

function DW_hideWindow(btn) {
 
	var window=btn.parentNode.parentNode;
	var minimaxBtn=document.evaluate('//div[@id="'+window.getAttribute("id")+'"]//a[@id="minimax"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotItem(0);
 
	if (!DW_isMinimized(window)) {
		DW_minimax(minimaxBtn);
	}
	window.style.top = 0;
	window.style.left = 0;
	window.getElementById("statusbar").style.display = "none";
}

//document.onmousemove = function(event) { DW_moving(event); }
//document.addEventListener('mousemove', function(event) { DW_moving(event); }, false);


/* Window exemple

function debug(){


	
	var dwwin = 


			'<p><img src="xls.jpg" alt="random image"/>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Phasellus venenatis fringilla purus. Suspendisse ultrices, leo vitae mollis eleifend, mi orci volutpat justo, in mollis erat dolor at dolor. Etiam volutpat diam. Morbi diam. Cras leo enim, imperdiet sit amet, facilisis a, ullamcorper in, nunc. Nunc elit quam, egestas sed, viverra eget, tempus nec, turpis. Morbi mauris dolor, adipiscing id, facilisis eget, dapibus ac, turpis.</p>'+
			'<p>Quisque nec magna. Morbi tellus nisl, ullamcorper sed, ullamcorper in, adipiscing et, tellus. Maecenas at urna. In vehicula est sed purus. Quisque lobortis vestibulum nulla. Sed lacinia pellentesque massa. Nulla facilisi. Vestibulum semper. Nulla vitae lacus eu mauris tincidunt luctus. Ut porttitor nisi quis tortor. Vestibulum adipiscing, elit id scelerisque molestie, tortor lacus ullamcorper neque, ut tristique mi purus sit amet orci.</p>'+
			'<p>Ut venenatis lacus ut diam. Nunc dignissim mattis risus. Nam sollicitudin nunc ut mauris commodo venenatis. Fusce augue tortor, consectetuer non, cursus nec, aliquam ac, magna. Praesent orci.</p>'+
			'<p id="debug">Ut venenatis lacus ut diam. Nunc dignissim mattis risus. Nam sollicitudin nunc ut mauris commodo venenatis. Fusce augue tortor, consectetuer non, cursus nec, aliquam ac, magna. Praesent orci.</p>';


	



	var body, windiv, titlebar, titlehead, content, statusbar, aclose, ahide, aminimax;
	body = document.getElementsByTagName('body')[0];
	
	windiv = document.createElement('DIV');
	windiv.id='win1';
	windiv.className='DW_window';
	windiv.style.top="600px";
	windiv.style.left="700px";
	
	titlebar = document.createElement('DIV');
	titlebar.className='titlebar';
	windiv.appendChild(titlebar);
	
	titlehead = document.createElement('H2');
	titlehead.innerHTML='Window Title';
	titlebar.appendChild(titlehead);
	
	aclose = document.createElement('A');
	aclose.title="Close";
	aclose.id="close";
	aclose.addEventListener('mouseup', function(){ DW_closeWindow(aclose);  }, false);
	aclose.innerHTML='x';
	titlebar.appendChild(aclose);
	
	ahide = document.createElement('A');
	ahide.title="Hide";
	ahide.id="hide";
	ahide.addEventListener('mouseup', function(){ DW_hideWindow(ahide);  }, false);
	ahide.innerHTML='^';
	titlebar.appendChild(ahide);
	
	aminimax = document.createElement('A');
	aminimax.title="Minimize";
	aminimax.id="minimax";
	aminimax.addEventListener('mouseup', function(){ DW_minimax(aminimax);  }, false);
	aminimax.innerHTML='-';
	titlebar.appendChild(aminimax);
	
	
	
	
	content = document.createElement('DIV');
	content.className='content';
	windiv.appendChild(content);
	
	statusbar = document.createElement('DIV');
	statusbar.className='statusbar';
	statusbar.innerHTML='statusbar .:';
	windiv.appendChild(statusbar);

	
	
	
	content.innerHTML = dwwin;
	body.appendChild(windiv);
	windiv.addEventListener('mousedown', function(){ DW_startDrag(windiv);  }, false);
	windiv.addEventListener('mouseup', DW_stopDrag, false);

	windiv.addEventListener('mousemove', function(event) { DW_moving(event); }, false);



}

*/




























































































































































































































































































//=================================
// support functions


// nice function for number formatting
// found at http://www.mredkj.com/javascript/numberFormat.html and  http://www.mredkj.com/javascript/nfbasic.html
function addSeparatorsNF(nStr, inD, outD, sep)
{
	nStr += '';
	var dpos = nStr.indexOf(inD);
	var nStrEnd = '';
	if (dpos != -1) {
		nStrEnd = outD + nStr.substring(dpos + 1, nStr.length);
		nStr = nStr.substring(0, dpos);
	}
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(nStr)) {
		nStr = nStr.replace(rgx, '$1' + sep + '$2');
	}
	return nStr + nStrEnd;
}


function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}


function TM_searchDOM(X){return document.evaluate(X,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);}
function TM_searchNode(doc,X){return document.evaluate(X,doc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);}
function pI(X){return parseInt(X);}

// ›› Adds a generic div.
function addDiv(id,style,html,parent){
	var body, div;
	if (!parent){body = document.getElementsByTagName('body')[0];}else{body = document.getElementById(parent);}
	if (!body) {return false;}
	div = document.createElement('DIV');
	if (id)		{div.id = id;}
	if (style)	{div.className = style;}
	if (html)	{div.innerHTML = html;}
	body.appendChild(div);
	return div;
}

// ›› Adds a generic image.
function addImg(id,style,src,parent){
	var body, img;
	if (!parent){body = document.getElementsByTagName('body')[0];}else{body = document.getElementById(parent);}
	if (!body) {return false;}
	img = document.createElement('IMG');
	if(id)		{img.id = id};
	if(style)		{img.className = style};
	if(src)		{img.src = src};
	body.appendChild(img);
	return img;
}

// ›› Add generic CSS 
function addCSS(cssString) {
	var style = document.createElement('STYLE');
	style.type = 'text/css';style.innerHTML = cssString;
	document.getElementsByTagName('HEAD')[0].appendChild(style);
}

// ›› Make default CSS.
function makeDefaultCSS(){
	var cssString = "";
	addCSS('.TMnull{position:relative;}');
	cssString = '.TMpopup{' +
		'background-color:white;' + 
		'border:thin solid #000000;' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:8pt;' +
		'font-weight:bold;' +
		'padding-bottom:3px;' +
		'padding-left:3px;' + 
		'padding-right:3px;' + 
		'padding-top:3px;' + 
		'position:absolute;' +
		'visibility:hidden;' +
		'z-index:200;}';
	addCSS(cssString);
	cssString = '.TMdisplay{' +
		'cursor:pointer;' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:8pt;' +
		'float:left;' + 
		'margin:3px;' +
		'padding:3px;' + 
		'position:relative;}';
	addCSS(cssString);
	cssString = '.TMmain{' +
		'border:thin solid #000000;' +
		'bottom:5px;' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:8pt;' +
		'font-weight:bold;' +
		'padding-bottom:5px;' +
		'padding-left:5px;' + 
		'padding-right:5px;' + 
		'padding-top:5px;' + 
		'position:fixed;' +
		'right:8px;' +
		'z-index:1050;}';
	addCSS(cssString);
	var cssString = '.TMbuildingtags{' +
		'background-color:#FDF8C1;' + 
		'border:thin solid #000000;' +
		'cursor:pointer;' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:8pt;' +
		'font-weight:bold;' +
		'height:14px;' +
		'position:absolute;' +
		'text-align:center;' +
		'visibility:hidden;' +
		'width:21px;' +
		'z-index:50;}';
	addCSS(cssString);
	cssString = '.TMtimers{' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:8pt;' +
		'float:left;' + 
		'padding-bottom:1px;' +
		'padding-left:15px;' +
		'position:relative;' +
		'z-index:50;}';
	addCSS(cssString);
	cssString = '.TMleftmenu{' +
		'background-color:white;' + 
		'cursor:pointer;' +
		'font-family: Verdana, Arial, Helvetica, sans-serif;' +
		'font-size:7pt;' +
		'font-weight:bold;' +
		'padding-bottom:5px;' +
		'padding-left:0px;' +
		//'padding-right:15px;' +
		'position:absolute;' +
		'width:145px;' +
		'border:0;' +
		'top:0px;' + 
		'z-index:4;}';
	addCSS(cssString);
	cssString = '.TMleftmenu td{' +
		'border:0;}';
	addCSS(cssString);
	cssString = '.TMdemo{' +
		'position:fixed;' +
		'top:108px;' +
		'right:8px;' + 
		'z-index:50;}';
	addCSS(cssString);
	cssString = '.TWoodBack{' +
		'background:#DDEEDD;}';
	addCSS(cssString);
	cssString = '.TClayBack{' +
		'background:#FFCD8E;}';
	addCSS(cssString);
	cssString = '.TIronBack{' +
		'background:#DEE3E9;}';
	addCSS(cssString);
	cssString = '.TCropBack{' +
		'background:#FDF8C1;}';
	addCSS(cssString);
	cssString = '.TTitle{' +
		'background:#FFFFFF;' +
		'text-align:center}';
	addCSS(cssString);
	cssString = '.DW_window table, .DW_window table tbody th, .DW_window table tbody td{' +
		'background-color:transparent;}';
	addCSS(cssString);
	cssString = 'td.tb3c table, table.traders tbody{' +
		'background-color:#FFFFFF;}';
	addCSS(cssString);
	cssString = '#vlist tbody tr, div#side_info table td{' +
		'line-height:1em;}';
	addCSS(cssString);
	
// Draggable Windows
	cssString = '.DW_window{' +
		'border-top: 1px solid #000000;' +
		'border-right: 2px solid #666666;' +
		'border-bottom: 2px solid #000000;' +
		'border-left: 1px solid #999999;' +
		'width: 400px;' +
		'position: absolute;' +
		'z-index: 1000;' +
		'top: 600px'+
		'left: 700px;}';
	addCSS(cssString);
	cssString = '.DW_window .titlebar{' +
		'width: 100%;' +
		'height: 25px;' +
		'background: #666666;' +
		'border-top: 1px solid #999999;' +
		'border-right: 1px solid #666666;' +
		'border-bottom: 1px solid black;' +
		'border-left: 1px solid #999999;}';
	addCSS(cssString);
	cssString = '.DW_window .titlebar h2{' +
		'font: 12px Verdana, Arial, Sans-serif;' +
		'color: #ffffff;' +
		'padding: 5px 5px;' +
		'margin: 0px;' +
		'float: left;}';
	addCSS(cssString);
	cssString = '.DW_window .titlebar a{' +
		'font: 12px Verdana, Arial, Sans-serif;' +
		'color: #ffffff;' +
		'padding: 1px 4px;' +
		'margin: 4px 2px 0px 1px;' +
		'text-decoration: none;' +
		'display: block;' +
		'border: 1px solid #000000;' +
		'float: right;}';
	addCSS(cssString);
	cssString = '.DW_window .content{' +
		//'padding: 10px 20px;' +
		'background: #f1f1f1;' +
		'border-top: 1px solid #999999;' +
		'border-bottom: 1px solid #CCCCCC;}';
	addCSS(cssString);
	cssString = '.DW_window .content p{' +
		'font: 12px Verdana, Arial, Sans-serif;' +
		'color: #333333;' +
		'margin-bottom: 5px;}';
	addCSS(cssString);
	cssString = '.DW_window .statusbar{' +
		'font: 10px Verdana, Arial, Sans-serif;' +
		'color: #999999;' +
		'padding: 1px 5px;' +
		'background: #d9d9d9;' +
		'border-top: 1px solid #666666;' +
		'text-align: right;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .floatLeft, .TMCPWindow .floatLeft{' +
		//'float: left;'+
		'margin-right:15px;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .village{' +
		'border-top: 1px solid;'+
		'padding:2px 2px 10px 2px;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .villageInfo{' +
		'padding:0 0 5px 0;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .villageEvent{' +
		'padding:0 0 2px 10px;}';
	addCSS(cssString);
	cssString = '.TMCPWindow td, .TMCPWindow th{' +
		'background-color:#FFFFFF;' +
		'border:0;' +
		'padding:5px 5px;}';
	addCSS(cssString);
	cssString = '.TMCPWindow th{' +
		'text-align: left;' +
		'padding-bottom: 10px;' +
		'border-bottom: 1px solid;' +
		'font-weight: bold}';
	addCSS(cssString);
	cssString = '.RunningEvent{' +
		'color:#6666FF;}';
	addCSS(cssString);
	cssString = '.ExpiredEvent{' +
		//'color:#CCCC00;}';
		'color:#808080;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .fullEvents{' +
		'margin-bottom:20px;}';
	addCSS(cssString);
	cssString = '.TMEventsWindow .fullEvents, .TMEventsWindow .emptyVillages{' +
		'border-bottom: 1px solid;'+
		'padding:20px 2px 2px 2px;}';
	addCSS(cssString);
	cssString = '#villagesData div table tbody tr td, #generalProd div table tbody tr td{' +
		'border: 1px solid #CCCCCC;}';
	addCSS(cssString);
	
	
	cssString = '.d1{' +
		'font-weight: bold;' +
		'color:#228B22;}';
	addCSS(cssString);
	cssString = '.d2{' +
		'font-weight: bold;' +
		'color:#F2C700;}';
	addCSS(cssString);
	

}




function getCurrentTime(){
	return Math.round(new Date().getTime()/1000);
}

function getSeconds(FormattedTime){
	var timeArray = FormattedTime.split(":");
	var secs = timeArray[0]*3600+timeArray[1]*60+timeArray[2]*1;
	return secs;
}

function formatTime(seconds){
	var negative=false;
	if (seconds<0){
		seconds = seconds*-1;
		negative=true;
	}
	az=Math.floor(seconds/3600);	//hour
	an=Math.floor(seconds/60)%60;if(an<10){an="0"+an;}	//minute
	af=seconds%60;				if(af<10){af="0"+af;}	//second
	t=az+':'+an+':'+af;
	if (negative){t="-"+t;}
	return t;
}

























	// ›› Inactive stub.
	function inactivestub (){alert('Bad news =[  No place to save preferences.  Firefox required.  If you have Firefox, your version of Greasemonkey might be too old.  If this is the case... UPGRADE NOW. There are SERIOUS security issues with older versions of Greasemonkey!');}
	// ›› Offsite stub.
	function offsitestub() {}
	// ›› Back to drawing board on redirect.
	function redirect() {}

//alert("support functions ok");







function switchLanguage(){


 //alert("vInfo.serverLang: "+vInfo.serverLang);

	switch(vInfo.serverLang){
	
		case 'br':
		case 'pt':
	
			xLang['Main']='Edifício Principal';
			xLang['Market']='Mercado';
			xLang['Academy']='Academia';
			xLang['Embassy']='Embaixada';
			xLang['Granary']='Celeiro';
			xLang['Stable']='Cavalaria';
			xLang['Wall']='Muralha';			// roman wall
			xLang['Gaul Wall']='Muralha';
			xLang['Teuton Wall']='Muralha';
			xLang['Warehouse']='Armazém';
			xLang['Rally']='Ponto de Reunião Militar';
			xLang['Blacksmith']='Ferreiro';
			xLang['Armoury']='Fábrica de Armaduras';
			xLang['Palace']='Palácio';
			xLang['Residence']='Residência';
			xLang['Workshop']='Oficina';
			xLang['Barracks']='Quartel';
			xLang['Town Hall']='Casa do Povo';	//nome mais cretino q conseguiram imaginar
			xLang['Trade']='Companhia do Comércio';
			xLang['Wood Field']='Bosque';
			xLang['Clay Field']='Poço de Barro';
			xLang['Iron Field']='Mina de Ferro';
			xLang['Crop Field']='Campo de Cereais';
			
			break;
			

	
		case 'nl':
		
 // translation by underke
			xLang['Main']='Hoofdgebouw';
			xLang['Market']='Marktplaats';
			xLang['Academy']='Academie';
			xLang['Embassy']='Ambassade';
			xLang['Granary']='Graansilo';
			xLang['Stable']='Stal';
			xLang['Wall']='Stadsmuur';			// roman wall
			xLang['Gaul Wall']='Palissade';
			xLang['Teuton Wall']='Muur van aarde';
			xLang['Warehouse']='Pakhuis';
			xLang['Rally']='Verzamelplaats';
			xLang['Blacksmith']='Wapensmid';
			xLang['Armoury']='Uitrustingssmederij';
			xLang['Palace']='Paleis';
			xLang['Residence']='Residentie';
			xLang['Workshop']='Werkplaats';
			xLang['Barracks']='Barakken';
			xLang['Town Hall']='Raadhuis';
			xLang['Trade']='Handelskantoor';
			
			xLang['Wood Field']='Houthakker';
			xLang['Clay Field']='Klei-afgraving';
			xLang['Iron Field']='IJzermijn';
			xLang['Crop Field']='Graanakker';
			
			
			break;
			
			
        case 'ru':
            xLang['Main']='Главное здание';
            xLang['Market']='Рынок';
            xLang['Academy']='Академия';
            xLang['Embassy']='Посольство';
            xLang['Granary']='Амбар';
            xLang['Stable']='Конюшня';
            xLang['Wall']='Римская стена';            // roman wall
            xLang['Gaul Wall']='Частоколл(галлы)';
            xLang['Teuton Wall']='Земляной вал';
            xLang['Warehouse']='Склад';
            xLang['Rally']='Пункт сбора';
            xLang['Blacksmith']='Кузница оружия';
            xLang['Armoury']='Кузница доспехов';
            xLang['Palace']='Дворец';
            xLang['Residence']='Резиденция';
            xLang['Workshop']='Мастерская';
            xLang['Barracks']='Казарма';
            xLang['Town Hall']='Ратуша';
            xLang['Trade']='Торговая палата';
            xLang['Wood Field']='Лесопилка';
            xLang['Clay Field']='Глиняный карьер';
            xLang['Iron Field']='Железный рудник';
            xLang['Crop Field']='Ферма';
            
            break;
		
		
		case 'com':
		case 'us':
		default:
	
			xLang['Main']='Main Building';
			xLang['Market']='Marketplace';
			xLang['Academy']='Academy';
			xLang['Embassy']='Embassy';
			xLang['Granary']='Granary';
			xLang['Stable']='Stable';
			xLang['Wall']='City Wall';			// roman wall
			xLang['Gaul Wall']='Palisade';
			xLang['Teuton Wall']='Earth Wall';
			xLang['Warehouse']='Warehouse';
			xLang['Rally']='Rally Point';
			xLang['Blacksmith']='Blacksmith';
			xLang['Armoury']='Armoury';
			xLang['Palace']='Palace';
			xLang['Residence']='Residence';
			xLang['Workshop']='Workshop';
			xLang['Barracks']='Barracks';
			xLang['Town Hall']='Town Hall';
			xLang['Trade']='Trade Office';
			xLang['Wood Field']='Woodcutter';
			xLang['Clay Field']='Clay Pit';
			xLang['Iron Field']='Iron Mine';
			xLang['Crop Field']='Cropland';

	
	}
 
 

	
	
	
	
	
	
	
	
	
	cps[0] 		= new CP(xLang['Main'],			0,1,2,10526);
	cps[1] 		= new CP(xLang['Main'],			1,2,1,4167);
	cps[2] 		= new CP(xLang['Market'],		2,1,2,10526);
	cps[3] 		= new CP(xLang['Embassy'],		3,1,5,9259);
	cps[4] 		= new CP(xLang['Academy'],		4,1,5,9804);
	cps[5] 		= new CP(xLang['Market'],		5,2,1,4167);
	cps[6] 		= new CP(xLang['Granary'],		6,1,1,3704);
	cps[7] 		= new CP(xLang['Main'],			7,4,1,2532);
	cps[8] 		= new CP(xLang['Main'],			8,5,1,1961);
	cps[9] 		= new CP(xLang['Palace'],		9,1,6,2553);
	cps[10] 	= new CP(xLang['Market'],		10,4,1,2532);
	cps[11] 	= new CP(xLang['Wall'],			11,1,1,2500);
	cps[12] 	= new CP(xLang['Warehouse'],	12,1,1,2381);
	cps[13] 	= new CP(xLang['Rally'],		13,1,1,2326);
	cps[14] 	= new CP(xLang['Blacksmith'],	14,1,2,2273);
	cps[15] 	= new CP(xLang['Armoury'],		15,1,2,2273);
	cps[16] 	= new CP(xLang['Granary'],		16,3,1,2247);
	cps[17] 	= new CP(xLang['Market'],		17,5,1,1961);
	cps[18] 	= new CP(xLang['Main'],			18,6,1,1538);
	cps[19] 	= new CP(xLang['Main'],			19,7,1,1190);
	cps[20] 	= new CP(xLang['Main'],			20,8,2,1860);
	cps[21] 	= new CP(xLang['Market'],		21,6,1,1538);
	cps[22] 	= new CP(xLang['Market'],		22,7,1,1190);
	cps[23] 	= new CP(xLang['Market'],		23,8,2,1860);
	cps[24] 	= new CP(xLang['Academy'],		24,2,1,1538);
	cps[25] 	= new CP(xLang['Wall'],			25,3,1,1527);
	cps[26] 	= new CP(xLang['Embassy'],		26,2,1,1460);
	cps[27] 	= new CP(xLang['Academy'],		27,3,1,1205);
	cps[28] 	= new CP(xLang['Academy'],		28,4,1,935);
	cps[29] 	= new CP(xLang['Academy'],		29,5,2,1465);	
	cps[30] 	= new CP(xLang['Warehouse'],	30,3,1,1460);
	cps[31] 	= new CP(xLang['Residence'],	31,1,2,1274);
	cps[32] 	= new CP(xLang['Main'],			32,9,1,730);
	cps[33] 	= new CP(xLang['Main'],			33,10,2,1140);
	cps[34] 	= new CP(xLang['Main'],			34,11,3,1339);
	cps[35] 	= new CP(xLang['Rally'],		35,3,1,1429);
	cps[36] 	= new CP(xLang['Barracks'],		36,1,1,1370);
	cps[37] 	= new CP(xLang['Market'],		37,9,1,730);
	cps[38] 	= new CP(xLang['Market'],		38,10,2,1140);
	cps[39] 	= new CP(xLang['Market'],		39,11,3,1339);
	cps[40] 	= new CP(xLang['Market'],		40,12,3,1045);
	cps[41] 	= new CP(xLang['Main'],			41,12,3,1045);
	cps[42] 	= new CP(xLang['Academy'],		42,6,2,1143);
	cps[43] 	= new CP(xLang['Embassy'],		43,3,1,1130);
	cps[44] 	= new CP(xLang['Embassy'],		44,4,1,881);
	cps[45] 	= new CP(xLang['Embassy'],		45,5,2,1375);
	cps[46] 	= new CP(xLang['Academy'],		46,7,2,891);
	cps[47] 	= new CP(xLang['Academy'],		47,8,3,1045);
	cps[48] 	= new CP(xLang['Academy'],		48,9,4,1087);
	cps[49] 	= new CP(xLang['Main'],			49,13,3,816);
	cps[50] 	= new CP(xLang['Main'],			50,14,5,1063);
	cps[51] 	= new CP(xLang['Blacksmith'],	51,2,1,889);
	cps[52] 	= new CP(xLang['Stable'],		52,1,2,2778);
	cps[53] 	= new CP(xLang['Academy'],		53,10,4,850);
	cps[54] 	= new CP(xLang['Workshop'],		54,1,4,2116);
	cps[55] 	= new CP(xLang['Town Hall'],	55,1,6,1422);
	cps[56] 	= new CP(xLang['Stable'],		56,2,1,1081);
	cps[57] 	= new CP(xLang['Embassy'],		57,6,2,1078);
	cps[58] 	= new CP(xLang['Market'],		58,13,3,816);
	cps[59] 	= new CP(xLang['Market'],		59,14,5,1063);
	cps[60] 	= new CP(xLang['Embassy'],		60,7,2,844);
	cps[61] 	= new CP(xLang['Embassy'],		61,8,3,1031);
	cps[62] 	= new CP(xLang['Embassy'],		62,9,4,1030);
	cps[63] 	= new CP(xLang['Main'],			63,15,5,830);
	cps[64] 	= new CP(xLang['Market'],		64,15,5,830);
	cps[65] 	= new CP(xLang['Academy'],		65,11,5,831);
	cps[66] 	= new CP(xLang['Embassy'],		66,10,4,802);
	cps[67] 	= new CP(xLang['Main'],			67,16,6,778);
	cps[68] 	= new CP(xLang['Main'],			68,17,7,710);
	cps[69] 	= new CP(xLang['Main'],			69,18,9,713);
	cps[70] 	= new CP(xLang['Main'],			70,19,11,680);
	cps[71] 	= new CP(xLang['Main'],			71,20,13,628);
	cps[72] 	= new CP(xLang['Market'],		72,16,6,778);
	cps[73] 	= new CP(xLang['Market'],		73,17,7,710);
	cps[74] 	= new CP(xLang['Market'],		74,18,9,713);
	cps[75] 	= new CP(xLang['Market'],		75,19,11,680);
	cps[76] 	= new CP(xLang['Market'],		76,20,13,628);
	cps[77] 	= new CP(xLang['Embassy'],		77,11,5,784);
	cps[78] 	= new CP(xLang['Academy'],		78,12,6,778);
	cps[79] 	= new CP(xLang['Embassy'],		79,12,6,735);
	cps[80] 	= new CP(xLang['Granary'],		80,6,1,1075);
	cps[81] 	= new CP(xLang['Granary'],		81,7,1,840);
	cps[82] 	= new CP(xLang['Barracks'],		82,3,1,837);
	cps[83] 	= new CP(xLang['Armoury'],		83,2,1,889);
	cps[84] 	= new CP(xLang['Academy'],		84,13,7,710);
	cps[85] 	= new CP(xLang['Warehouse'],	85,6,1,694);
	cps[86] 	= new CP(xLang['Academy'],		86,14,8,634);
	cps[87] 	= new CP(xLang['Academy'],		87,15,11,681);
	cps[88] 	= new CP(xLang['Embassy'],		88,13,7,670);
	cps[89] 	= new CP(xLang['Embassy'],		89,14,8,598);
	cps[90] 	= new CP(xLang['Embassy'],		90,15,11,643);
	cps[91] 	= new CP(xLang['Academy'],		91,16,12,580);
	cps[92] 	= new CP(xLang['Academy'],		92,17,15,566);
	cps[93] 	= new CP(xLang['Embassy'],		93,16,12,548);
	cps[94] 	= new CP(xLang['Warehouse'],	94,7,1,542);
	cps[95] 	= new CP(xLang['Embassy'],		95,17,15,535);
	cps[96] 	= new CP(xLang['Academy'],		96,18,17,502);
	cps[97] 	= new CP(xLang['Academy'],		97,19,22,507);
	cps[98] 	= new CP(xLang['Palace'],		98,2,1,332);
	cps[99] 	= new CP(xLang['Palace'],		99,3,2,519);
	cps[100] 	= new CP(xLang['Residence'],	100,2,1,498);
	cps[101] 	= new CP(xLang['Embassy'],		101,18,17,474);
	cps[102] 	= new CP(xLang['Embassy'],		102,19,22,479);
	cps[103] 	= new CP(xLang['Academy'],		103,20,25,450);
	cps[104] 	= new CP(xLang['Embassy'],		104,20,25,425);
	cps[105] 	= new CP(xLang['Granary'],		105,9,1,514);
	cps[106] 	= new CP(xLang['Stable'],		106,4,1,662);
	cps[107] 	= new CP(xLang['Stable'],		107,5,1,517);
	cps[108] 	= new CP(xLang['Wall'],			108,6,1,727);
	cps[109] 	= new CP(xLang['Wall'],			109,7,1,567);
	cps[110] 	= new CP(xLang['Blacksmith'],	110,4,1,542);
	cps[111] 	= new CP(xLang['Blacksmith'],	111,5,1,424);
	cps[112] 	= new CP(xLang['Armoury'],		112,4,1,541);
	cps[113] 	= new CP(xLang['Armoury'],		113,5,1,423);
	cps[114] 	= new CP(xLang['Rally'],		114,6,1,676);
	cps[115] 	= new CP(xLang['Rally'],		115,7,1,528);
	cps[116] 	= new CP(xLang['Stable'],		116,6,1,404);
	cps[117] 	= new CP(xLang['Granary'],		117,10,1,402);
	cps[118] 	= new CP(xLang['Granary'],		118,11,1,314);
	cps[119] 	= new CP(xLang['Granary'],		119,12,2,490);
	cps[120] 	= new CP(xLang['Blacksmith'],	120,6,1,331);
	cps[121] 	= new CP(xLang['Armoury'],		121,6,1,331);
	cps[122] 	= new CP(xLang['Blacksmith'],	122,7,1,258);
	cps[123] 	= new CP(xLang['Blacksmith'],	123,8,2,404);
	cps[124] 	= new CP(xLang['Armoury'],		124,7,1,258);
	cps[125] 	= new CP(xLang['Armoury'],		125,8,2,404);
	cps[126] 	= new CP(xLang['Stable'],		126,7,1,315);
	cps[127] 	= new CP(xLang['Stable'],		127,8,2,493);
	cps[128] 	= new CP(xLang['Granary'],		128,13,2,383);
	cps[129] 	= new CP(xLang['Stable'],		129,9,1,193);
	cps[130] 	= new CP(xLang['Stable'],		130,10,2,301);
	cps[131] 	= new CP(xLang['Trade'],		131,1,4,924);
	cps[132] 	= new CP(xLang['Palace'],		132,4,1,203);
	cps[133] 	= new CP(xLang['Palace'],		133,5,2,317);
	cps[134] 	= new CP(xLang['Palace'],		134,6,3,372);
	cps[135] 	= new CP(xLang['Stable'],		135,11,3,353);
	cps[136] 	= new CP(xLang['Warehouse'],	136,9,1,330);
	cps[137] 	= new CP(xLang['Wall'],			137,9,1,347);
	cps[138] 	= new CP(xLang['Wall'],			138,10,1,271);
	cps[139] 	= new CP(xLang['Wall'],			139,11,1,212);
	cps[140] 	= new CP(xLang['Wall'],			140,12,2,331);
	cps[141] 	= new CP(xLang['Rally'],		141,9,1,322);
	cps[142] 	= new CP(xLang['Granary'],		142,14,2,299);
	cps[143] 	= new CP(xLang['Warehouse'],	143,10,1,258);
	cps[144] 	= new CP(xLang['Warehouse'],	144,11,1,202);
	cps[145] 	= new CP(xLang['Warehouse'],	145,12,2,315);
	cps[146] 	= new CP(xLang['Rally'],		146,10,1,252);
	cps[147] 	= new CP(xLang['Rally'],		147,11,1,197);
	cps[148] 	= new CP(xLang['Rally'],		148,12,2,308);
	cps[149] 	= new CP(xLang['Barracks'],		149,6,1,399);
	cps[150] 	= new CP(xLang['Barracks'],		150,7,1,311);	
	cps[151] 	= new CP(xLang['Palace'],		151,7,3,290);
	cps[152] 	= new CP(xLang['Palace'],		152,8,3,227);
	cps[153] 	= new CP(xLang['Palace'],		153,9,5,295);
	cps[154] 	= new CP(xLang['Residence'],	154,4,1,304);
	cps[155] 	= new CP(xLang['Workshop'],		155,3,1,323);
	cps[156] 	= new CP(xLang['Workshop'],		156,4,1,252);
	cps[157] 	= new CP(xLang['Workshop'],		157,5,1,197);
	cps[158] 	= new CP(xLang['Workshop'],		158,6,2,308);
	cps[159] 	= new CP(xLang['Granary'],		159,15,2,234);
	cps[160] 	= new CP(xLang['Granary'],		160,16,3,274);
	cps[161] 	= new CP(xLang['Granary'],		161,17,4,285);
	cps[162] 	= new CP(xLang['Stable'],		162,12,3,276);
	cps[163] 	= new CP(xLang['Stable'],		163,13,3,215);
	cps[164] 	= new CP(xLang['Stable'],		164,14,5,281);
	cps[165] 	= new CP(xLang['Blacksmith'],	165,9,1,158);
	cps[166] 	= new CP(xLang['Blacksmith'],	166,10,2,246);
	cps[167] 	= new CP(xLang['Blacksmith'],	167,11,3,289);
	cps[168] 	= new CP(xLang['Armoury'],		168,9,1,158);
	cps[169] 	= new CP(xLang['Armoury'],		169,10,2,246);
	cps[170] 	= new CP(xLang['Armoury'],		170,11,3,289);
	cps[171] 	= new CP(xLang['Granary'],		171,18,5,279);
	cps[172] 	= new CP(xLang['Wall'],			172,13,2,258);
	cps[173] 	= new CP(xLang['Warehouse'],	173,13,2,246);
	cps[174] 	= new CP(xLang['Workshop'],		174,7,2,241);
	cps[175] 	= new CP(xLang['Rally'],		175,13,2,240);
	cps[176] 	= new CP(xLang['Residence'],	176,5,1,237);
	cps[177] 	= new CP(xLang['Town Hall'],	177,2,1,185);
	cps[178] 	= new CP(xLang['Town Hall'],	178,3,2,289);
	cps[179] 	= new CP(xLang['Palace'],		179,10,5,231);
	cps[180] 	= new CP(xLang['Blacksmith'],	180,12,3,226);
	cps[181] 	= new CP(xLang['Armoury'],		181,12,3,226);
	cps[182] 	= new CP(xLang['Blacksmith'],	182,13,3,176);
	cps[183] 	= new CP(xLang['Blacksmith'],	183,14,5,229);
	cps[184] 	= new CP(xLang['Armoury'],		184,13,3,176);
	cps[185] 	= new CP(xLang['Armoury'],		185,14,5,229);
	cps[186] 	= new CP(xLang['Stable'],		186,15,5,219);
	cps[187] 	= new CP(xLang['Granary'],		187,19,5,218);
	cps[188] 	= new CP(xLang['Palace'],		188,11,6,216);
	cps[189] 	= new CP(xLang['Palace'],		189,12,8,225);
	cps[190] 	= new CP(xLang['Workshop'],		190,8,2,188);
	cps[191] 	= new CP(xLang['Workshop'],		191,9,2,147);
	cps[192] 	= new CP(xLang['Workshop'],		192,10,4,229);
	cps[193] 	= new CP(xLang['Residence'],	193,6,1,185);
	cps[194] 	= new CP(xLang['Residence'],	194,7,1,145);
	cps[195] 	= new CP(xLang['Residence'],	195,8,2,226);
	cps[196] 	= new CP(xLang['Stable'],		196,16,6,205);
	cps[197] 	= new CP(xLang['Granary'],		197,20,6,204);
	cps[198] 	= new CP(xLang['Wall'],			198,14,2,202);
	cps[199] 	= new CP(xLang['Town Hall'],	199,4,1,113);
	cps[200] 	= new CP(xLang['Town Hall'],	200,5,2,177);
	cps[201] 	= new CP(xLang['Town Hall'],	201,6,3,207);
	cps[202] 	= new CP(xLang['Warehouse'],	202,14,2,192);
	cps[203] 	= new CP(xLang['Rally'],		203,14,2,188);
	cps[204] 	= new CP(xLang['Stable'],		204,17,7,187);
	cps[205] 	= new CP(xLang['Stable'],		205,18,9,188);
	cps[206] 	= new CP(xLang['Wall'],			206,15,2,158);
	cps[207] 	= new CP(xLang['Wall'],			207,16,3,185);
	cps[208] 	= new CP(xLang['Wall'],			208,17,4,193);
	cps[209] 	= new CP(xLang['Wall'],			209,18,5,188);
	cps[210] 	= new CP(xLang['Palace'],		210,13,8,176);
	cps[211] 	= new CP(xLang['Palace'],		211,14,11,189);
	cps[212] 	= new CP(xLang['Warehouse'],	212,15,2,150);
	cps[213] 	= new CP(xLang['Warehouse'],	213,16,3,176);
	cps[214] 	= new CP(xLang['Warehouse'],	214,17,4,183);
	cps[215] 	= new CP(xLang['Stable'],		215,19,11,180);
	cps[216] 	= new CP(xLang['Blacksmith'],	216,15,5,179);
	cps[217] 	= new CP(xLang['Armoury'],		217,15,5,179);
	cps[218] 	= new CP(xLang['Barracks'],		218,9,1,190);
	cps[219] 	= new CP(xLang['Barracks'],		219,10,1,149);
	cps[220] 	= new CP(xLang['Barracks'],		220,11,1,116);
	cps[221] 	= new CP(xLang['Barracks'],		221,12,2,181);
	cps[222] 	= new CP(xLang['Rally'],		222,15,2,147);
	cps[223] 	= new CP(xLang['Rally'],		223,16,3,172);
	cps[224] 	= new CP(xLang['Rally'],		224,17,4,179);
	cps[225] 	= new CP(xLang['Warehouse'],	225,18,5,179);
	cps[226] 	= new CP(xLang['Rally'],		226,18,5,175);
	cps[227] 	= new CP(xLang['Palace'],		227,15,13,175);
	cps[228] 	= new CP(xLang['Blacksmith'],	228,16,6,168);
	cps[229] 	= new CP(xLang['Armoury'],		229,16,6,168);
	cps[230] 	= new CP(xLang['Stable'],		230,20,13,166);
	cps[231] 	= new CP(xLang['Workshop'],		231,11,3,134);
	cps[232] 	= new CP(xLang['Workshop'],		232,12,5,175);
	cps[233] 	= new CP(xLang['Town Hall'],	233,7,3,162);
	cps[234] 	= new CP(xLang['Town Hall'],	234,8,3,126);
	cps[235] 	= new CP(xLang['Town Hall'],	235,9,5,164);
	cps[236] 	= new CP(xLang['Palace'],		236,16,15,157);
	cps[237] 	= new CP(xLang['Palace'],		237,17,19,156);
	cps[238] 	= new CP(xLang['Blacksmith'],	238,17,7,153);
	cps[239] 	= new CP(xLang['Blacksmith'],	239,18,9,154);
	cps[240] 	= new CP(xLang['Armoury'],		240,17,7,153);
	cps[241] 	= new CP(xLang['Armoury'],		241,18,9,154);
	cps[242] 	= new CP(xLang['Residence'],	242,9,1,88);
	cps[243] 	= new CP(xLang['Residence'],	243,10,2,138);
	cps[244] 	= new CP(xLang['Residence'],	244,11,3,162);
	cps[245] 	= new CP(xLang['Workshop'],		245,13,5,137);
	cps[246] 	= new CP(xLang['Workshop'],		246,14,7,150);
	cps[247] 	= new CP(xLang['Wall'],			247,19,5,147);
	cps[248] 	= new CP(xLang['Blacksmith'],	248,19,11,147);
	cps[249] 	= new CP(xLang['Armoury'],		249,19,11,147);
	cps[250] 	= new CP(xLang['Barracks'],		250,13,2,142);
	cps[251] 	= new CP(xLang['Palace'],		251,18,22,141);
	cps[252] 	= new CP(xLang['Warehouse'],	252,19,5,140);
	cps[253] 	= new CP(xLang['Wall'],			253,20,6,138);
	cps[254] 	= new CP(xLang['Rally'],		254,19,5,137);
	cps[255] 	= new CP(xLang['Blacksmith'],	255,20,13,136);
	cps[256] 	= new CP(xLang['Armoury'],		256,20,13,136);
	cps[257] 	= new CP(xLang['Palace'],		257,19,27,135);
	cps[258] 	= new CP(xLang['Warehouse'],	258,20,6,131);
	cps[259] 	= new CP(xLang['Residence'],	259,12,3,126);
	cps[260] 	= new CP(xLang['Residence'],	260,13,3,99);
	cps[261] 	= new CP(xLang['Residence'],	261,14,5,129);
	cps[262] 	= new CP(xLang['Rally'],		262,20,6,128);
	cps[263] 	= new CP(xLang['Town Hall'],	263,10,5,128);
	cps[264] 	= new CP(xLang['Palace'],		264,20,32,125);
	cps[265] 	= new CP(xLang['Town Hall'],	265,11,6,120);
	cps[266] 	= new CP(xLang['Town Hall'],	266,12,8,125);
	cps[267] 	= new CP(xLang['Workshop'],		267,15,7,117);
	cps[268] 	= new CP(xLang['Workshop'],		268,16,9,117);
	cps[269] 	= new CP(xLang['Workshop'],		269,17,12,122);
	cps[270] 	= new CP(xLang['Barracks'],		270,14,2,111);
	cps[271] 	= new CP(xLang['Trade'],		271,3,1,141);
	cps[272] 	= new CP(xLang['Trade'],		272,4,1,110);
	cps[273] 	= new CP(xLang['Trade'],		273,5,1,86);
	cps[274] 	= new CP(xLang['Trade'],		274,6,2,134);
	cps[275] 	= new CP(xLang['Town Hall'],	275,13,8,98);
	cps[276] 	= new CP(xLang['Town Hall'],	276,14,11,105);
	cps[277] 	= new CP(xLang['Trade'],		277,7,2,105);
	cps[278] 	= new CP(xLang['Workshop'],		278,18,13,103);
	cps[279] 	= new CP(xLang['Barracks'],		279,15,2,86);
	cps[280] 	= new CP(xLang['Barracks'],		280,16,3,101);
	cps[281] 	= new CP(xLang['Barracks'],		281,17,4,106);
	cps[282] 	= new CP(xLang['Barracks'],		282,18,5,103);
	cps[283] 	= new CP(xLang['Residence'],	283,15,5,100);
	cps[284] 	= new CP(xLang['Workshop'],		284,19,16,100);
	cps[285] 	= new CP(xLang['Town Hall'],	285,15,13,97);
	cps[286] 	= new CP(xLang['Residence'],	286,16,6,94);
	cps[287] 	= new CP(xLang['Trade'],		287,8,2,82);
	cps[288] 	= new CP(xLang['Trade'],		288,9,2,64);
	cps[289] 	= new CP(xLang['Trade'],		289,10,4,100);
	cps[290] 	= new CP(xLang['Workshop'],		290,20,19,92);
	cps[291] 	= new CP(xLang['Town Hall'],	291,16,15,88);
	cps[292] 	= new CP(xLang['Town Hall'],	292,17,19,87);
	cps[293] 	= new CP(xLang['Residence'],	293,17,7,86);
	cps[294] 	= new CP(xLang['Residence'],	294,18,9,86);
	cps[295] 	= new CP(xLang['Residence'],	295,19,11,82);
	cps[296] 	= new CP(xLang['Barracks'],		296,19,5,81);
	cps[297] 	= new CP(xLang['Town Hall'],	297,18,22,78);
	cps[298] 	= new CP(xLang['Residence'],	298,20,13,76);
	cps[299] 	= new CP(xLang['Barracks'],		299,20,6,75);
	cps[300] 	= new CP(xLang['Town Hall'],	300,19,27,75);
	cps[301] 	= new CP(xLang['Town Hall'],	301,20,32,70);
	cps[302] 	= new CP(xLang['Trade'],		302,11,3,59);
	cps[303] 	= new CP(xLang['Trade'],		303,12,5,76);
	cps[304] 	= new CP(xLang['Trade'],		304,13,5,60);
	cps[305] 	= new CP(xLang['Trade'],		305,14,7,65);
	cps[306] 	= new CP(xLang['Trade'],		306,15,7,51);
	cps[307] 	= new CP(xLang['Trade'],		307,16,9,51);
	cps[308] 	= new CP(xLang['Trade'],		308,17,12,53);
	cps[309] 	= new CP(xLang['Trade'],		309,18,13,45);
	cps[310] 	= new CP(xLang['Trade'],		310,19,16,43);
	cps[311] 	= new CP(xLang['Trade'],		311,20,19,40);

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	


}