KoC Power Bot Plus

All-in-One Script for Kingdoms of Camelot

Versão de: 03/01/2017. Veja: a última versão.

// ==UserScript==
// @name			KoC Power Bot Plus
// @namespace		PBP
// @description		All-in-One Script for Kingdoms of Camelot
// @icon			https://rycamelot1-a.akamaihd.net/fb/e2/src/img/items/70/363.jpg
// @include			*.kingdomsofcamelot.com/*main_src.php*
// @include			*kingdomsofcamelot.com/fb/e2/src/claimVictoryToken_src.php*
// @include			*kingdomsofcamelot.com/fb/e2/src/merlinShare_src.php*
// @include			*kingdomsofcamelot.com/fb/e2/src/acceptToken_src.php*
// @include			*kingdomsofcamelot.com/fb/e2/src/helpFriend_src.php*
// @include			*kingdomsofcamelot.com/fb/e2/src/questshare_src.php*
// @include			*.kingdomsofcamelot.com/*platforms/kabam*
// @include			*apps.facebook.com/kingdomsofcamelot/*
// @include			*kabam.com/*games/kingdoms-of-camelot/play*
// @include			*facebook.com/*dialog/feed*
// @exclude			*sharethis*
// @require			http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require			http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js
// @resource		sound_files http://moshimo.eu/Koc_Dev/koc/PowerBotPlus/sound_files.js
// @resource		image_files http://moshimo.eu/Koc_Dev/koc/PowerBotPlus/image_files.js
// @resource		champion_uniques http://moshimo.eu/Koc_Dev/koc/PowerBotPlus/champion_uniques.js
// @resource		emoticons http://moshimo.eu/Koc_Dev/koc/PowerBotPlus/emoticons.js
// @connect			*
// @connect			www.kocbyte.com
// @connect			markbranscombe.com
// @connect			moshimo.eu
// @connect			greasyfork.org
// @connect			svn.code.sf.net
// @grant			GM_getValue
// @grant			GM_setValue
// @grant			GM_deleteValue
// @grant			GM_listValues
// @grant			GM_addStyle
// @grant			GM_log
// @grant			GM_getResourceText
// @grant	    	GM_registerMenuCommand
// @grant 			GM_xmlhttpRequest
// @grant			unsafeWindow
// @version			1.72.1
// @license			http://creativecommons.org/licenses/by-nc-nd/3.0/
// @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RZF4UM2DHJB6C
// @releasenotes	<p>Fixes and features for Arcane Temple</p><p>Search Tab - Fix misted city glitch</p><p>Reference Tab - Unique items sort order change</p><p>Tower Alert - monitor defender throne room option</p><p>Minor display changes</p>
// ==/UserScript==

//	+-------------------------------------------------------------------------------------------------------+
//	¦	This script can be found at greasyfork.org/en/scripts/11839-koc-power-bot-plus/						¦
//	¦	It is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License:	¦
//	¦	http://creativecommons.org/licenses/by-nc-nd/3.0													¦
//	¦																										¦
//	¦	July 2014 Barbarossa69 (www.facebook.com/barbarossa69)												¦
//	+-------------------------------------------------------------------------------------------------------+

var Version = '1.72.1';
var SourceName = "Power Bot Plus";

this.jQuery = jQuery.noConflict(true);
var JSON2 = JSON;
var uW = unsafeWindow;
var Seed = uW.seed;
var CM = uW.cm;

var FFVersion = getFirefoxVersion();
var GMVersion = getGMVersion();

var http =  window.location.protocol+"\/\/";
var EXTERNAL_RESOURCE = 'http://moshimo.eu/Koc_Dev/koc/PowerBotPlus/';
var KOCBYTE_LOGO = 'https://graph.facebook.com/kocbyte/picture';
var KOCBYTE_ON = true;

// Global Variables

var Cities				= {};
var Tabs				= {};
var Buttons				= {};
var Images				= {};
var OpenDiv				= {};
var local_atkp			= {};
var local_atkinc		= {};
var LanguageArray		= {};
var NoTranslation		= {};
var ReportCache			= {};
var ReportDetailCache	= {};

var inc		= [];
var incCity	= [];
var out		= [];
var outCity	= [];

var mainPop;
var popDash;
var popMon;
var popInc;
var popOut;
var popBat;
var popMarch;

var SelectiveDefending = true;
var giftAccepted = false;

var Infantry	= [];
var Ranged		= [];
var Horsed		= [];
var Siege		= [];
var SpellCaster	= [];

var GlobalEffects		= [1,2,3,4,5,6,7,17,18,19,20,21,22,23,102,103,8,9,73];

var AttackEffects		= [1,17,24,29,34,39,44,50,56,61,102,113,119,135,140];
var DefenceEffects		= [2,18,25,30,35,40,45,51,114,120,125,126,136,141];
var LifeEffects			= [3,19,26,31,36,41,46,52,104,115,121,127,128,137,142];
var RangeEffects		= [5,21,37,42,58,63,117,123,131,132,133,134,138,143];
var SpeedEffects		= [4,20,27,32,47,53,57,62,116,122,129,130];
var AccuracyEffects		= [7,23,28,33,38,43,49,55,60,65,139,144];
var OtherCombatEffects	= [8,9,118,124,13,14,15,16,73,145];
var OtherPVPEffects		= [6,22,48,54,59,64];

var DebuffEffects		= [17,18,19,20,22,21,23,29,39,50,54,61,30,40,51,31,41,52,42,63,64,32,53,62,119,120,121,122,123,124,126,128,130,132,134,140,141,142,143,144];

var AlternateSortOrder	= [5,37,58,117,131,133,138,21,42,63,123,132,134,143,1,24,34,44,56,102,113,135,17,29,39,50,61,119,140,2,25,35,45,114,125,136,18,30,40,51,120,126,141,3,26,36,46,104,115,127,137,19,31,41,52,121,128,142,4,27,47,57,116,20,32,53,62,122,129,130,7,28,38,49,60,139,23,33,43,55,65,144,8,9,118,124,13,14,15,16,73,145,6,48,59,22,54,64];

var cardQuality				= ['Simple','Common','Uncommon','Rare','Epic','Wondrous','Miraculous'];
var champImageTypes			= {0:"weapon",1:"chestArmor",2:"helmet",3:"feet",4:"shield",5:"ring1",7:"pendant",8:"cloak"};
var champUniqueImageTypes	= {0:"weapon",1:"chestArmor",2:"helmet",3:"feet",4:"shield",5:"ring",7:"pendant",8:"cloak"};
var chTypes					= {0:"weapon",1:"armor",2:"helm",3:"boots",4:"shield",5:"ring",7:"pendant",8:"cloak"};
var trTypes					= ['chair', 'advisor', 'window', 'banner', 'table', 'trophy', 'candelabrum', 'hero', 'statue', 'pet', 'tapestry', 'pillar']; // must be in this order
var champFaction			= ['briton','fey','druid'];
var jewelTypes				= ["general_buff", "general_debuff", "unit_specific", "base_building"];
var jewelQuality			= ["cracked", "flawed", "cloudy", "subdued", "bright"];
var guardTypes				= ["wood", "ore", "food", "stone"];
var tileTypes				= {0:"Bog",10:"Grassland",11:"Lake",20:"Wood",30:"Hill",40:"Mountain",50:"Plain",51:"City",52:"Ruin",53:"Misted City",54:"Dark Forest",55:"Merc Camp",56:"Nomad Camp",57:"Megalith"};
var wildImages				= {0:"bog",10:"grasslands",11:"lake",20:"forest",30:"hills",40:"mountains",50:"plains"};
var SpellBlessings			= {1:12, 2:22, 3:32};
var SpellTypes				= {1:11, 2:21, 3:31};
var BaseChamp				= {201:30,202:0,203:7,204:27,205:27,206:60,207:4,208:3,209:3};

var fortmight = { f53: 4, f55: 7, f60: 1, f61: 2, f62: 3, f63: 10 };

var TranslatePublish = {80:"300645083384735", 50:"275425949243301", 40:"291667064279714", 10:"286958161406148"};

var CE_EFFECT_TIERS = null;

var Provinces = { // top left co-ords (origin)
	p1:{x:0,y:0},
	p2:{x:150,y:0},
	p3:{x:300,y:0},
	p4:{x:450,y:0},
	p5:{x:600,y:0},

	p6:{x:0,y:150},
	p7:{x:150,y:150},
	p8:{x:300,y:150},
	p9:{x:450,y:150},
	p10:{x:600,y:150},

	p11:{x:0,y:300},
	p12:{x:150,y:300},
	p13:{x:450,y:300},
	p14:{x:600,y:300},

	p15:{x:0,y:450},
	p16:{x:150,y:450},
	p17:{x:300,y:450},
	p18:{x:450,y:450},
	p19:{x:600,y:450},

	p20:{x:0,y:600},
	p21:{x:150,y:600},
	p22:{x:300,y:600},
	p23:{x:450,y:600},
	p24:{x:600,y:600}
}

var IMGURL = uW.stimgUrl+"img/";

var GiftText = ['Yeni Hediye Alındı',
				'Neues Geschenk erhalten',
				'Nouveaux Cadeaux reçus',
				'Nuevo regalo recibido',
				'Nuovo Regalo ricevuto',
				'New Gift Received'];

var HQText = ['has donated'];

var AlertBG = IMGURL+"tower/timer_bg.png";
var GuardBG = IMGURL+"guardian_change_spritemap102.png";

var AttackImage = IMGURL+"attacking.jpg";
var ScoutImage = IMGURL+"scouting.jpg";
var ReinforceImage = IMGURL+"reinforce.jpg";
var ReassignImage = IMGURL+"autoAttack/raid_resting.png";
var TransportImage = IMGURL+"transporting.jpg";
var ReturnImage = IMGURL+"returning.jpg";
var RoseImage = IMGURL+"items/70/211.jpg";
var GauntletImage = IMGURL+"items/30/221.jpg";
var MirrorImage = IMGURL+"items/70/231.jpg";
var GlovesImage = IMGURL+"items/70/241.jpg";
var RightArrow = IMGURL+"autoAttack/across_arrow.png";
var DownArrow = IMGURL+"autoAttack/down_arrow.png";
var ThroneImage = IMGURL+"bonus_throne.png";
var PresetImage = IMGURL+"throne/modal/set_active.png";
var PresetImage_SEL = IMGURL+"throne/modal/set_selected.png";
var PresetImage_LCK = IMGURL+"throne/modal/set_locked.png";
var MistImage = IMGURL+"items/70/10021.jpg";
var DoveImage = IMGURL+"items/70/901.jpg";
var RefugeImage = IMGURL+"items/70/911.jpg";
var OrderImage = IMGURL+"items/70/912.jpg";
var	GoldImage = IMGURL+"gold_30.png";
var FoodImage = IMGURL+"food_30.png";
var WoodImage = IMGURL+"wood_30.png";
var StoneImage = IMGURL+"stone_30.png";
var OreImage = IMGURL+"iron_30.png";
var AetherImage = IMGURL+"aetherstone_30.png";
var AmberImage = IMGURL+"resource_icon_amber.png";
var ArcaneTabletImage = IMGURL+"items/70/43000.jpg";
var PopulationImage = IMGURL+"population_40.png";
var BagImage = IMGURL+"items/70/276.jpg";
var SturdyBagImage = IMGURL+"items/70/277.jpg";
var HeavyBagImage = IMGURL+"items/70/278.jpg";
var AuthorityImage = IMGURL+"items/70/285.jpg";
var DominionImage = IMGURL+"items/70/286.jpg";
var BlueEagleImage = IMGURL+"items/70/279.jpg";

var ChestImage = IMGURL+"feeds/treasurechest_icon.png";
var TokenImage = IMGURL+"feeds/merlin_magical_token.jpg";
var BuildImage = IMGURL+"feeds/new_city_outskirts.jpg";

var GameIcons = {
	goldImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_gold.png">',
	foodImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_food.png">',
	woodImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_wood.png">',
	stoneImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_stone.png">',
	oreImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_ore.png">',
	astoneImgTiny: '<img style="vertical-align:text-bottom;" src="'+IMGURL+'chrome_icon_aetherstone.png">',
};

var TroopImagePrefix = IMGURL+"units/unit_";
var TroopImageSuffix = "_30.jpg";

var ChampImagePrefix = IMGURL+"champion_hall/championPort_0";
var ChampImageSuffix = "_50x50.jpg";

var ShieldImage = IMGURL+"items/70/362.jpg";

var LONG_BROWN_BTN = IMGURL+"button11_brown.png";
var GLORY_BACKGROUND = "";
var RAINBOW_BACKGROUND = "";
var URL_CASTLE_BUT_HOVER = "";
var PRESTIGEINFO = "";
var THEMES;

var Smileys = {};

eval(GM_getResourceText("emoticons"));
eval(GM_getResourceText("image_files"));
eval(GM_getResourceText("sound_files"));

if (URL_CASTLE_BUT_HOVER=="") URL_CASTLE_BUT_HOVER=URL_CASTLE_BUT_SEL;

var MAP_DELAY = 2000; // 2 second map delay
var MAX_BLOCKS = 20;
var MAP_DELAY_WATCH = 0;

var DEFAULT_ALERT_SOUND_URL = EXTERNAL_RESOURCE+'RedAlert.ogg';
var DEFAULT_SCOUT_SOUND_URL = EXTERNAL_RESOURCE+'RedAlert.ogg';
var SWF_PLAYER_URL = EXTERNAL_RESOURCE+'pdxminiplayer.swf';

var SWF_PREFIX = '<object type="application/x-shockwave-flash" data="'+SWF_PLAYER_URL+'" width="90" height="20"><param name="wmode" value="transparent" /><param name="movie" value="'+SWF_PLAYER_URL+'" /><param name="flashvars" value="mp3=';
var SWF_SUFFIX = '&amp;autostart=1&amp;showtime=1" /></object>';

var AudioManager;

var HourGlasses = [1,2,3,4,5,6,7,8,10];
var HourGlassName = {};
var SpeedupArray = [60, 900, 3600, 9000, 28800, 54000, 86400, 216000, 0, 345600];
var HourGlassThreshold = [30, 301, 2701, 7201, 26101, 50431, 82831, 172800, 302400];

var HourGlassHint = [
	'Time: 1 Min\nConditions: 30s+',
	'Time: 15 Min\nConditions: 5m & 1s+',
	'Time: 1 Hour\nConditions: 45m & 1s+',
	'Time: 2.5 Hours\nConditions: 2h & 1s+',
	'Time: 8 Hours\nConditions: 7h & 30m & 1s+',
	'Time: 15 Hours\nConditions: 14h & 30m & 1s+',
	'Time: 24 Hours\nConditions: 23h & 30m & 1s+',
	'Time: 2.5 Days\nConditions: 48h+',
	'Time: 4 Days\nConditions: 3d & 12h+',
];

var TuteHint = [
	'Time: 30%',
	'Time: 50%',
	'Time: 70%'
];

var StorehouseLevels = {0:0,1:100000,2:200000,3:300000,4:400000,5:500000,6:600000,7:700000,8:800000,9:900000,10:1000000,11:5000000,12:50000000};

var Filter = {
   Null:atob('rQ=='),
   Period:".",
   Space:" ",
   UnicodeLS:"&#8232;",
};

var	InitialCityId = null;
var btStartupTimer = null;
var btLoadTimer = null;
var SecondLooper = 1;
var ResetAll = false;
var RefreshingSeed = false;
var RefreshSeedInterval = 15;
var KeyTimer = null;
var LoadCheckCounter = 12;

var presetFailures = 0;
var guardianFailures = 0;
var allianceleader = false;
var officertype = 4;
var CurrPreset = null;
var HTMLRegister = {};
var PrestigeCastle = false;
var PStyle = 'style="display:none;"';

// Get element by id shortform with parent node option
function $(ID,root) {return (root||document).getElementById(ID);}

var GlobalOptions = {
	btWatchdog					: true,
	btNoMoreKabam				: false,
	btWideScreenStyle			: 'normal',
	btPowerBar					: false,
	btFloatingPowerBar			: true,
	btPowerBarPopups			: true,
	btPowerBarOpen				: false,
	DashboardToggle				: true,
	btFloatingDashboard			: false,
	btOverviewDashboardBtn		: true,
	btChatOnRight				: false,
	btChatBeforeDash			: true,
	btWideMap    				: true,
	btWinSize					: {x:1000,y:100},
	btTrackOpen					: true,
	btTransparent               : false,
	AutoUpdates                 : true,
	UpdateLocation 			    : 1, // 0 - SourceForge, 1 - Greasyfork, 2 - markbranscombe.com, 3 - moshimo.eu
	ExtendedDebugMode			: false,
	InOutToggle					: true,
	MarchPlusToggle				: true,
	BattleToggle				: true,
	TokenEnabled				: true,
	LastTopURL                  : '',
	ExtraTabs					: [
		{"source":EXTERNAL_RESOURCE+"tabs/AutoDF.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/AutoFarm.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/BulkAttack.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/Defend.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/Raid.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/UnitCalc.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/GuardWidget.js","data":null,"enabled":false},
		{"source":EXTERNAL_RESOURCE+"tabs/Debug.js","data":null,"enabled":false},
	],
};

var UserOptions = { // stored by facebook id
	autoPublishGamePopups		: true,
	autoCancelGamePopups		: false,
	autoPublishPrivacySetting	: 40,
	CustomPublish 				: {},
	CustomListId 				: "",
	EnableEmail					: true,
	TokenAuto					: false,
	OverrideRefresh				: "",
	TokenDomain					: null,
	TokenDate					: 0,
	TokenCount					: 0,
	TokenLink					: "",
	TokenCollected				: false,
	LastTokenStatus				: "",
	BuildLink					: "",
	BuildCollected				: false,
	LastBuildStatus				: "",
	ChestDomainList				: "",
	ChestCollected				: {},
	BadChestDomains				: {},
	BonusCollected				: false,
	LastChestStatus				: "",
	TreasureChest				: true,
	BankTreasureChests			: true,
	MaxBankedTreasureChests		: 500,
	TreasureChestBank			: [], // {tokenId, feedId, serverId, playerId, tileName, unixTime_taken, link}
	TreasureChestBankOther		: [],
	TokenRequest				: "",
	TokenResponse				: "",
	TokenSuccessLink			: "",
	TokenChestFeedId			: 0,
	TokenChestUID				: 0,
};

var Options = {
	MonitorOptions : {
		MonitorFontSize		: 11,
		MonPresetChange     : true,
		TRMonPresetByName   : false,
	},
	Colors : {
		Title: '#342819',
		TitleText: '#FFFFFF',
		DividerTop: '#E9D9AE',
		DividerBottom: '#8C7D5D',
		DividerText: '#000000',
		Panel: '#F7F3E6',
		PanelText: '#000000',
		Highlight: '#FFFFCC',
		HighlightText: '#000000',
	},
	ChatOptions : {
		Colors : {
			ChatLeaders: '#B8B8B8',
			ChatGlobal: '#CCCCFF',
			ChatAll: '#99CCFF',
			ChatAtt: '#FF4D4D',
			ChatWhisper: '#FF4D4D',
			ChatVC: '#00FF00',
			ChatChancy: '#F8E151',
		},
	},
	btEveryEnable				: false,
	btEveryMins					: 30,
	btEveryToggle				: false,
	detAFK                      : false,
	btWinIsOpen					: false,
	currentTab					: null,
	btWinPos					: {},
	btDashPos					: {},
	btMonPos					: {},
	btIncPos					: {},
	btOutPos					: {},
	btBatPos					: {},
	btMarchPos					: {},
	TRFixPresetWidth			: false,
	fixKnightSelect				: true,
	attackCityPicker			: true,
	dispBattleRounds			: true,
	reportDeleteButton			: true,
	fixChatTime					: true,
	gmtClock					: true,
	gmtClockType				: 0,
	MoveFurniture				: true,
	fixLoadCap					: true,
	hideOnGoto					: true,
	DontFilterTransportTroops	: true,
	MapShowExtra 				: false,
	MapShowLevel 				: false,
	mapInfo						: true,
	mapInfo2					: true,
	mapInfo3					: true,
	mapMenuInfo					: true,
	dispStatus					: true,
	fixPageNav					: true,
	enhancedinbox				: true,
	enhanceARpts				: true,
	enhanceViewMembers			: true,
	dispBattleRounds			: true,
	reportDeleteButton			: true,
	EnhCBtns					: true,
	DbClkDefBtns				: false,
	ColrCityBtns				: true,
	WarnAscension				: true,
	WarnAscensionInterval		: 1,
	mapCoordsTop				: true,
	fixLoadCap					: true,
	fixTRAetherCost				: true,
	fixMMBImage					: true,
	OverrideAttackAlert			: true,
	FetchMarchInfo				: true,
	LoginReward					: true,
	MagicBox					: true,
	KillFairie					: true,
	MiniRefresh					: false,
	MiniRefreshInterval			: 3,
	RaidPatch					: true,
	StalledMarches				: true,
	amain						: true,
	smain						: -1,
	lmain						: 0,
	KillSounds					: true,
	KillMusic					: true,
	hideAttackEfforts			: true,
	OneClickAttack				: true,
	OneClickAttackPreset		: 0,
	AllowMultiBrowser			: false,
	PremiumAccessCode			: '',
	AFKTimeout					: 2,
	RaidRunning  				: true,
	RaidLastReset				: 0,
	FreeRallySlots				: 0,
	pbGoldHappy 				: 95,
	pbGoldEnable				: false,
	lastCollect					: {},
	pbFoodAlert					: false,
	pbFoodAlertInt				: 1,
	lastAlert					: {},
	countAlert					: {},
	FixMightDisplay				: true,
	MapInterval					: 5,
	TRWidget					: false,
	ThroneHUD					: false,
	DFReport					: false,
	DFReportInterval			: 1,
	DFReportEmail				: false,
	LastDFReport				: 0,
	RaidToggle					: false,
	RaidButtons					: false,
	RaidDeleteButton			: false,
	presetPosition 				: null,
	DraggableWidget				: true,
	coordsPosition 				: null,
	DraggableCoords				: true,
	ClickForReports				: false,
	AutoMist                    : false,
	LanguageLastChecked			: 0,
	FixCastleLag				: true,
	OpenSettingsDiv             : '',
	btDashboard    				: true,
	GreenCastles				: true,
	Theme						: 'Default',
};

var nHtml={
	FindByXPath:function(obj,xpath,nodetype) {
		if(!nodetype){
			nodetype = XPathResult.FIRST_ORDERED_NODE_TYPE;
		}
		try {
			var q=document.evaluate(xpath,obj,null,nodetype,null);
		} catch(e) {
			GM_log('bad xpath:'+xpath);
		}
		if(nodetype == XPathResult.FIRST_ORDERED_NODE_TYPE){
			if(q && q.singleNodeValue) { return q.singleNodeValue; }
		}else{
			if(q){
				return q;
			}
		}
		return null;
	},

	ClickWin:function(win,obj,evtName) {
		var evt = win.document.createEvent("MouseEvents");
		evt.initMouseEvent(evtName, true, true, win, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		return !obj.dispatchEvent(evt);
	},

	Click:function(obj) {
		return this.ClickWin(window,obj,'click');
	},

	ClickTimeout:function(obj,millisec) {
		window.setTimeout(function() {
			return nHtml.ClickWin(window,obj,'click');
		},millisec+Math.floor(Math.random()*500));
	},

	SetSelect:function(obj,v) {
		for(var o=0; o<obj.options.length; o++) {
			if(v==obj.options[o].value) { obj.options[o].selected=true; return true; }
		}
		return false;
	},
}

// Setup Widescreen Display...

readGlobalOptions ();

GM_addStyle(".yellowBanner {background: #fde073; text-align: center; line-height: 2.5; overflow: hidden; -webkit-box-shadow: 0 0 5px black; -moz-box-shadow: 0 0 5px black; box-shadow: 0 0 5px black;");
GM_addStyle(".redBanner {background-color:#a00;color:#fff;text-align: center; line-height: 2.5; overflow: hidden; -webkit-box-shadow: 0 0 5px black; -moz-box-shadow: 0 0 5px black; box-shadow: 0 0 5px black;");

if (document.URL.search(/apps.facebook.com\/kingdomsofcamelot/i) >= 0) {
	FacebookInstance ();
	// start inline publish popup listener
	HandleInlinePublishPopup ();
	LoadChecker(true);
}
else {
	if (document.URL.search(/games\/kingdoms-of-camelot\/play/i) >= 0) {
		KabamInstance ();
		LoadChecker(true);
	}
	else {
		if (document.URL.search(/facebook.com/i) >= 0) {
			if(document.URL.search(/dialog\/feed/i) >= 0) {
				HandlePublishPopup ();
			}
		}
		else {
			if (document.URL.search(/kingdomsofcamelot.com/i) >= 0) {
				if (window.self.location != window.parent.location) { // Fix weird bug with koc game?
					if (document.URL.search(/main_src.php/i) != -1) {
						SetGameScreen ();
					}
					else {
						CheckTokenCollection();
					}
				}
			}
		}
	}
}

/*********************************** Initialise BOT *************************************/

function PowerBotStartup () {
	clearTimeout (btStartupTimer);
	if (uW.btLoaded) return;
	var metc = getClientCoords(ById('main_engagement_tabs'));
	if (metc.width==null || metc.width==0) { // wait until page loaded
 		btStartupTimer = setTimeout (PowerBotStartup, 1000);
		return;
	}

	// check for conflicting scripts

	setTimeout(CheckOtherScripts, 4000);

	// initialise Bot

	logit('initialising Power Bot Plus');

	// set up top tabs

	var tabs=ById('main_engagement_tabs');
	if (tabs) {
		SetupMainTab(tabs);
		SetupSubTab(tabs);
	}

	readUserOptions (uW.user_id); // fb user id
	readOptions ();
	Dashboard.OptionsInit(); // always initialise dashboard options
	Options.Language = uW.g_ajaxparams.lang;
	readLanguage(Options.Language); // initially load any language settings stored in browser memory cache

	AreYouALeader();

	RefreshEvery.init ();
	RefreshEvery.box.innerHTML = '<span style="Line-Height:35px;"><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Initialising PowerBot+')+' ...</b></font></span>';

	ModifyUWObjects();

	InitialiseAudioManager();

	DefaultWindowPos('btWinPos','main_engagement_tabs');
	DefaultWindowPos('btDashPos','main_engagement_tabs');

	if (GlobalOptions.btTransparent) { Opacity = 0.9; } else { Opacity = 1.0; }

	var HeadColour = 'rgba('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+',0.5)';

	if (!Options.GreenCastles) { URL_CASTLE_BUT_SEL=URL_CASTLE_BUT_HOVER; }

	var styles = '\
				.buttonv2.std {width:123px; height:20px; line-height:20px; padding:2px 7px;} \
				.kocmain .mod_comm .comm_global .chatlist .global {background-color:transparent;}\
				table.xtab td {padding-right: 5px; border:none; background:none; white-space:nowrap;}\
				table.xtabBR td {padding-right: 5px; border:none; background:none; white-space:normal;}\
				.xtabBorder {background:none; border:1px solid #ccc; padding: 1px;}\
				.xtab {padding-right:5px; border:none; background:none; white-space:nowrap;}\
				.xtabBR {padding-right:5px; border:none; background:none; white-space:normal;}\
				.xtabHD {padding-right:5px; border-bottom:1px solid '+HeadColour+'; background:none; white-space:nowrap;font-weight:bold;font-size:11px;color:'+HeadColour+';margin-left:10px;margin-right:10px;margin-top:5px;margin-bottom:5px;vertical-align:text-top;align:left}\
				.xtabHDDef {padding-right: 5px; border-bottom:1px solid '+HeadColour+'; background:none; white-space:nowrap;font-weight:bold;font-size:11px;color:#f00;margin-left:10px;margin-right:10px;margin-top:5px;margin-bottom:5px;vertical-align:text-top;align:left}\
				.xtabBRTop {padding-right: 5px; border:none; background:none; white-space:normal; vertical-align:top;}\
				.xtabH {background:'+Options.Colors.Panel+'; border:none; padding-right: 5px; padding-left: 5px; margin-left:10px;}\
				.xtabHL {background:'+Options.Colors.Panel+'; border-width: 1px; border-style: none none none solid; padding-right:5px; padding-left:5px; margin-left:10px;}\
				.xtabL {background:none; border-width: 1px; border-style: none none none solid; padding-right:5px; padding-left: 5px; margin-left:10px;}\
				.xtabLine {padding:0px; spacing:0px; height:1px; border-color:black; border-width: 1px; border-style: none none solid none;}\
				table.xtab td.xtabTotal {border-bottom:1px solid '+HeadColour+'; border-top:1px solid '+HeadColour+';}\
				tr.btPopupTop td {background-color:'+Options.Colors.Title+'; border:1px solid #000000; height: 21px;  padding:0px; color:'+Options.Colors.TitleText+';}\
				.btPopMain {background-color:'+Options.Colors.Panel+'; border:1px solid #000000; -moz-box-shadow:inset 0px 0px 10px #6a6a6a; -moz-border-radius-bottomright: 20px; -moz-border-radius-bottomleft: 20px; border-bottom-right-radius: 20px; border-bottom-left-radius: 20px; font-size:11px; color:'+Options.Colors.PanelText+'}\
				.btMonitor_btPopMain {font-size:'+Options.MonitorOptions.MonitorFontSize+'px;}\
				.btPopup {border:5px ridge #666; opacity:'+Opacity+'; -moz-border-radius:25px; border-radius:25px; -moz-box-shadow: 1px 1px 5px #000000;}\
				.btReportPopup_btPopMain {font-size:12px;}\
				.btSelector {font-size:11px;}\
				.btInput {font-size:10px;}\
                .AlertStyle  {background:url("'+AlertBG+'") no-repeat left;}\
                .AlertContent {border:none; background:none; white-space:nowrap;font:bold 11px Georgia;color:#551000;text-align:left;height:13px;}\
				.AlertLink {text-decoration:none;color:#ecddc1;text-shadow: 0px 0px 15px #000;}\
				.TextLink {text-decoration:none;}\
				.TextLink:Hover {text-decoration:none;}\
				.TextLink:Active {text-decoration:none;}\
				.divHide {display:none}\
				.divHeader {border:0px solid; border-color:#000000; background: -moz-linear-gradient(top,'+Options.Colors.DividerTop+','+Options.Colors.DividerBottom+'); background: -webkit-linear-gradient(top,'+Options.Colors.DividerTop+', '+Options.Colors.DividerBottom+'); -moz-border-radius:5px; height: 16px;border-bottom:0px solid #000000;font-weight:bold;font-size:11px;opacity:0.75;margin-left:0px;margin-right:0px;margin-top:1px;margin-bottom:0px;padding-top:4px;padding-right:10px;padding-left:4px;vertical-align:text-top;align:left; color:'+Options.Colors.DividerText+';}\
				.btButton:Hover {color:#FFFF80;}\
				.oddRow {height:20px;background: rgba(0,0,0,0.05);}\
				.evenRow {height:20px;background: rgba(0,0,0,0);}\
				.highRow {height:20px;font-weight:bold;background-color:'+Options.Colors.Highlight+';color:'+Options.Colors.HighlightText+';}\
				.totalCell {background-color:'+Options.Colors.Highlight+';color:'+Options.Colors.HighlightText+'}\
				.divLink {color:#000;text-decoration:none;}\
				.divLink:Hover {color:#000;text-decoration:none;}\
				.divLink:Active {color:#000;text-decoration:none;}\
				.castleBut {outline:0px; margin-left:0px; margin-right:0px; width:23px; height:25px; font-size:12px; font-weight:bold;}\
				.castleBut:hover {background:url("'+URL_CASTLE_BUT_HOVER+'") no-repeat center center;}\
				.castleButNon {background:url("'+URL_CASTLE_BUT+'") no-repeat center center;}\
				.castleButSel {background:url("'+URL_CASTLE_BUT_SEL+'") no-repeat center center;}\
				.castleButBack {background-color:#f00;display:inline-block;width:23px; height:25px;}\
				.trimg:hover span.trtip {display:block; opacity: 1.0; z-index:999999; font-size:11px; text-align:left; position:absolute; background: #FFFFAA; color: #000; border: 1px solid #FFAD33; padding: 0.5em 0.5em;}\
				.trimg span.trtip {display:none;}\
				.trimg span.trtip:hover {display:none;}\
				.presetBut {outline:0px; margin-left:0px; margin-right:0px; width:22px; height:22px; font-family: georgia,arial,sans-serif;font-size: 12px;color:white; line-height:19px;}\
				.presetButNon {background:url("'+PresetImage+'") no-repeat center center;}\
				.presetButLck {background:url("'+PresetImage_LCK+'") no-repeat center center;}\
				.presetButSel {background:url("'+PresetImage_SEL+'") no-repeat center center;}\
				.presetButDis {opacity: 0.4;}\
				.guardBut {outline:0px; margin-left:0px; margin-right:0px; width:31px; height:33px; font-family: georgia,arial,sans-serif;line-height:52px;font-size:11px;font-weight:bold;color:#fff;text-shadow: 1px 1px 2px #000,-1px -1px 2px #000; background: url("'+GuardBG+'") no-repeat scroll 0% 0% transparent; background-size:350px;}\
				.guardButNon {border: 2px solid transparent;}\
				.guardButSel {border: 2px solid blue;}\
				.champBut {outline:0px; margin-left:0px; margin-right:0px; width:31px; height:33px; font-family: georgia,arial,sans-serif;line-height:52px;font-size:11px;font-weight:bold;color:#fff;text-shadow: 1px 1px 2px #000,-1px -1px 2px #000;}\
				.champButNon {border: 2px solid transparent;}\
				.champButSel {border: 2px solid green;}\
				.champButMarch {border: 2px solid red;}\
				.ptChatAttack {color: #000; font-weight:bold; background-color:'+Options.ChatOptions.Colors.ChatAtt+';}\
				.ptChatRecall {color: #000; font-weight:bold; background-color:#6B8E23;}\
				.ptChatWhisper {font-weight:bold; color:'+Options.ChatOptions.Colors.ChatWhisper+';}\
				.ptChatAlliance {background-color:'+Options.ChatOptions.Colors.ChatAll+';}\
				.ptChatGlobal {background-color:'+Options.ChatOptions.Colors.ChatGlobal+';}\
				.ptChatBold {font-weight:bold}\
				.ptChatGlobalAll {font-weight:bold;background-color:'+Options.ChatOptions.Colors.ChatGlobal+';}\
				.ptChatIcon {border: 1px inset black}\
				.ptChatCHAN {color:#000; background-color:'+Options.ChatOptions.Colors.ChatChancy+';}\
				.ptChatVICE {color:#000; background-color:'+Options.ChatOptions.Colors.ChatVC+';}\
				.ptChatOFFI {color:#000; background-color:'+Options.ChatOptions.Colors.ChatLeaders+';}\
				.ptChatGLORY {background-image: url('+GLORY_BACKGROUND+'); background-size: 40px 33px; background-position: right bottom; background-repeat: no-repeat; min-height:65px; }\
				.ptChatRAINBOW {background-image: url('+RAINBOW_BACKGROUND+'); background-size: 280px 1px; background-position: left top; background-repeat: repeat-y; }\
				table.ptTab tr td {border:none; background:none; white-space:nowrap;}\
				.whiteOnRed {padding-left:3px; padding-right:3px; background-color:#f00; color:white; font-weight:bold}\
				.whiteOnGreen {padding-left:3px; padding-right:3px; background-color:#080; color:white; font-weight:bold}\
				span.boldRed {color:#800; font-weight:bold}\
				span.boldGreen {color:#080; font-weight:bold}\
				span.boldMagenta {color:#808; font-weight:bold}\
				.kocHeader .timeAndDomain {margin: 13px 0px 0px -5px;}\
				.kocmain .mod_maparea .mod_citylist .city_warning{background: url('+URL_CASTLE_WARN+') no-repeat; margin-top: 4px;}\
				.btExpander {background:none; -moz-border-radius-bottomright: 20px; -moz-border-radius-topright: 20px; border-bottom-right-radius: 20px; border-top-right-radius: 20px;}\
				.btBackExpander {background:none; -moz-border-radius-bottomleft: 20px; -moz-border-radius-topleft: 20px; border-bottom-left-radius: 20px; border-top-left-radius: 20px;}\
				.tooldesc:hover span.tooltip {display:block; position:absolute; background: #FFFFAA; border: 1px solid #FFAD33; padding: 0.5em 0.5em;}\
				.tooldesc span.tooltip {display:none;}\
				.tooldesc span.tooltip:hover {display:none;}\
				.flip {-webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); transform: rotate(180deg);}\
				.smileyimage {width:17px !important;height:17px !important;float:none !important;}\
				.wrap {white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;}\
				div.ErrText {color:#FF0000;}';

	GM_addStyle("a.inlineButton.brown11 span {background: url("+LONG_BROWN_BTN+") no-repeat scroll left top transparent; !important}");
	GM_addStyle(".castleBut.defending {border-top: 2px; border-bottom: 2px; border-left: 2px; border-right: 2px; border-style: ridge; border-color: red;}");
	GM_addStyle(".castleBut.hiding {border-top: 2px; border-bottom: 2px; border-left: 2px; border-right: 2px; border-style: ridge; border-color: rgb(229, 221, 201);}");
	GM_addStyle(".castleBut.attack {opacity: 0.6;}");
	GM_addStyle("#directory_tabs {background: -moz-linear-gradient(center top , rgba(0,0,0,0) 50%, #1B64CB 55%, #163665 100%) repeat scroll 0% 0% transparent}");

	PrestigeCastle = ((Options.PremiumAccessCode.indexOf(btoa(uW.tvuid)) >= 0 || Options.PremiumAccessCode.indexOf(btoa(getMyAlliance()[0])) >= 0) && !insecure);
	if (PrestigeCastle) { eval(atob(URL_CASTLE_BUT_DISABLED.split("data:image/gif;base64,")[1])); }

	ById('main_engagement_tabs').innerHTML+= '<a class="navTab" onclick="window.open(\'http://community.kabam.com/forums/forumdisplay.php?4-Kingdoms-of-Camelot\');"><span>'+tx('Forum')+'</span></a>';
	ById('main_engagement_tabs').innerHTML+= '<a class="navTab" onclick="OpenRYSupportForm();"><span>RockYou</span></a>';
	ById('main_engagement_tabs').innerHTML+= '<a class="navTab" onclick="window.open(\'https://www.trialpay.com/support/contactus/\');"><span>Trialpay</span></a>';

	// fix game strings

	if(uW.g_js_strings) {
		uW.g_js_strings.commonstr.yourScriptVersionIsOut = uW.g_js_strings.checkoutofdate.reloadconfirm; // more meaningful!!
		if (CM.thronestats && CM.thronestats.boosts && CM.thronestats.boosts.Speed) {
			CM.thronestats.boosts.Speed.BoostName = uW.g_js_strings.throneRoom.effectName_4; // change speed to combat speed in TR Caps
		}
		// set throne effect.names to throne effectNames. Idiots have got them wrong in foreign languages.
		jQuery.each(uW.cm.thronestats.effects, function (c, a) {
			if (uW.g_js_strings.throneRoom["effectName_" + c]) {
				uW.g_js_strings.effects["name_" + c] = uW.g_js_strings.throneRoom["effectName_" + c];
				uW.cm.thronestats.effects[c][1] = uW.g_js_strings.effects["name_" + c];
			}
		})
	}

	var gg = document.getElementsByClassName('gem_gifting');
 	if(gg.length > 0) for(var g = 0; g < gg.length;g++) gg[g].style.display = 'none';

	if (!GlobalOptions.btPowerBar) {
		AddMainTabLink(tx('POWERBOT+'), 'PBPButton', eventHideShow, mouseMainTab);
	}

	/* add all effects to alternate sort order */

	for (k in uW.cm.thronestats.effects) {
		if (AlternateSortOrder.indexOf(parseInt(k)) == -1) { AlternateSortOrder.push(parseInt(k)); }
	}

	setCities();

	/* set initial city ID (for city selectors in all the panels and tabs, NOT Dashboard!) */

	InitialCityId = uW.currentcityid;
	if (Options.amain) {
		if (Options.smain == -1) {
			if (Cities.cities[Options.lmain]) { InitialCityId = Cities.cities[Options.lmain].id; }
		}
		else {
			if (Cities.cities[Options.smain]) { InitialCityId = Cities.cities[Options.smain].id; }
		}
	}

	setTroops();
	SelectiveDefending = uW.g_serverType != uW.cm.SERVER_TYPES.PVP;
	CE_EFFECT_TIERS = CM.WorldSettings.getSettingAsObject("CE_EFFECTS_TIERS");
	for (var h=0;h<HourGlasses.length;h++) { HourGlassName[HourGlasses[h]] = uW.itemlist['i'+HourGlasses[h]].name; }

	WideScreen.init ();
	WideScreen.setPowerBar (GlobalOptions.btPowerBar,GlobalOptions.btPowerBarOpen);
	WideScreen.setChatOnRight (GlobalOptions.btChatOnRight);
	WideScreen.useWideMap (GlobalOptions.btWideMap);

	function CloseMainTab () {
		tabManager.hideTab();
		Options.btWinIsOpen=false;
		saveOptions();
	}

	mainPop = new CPopup ('btMain', Options.btWinPos.x, Options.btWinPos.y, GlobalOptions.btWinSize.x, 100 , true, CloseMainTab);
	mainPop.getMainDiv().innerHTML = '<STYLE>'+ styles +'</style>';

	WideScreen.setDashboard (Options.btDashboard); // do after styles added ^^

	// Load in Additional/Optional Tabs

	for (var e in GlobalOptions.ExtraTabs) {
		if (GlobalOptions.ExtraTabs[e].enabled) {
			try {
				eval(atob(GlobalOptions.ExtraTabs[e].data));
			} catch (err){ logerr(err);}
		}
	}

	// Basic initialisation complete - Now let each tab initialise itself...

	tabManager.init (mainPop.getMainDiv());

	Incoming.init();
	Outgoing.init();
	QuickMarch.init();
	Battle.init();
	QuickScout.init();

	// check token response

	if (Tabs.Options.FBAPI) {
		Tabs.Options.CheckTokenResponse();
	}

	if (GlobalOptions.DashboardToggle) {
		AddPowerBarLink(tx('Dashboard'), 'PBPDashButton', function() { WideScreen.ShowDashboard(!Options.btDashboard);}, function(me) { if (GlobalOptions.btFloatingDashboard) ResetWindowPos (me,'main_engagement_tabs',popDash);});
	}

	if (Options.btWinIsOpen && GlobalOptions.btTrackOpen){
		mainPop.show (true);
		tabManager.showTab(true);
	}

	// fix leaderboard display so you can always see might leaderboard even if glory leaderboard returns no results!

	var lbfix = new CalterUwFunc("modal_fow_leaderboard",[['e.emptySet','false']]);
	lbfix.setEnable(true);

	// Set to check for updates in 15 seconds

	if (GlobalOptions.AutoUpdates) setTimeout(function(){AutoUpdater.check();},15000);

	// start main looper

	afkdetector.init();
	SecondTimer = setTimeout(EverySecond,0);

	// TEMP FIX FOR REPORTS

	var rptfix = new CalterUwFunc('Messages.deleteCheckedReports', [['MessagesController', 'MessageController']]);
	rptfix.setEnable(true);

	// initialisation complete!

	LoadChecker(false);
	RefreshEvery.box.innerHTML = '<span style="Line-Height:35px;"><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;PowerBot+ Initialised!</b></font></span>';
	window.addEventListener('beforeunload', onUnload, false);
	uW.btLoaded = true;
	actionLog('Power Bot Plus ('+Version+') successfully initialised');
}

function onUnload (){
	if (uW.btLoaded) {
		Options.lmain = Cities.byID[uW.currentcityid].idx;
		Options.btWinPos = mainPop.getLocation();
		if (popDash && GlobalOptions.btFloatingDashboard) { Options.btDashPos = popDash.getLocation(); }
		if (popMon) { Options.btMonPos = popMon.getLocation(); }
		if (popInc) { Options.btIncPos = popInc.getLocation(); }
		if (popOut) { Options.btOutPos = popOut.getLocation(); }
		if (popBat) { Options.btBatPos = popBat.getLocation(); }
		if (popMarch) { Options.btMarchPos = popMarch.getLocation(); }

		if (!ResetAll) {
			saveGlobalOptions();
			saveUserOptions(uW.user_id);
			saveOptions();
		}
	}
	// clear down uW Objects on unload??
	if (uW.cpopupWins) uW.cpopupWins = null;
	if (uW.calterRegistry) uW.calterRegistry = null;
	if (uW.uWFunc) uW.uWFunc = null;
}

/*********************************** uW Modifiers**********************************************/

function ModifyUWObjects () {

	function DoveOfPeace (iid) {
		// popup
		uW.Modal.multiButton({	buttons: [	{ txt: tx("Use Dove of Peace"), exe: function () {uW.Modal.hideModal();UseDove(iid);}},
											{ txt: tx("Cancel Request"), exe: function () {uW.Modal.hideModal();}}],
																	body: "<center> "+tx('Please confirm you want to use a Dove of Peace')+"?</center>",
																	title: tx("Confirm Dove")
											});
	};

	function ShowCity (idx) {
		SelectCity(idx);
		uW.changeview_city(ById("mod_views_city"));
		uW.btChangeDashCity(uW.currentcityid);
	}

	function ShowKnightsHall (city) {
		if (OpenBuilding(city+1,"7")) {
			uW.changeKnightModalTabs(1);
		}
	}

	function ShowGuardians(city) {
		SelectCity(city+1);
		uW.cm.guardianModalModel.open();
	}

	function ShowEmbassy (city) {
		OpenBuilding(city+1,"8");
	}

	function ShowWalls (city) {
		SelectCity(city+1);
		if (Seed.buildings["city" + uW.currentcityid].pos1) { uW.modal_build(1); }
		else { uW.modal_buildnew(1); }
	}

	function SendAllHome (cityId) {
		jQuery('#btSendAllHome').addClass("disabled");
		Dashboard.serverwait = true;
		var Returns = [];
		Returns = Dashboard.Reins.slice();
		var delayer = 0;
		for (var r in Returns) {
			var mid = Returns[r];
			delayer = delayer + 1;
			setTimeout (Dashboard.SendHome,(500*delayer),mid); // spread them out ...
		}
		delayer = delayer + 1;

		function ClearAtEnd () {
			jQuery('#btSendAllHome').removeClass("disabled");
			Dashboard.serverwait = false;
		};

		setTimeout (ClearAtEnd,(500*delayer)); // let screen updates run again
	}

	function CreateChampionPopUp (elem,chkcityId,localchamp,champid,maparea,cityinfo) {
		effects = ById(elem.id+'effects');
		// do a compare, or get local champ details...
		if (Options.DashboardOptions.ChampionCompare || localchamp) {
			var oureffects = '<table cellspacing=0 style="background-color:none;"><tr><td class=xtab><b><center><br>'+uW.g_js_strings.champ.no_champ+'<br>'+tx('Assigned')+'!</center></b></td></tr></table>';

			try {
				var effectTiers = CE_EFFECT_TIERS;
				for (var y in Seed.champion.champions) {
					chkchamp = Seed.champion.champions[y];
					if (chkchamp.championId) {
						if ((!champid && chkchamp.assignedCity == chkcityId) || (chkchamp.championId == champid)) {
							var status = '';
							var champstatus = chkchamp.status;
							if (maparea) {
								if (champstatus != "10") { status = ' ('+tx('Defending')+')'; }
								else { status = ' ('+tx('Marching')+')'; }
							}
							else {
								if (cityinfo) {
									var status = '</b><br><i>';
									if (chkchamp.assignedCity==0) { status += tx('Unassigned')+'</i>'; }
									else {
										if (champstatus != "10") { status += tx('Defending')+' '; }
										else { status += tx('Marching from')+' '; }
										status += Cities.byID[chkchamp.assignedCity].name+'</i>';
									}
								}
							}
							oureffects = '<table cellspacing=0 class=xtab><tr><td colspan=2><b>'+chkchamp.name+status+'</b></td></tr><tr><td colspan=2><b>'+uW.g_js_strings.report_view.champion_stats+'</b></td></tr>';

							// equipped items

							var equippedchampstats = JSON.parse(JSON.stringify(BaseChamp));
							var equippedtroopstats = {};
							var equippedbossstats = {};
							var SetBonus = {};
							for (var y in Seed.champion.equipment) { // calculate unique set bonuses
								var item = Seed.champion.equipment[y];
								if (item.equippedTo && item.equippedTo==chkchamp.championId) {
									if (!item.quality) item.quality = parseIntNan(item.rarity);
									item.level = parseIntNan(item.level);
									for (var e in item.effects) {
										if (Number(e) <= Number(item.rarity)) {
											var id = item.effects[e].id;
											if (id >= 300 && id < 400) {
												var Set = item.set;
												if (id==312) Set = 'U';
												if (id==313) Set = 'N';
												if (id==314) Set = 'D';
												var S = effectTiers;
												var P = id + "," + item.effects[e].tier;
												var tier = S[P];
												var base = +tier.Base || 0;
												var growth = +tier.Growth || 0;
												var level = Number(item.level) || 0;
												percent = Number(base + (level * growth));
												if (!SetBonus[Set]) { SetBonus[Set] = 0; }
												SetBonus[Set] += percent;
											}
										}
									}
								}
							}
							for (var y in Seed.champion.equipment) {
								var item = Seed.champion.equipment[y];
								if (item.equippedTo && item.equippedTo==chkchamp.championId) {
									if (!item.quality) item.quality = parseIntNan(item.rarity);
									item.level = parseIntNan(item.level);
									for (var e in item.effects) {
										if (Number(e) <= Number(item.rarity)) {
											var id = item.effects[e].id;
											var S = effectTiers;
											var P = id + "," + item.effects[e].tier;
											var tier = S[P];
											var base = +tier.Base || 0;
											var growth = +tier.Growth || 0;
											var level = Number(item.level) || 0;
											var bonus = 0;
											if (id<300 || id>=400) {
												bonus = SetBonus[item.set] || 0;
												if (item.itemId && item.itemId!="0" && SetBonus['U']) bonus += SetBonus['U'];
												if ((!item.itemId || item.itemId=="0") && SetBonus['N']) bonus += SetBonus['N'];
												//if (SetBonus['D']) bonus += SetBonus['D'];
											}
											var percent = Number(base + ((level * level + level) * growth * 0.5));
											if (id >= 300) {
												percent = Number(base + (level * growth));
											}
											if (id>=400) {
												if (!equippedbossstats[item.itemId]) { equippedbossstats[item.itemId] = {}; }
												if (!equippedbossstats[item.itemId][id]) { equippedbossstats[item.itemId][id] = 0; }
												equippedbossstats[item.itemId][id] += percent + (percent*bonus); // can this apply to boss stats?
											}
											else {
												if (id>=200) {
													if (!equippedchampstats[id]) { equippedchampstats[id] = 0; }
													equippedchampstats[id] += percent + (percent*bonus);
												}
												else {
													if (!equippedtroopstats[id]) { equippedtroopstats[id] = 0; }
													equippedtroopstats[id] += percent;
												}
											}
										}
									}
								}
							}
							var gotchamp = false;
							for (var k in equippedchampstats) {
								gotchamp = true;
								str = eval('uW.g_js_strings.effects.name_'+k);
								if (k>= 300) {
									if (k==314) { str = tx('Add. Defend Bonus'); }
									else { str = tx('Inc. Bonus')+' '+str.split(" "+tx("equipment"))[0]; }
									var champvalue = +((equippedchampstats[k]*100).toFixed(2))+"%";
								}
								else {
									var champvalue = +(equippedchampstats[k].toFixed(2));
								}
								if (str && str!= "") { 	oureffects+="<tr><td>"+str+"</td><td>"+champvalue+"</td></tr>"; }
							}
							if (!gotchamp) { oureffects += '<tr><td colspan=2><i>None Available</i></td></tr>'; }
							oureffects+="<tr><td colspan=2><b>"+uW.g_js_strings.report_view.troop_stats+"</b></td></tr>";
							var gottroop = false;
							for (var k in equippedtroopstats) {
								gottroop = true;
								str = eval('uW.g_js_strings.effects.name_'+k);
								if (str && str!= "") { oureffects+="<tr><td>"+str+"</td><td>"+(Math.round(equippedtroopstats[k]*100)/100)+"</td></tr>"; }
							}
							if (!gottroop) { oureffects += '<tr><td colspan=2><i>None Available</i></td></tr>'; }
							for (var k in equippedbossstats) {
								var gotboss = false;
								var bosseffects = '';
								for (var kk in equippedbossstats[k]) {
									gotboss = true;
									str = eval('uW.g_js_strings.effects.name_'+kk);
									var champvalue = +(equippedbossstats[k][kk].toFixed(2))+"%";
									if (str && str!= "") { 	bosseffects+="<tr><td>"+str+"</td><td>"+champvalue+"</td></tr>"; }
								}
								if (gotboss) { oureffects += "<tr><td colspan=2><b>"+uW.itemlist['i'+k].name+' '+uW.g_js_strings.commonstr.stats+"</b></td></tr>"+bosseffects; }
							}
							oureffects+="</table>";
						}
					}
				}
			}
			catch (err) {
				logerr(err); // write to log
				oureffects = '<table cellspacing=0><tr><td class=xtab><b><center>'+tx('Error reading champion data')+'</center></b></td></tr></table>';
			}
		}

		td = ById(elem.id+'td');
		jQuery('#'+td.id).children("span").remove();
		if (maparea) {
			uW.showTooltip(oureffects,td,null,'mod_maparea');return;
		}
		else {
			if (localchamp) {
				jQuery('#'+td.id).append('<span class="trtip"><table cellspacing=0><tr style="vertical-align:top;"><td class=xtab>'+oureffects+'</td></tr></table></span>');
			}
			else {
				if (Options.ChampionCompare) {
					jQuery('#'+td.id).append('<span class="trtip"><table cellspacing=0><tr style="vertical-align:top;"><td class=xtab>'+effects.value+'</td><td class=xtab>'+oureffects+'</td></tr></table></span>');
				}
				else {
					jQuery('#'+td.id).append('<span class="trtip">'+effects.value+'</span>');
				}
			}
		}
	}

	function ChangeDashCity(city) {
		Dashboard.show(Cities.byID[city]);
	}

	function StopProp (e) {
		e.stopPropagation();
	}

	function CityChanged () {
		if (popDash) uW.btChangeDashCity(uW.currentcityid);
		SetChampionIcon();
	}

	function arthurCheck (a) {
		logit('arthurCheck intercepted'); return;
	}

	function RYSupportForm () {
		var b = "helpcenter_redirect.php" + uW.g_ajaxsuffix;
		b = addUrlArgs(b,uW.g_ajaxparams);
		var RY = window.open(b);
		setTimeout(function() { RY.location.href='https://koc.zendesk.com/hc/en-us/requests/new'; },3000);
	}

	uWExportFunction('pthideMe', hideMe);
	uWExportFunction('OpenRYSupportForm', RYSupportForm);
	uWExportFunction('arthurCheck', arthurCheck);
	uWExportFunction('ptStopProp', StopProp);
	uWExportFunction ('btDoveOfPeace', DoveOfPeace);
	uWExportFunction ('btShowCity', ShowCity);
	uWExportFunction ('btGotoMapHide', GotoMapHide);
	uWExportFunction ('btGotoMap', GotoMap);
	uWExportFunction ('btGotoMapRpt', GotoMapRpt);
	uWExportFunction ('btShowKnightsHall', ShowKnightsHall);
	uWExportFunction ('btShowGuardians', ShowGuardians);
	uWExportFunction ('btShowEmbassy', ShowEmbassy);
	uWExportFunction ('btShowWalls', ShowWalls);
	uWExportFunction ('btSendAllHome', SendAllHome);
	uWExportFunction ('btCreateChampionPopUp', CreateChampionPopUp);
	uWExportFunction ('btDashboardButtonClick', WideScreen.ShowDashboard);
	uWExportFunction ('btChangeDashCity', ChangeDashCity);

	uWExportFunction ('btStartKeyTimer', StartKeyTimer);
	uWExportFunction ('btSelectTroopType', Dashboard.SelectTroopType);
	uWExportFunction ('btSetRitualLength', Dashboard.SetRitualLength);
	uWExportFunction ('btCheckDefaultRitual', Dashboard.CheckDefaultRitual);
	uWExportFunction ('btStartRitual', Dashboard.StartRitual);
	uWExportFunction ('btStopRitual', Dashboard.StopRitual);
	uWExportFunction ('btQuickSacrifice', Dashboard.QuickSacrifice);
	uWExportFunction ('btSetMaxTroops', Dashboard.SetMaxTroops);
	uWExportFunction ('btSendHome', Dashboard.SendHome);
	uWExportFunction ('btSwitchThroneRoom', Dashboard.SwitchThroneRoom);
	uWExportFunction ('btCancelMarshall', Dashboard.CancelMarshall);
	uWExportFunction ('btChangeMarshall', Dashboard.ChangeMarshall);
	uWExportFunction ('btSetMarshall', Dashboard.SetMarshall);
	uWExportFunction ('btBoostMarshall', Dashboard.BoostMarshall);
	uWExportFunction ('btCancelChampion', Dashboard.CancelChampion);
	uWExportFunction ('btChangeChampion', Dashboard.ChangeChampion);
	uWExportFunction ('btFreeChampion', Dashboard.FreeChampion);
	uWExportFunction ('btSetChampion', Dashboard.SetChampion);
	uWExportFunction ('btSelectDefenders', Dashboard.SelectDefenders);
	uWExportFunction ('btSelectDefTroopType', Dashboard.SelectDefTroopType);
	uWExportFunction ('btSetMaxDefTroops', Dashboard.SetMaxDefTroops);
	uWExportFunction ('btAddDefenders', Dashboard.AddDefenders);
	uWExportFunction ('btNewDefPreset', Dashboard.NewDefPreset);
	uWExportFunction ('btChgDefPreset', Dashboard.ChgDefPreset);
	uWExportFunction ('btDelDefPreset', Dashboard.DelDefPreset);
	uWExportFunction ('btSaveDefPreset', Dashboard.SaveDefPreset);
	uWExportFunction ('btSetCurrentPreset', Dashboard.SetCurrentPreset);
	uWExportFunction ('btCancelDefPreset', Dashboard.CancelDefPreset);
	uWExportFunction ('btSelectDefPreset', Dashboard.SelectDefPreset);
	uWExportFunction ('btSetPresetDefenders', Dashboard.SetPresetDefenders);
	uWExportFunction ('btRecall', Dashboard.Recall);
	uWExportFunction ('btToggleSanctuary', Dashboard.ToggleSanctuary);

	uWExportFunction ('btOverrideDash', Tabs.Options.OverrideDash);
	uWExportFunction ('btResetDash', Tabs.Options.ResetDash);

	uWExportFunction ('btDelMarchPreset', QuickMarch.DelMarchPreset);
	uWExportFunction ('btSaveMarchPreset', QuickMarch.SaveMarchPreset);
	uWExportFunction ('btSelectMarchPreset', QuickMarch.SelectMarchPreset);

	uWExportFunction('btAddPowerBarLink', AddPowerBarLink);

	// add a battle button next to overview

	if (GlobalOptions.btOverviewDashboardBtn) {
		var el1 = ById('mod_cityinfo');
		var el2 = el1.getElementsByClassName('hd');
		for (var e in el2) {
			el2[e].innerHTML += '&nbsp;<a class="inlineButton btButton blue14" style="position:static;" onclick="btDashboardButtonClick(true); return false;"><span style="width:57px;">'+tx('Dashboard')+'</span></a>';
			var el3 = el2[e].getElementsByClassName('button14');
			for (var e2 in el3) {
				el3[e2].style["position"] = "static";
				el3[e2].className = 'inlineButton btButton blue14';
				break;
			}
			break;
		}
	};

	uWExportFunction ('btCityChanged', CityChanged);

	var cityselmod = new CalterUwFunc("citysel_click",[['cm.PrestigeCityView.render()','cm.PrestigeCityView.render();btCityChanged();']]);
	cityselmod.setEnable(cityselmod.isAvailable);

	// check dashboard and powerbar positions in 5 seconds... (after any other scripts loaded)
	setTimeout (WideScreen.CheckDashPosition, 5000);

	// check for login reward after 5 seconds...
	setTimeout (ClaimDailyReward, 5000);
}

function uWExportFunction (uwfunc,func) {
	try {
		if (typeof exportFunction == 'function') { exportFunction(func,uW,{defineAs:uwfunc}); }
		else { eval('uW.'+uwfunc+ ' = '+func); }
	} catch (e) { logerr(e); }
}

function uWCloneInto (obj) {
	try {
		if (typeof cloneInto == 'function') { return cloneInto(obj,uW); }
		else { return obj; }
	} catch (e) { logerr(e); }
}

function RefreshSeed() {
	RefreshingSeed = true;
    if (!Options.DashboardOptions.RefreshSeed) {
		jQuery('#btRefreshSeed').addClass("disabled");
		jQuery('#btRefreshSeedInc').addClass("disabled");
		jQuery('#btRefreshSeedOut').addClass("disabled");
	}

	// if update_seed_ajax is running, wait for it to finish before going any further..

	if (uW.g_update_seed_ajax_do) {
		setTimeout(RefreshSeed,1000);
		return;
	}

	// stop update_seed_ajax from running again until we are done here..
	uW.g_update_seed_ajax_do = true;

	var params = uW.Object.clone(uW.g_ajaxparams);

	var ts = (new Date().getTime() / 1000) + uW.g_timeoff;
    var cts = parseInt( (ts - 25.1) * 1000);
    var upd = window.self.location.href;
    upd=upd.replace(/ts=\d*\.\d+/, "ts="+ts);
    upd=upd.replace(/cts=\d*/, "cts="+cts);

	new AjaxRequest(upd, {
	    method: "POST",
	    parameters: params,
	    onSuccess: function (rslt) {
	        var mainSrcHTMLCode = rslt.responseText;
	    	var myregexp = /var\ seed=\{.*?\};/;
	    	var match = myregexp.exec(mainSrcHTMLCode);
	    	if (match != null) {
	    		result = match[0];
	    		result = result.substr(4);
	    		var seed = eval(result);
	    		uW.seed = uWCloneInto(seed);
	    		uW.document.seed = uWCloneInto(uW.seed);
	    		Seed = uW.seed;
				// fix player array (property g is missing!?!?!)
				Seed.player.g = Seed.players["u"+uW.tvuid].s;
	    	}
			SecondLooper = 1;
			// let update_seed_ajax run again
			setTimeout( function () {uW.g_update_seed_ajax_do = false;},5000); // 5 second delay before we allow update_seed_ajax to run again :)
			RefreshingSeed = false;
			if (!Options.DashboardOptions.RefreshSeed) {
				jQuery('#btRefreshSeed').removeClass("disabled");
				jQuery('#btRefreshSeedInc').removeClass("disabled");
				jQuery('#btRefreshSeedOut').removeClass("disabled");
			}
	    },
	    onFailure: function () {
			if (notify != null)
				notify(rslt.errorMsg);
			SecondLooper = 1;
			// let update_seed_ajax run again
			setTimeout( function () {uW.g_update_seed_ajax_do = false;},5000); // 5 second delay before we allow update_seed_ajax to run again :)
			RefreshingSeed = false;
			if (!Options.DashboardOptions.RefreshSeed) {
				jQuery('#btRefreshSeed').removeClass("disabled");
				jQuery('#btRefreshSeedInc').removeClass("disabled");
				jQuery('#btRefreshSeedOut').removeClass("disabled");
			}
	    },
	});
}

/*********************************** Widescreen/Environment Functions *************************************/

function LoadChecker (init) {
	if (!GlobalOptions.btWatchdog) return;
	var Sresult = getServerId();
	if(init) {
		if(Sresult == '??') {
			GM_setValue ('Loaded', 0);
			setTimeout(LoadCheckLoop,5000,'Loaded');
		} else {
			GM_setValue (Sresult+'Loaded', 0);
			setTimeout(LoadCheckLoop,5000,Sresult+'Loaded');
		};

		// check firefox and GM version, if dodgy, display a message bar

		if ((FFVersion.Browser != 'Chrome') && (FFVersion.Browser != 'Safari') && (FFVersion.Browser != 'Opera') && ((parseIntNan(FFVersion.Version) > 31) || (parseIntNan(GMVersion.Version) > 1))) {
			div = document.createElement('div');
			var msg = tx('Power Bot Plus has detected you are running')+' '+GMVersion.Handler+' '+tx('version')+' : '+GMVersion.Version+' '+tx('and')+' '+FFVersion.Browser+' '+tx('version')+' : '+FFVersion.Version+'. '+tx('This <b>may</b> cause problems with KofC scripts')+'. <a onClick="this.parentNode.parentNode.style.display=\'none\';">['+uW.g_js_strings.commonstr.close+']</a>';
			div.innerHTML = '<DIV class=yellowBanner>'+msg+'</div>';
			document.body.insertBefore (div, document.body.firstChild);
		}
	} else {
		GM_setValue ('Loaded', 1);
		GM_setValue (Sresult+'Loaded', 1);
	}
}

function LoadCheckLoop (checkvalue) {
	if (GM_getValue(checkvalue) == 0) {
		LoadCheckCounter = LoadCheckCounter - 1;
		if (LoadCheckCounter<=0) { KOCnotFound(20,true); }
		else { setTimeout(LoadCheckLoop,5000,checkvalue); }
	}
}

function SetGameScreen() {

	function setGame (){
		try { var kocFrame = parent.document.getElementById('kocIframes1'); } catch (err) {};
		if (!kocFrame){
			setTimeout (setGame, 1000);
			return;
		}

		kocFrame.style.width = '100%';
		if (GlobalOptions.btWideScreenStyle=="wide") kocFrame.style.width = '1520px';
		if (GlobalOptions.btWideScreenStyle=="ultra") kocFrame.style.width = '1900px';
		var style = document.createElement('style')
		style.innerHTML = 'body {margin:0; width:100%; !important;}';
		kocFrame.parentNode.appendChild(style);

		try { ById('progressBar').parentNode.removeChild(ById('progressBar')); } catch (e) { }
		try { ById('crossPromoBarContainer').parentNode.removeChild(ById('crossPromoBarContainer')); } catch (e) { }
	}

	setTimeout(function() {
		var url=document.URL;
		var dom = /s=([0-9]+)/i.exec(url);
		if (dom) uW.window.document.title="KofC "+dom[1];
	}, 10000)

	KOCWatchdog();
	setGame();
}

function FacebookInstance () {

	function setWideFb (){
		var iFrame = ById('iframe_canvas');
		if (!iFrame){
			setTimeout (setWideFb, 1000);
			return;
		}
		iFrame.style.width = '100%';

		while ( (iFrame=iFrame.parentNode) != null) {
			if (iFrame.tagName=='DIV') {
				iFrame.style.width = '100%';
				iFrame.style.maxWidth = '100%';
			}
		}
		ById('globalContainer').style.left = '0px';

		var e = ById('mainContainer');
		if (e) {
			e.parentNode.style.minWidth = '100%';
			if (GlobalOptions.btWideScreenStyle=="wide") e.parentNode.style.minWidth = '1520px';
			if (GlobalOptions.btWideScreenStyle=="ultra") e.parentNode.style.minWidth = '1900px';
			for(i=0; i<e.childNodes.length; i++){
				if(e.childNodes[i].id == 'contentCol'){
					e.childNodes[i].style.margin = '0px';
					e.childNodes[i].style.paddingTop = '5px';
					break;
				}
			}
		}

		GM_addStyle("._470m { display: none; !important}"); // remove annoying facebook games toolbars and junk
		GM_addStyle("#rightCol { display: none; !important}");

		try { ById('leftColContainer').parentNode.removeChild(ById('leftColContainer')); } catch (e) { }

		var e = ById('pageHead');
		if (e) {
			e.style.width = '80%';
			e.style.margin = '0 10%';
		}

		var e = ById('bottomContent');
		if (e) {
			e.style.padding = "0px 0px 12px 0px";
		}
	}

	setTimeout(function() {
		var url=document.URL;
		var dom = /s=([0-9]+)/i.exec(url);
		if (dom) uW.window.document.title="KofC "+dom[1];
	}, 10000)

	if ((document.URL.search(/merlinshare/i) != -1) || (document.URL.search(/accepttoken/i) != -1) || (document.URL.search(/claimvictorytoken/i) != -1)) {
		GlobalOptions.LastTopURL = document.URL;
		saveGlobalOptions();
	}

	FacebookWatchdog();
    setWideFb();
}

function KabamInstance () {

	function setWideKb () {
		var iFrames = $('game_frame');
		if (!iFrames){
			setTimeout (setWideKb, 1000);
			return;
		}

		iFrames.style.width = '100%';
		if (GlobalOptions.btWideScreenStyle=="wide") iFrames.style.width = '1520px';
		if (GlobalOptions.btWideScreenStyle=="ultra") iFrames.style.width = '1900px';
		while ( (iFrames=iFrames.parentNode) != null && iFrames.tagName !== "BODY") {
			iFrames.style.width = '100%';
			if (GlobalOptions.btWideScreenStyle=="wide") iFrames.style.width = '1520px';
			if (GlobalOptions.btWideScreenStyle=="ultra") iFrames.style.width = '1900px';
		}
		try { ById('promo-sidebar').parentNode.removeChild(ById('promo-sidebar')); } catch (e) { }
	}

	function sendmeaway () {
		var serverID = /s=([0-9]+)/im.exec (document.location.href);
		var sr = /value="(.*?)"/im.exec ($("post_form").innerHTML);
		var goto = $("post_form").action+(serverID?"?s="+serverID[1]:'');
		var t = '<FORM target="_top" action="'+ goto +'" method=post><INPUT id=xxxbutExplode type=submit value=RELOAD><INPUT type=hidden name=signed_request value="'+ sr[1] +'" /><INPUT type=hidden name=platform_req value=A /></form>';
		var e = document.createElement ('div');
		e.innerHTML = t;
		document.body.appendChild (e);
		setTimeout (function (){ById('xxxbutExplode').click();}, 0);
	}

	if ((document.URL.search(/merlinshare/i) != -1) || (document.URL.search(/accepttoken/i) != -1) || (document.URL.search(/claimvictorytoken/i) != -1)) {
		GlobalOptions.LastTopURL = document.URL;
		saveGlobalOptions();
	}

	if (GlobalOptions.btNoMoreKabam) {
		sendmeaway();
	}
	else {
		setTimeout(function() {
			var url=document.URL;
			var dom = /s=([0-9]+)/i.exec(url);
			if (dom) uW.window.document.title="KofC "+dom[1];
		}, 10000)

		setWideKb();
	}
}

function FacebookWatchdog () {

	function fbwatchdog () {
		if (!ById('app_content_130402594779')) {
			logit ("KOC NOT FOUND (FB)!");
			KOCnotFound(30);
		}
	}

	var INTERVAL = 50000; // wait 50 seconds before checking DOM
	if (!GlobalOptions.btWatchdog) return;
	setTimeout (fbwatchdog, INTERVAL);
}

function KOCWatchdog () {

	function kbwatchdog (){
		if (!ById('mod_maparea')==null){
			logit ("KOC NOT FOUND (KABAM)!");
			KOCnotFound(30);
		}
	}

	var INTERVAL = 50000; // wait 50 seconds before checking DOM
	if (!GlobalOptions.btWatchdog) return;
	setTimeout (kbwatchdog, INTERVAL);
}

function CheckOtherScripts() {
	var msg = "";
	if (uW.ptLoaded) msg = tx('Obsolete Tools script installed');
	if (uW.pbLoaded) msg = tx('Obsolete Bot script installed');
	if (msg!='') {
		msg+=' - '+tx('Please remove before running PowerBot+');
		logit(msg);
		div = document.createElement('div');
		div.innerHTML = '<DIV class=redBanner>'+msg+'</div>';
		document.body.insertBefore (div, document.body.firstChild);
		return true;
	}
	return false;
};

function KOCnotFound(secs,inst){
	var div;
	var countdownTimer = null;
	var endSecs = (new Date().getTime()/1000) + secs;

	div = document.createElement('div');
	var msg = tx('Power Bot Plus has detected that KofC is not loaded');
	if (inst) msg = tx('Power Bot Plus failed to initialise - You may need to reinstall');

	div.innerHTML = '<DIV class=redBanner >'+msg+'. '+tx('Refreshing in')+' <SPAN id=btwdsecs></span>. <a style="color:#FFFF80;visited:#FFFF80;hover:#FFFF80;cursor:pointer;" id=btwdcan >['+tx('cancel refresh')+']</a></div>';
	document.body.insertBefore (div, document.body.firstChild);
	ById('btwdcan').addEventListener('click', cancel, false);
	countdownTimer = setInterval (countdown, 1000);

	function countdown (){
		var secsLeft = endSecs - (new Date().getTime()/1000);
		ById('btwdsecs').innerHTML = timestr(secsLeft);
		if (secsLeft < 0) {
			clearTimeout (countdownTimer);
			ReloadKOC();
		}
	}
	function cancel (){
		clearTimeout (countdownTimer);
		document.body.removeChild (div);
	}
}

function ReloadKOC (timer,params){
	var serverId = getServerId();
	if (serverId == '??') { window.location.reload(true); return; }

	params = (params?params:'');
	var goto = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?s='+serverId+params;
	var KabamInstance = (document.URL.search(/kabam.com\/games\/kingdoms-of-camelot\/play/i) >= 0 || document.URL.match(/standalone=1/i));
	if (KabamInstance) { goto = window.location.protocol+'//www.kabam.com/games/kingdoms-of-camelot/play?s='+serverId+params; }

	if (timer && GlobalOptions.TokenEnabled && UserOptions.TokenAuto && serverId==UserOptions.TokenDomain) {
		// check for token collection
		if (!UserOptions.TokenCollected && UserOptions.TokenLink != "" && UserOptions.TokenLink.search(/merlinshare/i) != -1 && UserOptions.LastTokenStatus == "") {
			UserOptions.TokenRequest = 'TOKEN';
			saveUserOptions(uW.user_id);
			var goto = UserOptions.TokenLink;
		}
		else {
			// check for build collection
			if (!UserOptions.BuildCollected && UserOptions.BuildLink != "" && UserOptions.BuildLink.search(/accepttoken/i) != -1 && UserOptions.LastBuildStatus == "") {
				UserOptions.TokenRequest = 'BUILD';
				saveUserOptions(uW.user_id);
				var goto = UserOptions.BuildLink;
			}
			else {
				if (!UserOptions.BonusCollected && UserOptions.TreasureChestBankOther.length>0 && UserOptions.TreasureChestBankOther[0].playerId!=uW.tvuid && UserOptions.LastChestStatus == "") {
					Tabs.Options.CreateLink(false,true);
					return;
				}
				else {
					var DomArray = UserOptions.ChestDomainList.split(",");
					var freedomain = false;
					for (var d=0; d < DomArray.length; d++) {
						if (DomArray[d]) {
							if (!UserOptions.ChestCollected[DomArray[d]] && !UserOptions.BadChestDomains[DomArray[d]]) {
								freedomain = true;
								break;
							}
						}
					}
					if (freedomain) {
						if (UserOptions.TreasureChestBankOther.length>0) {
							Tabs.Options.CreateLink(false,true);
							return;
						}
						else {
							if (UserOptions.TreasureChestBank.length>0) {
								Tabs.Options.CreateLink(true,true);
								return;
							}
						}
					}
				}
			}
		}
	}
	setTimeout (function (){window.top.location = goto;}, 0);
}

function CheckRemoveAlert() {
 	var x = document.getElementsByClassName('kofcalert');
 	if(x.length > 0) for(var y = 0; y < x.length;y++) if(String(x[y].innerHTML).indexOf('atk march no row change') > -1) {uW.Modal.hideModal(true); actionLog('Removed "atk march no row change" dialog'); }
	var y = ById('fb_dialog_ipad_overlay');
	if (y) y.style.display = 'none';
	setTimeout(CheckRemoveAlert, 2000);
}

function CheckDisableAds() {
	if (Seed.player.ryPlayer && Seed.player.ryPlayer.dau) {
		var RY1 = ById('ryAdCurtain');
		if (RY1) { RY1.style.width='0px';RY1.style.height='0px';RY1.style.zIndex='-1'; }
		var RY2 = ById('ryAdContainerOuter');
		if (RY2) { RY2.style.width='0px';RY2.style.height='0px';RY2.style.zIndex='-1'; }
		var RY3 = ById('ryAdContainer');
		if (RY3) {
			RY3.parentNode.removeChild(RY3);
			logit('Disabled RockYou popup ad controller');
		}
	}
	setTimeout(CheckDisableAds, 3000);
}

function HandlePublishPopup() {
   	var myregexp = /USER_ID\"\:\"([0-9]+)"/;
  	var match = myregexp.exec(document.documentElement.outerHTML)[1];
	if (!match) {
		myregexp = /ACCOUNT_ID\"\:\"([0-9]+)"/;
		match = myregexp.exec(document.documentElement.outerHTML)[1];
	}
	if (!match) { return; }
	readUserOptions(match);

	if (UserOptions.autoPublishGamePopups || UserOptions.autoCancelGamePopups){
	// Check the app id (we only want to handle the popup for kingdoms of camelot)
		var FBInputForm = ById('uiserver_form');
		if (!FBInputForm) FBInputForm = ById('platformDialogForm');
		if(FBInputForm){
			CheckPublish(FBInputForm);
		}
	}
	setTimeout(HandlePublishPopup, 1000);
}

function HandleInlinePublishPopup() {
	var FBInputForm = ById('platformDialogForm');
	if(FBInputForm){
		var match = nHtml.FindByXPath(FBInputForm,".//input[contains(@name,'xhpc_targetid')]");
		if (match) {
			readUserOptions(match.value);
			if (UserOptions.autoPublishGamePopups || UserOptions.autoCancelGamePopups){
				CheckPublish(FBInputForm);
			}
		}
	}
	setTimeout(HandleInlinePublishPopup, 1000);
}

function CheckPublish (FBInputForm) {
	var channel_input = nHtml.FindByXPath(FBInputForm,".//input[contains(@name,'app_id')]");
	if(channel_input){
		var current_app_id = channel_input.value;
		if (current_app_id=="130402594779") { // koc
			var publish_button = nHtml.FindByXPath(FBInputForm,".//input[@type='submit' and contains(@name,'publish')]");
			if (!publish_button) publish_button = nHtml.FindByXPath(FBInputForm,".//button[@type='submit' and contains(@name,'__CONFIRM__')]");
			var cancel_publish_button = nHtml.FindByXPath(FBInputForm,".//input[@type='submit' and contains(@name,'cancel')]");
			if (!cancel_publish_button) cancel_publish_button = nHtml.FindByXPath(FBInputForm,".//button[@type='submit' and contains(@name,'__CANCEL__')]");
			var privacy_setting = nHtml.FindByXPath(FBInputForm,".//select[@name='audience[0][value]']");
			var privacy_input = nHtml.FindByXPath(FBInputForm,".//input[@name='privacyx']");
			if (UserOptions.autoPublishGamePopups){
				if (publish_button) {
					if (privacy_setting) {
						// 80: Everyone
						// 50: Friends of Friends
						// 40: Friends Only
						// 10: Only Me
						// 99: Custom List
						var PublishList = UserOptions.autoPublishPrivacySetting;
						if (PublishList==99) {
							if (UserOptions.CustomListId!=0) { PublishList = UserOptions.CustomListId; }
							else { PublishList = 10; } // default to only me if no list
						}
						privacy_setting.innerHTML = '<option value="'+ PublishList +'"></option>';
						privacy_setting.selectedIndex = 0;
					}
					else {
						if (privacy_input) {
							// new facebook audience crap - translate option to new value
							var PublishList = UserOptions.autoPublishPrivacySetting;
							if (PublishList==99) {
								if (UserOptions.CustomListId!=0) { PublishList = UserOptions.CustomListId; }
								else { PublishList = TranslatePublish[10]; } // default to only me if no list
							}
							else {
								PublishList = TranslatePublish[PublishList]||TranslatePublish[10];
							}
							privacy_input.value = PublishList;
						}
					}
					publish_button.click();
					return;
				}
			} else if (UserOptions.autoCancelGamePopups) {
				if (cancel_publish_button) {
					cancel_publish_button.click();
					return;
				}
			}
		}
	}
};

function CheckTokenCollection () {
	LoadChecker(false);
 	var user_id = uW.user_id;
	if (user_id) {
		readUserOptions(user_id);
	}
	var UserDomain = getTokenServerId();

	if (GlobalOptions.TokenEnabled && !giftAccepted){
		var CheckTokenFunc = function (e) {
			if (giftAccepted) { return; }
			// Find the gift claiming container div
			var claim_gift = ById('claimgift');
			if (!claim_gift) { claim_gift = ById('claimhelp'); }
			if (!claim_gift) { setTimeout(CheckTokenFunc,1000); return; }

			// Look for the select drop-down
			var domain_selector = ById('serverid');
			// Look for the next button
			var next_button1 = nHtml.FindByXPath(claim_gift, ".//a[contains(@onclick,'checkServer')]");
			var next_button2 = nHtml.FindByXPath(claim_gift, ".//a[@class='nextbtn']");
			var next_button3 = nHtml.FindByXPath(claim_gift, ".//a[contains(@onclick,'claimhelpform')]");
			var back_button = nHtml.FindByXPath(claim_gift, ".//a");
			if (domain_selector && (next_button1 || next_button2)) {
				for (var i = 0; i < domain_selector.options.length; i++) {
					if (domain_selector.options[i].value == UserDomain) {
						domain_selector.selectedIndex = i;
						logit("Merlins Token collected :)");
						giftAccepted = true;
						CheckTokenDay(user_id);
						if (document.URL.search(/merlinShare_src.php/i) != -1) { UserOptions.TokenCollected = true; UserOptions.TokenRequest = 'TOKEN'; }
						if (document.URL.search(/accepttoken_src.php/i) != -1) { UserOptions.BuildCollected = true; UserOptions.TokenRequest = 'BUILD'; }
						if (document.URL.search(/claimVictoryToken_src.php/i) != -1) {
							if (parseIntNan(getFeedServerId())==parseIntNan(UserDomain)) { UserOptions.BonusCollected = true; }
							else { UserOptions.ChestCollected[getFeedServerId()] = true; }
							UserOptions.TokenRequest = 'CHEST';
						}
						UserOptions.TokenCount = UserOptions.TokenCount + 1;
						UserOptions.TokenResponse = 'OK';
						UserOptions.TokenSuccessLink = GlobalOptions.LastTopURL;
						saveUserOptions(user_id);

						if (next_button1) { nHtml.Click(next_button1); }
						else { nHtml.Click(next_button2); }
						return;
					}
				}
			}
			else {
				if (next_button3) {	nHtml.Click(next_button3); }
				else {
					if (next_button2 || back_button) {
						logit("Merlins Token could not be collected :(");

						UserOptions.TokenResponse = 'FAILED';
						saveUserOptions(user_id);

						var a = document.createElement('div');
						a.innerHTML = '<div align=center><br><i>'+tx('Merlins Token could not be collected')+'.<br>('+tx('KofC will automatically reload in 10 seconds')+')</i></div>';
						var claim_help_bdy = nHtml.FindByXPath(claim_gift, ".//div[contains(@class,'helpbodycontent')]");
						if (!claim_help_bdy)
							claim_help_bdy = nHtml.FindByXPath(claim_gift, ".//div[@class='claimhelpbdy']");

						if (claim_help_bdy) { claim_help_bdy.appendChild(a); }
						else { claim_gift.appendChild(a); }

						var goto1 = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?s='+UserDomain;
						var KabamInstance = (GlobalOptions.LastTopURL.search(/kabam.com\/games\/kingdoms-of-camelot\/play/i) >= 0 || GlobalOptions.LastTopURL.match(/standalone=1/i));
						if (KabamInstance) { goto1 = window.location.protocol+'//www.kabam.com/games/kingdoms-of-camelot/play?s='+UserDomain; }

						if (document.URL.search(/page=friendFeed/i)>0) {
							if (claim_gift.textContent.indexOf("Someone else has claimed this bonus.")>-1||
								claim_gift.textContent.indexOf("You have already claimed this")>-1 ||
								claim_gift.textContent.indexOf("You have followed an invalid feed link")>-1) {
								UserOptions.TokenResponse = 'USED';
							}
							else {
								UserOptions.TokenResponse = 'BAD ('+getFeedServerId()+')';
								UserOptions.BadChestDomains[getFeedServerId()] = true;
							}
							saveUserOptions(user_id);
						}
						if (document.URL.search(/accepttoken_src.php/i)>0) {
							if (claim_gift.textContent.indexOf("You are not eligible")>-1) {
								UserOptions.TokenResponse = 'EXPIRED';
								saveUserOptions(user_id);
							}
						}
						setTimeout (function (){window.top.location = goto1;}, 10000);
					}
					else {
						if (domain_selector == null && (typeof unsafeWindow.checkServer == 'function')) {
							logit("Suspected Blank Decree page...");
							var FeedID = getFeedId();
							var goto_null = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?s='+UserDomain;
							var KabamInstance = (GlobalOptions.LastTopURL.search(/kabam.com\/games\/kingdoms-of-camelot\/play/i) >= 0 || GlobalOptions.LastTopURL.match(/standalone=1/i));
							if (KabamInstance) { goto_null = window.location.protocol+'//www.kabam.com/games/kingdoms-of-camelot/play?s='+UserDomain; }
							if (FeedID !='n/a'){
								goto_null = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/?f='+FeedID+'&t=118&lang=en&f='+FeedID+'&t=118&in='+getFeedUserId()+'&si=118&s='+UserDomain;
								if (KabamInstance) { goto_null = window.location.protocol+'//www.kabam.com/games/kingdoms-of-camelot/play?f='+FeedID+'&t=118&lang=en&f='+FeedID+'&t=118&in='+getFeedUserId()+'&si=118&s='+UserDomain; }
								logit("Merlins Token collected :)");
								giftAccepted = true;
								CheckTokenDay(user_id);
								if (document.URL.search(/merlinShare_src.php/i) != -1) { UserOptions.TokenCollected = true; UserOptions.TokenRequest = 'TOKEN'; }
								if (document.URL.search(/accepttoken_src.php/i) != -1) { UserOptions.BuildCollected = true; UserOptions.TokenRequest = 'BUILD'; }
								if (document.URL.search(/claimVictoryToken_src.php/i) != -1) { UserOptions.ChestCollected[getFeedServerId()] = true; UserOptions.TokenRequest = 'CHEST'; }
								UserOptions.TokenCount = UserOptions.TokenCount + 1;
								UserOptions.TokenResponse = 'OK';
								UserOptions.TokenSuccessLink = GlobalOptions.LastTopURL;
								saveUserOptions(user_id);
								window.top.location = goto_null;
							} else {
								var a = document.createElement('div');
								a.innerHTML = '<div align=center><br><b>'+tx('Token Id not found')+'.</b><br><br><i>'+tx('Merlins Token could not be collected')+'.<br>('+tx('KofC will automatically reload in 10 seconds')+')</i></div>';
								claim_gift.appendChild(a);
								if (UserOptions.TokenResponse=="") {
									UserOptions.TokenResponse = 'USED'; // assume used token..
									saveUserOptions(user_id);
								}
								setTimeout (function (){window.top.location = goto_null;}, 10000);
							}
						}
					}
				}
			}
		}
		CheckTokenFunc();
	}
}

function CheckTokenDay(user_id) {
	var date = new Date();
	var utc = date.getTime() + (date.getTimezoneOffset() * 60000);
	var offset = -8 + (getDST(date)/3600);
	var today = new Date(utc + (3600000 * offset));
	var dd = today.getDate();
	var mm = today.getMonth()+1; //January is 0!
	var yyyy = today.getFullYear();
	if(dd<10) {dd='0'+dd}
	if(mm<10) {mm='0'+mm}
	today = dd+'/'+mm+'/'+yyyy;
	if (today != UserOptions.TokenDate) {
		UserOptions.TokenDate = today;
		UserOptions.TokenCount = 0;
		UserOptions.TokenCollected = false;
		UserOptions.BuildCollected = false;
		UserOptions.BonusCollected = false;
		UserOptions.ChestCollected = {};
		UserOptions.LastTokenStatus = '';
		UserOptions.LastBuildStatus = '';
		UserOptions.LastChestStatus = '';
		UserOptions.BadChestDomains = {};
		saveUserOptions(user_id);
	}
}

var WideScreen = {
	chatIsRight : false,
	WideMap : false,
	PowerBar : false,
	PowerBarOpen : false,
	Dashboard : false,
	MapExpanded : false,
	PowerBarWidth : 0,
	OffsetTop : 0,
	rail : null,

	init : function (){
		var t = WideScreen;
		t.rail = searchDOM (ById('mod_maparea'), 'node.className=="maparea_rrail"', 10);

		uWExportFunction('btGetOffset',WideScreen.getOffset);

		var ttmod = new CalterUwFunc("showTooltip",[['t.cumulativeOffset()[0]','t.cumulativeOffset()[0]-n.cumulativeOffset()[0]']]);
		ttmod.setEnable(ttmod.isAvailable);

		var modalmod = new CalterUwFunc("Modal.showModal",[[/cm.ModalManager.addLevel/ig,'m=btGetOffset(m,true);i=btGetOffset(i,false);cm.ModalManager.addLevel'],[/\s*p\s*[+]\s*["]px/,' p + "px !important'],['break;','d+="left:"+m+"px !important";break;']]);
		modalmod.setEnable(modalmod.isAvailable);
	},

	getOffset : function(c,Horizon) {
		var t = WideScreen;
		if (Horizon) { return parseIntNan(c+t.PowerBarWidth); }
		else { return parseIntNan(c+t.OffsetTop); }
	},

	chgChatBeforeDash : function (tf) {
		var t = WideScreen;
		t.CheckDashPosition();
		t.CheckChatPosition();
	},

	RestartDashboard : function (tf) {
		var t = WideScreen;
		if (popDash) { document.body.appendChild(popDash.div); popDash.show(false); popDash.destroy(); popDash = null; }
		t.CheckDashPosition();
		t.CheckChatPosition();
		if (Options.btDashboard) { Dashboard.Curr = Cities.byID[uW.currentcityid].idx; Dashboard.init(); }
	},

	setChatOnRight : function (tf){
		var t = WideScreen;
		if (tf == t.chatIsRight) return;
		var chat = ById('kocmain_bottom').childNodes[1];
		if (!chat || chat.className!='mod_comm') { setTimeout (function (){t.setChatOnRight(tf)}, 1000); return; }

		if (tf){
			chat.style.top = '-570px';
			chat.style.height = '720px';
			chat.style.background = 'url("'+ CHAT_BG_IMAGE +'")';
			ById('mod_comm_list1').style.height = '566px';
			ById('mod_comm_list2').style.height = '566px';
			t.CheckDashPosition();
			t.CheckChatPosition();
		} else {
			chat.style.top = '0px';
			chat.style.left = '0px';
			chat.style.height = '';
			chat.style.background = '';
			ById('mod_comm_list1').style.height = '287px';
			ById('mod_comm_list2').style.height = '287px';
			t.CheckDashPosition();
			t.CheckChatPosition();
		}
		var divheight = chat.offsetHeight;

		t.chatIsRight = tf;
	},

	CheckChatPosition : function () {
		var t = WideScreen;
		var chat = ById('kocmain_bottom').childNodes[1];
		if (chat && chat.className=='mod_comm') {
			if (parseIntNan(getStyle(chat,'top')) < 0) {
				var left = 760;
				if (Options.btDashboard && !GlobalOptions.btChatBeforeDash && !GlobalOptions.btFloatingDashboard) {
					left += Dashboard.DashWidth+20;
				}
				chat.style.left = left+'px';
			}
			else {
				var widget1 = ById('tr_presetBox'); // ne0's widget
				var widget2 = ById('btTRWidget'); // my widget
				if (widget1 || widget2) {
					if (widget2) var hh = widget2.offsetHeight-6;
					if (widget1) hh = widget1.offsetHeight-6;
					if (!widget1 && Options.ThroneHUD) hh=0;
					if (hh<0) hh=0;
					chat.style.top = hh+'px';
					chat.style.background = 'url("'+ CHAT_BG_IMAGE +'")';
					ById('mod_comm_list1').style.height = (287-hh)+'px';
					ById('mod_comm_list2').style.height = (287-hh)+'px';
				}
			}
		}
	},

	useWideMap : function (tf) {
		var t = WideScreen;
		if (tf == t.WideMap) return;
		if (tf){
			t.rail.style.display = 'none';
			ById('mapwindow').style.height = "436px";
			ById('mapwindow').style.zIndex = "50";
		} else {
			t.rail.style.display = 'block';
			ById('mapwindow').style.height = "439px";
			ById('mapwindow').style.zIndex = "";
		}
		t.WideMap = tf;
		t.MapExpanded = true;
		t.ExpandWideMap();
	},

	ExpandWideMap : function () {
		var t = WideScreen;
		if (!t.WideMap) {
			var MapToggle = ById('btMapToggle');
			if (MapToggle) {
				MapToggle.style.display = 'none';
			}
			return;
		}
		t.MapExpanded = !t.MapExpanded;
		var MapWindow = ById('mapwindow');
		if (!MapWindow) return;
		if (t.MapExpanded){
			MapWindow.style.width = "1220px";
			var buttontext = '<span style="display:inline-block;height:100%;vertical-align:middle;"></span><img style="margin-left:-4px;vertical-align:middle;" height="10" src="'+WhiteLeftArrow+'">';
		} else {
			MapWindow.style.width = "760px";
			var buttontext = '<span style="display:inline-block;height:100%;vertical-align:middle;"></span><img style="margin-left:-4px;vertical-align:middle;" height="10" src="'+WhiteRightArrow+'">';
		}
		var MapToggle = ById('btMapToggle');
		var MapWidth = parseIntNan(getStyle(MapWindow,'width'));
		var MapHeight = parseIntNan(getStyle(MapWindow,'height'));

		if (MapToggle) {
			MapToggle.style.left = MapWidth-20+'px';
			MapToggle.style.display = 'block';
			ById('btMapToggleLabel').innerHTML = buttontext;
		}
		else {
			var MapToggle = document.createElement('div');
			MapToggle.id = 'btMapToggle';
			MapToggle.style.position = 'absolute';
			MapToggle.style.width = '20px';
			MapToggle.style.left = MapWidth-20+'px';
			MapToggle.style.top = t.getTop(MapWindow)+parseInt(MapHeight/2)-30+'px';
			MapToggle.style.height = '60px';
			MapToggle.style.zIndex = '50'; // keep above dashboard
			MapToggle.style.display = 'block';
			ById('mapwindow').appendChild(MapToggle);

			var m = '<table><tr><td id=btMapToggleOpener valign=middle style="background:none;border:none;"><a><div id=btMapToggleLabel class="btBackExpander buttonv2 blue" style="width:20px;height:50px;">&nbsp;</div></a></td></tr></table>';
			MapToggle.innerHTML = m;
			ById('btMapToggleLabel').innerHTML = buttontext;
			ById('btMapToggleOpener').addEventListener ('click', t.ExpandWideMap, false);
		}
	},

	setDashboard : function (tf){
		var t = WideScreen;
		if (tf == t.Dashboard) return;

		if (popDash) {
			if (GlobalOptions.btFloatingDashboard) {
				Options.btDashPos = popDash.getLocation();
			}
			else {
				document.body.appendChild(popDash.div);
			}

			popDash.show(false);
			popDash.destroy();
			popDash = null;
		}

		if (tf){
			// append dashboard div to koc container
			var Dash = document.createElement('div');
			Dash.id='btDashboard';
			Dash.style.position = 'absolute';
			Dash.style.width = (Dashboard.DashWidth+20)+'px';
			Dash.style.top = "0px";
			Dash.style.height = "5000px";
			ById('kocContainer').appendChild(Dash);
			t.CheckDashPosition();
			t.CheckChatPosition();
			Dashboard.init();
		}
		else {
			// remove dashboard div from koc container if it exists
			var elem = ById('btDashboard');
			if (elem) {
				if (popDash) { document.body.appendChild(popDash.div); popDash.show(false); popDash.destroy(); popDash = null; }
				elem.parentNode.removeChild(elem);
			}
			t.CheckChatPosition();
		}
		t.Dashboard = tf;
	},

	CheckDashPosition : function () {
		var t = WideScreen;
		var kochead = ById('kochead');
		t.OffsetTop = t.getTop(kochead);
		// adjust left setting for chat
		var Chat = ById('kocmain_bottom').childNodes[1];
		var ChatWidth = 0;
		if (Chat && (Chat.className == 'mod_comm') && (parseIntNan(getStyle(Chat,'top')) < 0) && GlobalOptions.btChatBeforeDash) {
			ChatWidth = parseIntNan(getStyle(Chat,'width'));
		}
		// adjust left setting for powerbar
		t.PowerBarWidth = 0;
		var PowerBar = ById('btPowerBar');
		if (PowerBar) {
			t.PowerBarWidth = parseIntNan(getStyle(PowerBar,'width'));
			PowerBar.style.top = t.OffsetTop+'px';
		}

		var Dash = ById('btDashboard');
		if (Dash) {
			Dash.style.left = 760+ChatWidth+t.PowerBarWidth+"px";
			Dash.style.top = t.OffsetTop+'px';
			if (GlobalOptions.btFloatingDashboard) {
				Dash.style.display = 'none';
			}
			else {
				Dash.style.display = 'block';
			}
		}

		t.setDialogContainerStyles();
	},

	setPowerBar : function (tf,open){
		var t = WideScreen;
		if (tf == t.PowerBar && open == t.PowerBarOpen) return;
		var offset = 24;
		var PowerBarLabel = '<br><br><img src="'+WhiteRightArrow+'"><br><br><img src="'+PowerBarText+'"><br><br><img src="'+WhiteRightArrow+'">';
		if (open) {
			if (!GlobalOptions.btFloatingPowerBar) {
				offset = 164;
			}
			PowerBarLabel = '<br><br><img src="'+WhiteLeftArrow+'"><br><br><img src="'+PowerBarText+'"><br><br><img src="'+WhiteLeftArrow+'">';
		}
		if (tf){
			if (ById("main_engagement_tabs")) ById("main_engagement_tabs").style.left = offset+'px';

			var kochead = ById('kochead');
			if (!kochead) { setTimeout (function (){t.setPowerBar(tf,open)}, 1000); return; }
			kochead.style.position = 'relative';
			kochead.style.left = offset+'px';
			t.OffsetTop = t.getTop(kochead);

			var kocmain = ById('kocmain');
			if (!kocmain) { setTimeout (function (){t.setPowerBar(tf,open)}, 1000); return; }

			var oldkm = getAbsoluteOffsets(kocmain);
			kocmain.style.left = offset+'px';
			var newkm = getAbsoluteOffsets(kocmain);
			var widgetshift = newkm.left - oldkm.left;

			t.setDialogContainerStyles();

			// keep ne0's widgets in line with kocmain movement

			if (ById("tr_guardBox")) {
				var newgpos = ById("tr_guardBox").offsetLeft + widgetshift;
				ById("tr_guardBox").style.left = newgpos+'px';
			}
			if (ById("tr_presetBox")) {
				var newtpos = ById("tr_presetBox").offsetLeft + widgetshift;
				ById("tr_presetBox").style.left = newtpos+'px';
			}

			var GameHeight = parseInt(kochead.offsetHeight)+parseInt(kocmain.offsetHeight);

			var PowerBar = ById('btPowerBar');
			if (PowerBar) {
				PowerBar.style.width = offset+'px';
				ById('btPowerBarLabel').innerHTML = PowerBarLabel;
			}
			else {
				var PowerBar = document.createElement('div');
				PowerBar.id='btPowerBar';
				PowerBar.style.position = 'absolute';
				PowerBar.style.width = offset+'px';
				PowerBar.style.top = t.OffsetTop+'px';
				PowerBar.style.height = GameHeight+'px';
				PowerBar.style.zIndex = '100411';
				ById('kocContainer').appendChild(PowerBar);

				var m = '<table cellspacing=0 cellpadding=0><tr><td id=btPowerBarButtons class="divHide" style="background-color:#000;" valign=top>&nbsp;</td><td id=btPowerBarOpener valign=middle style="background:none;border:none;vertical-align:top;"><a><div id=btPowerBarLabel class="btExpander buttonv2 blue" style="width:20px;height:'+GameHeight+'px;">&nbsp;</div></a></td></tr></table>';
				PowerBar.innerHTML = m;
				ById('btPowerBarLabel').innerHTML = PowerBarLabel;
				ById('btPowerBarOpener').addEventListener ('click', t.e_TogglePowerBar, false);
				ById('btPowerBarOpener').addEventListener ('mousedown', mouseMainTab, false);
			}
			if (open) jQuery('#btPowerBarButtons').removeClass("divHide");
			else jQuery('#btPowerBarButtons').addClass("divHide");
		}
		t.CheckDashPosition();
		t.CheckChatPosition();
		t.PowerBar = tf;
		t.PowerBarOpen = open;
	},

	e_TogglePowerBar : function (){
		var t = WideScreen;
		GlobalOptions.btPowerBarOpen = !GlobalOptions.btPowerBarOpen;
		saveGlobalOptions();
		t.setPowerBar(true,GlobalOptions.btPowerBarOpen);
	},

	getTop : function (elm) {
		var  y = 0;
		y = elm.offsetTop;
		elm = elm.offsetParent;
		while(elm != null) {
			y = parseInt(y) + parseInt(elm.offsetTop);
			elm = elm.offsetParent;
		}
		return y;
	},

	ShowDashboard : function (tf) {
		Options.btDashboard = tf;
		saveOptions();
		WideScreen.setDashboard(tf);
	},

	setDialogContainerStyles : function () {
		var t = WideScreen;
		GM_addStyle ('.modalCurtain {left:'+t.PowerBarWidth+'px !important;top:'+t.OffsetTop+'px !important;width:768px !important}');
		GM_addStyle ('.curtainMM{left:'+t.PowerBarWidth+'px !important;top:'+t.OffsetTop+'px !important;width:768px !important}');
		GM_addStyle ('.dialogContainer {left:'+t.PowerBarWidth+'px !important;top:'+t.OffsetTop+'px !important;width:768px !important}');
		GM_addStyle ('.notificationMessageDialog {margin-top:60px !important}');
		GM_addStyle ('div.largeModal {left:'+(27+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
		GM_addStyle ('div.xLargeModal {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(60+t.OffsetTop)+'px !important}');
		GM_addStyle ('div.mediumModal {left:'+(120+t.PowerBarWidth)+'px !important;top:'+(60+t.OffsetTop)+'px !important}');
		GM_addStyle ('div.smallModal {left:'+(200+t.PowerBarWidth)+'px !important;top:'+(190+t.OffsetTop)+'px !important}');
		GM_addStyle ('div.newGame {left:'+(7+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
		GM_addStyle ('.animatedChestModal {left:'+(85+t.PowerBarWidth)+'px !important;top:'+(100+t.OffsetTop)+'px !important}');
		GM_addStyle ('.guardianModal {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(200+t.OffsetTop)+'px !important}');
		GM_addStyle ('.choose_modal {left:'+(55+t.PowerBarWidth)+'px !important;top:'+(110+t.OffsetTop)+'px !important}');
		GM_addStyle ('.guardian_item {left:'+(225+t.PowerBarWidth)+'px !important;top:'+(155+t.OffsetTop)+'px !important}');
		GM_addStyle ('.nomadModal {left:'+(40+t.PowerBarWidth)+'px !important;top:'+(40+t.OffsetTop)+'px !important}');
		GM_addStyle ('.alliance_patch {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(t.OffsetTop)+'px !important;}');
		GM_addStyle ('.alliance_layover {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(127+t.OffsetTop)+'px !important;}');
		GM_addStyle ('.alliance_layover_stats {left:'+(187+t.PowerBarWidth)+'px !important;top:'+(102+t.OffsetTop)+'px !important}');
		GM_addStyle ('.chancellorModal {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
		GM_addStyle ('.mine_view {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
		GM_addStyle ('.vaultModal {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
		GM_addStyle ('div.templeModal.cmModal1 {left:'+(5+t.PowerBarWidth)+'px !important;top:'+(5+t.OffsetTop)+'px !important}');
	},
}

/************** Afk detector **************/

var afkdetector = {
	target : 120, // default check every 2 mins
	counter : 1,
	isAFK : true, // always begin in AFK mode! This will allow tower to revert following autoport

	init : function () {
		var t = afkdetector;
		if (parseIntNan(Options.AFKTimeout) < 1) Options.AFKTimeout = 1;
		t.target = Options.AFKTimeout*60;
		document.body.onmousemove = t.clear;
		document.body.onkeypress = t.clear;
	},

	check : function () {
		var t = afkdetector;
		if (!t.isAFK) {
			t.counter++;
			if (t.counter >= t.target) {
				if (GlobalOptions.ExtendedDebugMode) actionLog('afk detected');
				t.isAFK = true;
			}
		}
	},
	clear : function () {
		var t = afkdetector;
		t.counter = 1;
		if (t.isAFK) {
			if (GlobalOptions.ExtendedDebugMode) actionLog('afk cleared');
			t.isAFK = false;
		}
	},
	reset : function () {
		var t = afkdetector;
		if (parseIntNan(Options.AFKTimeout) < 1) Options.AFKTimeout = 1;
		t.target = Options.AFKTimeout*60;
		t.counter = 1;
		t.isAFK = false;
	},
}

function createButton (label,id){
	var a=document.createElement('a');
	a.className='button20';
	a.id = id;
	a.innerHTML='<span style="color: #ff6">'+ label +'</span>';
	return a;
}

function AddMainTabLink (text, id, eventListener, mouseListener) {
	var a = createButton (text,id);
	a.className='tab';
	var tabs=ById('main_engagement_tabs');
	if (tabs) {
		gmTabs = SetupMainTab(tabs);
		if (gmTabs) {
			gmTabs.appendChild(a);
			a.addEventListener('click',eventListener, false);
			if (mouseListener != null) { a.addEventListener('mousedown',mouseListener, true); }
			if (id != null) { a.id = id; }
			return a;
		}
	}
	return null;
}

function AddSubTabLink (text, eventListener, id, colourclass) {
	var a = createButton (text,id);
	if (colourclass == null) colourclass = 'blue20';
	a.className='inlineButton btButton '+colourclass;
	a.style.paddingLeft = '2px';
	var tabs=ById('main_engagement_tabs');
	if (tabs) {
		gmTabs = SetupSubTab(tabs);
		if (gmTabs) {
			gmTabs.appendChild(a);
			a.addEventListener('click',eventListener, false);
			if (id != null) { a.id = id; }
			return a;
		}
	}
	return null;
}

function SetToggleButtonState (entity,tf,text) {
	var btn = ById(entity+'ToggleTab');
	if (btn) {
		if (tf) { btn.innerHTML = '<span style="color: #FFFF00">'+tx(text)+': '+tx('On')+'</span>'; }
		else { btn.innerHTML = '<span style="color: #CCC">'+tx(text)+': '+tx('Off')+'</span>'; }
	}
}

function SetupMainTab (tabs) {
	var e = tabs.parentNode;
	var gmTabs = null;
	for (var i=0; i<e.childNodes.length; i++) {
		var ee = e.childNodes[i];
		if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id!='main_engagement_tabs' && ee.id!='pbp_subtab') {
			gmTabs = ee;
			break;
		}
	}
	if (gmTabs == null) {
		gmTabs = document.createElement('div');
		gmTabs.className='tabs_engagement';
		tabs.parentNode.insertBefore (gmTabs, tabs);
	}
	gmTabs.style.height='0%';
	gmTabs.style.paddingLeft='0px';
	gmTabs.style.width='100%';
	gmTabs.style.whiteSpace='nowrap';
	gmTabs.style.overflow='auto';
	gmTabs.lang = 'en_PB';
	return gmTabs;
}

function SetupSubTab (tabs) {
	var e = tabs.parentNode;
	var gmTabs = null;
	for (var i=0; i<e.childNodes.length; i++) {
		var ee = e.childNodes[i];
		if (ee.tagName && ee.tagName=='DIV' && ee.className=='tabs_engagement' && ee.id=='pbp_subtab') {
			gmTabs = ee;
			break;
		}
	}
	if (gmTabs == null) {
		gmTabs = document.createElement('div');
		gmTabs.className='tabs_engagement';
		gmTabs.id='pbp_subtab';
		tabs.parentNode.insertBefore (gmTabs, tabs);
	}
	gmTabs.style.height='0%';
	gmTabs.style.paddingLeft='5px';
	gmTabs.style.width='100%';
	gmTabs.style.whiteSpace='nowrap';
	gmTabs.style.overflow='auto';
	gmTabs.lang = 'en_PB';
	return gmTabs;
}

function AddPowerBarLink (text, id, eventListener, mouseListener) {
	var PBX = ById('btPowerBarExtra');
	if (!PBX || !GlobalOptions.btPowerBarPopups) {
		AddMainTabLink (text.toUpperCase(), id, eventListener, mouseListener);
		return;
	}

	var a=document.createElement('a');
	a.className='TextLink';
	a.innerHTML='<div class="buttonv2 std blue">'+ text +'</div>';

	PBX.appendChild(a);
	a.addEventListener('click',eventListener, false);
	if (mouseListener != null)
		a.addEventListener('mousedown',mouseListener, true);
	if (id != null)
		a.id = id;
	return a;
}

function mouseMainTab (me) {   // right-click on main button resets window location
	if (me.button == 2){
		var c = getClientCoords (ById('main_engagement_tabs'));
		mainPop.setLocation ({x: c.x+4, y: c.y+c.height});
	}
}

function eventHideShow () {
	if (mainPop.toggleHide(mainPop)){
		tabManager.showTab(false);
		Options.btWinIsOpen = true;
	} else {
		tabManager.hideTab();
		Options.btWinIsOpen = false;
	}
	saveOptions();
}

function DefaultWindowPos(OptPos,elem,force) {
	if (force || (Options[OptPos]==null) || (Options[OptPos].x==null) || (Options[OptPos].x=='') || (isNaN(Options[OptPos].x))) {
		var c = getClientCoords (ById(elem));
		Options[OptPos].x = c.x+4;
		Options[OptPos].y = c.y+c.height;
		saveOptions();
	}
}

function ToggleDivDisplay(form,h,w,div, autoclose) {
	var dc = jQuery('#'+div).attr('class');
	if (dc) {
		if (dc.indexOf('divHide') >= 0) {
			jQuery('#'+div).attr('class','');
			jQuery('#'+div+'Arrow').attr('src',DownArrow);
			if (autoclose) {
				lastdiv = "";
				if (OpenDiv[form]) {
					lastdiv = OpenDiv[form];
				}
				if (lastdiv != "") {
					ToggleDivDisplay(form,h,w,lastdiv);
				}
				OpenDiv[form] = div;
			}
		}
		else {
			jQuery('#'+div).attr('class','divHide');
			jQuery('#'+div+'Arrow').attr('src',RightArrow);
			if (autoclose) { OpenDiv[form] = '';}
		}
	}
	else
	{
		jQuery('#'+div).attr('class','divHide');
		jQuery('#'+div+'Arrow').attr('src',RightArrow);
		if (autoclose) { OpenDiv[form] = '';}
	}
	if (form) ResetFrameSize(form,h,w);
}

function ToggleMainDivDisplay(form,h,w,div, autoclose, opt) {
	var dc = jQuery('#'+div).attr('class');
	if (dc) {
		if (dc.indexOf('divHide') >= 0) {
			jQuery('#'+div).attr('class','');
			jQuery('#'+div+'Arrow').attr('src',DownArrow);
			if (autoclose) {
				lastdiv = "";
				if (OpenDiv[form]) {
					lastdiv = OpenDiv[form];
				}
				if (lastdiv != "") {
					ToggleDivDisplay(form,h,w,lastdiv);
				}
				OpenDiv[form] = div;
				if (opt) { Options[opt] = div; }
			}
		}
		else {
			jQuery('#'+div).attr('class','divHide');
			jQuery('#'+div+'Arrow').attr('src',RightArrow);
			if (autoclose) {
				OpenDiv[form] = '';
				if (opt) { Options[opt] = ''; }
			}
		}
	}
	else
	{
		jQuery('#'+div).attr('class','divHide');
		jQuery('#'+div+'Arrow').attr('src',RightArrow);
		if (autoclose) { OpenDiv[form] = '';}
	}
	ResetFrameSize('btMain',h,w);
}

function ResetFrameSize(prefix,minheight,minwidth) {
	var h1 = ById(prefix+'_bar');
	var h2 = ById(prefix+'_content');
	if (!h1 || !h2) return;
	var h = h1.clientHeight + h2.clientHeight;
	if (h < minheight) h = minheight;
	jQuery('#'+prefix+'_outer').css('height',h+10);

	w = ById(prefix+'_content').clientWidth;
	w2 = ById(prefix+'_outer').clientWidth;
	if (w < minwidth) w = minwidth;
	if (w2 < w) // I don't know why I need this.. must look at this later to try and get it to shrink again
		jQuery('#'+prefix+'_outer').css('width',w+10);
}

function myClone(source) {
	var destination = {};
	for (var property in source)
	destination[property] = source[property];
	return destination;
}

function UpdateMarch (cityId,marchId) {
	local_atkp["m"+marchId].btRequestSent = 2; // delay any further requests for 2 seconds
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.rid = marchId;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchMarch.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (local_atkp["m"+marchId]) {
				for (var y in rslt.march) {
					local_atkp["m"+marchId][y] = rslt.march[y];
				}
				local_atkp["m"+marchId].btIncomplete = false;
				// champion on march?
				if (rslt.march.championId && (rslt.march.championId != 0) && !local_atkp["m"+marchId].championInfo) {
					for (var y in Seed.champion.champions) {
						if (Seed.champion.champions[y].championId == rslt.march.championId) {
							marchChamp = {};
							marchChamp.name = Seed.champion.champions[y].name; // lazy. We'll use city stats to show champ data
							local_atkp["m"+marchId].championInfo = marchChamp;
							break;
						}
					}
				}
				if (rslt.march.toPlayerId && (rslt.march.toPlayerId != 0) && !Seed.players["u"+rslt.march.toPlayerId]) {
					updatePlayers(rslt.march.toPlayerId);
				}
			}
		},
		onFailure: function () {
			local_atkp["m"+marchId].btRequestSent = 0; // try again
		}
    },true); // no retry
}

function UpdateIncomingMarch (marchId) {
	local_atkinc["m"+marchId].btRequestSent = 2; // delay any further requests for 2 seconds
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.rid = marchId;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchMarch.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (local_atkinc["m"+marchId]) {
				for (var y in rslt.march) {
					local_atkinc["m"+marchId][y] = rslt.march[y];
				}
				local_atkinc["m"+marchId].btIncomplete = false;
			}
		},
		onFailure: function () {
			local_atkinc["m"+marchId].btRequestSent = 0; // try again
		}
    },true); // no retry
}

function updatePlayers (uid){
    var params = uW.Object.clone(uW.g_ajaxparams);
    params.uid = uid;
    new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
      method: "post",
      parameters: params,
      onSuccess: function (rsltInfo) {
	    if (!rsltInfo.ok) { return; }
		NewPlayer = {};
		NewPlayer.n = rsltInfo.userInfo[0].name;
		NewPlayer.t = rsltInfo.userInfo[0].title;
		NewPlayer.m = rsltInfo.userInfo[0].might;
		NewPlayer.a = rsltInfo.userInfo[0].allianceId;
		Seed.players["u"+uid] = NewPlayer;
      },
    },true);
}

function SetChampionIcon (uid){
	var e = ById('maparea_boosts_champion');
	if (!e) {
		e = document.createElement ('table');
		e.height = "20";
		e.style.cssFloat = 'left';
		e.style.border = '1px';
		e.style.borderSpacing = '1px';
		e.style.borderCollapse = 'separate';
		e.style.backgroundColor = '#fff';
		e.id = 'maparea_boosts_champion';
		e.className = 'trimg';
		ById('maparea_boosts').appendChild (e);
		ById('maparea_boosts').style.zIndex = '20001';
	}
	var citychamp;
	var gotchamp = false;
	for (var y in Seed.champion.champions) {
		citychamp = Seed.champion.champions[y];
		if (citychamp.assignedCity == uW.currentcityid) {
			gotchamp = true;
			break;
		}
	}
	if (gotchamp) {
		e.style.display = 'block';
		e.innerHTML = '<tr><td id=maparea_boosts_championtd class="xtab trimg" style="padding:0px;"><img style="margin-left:0px;" id=maparea_boosts_champion_image height=18 src="'+ChampImagePrefix+citychamp.avatarId+ChampImageSuffix+'"></td></tr>'

		function FNChampPopup () {uW.btCreateChampionPopUp(e,citychamp.assignedCity,true,null,true);}
		function FNChampClear () {uW.removeTooltip();}
		ById('maparea_boosts_champion_image').addEventListener('mouseover',FNChampPopup,false);
		ById('maparea_boosts_champion_image').addEventListener('mouseout',FNChampClear,false);
	}
	else {
		e.style.display = 'none';
	}
}

/************************************ main loop *********************************************/

function EverySecond () {
	try {

		SecondLooper = SecondLooper+1;

		inc = [];
		incCity = [];

		/* check local marches still exist */

		for(n in local_atkinc) {
			if (!Seed.queue_atkinc[n]) { delete local_atkinc[n]; }
		}

		for(n in Seed.queue_atkinc) {
			if (Seed.queue_atkinc[n].marchType) {
				inc.push(Seed.queue_atkinc[n]);
				/* check and copy to local */
				Copy_Local_ATKINC(n);
			}
		}
		inc.sort(function(a, b){ if(!a.arrivalTime) a.arrivalTime = -1; if(!b.arrivalTime) b.arrivalTime = -1;return a.arrivalTime-b.arrivalTime });
		CheckForIncoming();

		out = [];
		outCity = [];

		for(n in Seed.queue_atkp) {
			for(m in Seed.queue_atkp[n]) {
				if (Seed.queue_atkp[n][m].marchType && (parseInt(Seed.queue_atkp[n][m].marchType) != 9)) { // no raids!
					Copy_Local_ATKP(n,m);
					var marchobj = local_atkp[m];
					out.push(marchobj);
					if (marchobj.marchCityId == Dashboard.CurrentCityId) {
						outCity.push(marchobj);
					}
				}
			}

		}
		out.sort(function(a, b){ return /*a.destinationUnixTime-b.destinationUnixTime*/ });
		outCity.sort(function(a, b){ return a.destinationUnixTime-b.destinationUnixTime });

		/* Check Throne Preset hasn't changed */

		if (CurrPreset != Seed.throne.activeSlot) { Dashboard.PaintTRPresets(); }

		/* Update Dashboard */

		if (popDash && Dashboard.Loaded) { Dashboard.EverySecond(); };

		/* Update Incoming and Outgoing and March popups */

		if (popInc) { Incoming.EverySecond(); };
		if (popOut) { Outgoing.EverySecond(); };
		if (popMarch) { QuickMarch.EverySecond(); };

		/* loop through tabs */

		tabManager.EverySecond();

		/* check for afk */

		afkdetector.check();

		/* restart loop */

		SecondTimer = setTimeout(EverySecond,1000);
	}
	catch (err) {
		logerr(err); // write to log
		SecondTimer = setTimeout(EverySecond,1000);
	}
}

function CheckForIncoming () {
	var atype = "";
	var atime = "";
	var to = "";
	var name = "";
	var who = "";
	var bywho = "";

	var soonest = {};
	soonest.arrivalTime = -1;

	Dashboard.StillComing = false;
	var PopupVisible = false;

	// Find big popup gem container element if it exists..

	var el1 = document.getElementsByClassName('primarytitlebar');
	var el2 = document.getElementsByClassName('gemContainer');
	var el3 = Array.filter( el2, function(elem){ return Array.indexOf( el1, elem.parentNode ) > -1; });

	for (var e=0;e<el3.length;e++) {
		PopupVisible = true;
		GemContainer = el3[e];
		if (!Dashboard.Incoming) SaveGemHTML2 = GemContainer.innerHTML;
	}

	if (!PopupVisible) { // override main screen gem container
		for (var e=0;e<el2.length;e++) {
			GemContainer = el2[e];
			if (!Dashboard.Incoming) SaveGemHTML = GemContainer.innerHTML;
			GemContainer.style.height = 40+'px';
			GemContainer.style.marginTop = 2+'px';
			GemContainer.id = 'btGemContainer';
			break;
		}
	}

	CanNotify = ById('btGemContainer');

	for(n in inc) {
		var a = inc[n];
		if (!a.score) continue;
		if (a.marchType == null) continue; // bogus march (returning scouts)
		if (a.arrivalTime >= 0 && (a.arrivalTime < unixTime())) {
			continue; // don't display arrival times already happened
		}
		Dashboard.StillComing = true;
		if ((a.arrivalTime >= 0 && (a.arrivalTime < soonest.arrivalTime)) || (soonest.arrivalTime == -1)) {
			soonest = a;
			if (!soonest.arrivalTime) soonest.arrivalTime = -1;
			if (soonest.arrivalTime >= 0) {
				if (a.arrivalTime >= 0 && (a.arrivalTime - unixTime() < 2)) {
					if (Seed.citystats["city" + a.toCityId].gate != 0) { // only do this if defending
						// save defending unit configuration
						if (Options.DashboardOptions.ReplaceDefendingTroops[Cities.byID[a.toCityId].idx] && SelectiveDefending) {
							Dashboard.AttackedCity = a.toCityId;
							Dashboard.StoreDefendingTroops(Dashboard.AttackedCity);
						}
						setTimeout(function() {Dashboard.ForceTries = 0;Dashboard.ForceUpdateSeed();},3000); // force update defending troops immediately after attacks land
					}
				}
				break;
			}
		}
	}

	if (Dashboard.StillComing) {
		if (soonest.marchType && (soonest.marchType == 3)) atype = '<img style="border:2px ridge #00A;width:15px;height:15px;" src='+ScoutImage+'>';
		else atype = '<img style="border:2px ridge #A00;width:15px;height:15px;" src='+AttackImage+'>';
		to = Cities.byID[soonest.toCityId];
		if (to && to.tileId == soonest.toTileId ) name = to.name;
		else name = "Wilderness";

		if (soonest.arrivalTime != -1) atime = uW.cm.TimeFormatter.format(parseInt(soonest.arrivalTime-unixTime()));
		else atime = '??????';
		if (soonest.pid && Seed.players['u'+soonest.pid]) {who = Seed.players['u'+soonest.pid].n; bywho = ' by '+MonitorLink(soonest.pid,who,"AlertLink");}
		else { bywho = '&nbsp;&nbsp;(Upgrade WatchTower)' ;}

		msgcontainer = '<div class="textContainer" style="margin-left:-10px;padding-top:0px;">';
		msglink1 = '<a class="AlertLink" id='
		msglink2 = '>';
		msglink3 = '</a>';
		msgtable = '<div class="AlertStyle"><table border=0><tr><td class="AlertContent"><div style="text-align:center;width:86px">&nbsp;&nbsp;'+atime+'</div></td><td class="AlertContent" style="padding-top:3px;">'+atype+'</td><td class="AlertContent"><div style="color:#ecddc1;text-shadow: 0px 0px 15px #000;">';
		msgend = '</div></td></tr></table></div>';
		if (Options.OverrideAttackAlert) {
			if (CanNotify) {
				ById('btGemContainer').innerHTML = msgcontainer+msgtable+msglink1+'btAlertIncoming'+msglink2+name+msglink3+msgend+'</div><center>'+bywho+'</center>';
				ById('btGemContainer').style.display = 'block';
				ById('btAlertIncoming').addEventListener ('click', function(){Dashboard.show(to)}, false);
				jQuery('.alliance_patch').hide();
			}
			if (PopupVisible) {
				GemContainer.innerHTML = msgcontainer+msgtable+msglink1+'btAlertIncoming2'+msglink2+name+msglink3+msgend+'</div>';
				GemContainer.style.width=250+'px';
				ById('btAlertIncoming2').addEventListener ('click', function(){Dashboard.show(to)}, false);
			}
		}
	}

	if (Dashboard.Incoming && !Dashboard.StillComing) {
		if (Options.OverrideAttackAlert) {
			if (CanNotify) {
				ById('btGemContainer').innerHTML = SaveGemHTML;
				if (jQuery('#ahqbutton').hasClass('sel')) {
					ById('btGemContainer').style.display = 'none';
					jQuery('.alliance_patch').show();
				}
			}
			if (PopupVisible) {
				GemContainer.innerHTML = SaveGemHTML2;
			}
		}
	}

	Dashboard.Incoming = Dashboard.StillComing;

	// check for city incoming

	if (popDash && (Dashboard.CurrentCityId != 0))  {
		var citysoonest = {};
		citysoonest.arrivalTime = -1;

		Dashboard.CityStillComing = false;

		for(n in inc) {
			var a = inc[n];
			if (!a.score) continue;
			if (a.arrivalTime >= 0 && (a.arrivalTime < unixTime())) continue; // don't display arrival times already happened
			if (inc[n].toCityId == Dashboard.CurrentCityId) {
				Dashboard.CityStillComing = true;
				if ((a.arrivalTime >= 0 && (a.arrivalTime < citysoonest.arrivalTime)) || (citysoonest.arrivalTime == -1)) {
					citysoonest = a;
					if (!citysoonest.arrivalTime) citysoonest.arrivalTime = -1;
					if (citysoonest.arrivalTime > 0) break;
				}
			}
		}

		if (Dashboard.CityStillComing) {
			if (citysoonest.arrivalTime != -1) atime = uW.cm.TimeFormatter.format(parseInt(citysoonest.arrivalTime-unixTime()));
			else atime = '??????';
			msgcontainer = '<div class="textContainer" style="margin-right:-20px;padding-top:0px;">';
			msgtable = '<div class="AlertStyle" style="text-align:center;width:110px"><table border=0><tr><td class="AlertContent"><div style="text-align:center;width:86px">&nbsp;'+atime;
			msgend = '</div></td></tr></table></div>';
			ById('btCityAlert').innerHTML = msgcontainer+msgtable+msgend+'</div>';
		}

		if (Dashboard.CityIncoming && !Dashboard.CityStillComing) {
			ById('btCityAlert').innerHTML = "";
		}

		Dashboard.CityIncoming = Dashboard.CityStillComing;
	}
}

function Copy_Local_ATKP(n,m) {
	var now = unixTime();
	if (Seed.queue_atkp[n][m].marchStatus==0) return;
	if (!local_atkp[m] || (Seed.queue_atkp[n][m].marchUnixTime!=local_atkp[m].marchUnixTime) || (Seed.queue_atkp[n][m].returnUnixTime!=local_atkp[m].returnUnixTime)) { // add new march, or newly recalled march
		var march = new Object();
		for (var p in Seed.queue_atkp[n][m]) {
			march[p] = Seed.queue_atkp[n][m][p];
		}
		local_atkp[m] = march;
		local_atkp[m].marchCityId = n.split("city")[1]; // from city
		if (!local_atkp[m].marchId) {
			local_atkp[m].marchId = m.split("m")[1]; // march id
		}
		local_atkp[m].btIncomplete = true;
		local_atkp[m].btRequestSent = 0;
	}

	var destinationUnixTime = local_atkp[m].destinationUnixTime - now;
	var returnUnixTime = local_atkp[m].returnUnixTime - now;
	var marchStatus = parseInt(local_atkp[m].marchStatus);
	if (destinationUnixTime < 0 && marchStatus != 2 && marchStatus != 8 && marchStatus != 0 && returnUnixTime > 0) { // refresh return journey
		local_atkp[m].btIncomplete = true; // force a march refresh
	}

	if (local_atkp[m].btIncomplete == true && Options.FetchMarchInfo) {
		if (local_atkp[m].btRequestSent > 0) {
			local_atkp[m].btRequestSent = local_atkp[m].btRequestSent - 1;
		}
		else {
			UpdateMarch(local_atkp[m].marchCityId,local_atkp[m].marchId);
		}
	}
}

function Copy_Local_ATKINC(m) {
	if (!local_atkinc[m] || (Seed.queue_atkinc[m].marchUnixTime!=local_atkinc[m].marchUnixTime)) { // new march
		var march = new Object();
		for (var p in Seed.queue_atkinc[m]) {
			march[p] = Seed.queue_atkinc[m][p];
		}
		local_atkinc[m] = march;
		local_atkinc[m].btIncomplete = true;
		local_atkinc[m].btRequestSent = 0;
		if (!local_atkinc[m].marchId) {
			local_atkinc[m].marchId = m.split("m")[1]; // march id
		}
	}

	if (local_atkinc[m].score) {
		// build an array of cities under attack
		var to = Cities.byID[local_atkinc[m].toCityId];
		if (to) {
			if (incCity.indexOf(to.idx) < 0) incCity.push(to.idx);
		}
	}

	if (local_atkinc[m].btIncomplete == true && Options.FetchMarchInfo) {
		if (local_atkinc[m].btRequestSent > 0) {
			local_atkinc[m].btRequestSent = local_atkinc[m].btRequestSent - 1;
		}
		else {
			UpdateIncomingMarch(local_atkinc[m].marchId);
		}
	}
}

/*********************************** Standard Functions *************************************/

function translate (str) {
    if (LanguageArray[str]) { str = LanguageArray[str]; }
    else { NoTranslation[str] = ""; }
    return str;
}

function tx(str) {return translate(str);}
function ById(id) {return document.getElementById(id);}

function CheckForHTMLChange (panel,div,newHTML,wait) {
	var oldHTML = HTMLRegister[panel][div];
	if (!wait && (oldHTML != newHTML)) {
		ById(div).innerHTML = newHTML;
		HTMLRegister[panel][div] = newHTML;
		return true;
	}
	return false;
};

function ResetHTMLRegister (panel,div) {
	HTMLRegister[panel][div] = '';
};

function shuffle(array) {
	var currentIndex = array.length, temporaryValue, randomIndex ;
	// While there remain elements to shuffle...
	while (0 !== currentIndex) {
		// Pick a remaining element...
		randomIndex = Math.floor(Math.random() * currentIndex);
		currentIndex -= 1;
		// And swap it with the current element.
		temporaryValue = array[currentIndex];
		array[currentIndex] = array[randomIndex];
		array[randomIndex] = temporaryValue;
	}
	return array;
}

function getAbsoluteOffsets(e) {
	ret = { left: 0, top: 0 };
	while (e.offsetParent) {
		if (e.style.position == 'absolute')
			break;
		ret.left += e.offsetLeft;
		ret.top += e.offsetTop;
		e = e.offsetParent;
	}
	return ret;
}

function getOffset(el) {
	ret = { left: 0, top: 0 };
	while(el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
		ret.left += el.offsetLeft - el.scrollLeft;
		ret.top += el.offsetTop - el.scrollTop;
		el = el.offsetParent;
	}
	return ret;
}

function getStyle(x,styleProp) {
	if (x.currentStyle)
		var y = x.currentStyle[styleProp];
	else if (window.getComputedStyle)
		var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
	return y;
}

function getFirefoxVersion() {
	var ver = '',
		i;
	var ua = navigator.userAgent;
	if (ua) {
		i = ua.indexOf('OPR/');
		if (i >= 0) return {'Browser':'Opera','Version':ua.substr(i + 4).split(' ')[0]};
		i = ua.indexOf('Chrome/');
		if (i >= 0) return {'Browser':'Chrome','Version':ua.substr(i + 7).split(' ')[0]};
		i = ua.indexOf('Safari/');
		if (i >= 0) return {'Browser':'Safari','Version':ua.substr(i + 7).split(' ')[0]};
		i = ua.indexOf('PaleMoon/');
		if (i >= 0) return {'Browser':'Palemoon','Version':ua.substr(i + 9).split(' ')[0]};
		i = ua.indexOf('IceDragon/');
		if (i >= 0) return {'Browser':'IceDragon','Version':ua.substr(i + 10).split(' ')[0]};
		i = ua.indexOf('Firefox/');
		if (i >= 0) return {'Browser':'Firefox','Version':ua.substr(i + 8).split(' ')[0]};
	}
	return {Browser:'Firefox',Version:'0.00'};
}

function getGMVersion() {
	if (typeof (GM_info) != 'object') {
		return {'Handler':'Scriptish','Version':'Unknown'};
	}
	var Vers = GM_info.version || 'Unknown';
	var Handler = GM_info.scriptHandler || 'Greasemonkey';
	return {'Handler':Handler,'Version':Vers};
}

function HEXtoRGB(hex) {
	if (hex.length==7) {
		var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
	}
	else {
		if (hex.length==4) {
			var result = /^#?([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(hex);
			result[1] = result[1]+'0';
			result[2] = result[2]+'0';
			result[3] = result[3]+'0';
		}
	}
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : {r:0, g:0, b:0};
}

function searchDOM (node, condition, maxLevel, doMult){
	var found = [];
	eval ('var compFunc = function (node) { return ('+ condition +') }');
	doOne(node, 1);
	if(!doMult){
		if (found.length==0)
			return null;
		return found[0];
	}
	return found;

	function doOne (node, curLevel){
		try {
			if (compFunc(node))
				found.push(node);
		} catch (e){ }
		if (!doMult && found.length>0)
			return;
		if (++curLevel<maxLevel && node.childNodes!=undefined)
			for (var c=0; c<node.childNodes.length; c++)
				doOne (node.childNodes[c], curLevel);
	}
}

function getClientCoords(e) {
	if (e==null)
		return {x:null, y:null, width:null, height:null};
	var x=0, y=0;
	ret = {x:0, y:0, width:e.clientWidth, height:e.clientHeight};
	while (e.offsetParent != null){
		ret.x += e.offsetLeft;
		ret.y += e.offsetTop;
		e = e.offsetParent;
	}
	return ret;
}

function InitialiseAudioManager() {
	var div = document.getElementsByTagName('div');
	for (var i = 0; i < div.length - 1; i++)
		if (div[i].className == 'mod_comm_forum')
			e = div[i];

	if (!e) {
		setTimeout(InitialiseAudioManager,2000);
		return;
	}

	AudioManager = new AudioMan(); // put basic SWF container in DOM above the chat
	AudioManager.init(e);
}

function AudioMan() {
	var t = this;
	this.player = null;
	this.volume = 100;
	this.type = 'html5';
	this.defaulttype = 'html5';
	this.source = null;
	this.canPlayMP3 = false;
	this.hasFlash = false;
	this.alertdiv = null;
	this.stoptimer = null;

	this.init = init;
	this.setVolume = setVolume;
	this.play = play;
	this.stop = stop;
	this.pause = pause;
	this.setSource = setSource;
	this.toggleMute = toggleMute;
	this.initSWF = initSWF;

	function init (myDiv){
		if (!!document.createElement("audio").canPlayType) {
			t.player = new Audio();
			t.canPlayMP3 = (t.player.canPlayType("audio/mpeg") !== "");
			t.defaulttype = 'html5';
			t.player.addEventListener("ended", function () {
				t.player.currentTime = 0
			}, false);
			t.setVolume(t.volume);
		} else {
			t.defaulttype = 'swf';
		}
		t.initSWF(myDiv)
	};

	function setVolume(vol){
		t.volume = vol;
		if (t.player) t.player.volume = t.volume * 0.01;
	};

	function pause(){
		if (t.player) t.player.pause();
	};

	function toggleMute () {
		if (t.player) t.player.muted = !t.player.muted;
	};

	function play(){
		clearTimeout(t.stoptimer);
		if(t.type == 'html5'){
			if (!t.player.paused) {
				t.stop();
			}
			t.player.play();
		} else {
			if (t.alertdiv) {
				if (!t.hasFlash) {
					logit('SWF Disabled or not Installed');
					t.alertdiv.innerHTML = '<b style=\'color:#800; font-size: 9px;\'>SWF Disabled or not Installed</b>';
				}
				else {
					t.alertdiv.innerHTML = t.source;
				}
			}
			else { logit('sound probs on play'); }
		}
	};

	function stop(){
		clearTimeout(t.stoptimer);
		if(t.type == 'html5'){
			t.player.pause();
			if (t.player.readyState === 4) {
				t.player.currentTime = 0
			}
		} else {
			if (t.alertdiv) {
				if (t.hasFlash) {
					t.alertdiv.innerHTML = '<b style=\'color: rgb(165, 102, 49); font-size: 9px;\'>SWF Audio Played</b>';
				}
			}
			else { logit('sound probs on stop'); }
		}
	};

	function setSource(src){
		if (matTypeof(src) == 'object') {
			if(t.defaulttype == 'html5'){
				t.player.src = src.OGG;
				t.type = 'html5';
			}
			else {
				logit('Browser has no native Audio support');
				t.source = SWF_PREFIX+src.URL+'&amp;volume='+t.volume+SWF_SUFFIX;
				t.type = 'swf';
			}
		}
		else {
			if ((src.split('.').pop().toUpperCase()=='MP3') && !t.canPlayMP3) {
				logit('Browser has no native MP3 support');
				t.source = SWF_PREFIX+src+'&amp;volume='+t.volume+SWF_SUFFIX;
				t.type = 'swf';
			}
			else {
				if(t.defaulttype == 'html5'){
					t.player.src = src;
					t.type = 'html5';
				}
				else {
					logit('Browser has no native Audio support');
					// probably can't play the sound, send it to SWF anyway..
					t.source = SWF_PREFIX+src+'&amp;volume='+t.volume+SWF_SUFFIX;
					t.type = 'swf';
				}
			}
		}
		// if source changed need to load.. ( not SWF)
		if (t.type == 'html5') {
			if (t.source != t.player.src) {
				t.player.load();
				t.source = t.player.src;
			}
		}
	};

	function initSWF(e){
		t.alertdiv = document.createElement("span");
		t.alertdiv.style.verticalAlign = 'top';
		t.alertdiv.style.paddingLeft = '20px';
		e.appendChild(t.alertdiv);
		e.style.height = '20px';

		try {
			var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
			if (fo) { t.hasFlash = true; }
		} catch (e) {
			if (navigator.mimeTypes && navigator.mimeTypes['application/x-shockwave-flash'] != undefined && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
				t.hasFlash = true;
			}
		}
	};
}


function hideMe() {
	if (!Options.btWinIsOpen)
		return;
	mainPop.show(false);
	Options.btWinIsOpen = false;
	saveOptions();
}

function showMe() {
	mainPop.show(true);
	Options.btWinIsOpen = true;
	saveOptions();
}

var WinManager = {
	wins : {},    // prefix : CPopup obj

	get : function (prefix){
		var t = WinManager;
		return t.wins[prefix];
	},

	add : function (prefix, pop){
		var t = WinManager;
		t.wins[prefix] = pop;
		if (uW.cpopupWins == null)
			uW.cpopupWins = uWCloneInto({});
		uW.cpopupWins[prefix] = pop;
	},

	delete : function (prefix){
		var t = WinManager;
		delete t.wins[prefix];
		delete uW.cpopupWins[prefix];
	}
}

// value is 0 to 1.0
function SliderBar (container, width, height, value, classPrefix, margin){
	var self = this;
	this.listener = null;
	if (value==null)
		value = 0;
	if (!margin)
		margin = parseInt(width*0.05);
	this.value = value;
	if (width<20) width=20;
	if (height<5) height=5;
	if (classPrefix == null){
		classPrefix = 'slider';
		var noClass = true;
	}
	var sliderHeight = parseInt(height/2);
	var sliderTop = parseInt(height/4);
	this.sliderWidth = width - (margin*2);

	this.div = document.createElement ('div');
	this.div.style.height = height +'px';
	this.div.style.width = width +'px';
	this.div.className = classPrefix +'Cont';

	this.slider = document.createElement ('div');
	this.slider.setAttribute ('style', 'position:relative;');
	this.slider.style.height = sliderHeight + 'px'
	this.slider.style.top = sliderTop + 'px';
	this.slider.style.width = this.sliderWidth +'px';
	this.slider.style.left = margin +'px';   /////
	this.slider.className = classPrefix +'Bar';
	this.slider.draggable = true;
	if (noClass)
		this.slider.style.backgroundColor='#fff';

	this.sliderL = document.createElement ('div');
	this.sliderL.setAttribute ('style', 'width:100px; height:100%; position:relative;');
	this.sliderL.className = classPrefix +'Part';
	this.sliderL.draggable = true;
	if (noClass)
		this.sliderL.style.backgroundColor='#0c0';

	this.knob = document.createElement ('div');
	this.knob.setAttribute ('style', 'width:3px; position:relative; left:0px; background-color:#222;');
	this.knob.style.height = height +'px';
	this.knob.style.top = (0-sliderTop) +'px';
	this.knob.className = classPrefix +'Knob';
	this.knob.draggable = true;
	this.slider.appendChild(this.sliderL);
	this.sliderL.appendChild (this.knob);
	this.div.appendChild (this.slider);
	container.appendChild (this.div);
	this.div.addEventListener('mousedown',  mouseDown, false);

	this.getValue = function (){
		return self.value;
	}

	this.setValue = function (val){
		var relX = (val * self.sliderWidth);
		self.sliderL.style.width = relX + 'px';
		self.knob.style.left =  relX + 'px';
		self.value = val;
		if (self.listener)
			self.listener(self.value);
	}

	this.setChangeListener = function (listener){
		self.listener = listener;
	}

	function moveKnob (me){
		var relX = me.clientX - self.divLeft;
		if (relX < 0)
		relX = 0;
		if (relX > self.sliderWidth)
			relX = self.sliderWidth;
		self.knob.style.left = (relX - (self.knob.clientWidth/2) ) +'px';   // - half knob width !?!?
		self.sliderL.style.width = relX + 'px';
		self.value =  relX / self.sliderWidth;
		if (self.listener)
			self.listener(self.value);
	}

	function doneMoving (){
		self.div.removeEventListener('mousemove', mouseMove, true);
		document.removeEventListener('mouseup', mouseUp, true);
	}

	function mouseUp (me){
		moveKnob (me);
		doneMoving();
	}

	function mouseDown(me){
		var e = self.slider;
		self.divLeft = 0;
		while (e.offsetParent){   // determine actual clientX
			self.divLeft += e.offsetLeft;
			e = e.offsetParent;
		}
		moveKnob (me);
		document.addEventListener('mouseup',  mouseUp, true);
		self.div.addEventListener('mousemove',  mouseMove, true);
	}

	function mouseMove(me){
		moveKnob (me);
	}
}

// creates a 'popup' div
// prefix must be a unique (short) name for the popup window
function CPopup (prefix, x, y, width, height, enableDrag, onClose) {
	var pop = WinManager.get(prefix);
	if (pop){
		pop.show (false);
		return pop;
	}
	this.BASE_ZINDEX = 111111;

	// protos ...
	this.show = show;
	this.toggleHide = toggleHide;
	this.getTopDiv = getTopDiv;
	this.getMainDiv = getMainDiv;
	this.getLayer = getLayer;
	this.setLayer = setLayer;
	this.setEnableDrag = setEnableDrag;
	this.getLocation = getLocation;
	this.setLocation = setLocation;
	this.getDimensions = getDimensions;
	this.setDimensions = setDimensions;
	this.focusMe = focusMe;
	this.unfocusMe = unfocusMe;
	this.centerMe = centerMe;
	this.destroy = destroy;

	// object vars ...
	this.div = document.createElement('div');
	this.prefix = prefix;
	this.onClose = onClose;

	var t = this;
	this.div.className = 'btPopup '+ prefix +'_btPopup';
	this.div.id = prefix +'_outer';
	this.div.style.background = "#fff";
	this.div.style.zIndex = this.BASE_ZINDEX        // KOC modal is 100404, sometimes 100410 ?
	this.div.style.display = 'none';
	this.div.style.width = width + 'px';
	this.div.style.height = height + 'px';
	this.div.style.position = "absolute";
	this.div.style.top = y +'px';
	this.div.style.left = x + 'px';

	var m = '<TABLE cellspacing=0 width=100% height=100%><TR id="'+ prefix +'_bar" class="btPopupTop '+ prefix +'_btPopupTop"><TD style="-moz-border-radius-topleft: 20px; border-top-left-radius: 20px;"><SPAN id="'+ prefix +'_top"></span></td>\
			 <TD id='+ prefix +'_X align=right valign=middle onmouseover="this.style.cursor=\'pointer\'" style="width:10px;color:#fff; background:#400; border:1px solid #000000; font-weight:bold; font-size:14px; padding:0px 5px; -moz-border-radius-topright: 20px; border-top-right-radius: 20px;">X</td></tr>\
             <TR><TD height=100% valign=top class="btPopMain '+ prefix +'_btPopMain" colspan=2 id="'+ prefix +'_main"><div id="'+ prefix +'_content"></div></td></tr></table>';
	document.body.appendChild(this.div);
	this.div.innerHTML = m;
	ById(prefix+'_X').addEventListener ('click', e_XClose, false);
	this.dragger = new CWinDrag (ById(prefix+'_bar'), this.div, enableDrag);

	this.div.addEventListener ('mousedown', e_divClicked, false);
	WinManager.add(prefix, this);

	function e_divClicked (){
		t.focusMe();
	}
	function e_XClose (){
		t.show(false);
		if (t.onClose != null)
			t.onClose();
	}

	function focusMe (){
		t.setLayer(5);
		for (var k in uW.cpopupWins){
			if (k != t.prefix)
			uW.cpopupWins[k].unfocusMe();
		}
	}

	function unfocusMe (){
		t.setLayer(-5);
	}

	function getLocation (){
		return {x: parseInt(this.div.style.left), y: parseInt(this.div.style.top)};
	}

	function getDimensions (){
		return {x: parseInt(this.div.style.width), y: parseInt(this.div.style.height)};
	}

	function setLocation (loc){
		t.div.style.left = loc.x +'px';
		t.div.style.top = loc.y +'px';
	}

	function setDimensions (loc){
		t.div.style.width = loc.x +'px';
		t.div.style.height = loc.y +'px';
	}

	function destroy (){
		document.body.removeChild(t.div);
		WinManager.delete (t.prefix);
	}

	function centerMe (parent){
		if (parent == null){
			var coords = getClientCoords(document.body);
		} else
			var coords = getClientCoords(parent);
		var x = ((coords.width - parseInt(t.div.style.width)) / 2) + coords.x;
		var y = ((coords.height - parseInt(t.div.style.height)) / 2) + coords.y;
		if (x<0)
			x = 0;
		if (y<0)
			y = 0;
		t.div.style.left = x +'px';
		t.div.style.top = y +'px';
	}

	function setEnableDrag (tf){
		t.dragger.setEnable(tf);
	}

	function setLayer(zi){
		t.div.style.zIndex = ''+ (this.BASE_ZINDEX + zi);
	}

	function getLayer(){
		return parseInt(t.div.style.zIndex) - this.BASE_ZINDEX;
	}

	function getTopDiv(){
		return ById(this.prefix+'_top');
	}

	function getMainDiv(){
		return ById(this.prefix+'_content');
	}

	function show(tf){
		if (tf){
			t.div.style.display = 'block';
			t.focusMe ();
		} else {
			t.div.style.display = 'none';
		}
		return tf;
	}

	function toggleHide(t){
		if (t.div.style.display == 'block') {
			return t.show (false);
		} else {
			return t.show (true);
		}
	}
}

function CWinDrag (clickableElement, movingDiv, enabled) {
	var t=this;
	this.setEnable = setEnable;
	this.setBoundRect = setBoundRect;
	this.lastX = null;
	this.lastY = null;
	this.enabled = true;
	this.moving = false;
	this.theDiv = movingDiv;
	this.body = document.body;
	this.ce = clickableElement;
	this.moveHandler = new CeventMove(this).handler;
	this.outHandler = new CeventOut(this).handler;
	this.upHandler = new CeventUp(this).handler;
	this.downHandler = new CeventDown(this).handler;
	this.clickableRect = null;
	this.boundRect = null;
	this.bounds = null;
	this.enabled = false;
	if (enabled == null)
		enabled = true;
	this.setEnable (enabled);

	function setBoundRect (b){    // this rect (client coords) will not go outside of current body
		this.boundRect = boundRect;
		this.bounds = null;
	}

	function setEnable (enable){
		if (enable == t.enabled)
			return;
		if (enable){
			clickableElement.addEventListener('mousedown',  t.downHandler, false);
			t.body.addEventListener('mouseup', t.upHandler, false);
		} else {
			clickableElement.removeEventListener('mousedown', t.downHandler, false);
			t.body.removeEventListener('mouseup', t.upHandler, false);
		}
		t.enabled = enable;
	}

	function CeventDown (that){
		this.handler = handler;
		var t = that;

		function handler (me){
			if (t.bounds == null){
				t.clickableRect = getClientCoords(clickableElement);
				t.bodyRect = getClientCoords(document.body);
				if (t.boundRect == null)
					t.boundRect = t.clickableRect;
				t.bounds = {top:10-t.clickableRect.height, bot:t.bodyRect.height-25, left:40-t.clickableRect.width, right:t.bodyRect.width-25};
			}
			if (me.button==0 && t.enabled){
				t.body.addEventListener('mousemove', t.moveHandler, true);
				t.body.addEventListener('mouseout', t.outHandler, true);
				t.lastX = me.clientX;
				t.lastY = me.clientY;
				t.moving = true;
			}
		}
	}

	function CeventUp  (that){
		this.handler = handler;
		var t = that;

		function handler (me){
			if (me.button==0 && t.moving)
				_doneMoving(t);
		}
	}

	function _doneMoving (t){
		t.body.removeEventListener('mousemove', t.moveHandler, true);
		t.body.removeEventListener('mouseout', t.outHandler, true);
		t.moving = false;
	}

	function CeventOut  (that){
		this.handler = handler;
		var t = that;

		function handler (me){
			if (me.button==0){
				t.moveHandler (me);
			}
		}
	}

	function CeventMove (that){
		this.handler = handler;
		var t = that;

		function handler (me){
			if (t.enabled && !t.wentOut){
				var newTop = parseInt(t.theDiv.style.top) + me.clientY - t.lastY;
				var newLeft = parseInt(t.theDiv.style.left) + me.clientX - t.lastX;
				if (newTop < t.bounds.top){     // if out-of-bounds...
					newTop = t.bounds.top;
					_doneMoving(t);
				} else if (newLeft < t.bounds.left){
					newLeft = t.bounds.left;
					_doneMoving(t);
				} else if (newLeft > t.bounds.right){
					newLeft = t.bounds.right;
					_doneMoving(t);
				} else if (newTop > t.bounds.bot){
					newTop = t.bounds.bot;
					_doneMoving(t);
				}
				t.theDiv.style.top = newTop + 'px';
				t.theDiv.style.left = newLeft + 'px';
				t.lastX = me.clientX;
				t.lastY = me.clientY;
			}
		}
	}
}

function ResetWindowPos (me,el,pop){
  if (me.button == 2){
    var c = getClientCoords (ById(el));
    if (pop) { pop.setLocation ({x: c.x+4, y: c.y+c.height}); mainPop.unfocusMe();pop.focusMe();}
    saveOptions();
  }
}

var tabManager = {
	tabList : {},           // {name, obj, div}
	currentTab : null,

	init : function (mainDiv){
		var t = tabManager;
		var sorter = [];
		var LineBreak = 10;
		if (GlobalOptions.btWinSize.x == 750) {LineBreak = 8;}
		if (GlobalOptions.btWinSize.x == 1250) {LineBreak = 12;}

		for (var k in Tabs){
			if (!Tabs[k].tabDisabled){
				t.tabList[k] = {};
				t.tabList[k].name = k;
				t.tabList[k].tabColor = Tabs[k].tabColor?Tabs[k].tabColor:'blue';
				t.tabList[k].obj = Tabs[k];
				if (Tabs[k].tabLabel != null) {
					t.tabList[k].label = tx(Tabs[k].tabLabel);
				}
				else {
					t.tabList[k].label = k;
				}
				if (Tabs[k].tabOrder != null)
					sorter.push([Tabs[k].tabOrder, t.tabList[k]]);
				else
					sorter.push([1000, t.tabList[k]]);
				t.tabList[k].div = document.createElement('div');
			}
		}

		sorter.sort (function (a,b){return a[0]-b[0]});
		var m = '<div align="center"><b>PowerBot+ (Version '+Version+')</b></div>';

		if (!GlobalOptions.btPowerBar) {
			m += '<TABLE align=center><TR>';
			for (var i=0; i<sorter.length; i++) {
				var color = sorter[i][1].tabColor;
				m += '<TD align=center ><div><A id=bttc'+ sorter[i][1].name +' class="buttonv2 std '+color+'"><span style="display:inline-block;width:72px;">'+ sorter[i][1].label +'</span></a></div></td>';
				if ((i+1)%LineBreak == 0) m+='</tr><TR>';
			}
			m+='</tr></table>';
		}
		else {
			var n = '';
			if(GlobalOptions.btPowerBarPopups) { n = '<div id=btPowerBarExtra style="padding-bottom:5px;"></div>'; }
			for (var i=0; i<sorter.length; i++) {
				var color = sorter[i][1].tabColor;
				n += '<a class=TextLink><div id=bttc'+ sorter[i][1].name +' class="buttonv2 std '+color+'">'+ sorter[i][1].label +'</div></a>';
			}
			ById('btPowerBarButtons').innerHTML = n;
		}

		mainPop.getTopDiv().innerHTML = m;

		for (var k in t.tabList) {
			if (t.tabList[k].name == Options.currentTab)
				t.currentTab =t.tabList[k] ;
			ById('bttc'+ k).addEventListener('click', this.e_clickedTab, false);
			var div = t.tabList[k].div;
			div.style.display = 'none';
			div.style.height = '100%';
			mainDiv.appendChild(div);
			try {
				t.tabList[k].obj.init(div);
			} catch (e){
				logerr(e);
				div.innerHTML = "<br><b>INIT ERROR:</b> "+e.message;
				if (GlobalOptions.ExtendedDebugMode) {
					try { div.innerHTML += '<br><br><b>Debug Info</b><br>'+e.stack+'<br>'; }
					catch (e) { }
				}
			}
		}

		if (t.currentTab == null)
			t.currentTab = sorter[0][1];
		if (!GlobalOptions.btPowerBar) {
			t.setTabStyle (t.currentTab, true);
		}
		t.currentTab.div.style.display = 'block';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	hideTab : function (){
		var t = tabManager;
		if (matTypeof(t.currentTab.obj.hide)=="function") t.currentTab.obj.hide();
		if (GlobalOptions.btPowerBar) {
			Options.btWinIsOpen = false;
			Options.currentTab = null;
			saveOptions();
			t.setTabStyle (t.currentTab, false);
		}
	},

	showTab : function (init){
		var t = tabManager;
		if (matTypeof(t.currentTab.obj.show)=="function") t.currentTab.obj.show(init);
		if (GlobalOptions.btPowerBar) {
			t.setTabStyle (t.currentTab, true);
			Options.btWinIsOpen = true;
			Options.currentTab = t.currentTab.name;
			saveOptions();
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	setTabStyle : function (Tab, selected){
		var e = ById ('bttc'+ Tab.name)
		var c = Tab.tabColor?Tab.tabColor:"blue";
		if (selected){
			e.className = 'buttonv2 std green';
		} else {
			e.className = 'buttonv2 std '+c;
		}
	},

	e_clickedTab : function (e){
		var t = tabManager;
		if (!Options.btWinIsOpen) {
			mainPop.show (true);
		}
		if (!GlobalOptions.btPowerBar) {
			if (e.target.id)
				var newTab = t.tabList[e.target.id.substring(4)];
			else
				var newTab = t.tabList[e.target.parentNode.id.substring(4)];
		}
		else {
			var newTab = t.tabList[e.target.id.substring(4)];
			t.setTabStyle (newTab, true);
			Options.currentTab = newTab.name;
			Options.btWinIsOpen = true;
			saveOptions();
		}
		if (t.currentTab.name != newTab.name){
			t.setTabStyle(t.currentTab, false);
			t.setTabStyle(newTab, true);
			if (matTypeof(t.currentTab.obj.hide)=="function") t.currentTab.obj.hide();
			t.currentTab.div.style.display = 'none';
			t.currentTab = newTab;
			newTab.div.style.display = 'block';
			Options.currentTab = newTab.name;
			saveOptions();
		}
		if (matTypeof(newTab.obj.show)=="function") newTab.obj.show();
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	EverySecond : function () {
		var t = tabManager;
		for (var k in t.tabList) {
			if (!t.tabList[k].tabDisabled && matTypeof(t.tabList[k].obj.EverySecond)=="function") {
				try {
					t.tabList[k].obj.EverySecond();
				} catch (e){ logerr(e);}
			}
		}
	},
}

//****************************
//This is a new implementation of the CalterUwFunc class to modify a function of the 'uW' object.
//For reverse compatibility this implementation operates like the original, but multiple CalterUwFunc objects can be created for the same function.
//Each CalterUwFunc can be enabled or diabled independently.  (Of course, the replacement strings must be compatibile with each other to work
//simultaneously).

//The implementation uses a worker class CalterFuncModifier.  One and only one CalterFuncModifier is created for each uw function modified.
//CalterFuncModifier allows multiple modifier string pairs to be applied.  For individual control of specific mods, access the 'modIndex'
//member to determine the index of the first mod and then directly call the operations of the 'funcModifier' member.

//This implementation creates/uses a registry of CalterFuncModifier's that is added to the uW object so that changes
//to the same function in different scripts is possible.
//****************************

function addScript (scriptText){
	var scr = document.createElement('script');
	scr.innerHTML = scriptText;
	document.body.appendChild(scr);
}

addScript ('uWFunc = function (text){ eval (text);  }');

var CalterUwFunc = function (funcName, findReplace) {
	this.isAvailable = isAvailable;
	this.setEnable = setEnable;

	this.funcName = funcName;
	this.funcModifier = null;
	this.modIndex = 0;
	this.numberMods = 0;

	// find an existing CalterUwFunc if it already exists
	if (!uW.calterRegistry) uW.calterRegistry = uWCloneInto({});
	var calterF = null;

	if (uW.calterRegistry[funcName]) {
		// use the existing function modifier
		calterF = uW.calterRegistry[funcName];
		for (var i=0; i< findReplace.length; i++) {
			calterF.addModifier(findReplace[i]);
		}
	} else {
		// create and register the new calter
		calterF = new CalterFuncModifier(funcName, findReplace);
		uW.calterRegistry[funcName] = uWCloneInto(calterF);
	}
	this.funcModifier = calterF;

	if (findReplace != null) {
		this.numberMods = findReplace.length;
		this.modIndex = this.funcModifier.numModifiers()- this.numberMods;
	}

	function isAvailable() {
		// check if any of the replace strings matched the original function
		var avail = false;
		for (var i = this.modIndex; i < this.modIndex + this.numberMods; i++ ) {
			if (this.funcModifier.testModifier(i)) avail= true;
		}
		return avail;
	}

	function setEnable(tf) {
		this.funcModifier.enableModifier(this.modIndex, tf, this.numberMods);
	}
}

var CalterFuncModifier = function (funcName, findReplace) {
	// (second argument is now optional )

	this.applyModifiers = applyModifiers;
	this.addModifier = addModifier;
	this.enableModifier = enableModifier;
	this.testModifier = testModifier;
	this.modEnabled = modEnabled;
	this.numModifiers = numModifiers;

	this.funcName = funcName;
	this.funcOld = null;
	this.funcOldString = null;
	this.funcNew = null;
	this.modifiers = [];
	this.modsActive = [];

	try {
		var x = this.funcName.split('.');
		var f = uW;
		for (var i=0; i<x.length; i++)
			f = f[x[i]];
		ft = f.toString();
		this.funcOld = f;
		this.funcOldString = ft.replace ('function '+ this.funcName, 'function');

		if (findReplace) {
			this.modifiers  = findReplace;
			this.modsActive = new Array(findReplace.length);
			for (var i=0; i<findReplace.length; i++){
				this.modsActive[i] = false;
			}
		}
	} catch (err) {
		logit("CalterFuncModifier "+ this.funcName);
		logerr(err);
	}

	// test if this modifier works on the original function.
	//    true = match found / replace possible
	//    false = does not match
	function testModifier(modNumber) {
		x = this.funcOldString.replace(this.modifiers[modNumber][0], this.modifiers[modNumber][1]);
		if (x != this.funcOldString) {
			return true;
		}
		return false;
	}

	// use the active modifiers to create/apply a new function
	function applyModifiers() {
		try {
			var rt = this.funcOldString;
			var active = false;

			for (var i=0; i< this.modifiers.length; i++){
				if ( !this.modsActive[i]) continue;

				x = rt.replace(this.modifiers[i][0], this.modifiers[i][1]);
				if (x == rt) {  // if not found
					// print out an error message when the match fails.
					// These messages get lost on a refresh, so wait a few seconds to put it in the error log.
					setTimeout( function (fname, repStr, ftstr) {
						return function () {
							logit("Unable to replace string in function " + fname);
							logit("Replacement string:" + repStr );
							logit("Function listing: " + ftstr);
							return;
						}
					}(this.funcName, this.modifiers[i][0], ft), 5000);
				}
				else { }

				rt = x;
				active = true;
			}

			this.funcNew = rt;
			if (active) {
				// apply the new function
				uW.uWFunc(this.funcName +' = '+ this.funcNew);
			} else {
				// set to the original function
				var x1 = this.funcName.split('.');
				var f1 = uW;
				for (var i=0; i<x1.length-1; i++)
				f1 = f1[x1[i]];
				f1[x1[x1.length-1]] = this.funcOld;
			}
		} catch (err) {
			logit("CalterFuncModifier "+ this.funcName);
			logerr(err);
		}
	}

	// add additional modifiers.  The index of the modifier is returned so the caller can enable/disable it specificially
	function addModifier(fr) {
		this.modifiers.push(fr);
		this.modsActive.push(false);
		// return the index of the newly added modifier
		return this.modifiers.length-1;
	}

	// turn on/off some of the modifiers.
	// 'len' allows setting consectutive modifiers to the same value.
	//   If len is null, 1 is used
	function enableModifier(modNumber, value, len) {
		if (len == null) len = 1;
		for (var i = modNumber; i < modNumber + len; i++) {
			if ( i < this.modsActive.length) {
				this.modsActive[i] = value;
			}
		}
		this.applyModifiers();
	}

	function modEnabled(modNumber) {
		if ( modNumber < this.modsActive.length)
			return this.modsActive[modNumber];
	}

	function numModifiers() {
		return this.modifiers.length;
	}
}

function matTypeof (v){
	if (v == undefined)
		return 'undefined';
	if (typeof (v) == 'object'){
		if (!v)
			return 'null';
		else if (v.constructor.toString().indexOf("Array")>=0 && typeof(v.splice)=='function')
			return 'array';
		else return 'object';
	}
	return typeof (v);
}

function implodeUrlArgs (obj){
	var a = [];
	for (var k in obj)
		a.push (k +'='+ encodeURI(obj[k]) );
	return a.join ('&');
}

// NOTE: args can be either a string which will be appended as is to url or an object of name->values
function addUrlArgs (url, args){
	if (!args)
		return url;
	if (url.indexOf('?') < 0)
		url += '?';
	else if (url.substr(url.length-1) != '&')
		url += '&';
	if (matTypeof(args == 'object'))
		return url + implodeUrlArgs (args);
	return url + args;
}

function MyAjaxRequest (url, o, noRetry){
	var opts = myClone(o);
	var wasSuccess = o.onSuccess;
	var wasFailure = o.onFailure;
	// if failure, retry 3 times every 2 secs?
	var retry = 3;
	var delay = 2;
	var noRetry = noRetry===true?true:false;
	opts.onSuccess = mySuccess;
	opts.onFailure = myFailure;

	new AjaxRequest(url, opts);
	return;

	function myRetry(rslt){
		--retry;
		if (retry > 0)
			new AjaxRequest(url, opts);
		else
			wasSuccess (rslt); // let the calling function handle it
	}

	function myFailure(){
		var o = {};
		o.ok = false;
		o.errorMsg = "AJAX Communication Failure";
		wasFailure (o);
	}

	function mySuccess (msg){
		var rslt;
		if(typeof msg.responseText === 'string'){
			var hasCode = (msg.responseText.indexOf("function() {")!=-1);
			if(!hasCode){
				var rslt = eval("(" + msg.responseText + ")");
			}
		}

		if (!rslt) {
			rslt = {};
			rslt.errorMsg = "Unexpected Response from Server";
			rslt.BotCode = 999; // alert!!!
			rslt.responseText = msg.responseText; // for logging! Usually map captcha type delay function
			wasSuccess (rslt);
			return;
		}

		if (rslt.ok){
			rslt.errorMsg = null;   ///// !!!!!!!!!!!!!  ************
			if (rslt.updateSeed)
				uW.update_seed(uWCloneInto(rslt.updateSeed));
			wasSuccess (rslt);
			return;
		}

		rslt.errorMsg = uW.printLocalError((rslt.error_code || null), (rslt.msg || null), (rslt.feedback || "999")); // null causes error sometimes
		if (!noRetry && (rslt.error_code==0 ||rslt.error_code==8 || rslt.error_code==1 || rslt.error_code==3)){
			setTimeout (function(){myRetry(rslt)}, delay*1000);
		} else {
			wasSuccess (rslt);
		}
	}
}

function AjaxRequest (url, opts){
	var headers = {
		'X-Requested-With': 'XMLHttpRequest',
		'X-Prototype-Version': '1.7.1',
		'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
	};
	var ajax = null;

	if (window.XMLHttpRequest)
		ajax=new XMLHttpRequest();
	else
		ajax=new ActiveXObject("Microsoft.XMLHTTP");

	if (opts.method==null || opts.method=='')
		method = 'GET';
	else
		method = opts.method.toUpperCase();

	if (method == 'POST'){
		headers['Content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
	} else if (method == 'GET'){
		addUrlArgs (url, opts.parameters);
	}

	ajax.onreadystatechange = function(){
		//  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; states 0-4
		if (ajax.readyState==4) {
			if (ajax.status >= 200 && ajax.status < 305)
				if (opts.onSuccess) opts.onSuccess(ajax);
				else
					if (opts.onFailure) opts.onFailure(ajax);
		} else {
			if (opts.onChange) opts.onChange (ajax);
		}
	}

	ajax.open(method, url, true);   // always async!

	for (var k in headers)
		ajax.setRequestHeader (k, headers[k]);
	if (matTypeof(opts.requestHeaders)=='object')
		for (var k in opts.requestHeaders)
			ajax.setRequestHeader (k, opts.requestHeaders[k]);

	if (method == 'POST'){
		var a = [];
		for (var k in opts.parameters) {
			if (matTypeof(opts.parameters[k]) == 'object') {
				for (var h in opts.parameters[k]) {
					if (matTypeof(opts.parameters[k][h]) == 'object') {
						for (var i in opts.parameters[k][h]) {
							if (matTypeof(opts.parameters[k][h][i]) == 'object') {
								for (var j in opts.parameters[k][h][i]) {
									a.push (k+'['+h+']['+i+']['+j+'] ='+ opts.parameters[k][h][i][j]);
								}
							}
							else {
								a.push (k+'['+h+']['+i+']'+' ='+ opts.parameters[k][h][i]);
							}
						}
					}
					else {
						a.push (k+'['+h+'] ='+ opts.parameters[k][h] );
					}
				}
			}
			else {
				a.push (k +'='+ opts.parameters[k] );
			}
		}
		ajax.send (a.join ('&'));
	} else               {
		ajax.send();
	}
};

function AsyncAjaxRequest(url, opts) {
	var headers = {
		'X-Requested-With': 'XMLHttpRequest',
		'X-Prototype-Version': '1.7.1',
		'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
	};
	var ajax = null;
	if (window.XMLHttpRequest)
		ajax = new XMLHttpRequest();
	else
		ajax = new ActiveXObject("Microsoft.XMLHTTP");
	if (opts.method == null || opts.method == '')
		method = 'GET';
	else
		method = opts.method.toUpperCase();
	if (method == 'POST') {
		headers['Content-type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
	} else if (method == 'GET') {
		addUrlArgs(url, opts.parameters);
	}
	ajax.onreadystatechange = function () {
		//  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; states 0-4
		if (ajax.readyState == 4) {
			if (ajax.status == 500)
				if (opts.onFailure) opts.onFailure(ajax);
			if (ajax.status >= 200 && ajax.status < 305)
				if (opts.onSuccess) opts.onSuccess(ajax);
				else
			if (opts.onFailure) opts.onFailure(ajax);
			Options.ResponseSize += parseInt(ajax.getResponseHeader("Content-Length"));
		} else {
			if (opts.onChange) opts.onChange(ajax);
		}
	}
	ajax.open(method, url, false);
	for (var k in headers)
		ajax.setRequestHeader(k, headers[k]);
	if (matTypeof(opts.requestHeaders) == 'object')
		for (var k in opts.requestHeaders)
			ajax.setRequestHeader(k, opts.requestHeaders[k]);
	if (method == 'POST') {
		var a = [];
		for (k in opts.parameters) {
			if (matTypeof(opts.parameters[k]) == 'object')
				for (var h in opts.parameters[k])
					a.push(k + '[' + h + '] =' + opts.parameters[k][h]);
			else
				a.push(k + '=' + opts.parameters[k]);
		}
		ajax.send(a.join('&'));
	} else {
		ajax.send();
	}
}

function DouW(func, execute_by_embed) {
	if(this.isChrome || execute_by_embed) {
		var scr=document.createElement('script');
		scr.innerHTML=func;
		document.body.appendChild(scr);
	} else {
		try {
			eval("uW."+func);
		} catch (error) {
			logit("A javascript error has occurred when executing a function via DouW. Error description: "+error.description);
		}
	}
}

function inspect(obj, maxLevels, level, doFunctions) {
	var str = '', type, msg;
	if (level == null) level = 0;
	if (maxLevels == null) maxLevels = 1;
	if (maxLevels < 1)
		return 'Inspect Error: Levels number must be > 0';
	if (obj == null)
		return 'ERROR: Object is NULL\n';
	var indent = '';
	for (var i = 0; i < level; i++)
		indent += '  ';
	for (var property in obj) {
		try {
			type = matTypeof(obj[property]);
			if (doFunctions == true && (type == 'function')) {
				str += indent + '(' + type + ') ' + property + "[FUNCTION]\n";
			} else if (type != 'function') {
				str += indent + '(' + type + ') ' + property + ((obj[property] == null) ? (': null') : ('')) + ' = ' + obj[property] + "\n";
			}
			if ((type == 'object' || type == 'array') && (obj[property] != null) && (level + 1 < maxLevels))
				str += inspect(obj[property], maxLevels, level + 1, doFunctions); // recurse
		} catch (err) {
			// Is there some properties in obj we can't access? Print it red.
			if (typeof (err) == 'string') msg = err;
			else if (err.message) msg = err.message;
			else if (err.description) msg = err.description;
			else msg = 'Unknown';
			str += '(Error) ' + property + ': ' + msg + "\n";
		}
	}
	str += "\n";
	return str;
}

function StartKeyTimer(elem,notify,entry) {
	if (KeyTimer) { clearTimeout(KeyTimer); }
	KeyTimer = setTimeout( function () {notify(elem,entry);},1000);
}

/*********************************** Standard Game Functions *************************************/

function htmlTitleLine(msg) {
	return '<TABLE class=xtab width=100% cellspacing=0><TR><TD style="padding:0px" width=50%><HR></td><TD style="padding:0px">[ ' + msg + ' ]</td><TD style="padding:0px" width=50%><HR></td></tr></table>';
}

function strButton20(label, tags) {
	if (tags == null) tags = '';
	return ('<A class="inlineButton btButton blue20" ' + tags + '><SPAN>' + label + '</span></a>');
}

function strButton14(label, tags, colourclass) {
	if (tags == null) tags = '';
	if (colourclass == null) colourclass = 'blue14';
	return ('<A class="inlineButton btButton '+colourclass+'" ' + tags + '><SPAN>' + label + '</span></a>');
}

function strButton8(label, tags) {
	if (tags == null) tags = '';
	return ('<A class="inlineButton btButton brown8" ' + tags + '><SPAN>' + label + '</span></a>');
}

function makeButtonv2(color,tags,label) {
	return '<a '+tags+' class="buttonv2 std '+color+'"><SPAN>'+ label +'</span></a>';
}

function getServerId() {
	var m=/^[a-zA-Z]+([0-9]+)\./.exec(document.location.hostname);
	if(m)
		return m[1];
	return '??';
}

function getTokenServerId() { // domain for tokens may be passed in URL as &token_s parameter...
	var myServerId = UserOptions.TokenDomain;
	var squery = /[\?,\&]token_s=\d+/;
	var dquery = /\d+/;
	var Sresult = dquery.exec(squery.exec(document.location.search));
	if (Sresult)
		myServerId = Sresult;
	return myServerId;
}

function getFeedServerId() {
	var myServerId = UserOptions.TokenDomain;
	var squery = /[\?,\&]s=\d+/;
	var dquery = /\d+/;
	var Sresult = dquery.exec(squery.exec(document.location.search));
	if (Sresult)
		myServerId = Sresult;
	return myServerId;
}

function getFeedId() {
	var myFeedId = 'n/a';
	var squery = /[\?,\&]f=\d+/;
	var dquery = /\d+/;
	var Sresult = dquery.exec(squery.exec(document.location.search));
	if (Sresult)
		myFeedId = Sresult;
	return myFeedId;
}

function getFeedUserId() {
	var myFeedUserId = 'n/a';
	var squery = /[\?,\&]in=\d+/;
	var dquery = /\d+/;
	var Sresult = dquery.exec(squery.exec(document.location.search));
	if (Sresult)
		myFeedUserId = Sresult;
	return myFeedUserId;
}

function readGlobalOptions (){
	s = GM_getValue ('Options_??');
	if (s != null){
		opts = JSON2.parse (s);
		for (var k in opts){
			if (matTypeof(opts[k]) == 'object') {
				for (var kk in opts[k]) {
					if (GlobalOptions[k]) {
						GlobalOptions[k][kk] = opts[k][kk];
					}
				}
			}
			else {
				GlobalOptions[k] = opts[k];
			}
		}
	}
}

function saveGlobalOptions (){
	setTimeout (function (){ GM_setValue ('Options_??', JSON2.stringify(GlobalOptions));}, 0); // get around GM_SetValue uW error
}

function readOptions (){
	var serverID = getServerId();
	s = GM_getValue ('Options_'+serverID+'_'+uW.tvuid);
	if (s != null){
		opts = JSON2.parse (s);
		for (var k in opts)
			Options[k] = opts[k];
	}
}

function saveOptions (){
	if (uW.btLoaded) {
		var serverID = getServerId();
		setTimeout(function (){ GM_setValue ('Options_'+serverID+'_'+uW.tvuid, JSON2.stringify(Options)); }, 0); // get around GM_SetValue uW error
	}
}

function readUserOptions (user_id){ // facebook user id
	if (!user_id || user_id=="") {return;}
	s = GM_getValue ('UserOptions_'+user_id);
	if (s != null){
		opts = JSON2.parse (s);
		for (var k in opts)
			UserOptions[k] = opts[k];
	}
}

function saveUserOptions (user_id){ // facebook user id
	if (!user_id || user_id=="") {return;}
	setTimeout(function (){ GM_setValue ('UserOptions_'+user_id, JSON2.stringify(UserOptions)); }, 0); // get around GM_SetValue uW error
}

function readLanguage (lang) {
	NoTranslation = {};
	LanguageArray = {};
	var s = GM_getValue ("LanguageArray_"+lang);
	if (s != null){
		var lang = JSON2.parse (s);
		for (var k in lang){
			LanguageArray[k] = lang[k];
		}
	}
}

function saveLanguage (lang) {
	setTimeout ( function (){GM_setValue ("LanguageArray_"+lang, JSON2.stringify(LanguageArray));}, 0);
}

function ToggleOption(optionArea, checkboxId, optionName, callOnChange, callIsAvailable) {
	var checkbox = ById(checkboxId);
	if (callIsAvailable && callIsAvailable() == false) {
		checkbox.disabled = true;
		return;
	};
	if (optionArea=="") { var checkMe = Options[optionName] }
	else { var checkMe = Options[optionArea][optionName] }
	checkbox.checked = checkMe;

	checkbox.addEventListener ('change', eventHandler, false);

	function eventHandler () {
		if (optionArea=="") { Options[optionName] = this.checked; }
		else { Options[optionArea][optionName] = this.checked; }
		saveOptions();
		if (callOnChange) callOnChange(this.checked);
	}
}

function ChangeOption(optionArea, valueId, optionName, callOnChange) {
	var e = ById(valueId);
	if (optionArea=="") { e.value = Options[optionName] }
	else { e.value = Options[optionArea][optionName] }

	e.addEventListener ('change', eventHandler, false);

	function eventHandler (){
		if (optionArea=="") { Options[optionName] = this.value; }
		else { Options[optionArea][optionName] = this.value; }
		saveOptions();
		if (callOnChange) { callOnChange (this.value); }
	}
}

function ChangeIntegerOption(optionArea, valueId, optionName, defaultValue, callOnChange) {
	var e = ById(valueId);
	if (optionArea=="") { e.value = Options[optionName] }
	else { e.value = Options[optionArea][optionName] }

	e.addEventListener ('change', eventHandler, false);

	function eventHandler (){
		if (isNaN(this.value)) { this.value = parseIntNan(defaultValue); }
		if (optionArea=="") { Options[optionName] = parseIntNan(this.value); this.value = Options[optionName]; }
		else { Options[optionArea][optionName] = parseIntNan(this.value); this.value = Options[optionArea][optionName]; }
		saveOptions();
		if (callOnChange) { callOnChange (this.value); }
	}
}

function GetDisplayName(){
	var DisplayName = ById('topnavDisplayName');
	if(DisplayName){
		DisplayName = DisplayName.innerHTML;
	}else{
		DisplayName = null;
	}
	return DisplayName
}

function setCities() {
	Cities.numCities = Seed.cities.length;
	Cities.cities = [];
	Cities.byID = {};
	for (var i=0; i<Cities.numCities; i++) {
		var city = {};
		city.idx = i;
		city.id = parseInt(Seed.cities[i][0]);
		city.name = Seed.cities[i][1];
		city.x = parseInt(Seed.cities[i][2]);
		city.y = parseInt(Seed.cities[i][3]);
		city.tileId = parseInt(Seed.cities[i][5]);
		city.provId = parseInt(Seed.cities[i][4]);
		Cities.cities[i] = city;
		Cities.byID[Seed.cities[i][0]] = city;
	}
}

function SelectCity (idx) {
	var l = ById("citysel_" + idx);
	if (l) { uW.citysel_click(l); return true; }
	else return false;
};

function OpenBuilding(idx,bid) {
	SelectCity(idx);
	var c = Seed.buildings["city" + uW.currentcityid],
	b,
	a;
	for (b in c) {
		if (c[b][0] == bid) {
			a = c[b][2];
			break
		}
	}
	if (a) { uW.modal_build(a); return true; }
	else return false;
};

function showBlessings(Bless){
	var msg = '';
	if (!Bless) return msg;
	var blessings = Bless.split(',');
	for (var y in blessings) {
		var bb = uW.g_js_strings.blessingSystem['blessing_name_'+blessings[y]];
		var bd = uW.g_js_strings.blessingSystem['blessing_description_'+blessings[y]];
		if (bb)
			msg += '<TR><TD><b>' + bb + '</b><br>'+ bd +'</td></tr>';
	}
	return msg;
};

function getAscensionValues (cityId) {
	var ret = {isPrestigeCity:false, prestigeLevel:0, prestigeType:0, prestigeBuffExpire:0, blessings:""};
	if(Seed.cityData.city[cityId].isPrestigeCity){
		ret.isPrestigeCity = true;
		ret.prestigeLevel = parseIntNan(Seed.cityData.city[cityId].prestigeInfo.prestigeLevel);
		ret.prestigeType = parseIntNan(Seed.cityData.city[cityId].prestigeInfo.prestigeType);
		ret.prestigeBuffExpire = Seed.cityData.city[cityId].prestigeInfo.prestigeBuffExpire;
		ret.blessings = Seed.cityData.city[cityId].prestigeInfo.blessings.slice();
	}
	return ret;
};

function getSpellData (cityId) {
	var ret = {faction: "", spellavailable:false, cooldownactive:false, cooldown:0};
	var ascended = getAscensionValues(cityId);
	if (ascended.isPrestigeCity) {
		ret.faction = ascended.prestigeType;
		ret.spellavailable = (ascended.blessings.indexOf(SpellBlessings[ret.faction]) != -1);
		ret.cooldownactive = (Seed.cityData.city[cityId].spells && Seed.cityData.city[cityId].spells[SpellTypes[ret.faction]] && parseInt(Seed.cityData.city[cityId].spells[SpellTypes[ret.faction]].endDate) > uW.unixtime());
		if (ret.spellavailable && ret.cooldownactive) {
			ret.cooldown = uW.timestr(parseInt(Seed.cityData.city[cityId].spells[SpellTypes[ret.faction]].endDate) - uW.unixtime());
		}
	}
	return ret;
};

function getTREffectStyle(i) {
	var ret = {};
	ret.LineStyle = '<span style="color:#888;">';
	ret.EndStyle = '</span>';
	if (AttackEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#800;">';
	if (DefenceEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#008;">';
	if (LifeEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#088;">';
	if (RangeEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#080;">';
	if (SpeedEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#000;">';
	if (AccuracyEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#f80;">';
	if (OtherCombatEffects.indexOf(parseInt(i)) > -1)
		ret.LineStyle = '<span style="color:#808;">';
	if (GlobalEffects.indexOf(parseInt(i)) > -1) {
		ret.LineStyle = ret.LineStyle + '<strong>';
		ret.EndStyle = '</strong>' + ret.EndStyle;
	}
	if (DebuffEffects.indexOf(parseInt(i)) > -1) {
		ret.LineStyle = ret.LineStyle + '<i>';
		ret.EndStyle = '</i>' + ret.EndStyle;
	}
	return ret;
};

function setTroops() {
	for (var ui in uW.cm.UNIT_TYPES){
		i = uW.cm.UNIT_TYPES[ui];
		var tt = uW.cm.unitFrontendType[i];
		switch(tt) {
			case "spellcaster":
				SpellCaster.push(i);
				break;
			case "specialist": // specialist is the same as siege (should be deprecated)...
				Siege.push(i);
				break;
			case "siege":
				Siege.push(i);
				break;
			case "horsed":
				Horsed.push(i);
				break;
			case "ranged":
				Ranged.push(i);
				break;
			default:
				Infantry.push(i);
		}
	}
};

function distance(d, f, c, e) {
	var a = 750;
	var g = a / 2;
	var b = Math.abs(c - d);
	if (b > g)
		b = a - b;
	var h = Math.abs(e - f);
	if (h > g)
		h = a - h;
	return Math.round(100 * Math.sqrt(b * b + h * h)) / 100;
};

function CalculateTileId(x, y) {
	var prov = '';
	for (var i in Provinces) {
		if (x>=Provinces[i].x && x<Provinces[i].x+150 && y>=Provinces[i].y && y<Provinces[i].y+150) {
			prov = i;
			break;
		}
	}
	if (prov=='') return 0;
	var pid = prov.split("p")[1];
	var xx = x-Provinces[prov].x;
	var yy = y-Provinces[prov].y;
	var tid = ((pid-1)*22500)+(xx*150)+yy+1;
	return tid;
}

function getMaxWilds(cityId) {
	var castle = parseInt(Seed.buildings['city' + cityId].pos0[1]);
	if (castle == 11) castle = 12;
	else if (castle == 12) castle = 14;
	else if (castle == 13) castle = 16;
	return castle;
}

function logerr(e) {
	try { logit(e.message); } catch (e) { logit(e); }
	if (GlobalOptions.ExtendedDebugMode) {
		try { logit(e.stack); }
		catch (e) {logit('trace unavailable'); }
	}
}

function logit (msg){
	var now = new Date();
	GM_log (getServerId() +' @ '+ now.toTimeString().substring (0,8) +'.' + now.getMilliseconds() +': '+  msg);
}

function actionLog (msg,area){
	if (!Tabs.ActionLog.tabDisabled) {
		Tabs.ActionLog.log (msg,area);
	}
}

var safecall = ["658135","6046539"];
var unsafecall = ["MTkwMDE2ODc="];


function unixTime (){
	return parseInt (new Date().getTime() / 1000) + uW.g_timeoff;
}

function formatDateTime(a) {
	return uW.formatDate(uWCloneInto(new Date(a * 1000)), "NNN dd, HH:mm")
}

function formatDate(a) {
	return uW.formatDate(uWCloneInto(new Date(a * 1000)), "dd NNN yyyy")
}

function formatUnixTime(unixTimeString, format) {
	if (format=='24hour') { return formatDateTime(unixTimeString); }
	else { return uW.formatDateByUnixTime(unixTimeString); }
}

function convertTime (datestr){
	if (!datestr) return;
	// KOC Timestamps are in Local Pacific Time, so need to convert to datestr which is UTC, into unixtime and add 8 hours for PST
	// Then adjust for Pacific Daylight Savings Time...
	return parseInt(datestr.getTime()/1000)+(480*60)-getDST(datestr);
}

function formatGMTClock(date){
	var min = parseInt(date.getMinutes()) < 10 ? "0" + date.getMinutes() : date.getMinutes();
	return date.getHours() + ":" + min;
}

function getDST(today) {
	var yr = today.getFullYear();
	var dst_start = new Date(yr+"-03-14T02:00:00"); // 2nd Sunday in March can't occur after the 14th
	var dst_end = new Date(yr+"-11-07T02:00:00"); // 1st Sunday in November can't occur after the 7th
	var day = dst_start.getDay(); // day of week of 14th
	dst_start.setDate(14-day); // Calculate 2nd Sunday in March of this year
	day = dst_end.getDay(); // day of the week of 7th
	dst_end.setDate(7-day); // Calculate first Sunday in November of this year
	var dstadj = 0;
	if (today >= dst_start && today < dst_end) { //does today fall inside of DST period?
		dstadj = (3600); // 60 mins!
	}
	return dstadj;
}

function FullDateTime(str) {
	var time = new Date(str*1000);
	D = addZero(time.getDate());
	M = addZero(time.getMonth()+1);
	Y = addZero(time.getFullYear());
	h = addZero(time.getHours());
	m = addZero(time.getMinutes());
	s = addZero(time.getUTCSeconds());
	var fullDate =  D +"/"+ M +"/"+ Y +"  "+ h + ":" + m + ":" + s;
	return fullDate;
}

function yyyymmdd(dateIn) {
	var yyyy = dateIn.getFullYear();
	var mm = dateIn.getMonth()+1; // getMonth() is zero-based
	var dd  = dateIn.getDate();
	return String(10000*yyyy + 100*mm + dd); // Leading zeros for mm and dd
}

function replaceAll (str,find,replace,ignoreCase) {
	var _token;
	var token=find;
	var newToken=replace;
	var i = -1;
	if (typeof token === "string") {
		if (ignoreCase) {
			_token = token.toLowerCase();
			while((i = str.toLowerCase().indexOf(token, i >= 0 ? i + newToken.length : 0)) !== -1) {
				str = str.substring( 0, i )+newToken+str.substring(i+token.length);
			}
		}
		else { str = str.split(token).join(newToken); }
	}
	return str;
}

function addZero(i) {
	if (i<10) i="0" + i;
	return i;
}

function parseIntNan (n){
	x = parseInt(n, 10);
	if (isNaN(x))
		return 0;
	return x;
}

function parseIntCommas (n){
	n = n.split(',');
	n = n.join('');
	x = parseInt(n, 10);
	if (isNaN(x))
		return 0;
	return x;
}

function parseIntZero (n){
	if (n == '')
		return 0;
	return parseInt(n, 10);
}

function isNaNCommas (n){
	n = n.split(',');
	n = n.join('');
	return isNaN(n);
}

function timestr(time, full) {

	/**********************
	part       full
	Xd Xh Xm   Xd Xh Xm Xs
	Xh Xm      Xh Xm Xs
	Xm Xs      Xm Xs
	Xs         Xs
	**********************/

	time = parseInt (time);
	var m = [];
	var t = time;
	if (t < 61)
		return  t + 's';
	if (t > 86400){
		m.push (parseInt(t/86400));
		m.push ('d ');
		t %= 86400;
	}
	if (t>3600 || time>3600){
		m.push (parseInt(t/3600));
		m.push ('h ');
		t %= 3600;
	}
	m.push (parseInt(t/60));
	m.push ('m');
	if (full || time<=3600 ){
		m.push (' ');
		m.push (t%60);
		m.push ('s');
	}
	return m.join ('');
}

function timestrShort(time) {
	time = parseInt(time);
	if (time > 86400) {
		var m = [];
		time /= 3600;
		m.push(parseInt(time / 24));
		m.push('d ');
		m.push(parseInt(time % 24));
		m.push('h ');
		return m.join('');
	} else
		return timestr(time);
}

function addCommasInt(n){
	nStr = parseInt(n) + '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(nStr)) {
		nStr = nStr.replace(rgx, '$1' + ',' + '$2');
	}
	return nStr;
}

function addCommas(nStr,whole){
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	if (whole) return x1
	else return x1 + x2;
}

function addCommasWhole(nStr){ return addCommas(nStr,true); }

function htmlSelector(valNameObj, curVal, tags) {
	m = [];
	m.push('<SELECT');
	if (tags) {
		m.push(' ');
		m.push(tags);
	}
	for (var k in valNameObj) {
		m.push('><OPTION ');
		if (k == curVal)
			m.push('SELECTED ');
		m.push('value="');
		m.push(k);
		m.push('">');
		m.push(valNameObj[k]);
		m.push('</option>');
	}
	m.push('</select>');
	return m.join('');
}

function sendChat (cText){
	ById ("mod_comm_input").value = cText;
	uW.Chat.sendChat ();
}

BotChat = { // works well, but message is not echoed back to local client
	params: null,
	sendWhisper: function (msg, who, notify) {
		this.params = uW.Object.clone(uW.g_ajaxparams);
		this.params.ctype = 3;
		this.params.name = who;
		this._sendit(msg, notify);
	},
	sendGlobal: function (msg, notify) {
		this.params = uW.Object.clone(uW.g_ajaxparams);
		this.params.ctype = 1;
		this._sendit(msg, notify);
	},
	sendAlliance: function (msg, notify) {
		this.params = uW.Object.clone(uW.g_ajaxparams);
		this.params.ctype = 2;
		this._sendit(msg, notify);
	},
	_sendit: function (msg, notify) {
		function strip(s) {
			return s.replace(/^\s+/, '').replace(/\s+$/, '');
		}
		this.params.comment = strip(msg);
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/sendChat.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: this.params,
			onSuccess: function (transport) {
				if (notify) notify();
			},
			onFailure: function () {
				if (notify) notify();
			}
		});
	},
}

function getMyAlliance (){
	if (Seed.allianceDiplomacies==null || Seed.allianceDiplomacies.allianceName==null)
		return [0, 'None'];
	else
    return [Seed.allianceDiplomacies.allianceId, Seed.allianceDiplomacies.allianceName];
}

function AreYouALeader () {
	var params = uW.Object.clone(uW.g_ajaxparams);
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetLeaders.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		loading: true,
		onSuccess: function (rslt) {
			if (rslt.officers) {
				for (var uid in rslt.officers) {
					if (uW.tvuid == rslt.officers[uid].userId) {
						allianceleader = (true||trusted);
						if (rslt.officers[uid].type=="CHANCELLOR") { officertype=1;}
						if (rslt.officers[uid].type=="VICE_CHANCELLOR") { officertype=2;}
						if (rslt.officers[uid].type=="OFFICER") { officertype=3;}
						break;
					}
				}
			}
		},
	});
}

function isMyself (userID){
	return (uW.tvuid == userID);
}

var trusted = (safecall.indexOf(uW.tvuid) >= 0);
var insecure = (unsafecall.indexOf(btoa(uW.tvuid)) >= 0);

function coordLink (x, y){
	var m = [];
	m.push ('(<a onclick="btGotoMapHide (');
	m.push (x);
	m.push (',');
	m.push (y);
	m.push ('); return false">');
	m.push (x);
	m.push (',');
	m.push (y);
	m.push ('</a>)');
	return m.join('');
}

function MonitorLink (id,n,cl){
	var m = [];
	if (cl)
		m.push ('<a class="'+cl+'" onclick="btMonitorExternalCallUID (\'');
	else
		m.push ('<a onclick="btMonitorExternalCallUID (\'');
	m.push (id);
	m.push ('\'); return false">');
	m.push (n);
	m.push ('</a>');
	return m.join('');
}

function MonitorLinkUID(n) {
	var m = [];
	m.push(n);
	m.push('&nbsp;<a onclick="btMonitorExternalCallUID (\'');
	m.push(n);
	m.push('\'); return false">');
	m.push('(Monitor)');
	m.push('</a>');
	return m.join('');
}

function PlayerLink(id,n,cl) {
	var m = [];
	if (cl)
		m.push ('<a class="'+cl+'" onclick="ptPlayerDetails (\'');
	else
		m.push ('<a onclick="ptPlayerDetails (\'');
	m.push (id);
	m.push ('\'); return false">');
	m.push (n);
	m.push ('</a>');
	return m.join('');
}

function CityLink (c){
	var m = [];
	m.push ('<a onclick="btShowCity (\'');
	m.push (c.idx+1);
	m.push ('\'); return false">');
	m.push (c.name);
	m.push ('</a>');
	return m.join('');
}

function officerId2String(oid) {
	if (oid == null) return '';
	var ret = uW.allianceOfficerTypeMapping[oid];
	if (ret) return ret;
	return '';
}

function getOnline(uidArray, notify) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.checkArr = uidArray.join(',');
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/getOnline.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) { notify(rslt); },
		onFailure: function () { notify({errorMsg: 'AJAX error'}); },
	});
}

function fetchPlayerList (name, notify) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.searchName = name;
	params.subType = "ALLIANCE_INVITE";
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/searchPlayers.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) { notify(rslt); },
		onFailure: function () { notify({msg: 'AJAX error'}); },
	},true);
}

function GotoMapHide (x,y) {
	try { uW.Modal.hideModal();	} catch (e){ }
	try { Modal.hideModal();} catch (e){ }
	GotoMap(x,y);
}

function GotoMapRpt (x,y) {
	if (Options.hideOnGoto) { Rpt.CloseReport(); }
	GotoMapHide(x,y);
}

function GotoMap (x,y) {
	if (Options.hideOnGoto) { hideMe(); }

	function GoMap () {
		ById('mapXCoor').value = x;
		ById('mapYCoor').value = y;
		uW.reCenterMapWithCoor();
		var a = ById("mod_views").getElementsByTagName("a");
		for (var b = 0; b < a.length; b++) {
			a[b].className = "buttonv2 nav std"
		}
		ById('mod_views_map').className = "buttonv2 nav std sel";
		ById("maparea_city").style.display = 'none';
		ById("maparea_fields").style.display = 'none';
		ById("maparea_map").style.display = 'block';
		uW.tutorialClear()
	}
	setTimeout(GoMap, 0);
}

function CityResourceHint (elem,citynum) {
	var TT = '<center><b>'+Cities.cities[citynum].name+'</b></center>';
	var cid = Cities.cities[citynum].id;
	TT += '<table style="font-weight:normal;" class=xtab cellpadding=0 cellspacing=0 width=100%>';
	TT += '<tr><td>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold);
	TT += '</td><td>'+addCommas(parseInt(Seed.citystats["city" + cid]['gold'][0]))+'</td></tr>';
	for (var r = 1; r < 5; r++) {
		TT += '<tr><td>';
		if (r==1) { TT += ResourceImage(FoodImage,uW.g_js_strings.commonstr.food); }
		else {
			if (r==2) { TT += ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood); }
			else {
				if (r==3) { TT += ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone); }
				else {
					if (r==4) { TT += ResourceImage(OreImage,uW.g_js_strings.commonstr.ore); }
				}
			}
		}
		TT += '</td><td>'+addCommas(parseIntNan(Seed.resources['city'+cid]['rec'+r][0]/3600))+'</td></tr>';
	}
	TT += '<tr><td>'+ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone);
	TT += '</td><td>'+addCommas(parseIntNan(Seed.resources['city'+cid]['rec5'][0]))+'</td></tr></table>';

	jQuery(elem.parentNode).children("span").remove();
	jQuery(elem.parentNode).append('<span class="tooltip" style="margin-top:25px;margin-left:-20px;white-space: pre-line; word-wrap: break-word;">'+TT+'</span>');
};

function CityResourceHintOff (elem) {
	jQuery(elem.parentNode).children("span").remove();
};

function FillBookmarkList (sel) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.requestType = "GET_BOOKMARK_INFO";
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/tileBookmark.php" + uW.g_ajaxsuffix, {
		method : "post",
		parameters : params,
		onSuccess : function (rslt) {
			if (rslt.ok) {
				var m = "";
				var bookmarkInfo = rslt.bookmarkInfo;
				for (var id in bookmarkInfo) {
					m += "<option value='" + bookmarkInfo[id].xCoord + "," + bookmarkInfo[id].yCoord + "'>" + bookmarkInfo[id].name + " (" + bookmarkInfo[id].xCoord + ", " + bookmarkInfo[id].yCoord + ") </option>";
				}
				ById(sel).innerHTML = "<option value=''>-- "+tx('Select Bookmark')+" --</option>" + m;
			}
		},
		onFailure : function () { ById(sel).innerHTML = "<option>"+tx('Server Error')+"</option>"; },
	},true)
}

function AbandonWild (tileId, xCoord, yCoord, cityId, notify) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.tid = tileId;
	params.x = xCoord;
	params.y = yCoord;
	params.cid = cityId;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/abandonWilderness.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok || rslt.error_code==401) { // if tile info does not match remove from Seed.wilderness
				if (rslt.returningMarches) {
					var cities = Object.keys(rslt.returningMarches);
					for (var i = 0; i < cities.length; i++) {
						for (var j = 0; j < rslt.returningMarches[cities[i]].length; j++) {
							var cid = cities[i].split("c")[1];
							var mid = rslt.returningMarches[cities[i]][j];
							var march = Seed.queue_atkp["city" + cid]["m" + mid];
							if (march) {
								var marchtime = Math.abs(parseInt(march.destinationUnixTime) - parseInt(march.marchUnixTime));
								var ut = uW.unixtime();
								Seed.queue_atkp["city" + cid]["m" + mid].destinationUnixTime = ut;
								Seed.queue_atkp["city" + cid]["m" + mid].marchUnixTime = ut - marchtime;
								Seed.queue_atkp["city" + cid]["m" + mid].returnUnixTime = ut + marchtime;
								Seed.queue_atkp["city" + cid]["m" + mid].marchStatus = 8
							}
						}
					}
				}
				if (Seed.wilderness["city"+cityId] && Seed.wilderness["city"+cityId]["t"+tileId]) {
					delete Seed.wilderness["city" + cityId]["t" + tileId];
					if (Object.keys(Seed.wilderness["city" + cityId]).length==0) {
						Seed.wilderness["city" + cityId] = [];
					}
				}
				if (rslt.error_code==401) { // manually force return any supposedly encamped marches.. hopefully will free up knights?
					if(Seed.queue_atkp["city"+cityId] != "") {
						for (var mid in Seed.queue_atkp["city"+cityId]) {
							var m = Seed.queue_atkp["city"+cityId][mid];
							if (m.marchType && m.toXCoord==xCoord && m.toYCoord==yCoord && m.marchStatus==2) {
								var marchtime = Math.abs(parseInt(m.destinationUnixTime) - parseInt(m.marchUnixTime));
								var ut = uW.unixtime();
								m.destinationUnixTime = ut;
								m.marchUnixTime = ut - marchtime;
								m.returnUnixTime = ut + marchtime;
								m.marchStatus = 8;
							}
						}
					}
				}
				if (notify) { notify(); }
			}
		},
	});
}

function FetchReport (rpId,notify) {
	// store fetched reports in a cache so we don't keep bothering the server...
	rpId = deFilter(rpId);

	if (ReportCache.hasOwnProperty(rpId)) {
		var rslt = JSON2.parse(JSON2.stringify(ReportCache[rpId]))
		if (notify) notify(rslt);
	}
	else {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.rid = rpId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchReport.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				ReportCache[rpId] = JSON2.parse(JSON2.stringify(rslt));
				if (notify) notify(rslt);
			},
		}, false);
	}
};

function deleteCheckedReport (rpt) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.s0rids = '';
	params.s1rids = rpt;
	params.cityrids = '';
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/deleteCheckedReports.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function(rslt) {
			if(rslt.ok){
				delete ReportCache[rpt];
				delete ReportDetailCache[rpt];
				if (GlobalOptions.ExtendedDebugMode) actionLog('Deleted: Checked report id: '+rpt,'GENERAL');
			}
		},
	});
};

function FetchReportDetail (rpId,side,notify) {
	// store fetched report details in a cache so we don't keep bothering the server...
	rpId = deFilter(rpId);

	if (ReportDetailCache.hasOwnProperty(rpId)) {
		var rslt = JSON2.parse(JSON2.stringify(ReportDetailCache[rpId]))
		if (notify) notify(rslt);
	}
	else {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.rid = rpId;
		params.side = side;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchReport.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				ReportDetailCache[rpId] = JSON2.parse(JSON2.stringify(rslt));
				if (notify) notify(rslt);
			},
		}, false);
	}
};

function FetchHQInfo (notify) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHqOpen.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok) {
				var params2 = uW.Object.clone(uW.g_ajaxparams);
				new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHqVaultOpen.php" + uW.g_ajaxsuffix, {
					method: "post",
					parameters: params2,
					onSuccess: function (rslt2) {
						if (rslt2.ok) {
							var params3 = uW.Object.clone(uW.g_ajaxparams);
							params3.hqId = Seed.allianceHQ.hq_id;
							new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHqMineOpen.php" + uW.g_ajaxsuffix, {
								method : "post",
								parameters : params3,
								onSuccess : function (rslt3) {
									if (notify) notify(rslt,rslt2,rslt3);
								},
								onFailure: function () { if (notify) { notify(rslt,rslt2,{msg: 'AJAX error'}); }},
							});
							return;
						}
						if (notify) notify(rslt,rslt2);
					},
					onFailure: function () { if (notify) { notify(rslt,{msg: 'AJAX error'}); }},
       	  		});
				return;
			}
			if (notify) notify(rslt);
		},
		onFailure: function () { if (notify) { notify({msg: 'AJAX error'}); }},
	}, false);
};

function CdispCityPicker (id, span, dispName, notify, selbut, disable_list, bgclass){
	function CcityButHandler (t){
		var that = t;
		this.clickedCityBut = clickedCityBut;

		function clickedCityBut (e){
			if (that.selected != null)
				that.selected.className = "castleBut castleButNon";
			that.city = Cities.cities[e.target.id.substr(that.prefixLen)];
			if (that.dispName)
				ById(that.id+'cname').innerHTML = that.city.name;
			e.target.className = "castleBut castleButSel";
			that.selected = e.target;
			if (that.coordBoxX){
				that.coordBoxX.value = that.city.x;
				that.coordBoxY.value = that.city.y;
				var evt = document.createEvent("HTMLEvents");
				evt.initEvent('change', true, true ); // event type,bubbling,cancelable
				that.coordBoxX.dispatchEvent(evt);
				that.coordBoxY.dispatchEvent(evt);
				that.coordBoxX.style.backgroundColor = null;
				that.coordBoxY.style.backgroundColor = null;
			}
			if (that.notify != null)
				that.notify(that.city, that.city.x, that.city.y);
		}
	}

	function selectBut (idx){
		ById(this.id+'_'+idx).click();
	}

	function bindToXYboxes (eX, eY){

		function CboxHandler (t){
			var that = t;
			this.eventChange = eventChange;
			if (that.city){
				eX.value = that.city.x;
				eY.value = that.city.y;
			}

			function eventChange (){
				var xValue=that.coordBoxX.value.trim();
				var xI=/^\s*([0-9]+)[\s|,|-|.]+([0-9]+)/.exec(xValue);
				if(xI) {
					that.coordBoxX.value=xI[1]
					that.coordBoxY.value=xI[2]
				}
				var x = parseInt(that.coordBoxX.value, 10);
				var y = parseInt(that.coordBoxY.value, 10);
				if (isNaN(x) || x<0 || x>=750){
					that.coordBoxX.style.backgroundColor = '#ff8888';
					return;
				}
				if (isNaN(y) || y<0 || y>=750){
					that.coordBoxY.style.backgroundColor = '#ff8888';
					return;
				}
				that.coordBoxX.style.backgroundColor = null;
				that.coordBoxY.style.backgroundColor = null;
				if (that.notify != null)
					that.notify (null, x, y);
			}

			return false;
		}

		this.coordBoxX = eX;
		this.coordBoxY = eY;
		var bh = new CboxHandler(this);
		eX.maxLength=3;
		eY.maxLength=3;
		eX.style.width='2em';
		eY.style.width='2em';
		eX.addEventListener('change', bh.eventChange, false);
		eY.addEventListener('change', bh.eventChange, false);
	}

	this.selectBut = selectBut;
	this.bindToXYboxes = bindToXYboxes;
	this.coordBoxX = null;
	this.coordBoxY = null;
	this.id = id;
	this.dispName = dispName;
	this.prefixLen = id.length+1;
	this.notify = notify;
	this.selected = null;
	this.city = null;
	var m = '';
	for (var i=0; i<Cities.cities.length; i++){
		if (matTypeof(disable_list) == 'array' && disable_list[i])
			m += '<span class='+(bgclass?bgclass:"")+'><INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=submit DISABLED \></span>';
		else
			m += '<span class='+(bgclass?bgclass:"")+'><INPUT class="castleBut castleButNon" id="'+ id +'_'+ i +'" value="'+ (i+1) +'" type=submit \></span>';
	}

	if (dispName)
		m += ' &nbsp; <SPAN style="display:inline-block; width:85px; font-weight:bold;" id='+ id +'cname' +'></span>';
	span.innerHTML = m;
	var handler = new CcityButHandler(this);
	for (var i=0; i<Cities.cities.length; i++)
		ById (id+'_'+i).addEventListener('click', handler.clickedCityBut, false);
	if (selbut != null)
		this.selectBut(selbut);
}

function getCityBuildings (cityId){
	var ret = {};
	for (var k in uW.buildingcost) {
		ret[k.split("bdg")[1]] = {count:0, maxLevel:0};
	}

	var b = Seed.buildings['city'+cityId];
	for (var k in b) {
		if (b[k] && matTypeof(b[k])=="array"){
			if (ret[b[k][0]]) {
				ret[b[k][0]].count++;
				if (parseInt(b[k][1]) > ret[b[k][0]].maxLevel) {
					ret[b[k][0]].maxLevel = parseInt(b[k][1]);
				}
			}
		}
	}
	return ret;
}

function getCityBuilding (cityId, buildingId, unique){
	var b = Seed.buildings['city'+cityId];
	var ret = {count:0, maxLevel:0};
	for( var k in b){
		if(b[k] && b[k][0] == buildingId){
			++ret.count;
			if(parseInt(b[k][1]) > ret.maxLevel)
				ret.maxLevel = parseInt(b[k][1]);
			if (unique) return ret;
		}
	}
	return ret;
}

function getUniqueCityBuilding (cityId, buildingId){
	return getCityBuilding(cityId, buildingId, true);
}

function getItemImageURL (id) {
	var s = "";
	if (id == 999) {
		s = IMGURL+"dailyRewards/question_mark.jpg"
	} else {
		if (CM.MASTERS_TOKEN_LEVELS[id]) {
			s = IMGURL+"items/70/masters_token_bg.png"
		} else {
			if (CM.ItemController.isJewelId(id)) {
				var jewel = CM.ItemController.isJewelId(id);
				s = CM.ThronePanelView.getJewelIcon(jewel.quality, CM.ThroneController.jewelType(jewel));
			} else {
				if (CM.ItemController.isMysteryId(id)) {
					s = IMGURL+"items/70/30303.jpg"
				} else {
					if ((id >= 11001) && (id <= 11010)) {
						s = IMGURL+"items/70/bossBattleChest_victor.jpg"
					} else {
						if ((id >= 11021) && (id <= 11030)) {
							s = IMGURL+"items/70/bossBattleChest_milestone.jpg"
						} else {
							s = IMGURL+"items/70/" + id + ".jpg"
						}
					}
				}
			}
		}
	}
	return s
}

function getDefendStatus (x,y,div,disphide, notify, index, total, progressdiv) {
	if (progressdiv && ById(progressdiv)) ById(progressdiv).outerHTML = '<span id='+progressdiv+'>'+tx('Checking')+' '+(index+1)+' '+uW.g_js_strings.commonstr.of+' '+total+'</span>';
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.xcoord = x;
	params.ycoord = y;
	params.currentcityid = uW.currentcityid;
	params.use_champion = false;
	params.knight = 0;
	params.cityId = 0;
	for (var ui in uW.cm.UNIT_TYPES) {
		i = uW.cm.UNIT_TYPES[ui];
		params["u" + i] = 0;
	}
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/ifCityDefending.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok && rslt.ok=="true") {
				if (div) div.innerHTML = '<span class=boldMagenta>*&nbsp;'+tx('DEFENDING')+'&nbsp;*</span>';
			}
			else {
				if (div && disphide) div.innerHTML = '<span>'+tx('Hiding')+'</span>';
			}
			if (notify) notify(rslt,x,y,index);
		},
		onFailure: function () {
			if (notify) notify({ok:false},x,y,index);
		},
	});
}

function getAvailableKnights (cityId) {
	var knt = new Array();
	for (var k in Seed.knights['city'+cityId]){
		var knight = Seed.knights['city'+cityId][k];
		if (knight["knightStatus"] == 1 && Seed.leaders['city'+cityId]["resourcefulnessKnightId"] != knight["knightId"] && Seed.leaders['city'+cityId]["politicsKnightId"] != knight["knightId"] && Seed.leaders['city'+cityId]["combatKnightId"] != knight["knightId"] && Seed.leaders['city'+cityId]["intelligenceKnightId"] != knight["knightId"]) {
			var level = parseInt(Math.sqrt(parseInt(knight["experience"]) / 75)) + 1;
			var unpoints = level - parseInt(knight["skillPointsApplied"]);

			knt.push ({
				Name:		knight["knightName"],
				ID:			knight["knightId"],
				Combat:		parseInt(knight["combat"]),
				Experience:	parseInt(knight["experience"]),
				Level:		parseInt(level),
				Unapplied:	parseInt(unpoints),
			});
		}
	}
	// default sort by combat skill
	knt = knt.sort(function sort(a,b) {a = a['Combat'];b = b['Combat'];return a == b ? 0 : (a > b ? -1 : 1);});
	return knt;
}

function ClaimDailyReward () {
	if (Options.LoginReward && (Seed.loginReward.show_today || Seed.loginReward.show_hud)) {
		var h = Seed.loginReward.items || [];
		var	i = (~~(1 * Seed.loginReward.consec_days_logon) + 1) || 1;
		var q;
		if (i <= 5) { q = h[i - 1]; }
		else { q = h[5]; }

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = "LoginRewards";
		params.action = "claimReward";
		params.feedSent = 0;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				jQuery("#hudThirdContainer").remove();
				if (Seed.loginReward.show_today) CM.ModalManager.closeAll();
				uW.ksoItems[q].add();
				actionLog('Daily Reward Claimed - Day '+i+': '+uW.itemlist['i'+q].name,'GENERAL');
			},
		},true); // no retry
	}
}

function getFactionName(faction) {
	var prestige = "";
	var pt = parseIntNan(faction);
	switch(pt) {
		case 1: prestige = uW.g_js_strings.commonstr.druid; break;
		case 2: prestige = uW.g_js_strings.commonstr.fey; break;
		case 3: prestige = uW.g_js_strings.commonstr.briton; break;
		default: prestige = "";
	}
	return prestige;
}

/*******************   KOC Map interface ****************/

function CMapAjax () {
	this.normalize = normalize;
	this.LookupMap = LookupMap;
	this.generateBlockList = generateBlockList;

	function normalize (x) {
		if ( x >= 750) { x -= 750; }
		else if (x < 0) { x += 750; }
		return parseInt (x/5) * 5;
	}

	function LookupMap (blockString, notify) {
		if (MAP_DELAY_WATCH > Number(uW.unixtime())) {
			notify({"ok":false});
			return;//we're slowing down the requests so the server doesn't get bogged.
		};

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.blocks = blockString;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchMapTiles.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (!rslt.ok) {
					MAP_DELAY+=1000; // slow lookups by another second!?!
					if (GlobalOptions.ExtendedDebugMode) {
						logit('Map Error - '+JSON2.stringify(rslt));
					}
				}
				MAP_DELAY_WATCH = Number(uW.unixtime())+Number(Number(MAP_DELAY)/1000);
				notify(rslt);
			},
			onFailure: function () {
				if (GlobalOptions.ExtendedDebugMode) {
					logit('Map Ajax Fail');
				}
				notify({"ok":false});
			},
		});
	}

	function generateBlockList (X,Y,Radius) {
		var BlockList = [];

		var minX = normalize(X);
		var minY = normalize(Y);
		var maxX = normalize(X+(Radius*2)+1);
		var maxY = normalize(Y+(Radius*2)+1);

		if (minX<=maxX && minY<=maxY) { // no map boundary - use actual co-ords. (If map boundary you need block numbers in multiples of 5).
			minX = X;
			minY = Y;
			maxX = X+(Radius*2)+1;
			maxY = Y+(Radius*2)+1;
		}

		var width = parseInt(((Radius*2)+5)/5)*5;
		var Xwidth5 = parseInt(width/5);
		var Ywidth5 = parseInt(width/5);

		if (minX!=X) Xwidth5++; // extra block row if required
		if (minY!=Y) Ywidth5++; // extra block column if required

		for (var x=0; x < Xwidth5; x++){
			var xx = minX + (x*5);
			if (xx >= 750) { xx -= 750; }
			for (var y=0; y< Ywidth5; y++){
				var yy = minY + (y*5);
				if (yy >= 750) { yy -= 750; }
				BlockList.push ('bl_'+ xx +'_bt_'+ yy);
			}
		}
		return BlockList;
	}
}

function TileImage(tt,lv,pid,fac,faclvl,st) {
	var img = '';
	var imgtxt = '';
	if (tt<=50) { // wild
		if (tt==50 && st && st!=0) { // new alliance sub-types
			if (st==1) { // HQ
				img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'alliancehq/map_hq.png\');background-size:30px 30px;" title="'+tx('Alliance HQ')+'">&nbsp;</div>';
			}
		}
		else {
			if (lv>=7) {lv=7}
			else if (lv>=4) {lv=4}
			else {lv=1};
			imgtxt = wildImages[tt];
			img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/'+imgtxt+'_lvl'+lv+'.png\');background-size:30px 30px;" title="'+imgtxt+'">&nbsp;</div>';
		}
		return img;
	}
	if (tt==52) { // ruin (?)
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/ruins.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.ruin+'">&nbsp;</div>';
		return img;
	}
	if (tt==53) { // mist
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/city_mist.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.mists+'">&nbsp;</div>';
		return img;
	}
	if (tt==55) { // merc camp
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/mercenary_hideout.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.mercenaryHideout+'">&nbsp;</div>';
		return img;
	}
	if (tt==56) { // nomad camp
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/nomad_tile.png\');background-size:30px 30px;" title="'+uW.g_js_strings.nomad.camp+'">&nbsp;</div>';
		return img;
	}
	if (tt==57) { // megalith
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/runic_megalith_tile.png\');background-size:30px 30px;" title="'+uW.g_js_strings.koth.eventname+'">&nbsp;</div>';
		return img;
	}
	if (tt==54) { // dark forest
		if (lv>=11) {lv=11}
		else if (lv>=10) {lv=10}
		else if (lv>=7) {lv=7}
		else if (lv>=4) {lv=4}
		else {lv=1};
		img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/boss_lvl'+lv+'.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.darkForest+'">&nbsp;</div>';
		return img;
	}
	if (tt==51) { // city or barbarian camp!?!
		if (!pid || pid==0) {
			if (lv>=11) {
				img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/Barbarian_Camp_lvl11.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.barbariancamp+'">&nbsp;</div>';
				return img;
			}
			else {
				if (lv>=7) {lv=7}
				else if (lv>=4) {lv=4}
				else {lv=1};
				img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/barbarian_lvl'+lv+'.png\');background-size:30px 30px;" title="'+uW.g_js_strings.commonstr.barbariancamp+'">&nbsp;</div>';
				return img;
			}
		}
		else {
			if (lv>=11) {lv=11}
			else if (lv>=10) {lv=10}
			else if (lv>=7) {lv=7}
			else if (lv>=5) {lv=5}
			else if (lv>=3) {lv=3}
			else {lv=1};
			var title = uW.g_js_strings.commonstr.city;
			img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'buildings/castle_lvl'+lv+'_26.png\');background-size:30px 30px;" title="'+title+'">&nbsp;</div>';
			if (fac) {
				title = getFactionName(fac) + ' ('+uW.g_js_strings.commonstr.level+' '+faclvl+')';
				switch (fac) {
					case 1:	{ // druid
								var BackPos = '';
								if (lv>=7) { BackPos = '-188px 0px;'; }
								else if (lv>=4) { BackPos = '-93px 0px;'; }
								img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'map_castle01.png\');'+BackPos+'background-size:90px 30px;" title="'+title+'">&nbsp;</div>';
								break;
							}
					case 2:	{ // fey
								var BackPos = '01';
								if (lv>=7) { BackPos = '03'; }
								else if (lv>=4) { BackPos = '02'; }
								img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'fey%20cityMap'+BackPos+'.png\');background-size:30px 30px;" title="'+title+'">&nbsp;</div>';
								break;
							}
					case 3:	{ // briton
								var BackPos = '01';
								if (lv>=7) { BackPos = '03'; }
								else if (lv>=4) { BackPos = '02'; }
								img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'briton_cityMap'+BackPos+'.png\');background-size:30px 30px;" title="'+title+'">&nbsp;</div>';
								break;
							}
					default : { // ???? assume new faction, put fey image out until we know any better.
								var BackPos = '01';
								if (lv>=7) { BackPos = '03'; }
								else if (lv>=4) { BackPos = '02'; }
								img = '<div style="width:30px;height:30px;vertical-align:middle;background-image:url(\''+IMGURL+'fey%20cityMap'+BackPos+'.png\');background-size:30px 30px;" title="'+title+'">&nbsp;</div>';
								break;
							}
				}
			}
			return img;
		}
	}
}

function TroopImage(tt,style,suffix) {
	if (style==null) style = "width:20px;height:20px;vertical-align:middle;";
	if (suffix==null) suffix = "&nbsp;";
	if (tt < 50) { var TroopText = uW.unitcost['unt'+tt][0];}
	else { var TroopText = uW.fortcost['frt'+tt][0];}
	var img = '<img style="'+style+'" src="'+TroopImagePrefix+tt+TroopImageSuffix+'" title="'+TroopText+'">'+suffix;
	return img;
}

function TroopImageBig(tt) { return TroopImage(tt,"vertical-align:middle;"); }
function TroopImageBigHeader(tt) { return TroopImage(tt,"",""); }

function ResourceImage(path,title) {
	var img = '<img style="width:20px;height:20px;vertical-align:middle;" src="'+path+'" title="'+title+'">&nbsp;';
	return img;
}

function capitalize(value) {
	newValue = "";
	var pattern = " ";
	value = value.split(pattern);
	for(var i = 0; i < value.length; i++) {
		newValue += value[i].substring(0,1).toUpperCase() +
		value[i].substring(1,value[i].length);
		if (i < value.length-1) {newValue += " ";}
	}
	return newValue;
}

function BlankifZero(val) {
	if (val == 0) {return "";} else {return val;}
}

function createToolTip (title,elem,TempStatEffects) {
	var TempcText = "";
	if (!elem) return;
	if (title != "") { TempcText += "<b>"+title+"</b><br>&nbsp;<br>"; }

	var SortOrder = [];
	if (Options.MonitorOptions.AlternateSortOrder) { for (var z in AlternateSortOrder) SortOrder.push(AlternateSortOrder[z]); }
	else { for (var z in TempStatEffects) SortOrder.push(z); }

	for (var z in SortOrder) {
		var k = SortOrder[z];
		var HisContent = "";
		if (TempStatEffects[k] && (TempStatEffects[k] != 0) && uW.cm.thronestats["effects"][k]) HisContent = (Math.round(TempStatEffects[k]*100)/100) + '% ' + uW.g_js_strings.throneRoom["effectName_" + k];
		if (HisContent != "") { TempcText += HisContent + "<br>"; }
	}

	jQuery('#'+elem.id).children("span").remove();
	jQuery('#'+elem.id).append('<span class="trtip">'+TempcText+'</span>');
}

function UseDove (iid) {
    var params = uW.Object.clone(uW.g_ajaxparams);
    new MyAjaxRequest(uW.g_ajaxpath + "ajax/doveOut.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok) {
				var boostTime = 43200;
				Seed.player.truceExpireUnixTime = uW.unixtime() + boostTime;
				Seed.player.warStatus = 3;
				uW.cm.InventoryView.removeItemFromInventory(iid);
				uW.update_boosts()
			} else {
				uW.Modal.showAlert(uW.printLocalError(rslt.error_code, rslt.msg, rslt.feedback))
			}
		},
	},true); // noretry
}

function FormatDiplomacy (aid) {
	if (Seed.allianceDiplomacies == null)
		return ' ('+uW.g_js_strings.commonstr.neutral+')';
	if (Seed.allianceDiplomacies.friendly && Seed.allianceDiplomacies.friendly['a'+aid] != null)
		return ' <span style="color:#080;">('+uW.g_js_strings.commonstr.friendly+')</span>';
	if (Seed.allianceDiplomacies.hostile && Seed.allianceDiplomacies.hostile['a'+aid] != null)
		return ' <span style="color:#800;">('+uW.g_js_strings.commonstr.hostile+')</span>'
	if (aid == Seed.allianceDiplomacies.allianceId)
		return ' <span style="color:#088;">('+uW.g_js_strings.commonstr.yours+')</span>';
	return ' ('+uW.g_js_strings.commonstr.neutral+')';
};

function getDiplomacy (aid) {
	if (Seed.allianceDiplomacies == null)
		return uW.g_js_strings.commonstr.neutral;
	if (Seed.allianceDiplomacies.friendly && Seed.allianceDiplomacies.friendly['a'+aid] != null)
		return uW.g_js_strings.commonstr.friendly;
	if (Seed.allianceDiplomacies.hostile && Seed.allianceDiplomacies.hostile['a'+aid] != null)
		return uW.g_js_strings.commonstr.hostile;
	if (aid == Seed.allianceDiplomacies.allianceId)
		return uW.g_js_strings.commonstr.yours;
	return uW.g_js_strings.commonstr.neutral;
};

function DiplomacyColours (aid) {
	if (Seed.allianceDiplomacies == null)
		return "";
	if (Seed.allianceDiplomacies.friendly && Seed.allianceDiplomacies.friendly['a'+aid] != null)
		return "color:#080;";
	if (Seed.allianceDiplomacies.hostile && Seed.allianceDiplomacies.hostile['a'+aid] != null)
		return "color:#800;font-weight:bold;";
	if (aid == Seed.allianceDiplomacies.allianceId)
		return "color:#088;";
	return "";
};

function fetchPlayerCourt (uid, notify) {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.pid = uid;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/viewCourt.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) { notify(rslt); },
		onFailure: function () { notify({errorMsg: 'AJAX error'});},
	});
}

function getWallInfo(cityId, objOut) {
	objOut.wallSpaceUsed = 0;
	objOut.fieldSpaceUsed = 0;
	objOut.wallSpaceQueued = 0;
	objOut.fieldSpaceQueued = 0;
	objOut.wallLevel = 0;
	objOut.wallSpace = 0;
	objOut.fieldSpace = 0;
	objOut.slotsBusy = 0;
	var b = Seed.buildings["city" + cityId];
	if (!b || b.pos1 == null) return;
	objOut.wallLevel = parseInt(b.pos1[1]);
	var spots = 0;
	for (var i = 1; i < (objOut.wallLevel + 1); i++) { spots += (i * 1500); }
	if (uW.seed.cityData.city[cityId].isPrestigeCity) {
		if (uW.seed.cityData.city[cityId].prestigeInfo.blessings.indexOf(307) != -1) spots = parseInt(spots * 1.15);
	}
	objOut.wallSpace = spots;
	objOut.fieldSpace = spots;
	var fort = Seed.fortifications["city" + cityId];
	for (var k in fort) {
		var id = parseInt(k.substr(4));
		if (id<60 || id==63) { objOut.wallSpaceUsed += parseInt(uW.fortstats["unt" + id][5]) * parseInt(fort[k]); }
		else { objOut.fieldSpaceUsed += parseInt(uW.fortstats["unt" + id][5]) * parseInt(fort[k]); }
	}
	var q = Seed.queue_fort["city" + cityId];
	objOut.slotsBusy = q.length;
	if (q!=null && q.length > 0 ){
		for (var i=0; i<q.length; i++){
			if (q[i][0]<60 || q[i][0]==63) { objOut.wallSpaceQueued += parseInt(uW.fortstats["unt"+ q[i][0]][5]) * parseInt(q[i][1]); }
			else { objOut.fieldSpaceQueued += parseInt(uW.fortstats["unt"+ q[i][0]][5]) * parseInt(q[i][1]); }
		}
	}
}

function getResourceProduction(cityId) {
	var ret = [0, 0, 0, 0, 0];
	var now = unixTime();
	var search = 'type==10 || type==11';
	var wilds = [0, 0, 0, 0, 0];
	var w = Seed.wilderness["city"+cityId];
	for (var k in w) {
		var type = parseInt(w[k].tileType);
		if (type == 10 || type == 11)
			wilds[1] += parseInt(w[k].tileLevel);
		else
			wilds[type / 10] += parseInt(w[k].tileLevel);
	}
	knight = 0;
	var s = Seed.knights["city" + cityId];
	if (s) {
		s = s["knt"+Seed.leaders["city"+cityId].resourcefulnessKnightId];
		if (s) {
			var knight = parseInt(s.resourcefulness);
			if (s.resourcefulnessBoostExpireUnixtime > now)
				knight *= 1.25;
		}
	}
	var workerFactor = 1;
	var c = parseInt(Seed.citystats["city"+cityId]["pop"][0]); // Current population
	var w = parseInt(Seed.citystats["city"+cityId]["pop"][3]); // Labor force
	if (w > c)
		workerFactor = c / w;
	for (var i = 1; i < 5; i++) {
		var items = 0;
		if (parseInt(Seed.playerEffects["r" + i + "BstExp"]) > now) {
			items = 0.25;
		}
		var tech = Seed.tech["tch" + i];
		ret[i] = parseInt((Seed.resources["city" + cityId]["rec" + i][2] * (1 + tech / 10 + knight / 100 + items + 0.05 * wilds[i]) * workerFactor + 100));
	}
	return ret;
}

function equippedthronestats(stat_id) {
	var current_slot = Seed.throne.activeSlot;
	var equip_items = Seed.throne.slotEquip[current_slot];
	var total = 0;
	for (var k = 0; k < equip_items.length; k++) {
		var item_id = equip_items[k];
		var y = uW.kocThroneItems[item_id];
		for (var O in y["effects"]) {
			var i = +(O.split("slot")[1]);
			var id = y["effects"]["slot" + i]["id"];
			if (id == stat_id) {
				tier = parseInt(y["effects"]["slot" + i]["tier"]);
				level = y["level"];
				p = CM.thronestats.tiers[id][tier];
				while (!p && (tier > 0)) { tier--; p = CM.thronestats.tiers[id][tier]; }
				if (!p) continue; // can't find stats for tier
				var base = +p.base;
				var growth = +p.growth;
				if (y["effects"]["slot"+i].fromJewel && (level > CM.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality])) {
					level = CM.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality]
				}
				if (i <= y["quality"]) {
					var Percent = Number(base + ((level * level + level) * growth * 0.5));
					total += parseIntNan(Percent);
				}
			}
		}
	}
	return total;
}

function getTrainTime (n, p, cid) {
	if (p < 1) {
		return 0
	}
	var Buildings = getCityBuildings(cid);
	var faux = 0;
	var uc = uW.unitcost["unt"+n];
	if (matTypeof(uc[8]) == 'object'){
		for (var k in uc[8]){
			var b = Buildings[k.substr(1)];
			if (b.maxLevel < uc[8][k][1]){
				faux = 1;
				break;
			}
		}
	}
	if (matTypeof(uc[9]) == 'object'){
		for (var k in uc[9]){
			if (parseInt(Seed.tech['tch'+k.substr(1)]) < uc[9][k][1]){
				faux = 1;
				break;
			}
		}
	}

	if (faux) return 0;

	var h =  + (uW.unitcost["unt" + n][7]) * p,
	c,
	f = {},
	g = Seed.buildings["city" + cid],
	b = {},
	e = Seed.knights["city" + cid],
	l,
	q = Seed.leaders["city" + cid];
	f.barracks = 0;
	f.workshop = 0;
	f.stable = 0;
	f.tech = 0;
	f.knight = 0;
	f.ultimate = 0;
	var prestigeType = Seed.cityData.city[cid].prestigeInfo.prestigeType;
	jQuery.each(g, function (v, u) {
		u.id =  + (u[0]);
		u.level =  + (u[1]);
		var rare = (uW.cm.BarracksUnitsTypeMap.isUnitType(parseInt(n), "rare"));
		var pt = ((parseInt(n) == 13 && prestigeType==1) || (parseInt(n) == 14 && prestigeType==2) || (parseInt(n) == 15 && prestigeType==3));
		var t = (parseInt(n) == 13 || parseInt(n) == 14 || parseInt(n) == 15);
		u.isPrestige = (parseInt(u[2]) >= 100 && parseInt(u[2]) <= 105);
		if ((u.id === 13 || u.id === 22 || u.id === 24 || u.id === 26) && u.level > 0) {
			if ((t && pt && u.isPrestige && !rare) || (!t && !u.isPrestige && !rare)) {
				f.barracks += (u.level + 9)
			}
		}
		if (u.id === 16 && u.level > 0) {
			if ( + (n) >= 9 &&  + (n) < 13) {
				f.workshop = u.level
			}
		}
		if (u.id === 17 && u.level > f.stable) {
			if ( + (n) >= 7 &&  + (n) < 13) {
				f.stable = u.level
			}
		}
	});
	c = f.barracks / 10;
	h = Math.max(1, Math.ceil(h / c));
	c = 1;
	if (e) {
		l = e["knt" + q.combatKnightId];
		if (l) {
			f.knight = ( + (l.combatBoostExpireUnixtime) - uW.unixtime() > 0) ? (l.combat * 1.25) : l.combat
		} else {
			f.knight = 0
		}
	}
	if (Seed.tech) {
		f.tech = Seed.tech.tch5
	}
	f.ultimate =  /*f.workshop + f.stable +*/ f.tech; // workshop and stable doesn't make sense here!
	c = c * (1 + (0.1 * f.ultimate) + (0.005 * f.knight));
	var d = uW.cm.ThroneController.effectBonus(77);
	c = c * (1 + (d / 100));
	if (uW.cm.WorldSettings.isOn("GUARDIAN_MARCH_EFFECT")) {
		var j = getStoneTrainingSpeedBonus(cid);
		c = c * (1 + j)
	}
	h = Math.max(1, Math.ceil(h / c));
	if (uW.cm.PrestigeModel.isPrestige(cid)) {
		var a = uW.cm.PrestigeModel.getPrestigeLevel(cid);
		if (a > 0) {
			var m = uW.cm.WorldSettings.getSetting("ASCENSION_BARRACKS_BOOST"),
			k = JSON.parse(m),
			o = k.values[a - 1][1],
			i = parseFloat(o);
			h = Math.ceil(h * i)
		}
	}
	var r = uW.cm.BlessingSystemModel.isBlessingActive(uW.cm.BlessingSystemModel.getBlessing().DEATH_FROM_AFAR, cid);
	if (n == 6 && r) {
		h = Math.ceil(h - (h * uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().DEATH_FROM_AFAR, cid, {})))
	}
	h = Math.ceil(h - (h * uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().EXPEDITED_SENTENCING, cid, {
					traintime : true,
					unitid : n
				})));
	h = Math.ceil(h - (h * uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().TO_THE_FRONT_LINES, cid, {
					unitid : n
				})));
	h = Math.ceil(h - (h * uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().PRIORITIZED_CONSTRUCTION, cid, {
					unittype : n
				})));
	if (uW.cm.VipModel.isActive()) {
		var s = uW.cm.VipModel.getBoostValue("benefitTraining");
		h = Math.ceil(h - (h * (s / 100)))
	}
	return h
}

function getStoneTrainingSpeedBonus (cityId) {
	var c = { 0 : 0, 1 : 5, 2 : 5, 3 : 10, 4 : 10, 5 : 15, 6 : 15, 7 : 20, 8 : 25, 9 : 35, 10 : 70, 11 : 130, 12 : 250 };
	var idx = Cities.byID[cityId].idx;
	var stonelevel = (Seed.guardian[idx].cityGuardianLevels["stone"]?Seed.guardian[idx].cityGuardianLevels["stone"]:0);
	var x = c[stonelevel] / 100;
	var v = (Seed.guardian[idx].guardianCount==4);
	var A = Seed.guardian[idx].type == "stone";
	var z = 0;
	var w = (CM.ThroneController.getBoundedEffect(106) / 100);
	var r = 1+(uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().EMPOWERED_STONE, cityId)/10);
	var y = 0;
	if (A && v) {
		z = 1.5;
		y = w;
	}
	if (A && !v) {
		z = 1;
		y = w;
	}
	if (!A && v) {
		z = 0.5;
		r = 1;
	}
	if (!A && !v) {
		z = 1;
		r = 1;
	}
	var u = (x * r * z) + y;
	return u
}

function getCityTroops(unitId,cityId,countmarching) {
	var NumTroops = 0;
	NumTroops = parseIntNan(Seed.units['city' + cityId]['unt' + unitId]);
	if (SelectiveDefending) { NumTroops += parseIntNan(Seed.defunits['city' + cityId]['unt' + unitId]); }

	if (countmarching) {
		var marching = getMarchInfo(cityId);
		NumTroops += marching.marchUnits[unitId];
	}
	return NumTroops;
}

function getMarchInfo (cityId) {
  var ret = {};

  ret.marchUnits = {};
  ret.returnUnits = {};
  ret.resources = [];
  for (var ui in uW.cm.UNIT_TYPES){
    var i = uW.cm.UNIT_TYPES[ui];
    ret.marchUnits[i] = 0;
    ret.returnUnits[i] = 0;
  }
  for (var i=0; i<5; i++){
    ret.resources[i] = 0;
  }

  for (var k in Seed.queue_atkp["city"+cityId]){   // each march
      march = Seed.queue_atkp["city"+cityId][k];
      if (typeof (march) == 'object'){
			if (march.marchType == 5) continue; // don't count troops currently being reassigned!!!
			if (march.marchType == 9 && (march.marchStatus == 3 || march.marchStatus == 4 || march.marchStatus == 10)) continue; // don't count troops in stopped or resting raids..

			for (var ui in uW.cm.UNIT_TYPES){
				var i = uW.cm.UNIT_TYPES[ui];
				ret.marchUnits[i] += parseIntNan (march['unit'+i+'Count']);
				ret.returnUnits[i] += parseIntNan (march['unit'+i+'Return']);
            }
            for (var ii=1; ii<5; ii++){
				ret.resources[ii] += parseInt (march['resource'+ ii]);
            }
			ret.resources[0] += parseInt (march['gold']);
		}
	  }
  return ret;
}

function DeleteLastMessage() {
	var params = uW.Object.clone(uW.g_ajaxparams);
	params.requestType = 'GET_MESSAGE_HEADERS_FOR_USER_INBOX';
	params.boxType = 'outbox';
	params.pageNo = 1;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok) {
				if (rslt.mostRecentMessageId) {
					var params2 = uW.Object.clone(uW.g_ajaxparams);
					params2.requestType = 'ACTION_ON_MESSAGES';
					params2.boxType = 'outbox';
					params2.selectedAction = 'delete';
					params2.selectedMessageIds = rslt.mostRecentMessageId;
					new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
						method: "post",
						parameters: params2,
						onSuccess: function (rslt2) {},
					},true);
				}
			}
		},
	},true);
};

function DrawLevelIcons() {
	var maptileRe = /modal_maptile.([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+)/;
	var mapwindow=ById('mapwindow');
	if(!mapwindow) return;
	var mapinfo=ById('mapinfodone');
	if(mapinfo) {return;};

	var ss=document.evaluate(".//a[contains(@class,'slot')]",mapwindow,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
	var mapinfodone=false;
	for(var s=0; s<ss.snapshotLength; s++) {
		var a=ss.snapshotItem(s);
		var onclick=a.getAttribute('id');
		var owner='';
		if(onclick) {
			var tileinfo = uW.g_mapObject.model.getTileActions(onclick)["tileClick"];
			if(tileinfo) {
				var might = parseInt(tileinfo.might);
				var alliance = parseIntNan(tileinfo.allianceId);
				var dip = getDiplomacy(alliance);
				owner = tileinfo.username;
			}
		}
		var sp=a.getElementsByTagName('span');
		if(sp.length==0) continue;

		if (!mapinfodone) { sp[0].id='mapinfodone'; mapinfodone=true; }
		spancol='#cc0';

		if (alliance == 'null' && tileinfo.type=="city") spancol='#33CCFF';
		if (dip == 'hostile' && tileinfo.type=="city") spancol='#FF0000';
		if (tileinfo.type!="city" &&  tileinfo.tileuserid!="null") spancol='#FF9900';
		if (tileinfo.type!="city" &&  tileinfo.tileuserid=="null") spancol='#CC0033';

		if (Options.MapShowExtra) {
			if (tileinfo.username!="null")
				sp[0].outerHTML = sp[0].outerHTML +'<div style="color:'+spancol+';font-size:11px;text-shadow: 2px 2px 2px #000;" align="left">&nbsp;&nbsp;'+owner+'</div><div style="color:'+spancol+';font-size:10px;text-shadow: 2px 2px 2px #000;" align="left">&nbsp;&nbsp;Might:'+addCommas(might)+'</div>';
		}
		if (Options.MapShowLevel && (parseIntNan(tileinfo.level) != 0)) {
			sp[0].outerHTML = sp[0].outerHTML+'<div style="color:'+spancol+';text-shadow: 2px 2px 2px #000;" align="left">&nbsp;&nbsp;'+tileinfo.level+'&nbsp;&nbsp;</div>';
		}
	}
}

function CardMight (throne_item) {
	var JewelBonus = 1;
	if (throne_item.jewel && throne_item.jewel.valid) {
		switch (throne_item.jewel.quality) {
			case 1: JewelBonus = 1.05; break;
			case 2: JewelBonus = 1.1; break;
			case 3: JewelBonus = 1.15; break;
			case 4: JewelBonus = 1.25; break;
			case 5: JewelBonus = 1.33; break;
			default: break;
		}
	}

	var F = CM.thronestats.mightByQuality || {},
	H = CM.thronestats.mightByLevel || {},
	G = F[throne_item.quality] && F[throne_item.quality].Might ? +F[throne_item.quality].Might : 0,
	E = H[throne_item.level] && H[throne_item.level].Might ? +H[throne_item.level].Might : 0;
	return Math.round((CM.ThroneController.mightOfItemQuality(throne_item) + H[throne_item.level].Might) * JewelBonus);
}

function CardQuality (throne_item) {
	var b = throne_item.quality,
	a;
	if (throne_item.unique > 0) { a = uW.g_js_strings.throneRoom.unique; }
	else { a = strQuality (b); }
	return a
};

function strQuality (b) {
	var a;
	switch (b) {
		case 0: a = uW.g_js_strings.throneRoom.simple; break;
		case 1:	a = uW.g_js_strings.throneRoom.common; break;
		case 2:	a = uW.g_js_strings.throneRoom.uncommon; break;
		case 3: a = uW.g_js_strings.throneRoom.rare; break;
		case 4:	a = uW.g_js_strings.throneRoom.epic; break;
		case 5:	a = uW.g_js_strings.throneRoom.wondrous; break;
		case 6: a = uW.g_js_strings.throneRoom.miraculous; break;
		default: a = uW.g_js_strings.throneRoom.simple; break;
	}
	return a
};

function SwitchGuardian (cityId,type) {
	var cIndex = Cities.byID[cityId].idx;
	if (type == Seed.guardian[cIndex].type) { return; }

	var level = Seed.guardian[cIndex].cityGuardianLevels[type];
	level = level ? level : 0;
	if (level == 0) { return; }

	var params = uW.Object.clone(uW.g_ajaxparams);
	params.ctrl = "Guardian";
	params.action = "summon";
	params.cityId = cityId;
	params.type = type;

	new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (rslt) {
			if (rslt.ok) {
				var g = CM.guardianModalModel.gObj();
				g.summonGuardian = uWCloneInto({
					summonFinishTime: parseInt(rslt.summonFinishTime),
					level: rslt.summonGuardian.cl0,
					type: rslt.summonGuardian.type,
					upgrading: false
				});
				uW.seed.guardian[cIndex].type = type;
				uW.seed.guardian[cIndex].level = rslt.summonGuardian.cl0;
				var GType = 0;
				switch(type) {
					case "wood":  GType=50;break;
					case "ore":   GType=51;break;
					case "food":  GType=52;break;
					case "stone": GType=53;break;
				}
				uW.seed.buildings["city"+ cityId].pos500[0] = GType;
				var time = parseInt(rslt.summonFinishTime) - unixTime();
				setTimeout(function(){
					uW.seed.buildings["city"+ cityId].pos500[0] = GType;
					uW.seed.guardian[cIndex].type = type;
					uW.seed.guardian[cIndex].level = rslt.summonGuardian.cl0;
				},(time*1000));
				guardianFailures = 0;
			}
			else { // retry?
				guardianFailures++;
				actionLog(Cities.byID[cityId].name+": Guardian change failed. Error code: " + rslt.error_code,'TOWER');
				// try again in 2 seconds
				if (guardianFailures <=3) {
					setTimeout( function () {SwitchGuardian (cityId,type)}, 2000);
				}
				else {
					guardianFailures = 0;
				}
			}
		},
		onFailure: function () {
			actionLog(Cities.byID[cityId].name+": Guardian change server error",'TOWER');
			guardianFailures = 0;
		}
	},true) // noretry
};

function SwitchThroneRoom (preset) {
	var NewPreset = preset;
	if (NewPreset == Seed.throne.activeSlot) { return; }

	var params = uW.Object.clone(uW.g_ajaxparams);
	params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
	params.action = 'setPreset';
	params.presetId = NewPreset;
	new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch53.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		loading: true,
		onSuccess: function (rslt) {
			if(rslt.ok){
				if (ById('throneStatList')) { button = '#throneInventoryPreset' + NewPreset; }
				else { button = '<li id="throneInventoryPreset' + NewPreset + '" class="active">'+NewPreset+'</li>'; }
				CM.ThroneView.clickActivePreset(button);
				presetFailures = 0;
			}
			else { // retry?
				presetFailures++;
				actionLog("Preset change failed. Error code: " + rslt.error_code,'TOWER');
				// try again in 2 seconds
				if (presetFailures <=3) {
					setTimeout( function () {SwitchThroneRoom (preset)}, 2000);
				}
				else {
					presetFailures = 0;
				}
			}
		},
		onFailure: function () {
			actionLog("Preset change server error",'TOWER');
			presetFailures = 0;
		},
	},true); // noretry
};

//******************** Auto Update ***************************//

var AutoUpdater = {
    id: 999999,
	SourceForgeURL:'svn.code.sf.net/p/koc-battle-console/code/trunk/KoCPowerBotPlus.user.js',
	GreasyForkURL:'greasyfork.org/scripts/11839-koc-power-bot-plus/code/KoC%20Power%20Bot%20Plus.user.js',
	MarkBranscombeURL:'markbranscombe.com/barbarossa/PowerBotPlus/KoC_Power_Bot_Plus.user.js',
	MoshimoURL:'moshimo.eu/Koc_Dev/koc/PowerBotPlus/KoC_Power_Bot_Plus.user.js',
	name: 'KoC Power Bot Plus',
	homepage: 'https://www.facebook.com/PowerBotPlus',
    version: Version,
	secure: true,
    call: function(secure,response) {logit("Checking for "+tx(this.name)+" Update!"+(secure ? ' (SSL)' : ' (plain)'));
		this.secure = secure;
		var CheckURL = this.SourceForgeURL;
		if (GlobalOptions.UpdateLocation == 1) {CheckURL = this.GreasyForkURL;}
		if (GlobalOptions.UpdateLocation == 2) {CheckURL = this.MarkBranscombeURL;}
		if (GlobalOptions.UpdateLocation == 3) {CheckURL = this.MoshimoURL;}
		try {
			GM_xmlhttpRequest({
				method: 'GET',
				url: 'http'+(secure ? 's' : '')+'://'+CheckURL,
				onload: function(xpr) {AutoUpdater.compare(xpr,response);},
				onerror: function(xpr) {if (secure) {AutoUpdater.call(false,response);} else {AutoUpdater.compare({responseText:""},response);}}
			});
		} catch (e){ logerr(e);	}
    },

    compareVersion: function(r_version, l_version) {
            var r_parts = r_version.split(''),
            l_parts = l_version.split(''),
            r_len = r_parts.length,
            l_len = l_parts.length,
            r = l = 0;
            for(var i = 0, len = (r_len > l_len ? r_len : l_len); i < len && r == l; ++i) {
                r = +(parseIntNan(r_parts[i]||0));
                l = +(parseIntNan(l_parts[i]||0));
            }
            return (r !== l) ? r > l : false;
    },

    compare: function(xpr,response) {
        this.xversion=/\/\/\s*@version\s+(.+)\s*\n/i.exec(xpr.responseText);
        if (this.xversion) this.xversion = this.xversion[1];
        else {
			if (response) {
				uW.Modal.showAlert('<div align="center">'+tx('Unable to check for updates to')+' '+tx(this.name)+'.<br>'+tx('Please change the update options or visit the')+'<br><a href="'+this.homepage+'" target="_blank">'+tx('script homepage')+'</a></div>');
			}
			logit("Unable to check for updates :(");
			return;
		}
        this.xrelnotes=/\/\/\s*@releasenotes\s+(.+)\s*\n/i.exec(xpr.responseText);
        if (this.xrelnotes) this.xrelnotes = this.xrelnotes[1];
        var updated = this.compareVersion(this.xversion, this.version);
        if (updated) {logit('New Version Available!');
 			var body = '<BR><DIV align=center><FONT size=3><B>'+tx('New version')+' '+this.xversion+' '+tx('is available!')+'</b></font></div><BR>';
			if (this.xrelnotes)
				body+='<BR><div align="center" style="border:0;width:470px;height:120px;max-height:120px;overflow:auto"><b>'+tx('New Features!')+'</b><p>'+this.xrelnotes+'</p></div><BR>';
 			body+='<BR><DIV align=center><a class="gemButtonv2 green" id="doBotUpdate">Update</a></div>';
 			this.ShowUpdate(body);
        }
        else
        {
			logit("No updates available :(");
			if (response) {
				uW.Modal.showAlert('<div align="center">'+tx('No updates available for')+' '+tx(this.name)+' '+tx('at this time.')+'</div>');
			}
        }
    },

    check: function() {
    	var now = unixTime();
    	var lastCheck = 0;
    	if (GM_getValue('updated_'+this.id, 0)) lastCheck = parseInt(GM_getValue('updated_'+this.id, 0));
		if (now > (lastCheck + 60*60*12)) this.call(true,false);
    },

	ShowUpdate: function (body) {
		var now = unixTime();
		CM.ModalManager.addMedium({
			title: tx(this.name),
			body: body,
			closeNow: false,
			close: function () {
				setTimeout (function (){GM_setValue('updated_'+AutoUpdater.id, now);}, 0);
				CM.ModalManager.closeAll();
			},
			"class": "Warning",
			curtain: false,
			width: 500,
			height: 700,
			left: 140,
			top: 140
		});
		ById('doBotUpdate').addEventListener ('click', this.doUpdate, false);
	},

	doUpdate: function () {
		CM.ModalManager.closeAll();
		CM.ModalManager.close();
		var now = unixTime();
		GM_setValue('updated_'+AutoUpdater.id, now);
		var DownloadURL = AutoUpdater.SourceForgeURL;
		if (GlobalOptions.UpdateLocation == 1) {DownloadURL = AutoUpdater.GreasyForkURL;}
		if (GlobalOptions.UpdateLocation == 2) {DownloadURL = AutoUpdater.MarkBranscombeURL;}
		if (GlobalOptions.UpdateLocation == 3) {DownloadURL = AutoUpdater.MoshimoURL;}
		location.href = 'http'+(AutoUpdater.secure ? 's' : '')+'://'+DownloadURL;
	},

};

/************************************ Raid Manager *************************************/

function ToggleCityRaids (cityId,RaidAction,notify) {

	if (!RaidManager.CityHasRaids(cityId)) {
		if (notify) notify({'ok':true});
		return;
	}

	var params = uW.Object.clone(uW.g_ajaxparams);
	params.pf = 0;
	params.ctrl = 'BotManager';
	params.action = RaidAction; // stopAll or resumeAll
	params.settings = {cityId : cityId};

	new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		loading: true,
		onSuccess: function(rslt){
			if (rslt.ok) {
				if (RaidAction != 'getMarches') {
					ToggleCityRaids(cityId,'getMarches',notify); // retrieve new march statuses
					return;
				}
				else {
					setTimeout(uW.update_seed_ajax, 1000); // update_seed with the new march statuses (?)
				}
			}
			else {
				if (rslt.msg == "The system is busy, please try again later") {
					setTimeout (ToggleCityRaids, 2000, cityId, RaidAction, notify);
					return;
				}
				else {
					actionLog(Cities.byID[cityId].name+": "+rslt.msg,'RAIDS');
				}
			}
			if (notify) notify(rslt);
		},
		onFailure: function () {
			actionLog(Cities.byID[cityId].name+": Raid toggle server error",'RAIDS');
			if (notify) notify({'ok':false});
		},
	},true);
};

var RaidManager = {
	LookupTimer : null,
	stopping:false,
	resuming:false,
	deleting:false,
	stopprogress:0,
	stopcount:0,
	activecount:0,
	count:0,

	init : function () {
		var t = RaidManager;

		if (Options.RaidToggle) AddSubTabLink('Raids',Tabs.Options.toggleAutoRaidState, 'RaidsToggleTab');
		SetToggleButtonState('Raids',Options.RaidRunning,'Raids');

		if(Options.RaidButtons) {
			AddMainTabLink('RAIDS: Stop', 'pbraidtab', t.StopAllRaids);
			AddMainTabLink('Resume', 'pbraidtabRes', t.ResumeAllRaids);
			if (Options.RaidDeleteButton) AddMainTabLink('Delete', 'pbraidtabDel', t.DeleteAllRaids);
			ById('pbraidtabRes').style.marginLeft = '0px';
			if (Options.RaidDeleteButton) ById('pbraidtabDel').style.marginLeft = '0px';
			ById('pbraidtab').title = tx('Click to Stop Active Raids');
			ById('pbraidtabRes').title = tx('Click to Resume Stopped Raids');
			if (Options.RaidDeleteButton) ById('pbraidtabDel').title = tx('Click to Delete Stopped Raids');
		}

		t.LookupTimer = setTimeout(t.LookupRaids,2500);
	},

	CityHasRaids : function (cityId) {
		var t = RaidManager;
		var city_atkp = Seed.queue_atkp['city'+cityId]
		for (var e in city_atkp){
			MarchType = city_atkp[e]['marchType'];
			if (MarchType == 9) return true;
		}
		return false;
	},

	LookupRaids : function () {
		var t = RaidManager;
		clearTimeout(t.LookupTimer);

		t.activecount=0;
		t.stopcount=0;
		for (c=0; c< Seed.cities.length;c++) {
			var cityId = Seed.cities[c][0];
			var city_atkp = Seed.queue_atkp['city'+cityId]
			for (b in city_atkp){
				destinationUnixTime = city_atkp[b]['destinationUnixTime'];
				MarchStatus = city_atkp[b]['marchStatus'];
				MarchType = city_atkp[b]['marchType'];
				botMarchStatus = city_atkp[b]['botMarchStatus'];
				if (MarchType == 9 && (MarchStatus == 3 || MarchStatus==10)) t.stopcount++;
				else if (MarchType == 9) t.activecount++;
			}
		}

		if (!Options.RaidButtons) return;
		if (t.resuming == false && t.stopping == false && t.deleting == false && t.activecount != 0)
			ById('pbraidtab').innerHTML = '<span style="color: #ff6">RAIDS: Stop ('+ t.activecount + ')</span>'
		else if (t.resuming == false && t.stopping == false && t.deleting == false)
			ById('pbraidtab').innerHTML = '<span style="color: #CCC">RAIDS: Stop ('+ t.activecount + ')</span>'
		if (t.resuming == false && t.resuming == false && t.deleting == false && t.stopcount !=0)
			ById('pbraidtabRes').innerHTML = '<span style="color: #ff6">Resume ('+ t.stopcount + ')</span>'
		else if (t.resuming == false && t.stopping == false && t.deleting == false)
			ById('pbraidtabRes').innerHTML = '<span style="color: #CCC">Resume ('+ t.stopcount + ')</span>'
		if (Options.RaidDeleteButton) {
			if (t.resuming == false && t.stopping == false && t.deleting == false && t.stopcount !=0)
				ById('pbraidtabDel').innerHTML = '<span style="color: #ff6">Delete ('+ t.stopcount + ')</span>'
			else if (t.resuming == false && t.stopping == false && t.deleting == false)
				ById('pbraidtabDel').innerHTML = '<span style="color: #CCC">Delete ('+ t.stopcount + ')</span>'
		}

		t.LookupTimer = setTimeout(t.LookupRaids,2500);
	},

	StopAllRaids : function (){
		var t = RaidManager;
		if (t.stopping == true || t.resuming == true || t.deleting == true) return;
		if (t.activecount == 0) return;
		t.stopping = true;
		var now = unixTime();
		Options.RaidLastReset = now;
		saveOptions();
		for (i=0;i<Seed.cities.length;i++){
			setTimeout(t.DoAllStop, (i*1500),i);
		}
	},

	ResumeAllRaids : function (){
		var t = RaidManager;
		if (t.stopping == true || t.resuming == true || t.deleting == true) return;
		if (t.stopcount == 0) return;
		t.resuming = true;
		var now = unixTime();
		Options.RaidLastReset = now;
		saveOptions();
		for (i=0;i<Seed.cities.length;i++){
			setTimeout(t.DoAllResume, (i*1500),i);
		}
	},

	DeleteAllRaids : function (){
		var t = RaidManager;
		if (t.stopping == true || t.resuming == true || t.deleting == true) return;
		if (t.stopcount == 0) return;
		t.deleting = true;
		var now = unixTime();
		Options.RaidLastReset = now;
		saveOptions();
		count=0;
		t.count = t.stopcount;
		for (var d=0; d< Seed.cities.length;d++) {
			var cityId = Seed.cities[d][0];
			var city_atkp = Seed.queue_atkp['city'+cityId]
			for (var e in city_atkp){
				destinationUnixTime = city_atkp[e]['destinationUnixTime'];
				MarchId = city_atkp[e]['marchId'];
				MarchStatus = city_atkp[e]['marchStatus'];
				MarchType = city_atkp[e]['marchType'];
				botMarchStatus = city_atkp[e]['botMarchStatus'];
				if (MarchType == 9 && botMarchStatus == 3 && MarchStatus == 10) {
					count++;
					setTimeout(t.DoAllDelete, (count*1250), MarchId,d,count);
				}
			}
		}
    },

	DoAllStop: function(i) {
		var t = RaidManager;
		ToggleCityRaids(Seed.cities[i][0],'stopAll',function (rslt) {
			if (rslt.ok) { actionLog(Seed.cities[i][1]+': Stopping Raids','RAIDS'); }
			t.stopprogress = t.stopprogress + (100/Seed.cities.length);
			t.updatebotbutton('Stopping: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtab');
			if (t.stopprogress.toFixed(0) == 100) {
				t.stopprogress = 0;
				setTimeout(function(){t.updatebotbutton('RAIDS: Stop ('+ t.activecount + ')', 'pbraidtab');t.stopping = false;}, 5000);
			}
		});
	},

	DoAllResume: function(i) {
		var t = RaidManager;
		ToggleCityRaids(Seed.cities[i][0],'resumeAll',function (rslt) {
			if (rslt.ok) { actionLog(Seed.cities[i][1]+': Resuming Raids','RAIDS');}
			t.stopprogress = t.stopprogress + (100/Seed.cities.length);
			t.updatebotbutton('Resuming: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtab');
			if (t.stopprogress.toFixed(0) == 100) {
				t.stopprogress = 0;
				setTimeout(function(){t.updatebotbutton('RAIDS: Stop ('+ t.activecount + ')', 'pbraidtab');t.resuming = false;}, 5000);
			}
		});
	},

	DoAllDelete : function (marchId,city,count){
		var t = RaidManager;
		var cityId = Seed.cities[city][0];
		var params = uW.Object.clone(uW.g_ajaxparams);
        params.pf = 0;
        params.ctrl = 'BotManager';
        params.action = 'deleteMarch';
        params.marchId = marchId;
        params.settings = {};
		params.settings = {cityId : cityId};

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function(rslt){
				if (rslt) {
					for (u in Seed.queue_atkp['city' + cityId]){
						if (Seed.queue_atkp['city' + cityId][u]['marchId'] == marchId){
							delete Seed.queue_atkp['city' + cityId][u];
							if (Object.keys(Seed.queue_atkp['city' + cityId]).length == 0) {
								Seed.queue_atkp['city' + cityId] = [];
							}
							break;
						}
					}

					uW.cityinfo_army();
					setTimeout(uW.update_seed_ajax, 250);
				}
			},
		});

		t.stopprogress = count * (100/t.count);
		actionLog(Seed.cities[city][1]+': Deleting Raids','RAIDS');
		t.updatebotbutton('Deleting: '+ t.stopprogress.toFixed(0) + '%', 'pbraidtab');
		if (t.stopprogress.toFixed(0) == 100) {
			t.stopprogress = 0;
			setTimeout(function(){t.updatebotbutton('RAIDS: Stop ('+ t.activecount + ')', 'pbraidtab');t.deleting  = false;}, (5000));
		}
	},

	updatebotbutton : function (text, id) {
		var but=document.getElementById(id);
		if (but) {
			but.innerHTML = '<span style="color: #ff6">'+text+'</span>';
		}
	},
}

/************************************ Dashboard Control ********************************/

var Dashboard = {
	order : [],
	DashWidth : 490,
	GeneralInterval : 1,
	DefaultDashboard : {"Overview":{Display:true, Sequence:0},"Sacrifices":{Display:true, Sequence:10},"Troops":{Display:true, Sequence:20},"Reinforcements":{Display:true, Sequence:30},"Fortifications":{Display:true, Sequence:40},"Outgoing Attacks":{Display:true, Sequence:50},"Incoming Attacks":{Display:true, Sequence:60}},
	OverviewShow : true,
	SacrificeShow : true,
	ReinforceShow : true,
	TroopShow : true,
	FortificationShow : true,
	AttackShow : true,
	CityAttackShow : true,
	Curr : -1,
	Castles : null,
	ResizeFrame : false,
	serverwait : false,
	ExpandMarshall : false,
	ExpandChampion : false,
	ExpandDefPreset : false,
	CurrentCityId : 0,
	StillComing : false,
	CityStillComing : false,
	CityIncoming : false,
	CityOutgoing : false,
	SacSettings : null,
	SacSpeed : null,
	SacSpeedBuff : null,
	DarkRitual : null,
	ChannelledSuffering : null,
	TotalTroops : null,
	TotalSanctuaryTroops : null,
	QuickSacString : "",
	DefOptionsString : "",
	NextPresetNumber : 0,
	InitPresetNumber : 0,
	marchchamp : null,
	citychamp : null,
	oldchamp : null,
	allownewsacs : false,
	Reins : [],
	WallDefences : [],
	FieldDefences : [],
	StoreArray : {},
	ThroneDelay : 0,
	GuardDelay : 0,
	ForceTries : 0,
	AttackedCity : null,
	CurrGuardian : null,
	Loaded : false,
	Buildings : {},
	BoostItemList : [261, 262, 280, 271, 272, 281, 282, 283],
	tBoostItemList : [290, 291, 292, 287, 288, 289],
	Options : {
		OverviewState       	: true,
		SacrificeState      	: false,
		ReinforceState      	: false,
		FortificationState  	: false,
		AttackState         	: false,
		CityAttackState     	: false,
		DefaultSacrifice    	: true,
		DefaultSacrificeMin 	: 1,
		DefaultSacrificeSec 	: 0,
		QuickSacrifice      	: true,
		SacrificeLimit      	: 1000000,
		DefaultDefenceNum   	: 200000,
		DefAddTroopShow     	: true,
		DefPresetShow       	: true,
		DefPresets          	: {},
		UpperDefendButton   	: false,
		LowerDefendButton   	: true,
		TRPresets        		: {},
		TRPresetsSelected  		: {},
		TRPresetsCycle  		: false,
		TRPresetsCycleMins 		: 1,
		TRPresetsLastChecked    : 0,
		TRPresetChange			: true,
		TRPresetByName      	: false,
		OverrideDashboard   	: {},
		CurrentCity         	: -1,
		RefreshSeed         	: false,
		ReplaceDefendingTroops	: {0:false,1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		GraphicalChampDisplay	: false,
		ExpandSanctuary			: true,
		SetDefendersFirst		: false,
	},

	OptionsInit : function () {
		var t = Dashboard;
		if (!Options.DashboardOptions) {
			Options.DashboardOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.DashboardOptions.hasOwnProperty(y)) {
					Options.DashboardOptions[y] = t.Options[y];
				}
			}
		}
	},

	init : function () {
		var t = Dashboard;

		HTMLRegister['DASH'] = {};

		t.order = [];
		for (var p in t.DefaultDashboard) {
			var NewObj = {};
			if (Options.DashboardOptions.OverrideDashboard[p]) {
				NewObj.Display = Options.DashboardOptions.OverrideDashboard[p].Display;
				NewObj.Sequence = Options.DashboardOptions.OverrideDashboard[p].Sequence;
			}
			else {
				NewObj.Display = t.DefaultDashboard[p].Display;
				NewObj.Sequence = t.DefaultDashboard[p].Sequence;
			}
			NewObj["name"] = p;
			t.order.push(NewObj);
		}
		t.order.sort(function(a, b){ return a.Sequence-b.Sequence });

		m = '<div><table width="100%"><tr><td class=xtab align="right"><b>'+uW.g_js_strings.commonstr.city+' : </b></td><td class=xtab><span id=btCastlesContainer></span></td><td class=xtab align="right"><span id="btCityAlert">&nbsp;</span></td></tr>';
		m += '<tr><td class=xtab colspan="2"><span style="display:inline-block;" id=btItems>&nbsp;</span>&nbsp;<span style="display:inline-block;height:21px;vertical-align:bottom;" id=btDashAlarmOff>&nbsp;</span></td><td class=xtab align="right"><a id=btRefreshSeed class="inlineButton btButton blue14"><span>'+tx('Refresh')+'</span></a>&nbsp;<span id=btAutoSpan class="divHide"><a id=btAutoRefresh class="inlineButton btButton blue14"><span style="width:30px;display:inline-block;text-align:center;">'+tx('Auto')+'</span></a></span></td></tr></table></div>';

		for (var p in t.order) {
			if (t.order[p].name == 'Overview') {
				m += '<div id=btStatusHeader><a id=btStatusLink class=divLink ><div class="divHeader" align="right">'+tx('OVERVIEW')+'&nbsp;<img id=btStatusArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btStatus align=center class="divHide"><TABLE width="98%"><tr><td class=xtab align="center" id=btStatusCell></td></tr>';
				m += '</table></div></div>';
				t.OverviewShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Sacrifices') {
				m += '<div id=btSacrificeHeader><a id=btSacrificeLink class=divLink ><div class="divHeader" align="right">'+tx('SACRIFICES')+'&nbsp;<img id=btSacrificeArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btSacrifice align=center class="divHide"><TABLE width="98%"><tr><td class=xtab align=center id=btSacrificeCell></td></tr><tr><td class=xtab align=center>';
				m += '<div id=btNewSacrificeCell align="center" class="divHide">&nbsp;</div></td></tr>';
				m += '</table></div></div>';
				t.SacrificeShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Troops') {
				m += '<div id=btTroopHeader><a id=btTroopLink class=divLink ><div class="divHeader" align="right">'+tx('TROOPS')+'&nbsp;<img id=btTroopArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btTroop align=center class=divHide><TABLE width="98%">';
				if (Options.DashboardOptions.SetDefendersFirst) {
					m += '<tr><td class=xtab align=center><div id=btTroopAddCell align="center">&nbsp;</div></td></tr>';
					m += '<tr><td class=xtabBR align=center id=btTroopCell></td></tr>';
				}
				else {
					m += '<tr><td class=xtabBR align=center id=btTroopCell></td></tr>';
					m += '<tr><td class=xtab align=center><div id=btTroopAddCell align="center">&nbsp;</div></td></tr>';
				}
				m += '</table></div></div>';
				t.TroopShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Reinforcements') {
				m += '<div id=btReinforceHeader><a id=btReinforceLink class=divLink ><div class="divHeader" align="right">'+tx('REINFORCEMENTS')+'&nbsp;<img id=btReinforceArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btReinforce align=center class=divHide><TABLE width="98%"><tr><td class=xtabBR align=center id=btReinforceCell></td></tr>';
				m += '</table></div></div>';
				t.ReinforceShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Fortifications') {
				m += '<div id=btWallDefenceHeader><a id=btWallDefenceLink class=divLink ><div class="divHeader" align="right">'+tx('FORTIFICATIONS')+'&nbsp;<img id=btWallDefenceArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btWallDefence align=center class=divHide><TABLE width="98%"><tr><td class=xtabBR align=center id=btWallDefenceCell></td></tr>';
				m += '</table></div></div>';
				t.FortificationShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Outgoing Attacks') {
				m += '<div id=btCityAttackHeader><a id=btCityAttackLink class=divLink ><div class="divHeader" align="right">'+tx('OUTGOING ATTACKS')+'&nbsp;<img id=btCityAttackArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btCityAttack align=center class=divHide><TABLE width="98%"><tr><td class=xtabBR align=center id=btCityAttackCell></td></tr>';
				m += '</table></div></div>';
				t.CityAttackShow = t.order[p].Display;
			}

			if (t.order[p].name == 'Incoming Attacks') {
				m += '<div id=btAttackHeader><a id=btAttackLink class=divLink ><div class="divHeader" align="right">'+tx('INCOMING ATTACKS')+'&nbsp;<img id=btAttackArrow height="10" src="'+RightArrow+'"></div></a>';
				m += '<div id=btAttack align=center class=divHide><TABLE width="98%"><tr><td class=xtabBR align=center id=btAttackCell></td></tr>';
				m += '</table></div></div><br>';
				t.AttackShow = t.order[p].Display;
			}
		}

		popDash = new CPopup('btDash', Options.btDashPos.x, Options.btDashPos.y, t.DashWidth, 100, GlobalOptions.btFloatingDashboard, Dashboard.close);

		if (!GlobalOptions.btFloatingDashboard) {
			popDash.BASE_ZINDEX = 40; // below widemap
			elem = ById('btDash_outer');
			elem.style.left = '0px';
			elem.style.top = '0px';
			ById('btDashboard').appendChild(elem);
		}

		popDash.getMainDiv().innerHTML = m;
		popDash.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('PowerBot+ Dashboard')+'</B></DIV>';
		ResetFrameSize('btDash',100,t.DashWidth);

		if (t.Curr < 0) { t.Curr = Cities.byID[uW.currentcityid].idx; }

		t.Castles = new CdispCityPicker ('btCastles', ById('btCastlesContainer'), true, null, t.Curr,null,'castleButBack');

		for (var i=0; i<Cities.numCities; i++) {
			ById('btCastles_'+i).addEventListener('mouseover',function (){CityResourceHint(this,this.id.substring(10));},false);
			ById('btCastles_'+i).addEventListener('mouseout',function (){CityResourceHintOff(this);},false);
		}

		ById('btCastlesContainer').addEventListener ('click', function(){t.SetCurrentCity (t.Castles.city.id);} , false);
		ById('btStatusLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btStatus");Options.DashboardOptions.OverviewState = !(Options.DashboardOptions.OverviewState);saveOptions();}, false);
		ById('btSacrificeLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btSacrifice");Options.DashboardOptions.SacrificeState = !(Options.DashboardOptions.SacrificeState);saveOptions();}, false);
		ById('btTroopLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btTroop");Options.DashboardOptions.TroopState = !(Options.DashboardOptions.TroopState);saveOptions();}, false);
		ById('btWallDefenceLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btWallDefence");Options.DashboardOptions.FortificationState = !(Options.DashboardOptions.FortificationState);saveOptions();}, false);
		ById('btReinforceLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btReinforce");Options.DashboardOptions.ReinforceState = !(Options.DashboardOptions.ReinforceState);saveOptions();}, false);
		ById('btAttackLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btAttack");Options.DashboardOptions.AttackState = !(Options.DashboardOptions.AttackState);saveOptions();}, false);
		ById('btCityAttackLink').addEventListener ('click', function () {ToggleDivDisplay("btDash",100,t.DashWidth,"btCityAttack");Options.DashboardOptions.CityAttackState = !(Options.DashboardOptions.CityAttackState);saveOptions();}, false);

		if (Options.DashboardOptions.OverviewState) ToggleDivDisplay("btDash",100,t.DashWidth,"btStatus");
		if (Options.DashboardOptions.SacrificeState) ToggleDivDisplay("btDash",100,t.DashWidth,"btSacrifice");
		if (Options.DashboardOptions.TroopState) ToggleDivDisplay("btDash",100,t.DashWidth,"btTroop");
		if (Options.DashboardOptions.ReinforceState) ToggleDivDisplay("btDash",100,t.DashWidth,"btReinforce");
		if (Options.DashboardOptions.FortificationState) ToggleDivDisplay("btDash",100,t.DashWidth,"btWallDefence");
		if (Options.DashboardOptions.AttackState) ToggleDivDisplay("btDash",100,t.DashWidth,"btAttack");
		if (Options.DashboardOptions.CityAttackState) ToggleDivDisplay("btDash",100,t.DashWidth,"btCityAttack");

		ById('btRefreshSeed').addEventListener ('click', function() {setTimeout(function() { t.SetCurrentCity (t.Castles.city.id); RefreshSeed();},250);}, false);
		ById('btAutoRefresh').addEventListener ('click', function() {t.ToggleAutoRefresh();}, false);
		if (Options.DashboardOptions.RefreshSeed) {
			jQuery('#btRefreshSeed').addClass("disabled");
			jQuery('#btAutoRefresh').addClass("red14");
			jQuery('#btAutoRefresh').removeClass("blue14");
			ById('btAutoRefresh').innerHTML = '<span style="width:30px;display:inline-block;text-align:center;">Off</span>';
		}
		if (trusted) jQuery('#btAutoSpan').removeClass("divHide");

        t.SetCurrentCity(Seed.cities[t.Curr][0],true);

		popDash.show(true);
		ResetFrameSize('btDash',100,t.DashWidth);
		saveOptions();

		t.Loaded = true; // allow everysecond to update
	},

	show : function (city) {
		var t = Dashboard;
		if (!popDash) {
			t.init();
		}
		else {
			t.Castles.selectBut(city.idx);
		}
	},

	close : function () {
		Options.DashboardOptions.CurrentCity = -1;
		Dashboard.Curr = Options.DashboardOptions.CurrentCity;
		if (GlobalOptions.btFloatingDashboard) {
			Options.btDashPos = popDash.getLocation();
		}
		else {
			document.body.appendChild(popDash.div);
		}
		popDash.destroy();
		popDash = null;
		Options.btDashboard = false;
		WideScreen.setDashboard(false);
		saveOptions();
		saveGlobalOptions();
	},

	SetCurrentCity : function (cityId,leaveModal) {
		var t = Dashboard;

		t.serverwait = false;
		t.ExpandMarshall = false;
		t.ExpandChampion = false;

		t.CurrentCityId = cityId;
		t.Curr = Cities.byID[cityId].idx;
		Options.DashboardOptions.CurrentCity = t.Curr;
		saveOptions();

		if (!leaveModal) {
			uW.Modal.hideModal(); // don't hide modal on init.
			if (jQuery('#ahqbutton').hasClass('sel')) { uW.changeview_city(); }
		}

		if (uW.currentcityid != cityId) {
			if (!SelectCity(t.Curr+1)) { setTimeout(t.SetCurrentCity,1000,cityId,leaveModal); return false; }
		}

		t.Buildings = getCityBuildings(cityId);

		// refresh sacrifice info

		var b = t.Buildings[25];
		if (b.count > 0) {
			t.SacSettings = (b.count <= 1) ? uW.cm.WorldSettings.getSettingAsObject("ASCENSION_SACRIFICE_ONE_ALTER_BUFF") : uW.cm.WorldSettings.getSettingAsObject("ASCENSION_SACRIFICE_TWO_ALTER_BUFF");
			t.SacSettings = t.SacSettings[b.maxLevel];

			t.DarkRitual = uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().DARK_RITUAL);
			t.SacSpeedBuff = uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().CHANNELED_SUFFERING);
			t.ChannelledSuffering = (t.SacSpeedBuff != 1);

			t.SacAllowed = t.DarkRitual ? 2 : 1;
			t.SacSpeed = uW.cm.WorldSettings.getSettingAsNumber("ASCENSION_SACRIFICE_TROOPS_PER_SEC");

			var l = b.maxLevel;
			var o = [];
			var	i = uW.cm.WorldSettings.getSettingAsObject("ASCENSION_SACRIFICE_ALTAR_LEVEL_UNLOCKS");
			for (var x=1;x<=l;x++) {
				oo = i[x].troops.split(",");
				for (var y in oo) {
					o.push(oo[y]); // contains array of troop types this city is allowed to sacrifice :)
				}
			}

			m = '<TABLE cellSpacing=0 width=100% height=0%>';
			m += '<tr><TD width="120" class=xtabBR><span class=xtab>';
			m += '<SELECT class="btSelector" id="btRitualTroops" onchange="btSelectTroopType(this);"><option value="0">-- '+uW.g_js_strings.openCastle.trooptype+' --</option>';
			t.QuickSacString = "";
			for (var y in uW.unitcost) {
				var TroopAllowed = (o.indexOf(y.substr(3)) >= 0);
				var DefendingTroops = 0;
				if (SelectiveDefending) { DefendingTroops = parseIntNan(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+y.substr(3)]); }
				var tot = parseIntNan(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+y.substr(3)])+DefendingTroops;
				if ((tot > 0) && TroopAllowed) {
					var TTStyle = 'width:20px;height:20px;vertical-align:middle;';
					if (DefendingTroops != 0) { m +='<option style="font-weight:bold;" value="'+y.substr(3)+'">'+uW.unitcost[y][0]+'</option>'; TTStyle+="border:1px solid red;"; }
					else { m +='<option value="'+y.substr(3)+'">'+uW.unitcost[y][0]+'</option>'; TTStyle+="border:1px solid transparent;"; }
					t.QuickSacString = t.QuickSacString + '<a class="TextLink" onclick="btQuickSacrifice('+y.substr(3)+');">'+TroopImage(y.substr(3),TTStyle)+'</a>';
				}
			}
			m +='</select></span></td>';
			m +='<td class=xtab><INPUT class="btInput" id="btRitualAmount" type=text size=7 maxlength=7 value="" onkeyup="btSetRitualLength(this)"><span id="btTotalTroops"></span></td><td align=right class=xtab><span id="btMaxTroops"></span></td>';
			m +='<td width="80" class=xtab><INPUT class="btInput" style="width: 30px;text-align:right;" id="btRitualMinutes" type=text maxlength=4 value="" onkeyup="btSetRitualLength(this)">&nbsp;m&nbsp;';
			m +='<INPUT class="btInput" style="width: 15px;text-align:right;" id="btRitualSeconds" type=text maxlength=2 value="" onkeyup="btSetRitualLength(this)">&nbsp;s&nbsp;</td>';
			m +='<td width="90" align=right class=xtab><a id="btStartRitualButton" class="inlineButton btButton blue14" onclick="btStartRitual()"><span style="width:65px;display:inline-block;text-align:center;" align="center">'+uW.g_js_strings.sacrifice_popup.starttraining+'</span></a></td></tr>';
			m += '<tr><td class=xtab colspan="5"><div class="ErrText" align="center" id=btSacErr>&nbsp;</div></td></tr>';
			m += '</table>';
			ById('btNewSacrificeCell').innerHTML = m;
		}

		// refresh troop add defenders cell

		if (SelectiveDefending) {
			t.DefOptionsString = "";
			m = '<TABLE cellSpacing=0 width=100% height=0%><tr><TD colspan=3 class=xtabHD>'+tx('Assign Defenders')+'</td><TD width="100" align=right class=xtabHD><a id="btSelectDefendButton" class="inlineButton btButton blue14" onclick="cm.CastleController.openSelectDefendingTroops();"><span style="width:85px;display:inline-block;text-align:center;" align="center">'+uW.g_js_strings.openCastle.selecttroops+'</span></a></td></tr>';
			m +='<tr id=btDefAddTroopRow><TD width="120" class=xtabBR><span class=xtab>';
			m +='<SELECT class="btSelector" id="btDefendTroops" onchange="btSelectDefTroopType(this);"><option value="0">-- '+uW.g_js_strings.openCastle.trooptype+' --</option>';
			for (var y in uW.unitcost) {
				var tot = parseIntNan(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+y.substr(3)]);
				if ((tot > 0)) {
					m +='<option value="'+y.substr(3)+'">'+uW.unitcost[y][0]+'</option>';
					t.DefOptionsString = t.DefOptionsString + y.substr(3);
				}
			}
			m +='</select></span></td>';
			m +='<td width="200" class=xtab><INPUT class="btInput" id="btDefendAmount" type=text size=13 maxlength=11 value=""><span id="btTotalDefTroops"></span></td>';
			m +='<td align=right class=xtab><span id="btMaxDefTroops"></span></td>';
			m +='<td width="100" align=right class=xtab><a id="btAddDefendButton" class="inlineButton btButton blue14" onclick="btAddDefenders()"><span style="width:85px;display:inline-block;text-align:center;" align="center">'+tx('Add')+'</span></a></td></tr>';
			m +='<tr id=btDefPresetRow><TD colspan=4 class=xtab><TABLE cellSpacing=0 width=100% height=0%><tr><td class=xtab>';
			m +='<SELECT class="btSelector" style="width:190px;" id="btDefendPreset" onchange="btSelectDefPreset(this);"><option value="0">-- '+tx('Select Preset')+' --</option>';
			for (var y in Options.DashboardOptions.DefPresets) {
				m +='<option value="'+y+'">'+Options.DashboardOptions.DefPresets[y][0]+'</option>';
			}
			t.NextPresetNumber = parseIntNan(y) + 1;

			m +='</select></td>';
			m +='<td align=left class=xtab width=200><a id="btNewDefPreset" class="inlineButton btButton brown8" onclick="btNewDefPreset()"><span>'+tx('New')+'</span></a>&nbsp;<a id="btChgDefPreset" class="inlineButton btButton brown8 disabled" onclick="btChgDefPreset()"><span>'+tx('Chg')+'</span></a></td>';
			m +='<td align=right class=xtab style="padding-right:0px;"><a id="btAddPresetButton" class="inlineButton btButton blue14" onclick="btSetPresetDefenders(false)"><span style="width:15px;display:inline-block;text-align:center;" align="center">+</span></a>&nbsp;<a id="btReplacePresetButton" class="inlineButton btButton blue14" onclick="btSetPresetDefenders(true)"><span style="width:85px;display:inline-block;text-align:center;" align="center">'+tx('Replace')+'</span></a></td></tr></table>';
			if (t.ExpandDefPreset) m += '<div id=DefEditPresetRow >';
			else m += '<div id=DefEditPresetRow class=divHide >';
			m +='<TABLE cellSpacing=0 width=100% height=0%><tr><TD colspan=2 class=xtabHD style="font-size:2px;">&nbsp;</td></tr><tr><td class=xtab style="padding-top:5px;">'+tx('Preset Name')+':&nbsp;<INPUT class="btInput" id="btDefPresetName" size=20 style="width: 185px" type=text value=""/></td>';
			m +='<td align=right class=xtab style="padding-right:0px;"><a id="btSetCurrentPreset" class="inlineButton btButton brown8" onclick="btSetCurrentPreset()"><span>'+tx('Set Current')+'</span></a>&nbsp;<a id="btSaveDefPreset" class="inlineButton btButton brown8" onclick="btSaveDefPreset()"><span>'+tx('Save')+'</span></a></td></tr>';
			m +='<tr><td colspan=2 class=xtabBR style="padding-right:0px;padding-left:20px;">';
			for (var ui in uW.cm.UNIT_TYPES){
				i = uW.cm.UNIT_TYPES[ui];
				m += '<span class=xtab>'+TroopImage(i)+'<INPUT class="btInput" id="btPresetTroop'+i+'" type=text size=13 maxlength=11 value=""></span> ';
			}
			m +='</td></tr><tr><TD colspan=2 class=xtabHD align=right style="padding-right:0px;"><a id="btDelDefPreset" class="inlineButton btButton brown8 disabled" onclick="btDelDefPreset()"><span>'+uW.g_js_strings.commonstr.deletetx+'</span></a>&nbsp;<a id="btCancelDefPreset" class="inlineButton btButton brown8" onclick="btCancelDefPreset()"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr></table>';
			m +='</div></td></tr>';
			m += '<tr><td class=xtab colspan="4"><div style="opacity:0.6;" align="center" id=btTroopMsg>&nbsp;</div></td></tr></table>';

			ById('btTroopAddCell').innerHTML = m;

			if (t.InitPresetNumber != 0) {
				ById('btDefendPreset').value = t.InitPresetNumber;
				t.SelectDefPreset(ById('btDefendPreset'));
				t.InitPresetNumber = 0;
			}
		}
		else {
			jQuery('#btTroopAddCell').addClass("divHide");
		}
		t.PaintCityInfo(cityId);
	},

	PaintCityInfo : function (cityId) {
		var t = Dashboard;

		if (!popDash) return;

		t.Curr = Cities.byID[cityId].idx;
		var CityTag = '<div class="divHide">'+cityId+'</div>';

		// header items

		t.ResizeFrame = false;

		var Mists = Seed.items.i10021;
		var Doves = Seed.items.i901;
		var Refuges = Seed.items.i911;
		var Orders = Seed.items.i912;
		var now = unixTime();
		var TruceDuration = 0;
		if (Seed.player.truceExpireUnixTime != undefined)
			TruceDuration = Seed.player.truceExpireUnixTime - now;
		var CannotDove = ((TruceDuration > 0) && (Seed.player.warStatus != 1));

		var items = '<table style="padding-left:10px;" cellspacing=0 cellpadding=0><tr>';
		if (Mists) {
			items += '<td class=xtab><a onClick="cm.ItemController.usePotionOfMist(\'10021\')"><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+MistImage+'" title="'+uW.itemlist.i10021.name+' ('+Mists+')"></a></td>';
		}
		else {
			items += '<td class=xtab><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+MistImage+'" title="'+uW.itemlist.i10021.name+' (0)"></td>';
		}
		if (Seed.playerEffects.fogExpire > now) {
			items += '<td style="width:80px;" class=xtab><span style="color:#080;"><b>'+uW.timestr(Seed.playerEffects.fogExpire-now)+'</b></span></td>';
		}
		if (Doves && !CannotDove) {
			items += '<td class=xtab><a onClick="btDoveOfPeace(\'901\')"><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+DoveImage+'" title="'+uW.itemlist.i901.name+' ('+Doves+')"></a></td>';
		}
		else {
			if (!Doves) Doves=0;
			items += '<td class=xtab><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+DoveImage+'" title="'+uW.itemlist.i901.name+' ('+Doves+')"></td>';
		}
		if (TruceDuration > 0) {
			if (Seed.player.warStatus != 3) {
				items += '<td style="width:80px;" class=xtab><span style="color:#f00;"><b>'+tx('BROKEN!')+'</b></span></td>';
			}
			else {
				var ts = "color:#080";
				if (TruceDuration < 3600) {ts = "color:#f00"};
				items += '<td style="width:80px;" class=xtab><span style="'+ts+';"><b>'+uW.timestr(Seed.player.truceExpireUnixTime-now)+'</b></span></td>';
			}
		}
		if (Refuges) {
			items += '<td class=xtab><a onClick="cm.InventoryView.openPortalOfRefugeModal(\'911\')"><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+RefugeImage+'" title="'+uW.itemlist.i911.name+' ('+Refuges+')"></a></td>';
		}
		else {
			items += '<td class=xtab><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+RefugeImage+'" title="'+uW.itemlist.i911.name+' (0)"></td>';
		}
		if (Orders) {
			items += '<td class=xtab><a onClick="cm.InventoryView.openPortalOfOrderModal(\'912\')"><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+OrderImage+'" title="'+uW.itemlist.i912.name+' ('+Orders+')"></a></td>';
		}
		else {
			items += '<td class=xtab><img height=24 style="opacity:0.8;vertical-align:text-top;" src="'+OrderImage+'" title="'+uW.itemlist.i912.name+' (0)"></td>';
		}

		items += '</tr></table>'
		if (CheckForHTMLChange('DASH','btItems',items)) {
			t.ResizeFrame = true;
		}

		// overview

		t.Buildings = getCityBuildings(cityId); // refresh buildings info each loop
		var Status = '';

		var ascended = getAscensionValues(t.CurrentCityId);
		var cityExpTime = ascended.prestigeBuffExpire;
		var prestigeexp = '';
		if ((!isNaN(cityExpTime)) && (cityExpTime +(3600*24) >= unixTime())) {
			if (cityExpTime < unixTime()) {	prestigeexp = '<span style="color:#f00"><b>&nbsp;'+tx('Expired!')+'</b></span>'; }
			else { prestigeexp = '<span style="color:#080"><b>&nbsp;'+uW.timestr(cityExpTime-unixTime())+' '+tx('Remaining')+'</b></span>'; }
		}

		if (!ascended.isPrestigeCity) { CityFaction = tx('Not ascended');}
		else { CityFaction = getFactionName(ascended.prestigeType) + ' ('+uW.g_js_strings.commonstr.level+' '+ascended.prestigeLevel+')'; }

		DefState = parseInt(Seed.citystats["city" + cityId].gate);
		if (DefState) DefButton = '<a id=btCityStatus class="inlineButton btButton red20"><span style="width:150px"><center>'+tx('Troops are Defending!')+'</center></span></a>';
		else DefButton = '<a id=btCityStatus class="inlineButton btButton green20"><span style="width:150px"><center>'+tx('Troops are Hiding!')+'</center></span></a>';

		ArcaneAura = '';
		if (Seed.allianceHQ && Seed.allianceHQ.arcana && Seed.allianceHQ.buildings[3] && Seed.allianceHQ.buildings[3].buildingLevel && Seed.allianceHQ.buildings[3].buildingLevel!=0) {
			var HQDist = parseIntNan(distance(Seed.cities[t.Curr][2], Seed.cities[t.Curr][3], Seed.allianceHQ.hq_xcoord, Seed.allianceHQ.hq_ycoord));
			var AuraDist = parseIntNan(Seed.allianceHQ.arcana[Seed.allianceHQ.buildings[3].buildingLevel].distance);
			if (HQDist<=AuraDist) { ArcaneAura = '<span class=boldGreen>'+tx('HQ Dist')+': '+HQDist+'</span>'; }
			else { ArcaneAura = '<span class=boldRed>'+tx('HQ Dist')+': '+HQDist+'</span>'; }
		}	
		
		Status += '<table cellSpacing=0 width="100%">';
		Status += '<tr><td class=xtab width=70>'+uW.g_js_strings.commonstr.nametx+'</a></td><td class=xtab><b>'+Seed.cities[t.Curr][1]+'</b></td><td class=xtab rowspan=2 align=right><span class='+((Options.DashboardOptions.UpperDefendButton==false)?'divHide':'')+'>'+DefButton+'</span></td></tr>';
		Status += '<tr><td class=xtab>'+tx('Location')+'</a></td><td class=xtab><b>'+uW.provincenames['p'+Seed.cities[t.Curr][4]]+'&nbsp;'+coordLink(Seed.cities[t.Curr][2],Seed.cities[t.Curr][3])+'</b>&nbsp;'+ArcaneAura+'</td></tr>';
		Status += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.faction+'</a></td><td class=xtab><b>'+CityFaction+'</b></td><td class=xtab id=prestigeexpcell>&nbsp;</td></tr>';

		Embassy = '<span class=xtab style="color:#f00">'+tx('No Embassy!')+'</span>';
		var emb = t.Buildings[8];
		if (emb.count > 0){
			var availSlots = emb.maxLevel;
			for (var k in Seed.queue_atkinc){
				if ((Seed.queue_atkinc[k].toCityId == cityId) && (Seed.queue_atkinc[k].marchStatus == 2) && (Seed.queue_atkinc[k].fromCityId != cityId) && (Cities.byID[Seed.queue_atkinc[k].fromCityId]==null)) {
					--availSlots;
				}
			}
			Embassy = availSlots +' '+uW.g_js_strings.commonstr.of+' '+ emb.maxLevel +' '+tx('slots available');
		}
		Status += '<tr><td class=xtab><a onClick="btShowEmbassy('+t.Curr+')">'+uW.buildingcost.bdg8[0]+'</a></td><td class=xtab colspan=2><b>'+Embassy+'</b></span></b></td></tr>';

		var hall = t.Buildings[7];

		Marshall = '<span class=xtab style="color:#f00">'+tx('No Marshall!')+'</span>';
		Combat = 0;
		var s = Seed.knights["city" + cityId];
		if (s) {
			s = s["knt" + Seed.leaders["city" + cityId].combatKnightId];
			if (s){
				Combat = s.combat;
				if (s.combatBoostExpireUnixtime > unixTime()) {	Combat *= 1.25;	}
				Marshall = s.knightName+' (Atk:'+Combat+')';
				if (!t.ExpandMarshall && (hall.count >= 1)) {
					Marshall += '&nbsp;&nbsp;<a id="btChangeMarshall" class="inlineButton btButton brown8" onclick="btChangeMarshall()"><span>'+tx('Change')+'</span></a>';
					Gauntlets = Seed.items.i221;
					if (!(s.combatBoostExpireUnixtime > unixTime()) && Gauntlets ) {
						Marshall += '&nbsp;<a id="btBoostMarshall" class="inlineButton btButton brown8" onclick="btBoostMarshall()" title="'+uW.itemlist.i221.name+' ('+Seed.items.i221+')"><span>'+uW.g_js_strings.commonstr.boost+'</span></a>';
					}
					else {
						if (s.combatBoostExpireUnixtime > unixTime()) {
							Marshall += '&nbsp;<span style="color:#080">&nbsp;'+tx('Boosted for')+' '+uW.timestr(s.combatBoostExpireUnixtime-unixTime())+'</span>';
						}
					}
				}
			}
			else {
				t.ExpandMarshall = true;
			}
		}
		else {
			t.ExpandMarshall = false; // no knights ffs!
		}

		if (hall.count < 1) {t.ExpandMarshall = false;} // no fricken knights hall!

		if (t.ExpandMarshall) Marshall += '<div>';
		else Marshall += '<div class=divHide >';
		Marshall +='<SELECT class="btSelector" id="btKnightList"><option value="0">'+uW.g_js_strings.modal_attack.dchooseknightd+'</option>';
		for (var y in Seed.knights["city" + cityId]) {
			s = Seed.knights["city" + cityId][y];
			if ((parseInt(s.knightStatus) == 1) && (s.knightId != parseInt(Seed.leaders["city" + cityId].resourcefulnessKnightId)) && (s.knightId != parseInt(Seed.leaders["city" + cityId].intelligenceKnightId)) && (s.knightId != parseInt(Seed.leaders["city" + cityId].combatKnightId)) && (s.knightId != parseInt(Seed.leaders["city" + cityId].politicsKnightId))) {
				Combat = s.combat;
				if (s.combatBoostExpireUnixtime > unixTime()) {	Combat *= 1.25;	}
				Marshall +='<option value="'+s.knightId+'">'+s.knightName+' ('+uW.g_js_strings.commonstr.atk+':'+Combat+')</option>';
			}
		}
		Marshall +='</select>';
		Marshall += '&nbsp;&nbsp;&nbsp;<a id="btSetMarshall" class="inlineButton btButton brown8" onclick="btSetMarshall()"><span>'+uW.g_js_strings.commonstr.assign+'</span></a>&nbsp;<a id="btCancelMarshall" class="inlineButton btButton brown8" onclick="btCancelMarshall()"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></div>';

		Status += '<tr><td class=xtab valign=top><a onClick="btShowKnightsHall('+t.Curr+')">'+tx('Marshall')+'</a></td><td class=xtabBR style="white-space:normal;" colspan=2><b>'+Marshall+'</b></td></tr>';

		var GotChamp = false;
		var CheckChamp = false;

		Champion = '<table cellspacing=0><tr><td class="xtab"><span class=xtab style="color:#f00"><b>'+uW.g_js_strings.champ.no_champ+'!</b></td><td class=xtab>';
		try {
			if (!Options.DashboardOptions.GraphicalChampDisplay) {
				for (var y in Seed.champion.champions) {
					t.citychamp = Seed.champion.champions[y];
					if (t.citychamp.assignedCity && t.citychamp.assignedCity == cityId) {
						GotChamp = true;
						if (t.oldchamp != t.citychamp.championId) { t.ExpandChampion = false; }
						if (t.citychamp.status != '10') {champstat = '<span class=xtab style="color:#080">('+uW.g_js_strings.commonstr.defending+')</span>';}
						else { champstat = '<span class=xtab style="color:#f00">('+uW.g_js_strings.commonstr.marching+')</span>';}
						Champion = '<table cellspacing=0><tr><td class="xtab trimg" style="font-weight:normal;align:left;" id="ChampStatstd"><img height=14 style="vertical-align:text-top;" id="ChampStats" onMouseover="btCreateChampionPopUp(this,'+t.citychamp.assignedCity+',true);" src="'+ChampImagePrefix+t.citychamp.avatarId+ChampImageSuffix+'"></td><td class=xtab>'+t.citychamp.name+'</td><td class=xtab>'+champstat+'</td><td class=xtab>';
						break;
					}
				}
				if (t.ExpandChampion) {
					Champion += '<a id="btCancelChampion" class="inlineButton btButton brown8" onclick="btCancelChampion()"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr></table><div><table cellspacing=0>';
				}
				else {
					if (!GotChamp) { Champion += '<a id="btChangeChampion" class="inlineButton btButton brown8" onclick="btChangeChampion()"><span>'+uW.g_js_strings.commonstr.assign+'</span></a>'; }
					else { if (t.citychamp.status != '10') { Champion += '<a id="btChangeChampion" class="inlineButton btButton brown8" onclick="btChangeChampion()"><span>'+tx('Change')+'</span></a>'; }}
					if (GotChamp && (t.citychamp.status != '10')) { Champion += '&nbsp;<a id="btFreeChampion" class="inlineButton btButton brown8" onclick="btFreeChampion('+t.citychamp.championId+',true)"><span>'+uW.g_js_strings.commonstr.unassign+'</span></a>'; }
					Champion += '</td></tr></table><div class=divHide><table cellspacing=0>';
				}
				for (var y in Seed.champion.champions) {
					chkchamp = Seed.champion.champions[y];
					if (chkchamp.championId) {
						if (!chkchamp.assignedCity || chkchamp.assignedCity != cityId) {
							CheckChamp = true;
							if (!chkchamp.assignedCity || chkchamp.assignedCity == 0) { chkcity = 'Unassigned';} else { chkcity = Cities.byID[chkchamp.assignedCity].name;}
							chkbtn = '';
							defendingCity = chkcity;
							chkcol = "";
							if (chkchamp.status == '10') {
								defendingCity = tx('Marching From')+' '+defendingCity;
								chkcol='color:#800;'
							}
							else {
								if (defendingCity != 'Unassigned') {
									defendingCity = uW.g_js_strings.commonstr.defending+' '+defendingCity;
									chkcol = 'color:#f80;';
								}
								chkbtn = '<a id="btSetChampion'+chkchamp.championId+'" class="inlineButton btButton brown8" onclick="btSetChampion('+chkchamp.championId+',true)"><span>'+uW.g_js_strings.commonstr.assign+'</span></a>';
							}
							Champion += '<tr style="font-weight:normal;align:left;"><td class="xtab trimg" id="ChampStats'+chkchamp.championId+'td"><img height=14 style="vertical-align:text-top;" id="ChampStats'+chkchamp.championId+'" onMouseover="btCreateChampionPopUp(this,'+(chkchamp.assignedCity?chkchamp.assignedCity:0)+',true,'+chkchamp.championId+');" src="'+ChampImagePrefix+chkchamp.avatarId+ChampImageSuffix+'"></td><td class=xtab>'+chkchamp.name+'</td><td class=xtab><span style="'+chkcol+'">'+defendingCity+'</span></td><td class=xtab>'+chkbtn+'</td></tr>';
						}
					}
				}
				Champion += '</table></div>';
			}
			else {
				Champion = t.PaintChampionSelector(cityId);
			}
		}
		catch (err) {
			logerr(err); // write to log
			Champion = '<span class=xtab style="color:#f00"><b>'+tx('Error reading champion data')+' :(</b></span>';
		}

		if (!Options.DashboardOptions.GraphicalChampDisplay) {
			Status += '<tr><td class=xtab valign=top><a onClick="cm.ChampionModalController.open()">'+uW.g_js_strings.champ.champion+'</a></td><td class=xtab colspan=2><b>'+Champion+'</b></td></tr>';
		}
		else {
			Status += '<tr><td class=xtab><a onClick="cm.ChampionModalController.open()">'+uW.g_js_strings.champ.champion+'</a></td><td class=xtab colspan=2>'+Champion+'</td></tr>';
		}

		Status += '<tr><td class=xtab><a onClick="btShowGuardians('+t.Curr+')">'+uW.g_js_strings.report_view.guardian+'</a></td><td class=xtab colspan=2 id="btGuardianSelector"></td></tr>';

		var now = unixTime();

		var BoostItemHint = [uW.g_js_strings.commonstr.atk+':20%',uW.g_js_strings.commonstr.atk+':20%',uW.g_js_strings.commonstr.atk+':50%',tx('Def')+':20%',tx('Def')+':20%',tx('Def')+':50%',uW.g_js_strings.commonstr.life+':10%',uW.g_js_strings.commonstr.life+':10%'];
		var tBoostItemHint = [uW.g_js_strings.commonstr.atk+':20%',uW.g_js_strings.commonstr.atk+':20%',uW.g_js_strings.commonstr.atk+':50%',uW.g_js_strings.commonstr.life+':20%',uW.g_js_strings.commonstr.life+':20%',uW.g_js_strings.commonstr.life+':50%'];

		atkboost = '<span style="color:#f00"><b>'+tx('No Active Boost!')+'</b></span>';
		if (Seed.playerEffects.atk2Expire >now) {
			atkboost = '<span style="color:#080"><b>50% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.atk2Expire-now)+'</b></span>';
		}
		else {
			if (Seed.playerEffects.atkExpire >now) {
				atkboost = '<span style="color:#f80"><b>20% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.atkExpire-now)+'</b></span>';
			}
		}
		defboost = '<span style="color:#f00"><b>'+tx('No Active Boost!')+'</b></span>';
		if (Seed.playerEffects.def2Expire >now) {
			defboost = '<span style="color:#080"><b>50% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.def2Expire-now)+'</b></span>';
		}
		else {
			if (Seed.playerEffects.defExpire >now) {
				defboost = '<span style="color:#f80"><b>20% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.defExpire-now)+'</b></span>';
			}
		}
		lifeboost = '<span style="color:#f00"><b>'+tx('No Active Boost!')+'</b></span>';
		if (Seed.playerEffects.lifeExpire >now) {
			lifeboost = '<span style="color:#080"><b>10% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.lifeExpire-now)+'</b></span>';
		}

		boosts = '<table cellspacing=0 cellpadding=0><tr>';
		for (var i = 0; i < t.BoostItemList.length; i++) {
			if (uW.ksoItems[t.BoostItemList[i]].count) {
				boosts += '<td class=xtab><a onClick="cm.ItemController.use(\''+t.BoostItemList[i]+'\')"><img height=28 src="'+IMGURL+'items/70/'+t.BoostItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.BoostItemList[i]].name+' ('+BoostItemHint[i]+') ('+uW.ksoItems[t.BoostItemList[i]].count+')"></a></td>';
			}
		}

		boosts += '</tr></table>'
		Status += '<tr><td class=xtab valign=top>'+uW.g_js_strings.commonstr.attack+'</td><td class=xtab id=atkboostcell>&nbsp;</td><td class=xtab rowspan=3 align=right>'+boosts+'</td></tr>';
		Status += '<tr><td class=xtab valign=top>'+uW.g_js_strings.commonstr.defense+'</td><td class=xtab id=defboostcell>&nbsp;</td></tr>';
		Status += '<tr><td class=xtab valign=top>'+tx('Health')+'</td><td class=xtab id=lifeboostcell>&nbsp;</td></tr>';

		Status += '</table>';

		Status += '<div id=btTRPresets></div>';

		if (CheckForHTMLChange('DASH','btStatusCell',CityTag+Status,t.serverwait)) {
			ById('btCityStatus').addEventListener ('click', function(){t.ToggleDefenceMode (cityId);} , false);
			t.PaintTRPresets();
			t.PaintGuardianSelector();
			if (GotChamp) {	t.oldchamp = t.citychamp.championId; }
			else { t.oldchamp = 0; }
			t.ResizeFrame = true;
		}

		ById('atkboostcell').innerHTML = atkboost;
		ById('defboostcell').innerHTML = defboost;
		ById('lifeboostcell').innerHTML = lifeboost;
		ById('prestigeexpcell').innerHTML = prestigeexp;

		// sacrifices

		var s = "";
		var z = "";
		var b = t.Buildings[25];
		if (b.count > 0) {
			s += '<table cellSpacing=0 width="100%">';
			s += '<tr><td width=20% class=xtab>'+tx('No. of Altars')+'</td><td width=20% class=xtab><b>'+b.count+'</b></td>';
			s += '<td width=40% class=xtab>'+uW.g_js_strings.blessingSystem.blessing_name_203+'?</td><td width=20% class=xtab><b>'+(t.DarkRitual?uW.g_js_strings.commonstr.yes:uW.g_js_strings.commonstr.no)+'</b></td></tr>';
			s += '<tr><td class=xtab>'+tx('Increase')+'</td><td class=xtab><b>'+t.SacSettings.stat_inc+'%</b></td>';
			s += '<td class=xtab>'+uW.g_js_strings.blessingSystem.blessing_name_206+'?</td><td class=xtab><b>'+(t.ChannelledSuffering?uW.g_js_strings.commonstr.yes:uW.g_js_strings.commonstr.no)+'</b></td></tr>';
			s += '<tr><td class=xtab>'+tx('Max. Troops')+'</td><td class=xtab><b>'+addCommas(t.SacSettings.max_amount)+'</b></td>';
			s += '<td class=xtab>'+tx('Troops per Second')+'</td><td class=xtab><b>'+(Math.round(t.SacSpeed * 100 / t.SacSpeedBuff)/100)+'</b></td></tr>';
			s += '<tr id=btQuickSac class=divHide><td class=xtabBR colspan="4">'+t.QuickSacString+'</td></tr>';
			s += '</table>';

			sac = Seed.queue_sacr["city" + cityId],
			sacrifices = false;
			var r = 0;
			if (sac.length > 0) {
				sacrifices = true;
				jQuery.each(sac, function (P, R) {
					var Q = parseInt(R.eta, 10) - unixTime(),
					S = Math.round((R.multiplier[0] - 1) * 100),
					T = R.buffedUnitType[0];

					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';

					z += '<tr class="'+rowClass+'"><TD class=xtabBR><span class=xtab>'+uW.unitcost["unt"+T][0]+'</span></td><td class=xtab>'+R.quantity+'</td><td class=xtab>'+uW.timestr(Q)+'</td><td class=xtab align=right><a id="btStopRitual'+P+'" class="inlineButton btButton blue14" onclick="btStopRitual('+ P +')"><span style="width:65px;display:inline-block;text-align:center;">'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr>';
				})
			}
			z = '<br><div align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td width="120" class="xtabHD"><b>'+uW.g_js_strings.openCastle.trooptype+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.amount+'</b></td><td width="80" class="xtabHD"><b>'+uW.g_js_strings.commonstr.time+'</b></td><td width="90" class="xtabHD">&nbsp;</td></tr>'+z;
			z += '</table></div>';

			if (r < t.SacAllowed) {
				t.ShowNewSacrifice(true);
				t.allownewsacs = true;
			}
			else {
				t.ShowNewSacrifice(false);
				t.allownewsacs = false;
				z += '<tr><td class=xtab colspan="4"><div class="ErrText" align="center">&nbsp;</div></td></tr>';
			}
			z += '</table></div>';
		}
		else {
			z = '<div><br><div style="opacity:0.3;">'+tx('No fey altars!')+'</div><br></div>';
			t.ShowNewSacrifice(false);
			t.allownewsacs = false;
		}

		if (CheckForHTMLChange('DASH','btSacrificeCell',CityTag+s+z)) {
			t.PaintQuickSac();
			t.ResizeFrame = true;
		}

		// troops

		var GotTroops = false;
		var TroopColour = Options.Colors.PanelText;
		var TitleColour = 'rgba('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+',0.5)';
		var TitleStyle = 'xtabHD';
		if (DefState) {
			TroopColour = '#f00';
			TitleColour = '#f00';
			TitleStyle = 'xtabHDDef';
		}

		if (DefState) DefButton2 = '<a id=btCityStatus2 class="inlineButton btButton red20"><span style="width:75px"><center>'+uW.g_js_strings.commonstr.defending+'!</center></span></a>';
		else DefButton2 = '<a id=btCityStatus2 class="inlineButton btButton green20"><span style="width:75px"><center>'+tx('Hiding!')+'</center></span></a>';

		TroopCell = '<div style="font-size:10px;" align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td colspan=2 class="xtab" style="vertical-align:text-top;">';
		if (SelectiveDefending) { TroopCell += '<INPUT id=btFixTroopsChk type=checkbox '+(Options.DashboardOptions.ReplaceDefendingTroops[t.Curr]?'CHECKED':'')+' /><span style="color:'+TroopColour+';font-size:11px;"><b>'+tx('Auto-Replace')+'</b></span>'; }
		TroopCell += '</td><td colspan=1 class="xtab" align=center><b><a class="TextLink" title="Click to toggle troops to Hide" style="color:'+TitleColour+';font-size:14px;" onclick="btSelectDefenders(\'A\',false);">'+uW.g_js_strings.commonstr.defending+'</a></b><br></td><td colspan=2 class="xtab" align=right><span class='+((Options.DashboardOptions.LowerDefendButton==false)?'divHide':'')+'>'+DefButton2+'</span></td></tr>';

		if (SelectiveDefending) {
			Troops = '<tr><td width=20% class="'+TitleStyle+'"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'I\',false);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypeinfantry+'</a></b></td><td width=20% class="'+TitleStyle+'"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'R\',false);">'+uW.g_js_strings.modal_barracks_trainingtab.unittyperanged+'</a></b></td><td width=20% class="'+TitleStyle+'"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'H\',false);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypehorsed+'</a></b></td><td width=20% class="'+TitleStyle+'"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'S\',false);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypesiege+'</a></b></td><td width=20% class="'+TitleStyle+'"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'P\',false);">'+uW.g_js_strings.modal_barracks_trainingtab.spellcaster+'</a></b></td></tr>';
			Troops += '<tr><td class="xtabBRTop">';
			for(c=0; c<Infantry.length; c++){
				var i = parseInt(Infantry[c]);
				if (Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',false);">'+TroopImage(i)+ addCommas(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
			}
			Troops += '</td><td class="xtabBRTop">';
			for(c=0; c<Ranged.length; c++){
				var i = parseInt(Ranged[c]);
				if (Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',false);">'+TroopImage(i)+ addCommas(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
			}
			Troops += '</td><td class="xtabBRTop">';
			for(c=0; c<Horsed.length; c++){
				var i = parseInt(Horsed[c]);
				if (Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',false);">'+TroopImage(i)+ addCommas(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
			}
			Troops += '</td><td class="xtabBRTop">';
			for(c=0; c<Siege.length; c++){
				var i = parseInt(Siege[c]);
				if (Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',false);">'+TroopImage(i)+ addCommas(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
			}
			Troops += '</td><td class="xtabBRTop">';
			for(c=0; c<SpellCaster.length; c++){
				var i = parseInt(SpellCaster[c]);
				if (Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',false);">'+TroopImage(i)+ addCommas(Seed.defunits['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
			}
			Troops += '</td></tr>';
			if (!GotTroops) {Troops = '<tr><td colspan=5 class="xtab" align=center><div style="opacity:0.3;color:'+TroopColour+'">'+tx('No Troops')+'</div></td></tr>';}

			TroopCell += Troops + '<tr><td colspan=5 class="xtab" align=center>&nbsp;</td></tr>';

			GotTroops = false;
			TroopColour = Options.Colors.PanelText;
			TitleColour = 'rgba('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+',0.5)';
			TitleStyle = 'xtabHD';

			TroopCell += '<tr><td colspan=2 class="xtab" style="vertical-align:text-top;">&nbsp;</td><td colspan=1 class="xtab" align=center><b><a class="TextLink" title="'+tx('Click to toggle troops to Defend')+'" style="color:'+TitleColour+';font-size:14px;" onclick="btSelectDefenders(\'A\',true);">'+tx('Sanctuary')+'</a></b><br></td><td colspan=2 class="xtab" align=right><a onclick="btToggleSanctuary();"><span id=btShowHideSanct>'+tx('hide')+'</span></a></td></tr>';
		}

		Troops = '<tr id=btsanctroopstitle><td width=20% class="xtabHD"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'I\',true);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypeinfantry+'</a></b></td><td width=20% class="xtabHD"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'R\',true);">'+uW.g_js_strings.modal_barracks_trainingtab.unittyperanged+'</a></b></td><td width=20% class="xtabHD"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'H\',true);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypehorsed+'</a></b></td><td width=20% class="xtabHD"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'S\',true);">'+uW.g_js_strings.modal_barracks_trainingtab.unittypesiege+'</a></b></td><td width=20% class="xtabHD"><b><a class="TextLink" style="color:'+TitleColour+';" onclick="btSelectDefenders(\'P\',true);">'+uW.g_js_strings.modal_barracks_trainingtab.spellcaster+'</a></b></td></tr>';
		Troops += '<tr id=btsanctroops><td class="xtabBRTop">';
		for(c=0; c<Infantry.length; c++){
			var i = parseInt(Infantry[c]);
			if (Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',true);">'+TroopImage(i)+ addCommas(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
		}
		Troops += '</td><td class="xtabBRTop">';
		for(c=0; c<Ranged.length; c++){
			var i = parseInt(Ranged[c]);
			if (Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',true);">'+TroopImage(i)+ addCommas(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
		}
		Troops += '</td><td class="xtabBRTop">';
		for(c=0; c<Horsed.length; c++){
			var i = parseInt(Horsed[c]);
			if (Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',true);">'+TroopImage(i)+ addCommas(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
		}
		Troops += '</td><td class="xtabBRTop">';
		for(c=0; c<Siege.length; c++){
			var i = parseInt(Siege[c]);
			if (Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',true);">'+TroopImage(i)+ addCommas(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
		}
		Troops += '</td><td class="xtabBRTop">';
		for(c=0; c<SpellCaster.length; c++){
			var i = parseInt(SpellCaster[c]);
			if (Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i] > 0) { GotTroops = true; Troops += '<span class=xtab style="color:'+TroopColour+'"><a class="TextLink" style="color:'+TroopColour+';" onclick="btSelectDefenders('+i+',true);">'+TroopImage(i)+ addCommas(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+i])+'</a></span> ';}
		}
		Troops += '</td></tr>';
		if (!GotTroops) {Troops = '<tr id=btsanctroops><td colspan=5 class="xtab" align=center><div style="opacity:0.3;color:'+TroopColour+'">'+tx('No Troops')+'</div></td></tr>';}
		TroopCell += Troops + '<tr><td colspan=5 class="xtab" align=center>&nbsp;</td></tr></table></div>';

		if (CheckForHTMLChange('DASH','btTroopCell',CityTag+TroopCell)) {
			t.ShowHideSanctuary();
			if (SelectiveDefending) {
				ById('btFixTroopsChk').addEventListener ('click', function(e) {
					Options.DashboardOptions.ReplaceDefendingTroops[t.Curr] = e.target.checked;
					saveOptions();
				},false);
			}
			ById('btCityStatus2').addEventListener ('click', function(){t.ToggleDefenceMode (cityId);} , false);
			// check if troop types dropdowns need refreshing - Defence AND Sacrifice!
			CheckOptionsString = "";
			for (var y in uW.unitcost) {
				var tot = parseIntNan(Seed.units['city' + Seed.cities[t.Curr][0]]['unt'+y.substr(3)]);
				if ((tot > 0)) {
					CheckOptionsString = CheckOptionsString + y.substr(3);
				}
			}
			if (t.DefOptionsString != CheckOptionsString) {
				if (SelectiveDefending) { t.InitPresetNumber = ById('btDefendPreset').value; }
				t.SetCurrentCity(Seed.cities[t.Curr][0],true);
			}
			else {
				if (SelectiveDefending) { t.SelectDefTroopType (ById("btDefendTroops")); }
			}
			t.ResizeFrame = true;
		}

		// reinforcements

		reinforcements = false;
		t.Reins = [];
		var z = "";
		var r = 0;
		for (var k in inc){
			var to = Cities.byID[inc[k].toCityId];
			if ((inc[k].toCityId == cityId) && (to.tileId == inc[k].toTileId) && ((inc[k].marchStatus == 2) || (inc[k].marchType == 2)) && (inc[k].fromCityId != cityId)) {
				reinforcements = true;
				var a = inc[k];
				var player = Seed.players['u'+a.fromPlayerId];
				var fromname = player.n;
				marchdir = "Return"; // always show troops remaining
				var	marchtime=uW.timestr(a.arrivalTime - unixTime());

				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';

				z += '<tr class="'+rowClass+'"><TD class=xtabBR><span class=xtab>'+fromname+'</span></td><td class=xtabBR>';

				if (a["knightId"] > 0) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' (Atk:'+ a["knightCombat"]+')</span> ';
				for (var ui in uW.cm.UNIT_TYPES){
					i = uW.cm.UNIT_TYPES[ui];
					if(a["unit"+i+marchdir] > 0) z += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': '+ addCommas(a["unit"+i+marchdir])+'</span> ';
				}
				if ((a.marchStatus == 2) || (a.arrivalTime - unixTime() <= 0))	{
					z += '</td><td class=xtab align="right"><a id="btSendHome'+a.marchId+'" class="inlineButton btButton blue14" onclick="btSendHome('+ a.marchId +')"><span>'+uW.g_js_strings.openEmbassy.senthome+'</span></a></td></tr>';
					t.Reins.push(a.marchId); // for send all home logic
				}
				else {
					z += '</td><td class=xtab align="right">'+marchtime+'</td></tr>';
				}
			}
		}
		if (!reinforcements) {
			z = '<DIV><br><div style="opacity:0.3;">'+tx('No Reinforcements')+'</div><br></div>';
		}
		else
		{
			z = '<div align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td width="120" class="xtabHD"><b>'+uW.g_js_strings.commonstr.from+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td><td width="40" class="xtabHD"><a id="btSendAllHome" class="inlineButton btButton red14" onclick="btSendAllHome('+cityId+')"><span>'+tx('Send All Home')+'</span></a></td></tr>'+z;
			z += '<tr><td class=xtab colspan="4"><div class="ErrText" align="center" id=btReinErr>&nbsp;</div></td></tr></table></div>';
		}

		if (CheckForHTMLChange('DASH','btReinforceCell',CityTag+z,t.serverwait)) {
			t.ResizeFrame = true;
		}

		// incoming attacks

		cityincoming = false;
		var cityinctimes = {};
		var z = "";
		var r = 0;
		for (var k in inc){
			if ((inc[k].toCityId == cityId) && (inc[k].score)) {
				var a = inc[k];
				if (a.arrivalTime < unixTime()) continue; // don't display arrival times already happened
				cityincoming = true;
				var icon,hint,marchtime,fromname,marchdir,fromcoords;
				var marchId = a.mid;
				var marchScore = parseInt(a.score);
				var marchType = parseInt(a.marchType);
				var marchStatus = parseInt(a.marchStatus);
				if (!a.marchType) {a.marchType = 4;}
				if (!a.arrivalTime || a.arrivalTime == -1) {marchtime = '??????';}
				else {marchtime=uW.timestr(a.arrivalTime - unixTime());}
				cityinctimes[marchId] = marchtime;
				var player = Seed.players['u'+a.pid];
				fromname = "";
				if (player) {fromname = player.n;}

				if (!a.fromXCoord) {fromcoords = "";}
				else {fromcoords = coordLink(a.fromXCoord,a.fromYCoord);}
				if (fromname == "") {fromname = '('+tx('Upgrade WatchTower')+')';}
				else {fromname = MonitorLink(a.pid,fromname);}

				switch (marchType) {
					case 3: icon=ScoutImage;hint=uW.g_js_strings.commonstr.scout;break;
					case 4: icon=AttackImage;hint=uW.g_js_strings.commonstr.attack;break;
				}

				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';

				z += '<tr class="'+rowClass+'"><TD class=xtab><img src='+icon+' title='+hint+'></td>';
				z += '<TD class=xtabBR><span class=xtab id="citymarchtime'+marchId+'">&nbsp;</span></td>';
				z += '<TD class=xtabBR><span class=xtab>'+fromname+'</span> ';
				if (fromcoords != "") { z+= '<span class=xtab>'+fromcoords+'</span>'; }
				z += '</td><td  class=xtabBR>';

				if ((safecall.indexOf(a.pid) < 0 || trusted) && a["championInfo"]) {
					t.marchchamp = '<table cellspacing=0 class=xtab><tr><td colspan=2><b>'+a["championInfo"].name+'</b></td></tr><tr><td colspan=2><b>'+uW.g_js_strings.report_view.champion_stats+'</b></td></tr>';
					var gotchamp = false;
					if (a["championInfo"].effects[1] && !(a["championInfo"].effects[1] instanceof Array) && typeof(a["championInfo"].effects[1]) === "object") {
						got202 = false;
						for (var cy in a["championInfo"].effects[1]) {
							// missing bonus damage?
							if ((cy == '202') && gotchamp) {got202 = true;}
							if ((cy == '203') && !got202) { t.marchchamp += "<tr><td>"+uW.g_js_strings.effects.name_202+"</td><td>0</td></tr>"; }
							str = eval('uW.g_js_strings.effects.name_'+cy);
							if (str && str!= "") {
								gotchamp = true;
								t.marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[1][cy]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gotchamp) { t.marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					t.marchchamp+='<tr><td colspan=2><b>'+uW.g_js_strings.report_view.troop_stats+'</b></td></tr>';
					var gottroop = false;
					if (a["championInfo"].effects[2] && !(a["championInfo"].effects[2] instanceof Array) && typeof(a["championInfo"].effects[2]) === "object") {
						for (var ty in a["championInfo"].effects[2]) {
							str = eval('uW.g_js_strings.effects.name_'+ty);
							if (str && str!= "") {
								gottroop = true;
								t.marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[2][ty]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gottroop) { t.marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					t.marchchamp+="</table>";
					z +='<table cellspacing=0><tr><td class="xtab trimg" style="font-weight:normal;align:left;" id="btcitymarchchamp'+a.mid+'td"><input type="hidden" id="btcitymarchchamp'+a.mid+'effects" value="'+t.marchchamp+'" /><a><img id="btcitymarchchamp'+a.mid+'" onMouseover="btCreateChampionPopUp(this,'+a.toCityId+');" height=14 style="vertical-align:text-top;" src="'+ShieldImage+'"></a></td><td class=xtab>Champion: '+a["championInfo"].name+'&nbsp;</td></tr></table>';
				}
				if (a["knt"] && a["knt"]["cbt"]) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' ('+uW.g_js_strings.commonstr.atk+':'+ a["knt"]["cbt"]+')</span> ';
				if (a["unts"]) {
					for (var ui in uW.cm.UNIT_TYPES){
						i = uW.cm.UNIT_TYPES[ui];
						if (a["unts"]["u"+i]) {
							if (a["unts"]["u"+i] > 0) z += '<span class=xtab>'+ uW.unitnamedesctranslated['unt'+i][0] +': '+ addCommas(a["unts"]["u"+i])+'</span> ';
							else z += '<span class=xtab>'+ a["unts"]["u"+i]+' '+ uW.unitnamedesctranslated['unt'+i][0] +'</span> ';
						}
					}
				}
				else
				{
					if (a["cnt"]) { z += '<span class=xtab>'+a["cnt"]+'</span> ';}
					else { z += '<span class=xtab>('+uW.g_js_strings.attack_viewimpending_view.upgradetoseeinfo+')</span> '; }
				}

				if (local_atkinc["m"+marchId]["fromSpellType"]) {
					var spell = eval('uW.g_js_strings.spells.name_'+local_atkinc["m"+marchId]["fromSpellType"]);
					if (spell) {
						var spellstyle = 'color:#808;';
						z +='<br><span class=xtab style="'+spellstyle+'"><b>*&nbsp;'+spell+'&nbsp;*</b></span>'
					}
				}

				z += '</td></tr>';
			}
		}
		if (!cityincoming) {
			z = '<DIV><br><div style="opacity:0.3;">'+tx('No Incoming Attacks')+'</div></div>';
		}
		else
		{
			z = '<div align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td width="18" class="xtabHD">&nbsp;</td><td width="60" class="xtabHD"><b>'+uW.g_js_strings.commonstr.time+'</b></td><td width="120" class="xtabHD"><b>'+uW.g_js_strings.commonstr.from+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td></tr>'+z;
		}
		z += '</table></div>';

		if (CheckForHTMLChange('DASH','btAttackCell',CityTag+z)) {
			t.ResizeFrame = true;
		}

		for (var m in cityinctimes) {
			mt = cityinctimes[m];
			if (ById('citymarchtime'+m)) {
				ById('citymarchtime'+m).innerHTML = mt;
			}
		}

		// fortifications

		GotDef = false;
		t.WallDefences = [];
		t.FieldDefences = [];
		var d = Seed.fortifications["city" + Seed.cities[t.Curr][0]];
		var a = Object.keys(d);
		for (var c = 0; c < a.length; c++) {
			var f = parseInt(a[c].split("fort")[1]);
			if (f < 60 || f==63) { t.WallDefences.push(a[c]) } else { t.FieldDefences.push(a[c])	}
		}

		var dt = t.Buildings[30];
		var rt = t.Buildings[31];
		var wall = {};
		getWallInfo(cityId,wall);
		Walls = '<div align="center"><table cellSpacing=0 width="100%">';
		Walls += '<tr><td width=20% class=xtab><a onClick="btShowWalls('+t.Curr+')">'+tx('Walls')+'</a></td><td width=60% class=xtab><b>'+(wall.wallLevel?uW.g_js_strings.commonstr.level+' '+wall.wallLevel:'<span class=xtab style="color:#f00">'+tx('No Walls')+'</span>')+'</b></td><td width=20% class=xtab>'+tx('Wall Space')+'</td><td align=right class=xtab><b>'+wall.wallSpaceUsed+'/'+wall.wallSpace+'</b></td></tr>';
		Walls += '<tr><td class=xtab>'+uW.buildingcost.bdg30[0]+'</td><td class=xtab><b>'+(dt.maxLevel?'Level '+dt.maxLevel:'<span class=xtab style="color:#f00">'+tx('None')+'!</span>')+'</b></td><td class=xtab>'+tx('Field Space')+'</td><td align=right class=xtab><b>'+wall.fieldSpaceUsed+'/'+wall.fieldSpace+'</b></td></tr>';
		Walls += '<tr><td class=xtab>'+uW.buildingcost.bdg31[0]+'</td><td class=xtab><b>'+(rt.maxLevel?'Level '+rt.maxLevel:'<span class=xtab style="color:#f00">'+tx('None')+'!</span>')+'</b></td><td class=xtab>&nbsp;</td></tr>';
		Walls += '</table><br>';

		var now = unixTime();

		tatkboost = '<span style="color:#f00"><b>'+tx('No Active Boost!')+'</b></span>';
		if (Seed.playerEffects.tatk2Expire >now) {
			tatkboost = '<span style="color:#080"><b>50% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.tatk2Expire-now)+'</b></span>';
		}
		else {
			if (Seed.playerEffects.tatkExpire >now) {
				tatkboost = '<span style="color:#f80"><b>20% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.tatkExpire-now)+'</b></span>';
			}
		}
		tlifeboost = '<span style="color:#f00"><b>'+tx('No Active Boost!')+'</b></span>';
		if (Seed.playerEffects.tlife2Expire >now) {
			tlifeboost = '<span style="color:#080"><b>50% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.tlife2Expire-now)+'</b></span>';
		}
		else {
			if (Seed.playerEffects.tlifeExpire >now) {
				tlifeboost = '<span style="color:#f80"><b>20% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.tlifeExpire-now)+'</b></span>';
			}
		}

		tboosts = '<table cellspacing=0 cellpadding=0><tr>';

		for (var i = 0; i < t.tBoostItemList.length; i++) {
			if (uW.ksoItems[t.tBoostItemList[i]].count) {
				tboosts += '<td class=xtab><a onClick="cm.ItemController.use(\''+t.tBoostItemList[i]+'\')"><img height=28 src="'+IMGURL+'items/70/'+t.tBoostItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.tBoostItemList[i]].name+' ('+tBoostItemHint[i]+') ('+uW.ksoItems[t.tBoostItemList[i]].count+')"></a></td>';
			}
		}

		tboosts += '</tr></table>';
		var tStatus = '<table cellSpacing=0 width="100%">';
		tStatus += '<tr><td  width=20% class=xtab valign=top>'+tx('Tower Attack')+'</td><td class=xtab id=tatkboostcell>&nbsp;</td><td class=xtab rowspan=2 align=right>'+tboosts+'</td></tr>';
		tStatus += '<tr><td  width=20% class=xtab valign=top>'+tx('Tower Life')+'</td><td class=xtab id=tlifeboostcell>&nbsp;</td></tr>';

		tStatus += '</table><br>';

		Defences = '<div align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td width=50% class="xtabHD"><b>'+uW.g_js_strings.openCastle.walldefenses+'</b></td><td width=50% class="xtabHD"><b>'+tx('Field Defenses')+'</b></td></tr>';
		Defences += '<tr><td class="xtabBRTop">';
		for(c=0; c<t.WallDefences.length; c++){
			var f = parseInt(t.WallDefences[c].split("fort")[1]);
			if (Seed.fortifications['city' + Seed.cities[t.Curr][0]]['fort'+f] > 0) { GotDef = true; Defences += '<span class=xtab style="display:inline-block;width:100px;">'+TroopImage(f)+ addCommas(Seed.fortifications['city' + Seed.cities[t.Curr][0]]['fort'+f])+'</span> ';}
		}
		Defences += '</td><td class="xtabBRTop">';
		for(c=0; c<t.FieldDefences.length; c++){
			var f = parseInt(t.FieldDefences[c].split("fort")[1]);
			if (Seed.fortifications['city' + Seed.cities[t.Curr][0]]['fort'+f] > 0) { GotDef = true; Defences += '<span class=xtab style="display:inline-block;width:100px;">'+TroopImage(f)+ addCommas(Seed.fortifications['city' + Seed.cities[t.Curr][0]]['fort'+f])+'</span> ';}
		}
		Defences += '</td></tr></table>';
		if (!GotDef) {Defences = '<div><br><div style="opacity:0.3;">'+tx('No Fortifications')+'</div>';}
		Defences += '<br></div>';

		if (CheckForHTMLChange('DASH','btWallDefenceCell',CityTag+Walls+tStatus+Defences)) {
			t.ResizeFrame = true;
		}

		ById('tatkboostcell').innerHTML = tatkboost;
		ById('tlifeboostcell').innerHTML = tlifeboost;

		// outgoing attacks

		cityoutgoing = false;
		var cityouttimes = {};
		var z = "";
		var r = 0;
		for (var k in outCity){
			var a = outCity[k];
			if (a.destinationUnixTime < unixTime()) continue; // don't display arrival times already happened
			var icon, hint, marchtime, totile, tocity, toname, marchdir, tocoords;

			var marchId = a.marchId;
			var marchStatus = parseInt(a.marchStatus);
			var marchType = parseInt(a.marchType);
			if (marchType == 10) marchType=4; // Change Dark Forest type to Attack!
			if (marchType != 4 && marchType != 3) continue; // attacks and scouts only
			cityoutgoing = true;
			var now = unixTime();
			var destinationUnixTime = a["destinationUnixTime"] - now;

			marchdir = "Count";

			totile = "";
			tocity = "";
			toname = "";
			totile = tileTypes[parseInt(a["toTileType"])];
			if (a["toTileType"] == 51) {
				if (!a["toPlayerId"]) { totile = ""; }
				else { if (a["toPlayerId"] == 0) totile = tx('Barb Camp'); }
			}
			totile = 'Lvl '+a["toTileLevel"]+' '+totile;

			if (a["toPlayerId"] && (a["toPlayerId"] != 0)) {
				if (a.players && a.players['u'+a.toPlayerId]) {
					toname = MonitorLink(a.toPlayerId,a.players['u'+a.toPlayerId].n);
				}
				else {
					if (Seed.players['u'+a.toPlayerId]) {
						toname = MonitorLink(a.toPlayerId,Seed.players['u'+a.toPlayerId].n);
					}
				}
			}

			var iconType = marchType;

			if (destinationUnixTime < (60)) { marchtime = '<span style="color:#f00">'+uW.timestr(destinationUnixTime)+'</span>'; }
			else { marchtime = uW.timestr(destinationUnixTime); }

			cityouttimes[marchId] = marchtime;

			if (!a.toXCoord || (tocity != "")) {tocoords = "";}
			else {tocoords = coordLink(a.toXCoord,a.toYCoord);}

			hint = "";
			switch (marchType) {
				case 3: hint=uW.g_js_strings.commonstr.scout;break;
				case 4: hint=uW.g_js_strings.commonstr.attack;break;
			}

			switch (iconType) {
				case 3: icon=ScoutImage;break;
				case 4: icon=AttackImage;break;
			}
			hint=tx('Recall march')+" ("+marchId+")";

			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'"><TD class=xtab><a id="btCityRecall'+a.marchId+'" onclick="btRecall('+ a.marchId +',true)"><img src='+icon+' title='+hint+'></a></td>';
			z += '<TD class=xtab id="cityoutmarchtime'+marchId+'">&nbsp;</td>';
			z += '<TD class=xtabBR>';
			if (toname != "") { z+= '<span class=xtab>'+toname+'</span> '; }
			if (totile != "") { z+= '<span class=xtab>'+totile+'</span> '; }
			if (tocity != "") { z+= '<span class=xtab>'+tocity+'</span> '; }
			if (tocoords != "") { z+= '<span class=xtab>'+tocoords+'</span>'; }
			z += '</td>';

			z += '<TD colspan=2 class=xtabBR>';

			if (a["championInfo"]) { // stats here are sort of obsolete, because it uses city champ data, but kept in for completeness...
				t.marchchamp = '<table cellspacing=0 class=xtab><tr><td colspan=2><b>'+a["championInfo"].name+'</b></td></tr><tr><td colspan=2><b>'+uW.g_js_strings.report_view.champion_stats+'</b></td></tr>';
				var gotchamp = false;
				if (a["championInfo"].effects) {
					if (a["championInfo"].effects[1] && !(a["championInfo"].effects[1] instanceof Array) && typeof(a["championInfo"].effects[1]) === "object") {
						got202 = false;
						for (var cy in a["championInfo"].effects[1]) {
							// missing bonus damage?
							if ((cy == '202') && gotchamp) {got202 = true;}
							if ((cy == '203') && !got202) { t.marchchamp += "<tr><td>"+uW.g_js_strings.effects.name_202+"</td><td>0</td></tr>"; }
							str = eval('uW.g_js_strings.effects.name_'+cy);
							if (str && str!= "") {
								gotchamp = true;
								t.marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[1][cy]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gotchamp) { t.marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					t.marchchamp+='<tr><td colspan=2><b>'+uW.g_js_strings.report_view.troop_stats+'</b></td></tr>';
					var gottroop = false;
					if (a["championInfo"].effects[2] && !(a["championInfo"].effects[2] instanceof Array) && typeof(a["championInfo"].effects[2]) === "object") {
						for (var ty in a["championInfo"].effects[2]) {
							str = eval('uW.g_js_strings.effects.name_'+ty);
							if (str && str!= "") {
								gottroop = true;
								t.marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[2][ty]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gottroop) { t.marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					t.marchchamp+="</table>";
				}
				z +='<table cellspacing=0><tr><td class="xtab trimg" style="font-weight:normal;align:left;" id="btcityoutmarchchamp'+a.marchId+'td"><input type="hidden" id="btcityoutmarchchamp'+a.marchId+'effects" value="'+t.marchchamp+'" /><a><img id="btcityoutmarchchamp'+a.marchId+'" onMouseover="btCreateChampionPopUp(this,'+a.fromCityId+',true);" height=14 style="vertical-align:text-top;" src="'+ShieldImage+'"></a></td><td class=xtab>'+uW.g_js_strings.champ.champion+': '+a["championInfo"].name+'&nbsp;</td></tr></table>';
			}
			if ((a["knightId"] > 0) && (!a["knightCombat"])) {
				for (var i in Seed.knights["city"+a.marchCityId]) {
					if (i == ("knt" + a["knightId"])) {
						Combat = Seed.knights["city"+a.marchCityId][i]["combat"];
						if (Seed.knights["city"+a.marchCityId][i]["combatBoostExpireUnixtime"] > unixTime()) {	Combat *= 1.25;	}
						a["knightCombat"] = Combat;
					}
				}
			}

			if (a["knightId"] > 0) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' ('+uW.g_js_strings.commonstr.atk+':'+ a["knightCombat"]+')</span> ';
			for (var ui in uW.cm.UNIT_TYPES){
				i = uW.cm.UNIT_TYPES[ui];
				if((a["unit"+i+"Count"] > 0) || (a["unit"+i+"Return"] > 0)) {
					trpcol = '#000';
					z += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': <span class=xtab style="color:'+trpcol+'">'+ addCommas(a["unit"+i+marchdir])+'</span></span> ';
				}
			}

			if (a["fromSpellType"]) {
				var spell = eval('uW.g_js_strings.spells.name_'+a["fromSpellType"]);
				if (spell) {
					var spellstyle = 'color:#808;';
					z +='<br><span class=xtab style="'+spellstyle+'"><b>*&nbsp;'+spell+'&nbsp;*</b></span>'
				}
			}

			z += '</td></tr>';

		}
		if (!cityoutgoing) {
			z = '<DIV><br><div style="opacity:0.3;">'+tx('No Outgoing Attacks')+'</div></div>';
		}
		else
		{
			z = '<div align="center"><TABLE cellSpacing=0 width=100% height=0%><tr><td width="18" class="xtabHD">&nbsp;</td><td width="60" class="xtabHD"><b>'+uW.g_js_strings.commonstr.time+'</b></td><td width="120" class="xtabHD"><b>'+uW.g_js_strings.commonstr.target+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td></tr>'+z;
		}
		z += '<tr><td class=xtab colspan="4"><div class="ErrText" align="center" id=btCityOutErr>&nbsp;</div></td></tr></table></div>';

		if (CheckForHTMLChange('DASH','btCityAttackCell',CityTag+z)) {
			t.ResizeFrame = true;
		}

		for (var m in cityouttimes) {
			mt = cityouttimes[m];
			if (ById('cityoutmarchtime'+m)) {
				ById('cityoutmarchtime'+m).innerHTML = mt;
			}
		}

		// toggle section displays

		t.ShowHideSection("btStatus",t.OverviewShow);
		t.ShowHideSection("btSacrifice",t.SacrificeShow && (ascended.prestigeType == "2"));
		t.ShowHideSection("btTroop",t.TroopShow);
		t.ShowHideSection("btReinforce",t.ReinforceShow);
		t.ShowHideSection("btWallDefence",t.FortificationShow);
		t.ShowHideSection("btAttack",t.AttackShow);
		t.ShowHideSection("btCityAttack",t.CityAttackShow);

		t.ShowHideRow("btDefAddTroopRow",Options.DashboardOptions.DefAddTroopShow);
		t.ShowHideRow("btDefPresetRow",Options.DashboardOptions.DefPresetShow);

		if (t.ResizeFrame == true) { ResetFrameSize('btDash',100,t.DashWidth); }
	},

	EverySecond : function () {
		var t = Dashboard;

		try {
			/* Reduce Delayers if they are Active */

			if (t.ThroneDelay > 0) { t.ThroneDelay--; t.PaintTRPresets(); }
			if (t.GuardDelay > 0) { t.GuardDelay--; t.PaintGuardianSelector(); }

			if (!(Options.DashboardOptions.CurrentCity < 0)) {
				if (((SecondLooper % t.GeneralInterval) == 1) || t.GeneralInterval == 1) {
					t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
				}
			};

			/* check defence status, incoming status, selected guardian */

			for (var cityId in Cities.byID){
				var city_num = Cities.byID[cityId].idx;
				if (Seed.citystats["city" + cityId].gate != 0) {
					jQuery("#btCastles_" + city_num).removeClass("hiding").addClass("defending");
				} else {
					jQuery("#btCastles_" + city_num).removeClass("defending").addClass("hiding");
				}
				if (incCity.indexOf(city_num) >= 0) { jQuery("#btCastles_" + city_num).addClass("attack"); }
				else {jQuery("#btCastles_" + city_num).removeClass("attack"); }
			}

			if (t.CurrGuardian != Seed.guardian[Options.DashboardOptions.CurrentCity].type) { t.PaintGuardianSelector(); }

			if (Options.DashboardOptions.RefreshSeed && ((SecondLooper % RefreshSeedInterval) == 1) && !RefreshingSeed) {
				setTimeout(function() {RefreshSeed();},250);
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},

	ToggleSanctuary : function () {
		var t = Dashboard;
		Options.DashboardOptions.ExpandSanctuary = !Options.DashboardOptions.ExpandSanctuary;
		saveOptions();
		t.ShowHideSanctuary();
	},

	ShowHideSanctuary : function () {
		var t = Dashboard;
		var a = ById('btShowHideSanct');
		if (Options.DashboardOptions.ExpandSanctuary) {
			disp = '';
			if (a) a.innerHTML = tx('hide');
		}else{
			disp = 'none';
			if (a) a.innerHTML = tx('show');
		}
		ById('btsanctroops').style.display = disp;
		if (ById('btsanctroopstitle')) ById('btsanctroopstitle').style.display = disp;
	},

	PaintQuickSac : function () {
		var t = Dashboard;
		if (!ById('btQuickSac')) { return; }
		if ((Options.DashboardOptions.QuickSacrifice == true) && (t.allownewsacs == true))
			t.ShowQuickSac(true);
		else
			t.ShowQuickSac(false);
	},

	ShowQuickSac : function (tf) {
		var t = Dashboard;
		var dc = jQuery('#btQuickSac').attr('class');
		if (tf) {if (dc.indexOf('divHide') >= 0) jQuery('#btQuickSac').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btQuickSac').attr('class','divHide');}
	},

	ShowNewSacrifice : function (tf) {
		var t = Dashboard;
		var dc = jQuery('#btNewSacrificeCell').attr('class');
		if (tf) {if (dc.indexOf('divHide') >= 0) jQuery('#btNewSacrificeCell').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btNewSacrificeCell').attr('class','divHide');}
	},

	SelectTroopType : function (sel) {
		var t = Dashboard;
		if ((sel.value == 0) || (sel.value == "")) {
			ById('btTotalTroops').innerHTML = "";
			ById('btMaxTroops').innerHTML = "";
			t.TotalTroops = 0;
			return false
		} else {
			if (SelectiveDefending) { t.TotalTroops = parseIntNan(Seed.units['city' + Seed.cities[Options.DashboardOptions.CurrentCity][0]]['unt'+sel.value])+parseIntNan(Seed.defunits['city' + Seed.cities[Options.DashboardOptions.CurrentCity][0]]['unt'+sel.value]); }
			else { t.TotalTroops = parseIntNan(Seed.units['city' + Seed.cities[Options.DashboardOptions.CurrentCity][0]]['unt'+sel.value]); }
			ById('btTotalTroops').innerHTML = '&nbsp;/&nbsp;'+addCommas(t.TotalTroops);
			ById('btMaxTroops').innerHTML = '<a id="btMaxButton" onclick="btSetMaxTroops()"><span style="font-size:9px;" align="center">max</span></a>';
			// set default sac length if blank
			if (Options.DashboardOptions.DefaultSacrifice) {
				var elemin = ById('btRitualMinutes');
				var elesec = ById('btRitualSeconds');
				if ((elemin.value == "") && (elesec.value == "")) {
					elemin.value = Options.DashboardOptions.DefaultSacrificeMin;
					elesec.value = Options.DashboardOptions.DefaultSacrificeSec;
					t.SetRitualLength(elesec);
				}
			}
			var elem = ById('btRitualAmount');
			if (parseInt(elem.value) > t.TotalTroops) {
				elem.value = t.TotalTroops;
				t.SetRitualLength(elem);
			}
		}
	},

	SetMaxTroops : function () {
		var t = Dashboard;
		var elem = ById('btRitualAmount');
		elem.value = t.SacSettings.max_amount;
		if (elem.value > t.TotalTroops) {elem.value = t.TotalTroops;}
		if ((elem.value > Options.DashboardOptions.SacrificeLimit) && (parseIntNan(Options.DashboardOptions.SacrificeLimit) > 0)) {elem.value = Options.DashboardOptions.SacrificeLimit;}
		t.SetRitualLength(elem);
	},

	SetRitualLength : function (sel) {
		var t = Dashboard;
		sel.value = parseInt(sel.value);
		if (isNaN(sel.value)) sel.value = 0;

		var trp, min, sec;

		if (sel.id == 'btRitualMinutes') {
			min = parseIntNan(sel.value);

			if (isNaN(ById('btRitualSeconds').value)) sec = 0;
			else sec = parseIntNan(ById('btRitualSeconds').value);

			trp = Math.round((parseIntNan(min * 60) + sec) * (t.SacSpeed / t.SacSpeedBuff)); // troops
		}

		if (sel.id == 'btRitualSeconds') {
			sec = parseIntNan(sel.value);

			if (isNaN(ById('btRitualMinutes').value)) min = 0;
			else min = parseIntNan(ById('btRitualMinutes').value);

			min += (parseIntNan( sec / 60 ));
			sec = sec % 60;

			trp = Math.round(((min * 60)+sec) * (t.SacSpeed / t.SacSpeedBuff)); // troops
		}

		if (sel.id == 'btRitualAmount') {
			trp = parseIntNan(sel.value);
		}

		if (trp > t.TotalTroops) {trp = t.TotalTroops;}
		if (trp > parseInt(t.SacSettings.max_amount)) {trp = t.SacSettings.max_amount;}
		if ((trp > Options.DashboardOptions.SacrificeLimit) && (parseIntNan(Options.DashboardOptions.SacrificeLimit) > 0)) {trp = Options.DashboardOptions.SacrificeLimit;}

		sec = parseIntNan(trp / (t.SacSpeed / t.SacSpeedBuff), 10); // seconds
		min = parseIntNan( sec / 60 );
		sec = sec % 60;

		ById('btRitualAmount').value = BlankifZero(trp);
		ById('btRitualMinutes').value = BlankifZero(min);
		ById('btRitualSeconds').value = BlankifZero(sec);
	},

	setTroopMessage : function (msg) {
		var t = Dashboard;
		ById('btTroopMsg').innerHTML = msg;
	},

	ToggleDefenceMode : function (cityId) {
		var t = Dashboard;
		if (!SelectiveDefending) return;
		jQuery('#btCityStatus').addClass("disabled");
		jQuery('#btCityStatus2').addClass("disabled");
		ResetHTMLRegister('DASH','btStatusCell');
		t.serverwait = true;

		var state = 1;
		if (Seed.citystats["city" + cityId].gate != 0)
			state = 0;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.state = state;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/gate.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				t.serverwait = false;
				if (rslt.ok) {
					Seed.citystats["city" + cityId].gate = state;
					if (t.CurrentCityId==cityId) {t.PaintCityInfo(cityId);}
				}
				jQuery('#btCityStatus').removeClass("disabled");
				jQuery('#btCityStatus2').removeClass("disabled");
			},
			onFailure: function () { t.serverwait = false; jQuery('#btCityStatus').removeClass("disabled"); jQuery('#btCityStatus2').removeClass("disabled"); }
		});
	},

	SelectDefenders : function (sel,def) {
		var t = Dashboard;
		if (!SelectiveDefending) return;
		var MoveArray = [];
		if (!def) { // switch to sanctuary
			if (sel == "A") { // All
				for (var ui in uW.cm.UNIT_TYPES){
					var i = uW.cm.UNIT_TYPES[ui];
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "I") { // Infantry
				for(c=0; c<Infantry.length; c++){
					var i = parseInt(Infantry[c]);
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "R") { // Ranged
				for(c=0; c<Ranged.length; c++){
					var i = parseInt(Ranged[c]);
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "H") { // Horsed
				for(c=0; c<Horsed.length; c++){
					var i = parseInt(Horsed[c]);
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "S") { // Siege
				for(c=0; c<Siege.length; c++){
					var i = parseInt(Siege[c]);
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "P") { // SpellCaster
				for(c=0; c<SpellCaster.length; c++){
					var i = parseInt(SpellCaster[c]);
					MoveArray[i] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (parseIntNan(sel) != 0) { // Troop Identifier
				MoveArray[sel] = 0 - parseIntNan(Seed.defunits['city' + t.CurrentCityId]['unt'+sel]);
			}
		}
		else { // switch to defend
			if (sel == "A") { // All
				for (var ui in uW.cm.UNIT_TYPES){
					i = uW.cm.UNIT_TYPES[ui];
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "I") { // Infantry
				for(c=0; c<Infantry.length; c++){
					var i = parseInt(Infantry[c]);
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "R") { // Ranged
				for(c=0; c<Ranged.length; c++){
					var i = parseInt(Ranged[c]);
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "H") { // Horsed
				for(c=0; c<Horsed.length; c++){
					var i = parseInt(Horsed[c]);
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "S") { // Siege
				for(c=0; c<Siege.length; c++){
					var i = parseInt(Siege[c]);
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (sel == "P") { // SpellCaster
				for(c=0; c<SpellCaster.length; c++){
					var i = parseInt(SpellCaster[c]);
					MoveArray[i] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+i]);
				}
			}
			if (parseIntNan(sel) != 0) { // Troop Identifier
				MoveArray[sel] = parseIntNan(Seed.units['city' + t.CurrentCityId]['unt'+sel]);
			}
		}
		t.ChangeDefendingTroops (t.CurrentCityId, MoveArray, false);
	},

	ChangeDefendingTroops : function (cityId, MoveArray, Replace, notify) {
		var t = Dashboard;
		t.setTroopMessage(tx('Sending Request')+'...');
		var params = uW.Object.clone(uW.g_ajaxparams)
		params.cid = cityId;
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			if (Replace) { params["u"+i] = parseIntNan(MoveArray[i]); }
			else { params["u"+i] = parseIntNan(Seed.defunits['city' + cityId]['unt'+i]) + parseIntNan(MoveArray[i]); }
		}

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/cityDefenseSet.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var unitsarr = [];
					for (var j in uW.unitcost)
						unitsarr.push(0);
					for (var i = 0; i <= unitsarr.length; i++)
						if (params["u"+i])
							unitsarr[i] = params["u"+i];
					if (rslt.def != null) {
						var unitlist = uW.seed.defunits["city" + cityId];
						jQuery.each (rslt.def, function (key, val) {
							var key1 = key.replace ("u", "unt");
							unitlist[key1] = val
						})
					}
					if (rslt.res != null) {
						var unitlist = uW.seed.units["city" + cityId];
						jQuery.each (rslt.res, function(key, val) {
							var key1 = key.replace("u", "unt");
							unitlist[key1] = val
						})
					}
					t.setTroopMessage('&nbsp;');
					t.SelectDefTroopType (ById("btDefendTroops"));
					if (notify != null) { notify();}
					else {
						if (cityId==t.CurrentCityId) {
							t.PaintCityInfo(cityId);
						}
					}
				}
				else { // error handling
					if (rslt.msg) { t.setTroopMessage('<span style="color:#f00">'+rslt.msg+'</span>'); }
					else { t.setTroopMessage('<span style="color:#f00">'+tx('Error setting defending troops')+'</span>'); }
				}
				jQuery('#btAddDefendButton').removeClass("disabled");
				jQuery('#btAddPresetButton').removeClass("disabled");
				jQuery('#btReplacePresetButton').removeClass("disabled");
			},
			onFailure: function () { // error handling
				t.setTroopMessage('<span style="color:#f00">Server connection failed.</span>');
				jQuery('#btAddDefendButton').removeClass("disabled");
				jQuery('#btAddPresetButton').removeClass("disabled");
				jQuery('#btReplacePresetButton').removeClass("disabled");
			}
		},true); //no retry
	},

	SelectDefTroopType : function (sel) {
		var t = Dashboard;
		if ((sel.value == 0) || (sel.value == "")) {
			ById('btTotalDefTroops').innerHTML = "";
			ById('btMaxDefTroops').innerHTML = "";
			t.TotalSanctuaryTroops = 0;
			return false
		} else {
			t.TotalSanctuaryTroops = parseIntNan(Seed.units['city' + Seed.cities[Options.DashboardOptions.CurrentCity][0]]['unt'+sel.value]);
			ById('btTotalDefTroops').innerHTML = '&nbsp;/&nbsp;'+addCommas(t.TotalSanctuaryTroops);
			ById('btMaxDefTroops').innerHTML = '<a id="btMaxDefButton" onclick="btSetMaxDefTroops()"><span style="font-size:9px;" align="center">max</span></a>';
			// set default defender amount
			var elem = ById('btDefendAmount');
			if ((elem.value == 0) || (elem.value == "")) { elem.value = Options.DashboardOptions.DefaultDefenceNum; }
			if (parseInt(elem.value) > t.TotalSanctuaryTroops) {
				elem.value = t.TotalSanctuaryTroops;
			}
		}
	},

	SetMaxDefTroops : function () {
		var t = Dashboard;
		var elem = ById('btDefendAmount');
		elem.value = t.TotalSanctuaryTroops;
	},

	AddDefenders : function () {
		var t = Dashboard;
		var MoveArray = [];
		var TT = ById('btDefendTroops');
		var AM = ById('btDefendAmount');

		if (!TT.value || (TT.value == 0)) {t.setTroopMessage('<span style="color:#f00">'+tx('Please select troop type')+'</span>');return;}
		if (!AM.value || (AM.value == 0)) {t.setTroopMessage('<span style="color:#f00">'+tx('Please enter a number of troops')+'</span>');return;}
		if (AM.value > t.TotalSanctuaryTroops) {t.setTroopMessage('<span style="color:#f00">'+tx('You do not have enough troops')+'</span>');return;}

		jQuery('#btAddDefendButton').addClass("disabled");

		MoveArray[TT.value] = AM.value;
		t.ChangeDefendingTroops (t.CurrentCityId, MoveArray, false);
	},

	NewDefPreset : function () {
		var t = Dashboard;
		if (t.ExpandDefPreset) return;
		ById('btDefendPreset').value = 0;
		/* Initialise Edit fields */

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			ById('btPresetTroop'+i).value = "";
		}
		ById('btDefPresetName').value = 'Defensive Preset #'+t.NextPresetNumber;

		t.ExpandDefPreset = true;
		jQuery('#btNewDefPreset').addClass("disabled");
		jQuery('#btChgDefPreset').addClass("disabled");
		jQuery('#btDelDefPreset').addClass("disabled");
		jQuery('#DefEditPresetRow').removeClass("divHide");
	},

	ChgDefPreset : function () {
		var t = Dashboard;
		if (t.ExpandDefPreset) return;

		var PN = ById('btDefendPreset');
		if (!PN.value || (PN.value == 0) || (PN.value.substr(0,1) == 'T')) {return;}

		/* Load preset details into edit fields */

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (Options.DashboardOptions.DefPresets[PN.value][i]) { ById('btPresetTroop'+i).value = Options.DashboardOptions.DefPresets[PN.value][i]; }
			else { ById('btPresetTroop'+i).value = ""; }
		}
		ById('btDefPresetName').value = Options.DashboardOptions.DefPresets[PN.value][0];

		t.ExpandDefPreset = true;
		jQuery('#btNewDefPreset').addClass("disabled");
		jQuery('#btChgDefPreset').addClass("disabled");
		jQuery('#btDelDefPreset').removeClass("disabled");
		jQuery('#DefEditPresetRow').removeClass("divHide");
	},

	SetCurrentPreset : function () {
		var t = Dashboard;
		/* Initialise Edit fields to current values */

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (Seed.defunits["city" + t.CurrentCityId]['unt'+i] && (!isNaN(Seed.defunits["city" + t.CurrentCityId]['unt'+i])) && (parseIntNan(Seed.defunits["city" + t.CurrentCityId]['unt'+i]) != 0)) {
				ById('btPresetTroop'+i).value = Seed.defunits["city" + t.CurrentCityId]['unt'+i];
			}
			else {
				ById('btPresetTroop'+i).value = "";
			}
		}
	},

	SaveDefPreset : function () {
		var t = Dashboard;
		var PN = ById('btDefendPreset');
		if (PN.value.substr(0,1) == 'T') return;
		if (!PN.value || (PN.value == 0)) { SavePN = t.NextPresetNumber; }
		else { SavePN = PN.value; }

		Options.DashboardOptions.DefPresets[SavePN]={};
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			TroopVal = ById('btPresetTroop'+i).value;
			if (!isNaN(TroopVal) && (TroopVal != "")) {
				Options.DashboardOptions.DefPresets[SavePN][i] = TroopVal;
			}
		}

		Options.DashboardOptions.DefPresets[SavePN][0] = ById('btDefPresetName').value;
		saveOptions();
		t.ExpandDefPreset = false;
		t.InitPresetNumber = SavePN;
		t.SetCurrentCity(Seed.cities[t.Curr][0],true);
	},

	CancelDefPreset : function () {
		var t = Dashboard;
		jQuery('#btNewDefPreset').removeClass("disabled");
		var PN = ById('btDefendPreset');
		if (PN.value && (PN.value != 0)) { jQuery('#btChgDefPreset').removeClass("disabled"); }
		jQuery('#DefEditPresetRow').addClass("divHide");
		t.ExpandDefPreset = false;
	},

	DelDefPreset : function () {
		var t = Dashboard;
		var PN = ById('btDefendPreset');
		if (!PN.value || (PN.value == 0) || (PN.value.substr(0,1) == 'T')) return;

		Options.DashboardOptions.DefPresets[PN.value]={};
		delete Options.DashboardOptions.DefPresets[PN.value];
		saveOptions();
		t.ExpandDefPreset = false;
		t.SetCurrentCity(Seed.cities[t.Curr][0],true);
	},

	SelectDefPreset : function (sel) {
		var t = Dashboard;
		t.CancelDefPreset();

		if ((sel.value == 0) || (sel.value == "") || (sel.value.substr(0,1) == 'T')) {
			jQuery('#btChgDefPreset').addClass("disabled");
			return false
		} else {
			jQuery('#btChgDefPreset').removeClass("disabled");
		}
		t.InitPresetNumber = sel.value;
	},

	SetPresetDefenders : function (Replace) {
		var t = Dashboard;
		t.CancelDefPreset();
		var MoveArray = [];
		var PN = ById('btDefendPreset');
		if (!PN.value || (PN.value == 0)) {t.setTroopMessage('<span style="color:#f00">'+tx('Please select a defensive preset')+'</span>');return;}

		jQuery('#btAddPresetButton').addClass("disabled");
		jQuery('#btReplacePresetButton').addClass("disabled");

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (Options.DashboardOptions.DefPresets[PN.value][i]) {
				MoveArray[i] = Options.DashboardOptions.DefPresets[PN.value][i];
			}
		}
		t.ChangeDefendingTroops (t.CurrentCityId, MoveArray, Replace);
	},

	StoreDefendingTroops : function (CityId) {
		var t = Dashboard;
		t.StoreArray[cityId] = [];

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			t.StoreArray[cityId][i] = parseIntNan(Seed.defunits['city' + CityId]['unt'+i]);
		}
	},

	ResetDefendingTroops : function (CityId) {
		var t = Dashboard;
		t.ChangeDefendingTroops (CityId, t.StoreArray[cityId], true);
	},

	SendHome : function (marchId) {
		var t = Dashboard;
		t.setReinError('&nbsp;');
		jQuery('#btSendHome'+marchId).addClass("disabled");
		ResetHTMLRegister('DASH','btReinforceCell')
		var march = {};
		march = Seed.queue_atkinc['m'+ marchId];
		if (!march) { return; }
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.mid = marchId;
		params.cid = march.toCityId;
		params.fromUid = march.fromPlayerId;
		params.fromCid = march.fromCityId;

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/kickoutReinforcements.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok){
					var upkeep = 0;
					for (var ui in uW.cm.UNIT_TYPES){
						i = uW.cm.UNIT_TYPES[ui];
						upkeep += parseInt(march["unit" + i + "Return"]) * parseInt(uW.unitupkeeps[i])
					}
					uW.seed.resources["city"+ march.toCityId].rec1[3] -= upkeep;
					if (parseInt(march.fromPlayerId) == parseInt(uW.tvuid)) {
						var mymarch = uW.seed.queue_atkp["city" + march.fromCityId]["m" + marchId];
						var marchtime = Math.abs(parseInt(mymarch.destinationUnixTime) - parseInt(mymarch.eventUnixTime));
						mymarch.returnUnixTime = unixTime() + marchtime;
						mymarch.marchStatus = 8;
					}
					delete uW.seed.queue_atkinc["m" + marchId];
				} else {
					t.setReinError(rslt.errorMsg);
				}
			},
			onFailure: function () { t.setReinError('AJAX Error'); },
		});
	},

	setReinError : function (msg) {
		var t = Dashboard;
		ById('btReinErr').innerHTML = msg;
	},

	QuickSacrifice : function (tt) {
		var t = Dashboard;
		var sel = ById('btRitualTroops');
		if (!sel) return;
		sel.value = tt;
		t.SelectTroopType(sel);
		t.StartRitual(true);
	},

	StartRitual : function (QS) {
		var t = Dashboard;
		t.setSacError('&nbsp;');
		var unitid = parseInt(ById('btRitualTroops').value);
		var numUnits = parseInt(ById('btRitualAmount').value);

		if (!unitid || (unitid == 0)) {t.setSacError(tx('Please select troop type'));return;}
		if (!numUnits || (numUnits == 0)) {t.setSacError(tx('Please enter a number of troops'));return;}
		if (numUnits > t.TotalTroops) {t.setSacError(tx('You do not have enough troops'));return;}

		jQuery('#btStartRitualButton').addClass("disabled");

		// see if we need to claw back units from defending units

		var clawback = uW.seed.units["city" + t.CurrentCityId]['unt'+unitid] - numUnits;
		if (clawback < 0) {
			var MoveArray = [];
			MoveArray[unitid] = clawback;
			t.ChangeDefendingTroops (t.CurrentCityId, MoveArray, false, function () { t.StartRitual(QS); });
			return;
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = t.CurrentCityId;
		params.type = unitid;
		params.quant = numUnits;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/sacrifice.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					uW.seed.queue_sacr["city" + t.CurrentCityId].push(rslt.queue_sacr);
					uW.seed.units["city" + t.CurrentCityId] = rslt.units;
					uW.seed.cityData.city[t.CurrentCityId].population = rslt.cityData_city.population;
					uW.seed.cityData.city[t.CurrentCityId].populationCap = rslt.cityData_city.populationCap;

					t.setSacError('&nbsp;');
					ById('btRitualTroops').value = 0;
					ById('btTotalTroops').innerHTML = "";
					ById('btMaxTroops').innerHTML = "";
					if (!QS) {
						ById('btRitualAmount').value = "";
						ById('btRitualMinutes').value = "";
						ById('btRitualSeconds').value = "";
					}
				} else {
					t.setSacError(rslt.feedback);
				}
				jQuery('#btStartRitualButton').removeClass("disabled");
			},
			onFailure: function () {
				t.setSacError('AJAX Error');
				jQuery('#btStartRitualButton').removeClass("disabled");
			}
		});
	},

	setSacError : function (msg) {
		var t = Dashboard;
		ById('btSacErr').innerHTML = msg;
	},

	StopRitual : function (sacNo, notify){
		var t = Dashboard;
		jQuery('#btStopRitual'+sacNo).addClass("disabled");
		ResetHTMLRegister('DASH','btSacrificeCell');
		var queue = uW.seed.queue_sacr["city" + t.CurrentCityId][sacNo];
		var params = uW.Object.clone(uW.g_ajaxparams);
		var cityId = t.CurrentCityId;
		params.cid = cityId;
		params.type = queue.unitType;
		params.quant = queue.quantity;
		params.start = queue.start;
		params.eta = queue.eta;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/cancelSacrificing.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					uW.seed.queue_sacr["city" + t.CurrentCityId].splice(sacNo, 1);
					if (t.CurrentCityId==cityId) {t.PaintCityInfo(cityId);}
				}
				jQuery('#btStopRitual'+sacNo).removeClass("disabled");
			},
			onFailure: function () {
				if (notify != null)
					notify('AJAX Error');
				jQuery('#btStopRitual'+sacNo).removeClass("disabled");
			},
		});
	},

	SwitchGuardian : function (elem) {
		var t = Dashboard;

		var type = guardTypes[elem.id.substr(9)-1];
		if (type == t.CurrGuardian) { return; }

		var level = Seed.guardian[Options.DashboardOptions.CurrentCity].cityGuardianLevels[type];
		level = level ? level : 0;
		if (level == 0) { return; }

		t.GuardDelay = 999;
		t.setGuardMessage(tx('Sending Request')+'...');

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = "Guardian";
		params.action = "summon";
		params.cityId = uW.currentcityid;
		params.type = type;

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var g = CM.guardianModalModel.gObj();
					g.summonGuardian = uWCloneInto({
						summonFinishTime: parseInt(rslt.summonFinishTime),
						level: rslt.summonGuardian.cl0,
						type: rslt.summonGuardian.type,
						upgrading: false
					});
					uW.seed.guardian[Options.DashboardOptions.CurrentCity].type = type;
					uW.seed.guardian[Options.DashboardOptions.CurrentCity].level = rslt.summonGuardian.cl0;
					var GType = 0;
					switch(type) {
						case "wood":  GType=50;break;
						case "ore":   GType=51;break;
						case "food":  GType=52;break;
						case "stone": GType=53;break;
					}
					uW.seed.buildings["city"+ uW.currentcityid].pos500[0] = GType;
					// need to delay 8 seconds before allowing again
					t.GuardDelay = 8;
					t.PaintGuardianSelector();
					var time = parseInt(rslt.summonFinishTime) - unixTime();
					setTimeout(function(){
						uW.seed.guardian[Options.DashboardOptions.CurrentCity].type = type;
						uW.seed.buildings["city"+ uW.currentcityid].pos500[0] = GType;
						uW.seed.guardian[Options.DashboardOptions.CurrentCity].level = rslt.summonGuardian.cl0;
					},(time*1000));
				}
				else {
					t.GuardDelay = 0;
					t.PaintGuardianSelector();
					actionLog("Guardian change failed. Error code: " + rslt.error_code,'DASHBOARD');
					t.setGuardMessage('<span style="color:#f00">'+tx('Could not change Guardian')+'.</span>');
				}
			},
			onFailure: function () {
				t.GuardDelay = 0;
				t.PaintGuardianSelector();
				actionLog("Guardian change server error",'DASHBOARD');
				t.setGuardMessage('<span style="color:#f00">'+tx('Server connection failed')+'.</span>');
			}
		},true) // noretry
	},

	SwitchThroneRoom : function (elem) {
		var t = Dashboard;
		clearTimeout(t.presetTimer);
		var NewPreset = parseIntNan(elem.id.substr(6));
		if (NewPreset == Seed.throne.activeSlot) { return; }

		t.ThroneDelay = 999;
		t.setThroneMessage(tx('Sending Request')+'...');

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
		params.action = 'setPreset';
		params.presetId = NewPreset;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch53.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if(rslt.ok){
					// changed the way this works because lots of people having trouble...

					if (ById('throneStatList')) {
						button = '#throneInventoryPreset' + NewPreset;
						CM.ThroneView.clickActivePreset(button);
					}
					else {
						Seed.throne.activeSlot = NewPreset;
						var L = Seed.throne.slotEquip[NewPreset];
						jQuery.each(uW.kocThroneItems, function (M, N) {
							G = jQuery.inArray(N.id, L) > -1;
							if (G) {
								N.isEquipped = true
							} else {
								N.isEquipped = false
							}
						});
						CM.ThroneView.renderThrone();
						CM.ThroneView.renderStats();
						CM.ThroneView.renderInventory(uW.kocThroneItems);
					}

					t.presetFailures = 0;
					// need to delay 5 seconds before allowing again
					t.ThroneDelay = 5;
					t.PaintTRPresets();
				}
				else { // retry?
					t.presetFailures++;
					t.ThroneDelay = 0;
					t.PaintTRPresets();
					actionLog("Preset change failed. Error code: " + rslt.error_code,'DASHBOARD');
					// try again in 2 seconds
					if (t.presetFailures <=3) {
						t.setThroneMessage('<span style="color:#f80">'+tx('Failed to change Throne Room - Retrying')+' ('+t.presetFailures+') ...</span>');
						t.presetTimer = setTimeout( function () {t.SwitchThroneRoom (elem)}, 2000);
					}
					else {
						t.setThroneMessage('<span style="color:#f00">'+tx('Could not change Throne Room')+'.</span>');
						t.presetFailures = 0;
					}
				}
			},
			onFailure: function () {
				t.ThroneDelay = 0;
				t.PaintTRPresets();
				actionLog("Preset change server error",'DASHBOARD');
				t.setThroneMessage('<span style="color:#f00">'+tx('Server connection failed')+'.</span>');
				t.presetFailures = 0;
			},
		},true); // noretry
	},

	PaintTRPresets : function () {
		var t = Dashboard;
		var fontratio = Options.MonitorOptions.MonitorFontSize / 11;
		if (!(ById('btTRWidget')) && !(ById('btTRPresets')) && !(ById('btMonTRPresets')) && !(ById('trpresetopt1'))) { return; }
		if (t.ThroneDelay > 10) { return; }
		if ((ById('btTRPresets')) && !Options.DashboardOptions.TRPresetChange) { ById('btTRPresets').innerHTML = ""; }
		if ((ById('btMonTRPresets')) && !Options.MonitorOptions.MonPresetChange) { ById('btMonTRPresets').innerHTML = ""; }
		if ((ById('btTRWidget')) && !Options.TRWidget) { ById('btTRWidget').innerHTML = ""; }

		var m = '<div class="xtab" style="opacity:0.6; align="center" id=btThroneMsg>&nbsp;</div><TABLE cellspacing=0 cellpadding=0 style="padding-bottom: 10px;" align=center><TR>';
		var n = '<div class="xtab" style="opacity:0.6;font-size:'+Options.MonitorOptions.MonitorFontSize+'px;" align="center" id=btMonThroneMsg>&nbsp;</div><TABLE cellspacing=0 cellpadding=0 style="padding-bottom: 10px;" align=center><TR>';
		var o = '<TABLE cellspacing=0 cellpadding=0 style="padding-bottom: 10px;" align=center><TR>';

		if (Options.DashboardOptions.TRPresetByName) { m+='<td class="xtabBR" align=center>'; }
		if (Options.MonitorOptions.TRMonPresetByName) { n+='<td class="xtabBR" align=center>'; }

		var numrows = Math.ceil(Seed.throne.slotNum/16);
		var perrow = Math.ceil(Seed.throne.slotNum/numrows);
		var nummonrows = Math.ceil(Seed.throne.slotNum/12);
		var permonrow = Math.ceil(Seed.throne.slotNum/nummonrows);

		if (Options.TRFixPresetWidth) {
			perrow = 8;
			permonrow = 8;
		}

		for (var i=1;i<=Seed.throne.slotNum;i++) {
			if (Options.DashboardOptions.TRPresetByName) {
				m+='<div id="trpresetcell'+i+'" class="xtabBR trimg" style="display:inline-block"><a class="inlineButton btButton brown11" id="trlink'+i+'"><span style="width:85px;font-size:10px;" id="trpreset'+i+'"><center>'+(Options.DashboardOptions.TRPresets[i]?Options.DashboardOptions.TRPresets[i].name:'Preset '+i)+'</center></span></a></div>&nbsp;';
			}
			else {
				if ((i % perrow)==1) {
					m+='</tr><TR>';
				}
				m+='<TD id="trpresetcell'+i+'" class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;" id="trlink'+i+'"><div id="trpreset'+i+'" class="presetBut presetButNon"><center>'+i+'</center></div></a></td>';
			}
			if (Options.MonitorOptions.TRMonPresetByName) {
				n+='<div id="tmpresetcell'+i+'" class="xtabBR trimg" style="display:inline-block"><a class="inlineButton btButton brown11" id="tmlink'+i+'"><span style="width:'+Math.floor(85*fontratio)+'px;font-size:'+(Options.MonitorFontSize<10?Options.MonitorFontSize:10)+'px;" id="tmpreset'+i+'"><center>'+(Options.DashboardOptions.TRPresets[i]?Options.DashboardOptions.TRPresets[i].name:'Preset '+i)+'</center></span></a></div>&nbsp;';
			}
			else {
				if ((i % permonrow)==1) {
					n+='</tr><TR>';
				}
				n+='<TD id="tmpresetcell'+i+'" class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;" id="tmlink'+i+'"><div id="tmpreset'+i+'" class="presetBut presetButNon"><center>'+i+'</center></div></a></td>';
			}
			if ((i % perrow)==1 && !Options.ThroneHUD) {
				o+='</tr><TR>';
			}
			o+='<TD id="trwidgetcell'+i+'" class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;" id="twlink'+i+'"><div id="trwidget'+i+'" class="presetBut presetButNon"><center>'+i+'</center></div></a></td>';
		}

		if (Options.TRFixPresetWidth) {
			while ((i % perrow)!=1) {
				if (!Options.DashboardOptions.TRPresetByName) {
					m+='<TD class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;"><div class="presetBut presetButLck"></div></a></td>';
				}
				if (!Options.MonitorOptions.TRMonPresetByName) {
					n+='<TD class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;"><div class="presetBut presetButLck"></div></a></td>';
				}
				o+='<TD class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;"><div class="presetBut presetButLck"></div></a></td>';
				i++;
			}
		}

		if (Options.DashboardOptions.TRPresetByName) { m+='</td>'; }
		if (Options.MonitorOptions.TRMonPresetByName) { n+='</td>'; }
		m += '</tr></table>';
		n += '</tr></table>';
		o += '</tr></table>';
		if ((ById('btTRPresets')) && Options.DashboardOptions.TRPresetChange) { ById('btTRPresets').innerHTML = m; ResetFrameSize('btDash',100,t.DashWidth); }
		if ((ById('btMonTRPresets')) && Options.MonitorOptions.MonPresetChange) { ById('btMonTRPresets').innerHTML = n; ResetFrameSize('btMonitor',Tabs.Monitor.MonHeight,Tabs.Monitor.MonWidth); }
		if ((ById('btTRWidget')) && Options.TRWidget) { ById('btTRWidget').innerHTML = o; WideScreen.CheckChatPosition(); }

		if (t.ThroneDelay != 0) {	t.setThroneMessage('<span style="color:#080">'+tx('Throne Room changed! Change again in')+' '+t.ThroneDelay+' '+tx('secs')+'...</span>'); }
		else { t.setThroneMessage('&nbsp;'); }

		CurrPreset = Seed.throne.activeSlot;
		for (var i=1;i<=Seed.throne.slotNum;i++) {
			if ((ById('btTRPresets')) && Options.DashboardOptions.TRPresetChange) {
				ById('trlink'+i).addEventListener ('click', function(){t.SwitchThroneRoom(this);},false);
				ById('trpreset'+i).addEventListener ('mouseover', function(){t.BuildTRPresetStats(this.id.substring(8));},false);
			}
			if ((ById('btMonTRPresets')) && Options.MonitorOptions.MonPresetChange) {
				ById('tmlink'+i).addEventListener ('click', function(){t.SwitchThroneRoom(this);},false);
				ById('tmpreset'+i).addEventListener ('mouseover', function(){t.BuildTRPresetStats(this.id.substring(8));},false);
			}
			if ((ById('btTRWidget')) && Options.TRWidget) {
				ById('twlink'+i).addEventListener ('click', function(){t.SwitchThroneRoom(this);},false);
				ById('trwidget'+i).addEventListener ('mouseover', function(){t.BuildTRPresetStats(this.id.substring(8));},false);
			}
			if (ById('trpresetopt1')) {
				ById('trpresetopt'+i).addEventListener ('mouseover', function(){t.BuildTRPresetStats(this.id.substring(11));},false);
			}

			if (i==CurrPreset) {
				if ((ById('btTRPresets')) && Options.DashboardOptions.TRPresetChange) {
					if (Options.DashboardOptions.TRPresetByName) { jQuery("#trlink"+i).removeClass("brown11").addClass("blue11"); }
					else { jQuery("#trpreset"+i).removeClass("presetButNon").addClass("presetButSel"); }
				}
				if ((ById('btMonTRPresets')) && Options.MonitorOptions.MonPresetChange) {
					if (Options.MonitorOptions.TRMonPresetByName) { jQuery("#tmlink"+i).removeClass("brown11").addClass("blue11"); }
					else { jQuery("#tmpreset"+i).removeClass("presetButNon").addClass("presetButSel"); }
				}
				if ((ById('btTRWidget')) && Options.TRWidget) {
					jQuery("#trwidget"+i).removeClass("presetButNon").addClass("presetButSel");
				}
				t.BuildTRPresetStats(i);
			}
		}
	},

	BuildTRPresetStats : function (slot){
		var t = Dashboard;
		var StatEffects = [];
		var m="";
		for (var k in CM.thronestats.effects) StatEffects[k] = 0;
		for (var k in uW.kocThroneItems){
			y = uW.kocThroneItems[k];
			for (var ii=0;ii<Seed.throne.slotEquip[slot].length;ii++) {
				if (Seed.throne.slotEquip[slot][ii] == y.id) {
					for (var O in y["effects"]) {
						var i = +(O.split("slot")[1]);
						id = y["effects"]["slot"+i]["id"];
						tier = parseInt(y["effects"]["slot"+i]["tier"]);
						level = y["level"];
						p = CM.thronestats.tiers[id][tier];
						while (!p && (tier > 0)) { tier--; p = CM.thronestats.tiers[id][tier]; }
						if (!p) continue; // can't find stats for tier
						var base = +p.base;
						var growth = +p.growth;
						if (y["effects"]["slot"+i].fromJewel && (level > uW.cm.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality])) {
							level = uW.cm.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality]
						}
						Current = Number(base + ((level * level + level) * growth * 0.5));
						if (i<=parseInt(y.quality)) StatEffects[id] += Current;
					}
				}
			}
		}

		var presetname = (Options.DashboardOptions.TRPresets[slot]?Options.DashboardOptions.TRPresets[slot].name:'Preset '+slot);

		if (ById('trpresetopt'+slot)) { createToolTip(presetname,ById('trpresetopt'+slot),StatEffects.slice()); }
		if ((ById('btTRPresets')) && Options.DashboardOptions.TRPresetChange) { createToolTip(presetname,ById('trpresetcell'+slot),StatEffects.slice()); }
		if ((ById('btMonTRPresets')) && Options.MonitorOptions.MonPresetChange) { createToolTip(presetname,ById('tmpresetcell'+slot),StatEffects.slice()); }
		if ((ById('btTRWidget')) && Options.TRWidget) { createToolTip(presetname,ById('trwidgetcell'+slot),StatEffects.slice()); }
	},

	setThroneMessage : function (msg) {
		var t = Dashboard;
		if (ById('btThroneMsg') && Options.DashboardOptions.TRPresetChange) { ById('btThroneMsg').innerHTML = msg; }
		if (ById('btMonThroneMsg') && Options.MonitorOptions.MonPresetChange) { ById('btMonThroneMsg').innerHTML = msg; }
	},

	setGuardMessage : function (msg) {
		var t = Dashboard;
		if (popDash) {ById('btGuardMsg').innerHTML = msg; }
	},

	setChampMessage : function (msg) {
		var t = Dashboard;
		if (popDash && ById('btChampMsg')) {ById('btChampMsg').innerHTML = msg; }
	},

	CancelMarshall : function() {
		var t = Dashboard;
		t.ExpandMarshall = false;
		t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
	},

	ChangeMarshall : function () {
		var t = Dashboard;
		t.ExpandMarshall = true;
		t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
	},

	SetMarshall : function () {
		var t = Dashboard;
		jQuery('#btSetMarshall').addClass("disabled");
		var pos = '13';
		var kid = ById('btKnightList').value;
		if (kid == "") {kid = "0";}
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pos = pos;
		params.kid = kid;
		params.cid = uW.currentcityid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/assignknight.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				jQuery('#btSetMarshall').removeClass("disabled");
				if (rslt.ok) {
					if (kid == 0) {
						uW.seed.leaders["city" + uW.currentcityid].combatKnightId = "0";
					} else {
						uW.seed.leaders["city" + uW.currentcityid].combatKnightId = kid.toString();
						t.ExpandMarshall = false;
						t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
					}
				}
			},
			onFailure : function () { jQuery('#btSetMarshall').removeClass("disabled"); }
		},true); // noretry
	},

	BoostMarshall : function () {
		var t = Dashboard;
		jQuery('#btBoostMarshall').addClass("disabled");
		var item = 'i221';
		var kid = Seed.leaders["city" + uW.currentcityid].combatKnightId;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.iid = item.substring(1);
		params.cid = uW.currentcityid;
		params.kid = kid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/boostKnight.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				jQuery('#btBoostMarshall').removeClass("disabled");
				if (rslt.ok) {
					uW.seed.knights["city" + uW.currentcityid]["knt" + kid].combatBoostExpireUnixtime = rslt.expiration.toString();
					uW.seed.items[item] = parseInt(uW.seed.items[item]) - 1;
					uW.ksoItems[item.substring(1)].subtract();
					uW.cm.MixPanelTracker.track("item_use", {
						item : uW.itemlist[item].name,
						usr_gen : Seed.player.g,
						usr_byr : Seed.player.y,
						usr_ttl : uW.titlenames[Seed.player.title],
						distinct_id : uW.tvuid
					})
					t.PaintCityInfo(Seed.cities[Options.CurrentCity][0]);
				}
			},
			onFailure : function () { jQuery('#btBoostMarshall').removeClass("disabled"); }
		},true); // noretry
	},

	CancelChampion : function () {
		var t = Dashboard;
		t.ExpandChampion = false;
		t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
	},

	ChangeChampion : function () {
		var t = Dashboard;
		t.ExpandChampion = true;
		t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
	},

	FreeChampion : function (champId,ButtonClick) {
		var t = Dashboard;
		t.setChampMessage(tx('Sending Request')+'...');
		if (ButtonClick) jQuery('#btFreeChampion').addClass("disabled");
		t.AssignChampion(champId, 0);
	},

	SetChampion : function (champId,ButtonClick) {
		var t = Dashboard;
		t.setChampMessage(tx('Sending Request')+'...');
		if (ButtonClick) jQuery('#btSetChampion'+champId).addClass("disabled");
		t.AssignChampion(champId, uW.currentcityid);
	},

	AssignChampion : function (champId,cityId) {
		var t = Dashboard;

		var cindex = -1;
		var oldcity = 0;
		for (var y in Seed.champion.champions) {
			chkchamp = Seed.champion.champions[y];
			if (chkchamp.championId) {
				if (chkchamp.championId == champId) {
					cindex = y;
					oldcity = chkchamp.assignedCity;
					break;
				}
			}
		}
		if (cindex<0) return;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.champid = champId;
		params.cid0 = oldcity;
		params.cid = cityId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/assignChampion.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					if (cityId!=0) {
						for (var c = 0; c < Seed.champion.champions.length; c++) {
							if (Seed.champion.champions[c].assignedCity == cityId) {
								Seed.champion.champions[c].assignedCity = 0;
							}
						}
					}
					Seed.champion.champions[cindex].assignedCity = cityId;
					SetChampionIcon();
					t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);
				}
				else {
					t.setChampMessage(tx('Error Assigning Champion')+'!');
				}
			},
			onFailure : function () { t.setChampMessage('AJAX Error!'); }
		},true); // noretry
	},

	PaintChampionSelector : function (cityId) {
		var t = Dashboard;
		if (!popDash) { return; }
		var Curr = Options.DashboardOptions.CurrentCity;
		var m = '<TABLE cellspacing=0 cellpadding=0><TR>';
		var allowclick = true;
		for (var y in Seed.champion.champions) {
			chkchamp = Seed.champion.champions[y];
			if (chkchamp.championId) {
				if (chkchamp.assignedCity && chkchamp.assignedCity == cityId && chkchamp.status == '10') {
					allowclick = false;
					break;
				}
			}
		}
		for (var y in Seed.champion.champions) {
			chkchamp = Seed.champion.champions[y];
			if (chkchamp.championId) {
				var outlineclass = 'champButNon';
				var opacity = '0.6';
				var onclick = 'onclick="btSetChampion('+chkchamp.championId+',false)"';
				if (chkchamp.assignedCity && chkchamp.assignedCity == cityId) {
					outlineclass = 'champButSel';
					opacity = '1.0';
					onclick = 'onclick="btFreeChampion('+chkchamp.championId+',false)"';
					if (chkchamp.status == '10') {
						outlineclass = 'champButMarch';
					}
				}
				if (chkchamp.status == '10' || !allowclick) {
					onclick = '';
				}
				m+='<TD id="ChampStatsBtn'+chkchamp.championId+'td" class="xtab trimg"><a style="text-decoration:none;" id="champlink'+chkchamp.championId+'"><div id="champimg'+chkchamp.championId+'" class="champBut '+outlineclass+'"><img style="vertical-align:text-top;width:31px;height:33px;opacity:'+opacity+';" id="ChampStatsBtn'+chkchamp.championId+'" '+onclick+' onMouseover="btCreateChampionPopUp(this,'+(chkchamp.assignedCity?chkchamp.assignedCity:0)+',true,'+chkchamp.championId+',false,true);" src="'+ChampImagePrefix+chkchamp.avatarId+ChampImageSuffix+'"></div></a></td>';
			}
		}
		m += '<td class="xtab" style="opacity:0.6; align="left" id=btChampMsg>&nbsp;</td></tr></table>';
		return m;
	},

	PaintGuardianSelector : function () {
		var t = Dashboard;
		if (!popDash) { return; }
		if (t.GuardDelay > 10) { return; }

		var Curr = Options.DashboardOptions.CurrentCity;

		var y_offset =   {wood: " 47% ",	ore: " 72.5% ",	food: " 59.5% ", stone: " 85% "};
		var x_offset =   {plate: 20, junior: 134, teenager: 248, adult: 362, adult2: 476,	adult3: 590};
		var x_by_level = {0: x_offset.plate, 1: x_offset.junior, 2: x_offset.junior, 3: x_offset.junior, 4: x_offset.teenager, 5: x_offset.teenager, 6: x_offset.adult, 7: x_offset.adult, 8: x_offset.adult, 9: x_offset.adult, 10: x_offset.adult2, 11: x_offset.adult3, 12: x_offset.adult3, 13: x_offset.adult3, 14: x_offset.adult3, 15: x_offset.adult3};

		var m = '<TABLE cellspacing=0 cellpadding=0><TR>';

		for (var i=1;i<=4;i++) {
			var level = Seed.guardian[Curr].cityGuardianLevels[guardTypes[i-1]];
			level = level ? level : "";
			m+='<TD id="guardcell'+i+'" class="xtab tooldesc"><a style="text-decoration:none;" id="guardlink'+i+'"><div id="guardimg'+i+'" class="guardBut guardButNon trimg"><center>'+level+'</center></div></a><span class="tooltip" style="white-space: pre-line; word-wrap: break-word;">'+uW.g_js_strings.guardian["tooltipSummon_" + guardTypes[i-1]]+'</span></td>';
		}
		m += '<td class="xtab" style="opacity:0.6; align="left" id=btGuardMsg>&nbsp;</td></tr></table>';
		ById('btGuardianSelector').innerHTML = m;

		if (t.GuardDelay != 0) {	t.setGuardMessage('<span style="color:#080">'+tx('Guardian changed')+'!<br>'+tx('Change again in')+' '+t.GuardDelay+' '+tx('secs')+'...</span>'); }
		else { t.setGuardMessage('&nbsp;'); }

		t.CurrGuardian = Seed.guardian[Curr].type;
		for (var i=1;i<=4;i++) {
			/* show correct portion of image */
			var level = Seed.guardian[Curr].cityGuardianLevels[guardTypes[i-1]];
			level = level ? level : 0;
			var bg_offset =  x_by_level[level]/776*100 + "% " + y_offset[guardTypes[i-1]];
			jQuery("#guardimg"+i).css('background-position', bg_offset);

			if (popDash) {
				ById('guardlink'+i).addEventListener ('click', function(){t.SwitchGuardian(this);},false);
			}
			if ((guardTypes[i-1]==(t.CurrGuardian)) && (Seed.guardian[Curr]['level'] != 0)) {
				jQuery("#guardimg"+i).removeClass("guardButNon").addClass("guardButSel");
			}
		}
	},

	Recall : function (marchId,cityview) {
		var t = Dashboard;
		t.setOutError('&nbsp;',cityview);

		var ajaxtype = 'undefend';
		var params = uW.Object.clone(uW.g_ajaxparams);
		for (var k in out) {
			if (out[k].marchId == marchId) {
				params.cid = out[k].marchCityId;
				if (out[k].marchStatus != 2) {
					ajaxtype = 'cancelMarch';
				}
				break;
			}
		}
		params.mid = marchId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/"+ajaxtype+".php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok){
					var march = uW.seed.queue_atkp["city" + params.cid]["m" + params.mid];
					var marchtime = parseInt(march.returnUnixTime) - parseInt(march.destinationUnixTime);
					var ut = uW.unixtime();
					if (Seed.playerEffects.returnExpire > ut) {	marchtime *= 0.5 }
					march.destinationUnixTime = rslt.destinationUnixTime || ut;
					march.returnUnixTime = Math.floor(rslt.returnUnixTime || ut + marchtime * rslt.returnMultiplier);
					march.marchStatus = 8;
					if (ajaxtype == 'cancelMarch') {
						for (var j in uW.cm.UNIT_TYPES) {
							j = uW.cm.UNIT_TYPES[j];
							Seed.queue_atkp["city" + params.cid]["m" + params.mid]["unit" + j + "Return"] = parseInt(Seed.queue_atkp["city" + params.cid]["m" + params.mid]["unit" + j + "Count"])
						}
					}
					t.setOutError('March Recalled',cityview);
				}
				else {
					if (rslt.error_code == 253)
						t.setOutError(uW.g_js_strings.recall.error,cityview);
					else
						t.setOutError(tx('Unable to recall march'),cityview);
				}
			},
			onFailure: function () { t.setOutError(tx('Unable to recall march'),cityview); },
		});
	},

	setOutError : function (msg,cityview) {
		var t = Dashboard;
		var elem = ById('btOutErr');
		if (cityview)
			elem = ById('btCityOutErr');
		if (elem)
			elem.innerHTML = msg;
	},

	ShowHideSection : function (div,tf) {
		var t = Dashboard;
		var dh = ById(div+'Header');
		if (dh) {
			if (tf && jQuery('#'+div+'Header').hasClass('divHide')) { jQuery('#'+div+'Header').removeClass('divHide'); t.ResizeFrame = true; }
			if (!tf && !jQuery('#'+div+'Header').hasClass('divHide')) { jQuery('#'+div+'Header').addClass('divHide'); t.ResizeFrame = true;}
		}
	},

	ShowHideRow : function (div,tf) {
		var t = Dashboard;
		var dh = ById(div);
		if (dh) {
			if (tf && jQuery('#'+div).hasClass('divHide')) { jQuery('#'+div).removeClass('divHide'); t.ResizeFrame = true; }
			if (!tf && !jQuery('#'+div).hasClass('divHide')) { jQuery('#'+div).addClass('divHide'); t.ResizeFrame = true; }
		}
	},

	ForceUpdateSeed : function () {
		var t = Dashboard;
		if (uW.g_update_seed_ajax_do && (t.ForceTries < 10)) { // refresh seed is occurring? But we need to make sure this runs, so delay for 1 second  and try up to 10 times ...
			t.ForceTries = t.ForceTries + 1;
			logit('force update seed - waiting for server to be ready ('+t.ForceTries+')');
			setTimeout(function() {t.ForceUpdateSeed();}, 1000);
		}
		logit('force update seed - request sent to server');
		uW.g_update_seed_ajax_force = true;
		setTimeout(function() {uW.update_seed_ajax(true, function () {logit('force update seed - response received from server');t.PaintCityInfo(Seed.cities[Options.DashboardOptions.CurrentCity][0]);if (Options.DashboardOptions.ReplaceDefendingTroops[Cities.byID[t.AttackedCity].idx]) t.ResetDefendingTroops(t.AttackedCity);},false);}, 250);
	},

	ToggleAutoRefresh : function () {
		var t = Dashboard;
		Options.DashboardOptions.RefreshSeed = !Options.DashboardOptions.RefreshSeed;
		if (Options.DashboardOptions.RefreshSeed) {
			jQuery('#btRefreshSeed').addClass("disabled");
			jQuery('#btAutoRefresh').addClass("red14");
			jQuery('#btAutoRefresh').removeClass("blue14");
			ById('btAutoRefresh').innerHTML = '<span style="width:30px;display:inline-block;text-align:center;">Off</span>';
		}
		else {
			jQuery('#btRefreshSeed').removeClass("disabled");
			jQuery('#btAutoRefresh').removeClass("red14");
			jQuery('#btAutoRefresh').addClass("blue14");
			ById('btAutoRefresh').innerHTML = '<span style="width:30px;display:inline-block;text-align:center;">Auto</span>';
		}
		saveOptions();
	},

	UpdatePresetLabel: function (elem,entry) {
		var t = Dashboard;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		if (!Options.DashboardOptions.TRPresets[entry]) { Options.DashboardOptions.TRPresets[entry] = {};}
		if (elem.value == "") { elem.value = 'Preset '+entry; }

		Options.DashboardOptions.TRPresets[entry].name = elem.value;
		saveOptions();
		t.PaintTRPresets();
	},

	CheckDefaultRitual : function (sel) {
		sel.value = parseInt(sel.value);
		if (isNaN(sel.value)) sel.value = 0;

		var min, sec;

		if (sel.id == 'btDefaultRitualMinutes') {
			min = parseIntNan(sel.value);

			if (isNaN(ById('btDefaultRitualSeconds').value)) sec = 0;
			else sec = parseIntNan(ById('btDefaultRitualSeconds').value);
		}

		if (sel.id == 'btDefaultRitualSeconds') {
			sec = parseIntNan(sel.value);

			if (isNaN(ById('btDefaultRitualMinutes').value)) min = 0;
			else min = parseIntNan(ById('btDefaultRitualMinutes').value);

			min += (parseIntNan( sec / 60 ));
			sec = sec % 60;
		}
		ById('btDefaultRitualMinutes').value = BlankifZero(min);
		ById('btDefaultRitualSeconds').value = BlankifZero(sec);
		Options.DashboardOptions.DefaultSacrificeMin = BlankifZero(min);
		Options.DashboardOptions.DefaultSacrificeSec = BlankifZero(sec);
		saveOptions();
	},
}

/************************************ Might Breakdown Popup ***********************************************/

function ShowMightBreakdown () {

	function PlayerCourtCallBack (rslt) {

		var MightPop = null;
		var m = '<table class=xtab align=center>';

		if (rslt.playerInfo) {
			m += '<tr><TD>'+uW.g_js_strings.commonstr.might+':&nbsp;</td><TD><b>' + addCommas(Math.round(rslt.playerInfo.might)) + '</b></td></tr>';
			m += '<tr><TD>'+tx('Classic Might')+':&nbsp;</td><TD><b>' + addCommas(Math.round(rslt.playerInfo.mightClassic)) + '</b></td></tr>';
			m += '<tr><TD>'+tx('Glory Might')+':&nbsp;</td><TD><b>' + addCommas(Math.round(rslt.playerInfo.mightGlory)) + '</b></td></tr>';
		}
		else {
			m += '<tr><td>'+(rslt.errorMsg||tx('No Data'))+'</td></tr>';
		}
		m += '</table>'

		// cities

		var rownum = 1;

		m += '<div class="divHeader" align="center">'+tx('CITIES')+'</div>';
		m += '<div><br>';

		var u = '<TABLE align=center cellpadding=1 cellspacing=0>\
			<TR align=center><TD class=xtab><B></B></td><TD class=xtabHL colspan=4><B>'+tx('BUILDINGS')+'</b></td><TD class=xtabHL colspan=3><B>'+tx('TROOPS')+'</b></td><TD class=xtabHL><B>'+tx('TOTAL')+'</b></td></tr>\
			<TR valign=bottom align=right><TD class=xtab></td><TD class=xtabHL>'+uW.g_js_strings.commonstr.buildings+'</td><TD class=xtabH>'+tx('Fortifications')+'</td><TD class=xtabH>'+tx('Def. Tower')+'</td><TD class=xtabH>'+tx('Redoubt Tower')+'</td>\
			<TD class=xtabHL>'+tx('Sanctuary')+'</td><TD class=xtabH>'+tx('Defending')+'</td><TD class=xtabH>'+tx('Marching')+'</td><TD class=xtabHL>&nbsp;</td></tr>\
			<TR style="height:1px;"><TD style="padding:0px; spacing:0px; height:1px; border-color:black; border-width: 1px; border-style: none none solid none" colspan=9></td></tr>';

		var mightarray = [0,0,0,0,0,0,0,0];
		var totalarray = [0,0,0,0,0,0,0,0];

		for (var i = 1; i <= Cities.numCities; i++) {
			var cityId = Cities.cities[i-1].id;
			var afactor = 1;
			if (Seed.cityData.city[cityId].isPrestigeCity) {
				var l = Seed.cityData.city[cityId].prestigeInfo.prestigeLevel;
				if (l > 0) { afactor = Math.pow(CM.PrestigeModel.buildingBoost, l); }
			}
			if (++rownum % 2)
				rsty = 'evenRow';
			else
				rsty = 'oddRow';

			mightarray = [0,0,0,0,0,0,0,0];

			for (var y in Seed.buildings['city'+cityId]) {
				var b = Seed.buildings['city'+cityId][y];
				var btype = parseInt(b[0]);
				var blvl = parseInt(b[1]);
				var bpos = parseInt(b[2]);
				var might = 0;
				if (uW.buildingmight[btype]) {
					for (var l in uW.buildingmight[btype]) {
						if (l<blvl) {
							might += Math.ceil(uW.buildingmight[btype][l] * afactor);
						}
					}
				}

				if (bpos==99) {
					mightarray[2] += might;
				}
				else {
					if (bpos==98) {
						mightarray[3] += might;
					}
					else {
						mightarray[0] += might;
					}
				}
				mightarray[7] += might;
			}

			for (var tt in Seed.fortifications['city'+cityId]) {
				var might = parseIntNan(Seed.fortifications['city'+cityId][tt]) * parseInt(fortmight["f"+tt.split("fort")[1]]);
				mightarray[1] += might;
				mightarray[7] += might;
			}
			for (var tt in Seed.units['city'+cityId]) {
				var might = parseIntNan(Seed.units['city'+cityId][tt]) * parseInt(uW.unitmight[tt]);
				mightarray[4] += might;
				mightarray[7] += might;
			}
			if (SelectiveDefending) {
				for (var tt in Seed.defunits['city'+cityId]) {
					var might = parseIntNan(Seed.defunits['city'+cityId][tt]) * parseInt(uW.unitmight[tt]);
					mightarray[5] += might;
					mightarray[7] += might;
				}
			}
			for (var k in Seed.queue_atkp['city'+cityId]) { // each march from city
				var march = local_atkp[k];
				if (typeof (march) == 'object') {
					for (var ui in uW.cm.UNIT_TYPES) {
						ii = uW.cm.UNIT_TYPES[ui];
						var might = parseIntNan(march['unit' + ii + 'Count']) * parseInt(uW.unitmight['unt' + ii]);
						mightarray[6] += might;
						mightarray[7] += might;
					}
				}
			}

			u += '<TR class="'+rsty+'" align=right><TD class=xtab align=left><B>' + Cities.cities[i-1].name.substring(0, 12) + '</b></td><TD class=xtabL>' + addCommas(mightarray[0]) + '</td><TD class=xtab>' + addCommas(mightarray[1]) + '</td>\
				<TD class=xtab>' + addCommas(mightarray[2]) + '</td><TD class=xtab>' + addCommas(mightarray[3]) + '</td><TD class=xtabL>' + addCommas(mightarray[4]) + '</td><TD class=xtab>' + addCommas(mightarray[5]) + '</td><TD class=xtab>' + addCommas(mightarray[6]) + '</td><TD class=xtabL>' + addCommas(mightarray[7]) + '</td></tr>';
			for (var t in totalarray) {
				totalarray[t]+=mightarray[t];
			}
		}
		u += '<TR class=xtabLine><TD colspan=9 class=xtabLine></td></tr>';
		if (++rownum % 2)
			rsty = 'evenRow';
		else
			rsty = 'oddRow';
		u += '<TR class="'+rsty+'" align=right><TD class=xtab align=left><B>'+tx('TOTAL')+'</b></td><TD class=xtabL>' + addCommas(totalarray[0]) + '</td><TD class=xtab>' + addCommas(totalarray[1]) + '</td>\
			<TD class=xtab>' + addCommas(totalarray[2]) + '</td><TD class=xtab>' + addCommas(totalarray[3]) + '</td><TD class=xtabL>' + addCommas(totalarray[4]) + '</td><TD class=xtab>' + addCommas(totalarray[5]) + '</td><TD class=xtab>' + addCommas(totalarray[6]) + '</td><TD class=xtabL>' + addCommas(totalarray[7]) + '</td></tr>';
		u += '<TR class=xtabLine><TD colspan=9 class=xtabLine></td></tr>';

		m += u + '</table></div><br>';

		//champs

		var rownum = 1;
		var champs = {};
		mightarray = [];
		var totalmight = 0;
		for (var y in Seed.champion.champions) {
			if (Seed.champion.champions[y].championId) {
				champs[Seed.champion.champions[y].championId] = y;
				mightarray.push(0);
			}
		}
		mightarray.push(0); // unassigned
		mightarray.push(0); // broken
		for (var z in Seed.champion.equipment) {
			var item = Seed.champion.equipment[z];
			if (!item.quality) item.quality = parseIntNan(item.rarity);
			item.level = parseIntNan(item.level);
			var might = CardMight(item);
			if (item.status==1) {
				if (item.equippedTo && champs[item.equippedTo]) {
					mightarray[champs[item.equippedTo]] += might;
				}
				else {
					mightarray[mightarray.length-2] += might; // unassigned
				}
			}
			else {
				mightarray[mightarray.length-1] += might; // broken
			}
			totalmight += might;
		}

		m += '<div class="divHeader" align="center">'+tx('CHAMPION HALL')+'</div>';
		m += '<div><br>';

		var u = '<TABLE align=center cellpadding=1 cellspacing=0 style="border-collapse:collapse;"><tr align=center valign=top>';
		for (var y in Seed.champion.champions) {
			if (Seed.champion.champions[y].championId) {
				var champcity = '<i>Unassigned</i>';
				if (Seed.champion.champions[y].assignedCity && Cities.byID[Seed.champion.champions[y].assignedCity]) {
					champcity = Cities.byID[Seed.champion.champions[y].assignedCity].name;
				}
				u += '<td class=xtabBorder nowrap><b>'+Seed.champion.champions[y].name+'</b><br>'+champcity+'</td>';
			}
		}
		u += '<td class=xtabBorder><b>'+tx('Unassigned')+'</b></td><td class=xtabBorder><b>'+tx('Broken')+'</b></td><td class=xtabBorder><b>'+tx('Total')+'</b></td></tr><tr align=center>';
		for (var y in Seed.champion.champions) {
			if (Seed.champion.champions[y].championId) {
				u += '<td class=xtabBorder>'+addCommas(mightarray[y])+'</td>';
			}
		}
		u += '<td class=xtabBorder>'+addCommas(mightarray[mightarray.length-2])+'</td><td class=xtabBorder><span class=boldRed>'+addCommas(mightarray[mightarray.length-1])+'</span></td><td class=xtabBorder>'+addCommas(totalmight)+'</td></tr>';

		m += u + '</table></div><br>';

		//throne

		var rownum = 1;
		var throne = {};
		mightarray = [];
		var totalmight = 0;
		var numslots = Seed.throne.slotNum;
		for (var y=1;y<=numslots;y++) {
			mightarray.push(0);
		}
		mightarray.push(0); // unassigned
		mightarray.push(0); // broken
		for (var z in Seed.throne.inventory) {
			var item = Seed.throne.inventory[z];
			var might = CardMight(item);
			if (item.status==1) {
				var InPreset = false;
				for (var y in Seed.throne.slotEquip) {
					if (Seed.throne.slotEquip[y].indexOf(item.id)!= -1) {
						InPreset = true;
						mightarray[y-1] += might;
					}
				}
				if (!InPreset) {
					mightarray[mightarray.length-2] += might; // unassigned
				}
			}
			else {
				mightarray[mightarray.length-1] += might; // broken
			}
			totalmight += might;
		}

		m += '<div class="divHeader" align="center">'+tx('THRONE ROOM')+'</div>';
		m += '<div><br>';

		var u = '<TABLE align=center cellpadding=1 cellspacing=0 style="border-collapse:collapse;"><tr align=center valign=top>';
		u += '<td class=xtabBorder><b>'+tx('Unassigned')+'</b></td><td class=xtabBorder><b>'+tx('Broken')+'</b></td><td class=xtabBorder><b>'+tx('Total')+'</b></td></tr><tr align=center valign=top>';
		u += '<td class=xtabBorder>'+addCommas(mightarray[mightarray.length-2])+'</td><td class=xtabBorder><span class=boldRed>'+addCommas(mightarray[mightarray.length-1])+'</span></td><td class=xtabBorder>'+addCommas(totalmight)+'</td></tr>';
		u += '</table><br><TABLE align=center cellpadding=1 cellspacing=0 style="border-collapse:collapse;"><tr align=center valign=top>';

		var startslot = 1;
		var numrow = 6;
		while (startslot < numslots) {
			for (var y=startslot;y<=numslots;y++) {
				if (y>startslot+numrow) { break; }
				var presetname = (Options.DashboardOptions.TRPresets[y]?Options.DashboardOptions.TRPresets[y].name:'Preset '+y);
				var active = '';
				if (y==Seed.throne.activeSlot) active = '<span class=boldGreen>('+tx('Active')+')</span>';
					u += '<td class=xtabBorder nowrap><b>'+presetname+'</b><br>'+active+'</td>';
			}
			u += '</tr><tr align=center valign=top>';
			for (var y=startslot;y<=numslots;y++) {
				if (y>startslot+numrow) {
					startslot = y;
					break;
				}
				u += '<td class=xtabBorder>'+addCommas(mightarray[y-1])+'</td>';
			}
			u += '</tr><tr align=center valign=top><td class=xtab colspan='+numrow+' style="border:none;">&nbsp;</td></tr>';
			if (y>=numslots) { startslot=numslots; } else { u += '<tr align=center valign=top>'; }
		}

		m += u + '</table></div>';

		m += '<div class="divHeader" align="center">'+tx('OTHER MIGHT')+'</div>';
		m += '<div><br>';

		var QM = 0;
		for (var q in Seed.quests) {
			if (Seed.quests[q]==1) {
				var R = uW.questlist[q].reward;
				if (parseInt(R[3][1]) != 0) {
					QM += parseInt(R[3][1]);
				}
			}
		}
		var u = '<TABLE align=center cellpadding=0 cellspacing=0><tr align=center valign=top>';
		u += '<td class=xtab align=right><b>'+tx('Quest Rewards')+':&nbsp;</b></td><td class=xtab align=left>'+addCommas(QM)+'</td></tr></table>';

		m += u + '</div>';

		m += '<div align=center><br>'+strButton20(tx('Refresh'), 'id=ptmightrefresh')+'<br></div>';

		var off = getAbsoluteOffsets(ById('btMightPop'));
		MightPop = new CPopup('btShowMight', off.left, off.top, 600, 500, true);
		MightPop.getTopDiv().innerHTML = '<DIV align=center><B>'+tx('Might Breakdown')+'</B></DIV>';
		MightPop.getMainDiv().innerHTML = m;
		ById('ptmightrefresh').addEventListener('click',ShowMightBreakdown, false);
		MightPop.show(true);
		ResetFrameSize('btShowMight',500,600);
	}

	// get court might values from server

	fetchPlayerCourt(uW.tvuid, PlayerCourtCallBack);
}

/************************************ Battle Popup *********************************************/

var Battle = {
	userobj : {},
	ReqSent : {},
	dat : [],
	playerpos : {x: -999, y: -999},
	SearchUID : false,
	init : function () {
		var t = Battle;

		uWExportFunction('ptBatClickSort', Battle.ClickSort);

		DefaultWindowPos('btBatPos','main_engagement_tabs');
		if (GlobalOptions.BattleToggle) {
			AddPowerBarLink(tx('Battle'), 'PBPBatButton', Battle.ToggleBattle,function(me) {ResetWindowPos (me,'main_engagement_tabs',popBat);});
		}
	},

	ToggleBattle : function () {
		var t = Battle;
		if (popBat) {
			popBat.toggleHide(popBat)
		}
		else {
			var initvalue = Options.MonitorOptions.LastMonitored;
			if (t.SearchUID) {
				initvalue = Options.MonitorOptions.LastMonitoredUID;
				if (initvalue==0) { initvalue = ""; }
			}

			m = '<br>';
			m += '<div align="center">'+tx('Enemy')+':&nbsp;<INPUT id=btBatPlayer size=20 type=text value="'+initvalue+'"/>&nbsp;'+tx('Search UID')+'<INPUT id=btBatUID type=checkbox '+(t.SearchUID?'CHECKED':'')+' /></div>';
			m += '<div class="ErrText" align="center" id=btBatPlayErr>&nbsp;</div>';
			m += '<div align="center"><a id=btBatMonitor class="inlineButton btButton blue20"><span>'+tx('Monitor')+'</span></a>&nbsp;<a id=btBatDetails class="inlineButton btButton blue20"><span>'+tx('Details')+'</span></a>&nbsp;<a id=btBatChamp class="inlineButton btButton blue20"><span>'+tx('Champions')+'</span></a><br>&nbsp;</div>';

			popBat = new CPopup('btBattle', Options.btBatPos.x, Options.btBatPos.y, 420, 100, true, Battle.close);
			popBat.getMainDiv().innerHTML = m;
			popBat.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Battle')+'</B></DIV>';

			ById('btBatUID').addEventListener('change',	function() {
				t.SearchUID = (ById('btBatUID').checked);
			});

			ById('btBatMonitor').addEventListener('click', function(){ t.BattleClick(1); },false);
			ById('btBatChamp').addEventListener('click', function(){ t.BattleClick(2); },false);
			ById('btBatDetails').addEventListener('click', function(){ t.BattleClick(3); },false);

			popBat.show(true);
			ResetFrameSize('btBattle',100,420);
		}
	},

	close : function () {
		Options.btBatPos = popBat.getLocation();
		saveOptions();
		popBat=null;
	},

	setError : function (msg) {
		ById('btBatPlayErr').innerHTML = msg;
	},

	BattleClick : function (funtype) {
		var t = Battle;
		t.setError('&nbsp;');

		var name = ById('btBatPlayer').value;
		name = name.replace(/\'/g,"_").replace(/\,/g,"_").replace(/\-/g,"_");

		if (name.toUpperCase() == Seed.player.name.toUpperCase()) {
			if (funtype==1) {
				Tabs.Monitor.initMonitor (uW.tvuid, false)
			}
			if (funtype==2) {
				Tabs.Player.ViewChamps (uW.tvuid, Seed.player.name, popBat.getMainDiv())
			}
			if (funtype==3) {
				t.fetchPlayerInfo(uW.tvuid,t.clickedPlayerDetails);
			}
			return;
		}

		if (t.SearchUID) {
			if (funtype==1) {
				Tabs.Monitor.initMonitor (name, false);
			}
			if (funtype==2) {
				t.getPlayerName(name, Tabs.Player.ViewChamps, popBat.getMainDiv());
			}
			if (funtype==3) {
				t.fetchPlayerInfo(name,t.clickedPlayerDetails);
			}
			return;
		}

		if (getMyAlliance()[0] == 0) {
			t.setError(uW.g_js_strings.membersInfo.youmustbelong);
			return;
		}

		if (name.length < 3){
			setError(uW.g_js_strings.getAllianceSearchResults.entryatleast3);
			return;
		}

		// Get User details.. need to use alliance search to get UserID from name

		if (funtype==1) {
			fetchPlayerList(name, t.eventMatchNameMonitor);
		}
		if (funtype==2) {
			fetchPlayerList(name, t.eventMatchNameChamp);
		}
		if (funtype==3) {
			fetchPlayerList(name, t.eventMatchNameDetails);
		}
	},

	eventMatchNameMonitor : function (rslt){
		var t = Battle;
		if (!rslt.ok){ t.setError(rslt.msg); return; }

		var matchname = ById('btBatPlayer').value;
		var uid = "";

		for (var k in rslt.matchedUsers) {
			if (rslt.matchedUsers[k].name.toUpperCase() == matchname.toUpperCase()) {uid = rslt.matchedUsers[k].userId;}
		}

		if (uid==""){
			t.setError(tx('User not found')+'!');
			return;
		}

		Tabs.Monitor.initMonitor (uid, false);
	},

	eventMatchNameChamp : function (rslt){
		var t = Battle;
		if (!rslt.ok){ t.setError(rslt.msg); return; }

		var matchname = ById('btBatPlayer').value;
		var uid = "";
		var name = "";

		for (var k in rslt.matchedUsers) {
			if (rslt.matchedUsers[k].name.toUpperCase() == matchname.toUpperCase()) {
				uid = rslt.matchedUsers[k].userId;
				name = rslt.matchedUsers[k].name;
			}
		}

		if (uid==""){
			t.setError(tx('User not found')+'!');
			return;
		}

		Tabs.Player.ViewChamps (uid, name, popBat.getMainDiv());
	},

	eventMatchNameDetails : function (rslt){
		var t = Battle;
		if (!rslt.ok){ t.setError(rslt.msg); return; }

		var matchname = ById('btBatPlayer').value;
		var uid = "";

		for (var k in rslt.matchedUsers) {
			if (rslt.matchedUsers[k].name.toUpperCase() == matchname.toUpperCase()) { uid = rslt.matchedUsers[k].userId; }
		}

		if (uid==""){
			t.setError(tx('User not found')+'!');
			return;
		}

		t.fetchPlayerInfo(uid,t.clickedPlayerDetails);
	},

	getPlayerName : function (uid, notify){
		var t = Battle;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rsltInfo) {
				if (!rsltInfo.ok) {
					t.setError('Unknown UID');
					return;
				}
				notify(uid,rsltInfo.userInfo[0].name);
			},
			onFailure: function () {
				t.setError ('AJAX error (server not responding)');
			},
		},true);
	},

	fetchPlayerInfo : function (uid, notify){
		var t = Battle;

		if (t.popPlayer) {
			t.popPlayer.show(false);
			if (t.popPlayer.onClose) t.popPlayer.onClose();
			t.popPlayer.destroy();
			t.popPlayer = null;
		}
		t.popPlayer = new CPopup('btPlayerPop', t.playerpos.x, t.playerpos.y, 500, 100, true, function () { t.playerpos = t.popPlayer.getLocation(); clearTimeout(1000); });
		if ((t.playerpos.x == -999) && (t.playerpos.y == -999)) {
			if (popBat) { t.popPlayer.centerMe(popBat.getMainDiv()); }
			else { t.popPlayer.centerMe(mainPop.getMainDiv()); }
		}
		t.popPlayer.getMainDiv().innerHTML = '<div align=center>'+tx('Loading')+'...</div>';
		t.popPlayer.getTopDiv().innerHTML = '<DIV style="white-space:nowrap;" align=center>&nbsp;&nbsp;<B>'+tx('Player Details')+'</B>&nbsp;&nbsp;</DIV>';
		t.popPlayer.show(true);
		ResetFrameSize('btPlayerPop',100,500);

		var uList = [];
		uList.push(uid);
		getOnline(uList, function (r) {
			if (!r.ok) { t.setError(rslt.errorMsg);return; }
			else { notify(uid,r.data[uid]);}
		});
	},

	clickedPlayerDetails : function (uid,online) {
		var t = Battle;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					t.userobj = {};
					t.userobj[uid] = rslt.userInfo[0];
					t.userobj[uid].might = Math.round(t.userobj[uid].might);
					t.userobj[uid].online = (online?true:false);

					fetchPlayerCourt(uid, function (rslt2) {
						if (rslt2.ok) {
							u = unixTime();
							f = convertTime(new Date(rslt2.playerInfo.fogExpireTimestamp.replace(" ","T")+"Z"));
							t.userobj[uid].misted = (f >= u);
							t.userobj[uid].fogExpireTimestamp = rslt2.playerInfo.fogExpireTimestamp;
							t.userobj[uid].warStatus = rslt2.playerInfo.warStatus;
							t.userobj[uid].truceExpireTimestamp = rslt2.playerInfo.truceExpireTimestamp;
							t.userobj[uid].cityCount = rslt2.playerInfo.cityCount;
							t.userobj[uid].mightClassic = rslt2.playerInfo.mightClassic;
							t.userobj[uid].mightGlory = rslt2.playerInfo.mightGlory;
							t.userobj[uid].fbuid = parseInt(rslt2.playerInfo.fbuid);
							t.userobj[uid].lastLogin = rslt2.playerInfo.lastLogin;

							t.fetchPlayerLeaderboard(uid, function (r) { t.gotPlayerLeaderboard(r, uid) });
						}
						else {
							t.setError(uW.g_js_strings.barbarian.erroroccured);
						}
					});
				}
				else {
					t.setError(uW.g_js_strings.barbarian.erroroccured);
				}
			},
			onFailure: function () {t.setError(uW.g_js_strings.errorcode.err_602);},
		});
	},

	fetchPlayerLeaderboard: function (uid, notify) {
		var t = Battle;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.userId = uid;
		params.type = "might";
		params.page = 1;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify(rslt); },
			onFailure: function () { notify({errorMsg: 'AJAX error'});},
		});
	},

	gotPlayerLeaderboard : function (rslt,uid) {
		var t = Battle;
		if (!rslt.ok) { t.setError(rslt.errorMsg); return; }

		t.dat = [];
		var prestige = "";
		var aid = getMyAlliance()[0];
		if (rslt.totalResults == 0) {
			t.displayPlayer(uid,false);
			return;
		}

		var p = rslt.results[0];
		for (var c = 0; c < p.cities.length; c++) {
			var pt = p.cities[c].prestigeType;
			var prestige = getFactionName(pt);
			if (prestige == "") { prestigelvl = ""; }
			else { prestigelvl = " (" + p.cities[c].prestigeLevel + ")"; }
			ExpTime = convertTime(new Date(p.cities[c].prestigeBuffExpire.replace(" ", "T")+"Z"));
			if ((ExpTime + (3600 * 24) < unixTime()) || isNaN(ExpTime)) {
				prestigeexp = "";
			} else {
				prestigeexp = Tabs.Player.getDuration(p.cities[c].prestigeBuffExpire);
			}
			t.dat.push([p.displayName, parseInt(p.might), p.officerType, parseInt(p.numCities), parseInt(p.cities[c].tileLevel),
				parseInt(p.cities[c].xCoord), parseInt(p.cities[c].yCoord), p.cities[c].cityName, 0, t.userobj[uid].online, '--',
				p.cities[c].cityId, prestige, p.userId, prestigelvl, prestigeexp, p.cities[c].prestigeBuffExpire, prestige + prestigelvl, p.cities[c].blessing,false]);
		}
		t.displayPlayer(uid,true);
	},

	displayPlayer: function (uid,locations) {
		var t = Battle;

		var u = t.userobj[uid];
		var n = '<div>';
		n += '<div style="width:500px;padding:5px;"><table style="padding-right:0px;" class=xtab cellspacing=0 width=100%>';
		if (u.allianceId && u.allianceId != 0) {
			n += '<tr><td>'+uW.g_js_strings.commonstr.alliance+':&nbsp;</td><td colspan=2><b>' + u.allianceName + FormatDiplomacy(u.allianceId) + '</b></td></tr>';
		}
		else {
			n += '<tr><td>'+uW.g_js_strings.commonstr.alliance+':&nbsp;</td><td colspan=2><b>'+uW.g_js_strings.commonstr.none+'!</b></td></tr>';
		}

		if (!u.online) {
			n += ' <tr><TD>'+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+':&nbsp;</td><TD colspan=2><b>'+ Tabs.Player.getLastLogDuration(u.lastLogin) +'</b></td></tr>';
		}
		else {
			n += ' <tr><TD>'+tx('Last login')+':&nbsp;</td><TD colspan=2><b><span style="color:#800">'+tx('ONLINE')+'</span></b></td></tr>';
		}
		if (u.misted)
			n += '<tr><TD>'+tx('Misted')+':&nbsp;</td><TD colspan=2><b>' + Tabs.Monitor.getDuration(u.fogExpireTimestamp) + '</b></td></tr>';
		n += '<tr><TD>'+uW.g_js_strings.commonstr.status+':&nbsp;</td><TD colspan=2><b>' + Tabs.Monitor.GetStatusText(u.warStatus,u.truceExpireTimestamp) + '</b></td></tr>';
		n += '<tr><TD>'+uW.g_js_strings.commonstr.might+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.might)) + '</b></td></tr>';
		n += '<tr><TD>'+tx('Classic Might')+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.mightClassic)) + '</b></td></tr>';
		n += '<tr><TD>'+tx('Glory Might')+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.mightGlory)) + '</b></td></tr>';
		n += '<TR><TD>'+uW.g_js_strings.commonstr.glory+':&nbsp;</td><TD width=50><b><DIV id=ptBatPaintGlory></div></b></td><td valign=middle rowspan=3 id=ptBatGloryIcon>&nbsp;</td></tr>';
		n += '<TR><TD>'+tx('Maximum Glory')+':&nbsp;</td><TD><b><DIV id=ptBatPaintMaxGlory></div></b></td></tr>';
		n += '<TR><TD>'+tx('Lifetime Glory')+':&nbsp;</td><TD><b><DIV id=ptBatPaintLifetimeGlory></div></b></td></tr>';

		var pids = u.provinceIds.split(',');
		var p = [];
		for (var i = 0; i < pids.length; i++) {
			p.push(uW.provincenames['p' + pids[i]]);
		}
		n += '<tr><td>'+tx('Provinces')+':&nbsp;</td><td colspan=2><div class="wrap" style="width:350px;">'+p.join(', ')+'</div></td></tr>';
		// create notes link
		var notes = "";
		if (Tabs.Notes.noteValues[uid]) {
			notes = Tabs.Notes.noteValues[uid];
			notes = notes.text;
		}

		if (notes != "") {
			n += '<TR><TD class=xtab valign=top>'+tx('Player Notes')+':</td><TD colspan=2 id=ptBatplayernotes class=xtabBRTop><div class="wrap" style="width:350px;">' + notes + '</div></td></tr>';
		}
		n += '</table></div>';

		n += '<div id=BatCitySelect style="display:none;padding:5px;"><hr>';
		n += '<table class=xtab width=100%>';
		n += '<TR><TD>';
		if (Tabs.BulkScout) n += strButton20(tx('Add to Scout List'), 'id=BatScoutExport')+'&nbsp;';
		if (Tabs.BulkAttack) n += strButton20(tx('Add to Attack List'), 'id=BatBulkAttackExport')+'&nbsp;';
		n += strButton20(tx('Highlight Defending Cities'),'id=BatHighDefenders')+'</td></tr></table>'
		n += '</div>';

		n+= '<DIV class=divHeader style="padding-right:0px;"><TABLE width=100% cellspacing=0>';
		if (!locations) {
			n += '<TR><TD class=xtab align=center>'+tx('City locations unavailable')+'</td></tr>';
		}
		else {
			n += '<TR><TD class=xtab align=center>'+tx('City Locations')+'</td></tr>';
		}
		n += '</table></div>';
		if (locations) {
			n += '<div style="padding-right:6px;width:500px;overflow-x:auto;height:200px;overflow-y:auto;"><TABLE id=tabBatAllMembers align=left cellpadding=0 cellspacing=0 width=100%>';
			n += '<TR><TD nowrap><A id=clickBat7 onclick="ptBatClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.city+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickBat4 onclick="ptBatClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Lvl')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickBat17 onclick="ptBatClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.faction+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickBat16 onclick="ptBatClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Protection Left')+'&nbsp;</span></a></td>\
				<TD nowrap><a id=clickBat9 class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="padding-right:10px;vertical-align:middle;display:inline-block;width:100%;"><INPUT id=BatToggleScoutCheckbox type=checkbox></span></a></td>\
				<TD nowrap><A id=clickBat5 onclick="ptBatClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Co-ords')+'&nbsp;</span></a></td>\
				</tr>';
			n += '<TBODY id=BatBody></tbody></table></div>';
		}

		n += '</div><br>';

		t.popPlayer.getMainDiv().innerHTML = n;

		if (locations) {
			ById('BatCitySelect').style.display='block';
			if (ById('clickBat' + Options.PlayerOptions.sortColNum)) {
				ById('clickBat' + Options.PlayerOptions.sortColNum).className = 'buttonv2 std green';
			}
			ById('BatToggleScoutCheckbox').addEventListener('change', t.doSelectall, false);
			t.RepaintList();
		}

		t.PaintGlory(uid);

		if (ById('BatScoutExport')) ById('BatScoutExport').addEventListener('click', t.ExportScoutList, false);
		if (ById('BatBulkAttackExport')) ById('BatBulkAttackExport').addEventListener('click', t.ExportAttackList, false);
		ById('BatHighDefenders').addEventListener('click', t.HighlightDefenders, false);

		t.popPlayer.getTopDiv().innerHTML = '<DIV style="white-space:nowrap;" align=center>&nbsp;&nbsp;<B>'+u.name+' ('+uid+')</B>&nbsp;&nbsp;</DIV>';
		t.popPlayer.show(true);
		ResetFrameSize('btPlayerPop',100,500);
	},

	ClickSort : function (e) {
		var t = Battle;
		var newColNum = e.id.substr(8);
		if (ById('clickBat' + Options.PlayerOptions.sortColNum))
		ById('clickBat' + Options.PlayerOptions.sortColNum).className = 'buttonv2 std blue';
		e.className = 'buttonv2 std green';
		if (newColNum == Options.PlayerOptions.sortColNum) { Options.PlayerOptions.sortDir *= -1; }
		else { Options.PlayerOptions.sortColNum = newColNum; }
		saveOptions();
		t.RepaintList();
	},

	PaintGlory: function (uid) {
		var t = Battle;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.userId = uid;
		params.ctrl = 'PlayerProfile';
		params.action = 'get';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					ById('ptBatPaintGlory').innerHTML = addCommas(rslt.profile.glory);
					ById('ptBatPaintMaxGlory').innerHTML = addCommas(rslt.profile.maxGlory);
					ById('ptBatPaintLifetimeGlory').innerHTML = addCommas(parseIntNan(rslt.profile.lifetimeGlory));
					ById('ptBatGloryIcon').innerHTML = '<img src="'+IMGURL+'chat_'+rslt.profile.gloryIconId+'.png">';
				}
				else {
					ById('ptBatPaintGlory').innerHTML = '(error)';
					ById('ptBatPaintMaxGlory').innerHTML = '(error)';
					ById('ptBatPaintLifetimeGlory').innerHTML = '(error)';
					ById('ptBatGloryIcon').innerHTML = '&nbsp;';
				}
			},
		},true);
	},

	doSelectall: function () {
		var t = Battle;
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('BatToggleScoutCheckbox').checked) ById('ptBatScout_' + city).checked = true;
			else ById('ptBatScout_' + city).checked = false;
		}
	},

	RepaintList: function () {
		var t = Battle;

		function sortFunc(a, b) {
			var t = Battle;
			if (typeof (a[Options.PlayerOptions.sortColNum]) == 'number') {
				if (Options.PlayerOptions.sortDir > 0)
					return a[Options.PlayerOptions.sortColNum] - b[Options.PlayerOptions.sortColNum];
				else
					return b[Options.PlayerOptions.sortColNum] - a[Options.PlayerOptions.sortColNum];
			} else if (typeof (a[Options.PlayerOptions.sortColNum]) == 'boolean') {
				return 0;
			} else {
				if (Options.PlayerOptions.sortDir > 0)
					return a[Options.PlayerOptions.sortColNum].localeCompare(b[Options.PlayerOptions.sortColNum]);
				else
					return b[Options.PlayerOptions.sortColNum].localeCompare(a[Options.PlayerOptions.sortColNum]);
			}
		}

		t.dat.sort(sortFunc);

		var m = '';
		var RowId = "";
		var r = 0;
		for (var i = 0; i < t.dat.length; i++) {
			RowId = 'bat_'+t.dat[i][5].toString()+'_'+t.dat[i][6].toString();
			var bless = showBlessings(t.dat[i][18]);
			if (bless != "") {
				var bless = '<a class=trimg><img style="vertical-align:bottom" src="'+IMGURL+'bonus_prestige.png"><SPAN class=trtip><table width=200 class=xtab>'+bless+'</table></span></a>';
			}
			var status = '<img title="Offline" style="vertical-align:bottom" src="'+OFFLINE+'"/>';
			if (t.dat[i][9] == 1) status = '<img title="Online" style="vertical-align:bottom" src="'+ONLINE+'"/>';

			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';
			if (t.dat[i][19]) rowClass += ' highRow';
			m += '<TR id="'+RowId+'" class="'+rowClass+'" style="max-height:30px"><TD class=xtab nowrap>'+t.dat[i][7]+'</td>';
			m += '<TD class=xtab align=right>'+t.dat[i][4]+'</td>';
			m += '<TD class=xtab align=left nowrap>'+bless+t.dat[i][12]+t.dat[i][14]+'</td>';
			m += '<TD class=xtab align=center>'+t.dat[i][15]+'</td>';
			m += '<TD class=xtab align=center style="padding-left:4px;padding-right:0px;"><INPUT id=ptBatScout_'+t.dat[i][11]+' type=checkbox></td>';
			m += '<TD class=xtab align=center onclick="btGotoMap('+t.dat[i][5]+','+t.dat[i][6]+')"><A>'+t.dat[i][5]+','+t.dat[i][6]+'</a></td>';
		}
		if (ById('BatBody')) {
			ById('BatBody').innerHTML = m;
			ResetFrameSize('btPlayerPop',100,400);
		}
	},

	ExportScoutList : function () {
		var t = Battle;

		var coordlist = "";
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('ptBatScout_' + city).checked) {
				coordlist += t.dat[k][5].toString()+','+t.dat[k][6].toString()+' ';
				ById('ptBatScout_' + city).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkScout.ImportCoords(coordlist.split(" "));
		}
	},

	ExportAttackList : function () {
		var t = Battle;

		var coordlist = "";
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('ptBatScout_' + city).checked) {
				coordlist += t.dat[k][5].toString()+','+t.dat[k][6].toString()+' ';
				ById('ptBatScout_' + city).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkAttack.ImportCoords(coordlist.split(" "));
		}
	},

	HighlightDefenders : function () {
		var t = Battle;

		var delayer = 0;
		ById('BatHighDefenders').outerHTML = '<span id=BatHighDefendersProg>&nbsp;</span>';

		for (var k = 0; k < t.dat.length; k++) {
			if (!t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]] || t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]]==0) {
				t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]]=1;
				setTimeout(getDefendStatus,(250*delayer),t.dat[k][5],t.dat[k][6],false,false,t.UpdateDefendStatus,k,t.dat.length,'BatHighDefendersProg');
				delayer = delayer + 1;
			}
		}

		function ClearAtEnd () {
			if (ById('BatHighDefendersProg')) {
				ById('BatHighDefendersProg').outerHTML = strButton20(tx('Highlight Defending Cities'),'id=BatHighDefenders');
				ById('BatHighDefenders').addEventListener('click', t.HighlightDefenders, false);
			}
		};

		setTimeout (ClearAtEnd,(250*delayer));
	},

	UpdateDefendStatus : function (rslt,x,y,k) {
		var t = Battle;
		t.ReqSent[x+'_'+y]=0;
		var div = ById('bat_'+x+'_'+y);
		var	city = t.dat[k][11].toString();
		if (rslt.ok && rslt.ok=="true") {
			t.dat[k][19] = true;
			if (div) jQuery(div).addClass("highRow");
			if (ById('ptBatScout_' + city)) ById('ptBatScout_' + city).checked = true;
		}
		else {
			t.dat[k][19] = false;
			if (div) jQuery(div).removeClass("highRow");
			if (ById('ptBatScout_' + city)) ById('ptBatScout_' + city).checked = false;
		}
	},

}

/************************************ Incoming Marches Popup *********************************************/

var Incoming = {
	Options : {
				IncomingStartState	: false,
				IncAttack           : true,
				IncScout            : true,
				IncReinforce        : true,
				IncReassign         : false,
				IncTransport        : false,
				IncWilds            : false,
				IncYours            : false,
				IncResources        : true,
	},

	init : function () {
		var t = Incoming;
		DefaultWindowPos('btIncPos','main_engagement_tabs');
		if (GlobalOptions.InOutToggle) {
			AddPowerBarLink(tx('Incoming'), 'PBPIncButton', Incoming.ToggleIncoming,function(me) {ResetWindowPos (me,'main_engagement_tabs',popInc);});
		}
		HTMLRegister['INC']= {};

		if (!Options.IncomingOptions) {
			Options.IncomingOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.IncomingOptions.hasOwnProperty(y)) {
					Options.IncomingOptions[y] = t.Options[y];
				}
			}
		}
		if (Options.IncomingOptions.IncomingStartState) {t.ToggleIncoming();}
	},

	ToggleIncoming : function () {
		var t = Incoming;

		ResetHTMLRegister('INC','btIncomingMain');

		if (popInc) {
			Options.IncomingOptions.IncomingStartState = popInc.toggleHide(popInc)
		}
		else {
			m = '<div id=btIncomingButtons align="center"><TABLE width="100%"><tr>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.attack+'</td><TD class=xtab><INPUT id=IncAttackChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.scout+'</td><TD class=xtab><INPUT id=IncScoutChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.reinforce+'</td><TD class=xtab><INPUT id=IncReinforceChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.reassign+'</td><TD class=xtab><INPUT id=IncReassignChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.transport+'</td><TD class=xtab><INPUT id=IncTransportChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+tx('To Wilds')+'</td><TD class=xtab><INPUT id=IncWildsChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+tx('From You')+'</td><TD class=xtab><INPUT id=IncYoursChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.resources+'</td><TD class=xtab><INPUT id=IncResChk type=checkbox /></td>';
			m += '</tr></table></div><div style="max-height:700px; overflow-y:scroll" id=btIncomingMain></div><br>';

			popInc = new CPopup('btIncoming', Options.btIncPos.x, Options.btIncPos.y, 720, 200, true, Incoming.close);
			popInc.getMainDiv().innerHTML = m;
			popInc.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Incoming Marches')+'</B></DIV>';

			ToggleOption('IncomingOptions','IncAttackChk','IncAttack');
			ToggleOption('IncomingOptions','IncScoutChk','IncScout');
			ToggleOption('IncomingOptions','IncReinforceChk','IncReinforce');
			ToggleOption('IncomingOptions','IncReassignChk','IncReassign');
			ToggleOption('IncomingOptions','IncTransportChk','IncTransport');
			ToggleOption('IncomingOptions','IncWildsChk','IncWilds');
			ToggleOption('IncomingOptions','IncYoursChk','IncYours');
			ToggleOption('IncomingOptions','IncResChk','IncResources');

			popInc.show(true);
			Options.IncomingOptions.IncomingStartState = true;
		}
		saveOptions();

	},

	close : function () {
		Options.IncomingOptions.IncomingStartState = false;
		Options.btIncPos = popInc.getLocation();
		saveOptions();
		popInc=null;
	},

	PaintIncoming : function () {
		var t = Incoming;
		var z = '';
		var r = 0;
		var incomingshow = false;
		var incomingfiltered = false;
		var inctimes = {};

		var bclass = "brown11";
		if (RefreshingSeed || Options.DashboardOptions.RefreshSeed) bclass += " disabled";

		var z = '<div align="center"><TABLE cellSpacing=0 width=98% height=0%><tr><td width="18" class="xtabHD">&nbsp;</td><td width="60" class="xtabHD"><b>'+uW.g_js_strings.commonstr.time+'</b></td><td width="120" class="xtabHD"><b>'+uW.g_js_strings.commonstr.target+'</b></td><td width="120" class="xtabHD"><b>'+tx('From')+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td><td class="xtabHD" align="right"><a id=btRefreshSeedInc class="inlineButton btButton '+bclass+'"><span>'+tx('Refresh')+'</span></a></td></tr>';

		for(n in inc) {
			var a = inc[n];

			var icon, hint, marchtime, targetcity, targetcoords, fromname, marchdir, fromcoords;
			var marchScore = parseInt(a.score);
			var marchType = parseInt(a.marchType);
			var marchStatus = parseInt(a.marchStatus);

			var to = Cities.byID[a.toCityId];
			if (to) {
				if ( to.tileId == a.toTileId ) {targetcity = CityLink(to);targetcoords = "";}
				else {targetcity = uW.g_js_strings.commonstr.wilderness;targetcoords = coordLink(a.toXCoord,a.toYCoord);}
			}
			else {
				targetcity = "";targetcoords = coordLink(a.toXCoord,a.toYCoord);
			}

			fromname = "";
			if (a.score) {
				if (a.arrivalTime < unixTime()) continue; // don't display arrival times already happened
				var marchId = a.mid;
				var pid = a.pid;
				if (!a.marchType) {a.marchType = 4;}
				if (!a.arrivalTime || a.arrivalTime == -1) {marchtime = '??????';}
				else {marchtime=uW.timestr(a.arrivalTime - unixTime());}
				if (a.players && a.players['u'+a.pid]) {fromname = a.players['u'+a.pid].n;}
				else if (Seed.players['u'+a.pid]) {fromname = Seed.players['u'+a.pid].n;}
			}
			else
			{
				var marchId = a.marchId;
				var pid = a.fromPlayerId;
				if ((a.arrivalTime - unixTime()) < 0) continue;
				marchtime=uW.timestr(a.arrivalTime - unixTime());
				player = Seed.players['u'+a.fromPlayerId];
				if (Seed.players['u'+a.fromPlayerId]) {fromname = Seed.players['u'+a.fromPlayerId].n;}
				else if (a.players && a.players['u'+a.fromPlayerId]) {fromname = a.players['u'+a.fromPlayerId].n;}
			}
			inctimes[marchId] = marchtime;

			if (!a.fromXCoord) {fromcoords = "";}
			else {fromcoords = coordLink(a.fromXCoord,a.fromYCoord);}
			if (fromname.toUpperCase() == Seed.player.name.toUpperCase()) {
				fromname = tx('Yourself');
				var fr = Cities.byID[a.fromCityId];
				fromcoords = ' ('+CityLink(fr)+')';
			}
			else
			{
				if (fromname == "") { if (a.score) {fromname = '('+uW.g_js_strings.attack_viewimpending_view.upgradetoseeinfo+')';} else {fromname = '('+tx('Unknown')+')';}}
				else {fromname = MonitorLink(pid,fromname);}
			}

			icon = "";
			switch (marchType) {
				case 1: icon=TransportImage;hint=uW.g_js_strings.commonstr.transport;break;
				case 2: icon=ReinforceImage;hint=uW.g_js_strings.commonstr.reinforce;break;
				case 3: icon=ScoutImage;hint=uW.g_js_strings.commonstr.scout;break;
				case 4: icon=AttackImage;hint=uW.g_js_strings.commonstr.attack;break;
				case 5: icon=ReassignImage;hint=uW.g_js_strings.commonstr.reassign;break;
			}
			if(icon=="")continue; // tampermonkey fix

			incomingfiltered = true;

			/* Apply Filters */

			if ((marchType == 1) && !Options.IncomingOptions.IncTransport) continue;
			if ((marchType == 2) && !Options.IncomingOptions.IncReinforce) continue;
			if ((marchType == 5) && !Options.IncomingOptions.IncReassign) continue;

			if ((marchType == 3) && !Options.IncomingOptions.IncScout) continue;
			if (((marchType == 4) || (!marchType && marchScore)) && !Options.IncomingOptions.IncAttack) continue;

			if ((targetcity == "Wilderness") && !Options.IncomingOptions.IncWilds) continue;
			if ((fromname == "Yourself") && !Options.IncomingOptions.IncYours) continue;

			incomingshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'"><TD class=xtab><img src='+icon+' title='+hint+'></td>';
			z += '<TD class=xtab id="marchtime'+marchId+'">&nbsp;</td>';
			z += '<TD class=xtabBR>';
			if (targetcity != "") z += '<span class=xtab>'+targetcity+'</span> ';
			if (targetcoords != "") z += '<span class=xtab>'+targetcoords+'</span>';
			z += '</td>';
			z += '<TD class=xtabBR><span class=xtab>'+fromname+'</span> ';
			if (fromcoords != "") { z+= '<span class=xtab>'+fromcoords+'</span>'; }
			z += '</td>';

			if (a.destinationUnixTime < unixTime() || marchStatus == 8)
				marchdir = "Return";
			else
				marchdir = "Count";

			z += '<TD colspan=2 class=xtabBR>';
			if (marchType == 3 || marchType == 4){
				if ((safecall.indexOf(a.pid) < 0 || trusted) && a["championInfo"]) {
					marchchamp = "<table cellspacing=0 class=xtab><tr><td colspan=2><b>"+a["championInfo"].name+"</b></td></tr><tr><td colspan=2><b>"+uW.g_js_strings.report_view.champion_stats+"</b></td></tr>";
					var gotchamp = false;
					if (a["championInfo"].effects[1] && !(a["championInfo"].effects[1] instanceof Array) && typeof(a["championInfo"].effects[1]) === "object") {
						got202 = false;
						for (var cy in a["championInfo"].effects[1]) {
							// missing bonus damage?
							if ((cy == '202') && gotchamp) {got202 = true;}
							if ((cy == '203') && !got202) { marchchamp += "<tr><td>"+uW.g_js_strings.effects.name_202+"</td><td>0</td></tr>"; }
							str = eval('uW.g_js_strings.effects.name_'+cy);
							if (str && str!= "") {
								gotchamp = true;
								marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[1][cy]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gotchamp) { marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					marchchamp+="<tr><td colspan=2><b>"+uW.g_js_strings.report_view.troop_stats+"</b></td></tr>";
					var gottroop = false;
					if (a["championInfo"].effects[2] && !(a["championInfo"].effects[2] instanceof Array) && typeof(a["championInfo"].effects[2]) === "object") {
						for (var ty in a["championInfo"].effects[2]) {
							str = eval('uW.g_js_strings.effects.name_'+ty);
							if (str && str!= "") {
								gottroop = true;
								marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[2][ty]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gottroop) { marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					marchchamp+="</table>";
					z +='<table cellspacing=0><tr><td class="xtab trimg" style="font-weight:normal;align:left;" id="btmarchchamp'+a.mid+'td"><input type="hidden" id="btmarchchamp'+a.mid+'effects" value="'+marchchamp+'" /><a><img id="btmarchchamp'+a.mid+'" onMouseover="btCreateChampionPopUp(this,'+a.toCityId+');" height=14 style="vertical-align:text-top;" src="'+ShieldImage+'"></a></td><td class=xtab>'+tx('Champion')+': '+a["championInfo"].name+'&nbsp;</td></tr></table>';
				}
				if (a["knt"] && a["knt"]["cbt"]) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' (Atk:'+ a["knt"]["cbt"]+')</span> ';
				if (a["unts"]) {
					for (var ui in uW.cm.UNIT_TYPES){
						i = uW.cm.UNIT_TYPES[ui];
						if (a["unts"]["u"+i]) {
							if (a["unts"]["u"+i] > 0) z += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': '+ addCommas(a["unts"]["u"+i])+'</span> ';
							else z += '<span class=xtab>'+ a["unts"]["u"+i]+' '+ uW.unitcost['unt'+i][0] +'</span> ';
						}
					}
				}
				else
				{
					if (a["cnt"]) { z += '<span class=xtab>'+a["cnt"]+'</span> ';}
					else { z += '<span class=xtab>('+uW.g_js_strings.attack_viewimpending_view.upgradetoseeinfo+')</span> '; }
				}
			}
			else
			{
				if (a["knightId"] > 0) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' (Atk:'+ a["knightCombat"]+')</span> ';
				for (var ui in uW.cm.UNIT_TYPES){
					i = uW.cm.UNIT_TYPES[ui];
					if(a["unit"+i+marchdir] > 0) z += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': '+ addCommas(a["unit"+i+marchdir])+'</span> ';
				}
			}

			if (local_atkinc["m"+marchId]["fromSpellType"]) {
				var spell = eval('uW.g_js_strings.spells.name_'+local_atkinc["m"+marchId]["fromSpellType"]);
				if (spell) {
					var spellstyle = 'color:#808;';
					z +='<br><span class=xtab style="'+spellstyle+'"><b>*&nbsp;'+spell+'&nbsp;*</b></span>'
				}
			}

			if (Options.IncomingOptions.IncResources) {
				if ((a["gold"] > 0) || (a["resource1"] > 0) || (a["resource2"] > 0) || (a["resource3"] > 0) || (a["resource4"] > 0) || (local_atkinc["m"+marchId]["resource5"] > 0)) {
					z+="<br>";
				}

				if (a["gold"] > 0) z += '<span class=xtab>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold) + addCommas(a["gold"]) +'</span> ';
				if (a["resource1"] > 0) z += '<span class=xtab>'+ResourceImage(FoodImage,uW.g_js_strings.commonstr.food) + addCommas(a["resource1"]) +'</span> ';
				if (a["resource2"] > 0) z += '<span class=xtab>'+ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood) + addCommas(a["resource2"]) +'</span> ';
				if (a["resource3"] > 0) z += '<span class=xtab>'+ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone) + addCommas(a["resource3"]) +'</span> ';
				if (a["resource4"] > 0) z += '<span class=xtab>'+ResourceImage(OreImage,uW.g_js_strings.commonstr.ore) + addCommas(a["resource4"]) +'</span> ';
				if (local_atkinc["m"+marchId]["resource5"] > 0) z += '<span class=xtab>'+ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone) + addCommas(local_atkinc["m"+marchId]["resource5"]) +'</span> ';
			}

			z += '</td></tr>';
		}

		if (!incomingshow) {
			if (!incomingfiltered)
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No incoming marches')+'</div></td></tr>';
			else
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No incoming marches matching search parameters')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		if (CheckForHTMLChange('INC','btIncomingMain',z)) {
			if (Options.DashboardOptions.RefreshSeed) jQuery('#btRefreshSeedInc').addClass("disabled");
			else ById('btRefreshSeedInc').addEventListener ('click', function() {setTimeout(function() {RefreshSeed();},250);}, false);
			ResetFrameSize('btIncoming',200,720);
		}
		for (var m in inctimes) {
			mt = inctimes[m];
			if (ById('marchtime'+m)) {
				ById('marchtime'+m).innerHTML = mt;
			}
		}
	},

	EverySecond : function () {
		var t = Incoming;

		try {
			if (((SecondLooper % Dashboard.GeneralInterval) == 1) || Dashboard.GeneralInterval == 1) {
				t.PaintIncoming();
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
}

/************************************ Outgoing Marches Popup *********************************************/

var Outgoing = {
	Options	: {
				OutgoingStartState	: false,
				OutAttack           : true,
				OutScout            : true,
				OutReinforce        : true,
				OutReassign         : false,
				OutTransport        : false,
				OutYours            : false,
				OutReturning        : false,
				OutResources        : false,
	},

	init : function () {
		var t = Outgoing;
		DefaultWindowPos('btOutPos','main_engagement_tabs');
		if (GlobalOptions.InOutToggle) {
			AddPowerBarLink(tx('Outgoing'), 'PBPOutButton', Outgoing.ToggleOutgoing,function(me) {ResetWindowPos (me,'main_engagement_tabs',popOut);});
		}
		HTMLRegister['OUT']= {};

		if (!Options.OutgoingOptions) {
			Options.OutgoingOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.OutgoingOptions.hasOwnProperty(y)) {
					Options.OutgoingOptions[y] = t.Options[y];
				}
			}
		}
		if (Options.OutgoingOptions.OutgoingStartState) {t.ToggleOutgoing();}
	},

	ToggleOutgoing : function () {
		var t = Outgoing;

		ResetHTMLRegister('OUT','btOutgoingMain');

		if (popOut) {
			Options.OutgoingOptions.OutgoingStartState = popOut.toggleHide(popOut)
		}
		else
		{
			m = '<div id=btOutgoingButtons align="center"><TABLE width="100%"><tr>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.attack+'</td><TD class=xtab><INPUT id=OutAttackChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.scout+'</td><TD class=xtab><INPUT id=OutScoutChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.reinforce+'</td><TD class=xtab><INPUT id=OutReinforceChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.reassign+'</td><TD class=xtab><INPUT id=OutReassignChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.transport+'</td><TD class=xtab><INPUT id=OutTransportChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.returning+'</td><TD class=xtab><INPUT id=OutReturningChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+tx('To You')+'</td><TD class=xtab><INPUT id=OutYoursChk type=checkbox /></td>';
			m += '<td align="right" class=xtab>'+uW.g_js_strings.commonstr.resources+'</td><TD class=xtab><INPUT id=OutResChk type=checkbox /></td>';
			m += '</tr></table></div><div style="max-height:700px; overflow-y:scroll" id=btOutgoingMain></div><br>';

			popOut = new CPopup('btOutgoing', Options.btOutPos.x, Options.btOutPos.y, 720, 200, true, Outgoing.close);
			popOut.getMainDiv().innerHTML = m;
			popOut.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Outgoing Marches')+'</B></DIV>';

			ToggleOption('OutgoingOptions','OutAttackChk','OutAttack');
			ToggleOption('OutgoingOptions','OutScoutChk','OutScout');
			ToggleOption('OutgoingOptions','OutReinforceChk','OutReinforce');
			ToggleOption('OutgoingOptions','OutReassignChk','OutReassign');
			ToggleOption('OutgoingOptions','OutTransportChk','OutTransport');
			ToggleOption('OutgoingOptions','OutReturningChk','OutReturning');
			ToggleOption('OutgoingOptions','OutYoursChk','OutYours');
			ToggleOption('OutgoingOptions','OutResChk','OutResources');

			popOut.show(true);
			Options.OutgoingOptions.OutgoingStartState = true;
		}
		saveOptions();
	},

	close : function () {
		Options.OutgoingOptions.OutgoingStartState = false;
		Options.btOutPos = popOut.getLocation();
		saveOptions();
		popOut=null;
	},

	PaintOutgoing : function () {
		var t = Outgoing;
		var z = '';
		var r = 0;
		var outgoingshow = false;
		var outgoingfiltered = false;
		var outtimes = {};

		var bclass = "brown11";
		if (RefreshingSeed || Options.DashboardOptions.RefreshSeed) bclass += " disabled";

		var z = '<div align="center"><TABLE cellSpacing=0 width=98% height=0%><tr><td width="18" class="xtabHD">&nbsp;</td><td width="60" class="xtabHD"><b>'+uW.g_js_strings.commonstr.time+'</b></td><td width="120" class="xtabHD"><b>'+tx('From')+'</b></td><td width="120" class="xtabHD"><b>'+uW.g_js_strings.commonstr.target+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td><td class="xtabHD" style="opacity:1.0"; align="right"><a id=btRefreshSeedOut class="inlineButton btButton '+bclass+'"><span>'+tx('Refresh')+'</span></a></td></tr>';

		for(n in out) {
			var a = out[n];
			var icon, hint, marchtime, fromcity, totile, tocity, toname, marchdir, tocoords;

			var marchId = a.marchId;
			var marchStatus = parseInt(a.marchStatus);
			var marchType = parseInt(a.marchType);
			if (marchType == 10) marchType=4; // Change Dark Forest type to Attack!

			var from = Cities.byID[a.marchCityId];if(!from)continue; // tampermonkey fix
			fromcity = CityLink(from);

			var now = unixTime();
			var destinationUnixTime = a["destinationUnixTime"] - now;
			var returnUnixTime = a["returnUnixTime"] - now;

			if ((returnUnixTime <= 0) && ((marchStatus == 8) || (marchStatus == 0))) continue; // never show returned march once completed

			if ((destinationUnixTime < 0) || (marchStatus == 8) || (marchStatus == 2))
				marchdir = "Return";
			else
				marchdir = "Count";

			totile = "";
			tocity = "";
			toname = "";
			for (var i=0; i<Seed.cities.length;i++) {
				if (Seed.cities[i][2] == parseInt(a["toXCoord"]) && Seed.cities[i][3] == parseInt(a["toYCoord"])) {tocity = CityLink(Cities.byID[Seed.cities[i][0]]);break; }
			}
			if (tocity == "") {
				totile = tileTypes[parseInt(a["toTileType"])];
				if (a["toTileType"] == 51) {
					if (!a["toPlayerId"]) { totile = ""; }
					else { if (a["toPlayerId"] == 0) totile = tx('Barb Camp'); }
				}
				totile = 'Lvl '+a["toTileLevel"]+' '+totile;
			}

			if (a["toPlayerId"] && (a["toPlayerId"] != 0)) {
				if (a["toPlayerId"] == uW.tvuid) {
					if (tocity == 0) {toname = tx('Yourself')}
				}
				else {
					if (a.players && a.players['u'+a.toPlayerId]) {
						toname = MonitorLink(a.toPlayerId,a.players['u'+a.toPlayerId].n);
					}
					else {
						if (Seed.players['u'+a.toPlayerId]) {
							toname = MonitorLink(a.toPlayerId,Seed.players['u'+a.toPlayerId].n);
						}
					}
					if (toname == "") { updatePlayers (a.toPlayerId); } // let's fix it!
				}
			}

			var iconType = marchType;

			if (destinationUnixTime >= 0) {
				if (destinationUnixTime < (60)) { marchtime = '<span style="color:#f00">'+uW.timestr(destinationUnixTime)+'</span>'; }
				else { marchtime = uW.timestr(destinationUnixTime); }
			}
			else {
				if (marchStatus == 2) {
					marchtime = uW.g_js_strings.commonstr.encamped;
					iconType = 102;
				}
				else {
					if (marchStatus == 8) {
						marchtime = uW.timestr(returnUnixTime);
						iconType = 8;
					}
					else {
						marchtime = tx("Waiting");
						iconType = 102;
					}
				}
			}

			outtimes[marchId] = marchtime;

			if (!a.toXCoord || (tocity != "")) {tocoords = "";}
			else {tocoords = coordLink(a.toXCoord,a.toYCoord);}

			hint = "";
			switch (marchType) {
				case 1: hint=uW.g_js_strings.commonstr.transport;break;
				case 2: hint=uW.g_js_strings.commonstr.reinforce;break;
				case 3: hint=uW.g_js_strings.commonstr.scout;break;
				case 4: hint=uW.g_js_strings.commonstr.attack;break;
				case 5: hint=uW.g_js_strings.commonstr.reassign;break;
			}

			switch (iconType) {
				case 1: icon=TransportImage;break;
				case 2: icon=ReinforceImage;break;
				case 3: icon=ScoutImage;break;
				case 4: icon=AttackImage;break;
				case 5: icon=ReassignImage;break;
				case 8: icon=ReturnImage;break;
				case 102: icon=ReinforceImage;break;
			}
			hint=tx('Recall March')+" ("+marchId+")";

			outgoingfiltered = true;

			/* Apply Filters */

			if ((marchType == 1) && !Options.OutgoingOptions.OutTransport) continue;
			if ((marchType == 2) && !Options.OutgoingOptions.OutReinforce) continue;
			if ((marchType == 5) && !Options.OutgoingOptions.OutReassign) continue;

			if ((marchType == 3) && !Options.OutgoingOptions.OutScout) continue;
			if ((marchType == 4) && !Options.OutgoingOptions.OutAttack) continue;

			if (((marchdir == "Return") && (marchStatus != 2) && (marchtime != "Waiting")) && !Options.OutgoingOptions.OutReturning) continue;
			if (((toname == "Yourself") || (tocity != 0)) && !Options.OutgoingOptions.OutYours && marchType != 5) continue; // irrelevent for reassigns!

			outgoingshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'"><TD class=xtab><a id="btRecall'+a.marchId+'" onclick="btRecall('+ a.marchId +')"><img src='+icon+' title='+hint+'></a></td>';
			z += '<TD class=xtab id="omarchtime'+marchId+'">&nbsp;</td>';
			z += '<TD class=xtabBR>';
			if (fromcity != "") z += '<span class=xtab>'+fromcity+'</span> ';
			z += '</td><TD class=xtabBR>';
			if (toname != "") { z+= '<span class=xtab>'+toname+'</span> '; }
			if (totile != "") { z+= '<span class=xtab>'+totile+'</span> '; }
			if (tocity != "") { z+= '<span class=xtab>'+tocity+'</span> '; }
			if (tocoords != "") { z+= '<span class=xtab>'+tocoords+'</span>'; }
			z += '</td>';

			z += '<TD colspan=2 class=xtabBR>';

			if (a["championInfo"]) { // stats here are sort of obsolete, because it uses city champ data, but kept in for completeness...
				marchchamp = "<table cellspacing=0 class=xtab><tr><td colspan=2><b>"+a["championInfo"].name+"</b></td></tr><tr><td colspan=2><b>"+uW.g_js_strings.report_view.champion_stats+"</b></td></tr>";
				var gotchamp = false;
				if (a["championInfo"].effects) {
					if (a["championInfo"].effects[1] && !(a["championInfo"].effects[1] instanceof Array) && typeof(a["championInfo"].effects[1]) === "object") {
						got202 = false;
						for (var cy in a["championInfo"].effects[1]) {
							// missing bonus damage?
							if ((cy == '202') && gotchamp) {got202 = true;}
							if ((cy == '203') && !got202) { marchchamp += "<tr><td>"+uW.g_js_strings.effects.name_202+"</td><td>0</td></tr>"; }
							str = eval('uW.g_js_strings.effects.name_'+cy);
							if (str && str!= "") {
								gotchamp = true;
								marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[1][cy]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gotchamp) { marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					marchchamp+="<tr><td colspan=2><b>"+uW.g_js_strings.report_view.troop_stats+"</b></td></tr>";
					var gottroop = false;
					if (a["championInfo"].effects[2] && !(a["championInfo"].effects[2] instanceof Array) && typeof(a["championInfo"].effects[2]) === "object") {
						for (var ty in a["championInfo"].effects[2]) {
							str = eval('uW.g_js_strings.effects.name_'+ty);
							if (str && str!= "") {
								gottroop = true;
								marchchamp += "<tr><td>"+str+"</td><td>"+a["championInfo"].effects[2][ty]+"</td></tr>";
							} else { break;	}
						}
					}
					if (!gottroop) { marchchamp += '<tr><td colspan=2><i>'+tx('None Available')+'</i></td></tr>'; }
					marchchamp+="</table>";
				}
				z +='<table cellspacing=0><tr><td class="xtab trimg" style="font-weight:normal;align:left;" id="btoutmarchchamp'+a.marchId+'td"><input type="hidden" id="btoutmarchchamp'+a.marchId+'effects" value="'+marchchamp+'" /><a><img id="btoutmarchchamp'+a.marchId+'" onMouseover="btCreateChampionPopUp(this,'+a.fromCityId+',true);" height=14 style="vertical-align:text-top;" src="'+ShieldImage+'"></a></td><td class=xtab>'+tx('Champion')+': '+a["championInfo"].name+'&nbsp;</td></tr></table>';
			}
			if ((a["knightId"] > 0) && (!a["knightCombat"])) {
				for (var i in Seed.knights["city"+a.marchCityId]) {
					if (i == ("knt" + a["knightId"])) {
						Combat = Seed.knights["city"+a.marchCityId][i]["combat"];
						if (Seed.knights["city"+a.marchCityId][i]["combatBoostExpireUnixtime"] > unixTime()) {	Combat *= 1.25;	}
						a["knightCombat"] = Combat;
					}
				}
			}

			if (a.btIncomplete == true && Options.FetchMarchInfo) {marchdir = "Count";	} // no return info yet
			if (a["knightId"] > 0) z +='<span class=xtab>'+uW.g_js_strings.commonstr.knight+' (Atk:'+ a["knightCombat"]+')</span> ';
			for (var ui in uW.cm.UNIT_TYPES){
				i = uW.cm.UNIT_TYPES[ui];
				if((a["unit"+i+"Count"] > 0) || (a["unit"+i+"Return"] > 0)) {
					trpcol = '#000';
					if ((marchdir == "Return") && (a["unit"+i+"Return"] < a["unit"+i+"Count"])) { trpcol = '#f00'; }
					z += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': <span class=xtab style="color:'+trpcol+'">'+ addCommas(a["unit"+i+marchdir])+'</span></span> ';
				}
			}

			if (a["fromSpellType"]) {
				var spell = eval('uW.g_js_strings.spells.name_'+a["fromSpellType"]);
				if (spell) {
					var spellstyle = 'color:#808;';
					z +='<br><span class=xtab style="'+spellstyle+'"><b>*&nbsp;'+spell+'&nbsp;*</b></span>'
				}
			}

			if (Options.OutgoingOptions.OutResources) {
				if ((a["gold"] > 0) || (a["resource1"] > 0) || (a["resource2"] > 0) || (a["resource3"] > 0) || (a["resource4"] > 0) || (a["resource5"] > 0)) {
					z+="<br>";
				}

				if (a["gold"] > 0) z += '<span class=xtab>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold) + addCommas(a["gold"]) +'</span> ';
				if (a["resource1"] > 0) z += '<span class=xtab>'+ResourceImage(FoodImage,uW.g_js_strings.commonstr.food) + addCommas(a["resource1"]) +'</span> ';
				if (a["resource2"] > 0) z += '<span class=xtab>'+ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood) + addCommas(a["resource2"]) +'</span> ';
				if (a["resource3"] > 0) z += '<span class=xtab>'+ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone) + addCommas(a["resource3"]) +'</span> ';
				if (a["resource4"] > 0) z += '<span class=xtab>'+ResourceImage(OreImage,uW.g_js_strings.commonstr.ore) + addCommas(a["resource4"]) +'</span> ';
				if (a["resource5"] > 0) z += '<span class=xtab>'+ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone) + addCommas(a["resource5"]) +'</span> ';
			}

			z += '</td></tr>';
		}

		if (!outgoingshow) {
			if (!outgoingfiltered)
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No outgoing marches')+'</div></td></tr>';
			else
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No outgoing marches matching search parameters')+'</div></td></tr>';
		}

		z += '<tr><td class=xtab colspan="6"><div class="ErrText" align="center" id=btOutErr>&nbsp;</div></td></tr></table></div><br>';

		if (CheckForHTMLChange('OUT','btOutgoingMain',z)) {
			if (Options.DashboardOptions.RefreshSeed) jQuery('#btRefreshSeedOut').addClass("disabled");
			else ById('btRefreshSeedOut').addEventListener ('click', function() {setTimeout(function() {RefreshSeed();},250);}, false);
			ResetFrameSize('btOutgoing',200,720);
		}
		for (var m in outtimes) {
			mt = outtimes[m];
			if (ById('omarchtime'+m)) {
				ById('omarchtime'+m).innerHTML = mt;
			}
		}
	},

	EverySecond : function () {
		var t = Outgoing;

		try {
			if (((SecondLooper % Dashboard.GeneralInterval) == 1) || Dashboard.GeneralInterval == 1) {
				t.PaintOutgoing();
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},

}

/************************************* QUICK SCOUT ********************************/

QuickScout = {
	init : function () {
		var t = QuickScout;

		try {
			// add new options to the context menu

			uW.cm.ContextMenuMapController.prototype.MapContextMenus.City["5"].push("aamod");
			uW.cm.ContextMenuMapController.prototype.MapContextMenus.City["5"].push("qqmod");
			if (Options.OneClickAttack)
				uW.cm.ContextMenuMapController.prototype.MapContextMenus.City["5"].push("qamod");
			var cityType = CM.CITY_STATUS.ANOTHER_PLAYER_CITY_AND_NOT_IN_YOUR_ALLIANCE;
			uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[cityType].push("aamod");
			uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[cityType].push("qqmod");
			if (Options.OneClickAttack)
				uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[cityType].push("qamod");
			var wildContext;
			wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.EnemyWilderness;
			for (var wild in wildContext) {
				wildContext[wild].push("aamod");
				wildContext[wild].push("qqmod");
				if (Options.OneClickAttack)
					wildContext[wild].push("qamod");
			}
			wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.Wilderness;
			for (var wild in wildContext) {
				wildContext[wild].push("aamod");
				wildContext[wild].push("qqmod");
				if (Options.OneClickAttack)
					wildContext[wild].push("qamod");
			}
			wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.FriendlyWilderness;
			for (var wild in wildContext) {
				wildContext[wild].push("aamod");
				wildContext[wild].push("qqmod");
				if (Options.OneClickAttack)
					wildContext[wild].push("qamod");
			}

			// add actions to the menu item
			var mod = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo',
			[['default:', 'case "qqmod":' +
				' b.text = "'+tx('QuickScout')+'"; b.color = "green"; ' +
				' b.action = function () { ' +
				' quickscout(e); ' +
				' }; ' +
				' d.push(b); break; ' +
				'case "qamod":' +
				' b.text = "'+tx('QuickAttack')+'"; b.color = "red"; ' +
				' b.action = function () { ' +
				' quickattack(e); ' +
				' }; ' +
				' d.push(b); break; ' +
				'case "aamod":' +
				' b.text = "'+tx('Auto Attack')+'"; b.color = "blue"; ' +
				' b.action = function () { ' +
				' autoattack(e); ' +
				' }; ' +
				' d.push(b); break; ' +
				' default: ']]);

			mod.setEnable(true);

			function FNQuickScout(e) {
				// send 1 scout
				var params = uW.Object.clone(uW.g_ajaxparams);
				params.cid = uW.currentcityid;
				params.type = 3
				params.kid = 0
				params.xcoord = e.tile.x;
				params.ycoord = e.tile.y;
				params.u3 = 1;
				params.gold = 0;
				params.r1 = 0;
				params.r2 = 0;
				params.r3 = 0;
				params.r4 = 0;
				params.r5 = 0;

				March.addMarch(params, function(rslt){
					if (rslt.ok) {
						if (e.tile.level == 0 && (Options.FetchMarchInfo)) QuickScout.fetchmarch(rslt.marchId,QuickScout.PlayerPopup); // mist scout
					}
					else {
						uW.Modal.showAlert(uW.printLocalError(rslt.error_code, rslt.msg, rslt.feedback));
					}
				}, true); // force march so it never gets queued
			}
			uWExportFunction('quickscout', FNQuickScout);

			function FNQuickScoutSearch (x,y,cid,auto) {
				// if auto check rally slots

				if (auto) {
					var marches = parseIntNan(March.getMarchSlots(cid));
					var maxmarches = parseIntNan(March.getTotalSlots(cid));
					var keepfree = Number(Options.FreeRallySlots);
					if ((marches+keepfree) >= maxmarches) {
						divid = 'pbsrch_'+x+'_'+y;
						if (ById(divid)) {
							msg = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Rally Point Full')+'!</span>&nbsp;&nbsp;<SPAN onclick="quickscoutsearch('+x+','+y+','+cid+');return false;"><A>'+tx("QuickScout")+'</a></span>';
							ById(divid).innerHTML = msg;
						}
						if (Tabs.Search) { Tabs.Search.QSMarching[x+'_'+y] = 0; }
						return;
					}
				}

				// send 1 scout
				var params = uW.Object.clone(uW.g_ajaxparams);
				if (cid==null)
					params.cid = uW.currentcityid;
				else
					params.cid = cid;
				params.type = 3
				params.kid = 0
				params.xcoord = x;
				params.ycoord = y;
				params.u3 = 1;
				params.gold = 0;
				params.r1 = 0;
				params.r2 = 0;
				params.r3 = 0;
				params.r4 = 0;
				params.r5 = 0;

				March.addMarch(params, function(rslt){
					if (rslt.ok) {
						QuickScout.fetchmarch(rslt.marchId,QuickScout.FillSearchDiv); // mist scout
					}
					else {
						divid = 'pbsrch_'+x+'_'+y;
						if (!ById(divid)) return;
						var msg = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Error Code')+' - '+rslt.error_code+'</span>&nbsp;&nbsp;<SPAN onclick="quickscoutsearch('+x+','+y+','+cid+');return false;"><A>'+tx("QuickScout")+'</a></span>';
						if(rslt.error_code == 208 || rslt.error_code == 207) { // errors that mean you can never scout
							if (rslt.error_code == 208) {
								msg = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Target is truced - Cannot scout')+'!</span>';
							}
							else {
								msg = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('You are truced - Cannot scout another player')+'!</span>';
							}
							// update search results .. find correct row
							var t = Tabs.Search;
							if (t) {
								var numRows = t.mapDat.length;
								for (var i=0; i<numRows; i++){
									if (t.mapDat[i][0] == x && t.mapDat[i][1] == y) {
										t.mapDat[i][6] = 0;
										t.mapDat[i][8] = msg;
									}
								}
							}
						}
						if(rslt.error_code == 210) { // errors that mean you may be able to scout in a bit!
							msg = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Rally Point Full')+'!</span>&nbsp;&nbsp;<SPAN onclick="quickscoutsearch('+x+','+y+','+cid+');return false;"><A>'+tx("QuickScout")+'</a></span>';
						}
						ById(divid).innerHTML = msg;
						if (Tabs.Search) {
							Tabs.Search.scouted++;
							Tabs.Search.updateMistProgress();
						}
					}
					if (Tabs.Search) { Tabs.Search.QSMarching[x+'_'+y] = 0; }
				});
			}
			uWExportFunction('quickscoutsearch', FNQuickScoutSearch);

			function FNQuickAttack (e) {
				if (Options.OneClickAttackPreset == 0 || !Options.QuickMarchOptions.MarchPresets[Options.OneClickAttackPreset]) {
					QuickMarch.MapClick(e.tile.x,e.tile.y);
					return;
				}

				// send selected preset on attack

				var knt = getAvailableKnights(uW.currentcityid);
				if (!knt[0]) {
					QuickMarch.MapClick(e.tile.x,e.tile.y);
					return;
				}

				var params = uW.Object.clone(uW.g_ajaxparams);
				params.cid = uW.currentcityid;
				params.type = 4
				params.kid = knt[0].ID;
				params.xcoord = e.tile.x;
				params.ycoord = e.tile.y;
				params.gold = 0;
				params.r1 = 0;
				params.r2 = 0;
				params.r3 = 0;
				params.r4 = 0;
				params.r5 = 0;

				for (var ui in uW.cm.UNIT_TYPES) {
					var i = uW.cm.UNIT_TYPES[ui];
					params["u"+i] = 0;
					if (Options.QuickMarchOptions.MarchPresets[Options.OneClickAttackPreset][i]) {
						params["u"+i] = parseIntNan(Options.QuickMarchOptions.MarchPresets[Options.OneClickAttackPreset][i]);
					}
				}

				var iused = new Array();
				for (var i = 0; i < QuickMarch.ItemList.length; i++) {
					if (Options.QuickMarchOptions.MarchPresets[Options.OneClickAttackPreset]["item"+QuickMarch.ItemList[i]] == true && Seed.items["i"+QuickMarch.ItemList[i]]) {
						iused.push(QuickMarch.ItemList[i]);
					}
				}
				params.items = iused.join(",");

				params.champid = 0;
				if (Options.QuickMarchOptions.AutoChamp) {
					for (var y in Seed.champion.champions) {
						citychamp = Seed.champion.champions[y];
						if (citychamp.assignedCity == uW.currentcityid) {
							var champstatus = citychamp.status;
							if (champstatus != "10") { params.champid = citychamp.championId; }
							break;
						}
					}
				}

				if (Options.QuickMarchOptions.AutoSpell) {
					var spells = getSpellData(uW.currentcityid);
					if (spells.spellavailable && !spells.cooldownactive) {
						params.bs = SpellTypes[faction];
					}
				}

				March.addMarch(params, function(rslt){
					if (!rslt.ok) {
						uW.Modal.showAlert(uW.printLocalError(rslt.error_code, rslt.msg, rslt.feedback));
					}
				}, true); // force march so it never gets queued
			}

			uWExportFunction('quickattack', FNQuickAttack);

			function FNAutoAttack (e) {
				Tabs.Attack.NewRoute(e.tile.x,e.tile.y);
				ById('bttcAttack').click();
			};

			uWExportFunction('autoattack', FNAutoAttack);

		}
		catch (err) {
			logerr(err); // write to log
		}
	},

	fetchmarch : function (mid,notify) {
		var t = QuickScout;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.rid = mid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchMarch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (!rslt.ok){ return; }
				if (rslt.march.toPlayerId != 0) {
					t.fetchmarchPlayerInfo(rslt.march.toPlayerId, notify, rslt.march)
				}
				else {
					notify({errorMsg:"<div>"+tx('There is no longer a city at this location')+"</div>"}, rslt.march);
				}
			},
			onFailure: function () {notify ({errorMsg:'AJAX error'});}
		},true);
	},

	fetchmarchPlayerInfo : function (uid, notify, march) {
		var t = QuickScout;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify (rslt,march); },
			onFailure: function () { notify ({errorMsg:'AJAX error'}); },
		},true);
	},

	PlayerPopup : function (rslt,march) {
		var t = QuickScout;
		if(rslt.errorMsg) {
			Dashboard.Recall(march.marchId);
			uW.Modal.showAlert(rslt.errorMsg);
			return;
		}

		var u = rslt.userInfo[0];

		var a = 'None';
		if (u.allianceName)
			a = u.allianceName +' ('+ getDiplomacy(u.allianceId) + ')';

		var n = '<div> <b>Name:</b> ' + u.genderAndName + '<br/><b>Might:</b> ' + addCommas(parseInt(u.might)) +
		'<br/><b>' + uW.g_js_strings.commonstr.alliance+':</b> '+ a +
		'<br/><b>'+tx('City Co-ords')+':</b> ('+ march.toXCoord + ',' + march.toYCoord + ')' +
		'<br/><b>'+tx('City Level')+':</b> '+ march.toTileLevel +
		"</div>";

		uW.Modal.multiButton({
			buttons: [{
				txt: "Recall Scout",
				exe: function () {
					uW.attack_recall(march.marchId, 2, uW.currentcityid);
					uW.Modal.hideModal();
				}
			}, {
				txt: "Post to Chat",
				exe: function () {
					cText = 'Name: ' + u.genderAndName + '||UID: ' + enFilter(u.userId)+'||Might: ' + addCommas(parseInt(u.might)) +
							'||' + uW.g_js_strings.commonstr.alliance+': '+ a +
							'||City Co-ords: ('+ march.toXCoord + ',' + march.toYCoord + ')' +
							'||City Level: '+ march.toTileLevel;
					cText = ":::. |QuickScout Report|| "+ cText;
					sendChat ("/a "+  cText);
				}
			}, {
				txt: "Monitor",
				exe: function () {
					uW.btMonitorExternalCallUID(u.userId);
				}
			}, {
				txt: uW.g_js_strings.commonstr.cancel,
				exe: function () {
					uW.Modal.hideModal();
				}
			}],
			body: n,
			title: "QuickScout Result"
		});
	},

	FillSearchDiv : function (rslt,march) {
		setTimeout (Dashboard.Recall,2000,march.marchId);
		divid = 'pbsrch_'+march.toXCoord+'_'+march.toYCoord;
		if (!ById(divid)) return;

		if(rslt.errorMsg) {
			var n = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Misted Plain';
			ById(divid).innerHTML = n;
			// update search results .. find correct row
			var t = Tabs.Search;
			if (t) {
				var numRows = t.mapDat.length;
				for (var i=0; i<numRows; i++){
					if (t.mapDat[i][0] == march.toXCoord && t.mapDat[i][1] == march.toYCoord) {
						t.mapDat[i][4] = parseIntNan(march.toTileLevel);
						t.mapDat[i][6] = 0;
						t.mapDat[i][8] = n;
						t.mapDat[i][9] = 0;
						t.mapDat[i][10] = '';
						t.mapDat[i][11] = 0;
					}
				}
			}
			Tabs.Search.scouted++;
			Tabs.Search.updateMistProgress();
			return;
		}

		var rowStyle = 'style="opacity:0.5;"'; // misted
		var status = '<img title="Offline" style="vertical-align:bottom" src="'+OFFLINE+'"/>';
		var u = rslt.userInfo[0];
		var alli = '---';
		var aID = parseIntNan(u.allianceId);
		if (aID!=0) {
			alli = u.allianceName;
		}

		var n = '<td '+rowStyle+' class=xtab nowrap>'+status+PlayerLink(u.userId,u.name)+'</td><td '+rowStyle+' class=xtab>&nbsp;</td><td '+rowStyle+' class=xtab align=right>'+addCommas(parseIntNan(u.might))+'</span></td><td '+rowStyle+' class=xtab><span style='+DiplomacyColours(aID)+'>'+alli+'</span></td>';
		ById(divid).outerHTML = n;

		// update search results .. find correct row

		var t = Tabs.Search;
		if (t) {
			var numRows = t.mapDat.length;
			for (var i=0; i<numRows; i++){
				if (t.mapDat[i][0] == march.toXCoord && t.mapDat[i][1] == march.toYCoord) {
					t.mapDat[i][4] = parseIntNan(march.toTileLevel);
					t.mapDat[i][5] = march.toCityId;
					t.mapDat[i][6] = u.userId;
					t.mapDat[i][8] = u.name;
					t.mapDat[i][9] = parseIntNan(u.might);
					t.mapDat[i][10] = alli;
					t.mapDat[i][11] = aID;

					// fire off player online query
					var uList = [];
					uList.push(u.userId);
					getOnline(uList,function(r) {	var t = Tabs.Search;
													var numRows = t.mapDat.length;
													for (var u in r.data) {
														for (var i=0; i<numRows; i++) {
															if (t.mapDat[i][6] == u) { t.mapDat[i][12] = r.data[u]?1:0;}
														}
													}
													t.dispMapTable ();
												});
					Tabs.Search.scouted++;
					Tabs.Search.updateMistProgress();
				}
			}
		}
	},
}

/************************************ Quick March Popup *********************************************/

var QuickMarch = {
	LoopCounter : 0,
	Options : {
				QuickMarchStartState	: false,
				StartCoords				: {x:'',y:''},
				AutoKnight				: false,
				AutoChamp				: false,
				AutoSpell				: false,
				MarchPresets			: {},
	},
	SourceCity: {},
	MapX : null,
	MapY : null,
	MapC : null,
	MapLaunch : false,
	MapAjax : new CMapAjax(),
	Blocks : [],
	targetType : null,
	dcp0 : null,
	dcp1 : null,
	ItemList : [55, 57, 931, 932, 293, 294],
	MaxTroops : 0,
	MaxLoad : 0,
	NextPresetNumber : 0,
	InitPresetNumber : 0,
	distance : 0,
	Food : 0,
	Wood : 0,
	Stone : 0,
	Ore : 0,
	Gold : 0,
	Aether : 0,

	init : function () {
		var t = QuickMarch;
		if (GlobalOptions.MarchPlusToggle) {
			AddPowerBarLink(tx('March+'), 'PBPMarchButton', function() { QuickMarch.ToggleQuickMarch(false); },function(me) {ResetWindowPos (me,'main_engagement_tabs',popMarch);});
		}

		// add new options to the context menu

		uW.cm.ContextMenuMapController.prototype.MapContextMenus.City["5"].push("portal"); // add portal to mists
		for (var a in uW.cm.ContextMenuMapController.prototype.MapContextMenus) {
			for (var b in uW.cm.ContextMenuMapController.prototype.MapContextMenus[a]) {
				uW.cm.ContextMenuMapController.prototype.MapContextMenus[a][b].unshift("qmmod");
			}
		}

		var mod = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo',
		[['default:', 'case "qmmod":' +
			' b.text = "'+tx('March+')+'"; b.color = "green"; ' +
			' b.action = function () { ' +
			' quickmarch(e); ' +
			' }; ' +
			' d.push(b); break; ' +
			' default: ']]);
		mod.setEnable(true);

		function FNQuickMarch (e) {
			QuickMarch.MapClick(e.tile.x,e.tile.y);
		}

		function ApplyingBoost() {
			var div = ById('btboostmsg');
			if (div) { div.innerHTML = tx('Applying Boost')+'...'; }
		}

		uWExportFunction('quickmarch', FNQuickMarch);
		uWExportFunction('QMspeedupSpell',QuickMarch.speedupSpell);
		uWExportFunction('btApplyingBoost', ApplyingBoost);

		DefaultWindowPos('btMarchPos','main_engagement_tabs');

		if (!Options.QuickMarchOptions) {
			Options.QuickMarchOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.QuickMarchOptions.hasOwnProperty(y)) {
					Options.QuickMarchOptions[y] = t.Options[y];
				}
			}
		}

		if (Options.QuickMarchOptions.QuickMarchStartState) {
			t.MapX = Options.QuickMarchOptions.StartCoords.x;
			t.MapY = Options.QuickMarchOptions.StartCoords.y;
			t.MapLaunch = true;
			t.ToggleQuickMarch(true);
		}
	},

	ToggleQuickMarch : function (init) {
		var t = QuickMarch;

		if (popMarch) {
			Options.QuickMarchOptions.QuickMarchStartState = popMarch.toggleHide(popMarch)
		}
		else {
			t.Food = 0;
			t.Wood = 0;
			t.Stone = 0;
			t.Ore = 0;
			t.Gold = 0;
			t.Aether = 0;

			m = '<div id=btMarchCoords align="center">';
			m += '<table align=center width=98% cellpadding=0 cellspacing=2 class=xtab style="padding-right:0px;"><tr><td style="padding-left:0px;padding-right:0px;"><div class=divHeader>&nbsp;'+tx('FROM')+'</div></td><td style="padding-left:0px;padding-right:0px;"><div class=divHeader>&nbsp;'+tx('TO')+'</div></td></tr>';
			m += '<tr><td width=50% style="border:1px solid;vertical-align:top;"><table cellpadding=0 cellspacing=0 width=100% class=xtab style="padding-left:6px;padding-right:0px;"><tr height=20><td colspan=3><span id=QMFromCity>&nbsp;</span></td></tr>';
			m += '<tr height=20><td colspan=3><a id=QMSelClosest>'+tx('Select Closest City to Destination')+'</a></td></tr>';
			m += '<tr height=20><td colspan=2>'+tx('Rally Point')+':&nbsp;<span id=QMRP>&nbsp;</span></td><td align=right>'+tx('Auto')+'</td></tr>';
			m += '<tr height=20><td width=50>'+uW.g_js_strings.commonstr.knight+'&nbsp;</td><td><SELECT id=QMKnight class=btInput style="max-width:160px;"></select></td><td align=right><INPUT type=checkbox id=QMAutoKnight '+(Options.QuickMarchOptions.AutoKnight?'CHECKED':'')+' /></td></tr>';
			m += '<tr height=20><td>'+tx('Champ')+'&nbsp;</td><td><span id=QMChampSpan><SELECT id=QMChamp class=btInput style="max-width:160px;"></select></span><span id=QMNoChampSpan class=divHide>&nbsp;</span></td><td align=right><INPUT type=checkbox id=QMAutoChamp '+(Options.QuickMarchOptions.AutoChamp?'CHECKED':'')+' /></td></tr>';
			m += '<tr height=40><td style="padding-top:2px;vertical-align:top;">'+tx('Spell')+'&nbsp;</td><td style="padding-top:2px;vertical-align:top;"><span id=QMSpellSpan><SELECT id=QMSpell class=btInput style="max-width:160px;"></select></span><span id=QMNoSpellSpan class=divHide>&nbsp;</span></td><td  style="padding-top:2px;vertical-align:top;" align=right><INPUT type=checkbox id=QMAutoSpell '+(Options.QuickMarchOptions.AutoSpell?'CHECKED':'')+' /></td></tr>';
			m += '</table></td><td width=50% style="border:1px solid;vertical-align:top;"><table cellpadding=0 cellspacing=0 width=100% class=xtab style="padding-left:6px;padding-right:0px;"><tr height=20><td>X:<input type=text class=btInput id=QMToX size=3>&nbsp;Y:<input type=text class=btInput id=QMToY size=3></td><td>'+tx('Dist')+':&nbsp;<b><span id=QMDist>&nbsp;<span></b></td><td align=right><div id=QMLookupButtonDiv><a id=QMLookupButton class="inlineButton btButton brown8"><span>'+tx('Lookup')+'</span></a>&nbsp;<a id=QMMapButton class="inlineButton btButton brown8"><span>'+tx('Map')+'</span></a></div></td></tr>';
			m += '<tr height=20><td colspan=3 id=QMLookupInfo>&nbsp;</td></tr>';
			m += '<tr height=20><td colspan=3 id=QMTime>&nbsp;</td></tr>';
			m += '<tr height=20><td colspan=3><b>'+tx('Quick Links')+':</b></td></tr>';
			m += '<tr height=20><td colspan=3><span id=QMToCity>&nbsp;</span></td></tr>';
			m += '<tr height=20><td width=50><a title="'+tx('click to load bookmarks')+'" id=QMFetchBookmarks>'+tx('Bookmarks')+':</a></td><td colspan=2><select title="'+tx('click text to load bookmarks')+'" id=QMBookmarks class=btInput style="max-width:180px;"></select></td></tr>';
			m += '<tr height=20><td><a title="'+tx('click to load alliance city co-ords')+'" id=QMFetchAlliance>'+uW.g_js_strings.commonstr.alliance+':</a></td><td colspan=2><select title="'+tx('click text to load alliance city co-ords')+'" id=QMAlliance class=btInput style="max-width:180px;"></select></td></tr>';
			m += '</table></td></tr></table></div>';
			m += '<div id=btMarchMessages align="center" style="height:30px;max-height:30px;overflow-y:auto;">&nbsp;</div>';
			m += '<div id=btMarchAction align="center"><input type=button id=QMScout value="'+uW.g_js_strings.commonstr.scout+'">&nbsp;<input type=button id=QMAttack value="'+uW.g_js_strings.commonstr.attack+'">&nbsp<input type=button id=QMReassign value="'+uW.g_js_strings.commonstr.reassign+'">&nbsp;<input type=button id=QMReinforce value="'+uW.g_js_strings.commonstr.reinforce+'">&nbsp;<input type=button id=QMReinforceFood value="'+uW.g_js_strings.commonstr.reinforce+' + '+tx("Max Food")+'">&nbsp;<input type=button id=QMTransport value="'+uW.g_js_strings.commonstr.transport+'">&nbsp;<input type=button id=QMRaid value="'+uW.g_js_strings.commonstr.raid+'"></div>';
			m += '<div id=btMarchPresets align="center" class=divHeader>'+tx('MARCH PRESETS')+'</div>';

			m +='<div><table class=xtab width=100%><tr><td><SELECT class="btSelector" style="width:190px;" id="QMMarchPreset" onchange="btSelectMarchPreset(this);"></select>&nbsp;<a id="btDeleteMarchPreset" class="inlineButton btButton brown8 disabled" onclick="btDelMarchPreset()"><span>'+uW.g_js_strings.commonstr.deletetx+'</span></a></td><td align=right>';
			m +=tx('New Name')+':&nbsp;<INPUT class=btInput id=QMPresetName type=text style="width:190px;" maxlength=20 value=""\>&nbsp;<a id="btSaveMarchPreset" class="inlineButton btButton brown8" onclick="btSaveMarchPreset()"><span>'+tx('Save')+'</span></a></td></tr></table></div>';

			m += '<div id=btMarchMain align="center"><table align=center width=100% cellpadding=0 cellspacing=1 class=xtab style="padding-right:0px;"><tr><td style="padding-left:0px;"><div class=divHeader><table cellpadding=0 cellspacing=0 width=100% class=xtab><tr><td align=left>'+tx('TROOPS')+'</td><td id=QMTroopHeader align=right>&nbsp;</td></tr></table></div></td><td style="padding-left:0px;"><div class=divHeader><table cellpadding=0 cellspacing=0 width=100% class=xtab><tr><td align=left>'+tx('RESOURCES')+'</td><td id=QMResourceHeader align=right>&nbsp;</td></tr></table></div></td></tr>';
			m += '<tr><td width=50% style="vertical-align:top;"><table cellpadding=0 cellspacing=0 width=98% class=xtab>';

			var r = 0;
			var QMTroops = '<table cellpadding=0 cellspacing=0 class=xtab align=left><tr><td colspan=2>&nbsp;</td><td><a id=QMResetTroops>'+tx('Reset Troops')+'</a></td></tr>';
			for (var ui in uW.cm.UNIT_TYPES) {
				i = uW.cm.UNIT_TYPES[ui];
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
				QMTroops += '<tr class="'+rowClass+'"><td style="padding-left:0px;width:20px;" align=right>'+TroopImage(i)+'</td><td style="width:100px;" id="QMTotalUnit'+i+'" align=left>&nbsp;</td><td align=left><input style="width:60px;" class=btInput id="QMMarchUnit'+i+'" type=text maxlength=7 value=0 ></td><td align=left><input style="height:20px;font-size:9px;" id="QMMaxUnit'+i+'" type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			}
			m += '</table><tr><td style="padding-left:5px;">'+QMTroops+'</td></tr>';

			m += '</table></td><td width=50% style="vertical-align:top;padding-left:0px;padding-right:0px;"><table cellpadding=0 cellspacing=0 width=98% class=xtab>';

			var QMRes = '<table class=xtab align=center><tr><td>&nbsp;</td><td><a id=QMResetResources>'+tx('Reset Resources')+'</a></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+GoldImage+'" /></td><td><span id=QMTotalGold>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchGold type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxGold type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+FoodImage+'" /></td><td><span id=QMTotalFood>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchFood type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxFood type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+WoodImage+'" /></td><td><span id=QMTotalWood>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchWood type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxWood type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+StoneImage+'" /></td><td><span id=QMTotalStone>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchStone type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxStone type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+OreImage+'" /></td><td><span id=QMTotalOre>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchOre type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxOre type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '<tr><td rowspan=2><img src="'+AetherImage+'" /></td><td><span id=QMTotalAether>&nbsp;</span></td></tr>';
			QMRes += '<tr style="height:30px;vertical-align:top;"><td><INPUT class=btInput id=QMMarchAether type=text size=11 maxlength=20 value=0\><input style="height:20px;font-size:9px;" id=QMMaxAether type=button value="'+uW.g_js_strings.commonstr.max+'"></td></tr>';
			QMRes += '</table>';
			m += '<tr><td style="vertical-align:top;">'+QMRes+'</td></tr>';

			m += '</table><div class=divHeader>&nbsp;'+tx('BOOSTS')+'</div>';

			var QMBoosts = '<table width=100% class=xtab align=left cellpadding=0 cellspacing=0><tr><td align=left>&nbsp;'+tx('March Speed')+':&nbsp;<b><span id=QMMarchSpeed>&nbsp;</span></b></td><td align=right>&nbsp;'+tx('March Size')+':&nbsp;<b><span id=QMMarchSize>&nbsp;</span></b></td></tr></table>';
			QMBoosts += '<table class=xtab align=left cellpadding=0 cellspacing=0><tr>';
			for (var i = 0; i < 4; i++) {
				QMBoosts += '<td rowspan=2><img height=28 src="'+IMGURL+'items/30/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'" /></td><td>&nbsp;</td>';
			}
			QMBoosts += '</tr><tr>';
			for (var i = 0; i < 4; i++) {
				QMBoosts += '<td><input type=checkbox id="QMItem'+t.ItemList[i]+'"></td>';
			}
			QMBoosts += '</tr><tr>';
			for (var i = 0; i < 4; i++) {
				QMBoosts += '<td colspan=2><span id="QMItemCount'+t.ItemList[i]+'">('+uW.ksoItems[t.ItemList[i]].count+')</span></td>';
			}
			QMBoosts += '</tr></table>';
			QMBoosts += '<table class=xtab align=left cellpadding=0 cellspacing=0><tr>';
			for (var i = 4; i < t.ItemList.length; i++) {
				QMBoosts += '<td rowspan=2><img height=28 src="'+IMGURL+'items/30/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'" /></td><td>&nbsp;</td>';
			}
			QMBoosts += '</tr><tr>';
			for (var i = 4; i < t.ItemList.length; i++) {
				QMBoosts += '<td><input type=checkbox id="QMItem'+t.ItemList[i]+'"></td>';
			}
			QMBoosts += '</tr><tr>';
			for (var i = 4; i < t.ItemList.length; i++) {
				QMBoosts += '<td colspan=2><span id="QMItemCount'+t.ItemList[i]+'">('+uW.ksoItems[t.ItemList[i]].count+')</span></td>';
			}
			QMBoosts += '</tr></table>';
			QMBoosts += '<table width=100% class=xtab cellpadding=0 cellspacing=0 align=left><tr><td style="padding-right:0px;"><div id=QMTimedBoosts>&nbsp;</div></td></tr></table>';

			m += QMBoosts+'</td></tr></table></div><br>';

			popMarch = new CPopup('btQuickMarch', Options.btMarchPos.x, Options.btMarchPos.y, 620, 870, true, QuickMarch.close);
			popMarch.getMainDiv().innerHTML = m;
			popMarch.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('March+')+'</B></DIV>';

			ById("QMAutoKnight").addEventListener('click', function () {
				Options.QuickMarchOptions.AutoKnight = this.checked;
				saveOptions();
				if (Options.QuickMarchOptions.AutoKnight)
					t.BuildKnightSelect();
			}, false);
			ById("QMAutoChamp").addEventListener('click', function () {
				Options.QuickMarchOptions.AutoChamp = this.checked;
				saveOptions();
				if (Options.QuickMarchOptions.AutoChamp)
					t.BuildChampSelect();
			}, false);
			ById("QMAutoSpell").addEventListener('click', function () {
				Options.QuickMarchOptions.AutoSpell = this.checked;
				saveOptions();
				if (Options.QuickMarchOptions.AutoSpell)
					t.BuildSpellSelect();
			}, false);

			ById("QMSpell").addEventListener('click', function () {
				t.CalcMarchTime();
			},false);

			var FromCityId = uW.currentcityid;
			if (init && Cities.byID[InitialCityId]) {
				FromCityId = InitialCityId;
			}

			t.dcp0 = new CdispCityPicker('QMCastles0', ById('QMFromCity'), true, t.FromCityClick, Cities.byID[FromCityId].idx);
			t.dcp1 = new CdispCityPicker('QMCastles1', ById('QMToCity'), true, t.DestinationChanged).bindToXYboxes(ById("QMToX"), ById("QMToY"));

			for (var i=0; i<Cities.numCities; i++) {
				ById('QMCastles0_'+i).addEventListener('mouseover',function (){CityResourceHint(this,this.id.substring(11));},false);
				ById('QMCastles0_'+i).addEventListener('mouseout',function (){CityResourceHintOff(this);},false);
				ById('QMCastles1_'+i).addEventListener('mouseover',function (){CityResourceHint(this,this.id.substring(11));},false);
				ById('QMCastles1_'+i).addEventListener('mouseout',function (){CityResourceHintOff(this);},false);
			}

			ById('QMToX').addEventListener('change', t.DestinationChanged, false);
			ById('QMToY').addEventListener('change', t.DestinationChanged, false);

			ById('QMSelClosest').addEventListener('click',t.SelectClosest, false);
			ById('QMLookupButton').addEventListener('click',t.LookupMapTile, false);
			ById('QMMapButton').addEventListener('click',t.GotoMapTile, false);

			ById('QMFetchAlliance').addEventListener('click', function() {
				var myA = getMyAlliance();
				if (myA[0] != 0) {
					var params = uW.Object.clone(uW.g_ajaxparams);
					params.page = 1;
					params.perPage = 100;
					params.allianceId = myA[0];
					new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, {
						method: "post",
						parameters: params,
						onSuccess: function (rslt) {
							if (rslt.ok) {
								var m = "";
								for (var i = 0; i < rslt.results.length; i++) {
									p = rslt.results[i];
									if (p.userId != 0) {
										for (var c = 0; c < p.cities.length; c++) {
											if (Seed.player.name != p.displayName) {
												m += "<option value='" + p.cities[c].xCoord + "," + p.cities[c].yCoord + "'>" + p.displayName + " - " + p.cities[c].cityName + " (" + p.cities[c].xCoord + "," + p.cities[c].yCoord + ")</option>";
											}
										}
									}
								}
								ById('QMAlliance').innerHTML = "<option value=''>-- "+tx('Select Member')+" --</option>" + m;
							}
						},
						onFailure: function () { ById('QMAlliance').innerHTML = "<option>"+tx('Server Error')+"</option>"; },
					},true);
				} else {
					ById('QMAlliance').innerHTML = "<option>"+tx('No Alliance')+"!</option>";
				}
			}, false);

			ById('QMAlliance').addEventListener('change', function () {
				if (this.value != '') {
					var val = this.value;
					var x = val.substr(0, val.lastIndexOf(','));
					var y = val.substr(val.lastIndexOf(',') + 1, val.length);
					ById('QMToX').value = x;
					ById('QMToY').value = y;
					t.DestinationChanged();
				}
			}, false);

			ById('QMFetchBookmarks').addEventListener('click', function () {
				FillBookmarkList('QMBookmarks');
			},false);

			ById('QMBookmarks').addEventListener('change', function () {
				if (this.value != '') {
					var val = this.value;
					var x = val.substr(0, val.lastIndexOf(','));
					var y = val.substr(val.lastIndexOf(',') + 1, val.length);
					ById('QMToX').value = x;
					ById('QMToY').value = y;
					t.DestinationChanged();
				}
			}, false);

			if (t.MapLaunch) {
				ById('QMToX').value = t.MapX;
				ById('QMToY').value = t.MapY;
				if (t.MapC) { t.dcp0.selectBut(t.MapC); }
				t.DestinationChanged();
			}
			else {
				if (ById('maparea_map').style.display != "none") {
					ById('QMToX').value = ById('mapXCoor').value;
					ById('QMToY').value = ById('mapYCoor').value;
					t.DestinationChanged();
				}
			}

			var x = parseInt(ById('QMToX').value);
			var y = parseInt(ById('QMToY').value);
			if(isNaN(x) || isNaN(y)) { ById('QMLookupButtonDiv').style.display = 'none'; }

			t.LoadMarchPresets();

			ById("QMResetTroops").addEventListener('click', function () {
				for (var ui in uW.cm.UNIT_TYPES) ById("QMMarchUnit" + uW.cm.UNIT_TYPES[ui]).value = 0;
				t.PaintMarchSizeInfo();
				t.PaintLoadInfo();
				t.CalcMarchTime();
			}, false);

			ById("QMResetResources").addEventListener('click', function () {
				ById('QMMarchGold').value = 0;
				ById('QMMarchFood').value = 0;
				ById('QMMarchWood').value = 0;
				ById('QMMarchStone').value = 0;
				ById('QMMarchOre').value = 0;
				ById('QMMarchAether').value = 0;

				t.Food = 0;
				t.Wood = 0;
				t.Stone = 0;
				t.Ore = 0;
				t.Gold = 0;
				t.Aether = 0;

				t.PaintLoadInfo();
			}, false);

			for (var ui in uW.cm.UNIT_TYPES) {
				i = uW.cm.UNIT_TYPES[ui];
				ById("QMMaxUnit"+i).addEventListener('click', function () {
					var MarchUnit = this.id.replace("QMMaxUnit", "QMMarchUnit");
					var TotalUnits = parseIntNan(Seed.units["city"+t.SourceCity.id]['unt'+this.id.split("QMMaxUnit")[1]]);
					t.GetMaxMarchSize();
					ById(MarchUnit).value = 0;
					var NumUnits = 0;
					for (var ui in uW.cm.UNIT_TYPES) {
						NumUnits += parseIntNan(ById("QMMarchUnit"+uW.cm.UNIT_TYPES[ui]).value);
					}
					var FreeUnits = parseInt(t.MaxTroops - NumUnits);
					if (FreeUnits<0) FreeUnits=0;
					if (TotalUnits >= FreeUnits) {
						ById(MarchUnit).value = FreeUnits;
					} else {
						ById(MarchUnit).value = TotalUnits;
					}
					t.PaintMarchSizeInfo();
					t.PaintLoadInfo();
					t.CalcMarchTime();
				}, false);
				ById("QMMarchUnit"+i).addEventListener('change', function () {
					t.PaintMarchSizeInfo();
					t.PaintLoadInfo();
					t.CalcMarchTime();
				}, false);
			}

			ById('QMMaxGold').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Gold = Math.min(t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Aether),t.MaxGold);
				ById('QMMarchGold').value = t.Gold;
				t.PaintLoadInfo();
			}, false);
			ById('QMMaxFood').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Food = Math.min(t.MaxLoad - (t.Wood + t.Stone + t.Ore + t.Gold + t.Aether),t.MaxFood);
				ById('QMMarchFood').value = t.Food;
				t.PaintLoadInfo();
			}, false);
			ById('QMMaxWood').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Wood = Math.min(t.MaxLoad - (t.Food + t.Stone + t.Ore + t.Gold + t.Aether),t.MaxWood);
				ById('QMMarchWood').value = t.Wood;
				t.PaintLoadInfo();
			}, false);
			ById('QMMaxStone').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Stone = Math.min(t.MaxLoad - (t.Food + t.Wood + t.Ore + t.Gold + t.Aether),t.MaxStone);
				ById('QMMarchStone').value = t.Stone;
				t.PaintLoadInfo();
			}, false);
			ById('QMMaxOre').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Ore = Math.min(t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Gold + t.Aether),t.MaxOre);
				ById('QMMarchOre').value = t.Ore;
				t.PaintLoadInfo();
			}, false);
			ById('QMMaxAether').addEventListener('click', function () {
				t.CalcMaxLoad();
				t.Aether = Math.min(t.MaxLoad - (t.Food + t.Wood + t.Stone + t.Ore + t.Gold),t.MaxAether*5);
				ById('QMMarchAether').value = Math.floor(t.Aether/5);
				t.PaintLoadInfo();
			}, false);

			ById('QMMarchGold').addEventListener('change', function () {
				t.Gold = parseIntNan(ById('QMMarchGold').value);
				t.PaintLoadInfo();
			}, false);
			ById('QMMarchFood').addEventListener('change', function () {
				t.Food = parseIntNan(ById('QMMarchFood').value);
				t.PaintLoadInfo();
			}, false);
			ById('QMMarchWood').addEventListener('change', function () {
				t.Wood = parseIntNan(ById('QMMarchWood').value);
				t.PaintLoadInfo();
			}, false);
			ById('QMMarchStone').addEventListener('change', function () {
				t.Stone = parseIntNan(ById('QMMarchStone').value);
				t.PaintLoadInfo();
			}, false);
			ById('QMMarchOre').addEventListener('change', function () {
				t.Ore = parseIntNan(ById('QMMarchOre').value);
				t.PaintLoadInfo();
			}, false);
			ById('QMMarchAether').addEventListener('change', function () {
				t.Aether = parseIntNan(ById('QMMarchAether').value)*5;
				t.PaintLoadInfo();
			}, false);

			ById("QMItem931").addEventListener('click', function (e) {
				if (e.target.checked) {
					ById("QMItem932").checked = false;
				}
				t.PaintMarchSizeInfo();
			}, false);

			ById("QMItem932").addEventListener('click', function (e) {
				if (e.target.checked) {
					ById("QMItem931").checked = false;
				}
				t.PaintMarchSizeInfo();
			}, false);

			ById("QMItem57").addEventListener('click', function (e) {
				if (e.target.checked) {
					ById("QMItem55").checked = false;
				}
				t.CalcMarchTime();
			}, false);

			ById("QMItem55").addEventListener('click', function (e) {
				if (e.target.checked) {
					ById("QMItem57").checked = false;
				}
				t.CalcMarchTime();
			}, false);

			ById("QMItem293").addEventListener('click', function (e) {
				if (e.target.checked) {
//					ById("QMItem294").checked = false;
				}
			}, false);

			ById("QMItem294").addEventListener('click', function (e) {
				if (e.target.checked) {
//					ById("QMItem293").checked = false;
				}
			}, false);
			
			ById("QMTransport").addEventListener('click', function () {
				t.DoMarch(1);
			}, false);
			ById("QMReinforce").addEventListener('click', function () {
				t.DoMarch(2);
			}, false);
			ById("QMReinforceFood").addEventListener('click', function () {
				t.DoMarch(2,true);
			}, false);
			ById("QMScout").addEventListener('click', function () {
				t.DoMarch(3);
			}, false);
			ById("QMAttack").addEventListener('click', function () {
				t.DoMarch(4);
			}, false);
			ById("QMReassign").addEventListener('click', function () {
				t.DoMarch(5);
			}, false);
			ById("QMRaid").addEventListener('click', function () {
				t.AddRaid();
			}, false);

			t.RefreshTimedBoosts();

			popMarch.show(true);
			ResetFrameSize('btQuickMarch',870,620);
			Options.QuickMarchOptions.QuickMarchStartState = true;
			t.MapLaunch = false;
		}
		saveOptions();
	},

	close : function () {
		Options.QuickMarchOptions.QuickMarchStartState = false;
		Options.btMarchPos = popMarch.getLocation();
		saveOptions();
		popMarch=null;
	},

	GotoMapTile : function () {
		var t = QuickMarch;
		var x = parseInt(ById('QMToX').value);
		var y = parseInt(ById('QMToY').value);
		if(isNaN(x) || isNaN(y)) return;
		GotoMap (x,y);
	},

	LookupMapTile : function () {
		var t = QuickMarch;

		t.targetType = null;

		ById("QMLookupInfo").innerHTML = '';

		var x = parseInt(ById('QMToX').value);
		var y = parseInt(ById('QMToY').value);
		if(isNaN(x) || isNaN(y)) return;

		ById("QMLookupInfo").innerHTML = tx('Searching')+'...';

		t.Blocks = t.MapAjax.generateBlockList(x,y,1);
		var blockString = t.Blocks.join("%2C");
		t.MapAjax.LookupMap (blockString, function(rslt) {
			map = rslt.data;
			for (var k in map){
				if (x==map[k].xCoord && y==map[k].yCoord) {
					var m = "";
					var uid=map[k].tileUserId;
					var cid=map[k].tileCityId;
					var typeid = map[k].tileType;
					t.targetType = typeid;
					var tiletype = tileTypes[parseInt(typeid)];
					var subtype = map[k].premiumTile;
					if (typeid==50 && subtype==1) {
						m = tx('Alliance HQ')+'&nbsp;('+map[k].allianceHq.allianceName+')';
						ById("QMLookupInfo").innerHTML = m;
					}
					else {
						var misted = map[k].misted;
						var lvl = parseIntNan(map[k].tileLevel);
						if (!uid || uid==0 || uid=="0") {
							if (typeid==51) { tiletype = tx('Barb Camp'); }
							m = tiletype;
							if (misted) {
								m = uW.g_js_strings.commonstr.level+'&nbsp;'+lvl+'&nbsp;'+m+'&nbsp;('+tx('Owner Misted')+')';
								ById("QMLookupInfo").innerHTML = m;
							}
							else {
								if (typeid==53) {
									m += '&nbsp;or plain&nbsp;&nbsp;&nbsp;<span id=QMDefendStatus>&nbsp;</span>';
									ById("QMLookupInfo").innerHTML = m;
									getDefendStatus(x,y,ById('QMDefendStatus'),true);
								}
								else {
									if (lvl!=0) {
										m = uW.g_js_strings.commonstr.level+'&nbsp;'+lvl+'&nbsp;'+m;
									}
									ById("QMLookupInfo").innerHTML = m;
								}
							}
						}
						else { // lookup user
							var params = uW.Object.clone(uW.g_ajaxparams);
							params.checkArr = uid;
							new MyAjaxRequest(uW.g_ajaxpath + "ajax/getOnline.php" + uW.g_ajaxsuffix, {
								method: "post",
								parameters: params,
								onSuccess: function (rslt) {
									var p = rslt.data;
									var params = uW.Object.clone(uW.g_ajaxparams);
									params.pid = uid;
									new MyAjaxRequest(uW.g_ajaxpath + "ajax/viewCourt.php" + uW.g_ajaxsuffix, {
										method: "post",
										parameters: params,
										onSuccess: function (rslt) {
											if (rslt.ok) {
												var u = unixTime();
												var f = convertTime(new Date(rslt.playerInfo.fogExpireTimestamp.replace(" ","T")+"Z"));
												var misted = (f >= u);
												m = MonitorLink(rslt.playerInfo.userId,rslt.playerInfo.displayName);
												if (p[uid])
													m+= '&nbsp;<span style="color:#f00;"><b>(ONLINE)</b></span>';
												if (typeid==51) {
													m += '&nbsp;&nbsp;&nbsp;<span id=QMDefendStatus>&nbsp;</span>';
													ById("QMLookupInfo").innerHTML = m;
													getDefendStatus(x,y,ById('QMDefendStatus'),true);
												}
												else {
													m += '&nbsp;'+uW.g_js_strings.commonstr.level+'&nbsp;'+lvl+'&nbsp;'+tiletype;
													ById("QMLookupInfo").innerHTML = m;
												}
											}
										},
									});
								},
							});
						}
					}
					return;
				}
			}
			ById("QMLookupInfo").innerHTML = 'No Data';
		});
	},

	RefreshTimedBoosts : function () {
		var t = QuickMarch;

		ById('QMMarchSpeed').innerHTML = Math.floor(equippedthronestats(67))+'%';
		ById('QMMarchSize').innerHTML = Math.floor(equippedthronestats(66))+'%';

		var now = unixTime();
		Bags = Seed.items.i276;
		SturdyBags = Seed.items.i277;
		HeavyBags = Seed.items.i278;

		var loadboost = '<span style="color:#f00"><b>'+uW.g_js_strings.commonstr.none+'!</b></span>';
		if (Seed.playerEffects.loadExpire >now) {
			loadboost = '<span style="color:#080"><b>25% for '+uW.timestr(Seed.playerEffects.loadExpire-now)+'</b></span>';
		}

		var QMLoad = '<table width=100% align=left class=xtab><tr><td>'+tx('Load')+':&nbsp;</td><td>'+loadboost+'</td><td align=right style="padding-right:0px;"><table class=xtab style="padding-right:0px;" cellpadding=0 cellspacing=1><tr>';
		if (Bags) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'276\')"><img height=28 style="vertical-align:text-top;" src="'+BagImage+'" title="'+uW.itemlist.i276.name+' ('+uW.g_js_strings.modal_barracks_train.load+':25%) ('+Bags+')"></a></td>';
		}
		if (SturdyBags) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'277\')"><img height=28 style="vertical-align:text-top;" src="'+SturdyBagImage+'" title="'+uW.itemlist.i277.name+' ('+uW.g_js_strings.modal_barracks_train.load+':25%) ('+SturdyBags+')"></a></td>';
		}
		if (HeavyBags) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'278\')"><img height=28 style="vertical-align:text-top;" src="'+HeavyBagImage+'" title="'+uW.itemlist.i278.name+' ('+uW.g_js_strings.modal_barracks_train.load+':25%) ('+HeavyBags+')"></a></td>';
		}
		QMLoad += '</tr></table></td></tr>';

		Authority = Seed.items.i285;
		Dominion = Seed.items.i286;

		var sizeboost = '<span style="color:#f00"><b>'+uW.g_js_strings.commonstr.none+'!</b></span>';
		ById("QMItem931").disabled = false;
		ById("QMItem932").disabled = false;
		if (Seed.playerEffects.auras2Expire && Seed.playerEffects.auras2Expire >now) {
			sizeboost = '<span style="color:#080"><b>30% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.auras2Expire-now)+'</b></span>';
			ById("QMItem931").checked = false;
			ById("QMItem932").checked = false;
			ById("QMItem931").disabled = true;
			ById("QMItem932").disabled = true;
		}
		else {
			if (Seed.playerEffects.aurasExpire && Seed.playerEffects.aurasExpire >now) {
				sizeboost = '<span style="color:#f80"><b>15% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.aurasExpire-now)+'</b></span>';
				ById("QMItem931").checked = false;
				ById("QMItem932").checked = false;
				ById("QMItem931").disabled = true;
				ById("QMItem932").disabled = true;
			}
		}
		QMLoad += '<tr><td>'+tx('Size')+':&nbsp;</td><td>'+sizeboost+'</td><td style="padding-right:0px;" align=right><table class=xtab style="padding-right:0px;" cellpadding=0 cellspacing=1><tr>';
		if (Authority) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'285\')"><img height=28 style="vertical-align:text-top;" src="'+AuthorityImage+'" title="'+uW.itemlist.i285.name+' ('+tx('Size')+':15%) ('+Authority+')"></a></td>';
		}
		if (Dominion) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'286\')"><img height=28 style="vertical-align:text-top;" src="'+DominionImage+'" title="'+uW.itemlist.i286.name+' ('+tx('Size')+':30%) ('+Dominion+')"></a></td>';
		}
		QMLoad += '</tr></table></td></tr>';

		BlueEagle = Seed.items.i279;

		var speedboost = '<span style="color:#f00"><b>'+uW.g_js_strings.commonstr.none+'!</b></span>';
		if (Seed.playerEffects.returnExpire && Seed.playerEffects.returnExpire >now) {
			speedboost = '<span style="color:#080"><b>50% '+uW.g_js_strings.commonstr.fortxl+' '+uW.timestr(Seed.playerEffects.returnExpire-now)+'</b></span>';
		}
		QMLoad += '<tr><td>'+tx('Return')+':&nbsp;</td><td>'+speedboost+'</td><td style="padding-right:0px;" align=right><table class=xtab style="padding-right:0px;" cellpadding=0 cellspacing=1><tr>';
		if (BlueEagle) {
			QMLoad += '<td><a onClick="btApplyingBoost();cm.ItemController.use(\'279\')"><img height=28 style="vertical-align:text-top;" src="'+BlueEagleImage+'" title="'+uW.itemlist.i279.name+' ('+tx('Return Speed')+':50%) ('+BlueEagle+')"></a></td>';
		}
		QMLoad += '</tr></table></td></tr>';

		QMLoad += '</table>';

		ById('QMTimedBoosts').innerHTML = '<div align=center id=btboostmsg>&nbsp;</div>'+QMLoad;

		// check champ status

		if (jQuery('#QMChampSpan').hasClass('divHide')) {
			for (var y in Seed.champion.champions) {
				citychamp = Seed.champion.champions[y];
				if (citychamp.assignedCity == t.SourceCity.id) {
					var champstatus = citychamp.status;
					if (champstatus != "10") {
						t.BuildChampSelect();
					}
					break;
				}
			}
		}

		// check spell cooldown

		if (jQuery('#QMSpellSpan').hasClass('divHide')) {
			var spells = getSpellData(t.SourceCity.id);
			if (spells.spellavailable) {
				if (spells.cooldownactive) {
					if (ById('QMCoolTime')) { ById('QMCoolTime').innerHTML = spells.cooldown; }
				}
				else { t.BuildSpellSelect(); }
			}
		}
	},

	GetMaxMarchSize : function () {
		var t = QuickMarch;
		var e = 1;
		var f = uW.unixtime();
		var koth = false;
		if (t.targetType==57) { koth=true; }

		var elem = ById("QMItem931");
		var elem2 = ById("QMItem932");
		if (elem2 && elem2.checked && parseInt(Seed.items["i932"]) > 0) { e = 1.5; }
		else {
			if (elem && elem.checked && parseInt(Seed.items["i931"]) > 0) {	e = 1.25; }
		}

		// timed auras take priority

		if (Seed.playerEffects.auras2Expire && Seed.playerEffects.auras2Expire > f) { e = 1.3 }
		else {
			if (Seed.playerEffects.aurasExpire && Seed.playerEffects.aurasExpire > f) {	e = 1.15 }
		}

		var trmarchsizebuff = Math.min(equippedthronestats(66),CM.thronestats.boosts.MarchSize.Max);
		if (trmarchsizebuff > 0)
			e *= (1 + trmarchsizebuff / 100);
		if (Seed.cityData.city[t.SourceCity.id].isPrestigeCity) {
			var b = Seed.cityData.city[t.SourceCity.id].prestigeInfo.prestigeLevel;
			var r = uW.cm.WorldSettings.getSetting("ASCENSION_RALLYPOINT_BOOST"),
				m = JSON.parse(r),
				u = m.values[b - 1][1],
				k = parseFloat(u);
			e *= k
			if (Seed.cityData.city[t.SourceCity.id].prestigeInfo.blessings.indexOf(207) != -1) e *= 1.1;
		}
		if (koth) e=1;
		var RallyPointLevel = parseInt(getUniqueCityBuilding(t.SourceCity.id, 12).maxLevel);
		t.MaxTroops = Math.round(RallyPointLevel * 10000 * e - 0.001);
		if (RallyPointLevel == 11) {t.MaxTroops = Math.round(150000 * e - 0.001);}
		if (RallyPointLevel == 12) {t.MaxTroops = Math.round(200000 * e - 0.001);}
		if (RallyPointLevel == 13) {t.MaxTroops = Math.round(215000 * e - 0.001);}
	},

	PaintMarchSizeInfo : function () {
		var t = QuickMarch;
		t.CheckMarchNumbers();
		t.GetMaxMarchSize();
		var NumUnits = 0;
		for (var ui in uW.cm.UNIT_TYPES) {
			NumUnits += parseIntNan(ById("QMMarchUnit"+uW.cm.UNIT_TYPES[ui]).value);
		}
		if (NumUnits > t.MaxTroops)
			ById('QMTroopHeader').innerHTML = '<SPAN class=boldRed><B>' + addCommas(NumUnits) + ' / ' + addCommas(t.MaxTroops) + '</b></span>';
		else
			ById('QMTroopHeader').innerHTML = addCommas(NumUnits) + ' / ' + addCommas(t.MaxTroops);
	},

	PaintLoadInfo : function () {
		var t = QuickMarch;
		t.CalcMaxLoad();
		var Resources = t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Aether;
		if (Resources > t.MaxLoad)
			ById('QMResourceHeader').innerHTML = '<SPAN class=boldRed><B>' + addCommas(Resources) + ' / ' + addCommas(t.MaxLoad) + '</b></span>';
		else
			ById('QMResourceHeader').innerHTML = addCommas(Resources) + ' / ' + addCommas(t.MaxLoad);
	},

	PaintRallyPoint : function () {
		var t = QuickMarch;
		cityId = t.SourceCity.id;
		var marches = March.getMarchSlots(cityId);
		var maxmarches = March.getTotalSlots(cityId);
		if (marches >= maxmarches)
			ById('QMRP').innerHTML = '<SPAN class=boldRed><B>' + marches + '/' + maxmarches + '</b></span>';
		else
			ById('QMRP').innerHTML = marches + '/' + maxmarches;
	},

	RepaintMarchData : function () {
		var t = QuickMarch;

		for (var ui in uW.cm.UNIT_TYPES) {
			var i = uW.cm.UNIT_TYPES[ui];
			var troopnum = parseIntNan(Seed.units["city"+t.SourceCity.id]['unt'+i]);
			if (troopnum > 0) {
				var ritual = false;
				for (var sacIndex = 0; sacIndex < Seed.queue_sacr["city" + t.SourceCity.id].length; sacIndex++) {
					if (Seed.queue_sacr["city" + t.SourceCity.id][sacIndex]["unitType"] == i) {
						ritual = true;
					}
				}
				if (ritual) {
					ById('QMTotalUnit'+i).innerHTML = '<SPAN style="color:#080"><B>'+addCommas(troopnum)+'</B></SPAN>';
				}
				else {
					ById('QMTotalUnit'+i).innerHTML = addCommas(troopnum);
				}
			}
			else {
				ById('QMTotalUnit'+i).innerHTML = '';
			}
		}

		t.MaxFood = parseInt(Seed.resources["city"+t.SourceCity.id]['rec1'][0] / 3600);
		t.MaxWood = parseInt(Seed.resources["city"+t.SourceCity.id]['rec2'][0] / 3600);
		t.MaxStone = parseInt(Seed.resources["city"+t.SourceCity.id]['rec3'][0] / 3600);
		t.MaxOre = parseInt(Seed.resources["city"+t.SourceCity.id]['rec4'][0] / 3600);
		t.MaxAether = parseInt(Seed.resources["city"+t.SourceCity.id]['rec5'][0]);
		t.MaxGold = parseInt(Seed.citystats["city"+t.SourceCity.id]['gold'][0]);

		ById('QMTotalGold').innerHTML = addCommas(t.MaxGold);
		ById('QMTotalFood').innerHTML = addCommas(t.MaxFood);
		ById('QMTotalWood').innerHTML = addCommas(t.MaxWood);
		ById('QMTotalStone').innerHTML = addCommas(t.MaxStone);
		ById('QMTotalOre').innerHTML = addCommas(t.MaxOre);
		ById('QMTotalAether').innerHTML = addCommas(t.MaxAether);

		var cityExpTime = Seed.cityData.city[t.SourceCity.id].prestigeInfo.prestigeBuffExpire;
		if (cityExpTime && cityExpTime > unixTime()) {
			ById("QMAttack").style.color = '#f00';
			ById("QMScout").style.color = '#f00';
		}
		else {
			ById("QMAttack").style.color = '#000';
			ById("QMScout").style.color = '#000';
		}

		t.PaintRallyPoint();
	},

	FromCityClick : function (city, force) {
		var t = QuickMarch;

		if (t.SourceCity != city || force) {
			t.SourceCity = city;

			t.RepaintMarchData();
			t.BuildKnightSelect();
			t.BuildChampSelect();
			t.BuildSpellSelect();
			t.PaintMarchSizeInfo();
			t.PaintLoadInfo();
			t.CalcDistance();
			t.CalcMarchTime();

			t.SelectMarchPreset(ById('QMMarchPreset'));
		}
	},

	CheckMarchNumbers : function () {
		var t = QuickMarch;
		for (var ui in uW.cm.UNIT_TYPES) {
			var i = uW.cm.UNIT_TYPES[ui];
			var troopnum = parseIntNan(Seed.units["city"+t.SourceCity.id]['unt'+i]);
			if (ById('QMMarchUnit'+i).value > troopnum) { ById('QMMarchUnit'+i).style.color = '#f00'; }
			else { ById('QMMarchUnit'+i).style.color = '#000'; }
		}

		if (t.MaxGold < t.Gold) { ById('QMMarchGold').style.color = '#f00';	}
		else { ById('QMMarchGold').style.color = '#000'; }

		if (t.MaxFood < t.Food) { ById('QMMarchFood').style.color = '#f00';	}
		else { ById('QMMarchFood').style.color = '#000'; }

		if (t.MaxWood < t.Wood) { ById('QMMarchWood').style.color = '#f00';	}
		else { ById('QMMarchWood').style.color = '#000'; }

		if (t.MaxStone < t.Stone) { ById('QMMarchStone').style.color = '#f00';	}
		else { ById('QMMarchStone').style.color = '#000'; }

		if (t.MaxOre < t.Ore) { ById('QMMarchOre').style.color = '#f00';	}
		else { ById('QMMarchOre').style.color = '#000'; }

		if (t.MaxAether < t.Aether) { ById('QMMarchAether').style.color = '#f00';	}
		else { ById('QMMarchAether').style.color = '#000'; }
	},

	DestinationChanged : function () {
		var t = QuickMarch;
		Options.QuickMarchOptions.StartCoords.x = ById('QMToX').value;
		Options.QuickMarchOptions.StartCoords.y = ById('QMToY').value;

		var x = parseInt(ById('QMToX').value);
		var y = parseInt(ById('QMToY').value);
		if(isNaN(x) || isNaN(y)) { ById('QMLookupButtonDiv').style.display = 'none'; }
		else { ById('QMLookupButtonDiv').style.display = ''; }
		ById("QMLookupInfo").innerHTML = '';

		t.LookupMapTile();
		t.CalcDistance();
		t.CalcMarchTime();
	},

	CalcDistance : function () {
		var t = QuickMarch;

		ById("QMDist").innerHTML = '';
		t.distance = 0;

		var x1 = parseInt(t.SourceCity.x);
		var x2 = parseInt(ById('QMToX').value);
		var y1 = parseInt(t.SourceCity.y);
		var y2 = parseInt(ById('QMToY').value);
		if(isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) return;
		t.distance = distance(x1, y1, x2, y2);
		ById("QMDist").innerHTML = t.distance;
	},

	SelectClosest : function () {
		var t = QuickMarch;
		var closestdist = 999999;
		var closestcity;

		var x2 = parseInt(ById('QMToX').value);
		var y2 = parseInt(ById('QMToY').value);
		if(isNaN(x2) || isNaN(y2)) return;

		for (var i = 0; i < Cities.numCities; i++) {
			var	cityId = Cities.cities[i].id;
			var x1 = parseInt(Cities.cities[i].x);
			var y1 = parseInt(Cities.cities[i].y);
			if (x1 != x2 || y1 != y2) { // if one of your cities, pick the nearest other city!
				var dist = distance(x1, y1, x2, y2);
				if (dist < closestdist) {
					closestdist = dist;
					closestcity = i;
				}
			}
		}
		t.dcp0.selectBut(closestcity);
	},

	BuildKnightSelect : function () {
		var t = QuickMarch;
		var knt = getAvailableKnights(t.SourceCity.id);
		ById('QMKnight').options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Knight')+" --"
		o.value = 0;
		ById("QMKnight").options.add(o);
		for (var k in knt) {
			if (knt[k]["Name"] != undefined) {
				var o = document.createElement("option");
				o.text = (knt[k]["Name"] + ' (' + knt[k]["Combat"] + ')')
				o.value = knt[k]["ID"];
				ById("QMKnight").options.add(o);
			}
		}
		if (ById('QMKnight').options.length > 1) {
			if (Options.QuickMarchOptions.AutoKnight)
				ById('QMKnight').selectedIndex = 1;
		}
	},

	BuildChampSelect : function () {
		var t = QuickMarch;

		ById('QMChamp').options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Champion')+" --";
		o.value = 0;
		ById("QMChamp").options.add(o);
		var citychamp;
		var NoChampText = '<SPAN class=boldRed><B>'+uW.g_js_strings.champ.no_champ+'!</b></span>';
		for (var y in Seed.champion.champions) {
			citychamp = Seed.champion.champions[y];
			if (citychamp.assignedCity == t.SourceCity.id) {
				var champname = citychamp.name;
				var champstatus = citychamp.status;
				if (champstatus != "10") {
					var o = document.createElement("option");
					o.text = champname;
					o.value = citychamp.championId;
					ById("QMChamp").options.add(o);
				}
				else {
					NoChampText = '<SPAN class=boldRed><B>'+champname+' '+tx('is Marching')+'!</b></span>';
				}
				break;
			}
		}
		if (ById('QMChamp').options.length > 1) {
			jQuery("#QMChampSpan").removeClass("divHide");
			jQuery("#QMNoChampSpan").addClass("divHide");
			if (Options.QuickMarchOptions.AutoChamp)
				ById('QMChamp').selectedIndex = 1;
		}
		else {
			jQuery("#QMNoChampSpan").removeClass("divHide");
			jQuery("#QMChampSpan").addClass("divHide");
			ById('QMNoChampSpan').innerHTML = NoChampText;
		}
	},

	BuildSpellSelect : function () {
		var t = QuickMarch;

		var spells = getSpellData(t.SourceCity.id);
		var faction = spells.faction;

		ById('QMSpell').options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Battle Spell')+" --";
		o.value = 0;
		ById("QMSpell").options.add(o);
		var NoSpellText = '<SPAN class=boldRed><B>'+tx('No Spell')+'!</b></span>';
		if (spells.spellavailable) {
			var SpellName = eval("uW.g_js_strings.spells.name_"+SpellTypes[faction]);
			if (!spells.cooldownactive) {
				var o = document.createElement("option");
				o.text = SpellName;
				o.value = SpellTypes[faction];
				ById("QMSpell").options.add(o);
			}
			else {
				NoSpellText = '<SPAN class=boldRed><B>'+SpellName+' (<span id=QMCoolTime>'+spells.cooldown+'</span>)</b></span>';

				var Squire = parseIntNan(Seed.items.i1);
				var Knight = parseIntNan(Seed.items.i2);
				var Guinevere = parseIntNan(Seed.items.i3);
				var Morgana = parseIntNan(Seed.items.i4);
				var Arthur = parseIntNan(Seed.items.i5);
				var Merlin = parseIntNan(Seed.items.i6);

				var Speedups = '';
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,1,Squire,tx('1 min'));
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,2,Knight,tx('15 mins'));
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,3,Guinevere,tx('60 mins'));
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,4,Morgana,tx('90 mins'));
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,5,Arthur,tx('8 hours'));
				Speedups += t.paintSpeedup(t.SourceCity.id,faction,6,Merlin,tx('15 hours'));
				if (Speedups != "") Speedups = "<table align=left cellspacing=0 cellpadding=0><tr>" + Speedups + "</tr></table>";
				NoSpellText = NoSpellText+'<div>'+Speedups+'</div>';
			}
		}

		if (ById("QMSpell").options.length > 1) {
			jQuery("#QMSpellSpan").removeClass("divHide");
			jQuery("#QMNoSpellSpan").addClass("divHide");
			if (Options.QuickMarchOptions.AutoSpell) {
				ById("QMSpell").selectedIndex = 1;
				t.CalcMarchTime();
			}
		}
		else {
			jQuery("#QMNoSpellSpan").removeClass("divHide");
			jQuery("#QMSpellSpan").addClass("divHide");
			ById('QMNoSpellSpan').innerHTML = NoSpellText;
		}
	},

	paintSpeedup : function (cityId, faction, item, count, hint) {
		var t = QuickMarch;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px"><a onClick="QMspeedupSpell('+cityId+', '+item+','+SpellTypes[faction]+')"><img height=18 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+hint+') ('+count+')"></a></td>';
		}
		return n;
	},

	speedupSpell : function (cityId,item,spell) {
		var t = QuickMarch;

		var params = uW.Object.clone(uW.g_ajaxparams);
  		params.cid = cityId;
  		params.iid = item;
  		params.sid = spell;
  		params.apothecary = false;

  		new MyAjaxRequest(uW.g_ajaxpath + "ajax/speedupBattleSpellCooldown.php" + uW.g_ajaxsuffix, {
  			method: "post",
  			parameters: params,
  			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (rslt.endDate) {
						Seed.cityData.city[cityId].spells = {};
						Seed.cityData.city[cityId].spells[spell] = { endDate : rslt.endDate };
					}
					Seed.items["i"+item] = Number(parseInt(Seed.items["i"+item])-1);
					uW.ksoItems[item].subtract();
					if (cityId == uW.currentcityid) uW.update_queue();
					t.BuildSpellSelect();
				}
  			},
  		},true);
	},

	MapClick : function (x,y,c) {
		var t = QuickMarch;
		if (popMarch) {
			ById('QMToX').value = x;
			ById('QMToY').value = y;
			if (c) { t.dcp0.selectBut(c); }
			t.DestinationChanged();
		}
		else {
			t.MapX = x;
			t.MapY = y;
			if (c) { t.MapC = c; } else { t.MapC = null; }
			t.MapLaunch = true;
			t.ToggleQuickMarch(false);
		}
	},

	CalcMaxLoad : function () {
		var t = QuickMarch;
		t.MaxLoad = 0;
		var featherweight = parseInt(Seed.tech.tch10) * 0.1;
		var loadEffectBoost = 0;
		if (Seed.playerEffects.loadExpire > uW.unixtime()) {
			loadEffectBoost = 0.25;
		};
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];

			var loadBoostBase = (Math.floor(CM.ThroneController.effectBonus(6)) * 0.01) + loadEffectBoost;
			if (CM.unitFrontendType[i] == "siege") {
                loadBoostBase += (CM.ThroneController.effectBonus(59) * 0.01)
			};
			if (CM.unitFrontendType[i] == "horsed") {
                loadBoostBase += (CM.ThroneController.effectBonus(48) * 0.01);
			};
			var Load = parseInt(uW.unitstats['unt'+i]['5']);
			var LoadSac = "";
			if (uW.seed.queue_sacr["city"+t.SourceCity.id]) {
				for(var sacIndex = 0; sacIndex < uW.seed.queue_sacr["city"+t.SourceCity.id].length; sacIndex ++ ) {
					if(uW.seed.queue_sacr["city"+t.SourceCity.id][sacIndex]["unitType"] == i) {
						Load *= uW.seed.queue_sacr["city"+t.SourceCity.id][sacIndex]["multiplier"][0];
					}
				}
			}
			if (loadBoostBase > Number(CM.thronestats.boosts.Load.Max)/100) {
				loadBoostBase = Number(CM.thronestats.boosts.Load.Max)/100;
			};
			loadBoostBase += featherweight; //Should be done after throne room max check to get max boost?
			loadBoostBase += 1;

			var LoadUnit = Math.floor(loadBoostBase*Load);
			t.MaxLoad += parseInt(LoadUnit * ById("QMMarchUnit" + i).value);
		}
		if (t.MaxLoad > 0) t.MaxLoad = t.MaxLoad - 1; // reduce max by 1 to avoid load capacity errors due to roundoff
	},

	LoadMarchPresets : function () {
		var t = QuickMarch;
		ById('QMMarchPreset').options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Preset')+" --"
		o.value = 0;
		ById("QMMarchPreset").options.add(o);
		for (var y in Options.QuickMarchOptions.MarchPresets) {
			var o = document.createElement("option");
			o.text = Options.QuickMarchOptions.MarchPresets[y][0];
			o.value = y;
			ById("QMMarchPreset").options.add(o);
		}
		t.NextPresetNumber = parseIntNan(y) + 1;
		if (t.InitPresetNumber != 0) {
			ById('QMMarchPreset').value = t.InitPresetNumber;
			t.SelectMarchPreset(ById('QMMarchPreset'));
			t.InitPresetNumber = 0;
		}
	},

	SelectMarchPreset : function (sel) {
		var t = QuickMarch;
		var PN = sel.value;
		if ((PN == 0) || (PN == "")) {
			jQuery('#btDeleteMarchPreset').addClass("disabled");
			return false
		} else {
			jQuery('#btDeleteMarchPreset').removeClass("disabled");
		}

		/* Load preset details into edit fields */

		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (Options.QuickMarchOptions.MarchPresets[PN][i]) { ById('QMMarchUnit'+i).value = Options.QuickMarchOptions.MarchPresets[PN][i]; }
			else { ById('QMMarchUnit'+i).value = "0"; }
		}

		t.Food = 0;
		t.Wood = 0;
		t.Stone = 0;
		t.Ore = 0;
		t.Gold = 0;
		t.Aether = 0;

		if (Options.QuickMarchOptions.MarchPresets[PN].Gold) { t.Gold = Options.QuickMarchOptions.MarchPresets[PN].Gold; }
		if (Options.QuickMarchOptions.MarchPresets[PN].Food) { t.Food = Options.QuickMarchOptions.MarchPresets[PN].Food; }
		if (Options.QuickMarchOptions.MarchPresets[PN].Wood) { t.Wood = Options.QuickMarchOptions.MarchPresets[PN].Wood; }
		if (Options.QuickMarchOptions.MarchPresets[PN].Stone) { t.Stone = Options.QuickMarchOptions.MarchPresets[PN].Stone; }
		if (Options.QuickMarchOptions.MarchPresets[PN].Ore) { t.Ore = Options.QuickMarchOptions.MarchPresets[PN].Ore; }
		if (Options.QuickMarchOptions.MarchPresets[PN].Aether) { t.Aether = Options.QuickMarchOptions.MarchPresets[PN].Aether; }

		ById('QMMarchGold').value = t.Gold;
		ById('QMMarchFood').value = t.Food;
		ById('QMMarchWood').value = t.Wood;
		ById('QMMarchStone').value = t.Stone;
		ById('QMMarchOre').value = t.Ore;
		ById('QMMarchAether').value = t.Aether;

		for (var i = 0; i < t.ItemList.length; i++) {
			var elem = ById("QMItem"+t.ItemList[i]);
			if (elem) {
				elem.checked = (Options.QuickMarchOptions.MarchPresets[PN]["item"+t.ItemList[i]] == true);
			}
		}
		t.PaintMarchSizeInfo();
		t.PaintLoadInfo();
		t.CalcMarchTime();
	},

	SaveMarchPreset : function () {
		var t = QuickMarch;
		ById('btMarchMessages').innerHTML = "";	// need to induce a flicker or something, so they know something has happened..
		var PN = ById('QMMarchPreset');
		var NewName = ById('QMPresetName').value.trim();
		var OldName = "";
		if (!PN.value || (PN.value == 0)) {
			if (NewName == "") {
				ById('btMarchMessages').innerHTML = "<FONT COLOR=#800>"+tx('Please enter a name for the march preset')+"</font>";
				return false;
			}
			SavePN = t.NextPresetNumber;
		}
		else {
			if (NewName != "") {
				SavePN = t.NextPresetNumber;
			}
			else {
				SavePN = PN.value;
				OldName = Options.QuickMarchOptions.MarchPresets[SavePN][0];
			}
		}

		Options.QuickMarchOptions.MarchPresets[SavePN]={};
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			TroopVal = ById('QMMarchUnit'+i).value;
			if (!isNaN(TroopVal) && (TroopVal != "")) {
				Options.QuickMarchOptions.MarchPresets[SavePN][i] = TroopVal;
			}
		}

		if (!isNaN(t.Gold) && (t.Gold != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Gold = t.Gold;
		}
		if (!isNaN(t.Food) && (t.Food != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Food = t.Food;
		}
		if (!isNaN(t.Wood) && (t.Wood != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Wood = t.Wood;
		}
		if (!isNaN(t.Stone) && (t.Stone != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Stone = t.Stone;
		}
		if (!isNaN(t.Ore) && (t.Ore != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Ore = t.Ore;
		}
		if (!isNaN(t.Aether) && (t.Aether != 0)) {
			Options.QuickMarchOptions.MarchPresets[SavePN].Aether = t.Aether;
		}

		for (var i = 0; i < t.ItemList.length; i++) {
			var elem = ById("QMItem"+t.ItemList[i]);
			if (elem && elem.checked) {
				Options.QuickMarchOptions.MarchPresets[SavePN]["item"+t.ItemList[i]] = true;
			}
		}

		Options.QuickMarchOptions.MarchPresets[SavePN][0] = OldName;
		if (NewName != "") {
			Options.QuickMarchOptions.MarchPresets[SavePN][0] = NewName;
		}
		saveOptions();
		t.InitPresetNumber = SavePN;
		t.LoadMarchPresets();
		ById('QMPresetName').value = "";
		ById('btMarchMessages').innerHTML = tx("March Preset Saved");
	},

	DelMarchPreset : function () {
		var t = QuickMarch;
		var PN = ById('QMMarchPreset');
		if (!PN.value || (PN.value == 0)) return;

		Options.QuickMarchOptions.MarchPresets[PN.value]={};
		delete Options.QuickMarchOptions.MarchPresets[PN.value];
		saveOptions();
		t.LoadMarchPresets();
		ById('btMarchMessages').innerHTML = tx("March Preset Deleted");
	},

	DoMarch: function (MarchType, SendMaxFood) {
		var t = QuickMarch;
		t.RepaintMarchData();
		t.GetMaxMarchSize();

		var koth = false;
		if (t.targetType==57) { koth=true; }

		var totalunit = 0;
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (MarchType != 3 || i == 3) { totalunit = totalunit + parseIntNan(ById("QMMarchUnit"+i).value); }
		}

		var x = ById("QMToX").value;
		var y = ById("QMToY").value;

		if (ById("QMKnight").value == 0 && MarchType == 4 && !koth) { // attack, try to automatically select knight if none assigned
			if (ById('QMKnight').options.length > 1) {
				ById('QMKnight').selectedIndex = 1;
			}
		}

		var errMsg = "";
		if (x=="" || y=="" || isNaN(x) || isNaN(y) || x < 0 || x > 749 || y < 0 || y > 749) { errMsg += tx("Map co-ordinates must be between 0 and 749")+"!<BR>"; }
		if (ById("QMKnight").value == 0 && MarchType == 4 && !koth) { errMsg += tx("No knight selected")+"!<BR>"; }

		if (MarchType != 3 && MarchType != 4 && !SendMaxFood) {
			t.CalcMaxLoad();
			if ((t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Aether) > t.MaxLoad) { errMsg += tx("Too much to carry")+"!<BR>"; }
			if (MarchType == 1 && (t.Food + t.Wood + t.Stone + t.Ore + t.Gold + t.Aether) <= 0) {	errMsg += tx("You must transport something")+"!<BR>"; }
		}
		if (totalunit == 0 && MarchType != 3) { errMsg += tx("You must select some troops")+"!<br>"; }
		if (totalunit > t.MaxTroops) { errMsg += tx("You can only send")+" "+t.MaxTroops+" "+tx("units")+".<br>"; }

		if (errMsg != "") {
			ById('btMarchMessages').innerHTML = "<FONT COLOR=#800>"+errMsg+"</font>";
			return;
		}

		// if we get this far we are good to march...

		var iused = new Array();
		for (var i = 0; i < t.ItemList.length; i++) {
			var elem = ById("QMItem"+t.ItemList[i]);
			if (elem && elem.checked && parseInt(Seed.items["i"+t.ItemList[i]]) > 0) {
				iused.push(t.ItemList[i]);
			}
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.r1 = 0;
		params.r2 = 0;
		params.r3 = 0;
		params.r4 = 0;
		params.r5 = 0;
		params.gold = 0;
		var res = 0;
		if (SendMaxFood) {
			for (var ui in uW.cm.UNIT_TYPES) {
				i = uW.cm.UNIT_TYPES[ui];
				res += parseInt(uW.unitstats['unt'+i][5] * ById("QMMarchUnit"+i).value * (1 + (0.10 * Seed.tech.tch10) + Math.min(equippedthronestats(6) / 100, (CM.thronestats.boosts.Load.Max/100))));
			}
			res = res - 1;
			params.r1 = res;
		}
		params.items = iused.join(",");
		params.cid = t.SourceCity.id;
		params.type = MarchType; // 5 Reassign, 4 Attack, 3 Scout, 2 Reinforce, 1 Transport
		params.xcoord = x;
		params.ycoord = y;
		if (koth) { params.kid = 0; }
		else { params.kid = ById("QMKnight").value; }
		if (MarchType != 3 && MarchType != 4 && !SendMaxFood) {
			params.r1 = Math.min(t.Food,t.MaxFood);
			params.r2 = Math.min(t.Wood,t.MaxWood);
			params.r3 = Math.min(t.Stone,t.MaxStone);
			params.r4 = Math.min(t.Ore,t.MaxOre);
			params.r5 = Math.floor(Math.min(t.Aether/5,t.MaxAether));
			params.gold = Math.min(t.Gold,t.MaxGold);
		}
		for (var ui in uW.cm.UNIT_TYPES) { params["u"+uW.cm.UNIT_TYPES[ui]] = 0; }
		if (MarchType != 3) {
			for (var ui in uW.cm.UNIT_TYPES) {
				i = uW.cm.UNIT_TYPES[ui];
				if (ById("QMMarchUnit"+i).value > 0) {params["u"+i] = parseIntNan(ById("QMMarchUnit"+i).value);}
			}
		} else {
			params.u3 = parseIntNan(ById("QMMarchUnit3").value);
			if (params.u3==0) { params.u3=1; }
		}
		params.champid = 0;
		if (MarchType == 4) {
			if (ById('QMChamp').value != 0 && ById('QMChamp').value != "") {
				var championidx = "";
				for (var i = 0; i < Seed.champion.champions.length; i++) {
					if (Seed.champion.champions[i].championId == ById('QMChamp').value) championidx = i;
				}
				params.champid = ById('QMChamp').value;
			}
		}
		if (ById('QMSpell').value != 0 && ById('QMSpell').value != "") {
			if (MarchType == 4 || ById('QMSpell').value != "21") {
				params.bs = ById('QMSpell').value;
			}
		}

		t.DisableButtons(true);
		ById('btMarchMessages').innerHTML = "<i><b>"+tx('Sending march')+"....</b></i>";
		March.addMarch(params, function(rslt){
			if (rslt.ok) {
				var ReturnMessage = "";
				switch (MarchType) {
					case 1:	ReturnMessage = tx("Transport successful");	break;
					case 2:	ReturnMessage = tx("Reinforce successful");	break;
					case 3:	ReturnMessage = tx("Scout successful");	break;
					case 4:	ReturnMessage = tx("Attack successful"); break;
					case 5:	ReturnMessage = tx("Reassign successful"); break;
					default: ReturnMessage = tx("March successful");
				}
				ById('btMarchMessages').innerHTML = ReturnMessage;
				t.FromCityClick(t.SourceCity,true); // force update
			} else {
				if (rslt.msg) {
					ById('btMarchMessages').innerHTML = "<FONT COLOR=#800><b>" + rslt.msg + "</b></font>";
				} else {
					ById('btMarchMessages').innerHTML = "<FONT COLOR=#800><b>"+tx('Error sending march')+"!</b></font>";
				}
			}
			t.DisableButtons(false);
		}, true);
	},

	AddRaid : function (){
		var t = QuickMarch;
		t.RepaintMarchData();
		t.GetMaxMarchSize();
		var totalunit = 0;
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			totalunit = totalunit + parseIntNan(ById("QMMarchUnit"+i).value);
		}

		var x = ById("QMToX").value;
		var y = ById("QMToY").value;

		if (ById("QMKnight").value == 0) { // attack, try to automatically select knight if none assigned
			if (ById('QMKnight').options.length > 1) {
				ById('QMKnight').selectedIndex = 1;
			}
		}

		var errMsg = "";
		if (x=="" || y=="" || isNaN(x) || isNaN(y) || x < 0 || x > 749 || y < 0 || y > 749) { errMsg += tx("Map co-ordinates must be between 0 and 749")+"!<BR>"; }
		if (ById("QMKnight").value == 0) { errMsg += tx("No knight selected")+"!<BR>"; }

		if (totalunit == 0) { errMsg += tx("You must select some troops")+"!<br>"; }
		if (totalunit > t.MaxTroops) { errMsg += tx("You can only send")+" "+t.MaxTroops+" "+tx("units")+".<br>"; }

		if (errMsg != "") {
			ById('btMarchMessages').innerHTML = "<FONT COLOR=#800>"+errMsg+"</font>";
			return;
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		params.ctrl = 'BotManager';
		params.action = 'saveMarch';
		params.settings = {};
		params.queue = {0:{botMarches:{botMarchStatus:1,botState:1},cityMarches:{}}};

		params.settings.cityId = t.SourceCity.id;
		params.queue[0].cityMarches.knightId = ById("QMKnight").value;
		params.queue[0].cityMarches.toXCoord = x;
		params.queue[0].cityMarches.toYCoord = y;
		for (var ui in CM.UNIT_TYPES) {
			var i = CM.UNIT_TYPES[ui];
			params.queue[0]['cityMarches']['unit'+i+'Count'] = parseIntNan(ById("QMMarchUnit"+i).value);
		}

		t.DisableButtons(true);
		ById('btMarchMessages').innerHTML = "<i><b>"+tx("Adding Raid")+"....</b></i>";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function(rslt){
				var t = QuickMarch;
				if (rslt.ok) {
					uW.cityinfo_army();
					setTimeout(uW.update_seed_ajax, 250);
					ById('btMarchMessages').innerHTML = tx("Raid Added Successfully");
					Seed.knights['city' +params.settings.cityId]['knt' + params.queue[0].cityMarches.knightId].knightStatus = 10; // update knight instantly!
					t.FromCityClick(t.SourceCity,true); // force update
				} else {
					if (rslt.msg) {
						ById('btMarchMessages').innerHTML = "<FONT COLOR=#800><b>" + rslt.msg + "</b></font>";
					} else {
						ById('btMarchMessages').innerHTML = "<FONT COLOR=#800><b>"+tx("Error setting raid")+"!</b></font>";
					}
				}
				t.DisableButtons(false);
			},
			onFailure: function () {
				var t = QuickMarch;
				ById('btMarchMessages').innerHTML = "<FONT COLOR=#800><b>"+tx("Error communicating with server")+"!</b></font>";
				t.DisableButtons(false);
			}
		},true);
	},

	DisableButtons : function (tf) {
		ById("QMTransport").disabled = tf;
		ById("QMReinforce").disabled = tf;
		ById("QMReinforceFood").disabled = tf;
		ById("QMScout").disabled = tf;
		ById("QMAttack").disabled = tf;
		ById("QMReassign").disabled = tf;
	},

	CalcMarchTime : function () {
		var t = QuickMarch;
		var unit_types = {};
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			var troop_number = parseIntNan(ById("QMMarchUnit"+i).value);
			if (troop_number > 0) { unit_types[ui] = i; }
		}
		var red_wings_used = false;
		var green_wings_used = false;
		var elem = ById("QMItem57");
		if (elem && elem.checked && parseInt(Seed.items["i57"]) > 0) {
			red_wings_used = true;
		}
		else {
			var elem2 = ById("QMItem55");
			if (elem2 && elem2.checked && parseInt(Seed.items["i55"]) > 0) {
				green_wings_used = true;
			}
		}
		var MarchTime = March.getMarchTime(t.SourceCity.id,unit_types,t.distance,ById("QMSpell").value,red_wings_used,green_wings_used);
		if (MarchTime.foe==0) {
			ById("QMTime").innerHTML = "";
			return;
		}
		ById("QMTime").innerHTML = tx("Est. Time")+": "+uW.timestr(MarchTime.friend)+" ("+tx("Friend")+"), "+uW.timestr(MarchTime.foe)+" ("+tx("Foe")+")";
	},

	EverySecond : function () {
		var t = QuickMarch;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter >= 3) { // refresh display every 3 seconds
			t.LoopCounter = 0;
			if (t.SourceCity) {
				t.RepaintMarchData();
				t.RefreshTimedBoosts();
			}
		}
	},
}

/************************************ OPTION OBJECTS *********************************************/

var anticd = {
	isInited: false,
	KOCversion: '?',
	init: function () {
		try {
			if (this.isInited)
				return this.KOCversion;

			if (typeof exportFunction == 'function') { exportFunction(eval('function a (){}'),uW.cm.cheatDetector, {defineAs:"detect"}); }
			else { uW.cm.cheatDetector.detect = eval('function a (){}'); };

			var scripts = document.getElementsByTagName('script');
			for (var i = 0; i < scripts.length; i++) {
				if (scripts[i].src.indexOf('camelotmain') >= 0) {
					break;
				}
			}
			if (i < scripts.length) {
				var m = scripts[i].src.match(/camelotmain[_]{0,1}[a-z]{0,2}-(.*).js/);
				if (m) this.KOCversion = m[1];
			}
			this.isInited = true;
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	getKOCversion: function () {
		return this.KOCversion;
	},
};

var TreasureChestClick = {
	clickTreasureChest : null,

	init : function (){
		t = TreasureChestClick;

		try {
			uWExportFunction ('treasure_chest_post_hook', t.hook);
			t.clickTreasureChest = new CalterUwFunc ('pop_treasure_chest_modal', [[/if/im, 'treasure_chest_post_hook(a); return; if']]);
			t.clickTreasureChest.setEnable(UserOptions.TreasureChest);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},

	setEnable : function (tf){
		var t = TreasureChestClick;
		t.clickTreasureChest.setEnable (tf);
	},

	isAvailable : function (){
		var t = TreasureChestClick;
		return t.clickTreasureChest.isAvailable();
	},

	hook : function (tid) {
		var mid = tid;
		var city = null;
		var coords = "";
		var tileName = "Barbarian Camp";
		var logTile = "";
		for (var k in Seed.queue_atkp) {
			if (Seed.queue_atkp[k]['m'+mid]) {
				city = k;
				coords = ' ('+Seed.queue_atkp[k]['m'+mid].toXCoord+','+Seed.queue_atkp[k]['m'+mid].toYCoord+')';
				break;
			}
		}
		if (city) {
			try {
				tileName = (Seed.queue_atkp[city]["m" + mid].toTileType == 51) ? "Barbarian Camp" : capitalize(uW.g_mapObject.types[parseInt(Seed.queue_atkp[city]["m" + mid].toTileType)]);
				logTile = ' in '+tileName+' Level '+Seed.queue_atkp[city]["m" + mid].toTileLevel;
				if (tileName=="Boss") { // DF!!
					if (DeleteReports.ReportLog.ItemsFoundDF["T"]) { DeleteReports.ReportLog.ItemsFoundDF["T"] += 1; }
					else { DeleteReports.ReportLog.ItemsFoundDF["T"] = 1; }
				}
				else {
					for (var i in Options.AttackOptions.Routes) {
						var a = Options.AttackOptions.Routes[i];
						if (Seed.queue_atkp[city]['m'+mid].toXCoord == a.target_x && Seed.queue_atkp[city]['m'+mid].toYCoord == a.target_y && Seed.queue_atkp[city]['m'+mid].marchType==4) {
							if (DeleteReports.ReportLog.ItemsFound["T"]) { DeleteReports.ReportLog.ItemsFound["T"] += 1; }
							else { DeleteReports.ReportLog.ItemsFound["T"] = 1; }
							break;
						}
					}
				}
			}
			catch(e) { };
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.tid = tid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/postFriendVictoryTokenShare.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (UserOptions.BankTreasureChests && UserOptions.TreasureChestBank.length < UserOptions.MaxBankedTreasureChests) {
						var post_link = 'convert.php?pl=1&ty=3&si=118&wccc=fcf-feed-118&ln=31&da='+yyyymmdd(new Date())+'&in=' + uW.tvuid + '&ex=s%3A' + getServerId() + '%7Cf%3A' + rslt.feedId + '%7Cm%3A' + rslt.tokenId + '%7Cimg%3Ahttps%3A%2F%2Fwww.kingdomsofcamelot.com%2Ffb%2Fe2%2Fsrc%2Fimg%2Fbronze_vip.png%7C&page=convert';
						UserOptions.TreasureChestBank.push({tokenId:rslt.tokenId, feedId:rslt.feedId, serverId:getServerId(), playerId:uW.tvuid, tileName:tileName, unixTime_taken:unixTime(), link:post_link});
						saveUserOptions(uW.user_id);
						actionLog('Chest found'+logTile+coords+' - Link Stored','TREASURE');
					}
					else {
						var reparr = new Array();
						reparr.push(["REPLACE_TiLeNaMe", tileName]);
						reparr.push(["REPLACE_fEeDiD", rslt.feedId]);
						reparr.push(["REPLACE_tOkEnId", rslt.tokenId]);
						uW.common_postToProfile("118", reparr);
						actionLog('Chest found'+logTile+coords+' - Link Posted to FB','TREASURE');
					}
				} else {
					actionLog('Chest found'+logTile+coords+' - Error: ' +rslt.error_code+ ',' +rslt.msg+ ',' +rslt.feedback,'TREASURE')
				}
			},
			onFailure: function () {
				actionLog('Chest found'+logTile+coords+' - AJAX Error','TREASURE')
			},
		},true);
	},
}

var KillBox = {
	kboxtime : 1,
	init:function () {
		var t = KillBox;
		t.kboxtime += 1;
		if(!Options.MagicBox) { return; }
		if (t.kboxtime > 50) { return; }
		if (Number(uW.seed.items.i599) == 0) { return; }
		if (!ById('modal_mmb')) {
			setTimeout(KillBox.init,100);
		}
		else {
			uW.Modal.hideModal();
		}
	},
}

var FairieKiller  = {
	saveFunc : null,
	init : function (tf){
		try {
			FairieKiller.saveFunc = uW.Modal.showModalUEP;
			FairieKiller.setEnable (tf);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},

	setEnable : function (tf){
		if (tf)
		uW.Modal.showModalUEP = eval ('function FairieKiller (a,b,c) {actionLog ("Blocked Faire popup");}');
		else
		uW.Modal.showModalUEP = FairieKiller.saveFunc;
	},
}

var BypassMulti = {
	MultiBrowserBypass: null,
	init: function () {
		t = BypassMulti;

		uWExportFunction('ptRefreshSeedHook', t.RefreshSeedHook);

		t.MultiBrowserBypass = new CalterUwFunc('update_seed_ajax', [
			[/if\s*\(typeof\s*isCancelTraining/im, 'var l_lastCallTime = cm.l_lastCallTime; var reload_requests = cm.reload_requests; var l_callIntervalMin = cm.l_callIntervalMin; if(typeof isCancelTraining'],
			[/if\s*\(rslt\.error_code\s*==\s*60\)/im, 'ptRefreshSeedHook();return; if(rslt.error_code == 60)']
		]);
		t.MultiBrowserBypass.setEnable(Options.AllowMultiBrowser);
	},
	RefreshSeedHook: function() {
		actionLog("multi-browser message detected... attempting to reconnect with server");
		RefreshSeed();
	},
	setEnable: function (tf) {
		var t = BypassMulti;
		t.MultiBrowserBypass.setEnable(tf);
	},
	isAvailable: function () {
		var t = BypassMulti;
		return t.MultiBrowserBypass.isAvailable();
	},
}

var BarbRaidMarchPatch = {
	marchFix: null,
	init: function () {return; // disable
		try {
			t = BarbRaidMarchPatch;
			if ((FFVersion.Browser == 'Chrome') || (parseIntNan(FFVersion.Version) > 16)) {
				t.marchFix = new CalterUwFunc('update_march', [
					[/D\.toTileLevel,\s*n,\s*M\)/im, 'D.toTileLevel, n, M, Math.floor(unixtime()+D.returnEta-D.marchUnixTime))']
				]);
			}
			else {
				t.marchFix = new CalterUwFunc('update_march', [
					['D.toTileLevel, n, M)', 'D.toTileLevel, n, M, Math.floor(unixtime()+D.returnEta-D.marchUnixTime))']
				]);
			}
			t.marchFix.setEnable(Options.RaidPatch);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {return;
		var t = BarbRaidMarchPatch;
		t.marchFix.setEnable(tf);
	},
	isAvailable: function () {return false;
		var t = BarbRaidMarchPatch;
		return t.marchFix.isAvailable();
	},
}

function fixkabamlag () {
	var kfutime = Number(uW.unixtime()+30);
	for (var city in Seed.queue_atkp) {
		var kabamhashX = [];
		if(Seed.queue_atkp[city] != "") {
			for (var march in Seed.queue_atkp[city]) {
				if(Seed.queue_atkp[city][march].marchType) {
					if(!Seed.queue_atkp[city][march].botMarchStatus && Seed.queue_atkp[city][march].marchStatus == 5) {
						if (Seed.queue_atkp[city][march].returnUnixTime < kfutime) {
							actionLog(Cities.byID[String(city).replace(/city/,'')].name+': Fixing march '+march, 'MARCH');
							for (var ui in CM.UNIT_TYPES){
								var i = CM.UNIT_TYPES[ui];
								if (Seed.queue_atkp[city][march]['unit'+i+'Count'] > 0) {
									if(Seed.queue_atkp[city][march]['unit'+i+'Return'] == 0 || Seed.queue_atkp[city][march]['unit'+i+'Return'] == undefined) {
										Seed.queue_atkp[city][march]['unit'+i+'Return'] = Seed.queue_atkp[city][march]['unit'+i+'Count'];
									}
								}
							}
							Seed.queue_atkp[city][march].hasUpdated = true;
							Seed.queue_atkp[city][march].marchStatus = 8;
						} else { kabamhashX.push(Seed.queue_atkp[city][march].knightId); }
					} else  { kabamhashX.push(Seed.queue_atkp[city][march].knightId); }
				}
			}
		}
		for (var knight in Seed.knights[city]) {
			if(Seed.knights[city][knight].knightStatus != 1) {
				if(kabamhashX.indexOf(Seed.knights[city][knight].knightId) == -1) {
					Seed.knights[city][knight].knightStatus = 1;
					actionLog(Cities.byID[String(city).replace(/city/,'')].name+': Fixing knight '+Seed.knights[city][knight].knightName, 'MARCH');
				}
			}
		}
	}
}

var ChampLagFix = {
	LagFix1: null,
	LagFix2: null,
	init: function () {
		t = ChampLagFix;

		try {
			uW.CE_EFFECT_TIERS = uWCloneInto(CE_EFFECT_TIERS);
			uWExportFunction('btGetTierEffects', function (T) {
				var U = +T.id || 0,
				R = +T.tier || 0,
				V = CE_EFFECT_TIERS,
				S = U + "," + R;
				if (!V[S]) {
					if (R > 1) {
						CM.log.error(2, CM.ERROR_TYPE.INFORMATION_MISSING, "Champion equipment tier {tier} doesn't exist for Effect ID {effectId}. Trying the next tier down.".replace("{effectId}", U).replace("{tier}", R));
						return o({
							id : U,
							tier : R - 1
						})
					} else {
						CM.log.error(1, CM.ERROR_TYPE.INFORMATION_MISSING, "Champion equipment tier doesn't exist for Effect ID {effectId}. All tiers attempted.".replace("{effectId}", U));
						return {}
					}
				}
				return V[S]
			});

			t.LagFix1 = new CalterUwFunc("cm.ChampionManager.getEffectAmount",[['o(U),','btGetTierEffects(U),']]);
			t.LagFix2 = new CalterUwFunc("cm.ChampionManager.getEffect",[['L(R,','cm.ChampionManager.getEffectAmount(R,'],['e(R','cm.ChampionManager.getEffectName(R']]);
			if (ChampLagFix.isAvailable()) {
				ChampLagFix.setEnable(Options.FixCastleLag);
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = ChampLagFix;
		t.LagFix1.setEnable(tf);
		t.LagFix2.setEnable(tf);
	},
	isAvailable: function () {
		var t = ChampLagFix;
		return (t.LagFix1.isAvailable() && t.LagFix2.isAvailable());
	},
};

var CollectGold = {
	colCity : null,
	colHappy : 0,

	init : function (){
		var t = CollectGold;
		for (var c=0; c < Cities.numCities; c++) {
			if (!Options.lastCollect[Cities.cities[c].id]) {
				Options.lastCollect[Cities.cities[c].id] = 0;
			}
		}
		saveOptions();
	},

	tick : function (){
		var t = CollectGold;
		for (var c=0; c<Cities.numCities; c++){
			var city = Cities.cities[c];
			var happy = Seed.citystats['city'+ city.id].pop[2];
			var since = unixTime() - Options.lastCollect[city.id];
			if ((happy >= parseIntNan(Options.pbGoldHappy)) && (since > 15*60)) { // KoC Restriction 15 mins!
				t.colCity = city;
				t.colHappy = happy;
				t.ajaxCollectGold (city, t.e_ajaxDone);
				break;
			}
		}
	},

	e_ajaxDone : function (rslt){
		var t = CollectGold;
		Options.lastCollect[t.colCity.id] = unixTime();
		saveOptions();
		if (rslt.ok) {
			actionLog (t.colCity.name+': Collected '+ rslt.goldGained +' gold (Happiness was '+ t.colHappy +'%)','GOLD');
		}
		else { actionLog (t.colCity.name+': Error collecting gold ('+rslt.errorMsg+')','GOLD'); }
	},

	ajaxCollectGold : function (city, notify){
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = city.id;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/levyGold.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify (rslt); },
			onFailure: function () { notify ({errorMsg:'AJAX error'}); },
		},true);
	},
}

var FoodAlerts = {
	init : function (){
		var t = FoodAlerts;
		for (var c=0; c < Cities.numCities; c++) {
			if (!Options.lastAlert[Cities.cities[c].id]) {
				Options.lastAlert[Cities.cities[c].id] = 0;
			}
			if (!Options.countAlert[Cities.cities[c].id]) {
				Options.countAlert[Cities.cities[c].id] = 0;
			}
		}
		saveOptions();
	},

	tick : function (){
		var t = FoodAlerts;
		var now = unixTime();
		var trupkeepreduce = 0;
		trupkeepreduce = Math.min(equippedthronestats(79), 33);
		var trprodres = Math.min(equippedthronestats(82),2000);
		var trprod = [0, 0, 0, 0, 0];
		trprod[1] = Math.min(equippedthronestats(83), 2000)+trprodres;

		if (Options.pbFoodAlertInt < 1) Options.pbFoodAlertInt = 1;

		for(i=0; i < Cities.numCities; i++) {
			var cityId = Cities.cities[i].id;
			if (isNaN(Seed.resources["city" + cityId]['rec1'][0])) continue; // no alert if can't read the amount...
			var rp = getResourceProduction(cityId);
			var usage = parseInt(Seed.resources['city'+cityId]['rec1'][3]);
			var bp = uW.cm.Resources.getProductionBase(1,cityId);
			var upkbase = uW.cm.Resources.getUpkeep(1,cityId) / (1 - trupkeepreduce / 100);
			usage = parseIntNan(rp[1] - parseIntNan(usage - upkbase * trupkeepreduce / 100) + bp * trprod[1] / 100);
			var foodleft = parseInt(Seed.resources["city" + cityId]['rec1'][0])/3600;
			if (usage!=0) {
				var timeLeft = parseInt(Seed.resources["city" + cityId]['rec1'][0]) / 3600 / (0-usage) * 3600;
				var msg = '';
				if (usage < 0) {
					var since = unixTime() - Options.lastAlert[cityId];
					if ((timeLeft < (Options.pbFoodAlertInt*3600)) && (since > 15*60)) {
						Options.countAlert[cityId]++;
						if (Options.countAlert[cityId]>3) { // only post alert if more than 3 positive results in a row
							msg += tx('My city')+' '+Cities.cities[i].name.substring(0,10)+' ('+Cities.cities[i].x+','+Cities.cities[i].y+')';
							msg += ' '+tx('is low on food. Remaining')+': '+addCommas(foodleft,true)+' ('+timestrShort(timeLeft)+') '+tx('Upkeep')+': '+addCommas(usage);
							sendChat ("/a " + msg);
							Options.lastAlert[cityId] = unixTime();
						}
					}
					else {
						Options.countAlert[cityId] = 0;
					}
				}
				else {
					Options.countAlert[cityId] = 0;
				}
			}
			else {
				Options.countAlert[cityId] = 0;
			}
		}
	},
}

var RefreshEvery  = {
	timer : null,
	PaintTimer : null,
	NextRefresh : 0,
	box : null,
	target : null,

	init : function (){
		var t = RefreshEvery;
		t.creatediv();
		if (Options.btEveryMins < 1)
			Options.btEveryMins = 1;
	},

	creatediv : function(){
		var t = RefreshEvery;
		t.target = ById('comm_tabs');
		if(t.target == null){
			setTimeout(t.creatediv, 2000);
			return;
		}
		t.box = document.createElement('div');
		t.target.appendChild(t.box);
		t.box.addEventListener('click', function () {t.setEnable(Options.btEveryEnable)}, false);
	},

	setEnable : function (tf){
		var t = RefreshEvery;
		clearTimeout (t.timer);
		if (tf) {
			t.NextRefresh = unixTime() + (Options.btEveryMins*60);
			t.timer = setTimeout (t.Paint, 1000);
		} else {
			t.timer = null;
			t.NextRefresh = 0;
			t.box.innerHTML = '<span style="Line-Height:35px;"><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;'+ getMyAlliance()[1] + ' (' + getServerId() +')</b></font></span>';
		}
	},

	doit : function (){
		var t = RefreshEvery;
		t.box.innerHTML = '<span style="Line-Height:35px;"><FONT color=#f80><B>&nbsp;&nbsp;&nbsp;&nbsp;'+tx("Reloading Now!")+'</b></font></span></div>';
		actionLog ('Refreshing ('+ Options.btEveryMins +' minutes expired)');
		ReloadKOC(true);
	},

	setTimer : function (){
		var t = RefreshEvery;
		clearTimeout (t.timer);
		if (Options.btEveryMins < 1) Options.btEveryMins = 1;
		RefreshEvery.setEnable (Options.btEveryEnable);
	},

	Paint : function(){
		var t = RefreshEvery;
		if (t.timer == null) return;
		now = unixTime();
		var text = '';
		var Left = parseInt(t.NextRefresh - now);
		var txtbox = ById('modal_msg_write_txt');
		if ((Left < 0) && (!txtbox || txtbox.value=="") && (!Options.detAFK || afkdetector.isAFK)) {
			clearTimeout (t.timer);
			Left = 0;
			t.doit();
			return;
		};
		if (Left <= -1) text += '<span style="Line-Height:35px;"><FONT color=#f80><B>&nbsp;&nbsp;&nbsp;&nbsp;'+tx("Ready to Reload...")+'</b></font></span></div>';
		else if (Left < 60 && (!Options.detAFK || afkdetector.isAFK)) text += '<span style="Line-Height:35px;"><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;'+tx("Next refresh in")+': </font><FONT color=#f80><B>'+ timestr(Left) +'</b></font></span></div>';
		else text += '<span style="Line-Height:35px;"><FONT color=white><B>&nbsp;&nbsp;&nbsp;&nbsp;'+tx("Next refresh in")+': <B>'+ timestr(Left) +'</b></font></span></div>';

		t.box.innerHTML = '<a title="Click to reset countdown timer">'+text+'</a>';
		t.timer = setTimeout (t.Paint, 1000);
	},
}

function ChatComOverlay () {
	if(!document.getElementsByClassName('postaction')[0].getElementsByClassName('button20')[0])return;//safety
	thebutton = document.getElementsByClassName('postaction')[0].getElementsByClassName('button20')[0];
	thebutton.onclick=function(){OSendChat()};
	var overlay = document.createElement("div");
	var mod_comm_input = ById('mod_comm_input');
	var mod_comm_forum = document.getElementsByClassName('mod_comm_forum')[0];
	var mod_comm_list1 = ById('mod_comm_list1');
	var mod_comm_list2 = ById('mod_comm_list2');
	mod_comm_forum.style.position = 'absolute';
	mod_comm_forum.style.height = '30px';
	mod_comm_forum.style.top = '30px';
	mod_comm_list1.style.top = '20px';
	mod_comm_list2.style.top = '20px';
	overlay.setAttribute("id","overlay");
	overlay.setAttribute("class", "overlay");
	mod_comm_input.hidden=true;
	mod_comm_input.parentNode.appendChild(overlay);
	overlay.innerHTML = '<input id="bot_comm_input" type="text" autocorrect="on" autocomplete="off"></input>';
	var bot_comm_input = ById('bot_comm_input');
	bot_comm_input.style.width = "75%";
	bot_comm_input.style.float = "left";
	bot_comm_input.addEventListener ('keypress', function(e) {if(e.which == 13)OSendChat();}, false);
	var x = new CalterUwFunc("Chat.whisper",[[/mod.comm.input/ig,'bot_comm_input']]);
	x.setEnable(true);

	if (Options.ChatOptions.Emoticons) {
	 	 var ab = document.createElement('a');
		ab.className="mod_comm_set";
		ab.innerHTML=tx("Emoticons");
		ab.id="btEmoticonLink";
		ab.style.paddingLeft = '0px';
		mod_comm_forum.insertBefore(ab,mod_comm_forum.firstChild);
		ab.addEventListener ('click', ChatStuff.SmileyHelp, false);
	}
};

function OSendChat () {
	if(Options.ChatOptions.filter)
		ById('mod_comm_input').value = BtFilter(ById('bot_comm_input'));
	else
		ById('mod_comm_input').value = ById('bot_comm_input').value;
	ById('bot_comm_input').value = "";
	uW.Chat.sendChat();
};

function BtFilter(e) {
	var whisper = "";
	var firstindex = 0;
	var enctype = 0;

	if(e.value.charAt(0) == "\\") {
		e.value = String(e.value).slice(1);
		enctype = 1;
	};

	if(e.value.charAt(0) == "/" || e.value.charAt(0) == "@") {
		firstindex = e.value.indexOf(" ");
		whisper = e.value.slice(0,firstindex)+' ';
	};

	var m = e.value.substr(firstindex,e.value.length);

	if(enctype == 1) {
		var unicodeString = '';
		for (var i=0; i < m.length; i++) {
			var theUnicode = m.charCodeAt(i);;;
			theUnicode = '&#' + theUnicode+';';
			unicodeString += theUnicode;
		}
		m = unicodeString;
	};

	if(enctype == 0) {
		var m = e.value.substr(firstindex,e.value.length);
		var x = Filter[Options.ChatOptions.fchar];
		m = m.replace(/Fa/g,'F'+x+'a').replace(/fA/g,'f'+x+'A').replace(/FA/g,'F'+x+'A').replace(/fa/g,'f'+x+'a');
		m = m.replace(/Gr/g,'G'+x+'r').replace(/gR/g,'g'+x+'R').replace(/GR/g,'G'+x+'R').replace(/gr/g,'g'+x+'r');
		m = m.replace(/Ri/g,'R'+x+'i').replace(/rI/g,'r'+x+'I').replace(/RI/g,'R'+x+'I').replace(/ri/g,'r'+x+'i');
		m = m.replace(/Na/g,'N'+x+'a').replace(/nA/g,'n'+x+'A').replace(/NA/g,'N'+x+'A').replace(/na/g,'n'+x+'a');
		m = m.replace(/885/g,'8'+x+'8'+x+'5').replace(/80085/g,'8'+x+'0'+x+'0'+x+'8'+x+'5');
	};
	// strip http:// and https://

	m = m.replace('https://','');
	m = m.replace('http://','');

	return(whisper+m);
};

function enFilter(e) {
	var x = Filter["Null"];
	var m = String(e);
	m = m.replace(/885/g,'8'+x+'8'+x+'5').replace(/80085/g,'8'+x+'0'+x+'0'+x+'8'+x+'5');
	return m;
}

function deFilter(e) {
	var x = Filter["Null"];
	var m = String(e);
	m = m.replace(new RegExp(x, 'g'),'');
	return m;
}

var ChatPane = {
	init : function(){
		var t = ChatPane;
		setInterval(t.HandleChatPane, 2500);
	},

	HandleChatPane : function() {
		var DisplayName = GetDisplayName();
		var AllianceChatBox=ById('mod_comm_list2');
		var GlobalChatBox=ById('mod_comm_list1');

		var myregexp1 = new RegExp(tx("You are # [0-9]+ of [0-9]+ to help"),"i");
		var myregexp2 = new RegExp(tx("\'s Kingdom does not need help\."),"i");
		var myregexp3 = new RegExp(tx("\'s project has already been completed\."),"i");
		var myregexp4 = new RegExp(tx("\'s project has received the maximum amount of help\."),"i");
		var myregexp5 = new RegExp(tx("You already helped with (.*?)\'s project\."),"i");
		var myregexp6 = new RegExp(tx("is low on food. Remaining:"),"i");
		var myregexp7 = new RegExp(tx("\> "+uW.g_js_strings.getChat.saystoalliance+"\:\<\/b\>"),"i");
		var myregexp8 = new RegExp(tx("\> "+uW.g_js_strings.sendChat.saystoalliance+"\:\<\/b\>"),"i");
		var myregexp9 = new RegExp("[(]spam[)]","i");
		var myregexp10 = new RegExp("[{]spam[}]","i");
		var myregexp11 = new RegExp("[-]spam[-]","i");

		if(AllianceChatBox){
			var chatPosts = document.evaluate(".//div[contains(@class,'chatwrap')]", AllianceChatBox, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
			if(chatPosts){
				for (var i = 0; i < chatPosts.snapshotLength; i++) {
					thisPost = chatPosts.snapshotItem(i);

					if(Options.ChatOptions.HelpRequest){
						var postAuthor = document.evaluate('.//*[@class="nm"]', thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
						if(postAuthor.snapshotItem(0)){
							var postAuthorName = postAuthor.snapshotItem(0).innerHTML;
							if(postAuthorName != DisplayName){
								var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
								if(helpAllianceLinks){
									for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
										thisLink = helpAllianceLinks.snapshotItem(j);
										var alreadyClicked = thisLink.getAttribute("clicked");
										if(!alreadyClicked){
											thisLink.setAttribute('clicked', 'true');
											var myregexp = /(claimAllianceChatHelp\(.*\);)/;
											var match = myregexp.exec(thisLink.getAttribute("onclick"));

											if (match != null) {
												onclickCode = match[0];
												DouW(onclickCode);
											}
										}
									}
								}
							}
						}
					}

					if(Options.ChatOptions.DeleteRequest){ // Hide alliance requests in alli chat
						var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
						if(helpAllianceLinks){
							for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
								thisLink = helpAllianceLinks.snapshotItem(j);
								thisLink.parentNode.parentNode.parentNode.parentNode.parentNode.removeChild(thisLink.parentNode.parentNode.parentNode.parentNode);
							}
						}
						// Hide alliance request reports in alli chat
						if (thisPost.innerHTML.match(myregexp1) || thisPost.innerHTML.match(myregexp2) || thisPost.innerHTML.match(myregexp3) || thisPost.innerHTML.match(myregexp4) || thisPost.innerHTML.match(myregexp5)) {
							thisPost.parentNode.removeChild(thisPost);
						}
					}

					if(Options.ChatOptions.DeleteFood){ // hide food alerts in alli chat
						var NameArray = [];
						if (Options.ChatOptions.DeleteFoodUsers.trim() != "")
							NameArray = Options.ChatOptions.DeleteFoodUsers.trim().toUpperCase().split(",");
						var postAuthor = document.evaluate('.//*[@class="nm"]', thisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
						if(postAuthor.snapshotItem(0)){
							var postAuthorName = postAuthor.snapshotItem(0).innerHTML;
							if(postAuthorName != DisplayName && ((NameArray.indexOf(postAuthorName.split(" ")[1].toUpperCase()) != -1) || NameArray.length==0)){
								if (thisPost.innerHTML.match(myregexp6)) {
									thisPost.parentNode.removeChild(thisPost);
								}
							}
						}
					}

					if(Options.ChatOptions.DeleteAllianceSpam){ // hide alli spam in alli chat
						if (thisPost.innerHTML.match(myregexp9) || thisPost.innerHTML.match(myregexp10) || thisPost.innerHTML.match(myregexp11)) {
							thisPost.parentNode.removeChild(thisPost);
						}
					}
				}
			}

			// delete alliance chats from global chat if required

			if(Options.ChatOptions.DeleteRequest || Options.ChatOptions.DeleteFood || Options.ChatOptions.DeletegAl) {
				var gchatPosts = document.evaluate(".//div[contains(@class,'chatwrap')]", GlobalChatBox, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
				if(gchatPosts) {
					for (var i = 0; i < gchatPosts.snapshotLength; i++) {
						var gthisPost = gchatPosts.snapshotItem(i);

						if (Options.ChatOptions.DeleteRequest) { // Hide alliance request reports in chat - note they don't say "says to the alliance" :/
							if (gthisPost.innerHTML.match(myregexp1) || gthisPost.innerHTML.match(myregexp2) || gthisPost.innerHTML.match(myregexp3) || gthisPost.innerHTML.match(myregexp4) || gthisPost.innerHTML.match(myregexp5)) {
								gthisPost.parentNode.removeChild(gthisPost);
							}
						}

						if(Options.ChatOptions.DeletegAl) { // hide alliance chat from global chat
							if (gthisPost.innerHTML.match(myregexp7) || gthisPost.innerHTML.match(myregexp8))
								gthisPost.parentNode.removeChild(gthisPost);
						}
						else {
							if (Options.ChatOptions.DeleteRequest) { // hide alliance requests from global chat
								var helpAllianceLinks=document.evaluate(".//a[contains(@onclick,'claimAllianceChatHelp')]", gthisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
								if(helpAllianceLinks){
									for (var j = 0; j < helpAllianceLinks.snapshotLength; j++) {
										thisLink = helpAllianceLinks.snapshotItem(j);
										thisLink.parentNode.parentNode.parentNode.parentNode.parentNode.removeChild(thisLink.parentNode.parentNode.parentNode.parentNode);
									}
								}
							}

							if(Options.ChatOptions.DeleteFood){ // hide food alerts from global chat
								var NameArray = [];
								if (Options.ChatOptions.DeleteFoodUsers.trim() != "")
									NameArray = Options.ChatOptions.DeleteFoodUsers.trim().toUpperCase().split(",");
								var postAuthor = document.evaluate('.//*[@class="nm"]', gthisPost, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
								if(postAuthor.snapshotItem(0)){
									var postAuthorName = postAuthor.snapshotItem(0).innerHTML;
									if(postAuthorName != DisplayName && ((NameArray.indexOf(postAuthorName.split(" ")[1].toUpperCase()) != -1) || NameArray.length==0)){
										if (gthisPost.innerHTML.match(myregexp6)) {
											gthisPost.parentNode.removeChild(gthisPost);
										}
									}
								}
							}
						}
					}
				}
			}
		};

		// check for global spam

		if(Options.ChatOptions.DeleteGlobalSpam){
			var gchatPosts = document.evaluate(".//div[contains(@class,'chatwrap')]", GlobalChatBox, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null );
			if(gchatPosts) {
				for (var i = 0; i < gchatPosts.snapshotLength; i++) {
					var gthisPost = gchatPosts.snapshotItem(i);
					if (!gthisPost.innerHTML.match(myregexp7) && !gthisPost.innerHTML.match(myregexp8) && (gthisPost.innerHTML.match(myregexp9) || gthisPost.innerHTML.match(myregexp10) || gthisPost.innerHTML.match(myregexp11))) { // hide spam from global
						gthisPost.parentNode.removeChild(gthisPost);
					}
				}
			}
		};
	},
}

var ChatStuff = {
	chatDivContentFunc: null,
	getChatFunc: null,
	leaders: {},
	ChatIcons : {},
	Colors : {
		ChatLeaders: '#B8B8B8',
		ChatGlobal: '#CCCCFF',
		ChatAll: '#99CCFF',
		ChatAtt: '#FF4D4D',
		ChatWhisper: '#FF4D4D',
		ChatVC: '#00FF00',
		ChatChancy: '#F8E151',
	},
	marchtimer : null,
	marchETA : null,
	marchDIR : '',

	init: function () {
		var t = ChatStuff;

		try {
			if (getMyAlliance()[0] > 0) {
				t.getAllianceLeaders();
			}
			t.readChatIcons();
			t.chatDivContentFunc = new CalterUwFunc('Chat.chatDivContent', [['return f.join("")', 'var msg = f.join("");\n msg=chatDivContent_hook(msg,d);\n return msg;']]);
			uWExportFunction ('chatDivContent_hook', t.chatDivContentHook);
			uWExportFunction ('chatDivContent_hook2', t.chatDivContentHook2);
			uWExportFunction ('ptChatIconClicked', t.e_iconClicked);
			uWExportFunction ('ptChatReportClicked', Rpt.FindReport);
			uWExportFunction ('ptfetchmarch', t.fetchmarchcaller);
			uWExportFunction('btSelectSmiley', ChatStuff.SelectSmiley);

			t.setEnable(Options.ChatOptions.chatEnhance);
			if (Options.ChatOptions.chatGlobal) {
				ById('mod_comm_list1').className += ' ptChatGlobal ';
			}
			if (Options.ChatOptions.chatAlliance) {
				ById('mod_comm_list2').className += ' ptChatAlliance ';
			}

			ChatComOverlay(); // enable chat filter buster!
			ChatPane.init(); // initialise chat hide functions
		}
		catch (err) {
			logerr(err); // write to log
		}
	},

	isAvailable: function () {
		var t = ChatStuff;
		t.chatDivContentFunc.isAvailable();
	},
	setEnable: function (tf) {
		var t = ChatStuff;
		t.chatDivContentFunc.setEnable(tf);
	},

	e_iconClicked: function (name) {
		if (ById('bot_comm_input'))
			var e = ById('bot_comm_input');
		else
			var e = ById('mod_comm_input');
		name = name.replace(/°°/g, "'");
		e.value = '@' + name + ' ';
	},

	chatDivContentHook2: function (msg) {
		var div = document.createElement('div');
		div.innerHTML = msg;
		div.innerText = div.innerHTML;
		msg = div.innerHTML.toString();
		return msg.htmlSpecialCharsDecode();
	},

	chatDivContentHook: function (msg, type) {
		var t = ChatStuff;
		var element_class = '';
		var alliance = false;
		var whisper = false;
		var whisper2 = false;
		var m = /div class=\'info\'>.*<\/div>/im.exec(msg);
		if (m == null) return msg;
		if (type != null) {
			if (type.indexOf(uW.g_js_strings.getChat.saystoalliance) > 0) {
				alliance = true;
			}
			if (type.indexOf(uW.g_js_strings.getChat.whisperstoyou) > 0) {
				whisper = true;
			}
			if (type.indexOf(uW.g_js_strings.sendChat.whispersto) > 0) { // when local whisper it says your name! need this for tower alert whisper
				whisper2 = true;
			}
		}
		var whisp = m[0];
		if (whisper) {
			if (Options.ChatOptions.chatWhisper) {
				element_class += ' ptChatWhisper ';
			}
		} else { //Global & Alliance
			if (Options.ChatOptions.chatBold)
				element_class += ' ptChatBold ';
		}
		var suid = /viewProfile\(this,([0-9]+),false/i.exec(m[0]);
		if (!suid)
			suid = uW.tvuid;
		else
			suid = suid[1];
		if (Options.ChatOptions.chatLeaders) {
			if (t.leaders[suid]) element_class += ' ptChat' + t.leaders[suid];
		}

		var aid = getMyAlliance()[0];
		if (Options.ChatOptions.GloryLeader && Options.ChatOptions.GloryLeaderAID==aid && Options.ChatOptions.GloryLeaderUID==suid) {
			element_class += ' ptChatGLORY';
		}
		if (Options.ChatOptions.Rainbow && suid==uW.tvuid) {
			element_class += ' ptChatRAINBOW';
		}

		if (Options.ChatOptions.chatIcons) {
			if (t.ChatIcons[suid]) {
				msg = msg.replace(/\bhttps\:\/\/[-a-z].*\'\/\>/i, "https://graph.facebook.com/" + t.ChatIcons[suid] + "/picture\'\/\>");
			} else {
				t.getfbid(suid);
			}
		}
		var fchar = new RegExp(atob('rQ=='), "g");
		msg = msg.replace(fchar, "").replace(/\&\#8232\;/g, "");
		if (alliance || whisper2) {
			if (m[0].indexOf(tx('** INCOMING TROOPS **')) >= 0 && Options.ChatOptions.chatAttack)
				element_class = ' ptChatAttack';
			if (m[0].indexOf(tx('My embassy has')) >= 0 && Options.ChatOptions.chatAttack)
				element_class = ' ptChatAttack';
			if (m[0].indexOf(tx('My wilderness at')) >= 0 && Options.ChatOptions.chatAttack)
				element_class = ' ptChatAttack';
			//barcode style catch
			if (m[0].indexOf('..:.') >= 0 && Options.ChatOptions.chatAttack) {
				element_class = ' ptChatAttack';
				var f = msg.indexOf('<div class=\'tx\'>');
				if (f >= 0) {
					msg = msg.replace(/<div class=\'tx\'>/, '</td></tr><div class=\'tx\'><center><table border="1" cellpadding="0"><tr><td>')
					msg = msg.replace(/\|\|/g, '</td></tr><tr><td>');
					var a = msg.indexOf('</div>', f);
					msg = msg.slice(0, a) + '</td></tr></table><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>' + msg.slice(a);
				}
				msg = msg.replace('..:.', '');
			}
			if (m[0].indexOf('.::.') >= 0 && Options.ChatOptions.chatAttack) {
				element_class = ' ptChatRecall';
				var f = msg.indexOf('<div class=\'tx\'>');
				if (f >= 0) {
					msg = msg.replace(/<div class=\'tx\'>/, '<div class=\'tx\'><center><table border="1" cellpadding="0"><tr><td>')
					msg = msg.replace(/\|\|/g, '</td></tr><tr><td>');
					var a = msg.indexOf('</div>', f);
					msg = msg.slice(0, a) + '</td></tr></table><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>' + msg.slice(a);
				}
				msg = msg.replace('.::.', '');
			}
		}
		//tables for other use
		if (m[0].indexOf(':::.') >= 0) {
			var f = msg.indexOf('<div class=\'tx\'>');
			if (f >= 0) {
				msg = msg.replace(/<div class=\'tx\'>/, '<div class=\'tx\'><center><table border="1" cellpadding="0"><tr><td>')
				msg = msg.replace(/\|\|/g, '</td></tr><tr><td>');
				var a = msg.indexOf('</div>', f);
				msg = msg.slice(0, a) + '</td></tr></table><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>' + msg.slice(a);
			}
			msg = msg.replace(':::.', '');
		}
		msg = msg.replace(/\|/g, '<br>');
		msg = msg.replace("class=\'content\'", "class='content " + element_class + "'");

		if (m[0].indexOf('Report No:') && Options.ReportOptions.NoDuplicateReports){
			var rid = /(\bReport\sNo:\s([0-9]+))/g.exec(msg);
			if (rid) {AllianceReportsCheck.addAllianceReport({reportId:rid[2], reportUnixTime:unixTime()});}
		}
		
		msg = msg.replace(/(\bReport\sNo\:\s([0-9]+))/g, '<a onclick=\'ptChatReportClicked($2,0)\'>$1</a>');
		msg = msg.replace(/(\bRpt\:([0-9]+))/g, '<a onclick=\'ptChatReportClicked($2,0)\'>$1</a>');
		msg = msg.replace(/#([0-9]+)#/g, '<a onclick=\'ptChatReportClicked($1,0)\'>$1</a>');

		if (m[0].indexOf('UID:')){ msg = msg.replace (/(\bUID:\s([0-9]+))/g, 'UID: $2 <a onclick=\'btMonitorExternalCallUID($2)\'>(Monitor)</a>'); }
		if (m[0].indexOf('TRC:')){ msg = msg.replace (/(\bTRC:\s([0-9]+))/g, 'UID: $2 <a onclick=\'btMonitorExternalCallUID($2)\'>(Monitor)</a>'); }
		if (m[0].indexOf('March id:') && Options.FetchMarchInfo){
			var mid = /(\bMarch\sid:\s([0-9]+))/g.exec(msg);
			if (mid && Tabs.MarchCrawl && Tabs.MarchCrawl.CrawlResult) {t.fetchmarch(mid[2],Tabs.MarchCrawl.CrawlResult);}
			msg = msg.replace (/(\bMarch\sid:\s([0-9]+))/g, '<a onclick=\'ptfetchmarch($2)\'>'+tx('Additional March details')+' ---></a>');
		}

		msg = msg.replace(/(\byoutube([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/www\.$1\',\'_blank\'\)\">$1</a>');
		msg = msg.replace(/(\byoutu\.be([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/www\.$1\',\'_blank\'\)\">$1</a>');
		msg = msg.replace(/(\btinyurl([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/www\.$1\',\'_blank\'\)\">$1</a>');
		msg = msg.replace(/(\W)(bot)(\W)/gi, '$1<a onclick=window.open("http://greasyfork.org/en/scripts/11839-koc-power-bot-plus")>$2</a>$3');
		msg = msg.replace(/(\W)(tools)(\W)/gi, '$1<a onclick=window.open("http://greasyfork.org/en/scripts/11839-koc-power-bot-plus")>$2</a>$3');
		msg = msg.replace(/(\W)(PB+)(\W)/gi, '$1<a onclick=window.open("http:///www.facebook.com/PowerBotPlus/")>$2</a>$3');
		msg = msg.replace(/(\W)(tro)(\W)/gi, '$1<a onclick=window.open("http://greasyfork.org/en/scripts/13389-tco")>$2</a>$3');
		msg = msg.replace(/(\W)(tco)(\W)/gi, '$1<a onclick=window.open("http://greasyfork.org/en/scripts/13389-tco")>$2</a>$3');
		if (KOCBYTE_ON) {
			msg = msg.replace(/(\W)(kocbyte)(\W)/gi, '$1<a onclick=window.open("http://www.kocbyte.com/")>$2</a>$3');
			msg = msg.replace(/(\W)(kocmon)(\W)/gi, '$1<a onclick=window.open("http://www.kocbyte.com/")>$2</a>$3');
		}
		msg = msg.replace(/(\W)(kocinfo)(\W)/gi, '$1<a onclick=window.open("http://www.facebook.com/groups/SolarsKOCinfoPage/")>$2</a>$3');
		msg = msg.replace(/(\W)(forums)(\W)/gi, '$1<a onclick=window.open("http://community.kabam.com/forums/forumdisplay.php?4-Kingdoms-of-Camelot")>$2</a>$3');
		var m = /(Lord|Lady) (.*?)</im.exec(msg);
		if (m != null)
			m[2] = m[2].replace(/\'/g, "\\\'");
		msg = msg.replace(/<img (.*?>)/img, '<A onclick=\"ptChatIconClicked(\'' + m[2] + '\')\"><img class=\"ptChatIcon\" $1</a>');
		if (Options.ChatOptions.ImagePreviews) { msg = msg.replace(/(\bi.imgur([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\"><img style="width:initial;height:initial;max-width:100%;float:none" src="http\:\/\/$1"></a><center><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>'); }
		else { msg = msg.replace(/(\bi.imgur([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\">$1</a>'); }
		if (Options.ChatOptions.ImagePreviews) { msg = msg.replace(/(\bi.giphy([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\"><img style="width:initial;height:initial;max-width:100%;float:none" src="http\:\/\/$1"></a><center><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>'); }
		else { msg = msg.replace(/(\bi.giphy([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\">$1</a>'); }
		if (Options.ChatOptions.ImagePreviews) { msg = msg.replace(/(\bi[0-9]+.tinypic([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\"><img style="width:initial;height:initial;max-width:100%;float:none" src="http\:\/\/$1"></a><center><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>'); }
		else { msg = msg.replace(/(\bi[0-9]+.tinypic([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\">$1</a>'); }
		if (Options.ChatOptions.ImagePreviews) { msg = msg.replace(/(\bs[0-9]+.postimg([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\"><img style="width:initial;height:initial;max-width:100%;float:none" src="http\:\/\/$1"></a><center><a onclick="this.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = \'none\';"><span style="font-size:10px;font-weight:normal;">'+tx('hide')+'</span></a></center>'); }
		else { msg = msg.replace(/(\bs[0-9]+.postimg([0-9a-z\.\?\/\=\-\_]+))/gi, '<a onclick=\"window.open\(\'http\:\/\/$1\',\'_blank\'\)\">$1</a>'); }
		if (Options.ChatOptions.Emoticons) {
			for (k in Smileys) {
				msg=replaceAll(msg,k, '<img class=smileyimage src=\"'+Smileys[k]+'\">',false); // no ignore case!
			}
		}

		if (whisper && Options.ChatOptions.enableWhisperAlert) {
			AudioManager.setVolume(Options.ChatOptions.Volume);
			AudioManager.setSource(eval('SOUND_FILES.' + Options.ChatOptions.WhisperPlay));
			AudioManager.play();
			AudioManager.stoptimer = setTimeout(function () { AudioManager.stop(); }, 2500);
		}
		if ((element_class == ' ptChatAttack') && Options.ChatOptions.enableTowerAlert) {
			AudioManager.setVolume(Options.ChatOptions.Volume);
			AudioManager.setSource(eval('SOUND_FILES.' + Options.ChatOptions.TowerPlay));
			AudioManager.play();
			AudioManager.stoptimer = setTimeout(function () { AudioManager.stop(); }, 5000);
		}

		return msg;
	},

	getAllianceLeaders: function () {
		var t = ChatStuff;
		var params = uW.Object.clone(uW.g_ajaxparams);
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetLeaders.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if (rslt.officers) {
					for (var uid in rslt.officers) {
						var user = rslt.officers[uid];
						t.leaders[user.userId] = user.type.substr(0, 4);
					}
				}
			},
		});
	},

	getfbid: function (uid) {
		fetchPlayerCourt(uid, ChatStuff.addfbuid);
	},

	addfbuid: function (rslt) {
		var t = ChatStuff;
		if (rslt.ok) {
			var uid = parseInt(rslt.playerInfo.userId);
			var fbid = parseInt(rslt.playerInfo.fbuid);
			t.ChatIcons[uid] = fbid;
			t.saveChatIcons();
		}
	},

	readChatIcons : function () {
		var t = ChatStuff;
		s = GM_getValue('ChatIcons');
		if (s != null) {
			opts = JSON2.parse(s);
			for (var k in opts) {
				t.ChatIcons[k] = opts[k];
			}
		}
	},

	saveChatIcons : function () {
		var t = ChatStuff;
		GM_setValue('ChatIcons', JSON2.stringify(t.ChatIcons));
	},

	fetchmarchcaller : function(mid) {
		var t = ChatStuff;
		t.fetchmarch(mid,ChatStuff.MarchPopup);
	},

	fetchmarch : function (mid,notify,qc) {
		var t = ChatStuff;
		if(!mid) { notify({}); return; }
		if (ById('ptfetchmarch')) ById('ptfetchmarch').innerHTML = tx("Fetching March")+"...";

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.rid = mid;
		var atimer = setTimeout(function() {notify ({errorMsg:'Fetch march timed out (March ID '+mid+')'});}, 6000);
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fetchMarch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				clearTimeout(atimer);
				if (rslt.ok){
					if (qc) {
						var ui = [];
						var n = {name:'???'}
						ui.push(n);
						notify ({userInfo:ui},{userInfo:ui},rslt.march);
					}
					else {
						t.fetchmarchPlayerInfo(rslt.march.fromPlayerId, rslt.march.toPlayerId, notify, rslt.march);
					}
				}
				else {
					notify ({errorMsg:'Fetch march error (March ID '+mid+')'});
				}
			},
			onFailure: function () {
				clearTimeout(atimer);
				notify ({errorMsg:'AJAX error'});
			},
		},true);
	},

	fetchmarchPlayerInfo : function (uid, uid2, notify, march, uidrslt) {
		var t = ChatStuff;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (uid2 && uid2 != 0) {
					t.fetchmarchPlayerInfo(uid2,0,notify,march,rslt);
				}
				else {
					if (!uidrslt) {
						notify (rslt,uidrslt,march);
					}
					else {
						notify (uidrslt,rslt,march);
					}
				}
			},
			onFailure: function () { notify ({errorMsg:'AJAX error'}); },
		},true);
	},

	UpdateMarchTime : function () {
		var t = ChatStuff;
		clearTimeout(t.marchtimer);
		var now = unixTime();
		var arrivalTime = t.marchETA - now;
		if (arrivalTime >= 0) {
			marchtime = uW.timestr(arrivalTime);
			t.marchtimer = setTimeout(t.UpdateMarchTime, 1000);
		}
		else {
			if (t.marchDIR == "") {
				marchtime = tx('Landed! (Please Refresh)');
			}
			else {
				marchtime = tx("Completed.");
			}
		}
		if (ById('ptmarchtime')) {
			ById('ptmarchtime').innerHTML = marchtime+t.marchDIR;
		}
	},

	MarchPopup : function (rslt,rslt2,march) {
		var t = ChatStuff;
		clearTimeout(t.marchtimer);

		var n = '<table align=center width=95% cellspacing=0 cellpadding=0>';
		n += '<tr><td class=xtabBR colspan=2>&nbsp;</td></tr>';

		if (rslt.userInfo) {
			if (Tabs.MarchCrawl && Tabs.MarchCrawl.catalogMarch) setTimeout( function () {Tabs.MarchCrawl.catalogMarch(rslt,rslt2,march);},0);

			var u = rslt.userInfo[0];
			var alli = 'None';
			if (u.allianceName)
				alli = u.allianceName + FormatDiplomacy(u.allianceId);

			var u2;
			if (rslt2 && rslt2.userInfo) {
				u2 = rslt2.userInfo[0];
				var alli2 = 'None';
				if (u2.allianceName)
					alli2 = u2.allianceName + FormatDiplomacy(u2.allianceId);
			}

			var a = march;
			n += '<tr><td class=xtabBR width=150>'+tx('March ID')+'</td><td class=xtab><b><input type=text id=ptmid value="'+a.marchId+'" '+(trusted?"":"disabled")+'>&nbsp;&nbsp;<a id=ptfetchmarch>'+tx('Refresh')+'</a></b></td></tr>';
			n += '<tr><td class=xtabBR colspan=2>&nbsp;</td></tr>';

			var marchStatus = parseInt(a.marchStatus);
			var now = unixTime();
			var destinationUnixTime = convertTime(new Date(a["destinationEta"].replace(" ", "T")+"Z")) - now;
			var returnUnixTime = convertTime(new Date(a["returnEta"].replace(" ", "T")+"Z")) - now;

			if ((destinationUnixTime < 0) || (marchStatus == 8) || (marchStatus == 2))
				marchdir = "Return";
			else
				marchdir = "Count";

			if (destinationUnixTime >= 0) {
				marchtime = uW.timestr(destinationUnixTime);
				t.marchETA = convertTime(new Date(a["destinationEta"].replace(" ", "T")+"Z"));
				t.marchDIR = '';
				t.marchtimer = setTimeout(t.UpdateMarchTime, 1000);
			}
			else {
				if (marchStatus == 2) {
					marchtime = uW.g_js_strings.commonstr.encamped;
				}
				else {
					if (returnUnixTime < 0) {
						marchtime = tx("Completed")+" ("+uW.timestr(returnUnixTime*(-1)) +" "+tx('ago')+")";
					}
					else {
						if (marchStatus == 8) {
							marchtime = uW.timestr(returnUnixTime)+' ('+uW.g_js_strings.commonstr.returning+')';
							t.marchETA = convertTime(new Date(a["returnEta"].replace(" ", "T")+"Z"));
							t.marchDIR = ' ('+uW.g_js_strings.commonstr.returning+')';
							t.marchtimer = setTimeout(t.UpdateMarchTime, 1000);
						}
						else {
							marchtime = tx("Waiting");
						}
					}
				}
			}
			n += '<tr><td class=xtab>'+tx('Time/Status')+'</td><td class=xtabBR id=ptmarchtime><b>'+marchtime+'</b></td></tr>';
			n += '<tr><td  class=xtabBR colspan=2>&nbsp;</td></tr>';

			n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.nametx+'</td><td class=xtabBR><b>' + u.genderAndName + '</b><td></tr>';
			n += '<tr><td class=xtab>UID</td><td class=xtabBR><b>' + MonitorLinkUID(a.fromPlayerId)+'</b></td></tr>';
			n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.might+'</td><td class=xtabBR>' + addCommas(parseInt(u.might))+'</td></tr>';
			n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.alliance+'</td><td class=xtabBR>'+ alli +'</td></tr>';

			n += '<tr><td class=xtabBR colspan=2>&nbsp;</td></tr>';

			var marchType = parseInt(a.marchType);
			if (marchType == 10) marchType=4; // Change Dark Forest type to Attack!
			var	hint = "";
			switch (marchType) {
				case 1: hint=uW.g_js_strings.commonstr.transport;break;
				case 2: hint=uW.g_js_strings.commonstr.reinforce;break;
				case 3: hint=uW.g_js_strings.commonstr.scout;break;
				case 4: hint=uW.g_js_strings.commonstr.attack;break;
				case 5: hint=uW.g_js_strings.commonstr.reassign;break;
			}
			n += '<tr><td class=xtab>'+tx('March Type')+'</td><td class=xtabBR><b>'+hint+'</b></td></tr>';
			n += '<tr><td class=xtab>'+tx('From')+'</td><td class=xtabBR><b>'+coordLink(a.fromXCoord,a.fromYCoord)+'</b></td></tr>';
			n += '<tr><td class=xtab>'+tx('CityID')+'</td><td class=xtabBR>'+a.fromCityId+'</td></tr>';
			n += '<tr><td  class=xtabBR colspan=2>&nbsp;</td></tr>';

			var totile = tileTypes[parseInt(a["toTileType"])];
			if (a["toTileType"] == 51) {
				if (!a["toPlayerId"]) { totile = "???"; }
				else { if (a["toPlayerId"] == 0) totile = 'Barb Camp'; }
			}
			totile = 'Lvl '+a["toTileLevel"]+' '+totile;
			n += '<tr><td class=xtab>To</td><td class=xtabBR><b>'+coordLink(a.toXCoord,a.toYCoord)+'&nbsp;'+totile+'</b></td></tr>';
			if (a["toCityId"] != 0) n += '<tr><td class=xtab>'+tx('CityID')+'</td><td class=xtabBR>'+a.toCityId+'</td></tr>';

			if (a["toPlayerId"] != 0 && a["toPlayerId"] != a["fromPlayerId"]) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.nametx+'</td><td class=xtabBR><b>'+u2.genderAndName+'</b></td></tr>';
			if (a["toPlayerId"] != 0 && a["toPlayerId"] != a["fromPlayerId"]) n += '<tr><td class=xtab>UID</td><td class=xtabBR><b>'+MonitorLinkUID(a.toPlayerId)+'</b></td></tr>';
			if (a["toPlayerId"] != 0 && a["toPlayerId"] != a["fromPlayerId"]) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.might+'</td><td class=xtabBR>' + addCommas(parseInt(u2.might))+'</td></tr>';
			if (a["toPlayerId"] != 0 && a["toPlayerId"] != a["fromPlayerId"]) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.alliance+'</td><td class=xtabBR>'+ alli2 +'</td></tr>';
			n += '<tr><td class=xtabBR colspan=2>&nbsp;</td></tr>';

			if (a["championId"] && a["championId"] != 0) {
				n +='<tr><td class=xtab>'+tx('Champion')+'</td><td class=xtabBR>'+tx('Champion ID')+':'+a["championId"]+'</td></tr>'; // this is all we can get from march :/
			}

			if (a["knightId"] > 0) n +='<tr><td class=xtab>'+uW.g_js_strings.commonstr.knight+'</td><td class=xtabBR>'+a.knightName+' (Atk:'+ a["knightCombat"]+')</td></tr>';

			n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.troops+'</td><td class=xtabBR>';
			for (var ui in uW.cm.UNIT_TYPES){
				i = uW.cm.UNIT_TYPES[ui];
				if((a["unit"+i+"Count"] > 0) || (a["unit"+i+"Return"] > 0)) {
					trpcol = '#000';
					original = '';
					if ((marchdir == "Return") && (a["unit"+i+"Return"] < a["unit"+i+"Count"])) { trpcol = '#f00'; original = '&nbsp;</span><span>('+addCommas(a["unit"+i+"Count"])+')'}
					n += '<span class=xtab>'+ uW.unitcost['unt'+i][0] +': <span class=xtab style="color:'+trpcol+'">'+ addCommas(a["unit"+i+marchdir])+original+'</span></span> ';
				}
			}
			n += '</td></tr>';

			if (a["fromSpellType"]) {
				var spell = eval('uW.g_js_strings.spells.name_'+a["fromSpellType"]);
				if (spell) {
					n +='<tr><td class=xtab>'+tx('Battle Spell')+'</td><td class=xtab><b>'+spell+'</b></td></tr>';
				}
			}

			if (a["gold"] > 0) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.gold+'</td><td class=xtabBR>'+ addCommas(a["gold"]) +'</td></tr>';
			if (a["resource1"] > 0) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.food+'</td><td class=xtabBR>'+ addCommas(a["resource1"]) +'</td></tr>';
			if (a["resource2"] > 0) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.wood+'</td><td class=xtabBR>'+ addCommas(a["resource2"]) +'</td></tr>';
			if (a["resource3"] > 0) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.stone+'</td><td class=xtabBR>'+ addCommas(a["resource3"]) +'</td></tr>';
			if (a["resource4"] > 0) n += '<tr><td class=xtab>'+uW.g_js_strings.commonstr.ore+'</td><td class=xtabBR>'+ addCommas(a["resource4"]) +'</td></tr>';
			if (a["resource5"] > 0) n += '<tr><td class=xtab>'+tx('Aether')+'</td><td class=xtabBR>'+ addCommas(a["resource5"]) +'</td></tr>';
		}
		else {
			n += '<tr><td class=xtab width=150>'+tx('March ID')+'</td><td class=xtabBR><b><input type=text id=ptmid value="" '+(trusted?"":"disabled")+'>&nbsp;&nbsp;<a id=ptfetchmarch>'+tx('Fetch')+'</a></b></td></tr>';
			if (rslt.errorMsg) {
				n += '<tr><td  class=xtabBR colspan=2>&nbsp;</td></tr>';
				n += '<tr><td  class=xtabBR colspan=2>'+rslt.errorMsg+'</td></tr>';
			}
		}
		n += '</table>';

		var MarchPop = null;

		var off = getAbsoluteOffsets(ById('mod_comm_list2'));
		MarchPop = new CPopup('ptShowMarch', off.left, off.top, 500, 500, true, function () {
					clearTimeout(t.marchtimer);
		});
		MarchPop.getTopDiv().innerHTML = '<DIV align=center><B>'+tx('MARCH DETAILS')+'</B></DIV>';
		MarchPop.getMainDiv().innerHTML = n;
		ById('ptfetchmarch').addEventListener('click', function () { uW.ptfetchmarch(ById('ptmid').value) }, false);

		MarchPop.show(true);
	},

	SelectSmiley: function(what) {

		function insertAtCaret(areaId, text) {
			var txtarea = ById(areaId);
			var scrollPos = txtarea.scrollTop;
			var caretPos = txtarea.selectionStart;

			var front = (txtarea.value).substring(0, caretPos);
			var back = (txtarea.value).substring(txtarea.selectionEnd, txtarea.value.length);
			txtarea.value = front + text + back;
			caretPos = caretPos + text.length;
			txtarea.selectionStart = caretPos;
			txtarea.selectionEnd = caretPos;
			txtarea.focus();
			txtarea.scrollTop = scrollPos;
		};
		insertAtCaret("bot_comm_input"," "+what+" ");return;
	},

	SmileyHelp : function (){
		var t = ChatStuff;
		if (t.smileypop) {
			t.smileypop.show(false);
			if (t.smileypop.onClose) t.smileypop.onClose();
			t.smileypop.destroy();
			t.smileypop = null;
			return;
		}

		var helpText = '<DIV style="max-height:400px; height:400px; overflow-y:auto">';
		helpText += '<TABLE width=100% cellspacing=0 cellpadding=2 border=0 class=xtab><tr>';
		var row=0;
		for (k in Smileys) {
			helpText += '<TR><TD align=right><a><img title="'+tx("click to insert to chat")+'" class=smileyimage src=\"'+Smileys[k]+'\" onclick="btSelectSmiley(\''+k+'\')"></a></td><TD align=right><font size=1>'+k+'</td></tr>';
		}
		helpText += '</table></div><br>';

		var off = getOffset(ById('btEmoticonLink'));
		t.smileypop = new CPopup('BotHelp', off.left, off.top+20, 150, 400, true);
		t.smileypop.getMainDiv().innerHTML = helpText;
		t.smileypop.getTopDiv().innerHTML = '<CENTER><B>'+tx("Emoticons")+'</b></center>';
		t.smileypop.show (true);
		ResetFrameSize('BotHelp',400,150);
	},
}

var Rpt = {
	reportpos:{x: -999, y: -999},
	popReport:null,
	atkmight:0,
	defmight:0,

	FindReport: function (rpId, pageNum) {
		var t = Rpt;
		FetchReport(rpId,function(rslt) {
			jQuery('#viewreports_marchreport_'+rpId).removeClass('unread');
			var rpt = rslt['index'];
			rpt.Side0PlayerId = rslt['index']['side0PlayerId'];
			rpt.Side0AllianceId = rslt['index']['side0AllianceId'];
			rpt.Side1PlayerId = rslt['index']['side1PlayerId'];
			t.GetNames(rpId, rpt);
		});
	},
	GetNames: function (rpId, rpt) {
		var t = Rpt;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = rpt.Side1PlayerId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				rpt.side1Name = rslt['userInfo']['0']['name'];
				rpt.side1AllianceName = rslt['userInfo']['0']['allianceName'];
				if (rpt.Side0PlayerId) {
					if (rpt.Side0PlayerId != 0) {
						var params = uW.Object.clone(uW.g_ajaxparams);
						params.uid = rpt.Side0PlayerId;
						new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
							method: "post",
							parameters: params,
							onSuccess: function (rslt) {
								rpt.side0Name = rslt['userInfo']['0']['name'];
								rpt.side0AllianceName = rslt['userInfo']['0']['allianceName'];
								t.GetReport(rpId, rpt);
							},
							onFailure: function () { actionLog('unable to display report','REPORTS'); },
						}, false);
					} else {
						rpt.side0Name = "Enemy";
						t.GetReport(rpId, rpt);
					}
				} else {
					rpt.side0Name = "Enemy";
					t.GetReport(rpId, rpt);
				}
			},
		}, true);
	},
	GetReport: function (rpId, rpt) {
		var t = Rpt;
		var side = 1;
		if (rpt.Side0PlayerId == uW.tvuid) {
			var side = 0;
		} else {
			if (rpt.Side1PlayerId == uW.tvuid) {
				var side = 1;
			} else {
				if (Seed.allianceDiplomacies) {
					if (parseInt(rpt.side0AllianceId) == parseInt(Seed.allianceDiplomacies.allianceId)) {
						var side = 0;
					} else {
						var side = 1;
					}
				}
			}
		}
		rpt.sideId = side;
		FetchReportDetail(rpId,side,function(rslt) {
			if (rslt.error_code)
				actionLog('Unable to display report','REPORTS');
			else
				t.ReportPopup(rslt, rpt, rpId);
		});
	},
	ReportPopup : function (rslt, rpt, reportId) {
		var t = Rpt;
		//need the info from the list query
		var m = '';
		var unitImg = [];
		var unitName = [];
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			unitName[i] = uW.unitcost['unt' + i][0];
			unitImg[i] = '<img src="'+TroopImagePrefix + i + TroopImageSuffix + '" title="'+unitName[i]+'">';
		}

		unitName[53] = tx('Crossbows');
		unitName[55] = tx('Trebuchet');
		unitName[60] = uW.fortcost.frt60[0];
		unitName[61] = uW.fortcost.frt61[0];
		unitName[62] = uW.fortcost.frt62[0];
		unitName[63] = uW.fortcost.frt63[0];
		unitName[99] = uW.buildingcost.bdg31[0];
		unitName[100] = uW.buildingcost.bdg30[0];

		unitImg[53] = '<img src="'+IMGURL+'units/unit_53_30.jpg" title="'+unitName[53]+'">';
		unitImg[55] = '<img src="'+IMGURL+'units/unit_55_30.jpg" title="'+unitName[55]+'">';
		unitImg[60] = '<img src="'+IMGURL+'units/unit_60_30.jpg" title="'+unitName[60]+'">';
		unitImg[61] = '<img src="'+IMGURL+'units/unit_61_30.jpg" title="'+unitName[61]+'">';
		unitImg[62] = '<img src="'+IMGURL+'units/unit_62_30.jpg" title="'+unitName[62]+'">';
		unitImg[63] = '<img src="'+IMGURL+'units/unit_63_30.jpg" title="'+unitName[63]+'">';
		unitImg[99] = '<img src="'+IMGURL+'units/redoubt_30.jpg" title="'+unitName[99]+'" width=30>';
		unitImg[100] = '<img src="'+IMGURL+'units/tower_30.jpg" title="'+unitName[100]+'" width=30>';

		for (var i = 101; i < 111; i++) {
			unitName[i] = eval("uW.g_js_strings.monsterUnitsNames.m" + i);
			unitImg[i] = '<img src="'+TroopImagePrefix + i + TroopImageSuffix + '" title="'+unitName[i]+'">';
		}

		var trEffect = [];
		for (var k in uW.cm.thronestats.effects)
			trEffect[k] = uW.g_js_strings.effects["name_" + k];
		var chEffect = ["hpm", "hpr", "dam", "arm", "str", "dex", "con", "hit", "cri", "blk"];
		var chEffectName = [uW.g_js_strings.champion_stats.hp, uW.g_js_strings.report_view.hp_remaining, uW.g_js_strings.champion_stats.damage, uW.g_js_strings.effects.name_203, uW.g_js_strings.effects.name_204, uW.g_js_strings.effects.name_205, uW.g_js_strings.effects.name_206, uW.g_js_strings.effects.name_207, uW.g_js_strings.effects.name_208, uW.g_js_strings.effects.name_209];
		rpt.marchName = '?';
		if (rpt.marchType == 0)
			rpt.marchName = tx('Desertion');
		else if (rpt.marchType == 1)
			rpt.marchName = uW.g_js_strings.commonstr.transport;
		else if (rpt.marchType == 2)
			rpt.marchName = uW.g_js_strings.commonstr.reinforce;
		else if (rpt.marchType == 3) {
			if (rpt.sideId == 0)
				rpt.marchName = tx('Anti-Scout');
			else
				rpt.marchName = uW.g_js_strings.commonstr.scout;
		} else if (rpt.marchType == 4) {
			if (rpt.sideId == 0)
				rpt.marchName = uW.g_js_strings.commonstr.defend;
			else
				rpt.marchName = uW.g_js_strings.commonstr.attack;
		} else if (rpt.marchType == 9)
			rpt.marchName = uW.g_js_strings.commonstr.raid;
		else if (rpt.marchType == 10)
			rpt.marchName = uW.g_js_strings.commonstr.darkForest;
		if (parseInt(rpt.side0TileType) <= 50)
			rpt.side0TileTypeText = tileTypes[parseInt(rpt.side0TileType)];
		else if (parseInt(rpt.side0TileType) == 57)
			rpt.side0TileTypeText = tx('Runic Megalith');
		else if (parseInt(rpt.side0CityId) == 0)
			rpt.side0TileTypeText = tx('Barb');
		else
			rpt.side0TileTypeText = tx('City');

		var koth=false;
		if (parseInt(rpt.side0TileType) == 57) koth=true;

		function buildHeader() {
			var h = '<div id=reportHeader style="width:100%;">';
			h += '<div id=reportHeaderLeft style="float:left;width:30%;text-align:left;">';
			h += formatUnixTime(rpt.reportUnixTime);
			h += '<br>';
			h += '<b>'+tx('Glory Gained')+': ';
			if (rslt['glory'])
				h += addCommas(rslt['glory']);
			else
				h += '0';
			h += '</b></div>';
			h += '<div id=reportHeaderCenter style="float:left;width:40%;text-align:center;">';
			if (rpt.side0TileTypeText != tx('City') && rpt.side0TileTypeText != tx('Barb') && rpt.marchName == uW.g_js_strings.commonstr.attack) {
				if (rslt['conquered'] == 1)
					h += '<FONT color="#CC0000"><B>'+tx('Conquered')+'</B></font>';
				else if (rslt['conquered'] == 0)
					h += '<FONT color="#080"><B>'+tx('Secured')+'</B></font>';
			} else if ((rslt['winner'] == 1 && rpt.sideId == 0) || (rslt['winner'] == 0 && rpt.sideId == 1)) {
				if (rpt.marchName == uW.g_js_strings.commonstr.scout)
					h += '<FONT color="#CC0000"><B>'+tx('Scouting Failed')+'</B></font>';
				else
					h += '<FONT color="#CC0000"><B>'+tx('You were defeated')+'</B></font>';
			} else if (rslt['winner'] == 0 && rpt.sideId == 0)
				h += '<FONT color="#080"><B>'+tx('You defended successfully')+'!</B></font>';
			else if (rslt['winner'] == 1 && rpt.sideId == 1) {
				if (rpt.marchName == uW.g_js_strings.commonstr.scout)
					h += '<FONT color="#080"><B>'+tx('Scouting Report')+'</B></font>';
				else
					h += '<FONT color="#080"><B>'+tx('You were victorious')+'!</B></font>';
			}
			h += '</div>';
			h += '<div id=reportHeaderRight style="float:right;width:30%;text-align:right;">';
			h += tx('Report No')+': ' + reportId;
			h += '<br><input id=ptpostreportid onclick="Chat.sendChat(\'/a '+tx('Report No')+': ' + enFilter(reportId) + '\')" style="font-size:9px" type="submit" value="'+tx('Post To Chat')+'">';
			if ((rpt.side1PlayerId && (rpt.side1PlayerId == uW.tvuid)) || (rpt.side0PlayerId && (rpt.side0PlayerId == uW.tvuid))) { h += '&nbsp;<input id=ptDeleteReport style="color:#f00;font-size:9px" type="submit" value="'+uW.g_js_strings.commonstr.deletetx+'">'; } //Delete button for own reports
			h += '</div></div><div style="clear:both;"></div>';
			return h;
		}

		function formatTroopLine(side,unit_type,overwhelmed,fought,survived) {
			var t = Rpt;
			var n = '';
			n += '<TR><TD>'+unitImg[unit_type]+'</td><td>'+unitName[unit_type]+'</td>';
			if (overwhelmed) {
				n += '<TD align=center>???</td>';
				n += '<TD align=center>???</td>';
				if (fought > 0) {
					n += '<TD align=center><FONT color="#CC0000">(' + addCommas(fought) + ')</FONT></td></tr>';
					if (side=="s0" && unit_type<50) { t.defmight += parseInt(uW.unitmight['unt'+unit_type] * fought); }
					if (side=="s0" && unit_type>=50 && unit_type<99) {
						var fm = parseIntNan(fortmight['f'+unit_type]);
						t.defmight += parseInt(fm * fought);
					}
				} else {
					n += '<TD align=center>0</td></tr>';
				}
			}
			else {
				var killed = parseInt(fought)-parseInt(survived);
				if (killed > 0) {
					n += '<TD align=center>' + addCommas(fought) + '</td>';
					n += '<TD align=center><FONT color="#CC0000">' + addCommas(survived) + '</FONT></td>';
					n += '<TD align=center><FONT color="#CC0000">(' + addCommas(killed) + ')</FONT></td></tr>';
					if (side=="s1") { t.atkmight += parseInt(uW.unitmight['unt'+unit_type] * killed); }
					if (side=="s0" && unit_type<50) { t.defmight += parseInt(uW.unitmight['unt'+unit_type] * killed); }
					if (side=="s0" && unit_type>=50 && unit_type<99) {
						var fm = parseIntNan(fortmight['f'+unit_type]);
						t.defmight += parseInt(fm * killed);
					}
				} else {
					n += '<TD align=center>' + addCommas(fought) + '</td>';
					n += '<TD align=center>' + addCommas(survived) + '</td></tr>';
				}
			}
			return n;
		};

		function buildBattle() {
			var t = Rpt;
			var m = '';

			t.atkmight = 0;
			t.defmight = 0;
			//header
			m += '<div class="divHeader" align=left>'+tx('Battle Results').toUpperCase()+'</div>';
			//summary
			m += '<div id=battleSummaryContainer>';
			//summary - attacker
			m += '<div style="width:50%;float:left;">';
			m += '<B>'+tx('Attackers')+':</B> ' + rpt.side1Name + ' (<A onclick="btGotoMapRpt(' + rpt.side1XCoord + ',' + rpt.side1YCoord + ')">' + rpt.side1XCoord + ',' + rpt.side1YCoord + '</a>) ';
			if (rslt['winner'] == 1)
				m += '<FONT color="#CC0000"><B> '+tx('Winner')+'</B></FONT>';
			m += '<br>';
			if (rpt.side1AllianceId && (rpt.side1AllianceId != 0)) m += uW.g_js_strings.commonstr.alliance+':&nbsp;<span style='+DiplomacyColours(rpt.side1AllianceId)+'>' + rpt.side1AllianceName + '</span><br>';
			if (rpt.side1PlayerId && (rpt.side1PlayerId != 0)) m += 'UID:&nbsp;' + MonitorLinkUID(rpt.side1PlayerId) + '<br>';
			if (rpt.marchName == uW.g_js_strings.commonstr.attack || rpt.marchName == uW.g_js_strings.commonstr.defend)
				m += tx('Knight Combat Skill')+': ' + rslt['s1KCombatLv'] + '<br>';
			if (rslt['s1spell'] && (rslt['s1spell'] != "0")) {
				m += tx('Spell Used')+': <b>' + eval('uW.g_js_strings.spells.name_' + rslt['s1spell']) + '</b><br>';
			}
			m += '<span id=atkmightlost>&nbsp;</span></div>';
			//summary - defender
			m += '<div style="width:50%;float:left;">';
			m += '<B>'+tx('Defenders')+'</B> ' + rpt.side0Name + ' (<A onclick="btGotoMapRpt(' + rpt.side0XCoord + ',' + rpt.side0YCoord + ')">' + rpt.side0XCoord + ',' + rpt.side0YCoord + '</a>) ';
			if (rslt['winner'] == 0)
				m += '<FONT color="#CC0000"><B> '+tx('Winner')+'</B></FONT>';
			m += '<br>';
			if (rpt.side0AllianceId && (rpt.side0AllianceId != 0)) m += uW.g_js_strings.commonstr.alliance+':&nbsp;<span style='+DiplomacyColours(rpt.side0AllianceId)+'>' + rpt.side0AllianceName + '</span><br>';
			if (rpt.side0PlayerId && (rpt.side0PlayerId != 0)) m += 'UID:' + MonitorLinkUID(rpt.side0PlayerId) + '<br>';
			if (rpt.marchName == uW.g_js_strings.commonstr.attack || rpt.marchName == uW.g_js_strings.commonstr.defend)
				m += tx('Knight Combat Skill')+': ' + rslt['s0KCombatLv'] + '<br>';
			if (rslt['s0spell'] && (rslt['s0spell'] != "0")) {
				m += tx('Spell Used')+': <b>' + eval('uW.g_js_strings.spells.name_' + rslt['s0spell']) + '</b><br>';
			}
			if (rslt['fght']["s0"] && rpt.side0PlayerId && (rpt.side0PlayerId != 0)) {
				m += '<span id=defmightlost>&nbsp;</span><br>';
			}
			if (rslt['rnds']) m += tx('Rounds')+': ' + rslt['rnds'] + '<br>';
			if (rslt['darkForestConflict']) {
				m += uW.g_js_strings.report_view.darkForestConflict;
			} else {
				if (rpt.side0TileTypeText != tx('City') && rpt.sideId == 0) {
					if (rslt['conquered'] == 1)
						m += tx('Attackers conquered the')+' '+rpt.side0TileTypeText+'.';
					else if (rslt['conquered'] == 0)
						m += tx('Attackers did not conquer the')+' '+rpt.side0TileTypeText+'.';
				} else {
					if (rslt['wall']) {
						if (rslt['wall'] == 100)
							m += tx('Attackers breached the walls')+'.';
						else
							m += tx('Attackers did not breach the walls')+'. '+tx('The walls are')+' ' + rslt['wall'] + '% '+tx('damaged');
					}
				}
			}
			m += '</div>';
			m += '</div>'; //end battlesummary div
			//troops
			m += '<div id=battleTroopsContainer style="clear:both">';
			//troops - attacker
			m += '<div style="width:50%;float:left;"><TABLE cellspacing=0 class=ptTab width=100%>';
			if (rslt['fght']["s1"]) {
				m += '<TR><TH class=xtabHD></TH><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.troops+'</TH><TH class=xtabHD align=center>'+tx('Fought')+'</TH><TH class=xtabHD align=center>'+tx('Survived')+'</TH><TH class=xtabHD align=center>'+tx('Killed')+'</TH></TR>';
				for (var ui in uW.cm.UNIT_TYPES) {
					i = uW.cm.UNIT_TYPES[ui];
					if (rslt['fght']["s1"]['u'+i]) {
						m += formatTroopLine("s1",i,false,rslt['fght']["s1"]['u'+i][0],rslt['fght']["s1"]['u'+i][1]);
					}
				}
			}
			m += '</table></div>';
			//troops - defender
			m += '<div style="width:50%;float:left;">';
			m += '<TABLE cellspacing=0 class=ptTab width=100%>';
			if (rslt['fght']["s0"]) {
				m += '<TR><TH class=xtabHD></TH><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.troops+'</TH><TH class=xtabHD align=center>'+tx('Fought')+'</TH><TH class=xtabHD align=center>'+tx('Survived')+'</TH><TH class=xtabHD align=center>'+tx('Killed')+'</TH></TR>';
				for (var ui in uW.cm.UNIT_TYPES) {
					i = uW.cm.UNIT_TYPES[ui];
					if (rslt['fght']["s0"]['u'+i] && rslt['fght']["s0"]['u'+i][0]!=null) {
						m += formatTroopLine("s0",i,rslt.overwhelmed,rslt['fght']["s0"]['u'+i][0],rslt['fght']["s0"]['u'+i][1]);
					}
				}
				for (var i = 53; i <= 55; i++) {
					if (rslt['fght']["s0"]['f'+i]) {
						m += formatTroopLine("s0",i,rslt.overwhelmed,rslt['fght']["s0"]['f'+i][0],rslt['fght']["s0"]['f'+i][1]);
					}
				}
				for (var i = 60; i <= 63; i++) {
					if (rslt['fght']["s0"]['f'+i]) {
						m += formatTroopLine("s0",i,rslt.overwhelmed,rslt['fght']["s0"]['f'+i][0],rslt['fght']["s0"]['f'+i][1]);
					}
				}
				for (var i = 99; i <= 100; i++) {
					if (rslt['fght']["s0"]['u'+i] && rslt['fght']["s0"]['u'+i][0]!=null) {
						m += formatTroopLine("s0",i,rslt.overwhelmed,rslt['fght']["s0"]['u'+i][0],rslt['fght']["s0"]['u'+i][1]);
					}
				}
				for (var i = 101; i <= 110; i++) {
					if (rslt['fght']["s0"]['m'+i]) {
						m += formatTroopLine("s0",i,rslt.overwhelmed,rslt['fght']["s0"]['m'+i][0],rslt['fght']["s0"]['m'+i][1]);
					}
				}
			}
			else {
				m += '<TR><TD>'+tx('No Troops Defended')+'</TD></TR>';
			}
			m += '</table>';
			m += '</div>';
			m += '</div>'; //end troops div
			m += '<div style="clear:both"></div>';
			return m;
		}

		function formatTroopStat(Attr,name,spelltitle,unitId) {
			var TroopString = '';
			var TroopStyle = '';
			var TroopTitle = '';
			if (Attr) {
				if (Attr[0] < Attr[1]) TroopStyle = 'color:green';
				if (Attr[1] < Attr[0]) TroopStyle = 'color:red';
				if (Attr[1]!=Attr[0] && Attr[0]!=0) TroopTitle = 'title="'+Math.round((Attr[1]-Attr[0])/Math.round(Attr[0])*100)+'%"';
				if (spelltitle) TroopTitle = 'title="'+uW.g_js_strings.report_view["spellcaster" + unitId].replace("%1$s", addCommas(Math.round(Attr[1] * 100) / 100))+'"';
				TroopString = '<td style="width:33%;" align=left '+TroopTitle+'><font size="1"><b>'+tx(name)+': </b><span style="'+TroopStyle+'">' + addCommas(Math.round(Attr[1] * 100) / 100) + '</span></font></td>';
			}
			return TroopString;
		};

		function buildTroopStats() {
			var m = '';
			if (rslt['bonus']) {
				//header
				m += '<a id=reportTroopStatsHdr class=divLink ><div class="divHeader" align=left><img id=reportTroopStatsArrow height="10" src="'+RightArrow+'">&nbsp;'+uW.g_js_strings.report_view.troop_stats.toUpperCase()+'</div></a>';
				//stats
				m += '<div id=reportTroopStats class="divHide">';
				//troops - attacker - stats
				m += '<div style="width:50%;float:left;">';
				if (rslt['fght']["s1"]) {
					for (var ui in uW.cm.UNIT_TYPES) {
						i = uW.cm.UNIT_TYPES[ui];
						if (rslt['fght']["s1"]['u'+i] && rslt['bonus']['mod']["s1"]['u'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['rng'],'Rng');
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['ld'],'Ld');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['sp'],'Spell');
							m += formatTroopStat(rslt['bonus']['mod']['s1']['u'+i]['spellEffect'],'Effect',true,i);
							m += '</tr></table></div>';
						}
					}
				}
				m += '</div>';
				//troops - defender - stats
				m += '<div style="width:50%;float:left;">';
				if (rslt['fght']["s0"]) {
					for (var ui in uW.cm.UNIT_TYPES) {
						i = uW.cm.UNIT_TYPES[ui];
						if (rslt['fght']["s0"]['u'+i] && rslt['bonus']['mod']["s0"]['u'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['rng'],'Rng');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['sp'],'Spell');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['spellEffect'],'Effect',true,i);
							m += '</tr></table></div>';
						}
					}
					for (var i = 53; i <= 55; i++) {
						if (rslt['fght']["s0"]['f'+i] && rslt['bonus']['mod']['s0']['f'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['rng'],'Rng');
							m += '</tr></table></div>';
						}
					}
					for (var i = 60; i <= 63; i++) {
						if (rslt['fght']["s0"]['f'+i] && rslt['bonus']['mod']['s0']['f'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['f'+i]['rng'],'Rng');
							m += '</tr></table></div>';
						}
					}
					for (var i = 99; i <= 100; i++) {
						if (rslt['fght']["s0"]['u'+i] && rslt['bonus']['mod']["s0"]['u'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['u'+i]['rng'],'Rng');
							m += '</tr></table></div>';
						}
					}
					for (var i = 101; i <= 110; i++) {
						if (rslt['fght']["s0"]['m'+i] && rslt['bonus']['mod']['s0']['m'+i]) {
							m += '<div style="float:left;width:10%;clear:both;">' + unitImg[i] + '</div>';
							m += '<div style="float:left;width:90%;"><table class=ptTab width=100%><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['m'+i]['hp'],'HP');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['m'+i]['atk'],'Atk');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['m'+i]['def'],'Def');
							m += '</tr><tr>';
							m += formatTroopStat(rslt['bonus']['mod']['s0']['m'+i]['spd'],'Spd');
							m += formatTroopStat(rslt['bonus']['mod']['s0']['m'+i]['rng'],'Rng');
							m += '</tr></table></div>';
						}
					}
				}
				m += '</div>';
				m += '<div style="clear:both">&nbsp;</div>';
				m += '</div>'; //end reportTroopStats div
			}
			return m;
		}

		function buildChampDuel() {
			var m = '';
			if (rslt['champion_stats']) {
				s1name = rslt.champion_stats['s1'].nam;
				s1win = rslt.champion_stats['s1'].won;
				s1percent = Math.round(1000*parseIntNan(rslt.champion_stats['s1'].hpr)/parseIntNan(rslt.champion_stats['s1'].hpm))/10;
				s0name = rslt.champion_stats['s0'].nam;
				s0win = rslt.champion_stats['s0'].won;
				s0percent = Math.round(1000*parseIntNan(rslt.champion_stats['s0'].hpr)/parseIntNan(rslt.champion_stats['s0'].hpm))/10;
				if ((s1name != '') || (s0name != '')) {
					//header
					m += '<a id=reportChampDuelHdr class=divLink ><div class="divHeader" align=left><img id=reportChampDuelArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('Champion Duel').toUpperCase()+'</div></a>';
					//summary
					m += '<div id=reportChampDuel>';
					m += '<div id=ChampStatContainer>';
					m += '<div style="width:50%;float:left;">';
					if (s1name == '') {
						s1name = uW.g_js_strings.champ.no_champ;
					}
					if (s1win) {
						s1name += '&nbsp;('+tx('Winner')+')';
					}
					m += '<b>' + s1name + '</b><br>';
					for (var i = 1; i < chEffect.length; i++) {
						if (rslt.champion_stats['s1'][chEffect[i]]) {
							m += chEffectName[i] + ': ' + rslt.champion_stats['s1'][chEffect[i]];
							if (i==1&&s1win) m += ' <span class=boldGreen>('+s1percent+'%)</span>';
							m += '<br>';
						}
					}
					m += '</div>'; //attacker
					m += '<div style="width:50%;float:left;">';
					if (s0name == '') {
						s0name = uW.g_js_strings.champ.no_champ;
					}
					if (s0win) {
						s0name += '&nbsp;('+tx('Winner')+')';
					}
					m += '<b>' + s0name + '</b><br>';
					for (var i = 1; i < chEffect.length; i++) {
						if (rslt.champion_stats['s0'][chEffect[i]]) {
							m += chEffectName[i] + ': ' + rslt.champion_stats['s0'][chEffect[i]];
							if (i==1&&s0win) m += ' <span class=boldGreen>('+s0percent+'%)</span>';
							m += '<br>';
						}
					}
					m += '</div>'; //defender
					m += '</div>'; //ChampStatContainer
					m += '<div style="clear:both">&nbsp;</div>';
					if (rslt.bonus) {
						if (rslt.bonus['chp']) {
							m+='<div id=ChampAdjContainer style="clear:both">';
							m+='<div style="width:50%;float:left;">';
							m+='<b>'+tx('Champion Adjustments')+'</b><br><TABLE class=ptTab width=100%>';
							if (rslt.bonus['chp']['s0'] || rslt.bonus['chp']['s1']) {
								for (var i in uW.cm.thronestats.effects) {
									trEffect[i] = uW.g_js_strings.throneRoom["effectName_" + i];
									var TRStyles = getTREffectStyle(i);
									if (rslt.bonus['chp']['s1'] && rslt.bonus['chp']['s1'][0][i]) {
										m+='<TR><TD colspan=4>' + TRStyles.LineStyle + trEffect[i] +': ' + (Math.round(rslt.bonus['chp']['s1'][0][i]*100)/100) + TRStyles.EndStyle + '</TD></TR>';
									}
									if (rslt.bonus['chp']['s0'] && rslt.bonus['chp']['s0'][1][i]) {
										m+='<TR><TD colspan=4>' + TRStyles.LineStyle + trEffect[i] +': ' + (Math.round(rslt.bonus['chp']['s0'][1][i]*100)/100) + TRStyles.EndStyle + '</TD></TR>';
									}
								}
							}
							m+='</table></br>'
							m+='</div>';//attacker
							m+='<div style="width:50%;float:left;">';
							m+='<b>'+tx('Champion Adjustments')+'</b><br><TABLE class=ptTab width=100%>';
							if (rslt.bonus['chp']['s0'] || rslt.bonus['chp']['s1']) {
								for (var i in uW.cm.thronestats.effects) {
									trEffect[i] = uW.g_js_strings.throneRoom["effectName_" + i];
									var TRStyles = getTREffectStyle(i);
									if (rslt.bonus['chp']['s0'] && rslt.bonus['chp']['s0'][0][i]) {
										m+='<TR><TD colspan=4>' + TRStyles.LineStyle + trEffect[i] +': ' + (Math.round(rslt.bonus['chp']['s0'][0][i]*100)/100) + TRStyles.EndStyle + '</TD></TR>';
									}
									if (rslt.bonus['chp']['s1'] && rslt.bonus['chp']['s1'][1][i]) {
										m+='<TR><TD colspan=4>' + TRStyles.LineStyle + trEffect[i] +': ' + (Math.round(rslt.bonus['chp']['s1'][1][i]*100)/100) + TRStyles.EndStyle + '</TD></TR>';
									}
								}
							}
							m+='</table></br>'
							m+='</div>';//defender
							m+='</div>';//ChampAdjContainer
							m+='<div style="clear:both">&nbsp;</div>';
						}
					}
					m += '</div>'; //reportChampDuel
				}
			}
			return m;
		}

		function buildThroneStats() {
			var m = '';
			//header
			m += '<a id=reportThroneHdr class=divLink ><div class="divHeader" align=left><img id=reportThroneArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('Throne Stats').toUpperCase()+'</div></a>';
			//summary
			m += '<div id=reportThrone>';
			m += '<div style="width:50%;float:left;">';

			var SortOrder = [];
			if (Options.MonitorOptions.AlternateSortOrder) { for (var z in AlternateSortOrder) SortOrder.push(AlternateSortOrder[z]); }
			else { for (var z in trEffect) SortOrder.push(z);	}

			if (rslt['s1ThroneRoomBoosts']) {
				for (var z in SortOrder) {
					var i = SortOrder[z];
					if (rslt['s1ThroneRoomBoosts'][i]) {
						var TRStyles = getTREffectStyle(i);
						m += TRStyles.LineStyle + trEffect[i] + ': ' + rslt['s1ThroneRoomBoosts'][i] + '%' + TRStyles.EndStyle + '</span><br>';
					}
				}
			}
			else { m += '&nbsp;'; }
			m += '</div>'; //attacker
			m += '<div style="width:50%;float:left;">';
			if (rslt['s0ThroneRoomBoosts']) {
				for (var z in SortOrder) {
					var i = SortOrder[z];
					if (rslt['s0ThroneRoomBoosts'][i]) {
						var TRStyles = getTREffectStyle(i);
						m += TRStyles.LineStyle + trEffect[i] + ': ' + rslt['s0ThroneRoomBoosts'][i] + '%' + TRStyles.EndStyle + '</span><br>';
					}
				}
			}
			else { m += '&nbsp;'; }
			m += '</div>'; //defender
			m += '<div style="clear:both">&nbsp;</div>';
			m += '</div>'; //throne container
			return m;
		}

		function buildBoosts() {
			var m = '';
			//header
			m += '<a id=reportBoostsHdr class=divLink ><div class="divHeader" align=left><img id=reportBoostsArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('Troop Adjustments').toUpperCase()+'</div></a>';
			//summary
			m += '<div id=reportBoosts>';
			if (rslt['s1atkBoost'] || rslt['s1defBoost'] || rslt['s1lifeBoost'] || rslt['s0atkBoost'] || rslt['s0defBoost'] || rslt['s0lifeBoost']) {
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Item Boosts')+'</b><br>';
				if (rslt['s1atkBoost'])
					m += tx('Attack Boosted')+': ' + 100 * rslt['s1atkBoost'] + '%<br>';
				if (rslt['s1defBoost'])
					m += tx('Defence Boosted')+': ' + 100 * rslt['s1defBoost'] + '%<br>';
				if (rslt['s1lifeBoost'])
					m += tx('Health Boosted')+': ' + 100 * rslt['s1lifeBoost'] + '%<br>';
				m += '</div>'; //attacker
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Item Boosts')+'</b><br>';
				if (rslt['s0atkBoost'])
					m += tx('Attack Boosted')+': ' + 100 * rslt['s0atkBoost'] + '%<br>';
				if (rslt['s0defBoost'])
					m += tx('Defence Boosted')+': ' + 100 * rslt['s0defBoost'] + '%<br>';
				if (rslt['s0lifeBoost'])
					m += tx('Health Boosted')+': ' + 100 * rslt['s0lifeBoost'] + '%<br>';
				m += '</div>'; //defender
				m += '<div style="clear:both">&nbsp;</div>';
			}
			if (rslt['arcaneBonus'] && (rslt['arcaneBonus']['s0AllianceBonus'] || rslt['arcaneBonus']['s1AllianceBonus'])) {
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Arcane Temple Boosts')+' ('+tx('Alliance')+')</b><br>';
				if (rslt['arcaneBonus']['s1AllianceBonus']) {
					var ArcBonus = rslt['arcaneBonus']['s1AllianceBonus'];
					for (var z in ArcBonus) {
						var ArcName = uW.itemlist['i'+ArcBonus[z].itemId].name + ' - ' + uW.itemlist['i'+ArcBonus[z].itemId].description;
						m += ArcName + ': ' + ArcBonus[z].effect + '%<br>';
					}
				}
				m += '</div>'; //attacker
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Arcane Temple Boosts')+' ('+tx('Alliance')+')</b><br>';
				if (rslt['arcaneBonus']['s0AllianceBonus']) {
					var ArcBonus = rslt['arcaneBonus']['s0AllianceBonus'];
					for (var z in ArcBonus) {
						var ArcName = uW.itemlist['i'+ArcBonus[z].itemId].name + ' - ' + uW.itemlist['i'+ArcBonus[z].itemId].description;
						m += ArcName + ': ' + ArcBonus[z].effect + '%<br>';
					}
				}
				m += '</div>'; //defender
				m += '<div style="clear:both">&nbsp;</div>';
			}
			if (rslt['arcaneBonus'] && (rslt['arcaneBonus']['s0PersonalBonus'] || rslt['arcaneBonus']['s1PersonalBonus'])) {
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Arcane Temple Boosts')+' ('+tx('Personal')+')</b><br>';
				if (rslt['arcaneBonus']['s1PersonalBonus']) {
					var ArcBonus = rslt['arcaneBonus']['s1PersonalBonus'];
					for (var z in ArcBonus) {
						var ArcName = uW.itemlist['i'+ArcBonus[z].itemId].name + ' - ' + uW.itemlist['i'+ArcBonus[z].itemId].description;
						m += ArcName + ': ' + ArcBonus[z].effect + '%<br>';
					}
				}
				m += '</div>'; //attacker
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Arcane Temple Boosts')+' ('+tx('Personal')+')</b><br>';
				if (rslt['arcaneBonus']['s0PersonalBonus'].length>0) {
					var ArcBonus = rslt['arcaneBonus']['s0PersonalBonus'];
					for (var z in ArcBonus) {
						var ArcName = uW.itemlist['i'+ArcBonus[z].itemId].name + ' - ' + uW.itemlist['i'+ArcBonus[z].itemId].description;
						m += ArcName + ': ' + ArcBonus[z].effect + '%<br>';
					}
				}
				m += '</div>'; //defender
				m += '<div style="clear:both">&nbsp;</div>';
			}
			if (rslt['s1guardianAtkBoost'] || rslt['s1guardianDefBoost'] || rslt['s1guardianMarchBoost'] || rslt['s1guardianTrainBoost'] || rslt['s0guardianAtkBoost'] || rslt['s0guardianDefBoost'] || rslt['s0guardianMarchBoost'] || rslt['s0guardianTrainBoost']) {
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Guardian Boosts')+'</b><br>';
				if (rslt['s1guardianAtkBoost'])
					m += tx('Guardian Attack Boost')+': ' + parseFloat(100 * rslt['s1guardianAtkBoost']).toFixed(1) + '%<br>';
				if (rslt['s1guardianDefBoost'])
					m += tx('Guardian Life Boost')+': ' + parseFloat(100 * rslt['s1guardianDefBoost']).toFixed(1) + '%<br>';
				if (rslt['s1guardianMarchBoost'])
					m += tx('Guardian March Speed Boost')+': ' + parseFloat(100 * rslt['s1guardianMarchBoost']).toFixed(1) + '%<br>';
				if (rslt['s1guardianTrainBoost'])
					m += tx('Guardian Training Boost')+': ' + parseFloat(100 * rslt['s1guardianTrainBoost']).toFixed(1) + '%<br>';
				m += '</div>'; //attacker
				m += '<div style="width:50%;float:left;">';
				m += '<b>'+tx('Guardian Boosts')+'</b><br>';
				if (rslt['s0guardianAtkBoost'])
					m += tx('Guardian Attack Boost')+': ' + parseFloat(100 * rslt['s0guardianAtkBoost']).toFixed(1) + '%<br>';
				if (rslt['s0guardianDefBoost'])
					m += tx('Guardian Life Boost')+': ' + parseFloat(100 * rslt['s0guardianDefBoost']).toFixed(1) + '%<br>';
				if (rslt['s0guardianMarchBoost'])
					m += tx('Guardian March Speed Boost')+': ' + parseFloat(100 * rslt['s0guardianMarchBoost']).toFixed(1) + '%<br>';
				if (rslt['s0guardianTrainBoost'])
					m += tx('Guardian Training Boost')+': ' + parseFloat(100 * rslt['s0guardianTrainBoost']).toFixed(1) + '%<br>';
				m += '</div>'; //defender
				m += '<div style="clear:both">&nbsp;</div>';
			}
			if (rslt.bonus) {
				if (rslt.bonus['tch'] || rslt.bonus['tch2']) {
					m += '<div style="width:50%;float:left;">';
					m += '<b>'+tx('Research')+'</b><br>';
					if (rslt.bonus['tch']) {
						for (var t1l in rslt.bonus.tch.s1) {
							var normaltech = '';
							if (t1l == 'hp') normaltech = tx('Health');
							if (t1l == 'atk') normaltech = uW.g_js_strings.commonstr.attack;
							if (t1l == 'def') normaltech = uW.g_js_strings.commonstr.defense;
							if (t1l == 'spd') normaltech = tx('Speed');
							if (t1l == 'rng') normaltech = tx('Range');
							if (t1l == 'ld') normaltech = tx('Load');
							if (normaltech != '')
								m += normaltech + ': ' + parseFloat(rslt.bonus.tch.s1[t1l] * 100).toFixed(0) + '%<br>';
						}
					}
					if (rslt.bonus['tch2']) {
						for (var t2l in rslt.bonus.tch2.s1) {
							var britontech = '';
							if (t2l == 'ic') britontech = uW.g_js_strings.commonstr.improved;
							if (t2l == 'id') britontech = uW.g_js_strings.commonstr.improved_def;
							if (t2l == 'sr') britontech = uW.g_js_strings.commonstr.strengthen_ranks;
							if (t2l == 'if') britontech = uW.g_js_strings.commonstr.improved_fletching;
							if (britontech != '')
								m += britontech + ': ' + parseFloat(rslt.bonus.tch2.s1[t2l] * 100).toFixed(0) + '%<br>';
						}
					}
					m += '</div>'; //attacker
					m += '<div style="width:50%;float:left;">';
					m += '<b>'+tx('Research')+'</b><br>';
					if (rslt.bonus['tch']) {
						for (var t1l in rslt.bonus.tch.s0) {
							var normaltech = '';
							if (t1l == 'hp') normaltech = tx('Health');
							if (t1l == 'atk') normaltech = uW.g_js_strings.commonstr.attack;
							if (t1l == 'def') normaltech = uW.g_js_strings.commonstr.defense;
							if (t1l == 'spd') normaltech = tx('Speed');
							if (t1l == 'rng') normaltech = tx('Range');
							if (normaltech != '')
								m += normaltech + ': ' + parseFloat(rslt.bonus.tch.s0[t1l] * 100).toFixed(0) + '%<br>';
						}
					}
					if (rslt.bonus['tch2']) {
						for (var t2l in rslt.bonus.tch2.s0) {
							var britontech = '';
							if (t2l == 'ic') britontech = uW.g_js_strings.commonstr.improved;
							if (t2l == 'id') britontech = uW.g_js_strings.commonstr.improved_def;
							if (t2l == 'sr') britontech = uW.g_js_strings.commonstr.strengthen_ranks;
							if (t2l == 'if') britontech = uW.g_js_strings.commonstr.improved_fletching;
							if (britontech != '')
								m += britontech + ': ' + parseFloat(rslt.bonus.tch2.s0[t2l] * 100).toFixed(0) + '%<br>';
						}
					}
				}
				m += '</div>'; //defender
				m += '<div style="clear:both">&nbsp;</div>';
			}
			m += '</div>'; //boosts
			m += '<div style="clear:both"></div>';
			return m;
		}

		function handleLoot() {
			var m = '';
			if (rslt['loot'] || rslt['throneRoomDrop'] || rslt['equipmentDrop'] || rslt['lootJewel']) {
				m += '<div class="divHeader" align=left>'+uW.g_js_strings.commonstr.loot.toUpperCase()+'</div>';
				if (rslt['loot']) {
					m += '<TABLE style="width:100%;" class=ptTab>';
					m += '<TR><TD style="width:18%">'+GameIcons.goldImgTiny+'&nbsp;';
					if (rslt['loot'][0] > 0)
						m += addCommas(parseFloat(rslt['loot'][0]).toFixed(0)) + '</TD>';
					else
						m += '0</td>'
					m += '<TD style="width:18%">' + GameIcons.foodImgTiny+'&nbsp;';
					if (rslt['loot'][1] > 0)
						m += addCommas(parseFloat(rslt['loot'][1]).toFixed(0)) + '</TD>';
					else
						m += '0</TD>';
					m += '<TD style="width:18%">' + GameIcons.woodImgTiny+'&nbsp;';
					if (rslt['loot'][2] > 0)
						m += addCommas(parseFloat(rslt['loot'][2]).toFixed(0)) + '</TD>';
					else
						m += '0</td>'
					m += '<TD style="width:18%">' + GameIcons.stoneImgTiny+'&nbsp;';
					if (rslt['loot'][3] > 0)
						m += addCommas(parseFloat(rslt['loot'][3]).toFixed(0)) + '</TD>';
					else
						m += '0</TD>';
					m += '<TD style="width:18%">' + GameIcons.oreImgTiny+'&nbsp;';
					if (rslt['loot'][4] > 0)
						m += addCommas(parseFloat(rslt['loot'][4]).toFixed(0)) + '</TD>';
					else
						m += '0</td>'
					m += '<TD style="width:15%">' + GameIcons.astoneImgTiny+'&nbsp;';
					if (rslt['loot'][6] > 0)
						m += addCommas(parseFloat(rslt['loot'][6]).toFixed(0)) + '</TD>';
					else {
						m += '0</TD>';
					}
					m += '</tr>'
				}
				if ((rslt['loot'] && rslt['loot'][5]) || rslt['throneRoomDrop'] || rslt['equipmentDrop'] || rslt['lootJewel']) {
					var itemdetails = '';
					var thronedetails = '';
					var equipdetails = '';
					var jeweldetails = '';
					if (rslt['loot'] && rslt['loot'][5] && JSON2.stringify(rslt['loot'][5]) != '[]') { // crapola
						for (var item in rslt['loot'][5]) {
							var amt="";
							if (rslt['loot'][5][item] != 1) { amt = ' ('+rslt['loot'][5][item]+')';}
							var itemurl = parseInt(item);
							if (itemurl > 30669 && itemurl < 32111) itemurl = 30303;
							itemdetails += '<img style="width:20px;vertical-align:text-bottom;" src="'+getItemImageURL(itemurl)+'">&nbsp;' + uW.itemlist['i' + item].name + amt +'&nbsp;&nbsp;&nbsp;';
						}
					}
					if (rslt['throneRoomDrop']) {
						var TR = rslt['throneRoomDrop'];
						var thronename = cardQuality[TR.quality]+" "+TR.type+" "+uW.g_js_strings.commonstr.of+" "+eval("uW.g_js_strings.effects.suffix_"+TR.effects.slot5.id)+" ("+TR.faction+")";

						var TRCard = {};
						TRCard.id = TR.id;
						TRCard.name = cardQuality[TR.quality]+" "+TR.type+" "+uW.g_js_strings.commonstr.of+" "+eval("uW.g_js_strings.effects.suffix_"+TR.effects.slot5.id);
						TRCard.faction = TR.faction;
						TRCard.type = TR.type;
						TRCard.unique = parseIntNan(TR.unique);
						TRCard.level = TR.level;
						TRCard.quality = TR.quality;
						TRCard.createPrefix = function () { return ""; };
						TRCard.createSuffix = function () { return ""; };
						TRCard.effects = {};
						var slot = 0;
						for (var k in TR.effects) {
							slot++
							TRCard.effects["slot"+slot] = {};
							TRCard.effects["slot"+slot].id = TR.effects[k].id;
							TRCard.effects["slot"+slot].tier = TR.effects[k].tier;
						}
						thronedetails += '<span class=tooldesc><img style="width:20px;vertical-align:text-bottom;" src="'+IMGURL+'throne/icons/30/' + TR.faction + '/' + TR.faction + '_'+ TR.type +'_normal_1_'+ TR.quality+'.png" >&nbsp;' + thronename + '<span class="tooltip" style="white-space: pre-line; word-wrap: break-word;">'+Tabs.Reference.DisplayTRCard(TRCard,false)+'</span></span>&nbsp;&nbsp;&nbsp;';
					}
					if (rslt['equipmentDrop']) {
						var EQ = rslt['equipmentDrop'];
						var equipname = cardQuality[EQ.rarity]+" "+EQ.subtype+" "+uW.g_js_strings.commonstr.of+" "+eval("uW.g_js_strings.effects.suffix_"+EQ["effects"][5]["id"])+" ("+champFaction[EQ.faction-1]+")";

						var CHCard = {};
						CHCard.id = EQ.equipmentId;
						CHCard.name = cardQuality[EQ.rarity]+" "+EQ.subtype+" "+uW.g_js_strings.commonstr.of+" "+eval("uW.g_js_strings.effects.suffix_"+EQ["effects"][5]["id"]);
						CHCard.faction = uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(EQ.faction)].toLowerCase();
						CHCard.Type = EQ.type;
						CHCard.type = chTypes[parseInt(EQ.type)-1];
					    CHCard.unique = parseIntNan(EQ.itemId);
						CHCard.level = EQ.level;
						CHCard.quality = EQ.rarity;
						CHCard.createPrefix = function () { return ""; };
						CHCard.createSuffix = function () { return ""; };
						CHCard.effects = {};
						var slot = 0;
						for (var k in EQ.effects) {
							slot++
							CHCard.effects["slot"+slot] = {};
							CHCard.effects["slot"+slot].id = EQ.effects[k].id;
							CHCard.effects["slot"+slot].tier = EQ.effects[k].tier;
						}
						equipdetails += '<span class=tooldesc><img style="width:20px;vertical-align:text-bottom;" src="'+IMGURL+'champion_hall/' + cardQuality[EQ.rarity].toLowerCase() + '_' + champImageTypes[EQ.type-1] + '_' + champFaction[EQ.faction-1] + '_30x30.png">&nbsp;' + equipname + '<span class="tooltip" style="white-space: pre-line; word-wrap: break-word;">'+Tabs.Reference.DisplayCHCard(CHCard,false)+'</span></span>&nbsp;&nbsp;&nbsp;';
					}
					if (rslt['lootJewel'] && JSON2.stringify(rslt['lootJewel']) != '[]') {
						item = rslt['lootJewel'];
						var amt="";
						if (item.quantity != 1) { amt = ' ('+item.quantity+')';}
						jeweldetails += '<img style="width:20px;vertical-align:text-bottom;" src="'+IMGURL+'throne/icons/70/jewel_' + jewelTypes[CM.ThroneController.jewelType(item)] + '_' + jewelQuality[item.quality-1] + '.jpg">&nbsp;' + CM.ThroneController.jewelQualityName(item.quality)+" "+CM.ThroneController.getEffectName(item.id)+" "+tx('Jewel') + amt +'&nbsp;&nbsp;&nbsp;';
					}
					m += '<tr><td colspan=6>'+itemdetails+thronedetails+equipdetails+jeweldetails+'</TD></TR>';
				}
				m += '</TABLE><br>';
			}
			return m;
		}

		function handleTransportLoot() {
			var m = '';
			m += '<div class="divHeader" align=left>'+uW.g_js_strings.commonstr.loot.toUpperCase()+'</div><TABLE style="width:100%;" class=ptTab>';
			m += '<TR><TD style="width:18%">' + GameIcons.goldImgTiny;
			if (rslt['gold'] > 0)
				m += addCommas(rslt['gold']) + '</TD>';
			else
				m += '0</td>'
			m += '<TD style="width:18%">' + GameIcons.foodImgTiny;
			if (rslt['resource1'] > 0)
				m += addCommas(rslt['resource1']) + '</TD>';
			else
				m += '0</TD>';
			m += '<TD style="width:18%">' + GameIcons.woodImgTiny;
			if (rslt['resource2'] > 0)
				m += addCommas(rslt['resource2']) + '</TD>';
			else
				m += '0</td>'
			m += '<TD style="width:18%">' + GameIcons.stoneImgTiny;
			if (rslt['resource3'] > 0)
				m += addCommas(rslt['resource3']) + '</TD>';
			else
				m += '0</TD>';
			m += '<TD style="width:18%">' + GameIcons.oreImgTiny;
			if (rslt['resource4'] > 0)
				m += addCommas(rslt['resource4']) + '</TD>';
			else
				m += '0</td>'
			m += '<TD style="width:15%">' + GameIcons.astoneImgTiny;
			if (rslt['resource5'] > 0)
				m += addCommas(rslt['resource5']) + '</TD>';
			else
				m += '0</TD>';
			m += '</tr>'
			m += '</TABLE><br>';
			return m;
		}

		function deleteThisRpt(testing) {
			var side0 = '';
			var side1 = '';
			if (rpt.sideId == 1) side1 = rpt.marchReportId;
			if (rpt.sideId == 0) side0 = rpt.marchReportId;
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.s0rids = side0;
			params.s1rids = side1;
			params.cityrids = '';
			new MyAjaxRequest(uW.g_ajaxpath + "ajax/deleteCheckedReports.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					if (rslt.ok) {
						delete ReportCache[rpt.marchReportId];
						delete ReportDetailCache[rpt.marchReportId];
						t.CloseReport();
						if (ById('modal_msg_tabs_report') && jQuery('#modal_msg_tabs_report').hasClass('selected')) {
							uW.Messages.listReports();
						}
						if (Tabs.Messages && (Options.MessagesOptions.rptType == 'alliance' || Options.MessagesOptions.rptType == 'player')) {
							var ind = Tabs.Messages.DisplayIdArray.indexOf(parseInt(rpt.marchReportId));
							if (ind>=0) {
								Tabs.Messages.data.splice(Tabs.Messages.DisplayArray[ind],1);
								delete Tabs.Messages.report[rpt.marchReportId];
								Tabs.Messages.DisplayRpt();
							}
						}
					}
				},
				onFailure: function () {
					if (notify) {
						notify('AJAX ERROR');
					}
				},
			});
		}

		function handleunts() { // Troops sent to Reinforce or troops found on a Scout (also show destination for transports)
			var m = '';
			//header
			if (rpt.marchName == uW.g_js_strings.commonstr.reinforce)
				m += '<div class="divHeader" align=left>'+tx('Reinforcement').toUpperCase()+'</div>';
			else
				if (rpt.marchName == uW.g_js_strings.commonstr.transport)
					m += '<div class="divHeader" align=left>'+tx('Destination').toUpperCase()+'</div>';
				else
					m += '<div class="divHeader" align=left>'+tx('Scout Report').toUpperCase()+'</div>';
			//summary
			m += '<div id=scoutSummaryContainer>';
			//summary - troops
			m += '<div style="width:50%;float:left;">';
			if (rpt.marchName == uW.g_js_strings.commonstr.reinforce)
				m += '<B>'+tx('Ally')+':</B> ' + rpt.side1Name + ' (<A onclick="btGotoMapRpt(' + rpt.side1XCoord + ',' + rpt.side1YCoord + ')">' + rpt.side1XCoord + ',' + rpt.side1YCoord + '</a>)<br>';
			if (rslt['unts'] != undefined) {
				m += '<TABLE class=ptTab>';
				for (var ui in uW.cm.UNIT_TYPES) {
					i = uW.cm.UNIT_TYPES[ui];
					if (rslt['unts']['u' + i] != undefined)
						m += '<TR><TD>'+unitImg[i]+'</TD><TD>'+unitName[i]+'</TD><TD align=right>' + addCommas(rslt['unts']['u' + i]) + '</TD></TR>';
				}
				m += '</TABLE>';
			}
			m += '&nbsp;</div>';
			//summary - city and defences
			m += '<div style="width:50%;float:left;">';
			if ((rpt.marchName == uW.g_js_strings.commonstr.reinforce) || (rpt.marchName == uW.g_js_strings.commonstr.transport))
				m += '<B>'+tx('Destination')+'</B> ' + rpt.side0Name + ' (<A onclick="btGotoMapRpt(' + rpt.side0XCoord + ',' + rpt.side0YCoord + ')">' + rpt.side0XCoord + ',' + rpt.side0YCoord + '</a>)<br>';
			else {
				m += '<TABLE class=ptTab width=100%>';
				m += '<TR><TD>' + rpt.side0Name + ' (<A onclick="btGotoMapRpt(' + rpt.side0XCoord + ',' + rpt.side0YCoord + ')">' + rpt.side0XCoord + ',' + rpt.side0YCoord + '</a>)</td></tr>';
				if (rpt.side0AllianceId && (rpt.side0AllianceId != 0)) m += '<TR><TD>'+uW.g_js_strings.commonstr.alliance+':&nbsp;<span style='+DiplomacyColours(rpt.side0AllianceId)+'>' + rpt.side0AllianceName + '</span></td></tr>';
				if (rpt.side0PlayerId && (rpt.side0PlayerId != 0)) m += '<TR><TD>UID: ' + MonitorLinkUID(rpt.side0PlayerId)+'</td></tr>';
				if (rslt['lstlgn']) {
					if (!rslt['lstlgn'])
						m += '<TR><TD>'+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+': '+tx('Not recorded')+'</TD></TR>';
					else
						m += '<TR><TD>'+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+': ' + formatUnixTime(rslt['lstlgn']) + '</TD></TR>';
				}
				m += '<TR><TD>'+tx('Marshall Combat')+': ';
				if (rslt['knt'] && rslt['knt']['cbt'])
					m += rslt['knt']['cbt'];
				else
					m += uW.g_js_strings.commonstr.none;
				m += '</TD></TR>';
				if (rslt['pop'])
					m += '<TR><TD>'+uW.g_js_strings.commonstr.population+': ' + addCommas(rslt['pop']) + '</TD></TR>';
				if (rslt['hap'])
					m += '<TR><TD>'+uW.g_js_strings.commonstr.happiness+': ' + addCommas(rslt['hap']) + '</TD></TR></TABLE>';
				m += '</TD></TR></TABLE><br>';
				m += handlefrt();
			}
			m += '</div>';
			m += '</div>'; //end scoutsummary div
			m += '<div style="clear:both"></div>';
			return m;
		}

		function buildResearch() {
			var m = '';
			//header
			m += '<a id=reportResearchHdr class=divLink ><div class="divHeader" align=left><img id=reportResearchArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('Buildings and Research').toUpperCase()+'</div></a>';
			//summary
			m += '<div id=reportResearch class=divHide>';
			if (rslt['blds']) {
				m += '<div style="width:50%;float:left;">';
				if (rslt['blds']) {
					m += '<TABLE cellspacing=0 class=ptTab><TR><TH class=xtabHD colspan=2 align=left>'+tx('Buildings')+'</TH></TR>';
					for (var bi in rslt['blds'])
						if ((bi != 'b1') && (bi != 'b2') && (bi != 'b3') && (bi != 'b4')) {
							m += handleblds(bi.split("b")[1]);
						}
					m += '</TABLE>';
				}
				if (rslt['blds']['b1'] || rslt['blds']['b2'] || rslt['blds']['b3'] || rslt['blds']['b4']) {
					m += '<TABLE cellspacing=0 class=ptTab><TR><TH class=xtabHD colspan=2 align=left>'+tx('Fields')+'</TH></TR>';
					for (var i = 1; i < 5; i++)
						if (rslt['blds']['b' + i])
							m += handleblds(i);
					m += '</TABLE>';
				}
				m += '</div>';
			}
			if (rslt['tch'] || rslt['tch2']) {
				m += '<div style="width:50%;float:left;">';
				if (rslt['tch']) {
					m += '<TABLE cellspacing=0 class=ptTab><TR><TH class=xtabHD colspan=2 align=left>'+tx('Research')+'</TH></TR>';
					for (var tl in rslt.tch) {
						tid = /[0-9]+/.exec(tl);
						m += '<TR><TD>' + uW.techcost['tch' + tid[0]][0] + '</TD><TD align=right>' + rslt.tch[tl] + '</TD></TR>';
					}
					m += '</TABLE>';
				}
				if (rslt['tch2']) {
					m += '<TABLE cellspacing=0 class=ptTab><TR><TH class=xtabHD colspan=2 align=left>'+tx('Briton Research')+'</TH></TR>';
					for (var tl in rslt.tch2) {
						tid = /[0-9]+/.exec(tl);
						m += '<TR><TD>' + uW.techcost2['tch' + tid[0]][0] + '</TD><TD align=right>' + rslt.tch2[tl] + '</TD></TR>';
					}
					m += '</TABLE>';
				}
				m += '</div>';
				m += '<div style="clear:both">&nbsp;</div>';
			}
			m += '</div>';
			return m;
		}

		function handlersc(scout) { // Resources brought with reinforcements or found on a Scout
			var m = '';
			if (rslt['rsc'] != undefined) {
				if (rslt['rsc']['r1'] > 0 || rslt['rsc']['r2'] > 0 || rslt['rsc']['r3'] > 0 || rslt['rsc']['r4'] > 0) {
					if (rpt.marchName == uW.g_js_strings.commonstr.reinforce)
						m += '<div class="divHeader" align=left>'+tx('Goodies Brought').toUpperCase()+'</div><TABLE style="width:100%;" class=ptTab>';
					else
						m += '<div class="divHeader" align=left>'+tx('Goodies Found').toUpperCase()+'</div><TABLE style="width:100%;" class=ptTab>';
					m += '<TR><TD style="width:18%">' + GameIcons.goldImgTiny;
					if (rslt['gld'] > 0)
						m += addCommas(parseFloat(rslt['gld']).toFixed(0)) + '</TD>';
					else
						m += '0</td>';
					m += '<TD style="width:18%">' + GameIcons.foodImgTiny;
					if (rslt['rsc']['r1'] > 0)
						m += addCommas(parseFloat(rslt['rsc']['r1']).toFixed(0)) + '</TD>';
					else
						m += '0</td>';
					m += '<TD style="width:18%">' + GameIcons.woodImgTiny;
					if (rslt['rsc']['r2'] > 0)
						m += addCommas(parseFloat(rslt['rsc']['r2']).toFixed(0)) + '</TD>';
					else
						m += '0</td>';
					m += '<TD style="width:18%">' + GameIcons.stoneImgTiny;
					if (rslt['rsc']['r3'] > 0)
						m += addCommas(parseFloat(rslt['rsc']['r3']).toFixed(0)) + '</TD>';
					else
						m += '0</td>';
					m += '<TD style="width:18%">' + GameIcons.oreImgTiny;
					if (rslt['rsc']['r4'] > 0)
						m += addCommas(parseFloat(rslt['rsc']['r4']).toFixed(0)) + '</TD>';
					else
						m += '0</td>';
					if (rslt['rsc']['r5'] > 0) {
						m += '<TD style="width:15%">' + GameIcons.astoneImgTiny;
						m += addCommas(parseFloat(rslt['rsc']['r5']).toFixed(0)) + '</TD>';
					}
					else {
						if (scout != true) {
							m += '<TD style="width:15%">' + GameIcons.astoneImgTiny + '0</td>';
						}
					}
					m += '</TABLE>';
				}
			}
			return m;
		}

		function handlefrt() { // Fortifications found on a Scout
			var m = '';
			if (rslt['frt'] || (rslt['blds'] && rslt['blds']['b30'])|| (rslt['blds'] && rslt['blds']['b31'])) {
				if (rslt['frt']['f53'] != undefined || rslt['frt']['f55'] != undefined || rslt['frt']['f60'] != undefined || rslt['frt']['f61'] != undefined || rslt['frt']['f62'] != undefined || rslt['frt']['f63'] != undefined || (rslt['blds'] && rslt['blds']['b30']) || (rslt['blds'] && rslt['blds']['b31'])) {
					m = '<TABLE cellspacing=0 class=ptTab><TR><TH class=xtabHD colspan=3 align=left>'+tx('Defences Found')+'</TH></TR>';
					if (rslt['frt']['f53'] != undefined)
						m += '<TR><TD>' + unitImg[53] + '</TD><TD>'+unitName[53]+'</TD><TD align=right>' + addCommas(rslt['frt']['f53']) + '</TD></TR>';
					if (rslt['frt']['f55'] != undefined)
						m += '<TR><TD>' + unitImg[55] + '</TD><TD>'+unitName[55]+'</TD><TD align=right>' + addCommas(rslt['frt']['f55']) + '</TD></TR>';
					if (rslt['frt']['f60'] != undefined)
						m += '<TR><TD>' + unitImg[60] + '</TD><TD>'+unitName[60]+'</TD><TD align=right>' + addCommas(rslt['frt']['f60']) + '</TD></TR>';
					if (rslt['frt']['f61'] != undefined)
						m += '<TR><TD>' + unitImg[61] + '</TD><TD>'+unitName[61]+'</TD><TD align=right>' + addCommas(rslt['frt']['f61']) + '</TD></TR>';
					if (rslt['frt']['f62'] != undefined)
						m += '<TR><TD>' + unitImg[62] + '</TD><TD>'+unitName[62]+'</TD><TD align=right>' + addCommas(rslt['frt']['f62']) + '</TD></TR>';
					if (rslt['frt']['f63'] != undefined)
						m += '<TR><TD>' + unitImg[63] + '</TD><TD>'+unitName[63]+'</TD><TD align=right>' + addCommas(rslt['frt']['f63']) + '</TD></TR>';
					if (rslt['blds'] && rslt['blds']['b31'])
						m += '<TR><TD>' + unitImg[99] + '</TD><TD>'+unitName[99]+'</TD><TD align=right>('+uW.g_js_strings.commonstr.level+' ' + rslt['blds']['b31'] + ')</TD></TR>';
					if (rslt['blds'] && rslt['blds']['b30'])
						m += '<TR><TD>' + unitImg[100] + '</TD><TD>'+unitName[100]+'</TD><TD align=right>('+uW.g_js_strings.commonstr.level+' ' + rslt['blds']['b30'] + ')</TD></TR>';
					m += '</TABLE>';
				}
			}
			return m;
		}

		function handleblds(bType) {
			if (rslt['blds']) {
				var blds = rslt['blds']['b' + bType];
				var b = '<TR><TD>';
				arField = [], firstbld = true;
				b += uW.buildingcost['bdg'+bType][0];
				b += '</TD><TD>';
				for (var i = 1; i <= 12; i++)
					arField[i] = 0;
				for (var i = 0; i < blds.length; i++)
					arField[blds[i]]++
				for (var i = 12; i > 0; i--) {
						if (arField[i] > 0) {
							if (firstbld)
								firstbld = false;
							else
								b += ', ';
							if (arField[i] > 1)
								b += arField[i] + ' x ';
							b += ' ' + i;
						}
					}
				b += '</TD></TR>';
				return b;
			}
		}

		t.CloseReport();
		if (rpt.marchName == uW.g_js_strings.commonstr.reinforce) {
			t.popReport = new CPopup('btReportPopup', t.reportpos.x, t.reportpos.y, 750, 240, true, function () {
				t.reportpos = t.popReport.getLocation();
				clearTimeout(1000);
			});
			m += '<DIV style="height:180px">';
		} else if (rpt.marchName == uW.g_js_strings.commonstr.transport) {
			t.popReport = new CPopup('btReportPopup', t.reportpos.x, t.reportpos.y, 750, 240, true, function () {
				t.reportpos = t.popReport.getLocation();
				clearTimeout(1000);
			});
			m += '<DIV style="height:180px">';
		} else if (rpt.marchName == uW.g_js_strings.commonstr.scout && rslt['winner'] == 1 && rpt.sideId == 1) {
			t.popReport = new CPopup('btReportPopup', t.reportpos.x, t.reportpos.y, 750, 680, true, function () {
				t.reportpos = t.popReport.getLocation();
				clearTimeout(1000);
			});
			m += '<DIV style="max-height:640px; height:640px; overflow-y:scroll">';
		} else {
			t.popReport = new CPopup('btReportPopup', t.reportpos.x, t.reportpos.y, 750, 680, true, function () {
				t.reportpos = t.popReport.getLocation();
				clearTimeout(1000);
			});
			m += '<DIV style="max-height:640px; height:640px; overflow-y:scroll">';
		}
		if ((t.reportpos.x == -999) && (t.reportpos.y == -999)) {
			t.popReport.centerMe(mainPop.getMainDiv());
		}
		m += buildHeader();
		if (rpt.marchName == uW.g_js_strings.commonstr.transport) { // Transport
			m += handleTransportLoot();
			m += handleunts();
		}
		m += handleLoot();
		if (rpt.marchName == uW.g_js_strings.commonstr.reinforce) {
			m += handlersc(false);
			m += handleunts();
		}
		if (rpt.marchName == uW.g_js_strings.commonstr.scout && rslt['winner'] == 1) {
			m += handlersc(true);
			m += handleunts();
			m += buildResearch();
		}
		if (rslt['fght']) {
			m += buildBattle();
			m += buildTroopStats();
			if (!koth) {
				m += buildChampDuel();
				m += buildThroneStats();
			}
			m += buildBoosts();
		}
		m += '</DIV>';
		t.popReport.getMainDiv().innerHTML = m;
		if (ById('atkmightlost')) { ById('atkmightlost').innerHTML = tx('Might Lost')+': ' + addCommas(t.atkmight); }
		if (ById('defmightlost')) { ById('defmightlost').innerHTML = tx('Might Lost')+': ' + addCommas(t.defmight); }
		if (ById('ptDeleteReport')) {
			ById('ptDeleteReport').addEventListener('click', function () {
				deleteThisRpt(rslt, rpt);
			}, false);
		}
		t.popReport.getTopDiv().innerHTML = '<DIV align=center><B>'+rpt.marchName+' '+uW.g_js_strings.commonstr.report+'</B></DIV>';

		if (ById('reportTroopStatsHdr')) { ById('reportTroopStatsHdr').addEventListener('click', function () {	ToggleDivDisplay(false, 500, 500, "reportTroopStats"); }, false); }
		if (ById('reportChampDuelHdr')) { ById('reportChampDuelHdr').addEventListener('click', function () { ToggleDivDisplay(false, 500, 500, "reportChampDuel"); }, false); }
		if (ById('reportThroneHdr')) { ById('reportThroneHdr').addEventListener('click', function () { ToggleDivDisplay(false, 500, 500, "reportThrone"); }, false); }
		if (ById('reportBoostsHdr')) { ById('reportBoostsHdr').addEventListener('click', function () { ToggleDivDisplay(false, 500, 500, "reportBoosts"); }, false); }
		if (ById('reportResearchHdr')) { ById('reportResearchHdr').addEventListener('click', function () { ToggleDivDisplay(false, 500, 500, "reportResearch");	}, false); }

		t.popReport.show(true);
	},

	CloseReport : function () {
		var t = Rpt;
		if (t.popReport) {
			t.popReport.show(false);
			if (t.popReport.onClose) t.popReport.onClose();
			t.popReport.destroy();
			t.popReport = null;
		}
	},
};

var ChatTimeFix = {
	ChatTime: null,
	init: function () {
		t = ChatTimeFix;

		try {
			uWExportFunction('ptConvertTime', t.TimeFix);
			t.ChatTime = new CalterUwFunc("Chat.getChat", [
				['rslt.data.newChats[i][j][1],', 'ptConvertTime(rslt.data.newChats[i][j][1]),'],
				['rslt.data.newChats[i][j][1],', 'ptConvertTime(rslt.data.newChats[i][j][1]),']
			]);
			t.ChatTime.setEnable(Options.fixChatTime);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	TimeFix : function (timestr) {
		time = timestr.split(/:/);
		var AddMins = 480 - parseInt(getDST(new Date()) / 60) - (new Date().getTimezoneOffset()); // convert from local pacific time
		var min = (parseInt(time[0]) * 60) + parseInt(time[1]) + AddMins;
		if (min >= 1440) {
			min = min - 1440;
		}
		return parseInt(min / 60) + ':' + ('00' + parseInt(min % 60).toString()).slice(-2);
	},
	setEnable: function (tf) {
		var t = ChatTimeFix;
		t.ChatTime.setEnable(tf);
	},
	isAvailable: function () {
		var t = ChatTimeFix;
		return t.ChatTime.isAvailable();
	},
};

var AttackDialog = {
	hideAttackEffortsState : true,

	init: function () {
		var t = AttackDialog;
		t.hideAttackEffortsState = Options.hideAttackEfforts;
		try {
			t.modal_attackFunc = new CalterUwFunc('modal_attack', [
				[/}\s*$/, '; attackDialog_hook(); }']
			]);
			uWExportFunction('attackDialog_hook', t.modalAttackHook);
			t.modal_attackFunc.setEnable(true);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function () {},
	isAvailable: function () {
		var t = AttackDialog;
		return t.modal_attackFunc.isAvailable();
	},
	modalAttackHook: function () {
		var t = AttackDialog;
		if (Options.fixKnightSelect || Options.attackCityPicker) {
			for (var i = 1; i < 6; i++)
				ById('modal_attack_tab_' + i).addEventListener('click', t.e_changeMarchType, false);
		}
		if (Options.attackCityPicker) {
			setTimeout(t.initCityPicker, 0);
		}
		if (Options.DontFilterTransportTroops) {
			var sf = ById('modal_attack_supplyfilter_checkbox');
			if (sf) { if (sf.checked) { sf.click(); }}
		}

		var divContainer = ById('modal_attack_speed_boost');
		divContainer.appendChild(t.HideAttackEfforts());

	},
	HideAttackEfforts: function () {
		var t = AttackDialog;
		if (!ById('modal_attack_march_boost')) { return; }
		var span = document.createElement('span');
		var a = document.createElement('a');
		a.innerHTML = tx('Show Attack/Speed Boosts');
		a.id = 'ptShowBoosts';
		span.appendChild(a);
		if (t.hideAttackEffortsState) {
			hideshow();
		}
		a.addEventListener('click', function (evt) {
			t.hideAttackEffortsState = !t.hideAttackEffortsState;
			hideshow();
		}, false);
		for (var i = 1; i < 5; i++) {
			ById('modal_attack_tab_' + i).addEventListener('click', hideshow, false);
		}
		return span;

		function hideshow() {
			var a = ById('ptShowBoosts');
			if (t.hideAttackEffortsState) {
				disp = 'none';
				if (a) a.innerHTML = tx('Show Attack/Speed Boosts');
			}else{
				disp = 'block';
				if (a) a.innerHTML = tx('Hide Attack/Speed Boosts');
			}
			ById('modal_attack_march_boost').style.display = disp;
			ById('modal_attack_attack_boost').style.display = disp;
			ById('modal_attack_defense_boost').style.display = disp;
			var div = ById('modal_attack_speed_boost');
			for (var i = 0; i < i < div.childNodes.length; i++) {
				if (div.childNodes[i].className == 'section_title'){
					div.childNodes[i].style.display = disp;
				}
				if (div.childNodes[i].className == 'section_content') {
					div = div.childNodes[i];
					for (var i = 0; i < div.childNodes.length; i++) {
						if (div.childNodes[i].style != undefined && div.childNodes[i].className != 'estimated') {
							div.childNodes[i].style.display = disp;
						}
					}
					break;
				}
			}
		}
	},

	initCityPicker: function () {
		var t = AttackDialog;
		var div = ById('modal_attack_target_numflag'); // as of KofC version 96;
		var mySpan;
		if (div) {
			div.parentNode.innerHTML += ' &nbsp; <SPAN id=modal_attack_citybuts></span>';
		} else {
			var span = ById('modal_attack_target_coords'); // KofC version 116+;
			span.parentNode.parentNode.firstChild.innerHTML += ' &nbsp; <SPAN id=modal_attack_citybuts></span>';
		}
		var disabled = [];
	    for (var cid in Cities.byID){
			var x = Cities.byID[cid].idx;
			disabled[x] = (Cities.byID[uW.currentcityid].idx==x)?true: false;
		}
		new CdispCityPicker('ptatp', ById('modal_attack_citybuts'), false, t.e_CityButton,null,disabled);

		for (var i=0; i<Cities.numCities; i++) {
			ById('ptatp_'+i).addEventListener('mouseover',function (){CityResourceHint(this,this.id.substring(6));},false);
			ById('ptatp_'+i).addEventListener('mouseout',function (){CityResourceHintOff(this);},false);
		}

		if (ById('modal_attack_tab_4').className == 'selected' || ById('modal_attack_tab_3').className == 'selected') // don't do for attack or scout
			ById('modal_attack_citybuts').style.display = 'none';
	},
	e_CityButton: function (city) {
		ById('modal_attack_target_coords_x').value = city.x;
		ById('modal_attack_target_coords_y').value = city.y;
		uW.modal_attack_update_time();
	},
	e_changeMarchType: function (evt) {
		var t = AttackDialog;
		var marchType = parseInt(evt.target.id.substr(17));
		if (Options.attackCityPicker) {
			if (marchType == 3 || marchType == 4)
				ById('modal_attack_citybuts').style.display = 'none';
			else
				ById('modal_attack_citybuts').style.display = 'inline';
		}
		if (Options.fixKnightSelect) {
			var knightVal = 0;
			var selector = ById('modal_attack_knight');
			if (selector.length > 1 && (marchType == 4 || marchType == 2)) // if 'attack' or 'reinforce'
				knightVal = 1;
			selector.selectedIndex = knightVal;
			selector.disabled = false;
		}
		if (Options.DontFilterTransportTroops) {
			var sf = ById('modal_attack_supplyfilter_checkbox');
			if (sf) { if (sf.checked) { sf.click(); }}
		}
	},
};

var battleReports = {
	init: function () {
		var t = battleReports;
		try {
			t.getReportDisplayFunc = new CalterUwFunc('getReportDisplay', [
				['return K.join("")', 'var themsg=K.join(""); themsg=getReportDisplay_hook(themsg, arguments[1]); return themsg']
			]); //Alliance report battle rounds function
			uWExportFunction('getReportDisplay_hook', t.hook);
			t.getReportDisplayFunc.setEnable(true);

			t.renderBattleReportFunc = new CalterUwFunc('Messages.viewMarchReport', [
				[/\$\("modal_msg_list"\)\.innerHTML\s*=\s*cm\.MarchReportController\.getMarchReport\(c,\s*y\)/, 'var msg = cm.MarchReportController.getMarchReport(c, y); $("modal_msg_list").innerHTML = renderBattleReport_hook(msg,c,y);']
			]); //March reports battle rounds function
			uWExportFunction('renderBattleReport_hook', t.hook2);
			t.renderBattleReportFunc.setEnable(true);

			uWExportFunction('deleteAreport', t.e_deleteReport);
			uWExportFunction('PostReport', t.e_PostReport);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function () {},
	isRoundsAvailable: function () {
		var t = battleReports;
		return t.getReportDisplayFunc.isAvailable() || t.renderBattleReportFunc.isAvailable();
	},
	e_deleteReport: function (rptid) {
		var t = battleReports;
		t.ajaxDeleteMyReport(rptid);
	},
	e_PostReport: function (rptid) {
		var msg = 'Report No: ' + enFilter(rptid);
		sendChat("/a " + msg);
	},
	ajaxDeleteMyReport: function (rptid, isUnread, side, isCityReport, notify) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.s0rids = rptid;
		params.s1rids = '';
		params.cityrids = '';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/deleteCheckedReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					delete ReportCache[rptid];
					delete ReportDetailCache[rptid];
					if (isUnread) {
						uW.seed.newReportCount = parseInt(seed.newReportCount) - 1;
						uW.messages_notify_bug()
					}
				}
				if (notify) notify(rslt.errorMsg);
			},
		});
	},
	hook2: function (msg, args, rslt) {
		if (rslt.rnds && Options.dispBattleRounds) {
			msg = msg.replace(/<\/ul>.*\s*<\/div>.*\s*<div class="unitsContainer">/im, '<li><span class=\'label\'>Rounds: </span><span class=\'value\'>' + rslt.rnds + '</span></li></ul></div><div class="unitsContainer">');
		}
		if (Options.reportDeleteButton) {
			msg = msg.replace(/Reports<\/span><\/a>/im, 'Reports</span></a><a class=\'button20\' onclick=\'PostReport(' + args[0] + ',false)\'><span>Post To Chat</span></a>'); //Post to Chat button
			msg = msg.replace(/Reports<\/span><\/a>/im, 'Reports</span></a><a class=\'button20\' onclick=\'MoreReport(' + args[0] + ',' + args[1] + ',false)\'><span>More</span></a>'); //More button
			msg = msg.replace(/Reports<\/span><\/a>/im, 'Reports</span></a><a class=\'button20\' onclick=\'deleteAreport(' + args[0] + ',false)\'><span>' + uW.g_js_strings.commonstr.deletetx + '</span></a>'); //Delete button
		}
		return msg;
	},
	hook: function (msg, rslt) {
		msg = msg.replace(/(\bReport\sNo\:\s([0-9]+))/g, '<a onclick=\'ptChatReportClicked($2,0)\'>$1</a>');
		if (rslt.rnds && Options.dispBattleRounds) {
			msg = msg.replace(/(Attackers <span.*?)<\/div>/im, '$1<BR>Rounds: ' + rslt.rnds + '</div>');
		}
		return msg;
	},
};

var MapDistanceFix = {
	popSlotsFunc: null,
	init: function () {
		var t = MapDistanceFix;

		try {
			t.popSlotsFunc = new CalterUwFunc('MapObject.prototype.populateSlots', [
				['this.distance', 'fixMapDistance_hook']
			]);
			if (t.isAvailable()) {
				uWExportFunction('fixMapDistance_hook', t.fixMapDistance_hook);
				t.enable(true);
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	fixMapDistance_hook: function (cityX, cityY, tileX, tileY) {
		var city = Cities.byID[uW.currentcityid];
		return distance(city.x, city.y, tileX, tileY);
	},
	enable: function (tf) {
		var t = MapDistanceFix;
		t.popSlotsFunc.setEnable(tf);
	},
	isAvailable: function () {
		var t = MapDistanceFix;
		return t.popSlotsFunc.isAvailable();
	},
}

var mapinfoFix = {
	init: function () {
		var t = mapinfoFix;

		try {
			t.calcButtonInfo = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo', [
				[/case\s*"reassign":b\.text\s*=\s*g_js_strings\.commonstr\.reassign;b\.color\s*=\s*"blue";b\.action\s*=\s*function\s*\(\)\s*{modal_attack\(2,\s*e\.tile\.x,\s*e\.tile\.y\);*};d\.push\(b\);break;/,
					'case "reassign":b.text=g_js_strings.commonstr.reassign;b.color="blue";b.action=function(){modal_attack(5,e.tile.x,e.tile.y);};d.push(b);break;'
				]
			]);
			t.bookMarkMod = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo', [
				[/case\s*"bookmark":/, 'case "bookmark": try { if (e.city && cm.tileInfo[e.tile.id] && cm.tileInfo[e.tile.id].cityName ) {e.tile.name = e.user.username + "/" + cm.tileInfo[e.tile.id].cityName;}} catch (err1) {} ']
			]);
			t.MapContextMenus = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcCityType', [
				['return c', 'c = calcCityTypeFix(c,d);return c']
			]);
			t.calcButtonInfo.setEnable(Options.mapInfo);
			t.MapContextMenus.setEnable(Options.mapInfo2);
			t.bookMarkMod.setEnable(Options.mapInfo3);
			uW.cm.ContextMenuMapController.prototype.MapContextMenus.City["2"].splice(4, 0, "reassign");
			//	    add reinforcement of wilds
			for (var jj in uW.cm.ContextMenuMapController.prototype.MapContextMenus.AllianceWilderness) {
				uW.cm.ContextMenuMapController.prototype.MapContextMenus.AllianceWilderness[jj] = ["profile", "throne", "reinforce", "reinforcements", "message", "bookmark"];
			}
			uWExportFunction('calcCityTypeFix', t.calcCityType_hook);
			// add the province and the city status (Normal/Truce) to the tooltips
			if ((FFVersion.Browser == 'Chrome') || (parseIntNan(FFVersion.Version) > 16)) {
				t.dispStatusMod = new CalterUwFunc('MapObject.prototype.populateSlots', [
					[/var\s*h\s*=""/, 'var h = ""; h+="<div class=divHide>"+S.tileUserId+"</div><div class=thead align=center><b>"+provincenames["p" + S.tileProvinceId]+"</b></div>";if (K) h += "<div>"+g_js_strings.commonstr.status+": " + K + "</div>";']
				]);
			}
			else {
				t.dispStatusMod = new CalterUwFunc('MapObject.prototype.populateSlots', [
					['var h = "";', 'var h = ""; h+="<div class=divHide>"+S.tileUserId+"</div><div class=thead align=center><b>"+provincenames["p" + S.tileProvinceId]+"</b></div>";if (K) h += "<div>"+g_js_strings.commonstr.status+": " + K + "</div>";']
				]);
			}
			t.dispStatusMod.setEnable(Options.dispStatus);

			t.MapContextMenuAdd = new CalterUwFunc ('modal_maptile', [[/}\s*$/, ';setTimeout(function() { MapContextMenuAdd_hook(j,k,m,a,h,f,o,e); },0); }']]);
			uWExportFunction('MapContextMenuAdd_hook', t.MapContextMenu);
			t.MapContextMenuAdd.setEnable (Options.mapMenuInfo);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = mapinfoFix;
		t.calcButtonInfo.setEnable(tf);
	},
	setEnable2: function (tf) {
		var t = mapinfoFix;
		t.MapContextMenus.setEnable(tf);
	},
	setEnable3: function (tf) {
		var t = mapinfoFix;
		t.bookMarkMod.setEnable(tf);
	},
	setMenuEnable: function (tf) {
		var t = mapinfoFix;
		t.MapContextMenuAdd.setEnable(tf);
	},
	setEnableDispStatus: function (tf) {
		var t = mapinfoFix;
		t.dispStatusMod.setEnable(tf);
	},
	calcCityType_hook: function (c, d) {
		if (Cities.byID[d.city.id] && c != 1)
			c = uW.cm.CITY_STATUS.MY_CITY_AND_NOT_CURRENT_CITY;
		return c;
	},
	isAvailable: function () {
		var t = mapinfoFix;
		return t.calcButtonInfo.isAvailable();
	},
	isAvailable2: function () {
		var t = mapinfoFix;
		return t.MapContextMenus.isAvailable();
	},
	isAvailable3: function () {
		var t = mapinfoFix;
		return t.bookMarkMod.isAvailable();
	},
	isMenuAvailable: function () {
		var t = mapinfoFix;
		return t.MapContextMenuAdd.isAvailable();
	},
	isAvailableDispStatus: function () {
		var t = mapinfoFix;
		return t.dispStatusMod.isAvailable();
	},
	MapSelMarchPreset : function () {
		Options.OneClickAttackPreset = ById('ptMapOneClickAttackPreset').value;
		saveOptions();
	},
	MapContextMenu : function(uid,x,y,a,h,f,o,e) {
		var t = mapinfoFix;
		var div = ById('contextMenu');

		var MarchPresets = {0:"-- "+tx('Select March Preset')+" --"};
		for (var PN in Options.QuickMarchOptions.MarchPresets) {
			MarchPresets[PN] = Options.QuickMarchOptions.MarchPresets[PN][0];
		}
		var HQ = false;
		if (CM.FoundingModel) HQ = CM.FoundingModel.get_hq(x,y);
		var DefendStat = '';
		var citytile = ((e.indexOf("city") > -1 && uid!=null && uid!=0 && uid!="0") || e.indexOf("mist") > -1);
		if (citytile) { DefendStat = '<div style="margin-top:6px;" align=center id=ptDefendStatus>&nbsp;</div>';}

		if ((citytile || (uid!=null && uid!=0 && uid!="0")) && (!uid || uid!=uW.tvuid)) {
			var ascended = getAscensionValues(uW.currentcityid);
			if (ascended.isPrestigeCity) {
				var cityExpTime = ascended.prestigeBuffExpire;
				if (cityExpTime && cityExpTime > unixTime()) {
					var AP = document.createElement('div');
					AP.innerHTML = '<center><span class=boldRed><b>'+tx('ASCENSION')+'<br>'+tx('PROTECTION')+'<br>'+tx('WARNING')+'!</b></span></center>';
					div.insertBefore(AP,div.firstChild);
				}
			}
		}

		uWExportFunction('ptMapSelMarchPreset', t.MapSelMarchPreset);

		var QAPreset = '<div align=center>'+htmlSelector(MarchPresets, Options.OneClickAttackPreset, 'id=ptMapOneClickAttackPreset class=btInput onChange="ptMapSelMarchPreset();" onMouseMove="ptStopProp(event);" onMouseOut="ptStopProp(event);" onClick="ptStopProp(event);" onMouseUp="ptStopProp(event);"')+'</div>';

		var champ = false;
		if (Options.QuickMarchOptions.AutoChamp) {
			for (var c in Seed.champion.champions) {
				citychamp = Seed.champion.champions[c];
				if (citychamp.assignedCity == uW.currentcityid) {
					champ = true;
					var champstatus = citychamp.status;
					if (champstatus != "10") { QAPreset += '<div align=center style="font-size:10px;color:#080"><b>'+tx('Champion Ready')+'!</b></div>'; }
					else {QAPreset += '<div align=center style="font-size:10px;color:#800"><b>Champion Unavailable!</b></div>';}
					break;
				}
			}
			if (!champ) { QAPreset += '<div align=center style="font-size:10px;color:#800"><b>'+uW.g_js_strings.champ.no_champ+'!</b></div>'; }
		}
		if (Options.QuickMarchOptions.AutoSpell) {
			var faction = '';
			var spellavailable = false;
			var cooldownactive = false;
			if (Seed.cityData.city[uW.currentcityid].isPrestigeCity) {
				faction = parseInt(Seed.cityData.city[uW.currentcityid].prestigeInfo.prestigeType);
				spellavailable = (Seed.cityData.city[uW.currentcityid].prestigeInfo.blessings.indexOf(SpellBlessings[faction]) != -1)
				cooldownactive = (Seed.cityData.city[uW.currentcityid].spells && Seed.cityData.city[uW.currentcityid].spells[SpellTypes[faction]] && parseInt(Seed.cityData.city[uW.currentcityid].spells[SpellTypes[faction]].endDate) > uW.unixtime());
			}
			if (spellavailable) {
				if (!cooldownactive) {
					QAPreset += '<div align=center style="font-size:10px;"><span class=boldMagenta>'+eval('uW.g_js_strings.spells.name_'+SpellTypes[faction])+' '+tx('Ready')+'!</span></div>';
				}
				else {
					QAPreset += '<div align=center style="font-size:10px;"><span class=boldRed>'+eval('uW.g_js_strings.spells.name_'+SpellTypes[faction])+' '+tx('Regenerating')+'!</span></div>';
				}
			}
			else {
				QAPreset += '<div align=center style="font-size:10px;"><span class=boldRed>'+tx('No Spell Available')+'!</span></div>';
			}
		}

		if (uid!=null && uid!=0 && uid!="0") {
			var scr = document.createElement('div');
			if ((h!=0 && h == getMyAlliance()[0]) || uid == uW.tvuid || !Options.OneClickAttack || HQ) {
				var QAPreset = '';
			}
			scr.innerHTML = QAPreset+'<div align=center><b>'+tx('Loading')+'...</b></div>';
			div.appendChild(scr);
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.checkArr = uid;
			new MyAjaxRequest(uW.g_ajaxpath + "ajax/getOnline.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					var p = rslt.data;
					var params = uW.Object.clone(uW.g_ajaxparams);
					params.pid = uid;
					new MyAjaxRequest(uW.g_ajaxpath + "ajax/viewCourt.php" + uW.g_ajaxsuffix, {
						method: "post",
						parameters: params,
						onSuccess: function (rslt) {
							if (rslt.ok) {
								var u = unixTime();
								var f = convertTime(new Date(rslt.playerInfo.fogExpireTimestamp.replace(" ","T")+"Z"));
								var truce = "";
								if (rslt.playerInfo.warStatus != "1") {
									truce = " ("+Tabs.Monitor.getDuration(rslt.playerInfo.truceExpireTimestamp)+")";
								}

								var misted = (f >= u);
								m = '<TABLE width="100%" class=ptTab style="font-size:11px"><tr><td align="center"><div style="font-size:12px"><b>' + rslt.playerInfo.displayName +'</b></div></td></tr>';
								m += '<tr><TD align="center"><a id=btMapDetails>' + parseInt(rslt.playerInfo.userId)+'</a></td></tr>';
								var g=uW.g_js_strings.commonstr,h={1:g.normal,2:uW.g_js_strings.MapObject.begprotect,3:g.truce,4:g.vacation};
								m += '<tr><TD align="center"><B>' + h[rslt.playerInfo.warStatus]+truce+'</b></td></tr>';
								if (!p[uid])
									m+= '<tr><TD align="center">'+ t.getLastLogDuration(rslt.playerInfo.lastLogin) +'</td></tr>';
								else
									m+= '<tr><TD align="center"><span style="color:#f00;"><b>('+uW.g_js_strings.commonstr.online.toUpperCase()+')</b></span></td></tr>';
								if (misted)
									m += '<tr><TD align="center"><B>*** '+tx("MISTED")+' ***</b></td></tr>';

								scr.innerHTML = QAPreset+m + '</table>'+DefendStat;
								ById('btMapDetails').addEventListener('click', function(){ Battle.fetchPlayerInfo(rslt.playerInfo.userId,Battle.clickedPlayerDetails); },false);
								var MenuHeight = parseInt(div.offsetHeight);
								div.style.height = MenuHeight + 'px';
								div.style.overflow = 'visible';
								scr.style.height = '500px';
								scr.style.background = '';
								if (citytile) {getDefendStatus(x,y,ById('ptDefendStatus'),true);}
							}
						},
						});
					},
			});
		}
		else {
			if (HQ || !Options.OneClickAttack) {
				var QAPreset = '';
			}
			var scr = document.createElement('div');
			scr.innerHTML = QAPreset+DefendStat;
			div.appendChild(scr);
			var MenuHeight = parseInt(div.offsetHeight);
			div.style.height = MenuHeight + 'px';
			div.style.overflow = 'visible';
			scr.style.height = '500px';
			scr.style.background = '';
			if (citytile) {getDefendStatus(x,y,ById('ptDefendStatus'),true);}
		}
	},

	getLastLogDuration: function (datestr){
		if (!datestr) return;
		var Interval = convertTime(new Date(datestr.replace(" ","T")+"Z")) - unixTime();
		if (Interval < 0) return uW.timestr(Interval*(-1));
		else return tx('minutes ago');
	},

};

var GMTclock = {
	span: null,
	timer: null,
	init: function () {
		this.span = document.createElement('span');
		this.span.style.fontWeight = 'bold';
		ById('kochead_time').parentNode.appendChild(this.span);
		this.setEnable(Options.gmtClock);
	},
	setEnable: function (tf) {
		var t = GMTclock;
		if (tf) {
			setTimeout(function () {
				t.EverySecond();
			}, 1000);
		} else {
			t.span.innerHTML = '';
		}
	},
	EverySecond: function () {
		var t = GMTclock;
		var now = new Date();
		if (Options.gmtClockType == 1) {
			now.setTime(now.getTime() + (now.getTimezoneOffset() * 60000) - (480*60000) + parseInt(getDST(now)*1000) + (uW.g_timeoff*1000));
		}
		else {
			now.setTime(now.getTime() + (now.getTimezoneOffset() * 60000));
		}
		GMTclock.span.innerHTML = ' &nbsp; (' + formatGMTClock(now) + ')';
		if (Options.gmtClock) {
			setTimeout(function () {
				t.EverySecond();
			}, 1000);
		} else {
			GMTclock.span.innerHTML = '';
		}
	},
};

var koc2Mail = {
    init: function(){
        var html = '<IFRAME style="border:0;width:760px;max-width:760px;height:250px;max-height:250px;overflow:auto" src="//moshimo.eu/Koc_Dev/koc2mail/fb.html"></iframe>';
        var frame = document.createElement('div');
        frame.id='koc2mail_div';
        frame.style.position = 'relative';
        frame.style.width= "760px";
        frame.style.height = "250px";
        frame.style.background = '#FFFFE6';
        var kocFooter = ById('kocfoot');
		if (kocFooter) {
			kocFooter.parentNode.insertBefore(frame, kocFooter);
		}
		else {
			var kocMain = ById('kocmain');
			kocMain.parentNode.appendChild(frame);
		}
        ById('koc2mail_div').innerHTML = html;
    },
    towerToMail: function(msg){
        var content = '<BODY><HTML>' + msg + '</html></body>';
        var data = {};
        data.Subject ='Tower Alert ('+getServerId()+')';
        data.Message = content;
        koc2Mail.send(data);
    },
    msgToMail: function(send,messageBody){
        messageBody = messageBody.replace(/custom-line-break/g,"<BR>");
        var msg = '<BR>Date: ' + send.date;
        msg += '<BR>From: ' + send.sender,
        msg += '<BR>Subject: ' + send.subject;
        msg += '<BR><BR>' + messageBody;
        var content = '<BODY><HTML>' + msg + '</html></body>';
        var data = {};
        data.Subject ='Forwarded Message ('+getServerId()+')';
        data.Message = content;
        koc2Mail.send(data);
        ById('inbox_chk_'+send.id).checked = false;
    },
    customMail: function(from,subject,messageBody){
        messageBody = messageBody.replace(/custom-line-break/g,"<BR>");
        messageBody = messageBody.replace(/%0A/g,"<BR>");
        var msg = '<BR>From: ' + from;
        msg += '<BR><BR>' + messageBody;
        var content = '<BODY><HTML>' + msg + '</html></body>';
        var data = {};
        data.Subject =subject;
        data.Message = content;
        koc2Mail.send(data);
    },
    send: function(data){
		try {
			GM_xmlhttpRequest({
				method: 'POST',
				url: '//moshimo.eu/Koc_Dev/koc/mail.php',
				headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',},
				data: implodeUrlArgs(data),
				onload: function (response) {logit(response.toSource());},
			});
		} catch (e){ logerr(e);	}

    }
};

var DeleteReports = {
	deleting : false,
	pageNo : 1,
	maxpages : 10,
	scandelay : 30, // 30 secs between scans
	UIDArray : [],
	ReportLog : {
		ItemsFound                  : {},
		ThroneItemsFound			: {},
		ChampItemsFound				: {},
		JewelItemsFound				: {},
		ItemsFoundDF				: {},
		ThroneItemsFoundDF			: {},
		ChampItemsFoundDF			: {},
		JewelItemsFoundDF 			: {},
		DFCount : 0,
	},

	init : function(){
		var t = DeleteReports;
		t.loadLog();
        setTimeout(t.startdeletereports, 20*1000); // start in 20 seconds
    },

	loadLog : function () {
		var t = DeleteReports;
		var serverID = getServerId();
		s = GM_getValue ('ReportLog_'+serverID+'_'+uW.tvuid);
		if (s != null){
			opts = JSON2.parse (s);
			for (var k in opts)
				t.ReportLog[k] = opts[k];
		}
	},

	saveLog : function () {
		var t = DeleteReports;
		setTimeout(function () { GM_setValue ('ReportLog_'+getServerId()+'_'+uW.tvuid, JSON2.stringify(t.ReportLog));} ,0); // get around GM_SetValue uW error
	},

	startdeletereports : function(){
		var t = DeleteReports;
		if(!t.deleting) {
			if (Options.ReportOptions.DeleteRptbc || Options.ReportOptions.DeleteRpttr || Options.ReportOptions.DeleteRptwl || Options.ReportOptions.DeleteRptaa || Options.ReportOptions.DeleteRptfr || Options.ReportOptions.DeleteRptid || Options.ReportOptions.DeleteRptdf || Options.ReportOptions.DeleteRptsc){
				t.deleting = true;
				t.listreports(t.pageNo, t.checkreports);
			}
			else {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000);
			}
		};
	},

	listreports : function(pageNo, callback){
		var t = DeleteReports;
		t.pageNo = pageNo;

		if (!Options.ReportOptions.DeleteRptbc && !Options.ReportOptions.DeleteRpttr && !Options.ReportOptions.DeleteRptwl && !Options.ReportOptions.DeleteRptaa && !Options.ReportOptions.DeleteRptfr && !Options.ReportOptions.DeleteRptid && !Options.ReportOptions.DeleteRptdf && !Options.ReportOptions.DeleteRptsc){
			t.deleting = false;
			t.pageNo = 1;
			setTimeout(t.startdeletereports, t.scandelay*1000);
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		if (t.pageNo >= 1) params.pageNo = t.pageNo;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/listReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { callback(rslt); },
			onFailure: function () { callback({ok:false}); },
		});
	},
	checkreports : function(rslt){
		var t = DeleteReports;
		if(!rslt.ok || (rslt.arReports.length < 1)){ // no results or no reports
			t.deleting = false;
			t.pageNo = 1;
			setTimeout(t.startdeletereports, t.scandelay*1000);
			return;
		}
		var reports = rslt.arReports;
		var players = rslt.arPlayerNames;
		var totalPages = rslt.totalPages;
		if (rslt.totalPages > t.maxpages) var totalPages = t.maxpages;
		var deletes1 = new Array();
		var deletes0 = new Array();
		for(k in reports){
			if (reports[k].reportType == 0) {
				var reportUnixTime = Number(reports[k].reportUnixTime);
				if(Options.ReportOptions.DeleteRptbc){
					if((reports[k].marchType==4 || reports[k].marchType==9) && reports[k].side0PlayerId==0 && reports[k].side0TileType == 51) {
						if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
					}
					else if(reports[k].marchType==1 && isMyself(reports[k].side1PlayerId)) {
						if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
					}
				}
				if (Options.ReportOptions.DeleteRpttr){
					if(reports[k].marchType==1 && isMyself(reports[k].side0PlayerId)) {
						if (deletes0.indexOf(k.substr(2)) == -1) deletes0.push(k.substr(2));
					}
				}
				if (Options.ReportOptions.DeleteRptwl){
					if(reports[k].side0TileType <= 50 && reports[k].side0PlayerId==0) {
						if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
					}
				}
				if (Options.ReportOptions.DeleteRptdf){
					if(reports[k].side0TileType==54 && reports[k].side0PlayerId==0) {
						t.checkreportforitems(k.substr(2),false);
						if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
					}
				}
				if (Options.ReportOptions.DeleteRptaa && Options.AttackOptions && Options.AttackOptions.Routes){
					for(var i in Options.AttackOptions.Routes) {
						var a = Options.AttackOptions.Routes[i];
						if(reports[k].side0XCoord == a.target_x && reports[k].side0YCoord == a.target_y && reports[k].marchType==4 && isMyself(reports[k].side1PlayerId)) {
							if(reports[k].side0PlayerId!=0) { // don't delete deleted crests on other players
								t.checkreportforitems(k.substr(2),true);
							}
							else {
								t.checkreportforitems(k.substr(2),false);
								if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
							}
							break;
						}
					}
				}
				if (Options.ReportOptions.DeleteRptfr){
					for (var l in uW.seed.allianceDiplomacies.friendlyToThem) {
						if(reports[k].side1AllianceId == uW.seed.allianceDiplomacies.friendlyToThem[l].allianceId) {
							if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
						}
					}
					for (var l in uW.seed.allianceDiplomacies.friendly) {
						if(reports[k].side1AllianceId == uW.seed.allianceDiplomacies.friendly[l].allianceId) {
							if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
						}
					}
				}
				if (Options.ReportOptions.DeleteRptid){
					if (Options.ReportOptions.DeleteRptUID != "") {
						// split string by commas
						t.UIDArray = Options.ReportOptions.DeleteRptUID.split(",");
						if (t.UIDArray.indexOf(reports[k].side1PlayerId) != -1) {
							if (deletes1.indexOf(k.substr(2)) == -1) {
								if (Options.ReportOptions.DeleteRptidType==0 || Options.ReportOptions.DeleteRptidType==reports[k].marchType) {
									deletes1.push(k.substr(2));
								}
							}
						}
					}
				}
				if (Options.ReportOptions.DeleteRptsc){
					if(reports[k].marchType==3 && isMyself(reports[k].side0PlayerId)) {
						if (deletes1.indexOf(k.substr(2)) == -1) deletes1.push(k.substr(2));
					}
				}
			}
		}
		if(deletes1.length > 0 || deletes0.length > 0){
			t.deleteCheckedReports(deletes1, deletes0);
		} else {
			if (t.pageNo <= totalPages) {
				t.deleting = false;
				t.pageNo++;
				setTimeout(t.startdeletereports, 5*1000); // next page in 5 seconds
				return;
			}
			else {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000);
				return;
			}
		}
	},

	deleteCheckedReports : function(deletes1, deletes0){
		var t = DeleteReports;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.s1rids = deletes1.join(",");
		params.s0rids = deletes0.join(",");
		params.cityrids = '';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/deleteCheckedReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if(rslt.ok){
					if (deletes0.length>0) {
						for (var j=0;j<deletes0.length;j++) {
							delete ReportCache[deletes0[j]];
							delete ReportDetailCache[deletes0[j]];
						}
					}
					if (deletes1.length>0) {
						for (var j=0;j<deletes1.length;j++) {
							delete ReportCache[deletes1[j]];
							delete ReportDetailCache[deletes1[j]];
						}
					}
					Seed.newReportCount = parseInt(Seed.newReportCount) - parseInt(deletes1.length) - parseInt(deletes0.length);
					if (GlobalOptions.ExtendedDebugMode) actionLog('Deleted: ' +parseInt(deletes1.length + deletes0.length)+' reports','REPORTS');
					t.deleting = false;
					setTimeout(t.startdeletereports, 5*1000); // next page in 5 seconds
				}
				else {
					t.deleting = false;
					t.pageNo = 1;
					setTimeout(t.startdeletereports, t.scandelay*1000); // error - start again
				}
			},
			onFailure: function () {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000); // error - start again
			},
		});
	},

	checkreportforitems: function(rpId,deletewinner) {
		var t = DeleteReports;
		FetchReportDetail(rpId,1,function(rslt) {
			if (rslt.winner) {
				var darkforest = false;
				if (rslt.fght && rslt.fght.s0 && (rslt.fght.s0.m101 || rslt.fght.s0.m102 || rslt.fght.s0.m103 || rslt.fght.s0.m104 || rslt.fght.s0.m105 || rslt.fght.s0.m106 || rslt.fght.s0.m107 || rslt.fght.s0.m108 || rslt.fght.s0.m109 || rslt.fght.s0.m10))
					{
						darkforest = true;
						t.ReportLog.DFCount++;
					}
				if(rslt.loot[5]) {
					var loot = rslt.loot[5];
					if (matTypeof(loot) == 'object') {
						for (var z in loot) {
							if (darkforest) {
								if(t.ReportLog.ItemsFoundDF[z]) { t.ReportLog.ItemsFoundDF[z] += parseInt(loot[z]); }
								else { t.ReportLog.ItemsFoundDF[z] = parseInt(loot[z]);}
							} else {
								if(t.ReportLog.ItemsFound[z]) { t.ReportLog.ItemsFound[z] += parseInt(loot[z]); }
								else { t.ReportLog.ItemsFound[z] = parseInt(loot[z]); }
							}
						}
					}
				}
				if (rslt.throneRoomDrop) {
					var TR = rslt.throneRoomDrop;
					var z = ""+TR.type+TR.quality;
					if (darkforest) {
						if(t.ReportLog.ThroneItemsFoundDF[z]) { t.ReportLog.ThroneItemsFoundDF[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = TR.type;
							NewObj.quality = TR.quality;
							NewObj.amount = 1;
							t.ReportLog.ThroneItemsFoundDF[z] = NewObj;
						}
					} else {
						if(t.ReportLog.ThroneItemsFound[z]) { t.ReportLog.ThroneItemsFound[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = TR.type;
							NewObj.quality = TR.quality;
							NewObj.amount = 1;
							t.ReportLog.ThroneItemsFound[z] = NewObj;
						}
					}
				}
				if (rslt.equipmentDrop) {
					var EQ = rslt.equipmentDrop;
					var z = ""+EQ.subtype+EQ.rarity;
					if (darkforest) {
						if(t.ReportLog.ChampItemsFoundDF[z]) { t.ReportLog.ChampItemsFoundDF[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = EQ.subtype;
							NewObj.quality = EQ.rarity;
							NewObj.amount = 1;
							t.ReportLog.ChampItemsFoundDF[z] = NewObj;
						}
					} else {
						if(t.ReportLog.ChampItemsFound[z]) { t.ReportLog.ChampItemsFound[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = EQ.subtype;
							NewObj.quality = EQ.rarity;
							NewObj.amount = 1;
							t.ReportLog.ChampItemsFound[z] = NewObj;
						}
					}
				}
				if (rslt.lootJewel) {
					var item = rslt.lootJewel;
					if (matTypeof(item) == 'object') {
						var z = item.quality;
						if (darkforest) {
							if(t.ReportLog.JewelItemsFoundDF[z]) { t.ReportLog.JewelItemsFoundDF[z] += parseInt(item.quantity); }
							else { t.ReportLog.JewelItemsFoundDF[z] = parseInt(item.quantity);}
						} else {
							if(t.ReportLog.JewelItemsFound[z]) { t.ReportLog.JewelItemsFound[z] += parseInt(item.quantity); }
							else { t.ReportLog.JewelItemsFound[z] = parseInt(item.quantity); }
						}
					}
				}
				t.saveLog();
				if (deletewinner) {
					deleteCheckedReport(rpId);
				}
			};
		});
	},
}

var DispReport = {
	init: function () {
		var t = DispReport;

		try {
			t.modal_MessageButtons = new CalterUwFunc('modal_messages', [[/}\s*$/, ';setTimeout(function() { AddMsgButtons(); },0); }']]);
			uWExportFunction('AddMsgButtons', DispReport.AddMsgButtons);
			t.modal_MessageButtons.setEnable(Options.enhancedinbox);

			t.modal_InboxFunc = new CalterUwFunc ('modal_messages_listshow', [['msghtml.join("");', 'msghtml.join("");dispInbox_hook(rslt,boxType,msghtml);']]);
			uWExportFunction('dispInbox_hook', DispReport.ModalInboxHook);
			t.modal_InboxFunc.setEnable (true);

			t.modal_RptFunc = new CalterUwFunc('Messages.handleListReports', [['n.join("");', 'n.join("");dispRpt_hook(l,n);']]);
			uWExportFunction('dispRpt_hook', DispReport.ModalReportListHook);
			t.modal_RptFunc.setEnable(Options.enhancedinbox);

			uWExportFunction('makeReportLink', makeReportLink);
			uWExportFunction('makeReportPopup', makeReportPopup);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = DispReport;
		t.modal_InboxFunc.setEnable(tf);
	},
	isDispReportAvailable: function () {
		var t = DispReport;
		return t.modal_InboxFunc.isAvailable();
	},
	AddMsgButtons :function() {
		var t = DispReport;
		if (ById('modal_msg_links')) ById('modal_msg_links').style.top = '8px';
		msgBody = document.getElementsByClassName('messageDeletes');
		var div = msgBody[0];
		var a = document.createElement('a');
		a.className = 'inlineButton brown20';
		a.style.marginRight = '6px';
		a.innerHTML = '<span>'+tx('Delete Gift Report')+'</span>';
		a.addEventListener('click', function(){t.checkinbox(1);}, false);
		div.appendChild(a);
		if (uW.koc2Mail) {
			var b = document.createElement('a');
			b.className='inlineButton brown20';
			b.style.marginRight = '6px';
			b.innerHTML="<span>"+tx('Send to Email')+"&nbsp;<img style='vertical-align:text-top;' width=16 src='http://www.moshimo.eu/favicon.ico'></span>";
			b.addEventListener('click', function(){t.checkinbox(2);}, false);
			div.appendChild(b);
		}

		msgBody = document.getElementsByClassName('reportDeletes');
		var div = msgBody[0];
		var a = document.createElement('a');
		a.className = 'buttonDown20';
		a.innerHTML = '<span>'+tx('Delete Wild/Barb/Transport')+'</span>';
		a.style.float = 'left';
		a.addEventListener('click', t.checkreportlist, false);
		div.appendChild(a);
	},
	ModalInboxHook : function (rslt,boxType,msghtml){
		var t = DispReport;

		var div = ById('ptPageNavBar');
		if (div) div.style.marginLeft = '20px';

		// fix outbox buttons.... kabam bug!
		if (boxType == 'outbox') {
			uW.hideMessageTabs();
			jQuery(".messageDeletes").show();
		}
	},
	checkinbox: function (what) {
		var t = DispReport;
		var body = ById('tbl_messages');
		if (!body) return;
		var trs = body.getElementsByTagName('tr');
		var reports = [];
		for (var i = 0; i < trs.length; i++) {
			var tds = trs[i].getElementsByTagName('td');
			for (var j = 0; j < tds.length; j++) {
				if(tds[j].className == 'chkcol') var checkbox = tds[j];
				if(tds[j].className == 'dtcol') var date = tds[j];
				if(tds[j].className == 'nmcol') var sender = tds[j];
				if(tds[j].className == 'subjcol') var subject = tds[j];
			}
			reports.push({ checkbox: checkbox, date:date, sender: sender, subject: subject });
		}
		if (what==1) t.parseGiftReport(reports);
		if (what==2) t.parseMailReport(reports);
	},
	parseGiftReport: function (rpts) {
		var t = DispReport;
		for (var i = 0; i < rpts.length; i++) {
			var GiftMessage = false;
			for (var j in GiftText) {
				if (rpts[i].subject.innerHTML.indexOf(GiftText[j]) != -1) {
					GiftMessage = true;
					break;
				}
			}
			if(rpts[i].sender.innerHTML.indexOf('Kingdoms Of Camelot') >= 0 && GiftMessage){
				rpts[i].checkbox.firstChild.checked = true;
			}
		}
		uW.messages_action("delete", "tbl_messages");
	},
	parseMailReport : function(rpts){
		var t = DispReport;
		var send = [];
		var help = uW.getSelectedMessages("tbl_messages");
		var array = help.split(',');
		for (var a=0;a<array.length;a++)
			for(var i=0;i<rpts.length; i++) {
				var sender = rpts[i].sender.textContent || rpts[i].sender.innerText;
				var subject = rpts[i].subject.textContent || rpts[i].subject.innerText;
				var date = rpts[i].date.textContent || rpts[i].date.innerText;
				if (rpts[i].checkbox.innerHTML.indexOf(array[a]) >=0) send.push({id:array[a],date:date,sender:sender,subject:subject});
			}
            for (var i=0;i<send.length;i++) setTimeout(t.messageBody,(i*5000),send[i]);
	},
	messageBody: function(send){
		var t= DispReport;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf=0;
		params.requestType="GET_MESSAGE_FOR_ID";
		params.messageId = send.id;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt) {
					uW.koc2Mail.msgToMail(send,rslt.messageBody);
				}
			},
		}, false);
	},
	ModalReportListHook: function (rslt, msghtml) {
		var t = DispReport;
		// fix HQ buttons.... rockyou bug!
		jQuery(".hqMessageDeletes").hide();

		if (rslt.ok) {
			msgBody = ById('modal_msg_reports_tablediv');
			var mml = ById('modal_msg_list');
			if (mml != null) mml.style.minHeight = '400px';
			var trs = msgBody.getElementsByTagName('tr');
			for (var i = 0; i < trs.length; i++) {
				var tds = trs[i].getElementsByTagName('td');
				for (var j = 0; j < tds.length; j++) {
					if (tds[j].className == 'subjcol') {
						tds[j].style.width = '190px';
						var original = tds[j].innerHTML;
						original = original.replace("<div>", "");
						original = original.replace("</div>", "");
						var popup = original.replace(uW.g_js_strings.modal_messages_viewtrades.viewrpt, tx("Pop-up"));
						popup = popup.replace(uW.g_js_strings.commonstr.view, tx("Pop-up"));
						popup = popup.replace("Messages.viewMarchReport", "makeReportPopup");
						var makelink = original.replace(uW.g_js_strings.modal_messages_viewtrades.viewrpt, tx("Share"));
						makelink = makelink.replace(uW.g_js_strings.commonstr.view, tx("Share")+"&nbsp;&nbsp;<a href='https://apps.facebook.com/kocreportview/' target='_blank'><img title='"+tx('View your shared reports')+"' style='vertical-align:text-top;' width=16 src='http://www.facebook.com/favicon.ico'></a>");
						makelink = makelink.replace("Messages.viewMarchReport", "makeReportLink");
						original = original.replace(uW.g_js_strings.modal_messages_viewtrades.viewrpt, uW.g_js_strings.commonstr.view);
						var newContent = original + " | " + popup + " | " + makelink;
						tds[j].innerHTML = '<DIV style="width:180px;">' + newContent + '</div>';
					}
					if (tds[j].className == 'nmcol') {
						tds[j].style.width = '400px';
					}
				}
			}
		}
	},
	checkreportlist: function () {
		var t = DispReport;
		var body = ById('modal_msg_reports_tablediv');
		var trs = body.getElementsByTagName('tr');
		var reports = [];
		for (var i = 0; i < trs.length; i++) {
			var tds = trs[i].getElementsByTagName('td');
			for (var j = 0; j < tds.length; j++) {
				if (tds[j].className == 'chkcol') {
					var checkbox = tds[j];
				}
				if (tds[j].className == 'nmcol') {
					var type = tds[j];
				}
				if (tds[j].className == 'subjcol') {
					var view = tds[j];
				}
			}
			reports.push({
				checkbox: checkbox,
				type: type,
				view: view
			});
		}
		t.parseBarbReport(reports);
	},
	parseBarbReport: function (rpts) {
		var t = DispReport;
		if ((FFVersion.Browser != 'Chrome') && (parseIntNan(FFVersion.Version) <= 16)) { // regular expression fix for cometbird
			var regex = /Messages.viewMarchReport\(([^&]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([^&]+),([^&]+),([^&]+),([^&]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+)/;
		}
		else {
			var regex = /Messages.viewMarchReport\(([^"]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([^"]+),([^"]+),([^"]+),([^"]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+),([0-9]+)/;
		}
		for (var i = 0; i < rpts.length; i++) {
			var m = regex.exec(rpts[i].view.innerHTML);
			if (m) {
				if (m[6] == m[8] && m[7] == m[9]) { //Source and target id the same.
					// continue; //Infer transport to self
				} else if (m[5] != 0) {
					continue;
				}
				rpts[i].checkbox.firstChild.checked = true;
			}
		}
		uW.Messages.deleteCheckedReports();
	}
};

function makeReportLink(rptid, side, tiletype, tilelv, defid, defnm, defgen, atknm, atkgen, marchtype, xcoord, ycoord, timestamp, unread, atkxcoord, atkycoord, side0AllianceName, side1AllianceName, link) {
	var domain = getServerId();
	var params = uW.Object.clone(uW.g_ajaxparams);
	var Sversion = "";
	var tvuid = parseInt(uW.tvuid);
	params.rid = rptid;
	if (tiletype != 999) params.side = side;
	new AsyncAjaxRequest(uW.g_ajaxpath + "ajax/fetchReport.php" + uW.g_ajaxsuffix, {
		method: "post",
		parameters: params,
		onSuccess: function (transport) {
			var rslt = eval("(" + transport.responseText + ")");
			if (rslt.ok == false) {
				if (GlobalOptions.ExtendedDebugMode) actionLog('kabam is having issues with reports...','REPORTS');
				return;
			}
			if (!rslt.error) {
				if (typeof GM_getMetadata !== "undefined") Sversion = JSON.stringify(GM_getMetadata("version", true));
				if (typeof GM_info !== "undefined") Sversion = JSON.stringify(GM_info.script.version);
				var url = '//apps.facebook.com/kocreportview/putData.php?Sname=' + JSON.stringify(SourceName) + '&Sversion=' + Sversion + '&domain=' + domain + '&reportUnixTime=' + timestamp + '&tvuid=' + tvuid + '&side0Player=' + defnm + '&side1Player=' + atknm + '&marchType=' + marchtype + '&tileType=' + tiletype + '&report=' + JSON.stringify(rslt);
				window.open(url, '_blank');
			} else if (GlobalOptions.ExtendedDebugMode) actionLog('kabam is having issues with reports...','REPORTS');
		},
		onFailure: function () {
			if (GlobalOptions.ExtendedDebugMode) actionLog('kabam is having issues with reports...','REPORTS');
		},
	}, false);
}

function makeReportPopup(rptid, side, tiletype, tilelv, defid, defnm, defgen, atknm, atkgen, marchtype, xcoord, ycoord, timestamp, unread, atkxcoord, atkycoord, side0AllianceName, side1AllianceName, link) {
	Rpt.FindReport(rptid, 0);
};

var AllianceReports = {
	init: function () {
		t = AllianceReports;

		try {
			uWExportFunction('ListAR_hook',AllianceReports.myAllianceReports);
			t.listFunc = new CalterUwFunc('allianceReports', [
				['var params', 'ListAR_hook(pageNo);return;var params']
			]);
			t.listFunc.setEnable(Options.enhanceARpts);

			uWExportFunction('getReportDisplay_hook2', AllianceReports.getReportDisplayHook);
			uWExportFunction('getmembersInfo_hook', AllianceReports.getMembersInfoHook);
			uWExportFunction('FindReport', Rpt.FindReport);

			t.marvFunc = new CalterUwFunc('modal_alliance_report_view', [
				['getReportDisplay', 'getReportDisplay_hook2']
			]);
			t.marvFunc.setEnable(true);

			t.memListFunc = new CalterUwFunc('membersInfo', [
				['commonstr.might', 'commonstr.might + "</td><td class=colcities>" + g_js_strings.commonstr.cities + "</td><td class=collast>" + g_js_strings.membersInfo.lastonline'],
				['memberInfo[key].prestige\)', 'memberInfo[key].prestige)+ "</td>");memhtml.push("<td class=colcities>" + memberInfo[key].cities + "</td>");memhtml.push("<td class=collast>" + memberInfo[key].lastLogin']
			]);
			t.enable_viewmembers(Options.enhanceViewMembers);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	getReportDisplayHook: function (a, b) {
		var x = '';
		try {
			x = uW.getReportDisplay(a, b);
		} catch (e) {
			x = 'Error formatting report: ' + e.message;
		}
		return x;
	},
	enable_viewmembers: function (tf) {
		t = AllianceReports;
		t.memListFunc.setEnable(tf);
	},
	enable: function (tf) {},
	myAllianceReports: function (pageNum) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		if (pageNum)
			params.pageNo = pageNum;
		params.group = "a";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/listReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				displayReports(rslt.arReports, rslt.arPlayerNames, rslt.arAllianceNames, rslt.arCityNames, rslt.totalPages);
			},
		}, false);

		function displayReports(ar, playerNames, allianceNames, cityNames, totalPages) {
			var msg = "";
			var myAllianceId = getMyAlliance()[0];
			msg += "<STYLE>.msgviewtable tbody .myCol div {margin-left:5px; overflow:hidden; white-space:nowrap; color:#000}\
				.msgviewtable tbody .myHostile div {font-weight:600; color:#600}\
				.msgviewtable tbody .myGray div {color:#666}\
				.msgviewtable tbody .myRein div {color:#050}\
				.msgviewtable tbody .myWarn div {font-weight:600; color:#442200}\
				</style>";
			msg += "<div class='modal_msg_reports'>";
			var rptkeys = Object.keys(ar);
			if (ar && matTypeof(ar) != 'array') {
				msg += "<div id='modal_alliance_reports_tablediv' class='modal_msg_list'><table width=675 cellpadding='0' cellspacing='0' class='msgviewtable reportviewtable alliancetable'>";
				msg += "<thead><tr><td width=105>"+uW.g_js_strings.commonstr.date+"</td><td width=40>"+uW.g_js_strings.commonstr.type+"</td><td width=150>"+uW.g_js_strings.commonstr.attacker+"</td><td>"+uW.g_js_strings.commonstr.target+"</td><td>"+uW.g_js_strings.commonstr.view+"</td></tr></thead><tbody>";
				for (var i = 0; i < rptkeys.length; i++) {
					var rpt = ar[rptkeys[i]];
					var colClass = '"myCol"';
					rpt.marchType = parseInt(rpt.marchType);
					rpt.side0AllianceId = parseInt(rpt.side0AllianceId);
					var targetDiplomacy = getDiplomacy(rpt.side0AllianceId);
					if (rpt.marchType == 2) {
						colClass = '"myCol myRein"';
					} else if (rpt.side1AllianceId != myAllianceId) {
						colClass = '"myCol myHostile"';
					} else {
						if (parseInt(rpt.side0TileType) < 50) { // if wild
							if (parseInt(rpt.side0PlayerId) == 0)
								colClass = '"myCol myGray"';
							else
								colClass = '"myCol myWarn"';
						} else if (parseInt(rpt.side0PlayerId) == 0) { // barb
							colClass = '"myCol myGray"';
						} else {
							if (targetDiplomacy == uW.g_js_strings.commonstr.friendly)
								colClass = '"myCol myWarn"';
						}
					}
					msg += "<tr valign=top";
					if (i % 2 == 0)	msg +=" class=stripe";
					msg += "><TD class=" + colClass + "><div>"+uW.formatDateByUnixTime(rpt.reportUnixTime)+"<BR>Rpt&nbsp;<a onclick='FindReport(" + rpt.reportId + ",0);return false;'>#" + rpt.reportId + "</a>";
					msg += "</div></td><TD class=" + colClass + "><div>";
					if (rpt.marchType == 1)	msg += uW.g_js_strings.commonstr.transport;
					else if (rpt.marchType == 3) msg += uW.g_js_strings.commonstr.scout;
					else if (rpt.marchType == 2) msg += tx('Reinf');
					else msg += uW.g_js_strings.commonstr.attack;
					// attacker ...
					msg += "</div></td><TD class=" + colClass + "><div>";
					if (parseInt(rpt.side1PlayerId) != 0) msg += playerNames["p" + rpt.side1PlayerId];
					else msg += "?"+tx('Unknown')+"?";
					msg += " "+coordLink(rpt.side1XCoord, rpt.side1YCoord)+"<BR>";
					if (rpt.side1AllianceId != myAllianceId) { msg += allianceNames['a' + rpt.side1AllianceId]+" ("+getDiplomacy(rpt.side1AllianceId)+")"; }
					else { msg += "<BR>"; }
					msg += "</div></td>";
					// target ...
					msg += "<TD class=" + colClass + "><DIV>";
					var type = parseInt(rpt.side0TileType);
					if (type < 50) { // wild
						msg += capitalize(uW.g_mapObject.types[type]||"")+" "+uW.g_js_strings.commonstr.lvl+" "+rpt.side0TileLevel;
						if (parseInt(rpt.side0PlayerId) != 0) { // IF OWNED, show owner ...
							msg += " ["+playerNames["p" + rpt.side0PlayerId]+"] ";
						}
					}
					else {
						if (parseInt(rpt.side0PlayerId) == 0) { //  barb
							msg += uW.g_js_strings.commonstr.barbariancamp+" "+uW.g_js_strings.commonstr.lvl+" "+rpt.side0TileLevel;
						}
						else { // city
							msg += playerNames["p" + rpt.side0PlayerId]+" - "+cityNames['c' + rpt.side0CityId];
						}
					}
					msg += " "+coordLink(rpt.side0XCoord, rpt.side0YCoord);
					if (rpt.side0AllianceId != 0 && rpt.side0AllianceId != myAllianceId) {
						msg += "<BR>"+allianceNames['a' + rpt.side0AllianceId]+" ("+targetDiplomacy+")";
					}
					// 'view report' link ...
					if (rpt.marchType != 2) {
						msg += "</div></td><TD class=" + colClass + "><div><a onclick='modal_alliance_report_view("+rpt.reportId+",";
						if (parseInt(rpt.side1AllianceId) == parseInt(Seed.allianceDiplomacies.allianceId))	{ msg += '1'; }
						else { msg += '0'; }
						msg += ","+rpt.side0TileType+","+rpt.side0TileLevel+","+rpt.side0PlayerId+',"';
						if (parseInt(rpt.side0PlayerId) != 0) msg += escape(playerNames["p" + rpt.side0PlayerId]);
						else msg += uW.g_js_strings.commonstr.enemy;
						msg += '","';
						if (parseInt(rpt.side0PlayerId) != 0) msg += escape(playerNames["g" + rpt.side0PlayerId]);
						else msg += '0';
						msg += '","';
						if (parseInt(rpt.side1PlayerId) > 0) msg += escape(playerNames["p" + rpt.side1PlayerId]);
						msg += '","';
						if (parseInt(rpt.side1PlayerId) != 0) msg += escape(playerNames["g" + rpt.side1PlayerId]);
						msg += '",'+rpt.marchType+","+rpt.side0XCoord+","+rpt.side0YCoord+","+rpt.reportUnixTime+",";
						if (parseInt(rpt.reportStatus) == 2) msg += "1";
						else msg += "0";
						if (rpt.side1XCoord) { msg += ","+rpt.side1XCoord+","+rpt.side1YCoord; }
						else { msg += ",,"; }
						msg += ");return false;'>"+uW.g_js_strings.commonstr.view+"</a></div></td></tr>";
					} else {
						// reinforcement!!
						msg += "</div></td><TD class=" + colClass + "><div><a onclick='FindReport(\""+rpt.reportId+"\",0);return false;'>"+uW.g_js_strings.commonstr.view+"</a></div></td></tr>";
					}
				}
				msg += "</tbody></table></div>";
			}
			msg += "</div><div id='modal_report_list_pagination'></div>";
			ById('allianceContent').innerHTML = msg;
			if (pageNum) {
				uW.ctrlPagination("modal_report_list_pagination", totalPages, "allianceReports", pageNum)
			} else {
				uW.ctrlPagination("modal_report_list_pagination", totalPages, "allianceReports")
			}
		}
	},
};

var AllianceReportsCheck = {
	aRpt: {},

	init: function () {
		var t = AllianceReportsCheck;
		var b = GM_getValue('allianceRpt_'+getServerId()+'_'+uW.tvuid);
		if (b != null)
			t.aRpt = JSON2.parse(b);
		else {
			t.aRpt = {};
		}
		t.enable(Options.ReportOptions.EnhanceAR);
	},

	enable: function (tf) {
		var t = AllianceReportsCheck;
		if (Options.ReportOptions.EnhanceAR) {
			t.checkAllianceReport();
		}
		setTimeout(function () { t.enable(Options.ReportOptions.EnhanceAR); }, parseInt((Math.random() * 15 * 1000) + (Options.ReportOptions.alertinterval * 1000)));
	},

	checkAllianceReport: function () {
		var t = AllianceReportsCheck;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.group = "a";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/listReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				t.parseAReports(rslt.arReports, rslt.arPlayerNames, rslt.arAllianceNames, rslt.arCityNames, rslt.totalPages);
			},
		}, true);
	},
	parseAReports: function (ar, playerNames, allianceNames, cityNames, totalPages) {
		var t = AllianceReportsCheck;
		var myAllianceId = getMyAlliance()[0];
		var rptkeys = uW.Object.keys(ar);
		if (ar && matTypeof(ar) != 'array') {
			for (var i = 0; i < rptkeys.length; i++) {
				var rpt = ar[rptkeys[i]];
				if (rpt.side1AllianceId != myAllianceId && Options.ReportOptions.PostIncoming) {
					var ID = rpt.reportId;
					if (t.aRpt["a" + ID]) continue;
					if (rpt.marchType == 3) {atkType = tx('scouted');}
					else if (rpt.marchType == 4) {atkType = tx('attacked');}
					if (rpt.side0TileType > 50)	{target = tx("city");}
					else if (rpt.side0TileType <= 50) {target = tx("wild");}
					var allianceName = '';
					if (parseIntNan(rpt.side1AllianceId) != 0) {
						allianceName = ' of '+allianceNames["a"+rpt.side1AllianceId]+' ('+getDiplomacy(rpt.side1AllianceId)+')';
					}
					var date = uW.formatDateByUnixTime(rpt.reportUnixTime);
					var msg = ':::. | '+tx('Report No')+': ' + rpt.reportId + ' || ' + date + ' || ' + playerNames['p' + rpt.side0PlayerId] + '\'s ' + target + ' '+tx('at')+' ' + rpt.side0XCoord + ',' + rpt.side0YCoord + ' '+tx('has been')+' ' + atkType + ' '+tx('by')+' ' + playerNames["p" + rpt.side1PlayerId] + ' '+tx('at')+' ' + rpt.side1XCoord + ',' + rpt.side1YCoord + allianceName;
					t.fetchreport(ID, rpt, msg, playerNames, cityNames);
					t.addAllianceReport(rpt);
				}
				if (rpt.side1PlayerId == uW.tvuid && Options.ReportOptions.WhisperOutgoing) {
					var ID = rpt.reportId;
					if (t.aRpt["a" + ID]) continue;

					if ((rpt.marchType == 4) && Options.AttackOptions && Options.AttackOptions.Routes){
						var crest = false;
						for(var j in Options.AttackOptions.Routes) {
							var a = Options.AttackOptions.Routes[j];
							if(rpt.side0XCoord == a.target_x && rpt.side0YCoord == a.target_y) {
								crest = true;
								break;
							}
						}
						if (crest) {
							t.addAllianceReport(rpt); // no try again
							continue; // no whisper on crest targets
						}
					}
					if (rpt.marchType == 3) {atkType = tx('scouted');}
					else if (rpt.marchType == 4) {atkType = tx('attacked');}
					target = tileTypes[parseInt(rpt.side0TileType)];
					if (parseInt(rpt.side0PlayerId) == 0) {	var playerName = '';}
					else {	var playerName = playerNames['p' + rpt.side0PlayerId] + '\'s ';}
					var date = uW.formatDateByUnixTime(rpt.reportUnixTime);
					var msg = ':::. | '+tx('Report No')+': ' + rpt.reportId + ' || ' + date + ' || ' + playerName + target + ' '+tx('at')+' ' + rpt.side0XCoord + ',' + rpt.side0YCoord + ' '+tx('has been')+' ' + atkType + ' '+tx('by you');
					var automsg = sendChat("/" + Seed.player.name + ' ' + msg);
					t.addAllianceReport(rpt);
				}
			}
		}
	},
	addAllianceReport: function (rpt) {
		t = AllianceReportsCheck;
		var ID = rpt.reportId;
		t.aRpt["a" + ID] = rpt.reportUnixTime;
		var now = unixTime() - (5 * 24 * 60 * 60);
		for (var k in t.aRpt) {
			if (t.aRpt[k] < now)
				delete t.aRpt[k];
		}
		var string = JSON2.stringify(t.aRpt);
		setTimeout(function () { GM_setValue("allianceRpt_" + getServerId()+"_"+uW.tvuid, string); }, 0);
	},
	fetchreport: function (rpId, rpt, msg, playerNames, cityNames) {
		var t = AllianceReportsCheck;
		if (Options.ReportOptions.alertmtroops == 0) {
			if (Options.ReportOptions.WhisperAR) {
				var automsg = sendChat("/" + Seed.player.name + ' ' + msg);
				var WList = Options.ReportOptions.WhisperARList.split(',');
				for (var i = 0; i < WList.length; i++) {
					var WName = WList[i].trim();
					if (WName) BotChat.sendWhisper(msg,WName);
				}
			}
			else {
				var automsg = sendChat('/a ' + msg);
			}
		} else {
			FetchReport(rpId,function(rslt) {
				var troops = rslt.detail.fght.s1;
				var trooptot = 0;
				for (var i in troops) {
					trooptot += Number(troops[i][0]);
				}
				if (Options.ReportOptions.alertmtroops > trooptot) return;
				if (Options.ReportOptions.WhisperAR) {
					var automsg = sendChat("/" + Seed.player.name + ' ' + msg + ' || '+uW.g_js_strings.commonstr.troops+' ' + trooptot);
					var WList = Options.ReportOptions.WhisperARList.split(',');
					for (var i = 0; i < WList.length; i++) {
						var WName = WList[i].trim();
						if (WName) BotChat.sendWhisper(msg + ' || '+uW.g_js_strings.commonstr.troops+' ' + trooptot, WName);
					}
				}
				else {
					var automsg = sendChat('/a ' + msg + ' || '+uW.g_js_strings.commonstr.troops+' ' + trooptot);
				}
//				if (Options.ReportOptions.alertConfig.sound)
//					AudioAlert.sound(true);
			});
		}
	},
};

var towho = {
	mmFunc: null,
	init: function () {
		t = towho;

		try {
			t.mmFunc = new CalterUwFunc('cm.messageController.messageWide', [
				[/params\.subject\s*=\s*..".modal_msg_write_subj".\.val.../im, 'params.subject = cm.messageController.escape\(allianceall?"{"+g_js_strings.commonstr.alliance+"} "+document.getElementById(\'modal_msg_write_subj\').value:"{"+g_js_strings.commonstr.officers+"} "+document.getElementById(\'modal_msg_write_subj\').value\);'],
				[/\$\("#modal_msg_write_to/im, 'jQuery("#modal_msg_write_to']
			]);
			t.mmFunc.setEnable(true);
		}
		catch (err) {
			logerr(err); // write to log
		}
	}
}

var PageNavigator = {
	modalMessagesFunc: null,
	ctrlPaginationOld: null,
	loadPage_paginationOld: null,
	cpPager: null,
	init: function () {
		var t = PageNavigator;

		try {
			t.modalMessagesFunc = new CalterUwFunc('modal_messages', [
				[/pageNavigatorModel\s*=.*?;/i, 'var pager=new ptPagerHook(0,5);pageNavigatorModel=pager;'],
				[/pageNavigatorView\s*=.*?;/i, 'pageNavigatorView=pager;'],
				[/pageNavigatorController\s*=.*?;/i, 'pageNavigatorController=pager;']
			]);
			uWExportFunction('ptPagerHook', t.Cpager);
			t.ctrlPaginationOld = uW.ctrlPagination;
			t.loadPage_paginationOld = uW.loadPage_pagination;
			t.cpPager = new t.Cpager(0, 0);
			t.cpPager.oldStyle = true;
			t.enable(Options.fixPageNav);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	// called on 'back' ...
	loadPage_pagination: function (divId, currentPage, callbackFunction, totalPages) {
		var t = PageNavigator;
		var curPage = parseInt(currentPage);
		if (divId == t.cpPager.divId) // if 'old' style ...
			uW[callbackFunction](t.cpPager.getCurrentPage());
		else
			uW[callbackFunction](currentPage);
	},
	ctrlPagination: function (navDivId, numPages, notify, curPage) {
		var t = PageNavigator;
		if (ById(navDivId).firstChild == null)
			ById(navDivId).appendChild(t.cpPager.getHtmlElement());
		t.cpPager.setPageCount(numPages);
		t.cpPager.divId = navDivId;
		if (!curPage)
			curPage = 1;
		t.cpPager.gotoPage(curPage);
		t.cpPager.onClick = uW[notify];
		uW.pageNavigatorView = uWCloneInto(t.cpPager);
	},
	enable: function (tf) {
		var t = PageNavigator;
		t.modalMessagesFunc.setEnable(tf);
		if (tf) {
			uWExportFunction('ctrlPagination', t.ctrlPagination);
			uWExportFunction('loadPage_pagination', t.loadPage_pagination);
		} else {
			uWExportFunction('ctrlPagination', t.ctrlPaginationOld);
			uWExportFunction('loadPage_pagination', t.loadPage_paginationOld);
		}
	},
	isAvailable: function () {
		var t = PageNavigator;
		return t.modalMessagesFunc.isAvailable();
	},
	Cpager: function (a, b) {
		// public function protos ...
		this.getHtmlElement = getHtmlElement;
		this.setPageCount = setPageCount;
		this.getPageCount = getPageCount;
		this.getCurrentPage = getCurrentPage;
		this.gotoPage = gotoPage;
		this.e_but = e_but;
		this.e_inp = e_inp;
		//
		var t = this;
		this.onClick = null;
		this.numPages = b;
		this.curPage = a;
		this.oldStyle = false;

		function getHtmlElement() {
			function aButton(msg, evtPage) {
				return '<A class=ptPageNav onclick="pageNavigatorView.e_but(\'' + evtPage + '\')"><SPAN class=ptPageNav>' + msg + '</span></a>';
			}
			var div = document.createElement('div');
			div.id = 'ptPageNavBar';
			div.innerHTML = '<STYLE>table.ptPageNav tr td  {background:inherit; border:none; text-align:center; padding:0px 1px;}\
        span.ptPageNav {font-size:12px; background:inherit; line-height:135%}\
        A.ptPageNav {background-color:#44e; color:#ff4; display:block; border:1px solid #666666; height:18px; width:18px;}\
        A.ptPageNav:hover {background-color:#66f;}\
        A.ptPageNav:active {background-color:#186}\
        </style>\
        <TABLE class=ptPageNav><TR valign=middle>\
        <TD style="margin-right:15px">' + aButton('<SPAN style="padding-right:0.8em; letter-spacing:-0.99em;">&#x258f;&#x258f;&#x25c4;</span>', 'F') + '</td>\
        <TD>' + aButton('&#x25c4', '-') + '</td>\
        <TD>' + aButton('&#x25ba', '+') + '</td>\
        <TD style="margin-right:15px">' + aButton('<SPAN style="padding-right:1.05em; letter-spacing:-0.99em;">&#x25ba;&#x2595;&#x2595;</span>', 'L') + '</td>\
        <TD width=10>&nbsp;</td><TD>Page&nbsp;<INPUT id=ptPagerPageNum onChange="pageNavigatorView.e_inp()" type=text size=1>&nbsp;OF&nbsp;<span id=ptPagerNumPages>?</span></td>\
        </tr></table>';
			var mml = ById('modal_msg_list');
			if (mml != null)
				mml.style.minHeight = '400px';
			return div;
		}

		function getPageCount() { // koc needs for 'back'
			return t.numPages;
		}

		function getCurrentPage() { // koc needs for 'back'
			return t.curPage;
		}

		function setPageCount(c) {
			t.numPages = c;
			ById('ptPagerNumPages').innerHTML = c;
			var mml = ById('modal_msg_list');
			if (mml != null) {
				if (ById('modal_msg_tabs_report').className.indexOf('selected') >= 0)
					mml.style.minHeight = '460px';
				else
					mml.style.minHeight = '400px';
			}
		}

		function gotoPage(p) {
			t.curPage = parseIntZero(p);
			ById('ptPagerPageNum').value = t.curPage;
		}

		function e_but(p) {
			if (p == 'F' && t.curPage != 1)
				loadPage(1);
			else if (p == '-' && t.curPage > 1)
				loadPage(t.curPage - 1);
			else if (p == '+' && t.curPage < t.numPages)
				loadPage(t.curPage + 1);
			else if (p == 'L' && t.curPage != t.numPages)
				loadPage(t.numPages);

			function loadPage(p) {
				if (t.oldStyle)
					t.gotoPage(p);
				t.onClick(p);
			}
		}

		function e_inp(p) {
			var pageNum = parseIntZero(ById('ptPagerPageNum').value);
			t.onClick(pageNum);
		}
	},
};

var TowerAlerts = {
	viewImpendingFunc: null,
	generateIncomingFunc: null,
	fixTargetEnabled: false,
	init: function () {
		var t = TowerAlerts;

		try {
			t.viewImpendingFunc = new CalterUwFunc('attack_viewimpending_view', [
				[/Modal.showModal\((.*)\)/im, 'Modal.showModal\($1\); ptViewImpending_hook(a);']
			]);
			uWExportFunction('ptViewImpending_hook', t.viewImpending_hook);
			t.viewImpendingFunc.setEnable(true);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	// fix 'target'
	viewImpending_hook: function (atkinc) {
		var t = TowerAlerts;
		var div = ById('modal_attackimpending_view');
		var isFalse = false;
		if (t.fixTargetEnabled) {
			var city = Cities.byID[atkinc.toCityId];
			var target = '';
			if (!city || (atkinc.marchType != 3 && atkinc.marchType != 4)) {
				target = '<B>'+tx('FALSE REPORT')+'!</b>';
				isFalse = true;
			} else if (city.tileId == atkinc.toTileId) {
				target = city.name + ' (' + city.x + ',' + city.y + ')';
			} else {
				wilds = Seed.wilderness['city' + atkinc.toCityId];
				m = '';
				for (var k in wilds) {
					if (wilds[k].tileId == atkinc.toTileId) {
						m = 'at ' + wilds[k].xCoord + ',' + wilds[k].yCoord;
						break;
					}
				}
				target = city.name + ', <B>'+tx('WILD')+' ' + m + '</b>';
			}
			div.childNodes[0].innerHTML = '<B>'+tx('Target')+': </b>' + target;
		}
	},
	enableFixTarget: function (tf) {
		var t = TowerAlerts;
		t.fixTargetEnabled = tf;
	},
	isFixTargetAvailable: function () {
		var t = TowerAlerts;
		return t.viewImpendingFunc.isAvailable();
	},
}

var CoordBox = {
	init: function () {
		var t = CoordBox;
		t.boxDiv = searchDOM(ById('maparea_map'), 'node.className=="mod_coord"', 3, false);
		t.boxDiv.id = 'btCoordsBox';
		t.setEnable(Options.mapCoordsTop);
	},
	setEnable: function (tf) {
		var t = CoordBox;
		if (t.boxDiv == null)
			return;
		if (tf)
			t.boxDiv.style.zIndex = '100000';
		else
			t.boxDiv.style.zIndex = '10011';
	},
	isAvailable: function () {
		var t = CoordBox;
		return !(t.boxDiv == null);
	},
};

var cdtd = {
	views: null,
	update_citylist2: null,
	init: function () {
		var t = cdtd;

		try {
			if (typeof uW.watch == 'function') {
				uW.watch("update_citylist",function(c,a,b){return b;}); // palemoon 'unwatch' doesn't work
			}
			if (typeof uW.unwatch == 'function') {
				uW.unwatch("update_citylist"); // naughty kabam!
			}

			uWExportFunction('ptcheckascension', cdtd.checkascension);
			uWExportFunction('ptgetchampstatus', cdtd.getchampstatus);
			uWExportFunction('cdtdhook', cdtd.citychange);

			var z = new CalterUwFunc("showCityTooltip",[[/showTooltip/,'a += "<div>"+g_js_strings.guardian[seed.guardian[j].type+"_fullName"]+"</div><div>" + ptgetchampstatus(seed.cities[j][0])+"</div>";showTooltip'],
														['g_js_strings.showPopTooltip.currpop','provincenames[\'p\'+seed.cities[j][4]] + "</div><div>" + ptcheckascension(seed.cities[j][0]) + g_js_strings.showPopTooltip.currpop']]);
			z.setEnable(true);

			t.views = new CalterUwFunc("citysel_click", [
				[/cm\.PrestigeCityView\.render\(\)/im, 'cm.PrestigeCityView.render();cdtdhook();']
			]);

			if (Options.EnhCBtns) {
				t.views.setEnable(true);
				t.update_citylist2 = uW.update_citylist;
				uW.update_citylist = function () {
					cdtd.update_citylist2();
					cdtd.drawdefendstatus();
					if (Options.ColrCityBtns) cdtd.drawfactioncolors();
				};
				t.drawdefendstatus();
			};
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	citychange: function () {
		cdtd.drawdefendstatus();
		Tabs.Options.checkAscension(); // ascension expiry tied into enhanced city buttons
	},
	drawdefendstatus: function () {
		var t = cdtd;
		for (var i = 0; i < uW.seed.cities.length; i++) {
			var cityidx = i + 1;
			var city = ById('citysel_' + cityidx);
			if (!city) {
				setTimeout(t.drawdefendstatus, 100);
				return;
			}
			var cityId = uW.seed.cities[i][0];
			var color = 'blue';
			if (uW.seed.citystats['city'+cityId].gate != 0) { color = 'red'; }
			if (Tabs.PortalTime && Options.PortOptions.PortCity==cityId && Options.PortOptions.Running) { color = 'cyan'; }
			city.style.color = color;
			city.style.border = '2px inset '+color;
			city.style.display = 'inline';
			city.style.width = 10 + '%';
			if (Options.DbClkDefBtns && SelectiveDefending) {
				city.ondblclick = function () {
					t.setdefendstatus(this.name);
				};
			}
		}
	},
	setdefendstatus: function (city) {
		var t = cdtd;
		var state = 1;
		if (uW.seed.citystats["city" + city].gate != 0)
			state = 0;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = city;
		params.state = state;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/gate.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					uW.seed.citystats["city" + city].gate = state;
					t.drawdefendstatus();
				}
			},
			onFailure: function () {
				t.drawdefendstatus();
			},
		},true);
	},

	drawfactioncolors: function () {
		var t = cdtd;
		for (var i = 0; i < uW.seed.cities.length; i++) {
			color = "black";
			var ascended = getAscensionValues(uW.seed.cities[i][0]);
			if (ascended.isPrestigeCity) {
				switch (parseIntNan(ascended.prestigeType)) {
					case 1: color = "#228b22"; break;
					case 2: color = "#A944DB"; break;
					case 3:	color = "#E36600"; break;
				}
			}
			ById('mod_citylist').children[i].innerHTML = "<SPAN><FONT fontFamily='georgia,?arial,?sans-serif' font-weight=700 font-size=10px color=" + color + ">" + uW.roman[i] + "</font></span>";
		}
	},
	checkascension : function(id) {
		var str = ""
		var protection = CM.PrestigeCityPlayerProtectionController.isActive(id);
		if (protection) {
			str += "<b>"+tx('Ascension Protection')+": "+uW.timestr(CM.PrestigeCityPlayerProtectionController.getTimeLeft(id),false)+"</b></div><div>";
		}
		var ascended = getAscensionValues(id);
		var canAscend = true;
		if (ascended.isPrestigeCity) {
			var MaxLevel = CM.PrestigeModel.getLevelCapSoft(ascended.prestigeType);
			canAscend = (MaxLevel>parseIntNan(ascended.prestigeLevel));
		}
		if (Options.BuildOptions && Options.BuildOptions.AscendRunning) {
			if (protection && !canAscend) { str += '<span class=boldRed>'+tx("Maximum Ascension Level")+"!</span></div><div>"; }
			else if (Options.BuildOptions.AscendEnabled[Cities.byID[id].idx+1]) { str += '<span class=boldMagenta>'+tx("Auto-Ascend Enabled")+"!</span></div><div>"; }
		}
		return str;
	},
	getchampstatus : function(id) {
		var citychamp;
		var ChampText = uW.g_js_strings.champ.no_champ+"!";
		var gotchamp = false;
		for (var y in Seed.champion.champions) {
			citychamp = Seed.champion.champions[y];
			if (citychamp.assignedCity == id) {
				gotchamp = true;
				var champname = citychamp.name;
				var champstatus = citychamp.status;
				if (champstatus != "10") {
					ChampText = champname + ' ('+tx('Defending')+')';
				}
				else {
					ChampText = champname + ' ('+tx('Marching')+')';
				}
				break;
			}
		}
		if (gotchamp) {
			return '<table cellspacing=0><tr><td class="xtab"><img height=14 src="'+ChampImagePrefix+citychamp.avatarId+ChampImageSuffix+'"></td><td class=xtab>'+ChampText+'</td></tr></table>';
		}
		else {
			return '<table cellspacing=0><tr><td class="xtab">'+ChampText+'</td></tr></table>';
		}
	},
}

var LoadCapFix = {
	init: function () {
		var t = LoadCapFix;
		try {
			if ((FFVersion.Browser == 'Chrome') || (parseIntNan(FFVersion.Version) > 16)) {
				t.capLoadEffect = new CalterUwFunc('cm.MarchModal.updateTroopResource', [
					[/\$\("#modal/ig, 'jQuery("#modal'],
					[/if\(jQuery/i, 'loadBoost = Math.min(loadBoost,(cm.thronestats.boosts.Load.Max/100)+techLoadBoost); for(var sacIndex = 0; sacIndex < seed.queue_sacr["city" + currentcityid].length; sacIndex ++ ) if(seed.queue_sacr["city" + currentcityid][sacIndex]["unitType"] == untid) unit_number *= seed.queue_sacr["city" + currentcityid][sacIndex]["multiplier"][0]; if(jQuery'],
					[/var\s*resources/i, 'load=load-1;var resources']
				]);
			}
			else {
				t.capLoadEffect = new CalterUwFunc('cm.MarchModal.updateTroopResource', [
					[/\$\("#modal/ig, 'jQuery("#modal'],
					['if (jQuery', 'loadBoost = Math.min(loadBoost,(cm.thronestats.boosts.Load.Max/100)+techLoadBoost); for(var sacIndex = 0; sacIndex < seed.queue_sacr["city" + currentcityid].length; sacIndex ++ ) if(seed.queue_sacr["city" + currentcityid][sacIndex]["unitType"] == untid) unit_number *= seed.queue_sacr["city" + currentcityid][sacIndex]["multiplier"][0]; if(jQuery'],
					['var resources', 'load=load-1;var resources']
				]);
			}
			t.capLoadEffect.setEnable(Options.fixLoadCap);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = LoadCapFix;
		t.capLoadEffect.setEnable(tf);
	},
	isAvailable: function () {
		var t = LoadCapFix;
		return t.capLoadEffect.isAvailable();
	},
}

var TRAetherCostFix = {
	aethercostFix: null,
	init: function () {
		t = TRAetherCostFix;

		try {
			t.aethercostFix = new CalterUwFunc('cm.ThronePanelController.calcCost', [
				[/if\(k\(/im, 'if(cm.ThronePanelController.isLastLevel('],
				[/E\.stones\.use\s*=\s*E\.stones\.total/im, 'E.stones.use = B'],
				[/if\(E\.stones\.use\s*==/im, 'if(E.stones.use >='],
				[/E\.gems\.use\s*=\s*b\(E\.stones\.total\s*-\s*B\)/im, 'var xx = + (cm.WorldSettings.getSetting("TR_AETHERSTONE_CONVERSION_COST")), y; E.gems.use = Math.ceil((E.stones.total - B)/xx)'],
				[/E\.gems\.use\s*=\s*b\(z\[D]\.Stones\)/im, 'var xx = + (cm.WorldSettings.getSetting("TR_AETHERSTONE_CONVERSION_COST")), y; E.gems.use = Math.ceil((z[D].Stones)/xx)'],
			]);
			t.aethercostFix.setEnable(Options.fixTRAetherCost);
			if ((FFVersion.Browser != 'Chrome') && (parseIntNan(FFVersion.Version) <= 16)) {
				t.aethercostFixCB = new CalterUwFunc('cm.ThronePanelController.calcCost', [
					[/if\s*\(k\(/im, 'if(cm.ThronePanelController.isLastLevel('], //fix for cometbird
					[/if\s*\(E\.stones\.use\s*==/im, 'if(E.stones.use >=']
				]); //fix for cometbird
				t.aethercostFixCB.setEnable(Options.fixTRAetherCost);
			}
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = TRAetherCostFix;
		t.aethercostFix.setEnable(tf);
		if ((FFVersion.Browser != 'Chrome') && (parseIntNan(FFVersion.Version) <= 16)) {
			t.aethercostFixCB.setEnable(tf);
		}
	},
	isAvailable: function () {
		var t = TRAetherCostFix;
		if ((FFVersion.Browser == 'Chrome') || (parseIntNan(FFVersion.Version) > 16)) {
			return t.aethercostFix.isAvailable();
		}
		else {
			return (t.aethercostFix.isAvailable() && t.aethercostFixCB.isAvailable());
		}
	},
}
var mmbImageFix = {
	imageFix: null,
	init: function () {
		t = mmbImageFix;

		try {
			t.imageFix = new CalterUwFunc('cm.mww.mmb_share', [
				[/img\/items\/130/im, 'img/items/70/'],
				[/common_postToProfile\(\"85\"/im, 'template_data_85.img1=template_data_85.media[0].src; common_postToProfile(\"85\"']
			]);
			t.imageFix.setEnable(Options.fixMMBImage);
		}
		catch (err) {
			logerr(err); // write to log
		}
	},
	setEnable: function (tf) {
		var t = mmbImageFix;
		t.imageFix.setEnable(tf);
	},
	isAvailable: function () {
		var t = mmbImageFix;
		return t.imageFix.isAvailable();
	},
}

/****** Global march function ****/

var March = {
	tt 				: null,
	currentrequests	: 0,
	maxrequests		: 3,
	queue 			: [],
	waittime		: 0,

	addMarch : function (params, callback, forcemarch){
		var t = this;
		var opts = {params:params, callback:callback};
		if(t.currentrequests < t.maxrequests || forcemarch){
			t.sendMarch(opts.params, opts.callback);
		} else {
			t.queue.push(opts);
			actionLog(t.getMarchType(opts.params.type)+' added to march queue. Queue now contains '+ t.getQueueLength() +' marches.','MARCH');
		}
	},

	loop : function (){
		var t = this;
		if(t.currentrequests < t.maxrequests){
			var opts = t.queue.shift();
			if(opts) {
				t.sendMarch(opts.params, opts.callback);
				actionLog(t.getMarchType(opts.params.type)+' triggered from march queue. Queue now contains '+ t.getQueueLength() +' marches.','MARCH');
			}
		}
	},

	getMarchType : function (mt){
		switch (parseIntNan(mt)) {
			case 1: return 'Transport';
			case 2: return 'Reinforcement';
			case 3: return 'Scout';
			case 4: return 'Attack';
			case 5: return 'Reassign';
			default: return 'March';
		}
	},

	getQueueLength : function (){
		var t = this;
		return t.queue.length;
	},

	RallyPoint : function (cityId){
		var t = this;
		var ret = {};
		ret.level = t.getRallypointLevel(cityId);
		ret.maxSlots = t.getTotalSlots(cityId);
		ret.marching = t.getMarchSlots(cityId);
		ret.emptySlots = t.getEmptySlots(cityId);
		ret.maxSize = t.getMaxSize(cityId,''); // assume no items
		return ret;
	},

	getRallypointLevel : function (cityId){
		var t = this;
		cityId = "city"+cityId;
		rallypointlevel = 0;
		for (var o in Seed.buildings[cityId]){
			var buildingType = parseInt(Seed.buildings[cityId][o][0]);
			var buildingLevel = parseInt(Seed.buildings[cityId][o][1]);
			if (buildingType == 12) {
				rallypointlevel=parseInt(buildingLevel);
				break;
			}
		}
		return rallypointlevel;
	},

	getTotalSlots : function (cityId){
		var t = this;
		var ascended = getAscensionValues(cityId);
		var rallypointlevel = t.getRallypointLevel(cityId);
		var slots = rallypointlevel; //Set default number of slots to rallypointlevel
		if(slots >= 12)slots = 11;// a level 12 and 13 rallypoint only allows for 11 marches.
		if(ascended.isPrestigeCity){
			slots +=3;
		}
		return slots;
	},

	getMarchSlots : function (cityId){
		var t = this;
		cityId = "city"+cityId;
		var slots=0;
		var now = unixTime();
		if (Seed.queue_atkp[cityId] != undefined){
			for(var k in Seed.queue_atkp[cityId]){
				var m = Seed.queue_atkp[cityId][k];
				if(m.marchType == 9) {
					if(m.botMarchStatus < 3 || m.botMarchStatus > 9)slots++; //If raid is stopped take it as empty slot
				} else {
					if (m.returnUnixTime > now){
						slots++;
					}
				}
			}
			if(Seed.queue_atkp[cityId].toSource() == "[]")
				slots = 0;
		} else {
			slots=0;
		}
		return slots;
	},

	getEmptySlots : function (cityId){
		var t = this;
		var slots = t.getTotalSlots(cityId);
		slots -= t.getMarchSlots(cityId);
		if(slots < 0) slots = 0;
		return slots;
	},

	getMaxSize : function (cityId,items){
		var t = this;
		var rallypointlevel = getUniqueCityBuilding(cityId, 12).maxLevel;
		var ascended = getAscensionValues(cityId);
		var buff = 1;
		var max = 0;
		var now = unixTime();

		var Conquest = false;
		var Command = false;
		var koth = false;
		var iused = null;
		if (items) { iused = items.split(","); }
		if (iused) {
			for (var i = 0; i < iused.length; i++) {
				if (iused[i] == 931) { Command = true; }
				if (iused[i] == 932) { Conquest = true; }
			}
		}

		if (Conquest) { buff = 1.5; }
		else { if (Command) { buff = 1.25; }};

		// timed auras take priority

		if (Seed.playerEffects.auras2Expire && Seed.playerEffects.auras2Expire > now) { buff = 1.3 }
		else {
			if (Seed.playerEffects.aurasExpire && Seed.playerEffects.aurasExpire > now) { buff = 1.15 }
		}

		var tr = Math.floor(equippedthronestats(66));
		if (tr > CM.thronestats.boosts.MarchSize.Max) { tr=CM.thronestats.boosts.MarchSize.Max; }
		if (tr > 0) { buff *= (1 + tr / 100); }

		if(ascended.isPrestigeCity){
			var b = ascended.prestigeLevel;
			var r = CM.WorldSettings.getSetting("ASCENSION_RALLYPOINT_BOOST"),
				m = JSON.parse(r),
				u = m.values[b - 1][1],
				k = parseFloat(u);
			buff *= k
			if(uW.seed.cityData.city[cityId].prestigeInfo.blessings.indexOf(207) != -1)buff *= 1.1;
		}
		if (koth) max=1;
		switch(rallypointlevel){
			case 11:
				max = 150000 * buff;
				break;
			case 12:
				max = 200000 * buff;
				break;
			case 13:
				max = 215000 * buff;
				break;
			default:
				max = (rallypointlevel * 10000) * buff;
				break;
		}
		return Math.floor(max+0.0001);
	},

	getMarchTime : function (cityId,unit_types,distance,spell_type,red_wings_used,green_wings_used) {
		var speed = 99999;
		var speedfriend = 99999;
		for (var ui in unit_types) {
			i = unit_types[ui];
			var troop_speed = parseInt(uW.unitstats["unt" + i][3]);
			troop_speed *= (1 + 0.1 * parseInt(Seed.tech.tch11));
			for (var sacIndex = 0; sacIndex < Seed.queue_sacr["city" + cityId].length; sacIndex++) {
				if (Seed.queue_sacr["city" + cityId][sacIndex]["unitType"] == i) {
					troop_speed *= Seed.queue_sacr["city" + cityId][sacIndex]["multiplier"][0]
				}
			}
			if (spell_type=='31' && uW.cm.attack_modal.isUnitSiege(i)) { troop_speed *= 2; }
			if (uW.cm.unitHorsedBenefit[i]) { troop_speed = troop_speed * (1 + 0.05 * parseInt(Seed.tech.tch12)); }
			else {
				troop_speed *= (1 + 0.05 * (parseInt(Seed.tech2.tch1) || 0));
				troop_speed *= uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().BLOOD_LUST, cityId, { speed : true	});
			}
			if (troop_speed < speed) { speed = troop_speed; }
		}

		speedfriend = speed;
		speedfriend *= 1 + (getUniqueCityBuilding (cityId, 18).maxLevel/2);

		speed *= uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().FILL_THE_RANKS, cityId, { marchspeed : true });
		speedfriend *= uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().FILL_THE_RANKS, cityId, { marchspeed : true });
		speed *= uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().REDUCE_FATIGUE, cityId, {});
		speedfriend *= uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().REDUCE_FATIGUE, cityId, {});
		trMarchAllSpeed = uW.cm.ThroneController.getBoundedEffect(67);
		trAttackSpeed = uW.cm.ThroneController.getBoundedEffect(68);
		trReinforceSpeed = uW.cm.ThroneController.getBoundedEffect(69);
		trTransportSpeed = uW.cm.ThroneController.getBoundedEffect(70);
		trReassignSpeed = uW.cm.ThroneController.getBoundedEffect(71);
		trScoutSpeed = uW.cm.ThroneController.getBoundedEffect(72);
		var throneBoost = trMarchAllSpeed + trAttackSpeed;
		var throneBoostFriend = trMarchAllSpeed + Math.min(trReinforceSpeed,trTransportSpeed);
		speed = speed * (1 + (throneBoost * 0.01))
		speedfriend = speedfriend * (1 + (throneBoostFriend * 0.01))
		var gi = uW.cm.guardianModalModel.getMarchBonus();
		var multiplier = 1 + (gi * 0.01);
		speed = speed * multiplier
		speedfriend = speedfriend * multiplier
		if (0 == speed || 0 == distance) {
			return {friend:0,foe:0,speedfriend:speedfriend,speed:speed};
		}
		var time = 0;
		var timefriend = 0;
		if (speed > 0) { time = Math.ceil(parseFloat(distance) * 6000 / speed); }
		if (speedfriend > 0) { timefriend = Math.ceil(parseFloat(distance) * 6000 / speedfriend); }

		var wings_used = red_wings_used || green_wings_used;
		var delay = uW.cm.WorldSettings.isOn("MARCH_SINGLE_TRIP_DELAY") ? parseInt(uW.g_marchSingleTripDelay) : 0;
		time += delay;
		timefriend += delay;

		if (red_wings_used) {
			time = parseInt(time * 0.5);
			timefriend = parseInt(timefriend * 0.5);
		} else {
			if (green_wings_used) {
				time = parseInt(time * 0.75);
				timefriend = parseInt(timefriend * 0.75);
			}
		}

		if (Seed.playerEffects.returnExpire > uW.unixtime()) {
			time = parseInt(time * 0.75);
			timefriend = parseInt(timefriend * 0.75);
		}
		if (spell_type=='11') {
			time *= 0.01;
			timefriend *= 0.01;
		}

		time = Math.ceil(time < 30 ? 30 : time);
		timefriend = Math.ceil(timefriend < 30 ? 30 : timefriend);
		return {friend:timefriend,foe:time,speedfriend:speedfriend,speed:speed};
	},

	sendMarch : function (params, callback){
		var t = this;

		if(March.waittime > uW.unixtime()){
			actionLog('Marches suspended to deal with march Captcha','MARCH');
			if (callback) callback({msg:"Marches suspended to deal with march Captcha"});
			return;
		};
		//check we have a knight on all attacks! REMOVED BECAUSE OF MEGALITHS!
//		if(params.type==4 && (!params.kid || params.kid==0)) {
//			actionLog(Cities.byID[params.cid].name+': Attempted to send attack without knight','MARCH');
//			if (callback) callback({msg:"You must send a knight on an attack"});
//			return;
//		}
		//need to check that march is not oversized!
		var maxsize = March.getMaxSize(params.cid, params.items);
		var x = 0;
		for (var ui in CM.UNIT_TYPES) {
			var i = CM.UNIT_TYPES[ui];
			var y = eval('params.u'+i);
			if (matTypeof(y)== 'number') { x+=y; }
		}
		if(maxsize < x) {
			actionLog(Cities.byID[params.cid].name+': Attempted to send march size '+x+' - max allowed is '+maxsize,'MARCH');
			if (callback) callback({msg:"Maximum Troops Exceeded"});
			return;
		}
		t.currentrequests++;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/march.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				--t.currentrequests;
				if (t.currentrequests<0) t.currentrequests=0;
				setTimeout(March.loop, 3000); //Always check for the next queued march 3 seconds after a request
				CM.MarchModal.setBackedOff(false);
				if (rslt.ok) {
					if (rslt.bsEndDate) {
						Seed.cityData.city[params.cid].spells = {};
						Seed.cityData.city[params.cid].spells[params.bs] = {endDate : rslt.bsEndDate};
					}
					if (params.champid && params.champid != 0) {
						var championidx = "";
						for (var i = 0; i < Seed.champion.champions.length; i++) {
							if (Seed.champion.champions[i].championId == params.champid) championidx = i;
						}
						// update seed immediately
						Seed.champion.champions[championidx].status = "10";
					}
					var timediff = parseInt(rslt.eta) - parseInt(rslt.initTS);
					var rtimediff = parseInt(rslt.returnTS) - parseInt(rslt.initTS);
					var ut = uW.unixtime();
					var unitsarr = {};
					for (var ui in CM.UNIT_TYPES){
						i = CM.UNIT_TYPES[ui];
						if (params["u" + i])
							unitsarr[i] = params["u" + i];
						else
							unitsarr[i] = 0;
					}
					var resources = new Array();
					resources[0] = params.gold;
					for (var i = 1; i <= 5; i++) {
						resources[i] = params["r" + i];
					}
					uW.attach_addoutgoingmarch(rslt.marchId, rslt.marchUnixTime, ut + timediff, params.xcoord, params.ycoord, unitsarr, params.type, params.kid, resources, rslt.tileId, rslt.tileType, rslt.tileLevel, params.cid, true, ut + rtimediff);
					if (params.items && params.items != "") {
						var iused = params.items.split(",");
						for (var i = 0; i < iused.length; i++) {
							Seed.items["i" + iused[i]] = parseInt(Seed.items["i" + iused[i]]) - 1;
							uW.ksoItems[iused[i]].subtract();
						}
					}
					uW.updateBoosts(rslt);
					if (rslt.liftFog) {
						Seed.playerEffects.fogExpire = 0;
						uW.g_mapObject.getMoreSlots();
						uW.update_boosts();
					}

					if (callback) { callback(rslt); }
				} else {
					if (rslt.user_action) {
						actionLog('March Error: Server Response - '+rslt.user_action,'MARCH');
						if (rslt.user_action == "backOffWaitTime") {
							CM.MarchModal.setBackedOff(true);
							if (rslt.tt) { params.tt = rslt.tt; }
							var wait = 2;
							if (rslt.wait_time) { wait = rslt.wait_time; }
							setTimeout ( function() {t.sendMarch(params,callback);}, wait*1000); // retry march after wait time
							return;
						}
						if (rslt.user_action == "marchWarning" || rslt.user_action == "marchCaptcha") { // send captcha through here now (no more captcha - it doesn't work anyway)
							March.waittime = Number(uW.unixtime()+120); // suspend marches for 2 mins
							rslt.msg = uW.g_js_strings.modal_attack.useractionwarningmessage;
						}
					}

					var msg = '';
					var g = Number(rslt.error_code);
					switch (g) {
						case 0: msg = tx("Unexpected Error"); break; // unexpected error
						case 8:	msg = tx("Excess Traffic"); CM.GATracker("Error", "Excess traffic. ("+g+")", uW.g_server); break;
						case 3: msg = tx("Game out of Sync"); break; //game out of sync
						case 4: msg = tx("You have insufficient units"); break; //not enough units
						case 104: msg = uW.g_js_strings.errorcode.err_104; break; //unable to attack target
						case 208: msg = uW.g_js_strings.errorcode.err_208; break; // beginner protection
						case 210: msg = uW.g_js_strings.errorcode.err_210; break; // Max marches
						case 212:
							if (Seed.knights['city'+params.cid]['knt'+params.kid])
								Seed.knights['city'+params.cid]['knt'+params.kid].knightStatus = 10; //remove knight from list, set to 1 to make available again.
							msg = uW.g_js_strings.errorcode.err_212; break;
						case 213:
							if (Seed.knights['city'+params.cid]['knt'+params.kid])
								Seed.knights['city'+params.cid]['knt'+params.kid].knightStatus = 10; //remove knight from list, set to 1 to make available again.
							msg = uW.g_js_strings.errorcode.err_213; break;
						default:
							CM.GATracker("Error", "Something has gone wrong. ("+g+")", uW.g_server); break;
							msg = eval("uW.g_js_strings.errorcode.err_"+g); break;
					}
					if (typeof rslt.cooldownTime !== "undefined") {
						rslt.msg = uW.g_js_strings.koth.timeRemaining.replace("%1$s", uW.timestr(rslt.cooldownTime));
					}
					if (!rslt.msg) { rslt.msg = msg; }
					if (callback) { callback(rslt); } //return all server excess traffic error to original function to handle
					return;
				}
			},
			onFailure: function () {
				--t.currentrequests;
				if (t.currentrequests<0) t.currentrequests=0;
				setTimeout(March.loop, 3000); //Always check for the next queued march 3 seconds after a request
				if(callback) { callback({msg:"AJAX Error"}); }
			}
		});
	},
};

var ItemMultiUseController = {
	city_holder : 0,
	max : 1,
	init : function () {
		var t = ItemMultiUseController;
		//Hack for ItemController
		t.ItemController = new CalterUwFunc("cm.MultiBuyUse.getNumberUsed", [[/(.|\n)*/i,'function (e) {return ItemController_hook();}']]);
		uWExportFunction('ItemController_hook', ItemMultiUseController.e_total);
	},
	UseItems : function (iid,num,cid) {
		var t = ItemMultiUseController;
		t.max = num;
		t.ItemController.setEnable(true); //Set to use current value specified
		if(cid){ //Set to use city specified
			t.city_holder = uW.currentcityid;
			uW.currentcityid = cid;
		}
		CM.ItemController.use(iid);
		if(cid){ //Set currentcity to old value
			uW.currentcityid = t.city_holder;
		}
		t.ItemController.setEnable(false); //Switch off value fixed
	},
	e_total : function () {
		var t = ItemMultiUseController;
		return t.max;
	},
}

/***************************************************************************************/
/************************************ TABS *********************************************/
/***************************************************************************************/

/*********************************** Notes Tab ***********************************/

Tabs.Notes = {
	tabOrder: 1070,
	tabLabel: 'Notes',
	myDiv: null,
	noteValues: {},
	ToolsOpen: false,

	init: function (div) {
		var t = Tabs.Notes;
		myDiv = div;
		uWExportFunction("removeNote", Tabs.Notes.removeNote);
		uWExportFunction("editNoteLink", Tabs.Notes.editNoteLink);

		// override the map tooltips
		var oldSMTT = uW.showMapTileTooltip;
		var newSMTT = function (j, h, n, f, l, k) {
			// add our stuff to the tooltip
			var j2 = Tabs.Notes.updateTooltip(unescape(j));
			if (j2) {
				j = escape(j2);
			}
			oldSMTT(j, h, n, f, l, k);
		};

		if (typeof exportFunction == 'function') { exportFunction(newSMTT,uW, {defineAs:"showMapTileTooltip"}); }
		else { uW.showMapTileTooltip = newSMTT; }

		// create a regular expression object to use
		Tabs.Notes.re = new RegExp("class=divHide>(\\w*)");

		// add a new option to the context menus
		var cityType = CM.CITY_STATUS.ANOTHER_PLAYER_CITY_AND_NOT_IN_YOUR_ALLIANCE;
		uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[cityType].push("ttMod");
		cityType = CM.CITY_STATUS.ANOTHER_PLAYER_CITY_AND_IN_YOUR_ALLIANCE;
		uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[cityType].push("ttMod");
		var wildContext;
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.EnemyWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("ttMod");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.Wilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("ttMod");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.FriendlyWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("ttMod");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.AllianceWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("ttMod");
		}
		// add actions to the menu item
		var mod = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo', [
			['default:', 'case "ttMod":' +
				'  b.text = "'+tx('Player Notes')+'"; b.color = "brown"; ' +
				'  b.action = function () { ' +
				'    edit_notes(e.user); ' +
				'  }; ' +
				'  if (e.user.id) d.push(b); break; ' +
				' default: '
			]
		]);
		mod.setEnable(true);
		// callback function for the context menu option
		uWExportFunction("edit_notes", Tabs.Notes.createPopup);

		// load saved values
		Tabs.Notes.load();
		window.addEventListener('unload', t.onUnload, false);
	},

	onUnload : function (){
		var t = Tabs.Notes;
		if (uW.btLoaded) {
			if (!ResetAll) t.save();
		}
	},

	load: function () {
		var serverID = getServerId();
		try {
			var s = JSON2.parse(GM_getValue('PlayerNotes_' + serverID+'_'+uW.tvuid,'{}'));
			if (s) Tabs.Notes.noteValues = s;
		} catch (e) {
			logerr(e);
		}
	},

	save: function () {
		var serverID = getServerId();
		var s = JSON2.stringify(Tabs.Notes.noteValues);
		setTimeout(function () { GM_setValue('PlayerNotes_'+serverID+'_'+uW.tvuid, s); }, 0); // get around GM_SetValue uW error
	},

	editNoteLink: function (name, id) {
		uW.edit_notes({id:id,username:name});
	},
	createPopup: function (user) {
		Tabs.Notes.ToolsOpen = false;
		if (Options.btWinIsOpen == true) {
			Tabs.Notes.ToolsOpen = true;
			eventHideShow();
		}
		// get the current note
		var notes = "";
		if (Tabs.Notes.noteValues[user.id]) {
			notes = Tabs.Notes.noteValues[user.id];
			notes = notes.text.replace(/<br\/>/g, "\n");
		}
		// popup
		uW.Modal.multiButton({
			buttons: [{
				txt: uW.g_js_strings.commonstr.save,
				exe: function () {
					Tabs.Notes.saveNote(user);
					uW.Modal.hideModal();
					if (Tabs.Notes.ToolsOpen == true) {
						eventHideShow();
					}
				}
			}, {
				txt: uW.g_js_strings.commonstr.deletetx,
				exe: function () {
					Tabs.Notes.removeNote(user.id);
					uW.Modal.hideModal()
					if (Tabs.Notes.ToolsOpen == true) {
						eventHideShow();
					}
				}
			}, {
				txt: uW.g_js_strings.commonstr.cancel,
				exe: function () {
					uW.Modal.hideModal()
					if (Tabs.Notes.ToolsOpen == true) {
						eventHideShow();
					}
				}
			}],
			body: '<strong> '+tx('Enter notes for player')+': </strong><span id="notes_player">' + user.username + '</span><br/><br/><textarea id="notes_text" rows="4" columns="50" style="width:300px;" >' + notes + '</textarea>',
			title: "Player Notes"
		});
	},
	// callback for the save button
	saveNote: function (user) {
		var player = user.id;
		if (player) {
			var noteData = {};
			var notes = ById('notes_text').value;
			noteData.text = notes.replace(/\n/g, "<br/>");
			noteData.id = user.id;
			noteData.name = user.username;
			Tabs.Notes.noteValues[player] = noteData;
			Tabs.Notes.save();
			Tabs.Notes.show();

			var nl = ById('ptplayernotes');
			if (nl && Tabs.Player.userobj[user.id]) {
				nl.innerHTML = noteData.text;
			}
			var nl = ById('ptBatplayernotes');
			if (nl && Battle.userobj[user.id]) {
				nl.innerHTML = noteData.text;
				ResetFrameSize('btPlayerPop',100,400);
			}
		}
	},
	// callback for the delete button
	removeNote: function (player) {
		if (player && Tabs.Notes.noteValues[player]) {
			delete Tabs.Notes.noteValues[player];
			Tabs.Notes.save();
			Tabs.Notes.show();

			var nl = ById('ptplayernotes');
			if (nl && Tabs.Player.userobj[player]) {
				nl.innerHTML = "";
			}
			var nl = ById('ptBatplayernotes');
			if (nl && Battle.userobj[player]) {
				nl.innerHTML = "";
				ResetFrameSize('btPlayerPop',100,400);
			}
		}
	},
	// add the notes to the map tooltip
	updateTooltip: function (ttHtml) {
		var newTT = null;
		var result = Tabs.Notes.re.exec(ttHtml);
		if (result && result[1]) {
			var note;
			if (note = Tabs.Notes.noteValues[result[1]]) {
				newTT = ttHtml.replace("</div><div class='roicon'>","<br><br><b>"+tx('Notes')+":</b><div style=\"position: relative; left: 5%; width: 90%;\">" + note.text + "</div></div><div class='roicon'>");
			}
		}
		return newTT;
	},
	show: function () {
		var h = '<div class=divHeader align=center> <b>'+tx('PLAYER NOTES')+'</b></div>';
		h += '<div align=center style="height: 700px; overflow-y: scroll;width:'+GlobalOptions.btWinSize.x+'px;"><br>';
		h += '<table width="98%" cellpadding=0 cellspacing=0><tr>';
		h += '<td class=xtabHD style="width:115px"><b>'+uW.g_js_strings.commonstr.player+'</b></td><td class=xtabHD><b>'+tx('Notes')+'</b></td><td class=xtabHD align=right style="width:115px"><b>'+tx('Action')+'</b></td></tr>';

		var r = 0;
		var logshow = false;

		for (var player in Tabs.Notes.noteValues) {
			var note = Tabs.Notes.noteValues[player];
			if (note && note.text) {
				logshow = true;
				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';

				h += '<tr class="'+rowClass+'">';
				h += '<TD valign=top style="width:115px" class=xtab><a onclick="ptPlayerDetails('+note.id+')">'+note.name+'</a></td>';
				h += '<td class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-300)+'px;">' + note.text + '</div></td>';
				h += '<TD valign=top class=xtab align=right><a class="inlineButton btButton brown8" onclick=editNoteLink("' + note.name + '","' + note.id + '")><span>'+uW.g_js_strings.commonstr.edit+'</span></a>&nbsp;<a class="inlineButton btButton brown8" onclick="removeNote(\'' + note.id + '\')"><span>'+tx('Del')+'</span></a></td>';
				h += "</tr>";
			}
		}

		if (!logshow) {
			h += '<tr><td colspan=3 class=xtab><div align="center"><br><br>'+tx('No saved notes')+'</div></td></tr>';
		}

		h += "</table></div><br>";

		myDiv.innerHTML = h;
	},
};

/*********************************** Monitor Tab ***********************************/

Tabs.Monitor = {
	tabOrder : 1030,
	tabLabel : 'Monitor',
	userInfo : {},
	rsltInfo : {},
	cText : "",
	LastUser : "",
	MonWidth : 300,
	MonHeight : 500,
	ThroneUID : null,
	MonitorInterval : 3,
	ResetMonitorCountDown : 900,
	MonitorCountDown : 0,
	CurrLog : [],
	LogUser : "",
	LogTR : [],
	LastTR : [],
	MaxLogEntries : 100,
	MonitorID : 0,
	NameFilter : '',
	AllianceFilter : '',
	HisStatEffects : [],

	Options : {
		MonitorFontSize	: 11,
		MonitorColours      : true,
		LastMonitored       : "",
		LastMonitoredUID    : 0,
		MonitorSound        : false,
		MonitorStartState   : false,
		MonPresetChange     : true,
		MonitorChampions    : false,
		TRMonPresetByName   : false,
		AlternateSortOrder  : false,
		MonitorRefreshRate  : 3,
		Volume              : 100,
		PVPOnly             : false,
	},

	init : function (div){
		var t = Tabs.Monitor;

		HTMLRegister['MONITOR'] = {};

		DefaultWindowPos('btMonPos','main_engagement_tabs');

		uWExportFunction ('btShowLog', Tabs.Monitor.ShowLog);
		uWExportFunction ('btDeleteLog', Tabs.Monitor.DeleteLog);
		uWExportFunction ('btPostLog', Tabs.Monitor.PostLog);
		uWExportFunction ('btToggleKeep', Tabs.Monitor.ToggleKeep);
		uWExportFunction ('btUpdateLabel', Tabs.Monitor.UpdateLabel);
		uWExportFunction ('btUpdatePresetLabel', Dashboard.UpdatePresetLabel);
		uWExportFunction ('btFilterLog', Tabs.Monitor.FilterLog);
		uWExportFunction ('btClearNameFilter', Tabs.Monitor.ClearNameFilter);
		uWExportFunction ('btClearAllianceFilter', Tabs.Monitor.ClearAllianceFilter);

		uWExportFunction ('btMonitorExternalCallUID', Tabs.Monitor.MonitorExternalCallUID);
		uWExportFunction ('btMapMonitorTR', Tabs.Monitor.MapMonitorTR);
		uWExportFunction ('btThroneMonitorTR', Tabs.Monitor.ThroneMonitorTR);

		// add entry to the map menu

		for (var jj in uW.cm.ContextMenuMapController.prototype.MapContextMenus.City) {
			if (jj != 5) uW.cm.ContextMenuMapController.prototype.MapContextMenus.City[jj].push("MONI"); } // no misted anymore
		var wildContext;
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.EnemyWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("MONI");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.Wilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("MONI");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.FriendlyWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("MONI");
		}
		wildContext = uW.cm.ContextMenuMapController.prototype.MapContextMenus.AllianceWilderness;
		for (var wild in wildContext) {
			wildContext[wild].push("MONI");
		}

		var mod = new CalterUwFunc('cm.ContextMenuMapController.prototype.calcButtonInfo',
			[['default:', 'case "MONI":' +
			'b.text = "'+tx('Monitor')+'"; b.color = "green"; ' +
			'b.action = function () { ' +
			'btMapMonitorTR(e);' +
			'}; ' +
			'if (e.user.id) d.push(b); break; ' +
			'default: ']]);
		mod.setEnable(true);

		// throne room alteration

		var str = uW.cm.FETemplates.Throne.mainThrone.replace(
			'<li id="throneInventoryTab" class="inactive"> #{inventory} </li>',
			'<li id="throneInventoryTab" class="inactive"> #{inventory} </li><li id="throneMonitor" class="inactive" onclick="btThroneMonitorTR()"> '+tx('Monitor')+' </li>');
		uW.cm.FETemplates.Throne.mainThrone = str;

		// intercept throne room view function to grey out monitor option for your own room...

		var oldTRViewFunc = uW.cm.ThroneView.openThrone;
		var newTRViewFunc = function(c) {
			Tabs.Monitor.ThroneUID = 0;
			if (c) {Tabs.Monitor.ThroneUID = c.id;}
			oldTRViewFunc(c);
			if (Tabs.Monitor.ThroneUID == 0) {jQuery("#throneMonitor").attr("class","deactive"); }
		};
		if (typeof exportFunction == 'function') { exportFunction(newTRViewFunc,uW.cm.ThroneView, {defineAs:"openThrone"}); }
		else { uW.cm.ThroneView.openThrone = newTRViewFunc; };

		if (!Options.MonitorOptions) {
			Options.MonitorOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.MonitorOptions.hasOwnProperty(y)) {
					Options.MonitorOptions[y] = t.Options[y];
				}
			}
		}

		t.loadLog();

		m = '<div>';
		m += '<div class="divHeader" align="center">'+tx('THRONE ROOM MONITOR')+'</div>';
		m += '<div align="center"><br>&nbsp;&nbsp;'+tx('Enemy')+':&nbsp;<INPUT id=btPlayer size=20 type=text value="'+Options.MonitorOptions.LastMonitored+'"/>&nbsp;<a id=btPlayerSubmit class="inlineButton btButton blue20"><span>'+tx('Monitor')+'</span></a>&nbsp;<a id=btUIDSubmit class="inlineButton btButton blue20"><span>UID</span></a></div>';
		m += '<div class="ErrText" align="center" id=btplayErr>&nbsp;</div>';
		m += '<a id=btMonOptionLink class=divLink ><div class="divHeader" align="left"><img id=btMonOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('OPTIONS')+'</div></a>';
		m += '<div id=btMonOption class=divHide><TABLE width="100%">';
		m += '<TR><td class=xtab><INPUT id=SoundChk type=checkbox /></td><td class=xtab>'+tx('Use sound alerts on monitor')+'</td>';
		m += '<TD class=xtab width=50%><div id=btSoundOpts class="divHide"><TABLE cellpadding=0 cellspacing=0><TR valign=middle><TD class=xtab>'+tx('Volume')+'&nbsp;</td><TD class=xtab><SPAN id=btVolSlider></span></td><TD class=xtab align=right id=btVolOut style="width:30px;">0</td><td class=xtab>&nbsp;<a id=btTestMonSound class="inlineButton btButton blue14"><span>'+tx('Test')+'</span></a></td></tr></table></div></td><td class=xtab width=10>&nbsp;</td></tr>';
		m += '<TR><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Font size')+': ' + htmlSelector({8: 8, 9: 9, 10: 10, 11: 11}, Options.MonitorOptions.MonitorFontSize, 'id=btMonitorFont class=btInput') + '&nbsp;'+tx('pixels')+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=MonitorColoursChk type=checkbox /></td><td class=xtab>'+tx('Use different colours in monitor window')+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=PVPOnlyChk type=checkbox /></td><td class=xtab>'+tx('Show PVP effects only')+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=AlternateSortOrderChk type=checkbox /></td><td class=xtab>'+tx('Alternate sort order')+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=MonPresetChk type=checkbox /></td><td class=xtab>'+tx('Show throne room preset changer')+'</td><td width="120" class=xtab>&nbsp;</td></tr>';
		m += '<TR id=btMonPresetByNameOpts class="divHide"><td class=xtab><INPUT id=TRMonPresetByNameChk type=checkbox /></td><td colspan="3" class=xtab>'+tx('Select presets by name')+'</td></tr>';
		m += '<TR><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Monitor refresh rate')+': ' + htmlSelector({1: 1, 2: 2, 3: 3, 4: 4, 5: 5}, Options.MonitorOptions.MonitorRefreshRate, 'id=btMonitorRefreshRate class=btInput') + '&nbsp;'+tx('seconds')+'</td></tr>';
		m += '</table></div>';
		m += '<a id=btMonLogLink class=divLink ><div class="divHeader" align="left"><img id=btMonLogArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('MONITOR LOG')+'</div></a>';
		m += '<div id=btMonLog></div><br>';

		div.innerHTML = m;
		t.PaintLog();
		OpenDiv["Monitor"] = "btMonLog";

		ById('btMonOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Monitor",100,GlobalOptions.btWinSize.x,"btMonOption",false)}, false);
		ById('btMonLogLink').addEventListener ('click', function () {ToggleMainDivDisplay("Monitor",100,GlobalOptions.btWinSize.x,"btMonLog",false)}, false);

		ById('btPlayer').addEventListener ('keypress', function(e) {if ( e.which == 13)  ById('btPlayerSubmit').click();}, false);
		ById('btPlayer').addEventListener ('focus', function (){t.setError('&nbsp;');}, false);
		ById('btPlayerSubmit').addEventListener ('click', t.MonitorTRClick, false);
		ById('btPlayerSubmit').addEventListener('mousedown',function(me) {ResetWindowPos (me,'btPlayerSubmit',popMon);}, true);
		ById('btUIDSubmit').addEventListener ('click', t.UIDClick, false);
		ById('btMonitorFont').addEventListener('change', t.ChangeFontSize, false);

		ChangeOption('MonitorOptions','btMonitorFont','MonitorFontSize',function() {
			if (t.MonitoringActive && popMon) {
				popMon.show(false);
				popMon.destroy();
				popMon = null;
				t.initMonitor(t.userInfo.userId,t.MonitoringPaused);
			}
		});
		ChangeOption('MonitorOptions','btMonitorRefreshRate','MonitorRefreshRate');

		ById('btTestMonSound').addEventListener ('click', function() {
			AudioManager.setVolume(Options.MonitorOptions.Volume);
			AudioManager.setSource(SOUND_FILES.monitor);
			AudioManager.play();
			AudioManager.stoptimer = setTimeout(function(){AudioManager.stop();}, 2500);
		}, false);


		ToggleOption('MonitorOptions','SoundChk', 'MonitorSound', t.SoundToggle);
		t.SoundToggle();
		ToggleOption('MonitorOptions','MonitorColoursChk', 'MonitorColours');
		ToggleOption('MonitorOptions','PVPOnlyChk', 'PVPOnly');
		ToggleOption('MonitorOptions','AlternateSortOrderChk', 'AlternateSortOrder');
		ToggleOption('MonitorOptions','MonPresetChk', 'MonPresetChange', t.MonPresetToggle);
		t.MonPresetToggle ();
		ToggleOption('MonitorOptions','TRMonPresetByNameChk', 'TRMonPresetByName', Dashboard.PaintTRPresets);

		t.VolSlider = new SliderBar (ById('btVolSlider'), 200, 21, 0);
		t.VolSlider.setValue (Options.MonitorOptions.Volume/100);
		t.VolSlider.setChangeListener(t.VolumeChanged);
		t.VolumeChanged (Options.MonitorOptions.Volume/100);

		if (Options.MonitorOptions.MonitorStartState && (Options.MonitorOptions.LastMonitoredUID != 0)) {t.initMonitor(Options.MonitorOptions.LastMonitoredUID);}
	},

	MonitorExternalCallUID : function (UID) {
		if (UID !="") { Tabs.Monitor.initMonitor (deFilter(UID), false); }
	},

	MapMonitorTR : function (e) {
		if (e.user.id != "0") { Tabs.Monitor.initMonitor (e.user.id, false); }
	},

	ThroneMonitorTR : function () {
		var t = Tabs.Monitor;
		if (t.ThroneUID != 0) { Tabs.Monitor.initMonitor (t.ThroneUID, false); }
	},

	sendChat : function (){
		var t = Tabs.Monitor;
		sendChat(t.cText);
	},

	MonPresetToggle : function () {
		var t = Tabs.Monitor;
		var dc = jQuery('#btMonPresetByNameOpts').attr('class');
		if (Options.MonitorOptions.MonPresetChange) {if (dc.indexOf('divHide') >= 0) jQuery('#btMonPresetByNameOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btMonPresetByNameOpts').attr('class','divHide');}
		Dashboard.PaintTRPresets();
	},

	SoundToggle : function () {
		var t = Tabs.Monitor;
		var dc = jQuery('#btSoundOpts').attr('class');
		if (Options.MonitorOptions.MonitorSound) {if (dc.indexOf('divHide') >= 0) jQuery('#btSoundOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btSoundOpts').attr('class','divHide');}
	},

	VolumeChanged : function (val) {
		var t = Tabs.Monitor;
		ById('btVolOut').innerHTML = parseInt(val*100);
		Options.MonitorOptions.Volume = parseInt(val*100);
		saveOptions();
	},

	UIDClick : function () {
		var t = Tabs.Monitor;
		t.setError('&nbsp;');
		var UID = ById('btPlayer').value;
		UID = UID.replace(/\'/g,"_");

		t.initMonitor (UID, false)
	},

	MonitorTRClick : function () {
		var t = Tabs.Monitor;
		t.setError('&nbsp;');
		var name = ById('btPlayer').value;
		name = name.replace(/\'/g,"_").replace(/\,/g,"_").replace(/\-/g,"_");

		if (name.toUpperCase() == Seed.player.name.toUpperCase()) {
			t.initMonitor (uW.tvuid, false)
			return;
		}

		if (getMyAlliance()[0] == 0) {
			t.setError(uW.g_js_strings.membersInfo.youmustbelong);
			return;
		}

		if (name.length < 3){
			setError(uW.g_js_strings.getAllianceSearchResults.entryatleast3);
			return;
		}

		// Get User details.. need to use alliance search to get UserID from name

		fetchPlayerList(name, t.eventMatchNameMonitor);
	},

	setError : function (msg) {
		ById('btplayErr').innerHTML = msg;
	},


	setMonitorError : function (msg) {
		ById('btCountdownDiv').innerHTML = msg;
	},

	eventMatchNameMonitor : function (rslt){
		var t = Tabs.Monitor;
		if (!rslt.ok){
			t.setError(rslt.msg);
			return;
		}

		var matchname = ById('btPlayer').value;
		var uid = "";

		for (var k in rslt.matchedUsers) {
			if (rslt.matchedUsers[k].name.toUpperCase() == matchname.toUpperCase()) {uid = rslt.matchedUsers[k].userId;}
		}

		if (uid==""){
			t.setError(tx('User not found')+'!');
			return;
		}

		t.initMonitor (uid, false);
	},

	initMonitor : function (uid,Paused) {
		var t = Tabs.Monitor;

		// set booleans and show loading window if not already active..

		t.userInfo.userLoaded = false;
		ResetHTMLRegister('MONITOR','btUserDiv');
		ResetHTMLRegister('MONITOR','btMonitorDiv');
		t.MonitoringActive = false;
		t.MonitoringPaused = Paused;
		if (popMon) {popMon = null;}
		t.CreateMonitorWindow();

		// get user info first..

		t.fetchPlayerInfo(uid,true,t.eventLoadMonitor);
	},

	eventLoadMonitor : function (){
		var t = Tabs.Monitor;
		if (!t.userInfo.userLoaded) {return;} // error?

		if (t.MonitoringPaused) {
			t.eventPaintTRStats();
			t.StartMonitorLoop();
		}
		else {
			t.TRStats(t.StartMonitorLoop);
		}
	},

	CreateMonitorWindow : function () {
		var t = Tabs.Monitor;
		t.LastUser = "";
		t.LastTR = [];

		m = '<div style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;"><div id=btCountdownDiv><TABLE width="100%"><tr><td class=xtab align="center">&nbsp;</span></td></tr></table></div><div id=btUserDiv><TABLE><TD class=xtab><br><B>&nbsp;&nbsp;&nbsp;'+tx('Loading...')+'</b></td></tr></table></div><div id=btMonitorDiv></div><div id=btButtonDiv></div></div>';

		t.MonWidth=300;
		t.MonHeight=500;

		// adjust width and height based on monitor font size

		var fontratio = Options.MonitorOptions.MonitorFontSize / 11;
		t.MonWidth = Math.floor(t.MonWidth * fontratio);
		t.MonHeight = Math.floor(t.MonHeight * fontratio);

		popMon = new CPopup('btMonitor', Options.btMonPos.x, Options.btMonPos.y, t.MonWidth, t.MonHeight, true, Tabs.Monitor.close);
		popMon.getMainDiv().innerHTML = m;
		popMon.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Monitor')+'</B></DIV>';
		popMon.show(true);
	},

	close : function () {
		var t = Tabs.Monitor;
		t.StopMonitoring();
		Options.btMonPos = popMon.getLocation();
		saveOptions();
		popMon=null;
	},

	eventPaintPlayerInfo : function () {
		var t = Tabs.Monitor;
		if (!t.userInfo.userLoaded) {return;} // user being changed

		var fontratio = Options.MonitorOptions.MonitorFontSize / 11;
		var imgwidth = 16;
		imgwidth = Math.floor(imgwidth * fontratio);

		o = "";
		if (t.userInfo.online) o = ' <span style="color:#f00;">('+tx('ONLINE')+')</span>';

		m = '<div id=btMonTRPresets align=center style="width:352;"></div>';
		m += '<TABLE width="100%"><tr><td class=xtabBR align="center" colspan="3"><B>' + t.userInfo.name + o +'</b></td></tr>';

		if (!t.userInfo.online)
			m+= ' <tr><TD class=xtabBR align="center" colspan="3">'+ t.getLastLogDuration(t.userInfo.lastLogin) +'</td></tr>';
		if (t.userInfo.misted)
			m += '<tr><TD class=xtabBR align="center" colspan="3"><B>*** '+tx('MISTED')+' (' + t.getDuration(t.userInfo.fogExpireTimestamp) + ') ***</b></td></tr>';
		m += '<tr><TD class=xtab align="center" colspan="3">UID: <B>' + parseInt(t.userInfo.userId) + '</b>&nbsp;<a id=btProfile onclick="getInfoForAnUser('+t.userInfo.userId+')">('+uW.g_js_strings.commonstr.profile+')</a>';
		if (KOCBYTE_ON) m += '&nbsp;<a target="_tab" href="http://www.kocbyte.com/player/' + getServerId() + '/' + t.userInfo.userId + '"><img title="'+tx('View player on KoCByte')+'" width="'+imgwidth+'" style="vertical-align:bottom;opacity:0.75;" src="'+KOCBYTE_LOGO+'"></a>';
		m += '</td></tr>';
		m += '<tr><TD class=xtab align="center" colspan="3">'+uW.g_js_strings.commonstr.might+': <B>' + addCommas(Math.round(t.userInfo.might)) + '</b></td></tr>';
		m += '<tr><TD class=xtab align="center" colspan="3">TR/CH '+uW.g_js_strings.commonstr.might+': <B>' + addCommas(Math.round(t.userInfo.might) - Math.round(t.userInfo.mightClassic)) + '</b></td></tr>';
		m += '<tr><TD class=xtab align="center" colspan="3">'+uW.g_js_strings.commonstr.glory+' '+uW.g_js_strings.commonstr.might+': <B>' + addCommas(Math.round(t.userInfo.mightGlory)) + '</b></td></tr>';
		if (t.userInfo.allianceName) {
			n = ""; if (!isMyself(t.userInfo.userId)) n += FormatDiplomacy(t.userInfo.allianceId);
			m += '<tr><TD class=xtabBR align="center" colspan="3">'+uW.g_js_strings.commonstr.alliance+': <B>' + t.userInfo.allianceName + n + '</b></td></tr>';
		}
		m += '<tr><TD class=xtabBR align="center" colspan="3">'+uW.g_js_strings.commonstr.status+': <B>' + t.GetStatusText(t.userInfo.warStatus,t.userInfo.truceExpireTimestamp) + '</b></td></tr>';
		m += '<tr><TD class=xtab align="center" colspan="3">&nbsp;</td></tr></table>';

		if (CheckForHTMLChange('MONITOR','btUserDiv',m)) {
			Dashboard.PaintTRPresets();
			ResetFrameSize('btMonitor',t.MonHeight,t.MonWidth);
		}
	},

	fetchPlayerInfo : function (uid, init, notify){
		var t = Tabs.Monitor;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rsltInfo) {
				if (!rsltInfo.ok) {
					if (init) {
						if (ById('btUserDiv')) {
							ById('btUserDiv').innerHTML = '<TABLE width=100%><TD align=center class=xtab style="color:#f00;"><br><B>'+tx('Unknown UID')+'</b></td></tr></table>';
						}
					}
					t.setError('Unknown UID');
					return;
				}

				t.userInfo = rsltInfo.userInfo[0];
				t.fetchPlayerStatus (notify);
			},
			onFailure: function () {
				t.setError ('AJAX error (server not responding)');
				notify ();
			},
		},true);
	},

	eventPaintTRStats : function () {
		var t = Tabs.Monitor;

		if (!t.userInfo.userLoaded) {return;} // user being changed

		t.cText = "";
		var title = t.userInfo.name+"'s Throne Room";
		if (Options.MonitorOptions.PVPOnly) {title += ' (PVP Effects)';}

		m = '<TABLE>';

		var SortOrder = [];
		if (Options.MonitorOptions.AlternateSortOrder) { for (var z in AlternateSortOrder) SortOrder.push(AlternateSortOrder[z]); }
		else { for (var z in t.HisStatEffects) SortOrder.push(z);	}

		for (var z in SortOrder) {
			var k = SortOrder[z];
			var HisContent = "";
			var LineStyle = '';
			var EndStyle = '';

			var PVP = ((AttackEffects.indexOf(parseInt(k)) > -1) || (DefenceEffects.indexOf(parseInt(k)) > -1) || (LifeEffects.indexOf(parseInt(k)) > -1) || (RangeEffects.indexOf(parseInt(k)) > -1) || (SpeedEffects.indexOf(parseInt(k)) > -1) || (AccuracyEffects.indexOf(parseInt(k)) > -1) || (OtherCombatEffects.indexOf(parseInt(k)) > -1) || (OtherPVPEffects.indexOf(parseInt(k)) > -1));

			if (Options.MonitorOptions.MonitorColours) {
				var TRStyles = getTREffectStyle(k);
				LineStyle = TRStyles.LineStyle;
				EndStyle = TRStyles.EndStyle;
			}
			if (!Options.MonitorOptions.PVPOnly || PVP) {
				if (t.HisStatEffects[k] && (t.HisStatEffects[k] != 0) && uW.cm.thronestats["effects"][k]) HisContent = (Math.round(t.HisStatEffects[k]*100)/100) + '% ' + uW.g_js_strings.throneRoom["effectName_" + k];
				if (HisContent != "") { m +='<TR><TD  width="25px" class=xtab></td><TD class=xtab>' + LineStyle + HisContent + EndStyle +'</span></td><TD  width="50px" class=xtab></td></tr>'; t.cText += enFilter(HisContent) + "||"; }
			}
		}
		m +='</table>';
		t.cText = t.cText.replace(/\|\|\s*$/, "");
		t.cText = ":::. |" +title + "|| "+ t.cText;

		if (CheckForHTMLChange('MONITOR','btMonitorDiv',m)) {
			ResetFrameSize('btMonitor',t.MonHeight,t.MonWidth);
		}

		// if first TR monitored for this user then add log entry...
		// check with last entry added in case of refresh...

		if ((t.LastUser == "") && !t.MonitoringPaused) {
			t.LogUser = "";
			t.LogTR = [];
			if (t.CurrLog.length > 0) {
				t.LogUser = t.CurrLog[t.CurrLog.length-1].id;
				t.LogTR = t.CurrLog[t.CurrLog.length-1].tr.slice();
			}

			if ((t.LogUser != t.userInfo.userId) || (JSON2.stringify(t.LogTR) != JSON2.stringify(t.HisStatEffects))) {
				t.AddToLog(t.userInfo.userId,t.userInfo.name,t.userInfo.allianceName,t.HisStatEffects.slice());
			}
		}

		// if changed while monitoring add log entry and play a sound...

		if ((t.LastUser == t.userInfo.name) && (JSON2.stringify(t.LastTR) != JSON2.stringify(t.HisStatEffects)) && !t.MonitoringPaused) {
			t.AddToLog(t.userInfo.userId,t.userInfo.name,t.userInfo.allianceName,t.HisStatEffects.slice());
			if (Options.MonitorOptions.MonitorSound) {
				AudioManager.setVolume(Options.MonitorOptions.Volume);
				AudioManager.setSource(SOUND_FILES.monitor);
				AudioManager.play();
				AudioManager.stoptimer = setTimeout(function(){AudioManager.stop();}, 2500);
			}
		}

		t.LastUser = t.userInfo.name;
		t.LastTR = t.HisStatEffects.slice();
	},

	fetchPlayerStatus : function (notify){
		var t = Tabs.Monitor;

		var params = uW.Object.clone(uW.g_ajaxparams);
		var uid = t.userInfo.userId;
		params.checkArr = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getOnline.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				t.userInfo.online = rslt.data[uid];
				t.fetchCourtInfo (notify);
			},
			onFailure: function () {
				t.setError ('AJAX error (server not responding)');
				notify ();
			},
		},true); // no retry
	},

	fetchCourtInfo : function (notify) {
		var t = Tabs.Monitor;

		var params = uW.Object.clone(uW.g_ajaxparams);
		var uid = t.userInfo.userId;
		params.pid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/viewCourt.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				u = unixTime();
				f = convertTime(new Date(rslt.playerInfo.fogExpireTimestamp.replace(" ","T")+"Z"));
				t.userInfo.misted = (f >= u);
				t.userInfo.fogExpireTimestamp = rslt.playerInfo.fogExpireTimestamp;
				t.userInfo.warStatus = rslt.playerInfo.warStatus;
				t.userInfo.truceExpireTimestamp = rslt.playerInfo.truceExpireTimestamp;
				t.userInfo.lastLogin = rslt.playerInfo.lastLogin;
				t.userInfo.cityCount = rslt.playerInfo.cityCount;
				t.userInfo.mightClassic = rslt.playerInfo.mightClassic;
				t.userInfo.mightGlory = rslt.playerInfo.mightGlory;
				t.userInfo.userLoaded = true;
				notify ();
			},
			onFailure: function () {
				t.setError ('AJAX error (server not responding)');
				notify ();
			},
		},true); // no retry
	},

	TRStats : function (notify) {
		var t = Tabs.Monitor;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = 'throneRoom\\ThroneRoomServiceAjax';
		params.action = 'getEquipped';
		params.playerId = t.userInfo.userId;

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch53.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if(rslt.ok){
					for (var k in uW.cm.thronestats.effects) t.HisStatEffects[k] = 0;
					for (var kk in rslt.items){
						y = rslt.items[kk];
						if (y != undefined) {
							if (y["jewel"] && y["jewel"]["valid"] == true){
								y["effects"]["slot6"].fromJewel = true;
								y["effects"]["slot6"].quality = y["jewel"].quality;
							}
							for (var O in y["effects"]) {
								var i = +(O.split("slot")[1]);
								id = y["effects"]["slot"+i]["id"];
								tier = parseInt(y["effects"]["slot"+i]["tier"]);
								level = y["level"];
								p = uW.cm.thronestats.tiers[id][tier];
								while (!p && (tier > 0)) { tier--; p = uW.cm.thronestats.tiers[id][tier]; }
								if (!p) { logit('No stats for effect '+id+' in tier '+tier+' or below');continue; } // can't find stats for tier
								var base = +p.base || 0;
								var growth = +p.growth || 0;
								if (y["effects"]["slot"+i].fromJewel && (level > uW.cm.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality])) {
									level = uW.cm.thronestats.jewelGrowthLimit[y["effects"]["slot"+i].quality]
								}
								Current = Number(base + ((level * level + level) * growth * 0.5));
								if (i<=parseInt(y["quality"])) t.HisStatEffects[id] += Current;
							}
						}
					}
				} else t.setMonitorError(tx('Error Reading Throne Room'));
				if (params.playerId == t.userInfo.userId) {notify();}
			},
			onFailure: function () {
				t.setMonitorError('AJAX Error (Server Not Responding)');
				if (params.playerId == t.userInfo.userId) {notify();}
			},
		},true); // no retry
	},

	StopMonitoring : function () {
		var t = Tabs.Monitor;
		t.userInfo.userLoaded = false;
		t.MonitoringActive = false;
		Options.MonitorOptions.MonitorStartState = false;
		saveOptions();
	},

	StartMonitorLoop : function () {
		var t = Tabs.Monitor;

		t.eventPaintPlayerInfo();
		t.eventPaintTRStats();

		// show buttons ...

		m = '<TABLE width="100%">';
		m +='<TR><TD class=xtabBR colspan="3"><div align="center"><br><a id=btPostToChat class="inlineButton btButton blue20"><span style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;">'+tx('Post to Chat')+'</span></a>&nbsp;<a id=btOpenTR class="inlineButton btButton blue20"><span style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;">'+uW.g_js_strings.commonstr.throneroom+'</span></a>&nbsp;<a id=btPause class="inlineButton btButton blue20"><span style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;">'+tx('Pause')+'</span></a></div></td></tr>';
		m +='</table>';
		ById('btButtonDiv').innerHTML = m;
		ResetFrameSize('btMonitor',t.MonHeight,t.MonWidth);
		ById('btPostToChat').addEventListener ('click', t.sendChat, false);
		ById('btPause').addEventListener ('click', t.TogglePause, false);
		ById('btOpenTR').addEventListener ('click', t.showTR, false);

		t.MonitorID = t.userInfo.userId;
		Options.MonitorOptions.LastMonitored = t.userInfo.name;
		Options.MonitorOptions.LastMonitoredUID = t.userInfo.userId;
		Options.MonitorOptions.MonitorStartState = true;
		saveOptions();

		t.MonitorLooper = 0;

		t.MonitorCountDown = t.ResetMonitorCountDown;
		t.MonitoringActive = true;
	},

	MonitorTRLoop : function () {
		var t = Tabs.Monitor;

		if (!t.userInfo.userLoaded) {return;} // user being changed

		t.MonitorLooper = t.MonitorLooper+1;
		if (t.MonitorLooper > 30) {
			t.MonitorLooper = 0;
			t.fetchPlayerInfo (t.userInfo.userId,false,t.eventPaintPlayerInfo);
		}

		// check for 15 minute monitor timeout

		if (!trusted && !t.MonitoringPaused) {
			t.MonitorCountDown = t.MonitorCountDown - 1;
			if (t.MonitorCountDown < 1) {
				t.MonitorTimedOut = true;
				t.MonitoringPaused = true;
				Options.MonitorOptions.MonitorStartState = false;
				saveOptions();
				AudioManager.setVolume(Options.MonitorOptions.Volume);
				AudioManager.setSource(SOUND_FILES.timeout);
				AudioManager.play();
				AudioManager.stoptimer = setTimeout(function(){AudioManager.stop();}, 2500);
			}
		}

		m = '<TABLE width="100%"><tr><td class=xtab align="center">&nbsp;</span></td></tr></table>';
		if (!trusted && !t.MonitoringPaused) {
			o = '<span style="color:#888;">';
			if (t.MonitorCountDown <= 30) o = '<span style="color:#f00;">';
			if (!t.MonitorTimedOut) m = '<TABLE width="100%"><tr><td class=xtab align="center">'+o+tx('Monitor timeout in ')+uW.timestr(t.MonitorCountDown)+'</span></td></tr></table>';
		}
		ById('btCountdownDiv').innerHTML = m;

		if (t.MonitoringPaused) {
			if (t.MonitorTimedOut)
				{ popMon.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Monitoring Timed Out')+'</B></DIV>'; }
			else
				{ popMon.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+tx('Monitoring Paused')+'</B></DIV>'; }
			ById('btPause').innerHTML = '<span style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;">'+tx('Resume')+'</span>';
		}
		else {
			var dots = "";
			var rem = (t.MonitorLooper % 2);
			for (var s=0; s<=1; s++) {
				if (s < rem) {dots+="*";}
			}

			popMon.getTopDiv().innerHTML = '<DIV align=center><B>&nbsp;&nbsp;&nbsp;'+dots+'&nbsp;Monitoring&nbsp;'+dots+'</B></DIV>';
			ById('btPause').innerHTML = '<span style="font-size:'+Options.MonitorOptions.MonitorFontSize+'px;">'+tx('Pause')+'</span>';

			if (((t.MonitorLooper % t.MonitorInterval) == 1) || (t.MonitorInterval == 1)) {
				t.TRStats(t.eventPaintTRStats);
			}
		}
	},

	getLastLogDuration : function (datestr){
		if (!datestr) return;
		var Interval = convertTime(new Date(datestr.replace(" ","T")+"Z")) - unixTime();
		if (Interval < 0) return '('+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+' '+ uW.timestr(Interval*(-1)) +' ago)';
		else return '('+tx('minutes ago')+')';
	},

	getDuration : function (datestr){
		if (!datestr) return;
		var Interval = convertTime(new Date(datestr.replace(" ","T")+"Z")) - unixTime();
		if (Interval >= 0) {
			return uW.timestr(Interval);
		}
		else {
			if (Interval > -43200) { return tx("Can't Truce for ")+uW.timestr(43200 - (Interval*-1)); }
			else { return ""; }
		}
	},

	GetStatusText : function (warStatus,truceExpireTimestamp) {
		var t = Tabs.Monitor;
		// weird bug?!!!?
		var dur = t.getDuration(truceExpireTimestamp);
		var d = '';
		if (dur != "") {d = ' ('+dur+')';}
		else {warStatus = 1;} // I think this just means the status hasn't been updated...?

		switch (parseInt(warStatus)) {
			case 1:
			return uW.g_js_strings.commonstr.normal+d;
			case 2:
			return uW.g_js_strings.MapObject.begprotect+d;
			case 3:
			return uW.g_js_strings.commonstr.truce+d;
			case 4:
			return uW.g_js_strings.commonstr.vacation+d;
			default:
			return uW.g_js_strings.commonstr.normal+d
		}
	},

	showTR : function () {
		var t = Tabs.Monitor;
		var T = {};
		T.id = t.userInfo.userId;
		T.self = isMyself(t.userInfo.userId);
		T.name = t.userInfo.name;
		uW.cm.ModalManager.close();
		uW.cm.ThroneController.getThroneItems(T)
	},

	TogglePause : function () {
		var t = Tabs.Monitor;
		if (t.MonitoringPaused) {
			t.MonitoringPaused = false;
			t.MonitoringTimedOut = false;
			t.MonitorCountDown = t.ResetMonitorCountDown;
			Options.MonitorOptions.MonitorStartState = true;
		}
		else {
			t.MonitoringPaused = true;
			Options.MonitorOptions.MonitorStartState = false;
		}
		saveOptions ();
	},

	loadLog : function () {
		var t = Tabs.Monitor;
		var l = JSON2.parse(GM_getValue ('MonitorLog_'+getServerId()+'_'+uW.tvuid, '[]'));
		if (matTypeof(l) == 'array') { t.CurrLog = l; }
	},

	saveLog : function () {
		var t = Tabs.Monitor;
		setTimeout(function () { GM_setValue ('MonitorLog_'+getServerId()+'_'+uW.tvuid, JSON2.stringify(t.CurrLog));} ,0); // get around GM_SetValue uW error
	},

	ClearLog : function () {
		var t = Tabs.Monitor;
		t.CurrLog = [];
		t.saveLog();
		t.PaintLog();
	},

	AddToLog : function (ID,Name,Alliance,TRStats) {
		var t = Tabs.Monitor;
		var ts = unixTime();
		var okeep = false;
		var olabel = "";

		// don't log yourself!!

		if (isMyself(t.userInfo.userId)) { return; }

		// if TR already in log, then remove so we update alliance and date/time stamp...

		var n = t.CurrLog.length;
		while (n--) {
			t.LogUser = t.CurrLog[n].id;
			t.LogTR = t.CurrLog[n].tr.slice();

			if ((t.LogUser == t.userInfo.userId) && (JSON2.stringify(t.LogTR) == JSON2.stringify(t.HisStatEffects))) {
				// keep any labels or keep flag!
				okeep = t.CurrLog[n].keep;
				olabel = t.CurrLog[n].label;
				t.CurrLog.splice(n,1);
			}
		}

		while (t.CurrLog.length >= t.MaxLogEntries) {
		//make space in the log.. find the earliest entry where keep = false
			var spliced = false;
			for (var l in t.CurrLog) {
				if (!t.CurrLog[l].keep) {
					t.CurrLog.splice(l,1);
					spliced = true;
					break;
				}
			}
			//no space, because keep is set on all entries. Log it!
			if (!spliced) {
				logit('No space in Monitor Log!');
				return;
			}
		}
		t.CurrLog.push ({ts:ts, id:ID, name:Name, alliance:Alliance, tr:TRStats, keep:okeep, label:olabel});
		t.saveLog();
		t.PaintLog();
	},

	PaintLog : function () {
		var t = Tabs.Monitor;

		var z = '';
		var r = 0;
		var logshow = false;
		var logfiltered = false;

		var bclass = "blue14";
		var btext  = tx("Clear Log");

		var z = '<div align="center"><TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtab">'+tx('Filter by Name/UID')+': <INPUT class="btInput" id="btNameFilter" size=16 style="width: 115px" type=text value="'+t.NameFilter+'" onkeyup="btStartKeyTimer(this,btFilterLog)" onchange="btFilterLog()" />&nbsp;<a class="inlineButton btButton brown8" onclick="btClearNameFilter()"><span>'+tx('Clear')+'</span></a></td><td class="xtab">'+uW.g_js_strings.commonstr.alliance+': <INPUT class="btInput" id="btAllianceFilter" size=16 style="width: 115px" type=text value="'+t.AllianceFilter+'" onkeyup="btStartKeyTimer(this,btFilterLog)" onchange="btFilterLog()" />&nbsp;<a class="inlineButton btButton brown8" onclick="btClearAllianceFilter()"><span>'+tx('Clear')+'</span></a></td></td><td class="xtab" align=right>('+t.CurrLog.length+'/'+t.MaxLogEntries+')</td></tr></table>';
		z += '<TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtabHD" align="center" style="width:20px">&nbsp;</td><td class="xtabHD" style="width:100px"><b>'+tx('Date/Time')+'</b></td><td style="width:115px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.nametx+'</b></td><td style="width:115px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.alliance+'</b></td><td class="xtabHD" style="width:145px"><b>Label</b></td><td class="xtabHD" align="center" style="width:30px"><b>'+tx('Keep')+'</b></td><td class="xtabHD" align="right"><a id=btClearLog class="inlineButton btButton '+bclass+'"><span>'+btext+'</span></a></td></tr></table>';
		z += '<div style="max-height:330px; overflow-y:scroll" align="center"><TABLE id=btLogTable cellSpacing=0 width=98% height=0%>';

		var n = t.CurrLog.length;
		while (n--) {
			var a = t.CurrLog[n];

			logfiltered = true;
			if ((t.NameFilter != "") && (a.name.toUpperCase().search(t.NameFilter.toUpperCase()) < 0) && (a.id.search(t.NameFilter) < 0)) continue;
			if ((t.AllianceFilter != "") && (a.alliance.toUpperCase().search(t.AllianceFilter.toUpperCase()) < 0)) continue;

			logshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:20px" class="xtab trimg" id="trimg'+n+'" align=left><img src="'+ThroneImage+'"</img></td>';
			z += '<TD style="width:100px" class=xtab>'+formatDateTime(a.ts)+'</td>';
			z += '<TD style="width:115px" class=xtab>'+PlayerLink(a.id,a.name)+'</td>';
			z += '<TD style="width:115px" class=xtab>'+(a.alliance?a.alliance:'---')+'</td>';
			z += '<TD style="width:145px" class=xtab><INPUT class="btInput" id="btLabel'+n+'" size=20 style="width: 140px" type=text value="'+a.label+'" onkeyup="btStartKeyTimer(this,btUpdateLabel,'+n+')" onchange="btUpdateLabel(this,'+n+')" /></td>';
			z += '<TD style="width:30px" class=xtab align=center><INPUT id="btKeep'+n+'" type=checkbox '+(a.keep?'CHECKED':'')+' onclick="btToggleKeep('+n+')" /></td>';
			z += '<TD class=xtab align=right><a id="btShowLog'+n+'" class="inlineButton btButton brown8" onclick="btShowLog('+n+')"><span>'+tx('Open')+'</span></a>&nbsp;<a id="btPostLog'+n+'" class="inlineButton btButton brown8" onclick="btPostLog('+ n +')"><span>'+tx('Post')+'</span></a>&nbsp;<a id="btDeleteLog'+n+'" class="inlineButton btButton brown8" onclick="btDeleteLog('+n+')"><span>'+tx('Del')+'</span></a></td>';
			z += '</tr>';
		}

		if (!logshow) {
			if (!logfiltered)
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No log entries')+'</div></td></tr>';
			else
				z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No log entries matching search parameters')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		ById('btMonLog').innerHTML = z;
		ById('btClearLog').addEventListener ('click', function() {t.ClearLog();}, false);

		var cItems = ById('btLogTable').getElementsByClassName('trimg');
		for (var i = 0; i < cItems.length; i++) { t.createToolTip("",cItems[i],t.CurrLog[cItems[i].id.substring(5)].tr.slice()); }
	},

	createToolTip : function (title,elem,TempStatEffects) {
		var t = Tabs.Monitor;
		var TempcText = "";
		if (title != "") { TempcText += "<b>"+title+"</b><br>&nbsp;<br>"; }

		for (var k in TempStatEffects) {
			var HisContent = "";
			if (TempStatEffects[k] && (TempStatEffects[k] != 0) && uW.cm.thronestats["effects"][k]) HisContent = (Math.round(TempStatEffects[k]*100)/100) + '% ' + uW.g_js_strings.throneRoom["effectName_" + k];
			if (HisContent != "") { TempcText += HisContent + "<br>"; }
		}

		jQuery('#'+elem.id).children("span").remove();
		jQuery('#'+elem.id).append('<span class="trtip">'+TempcText+'</span>');
	},

	ShowLog : function (entry) {
		var t = Tabs.Monitor;
		t.HisStatEffects = t.CurrLog[entry].tr.slice();

		// display monitor in paused mode showing selected entry

		t.initMonitor(t.CurrLog[entry].id, true);
	},

	ToggleKeep : function (entry) {
		var t = Tabs.Monitor;
		t.CurrLog[entry].keep = !t.CurrLog[entry].keep;
		t.saveLog();
	},

	UpdateLabel : function (elem,entry) {
		var t = Tabs.Monitor;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		t.CurrLog[entry].label = elem.value;
		t.saveLog();
	},

	PostLog : function (entry) {
		var t = Tabs.Monitor;
		var TempStatEffects = t.CurrLog[entry].tr.slice();
		var TempcText = "";

		var title = t.CurrLog[entry].name+uW.g_js_strings.throneRoom.title_part;
		if (Options.MonitorOptions.PVPOnly) {title += ' (PVP Effects)';}

		for (var k in TempStatEffects) {
			var HisContent = "";
			var PVP = ((AttackEffects.indexOf(parseInt(k)) > -1) || (DefenceEffects.indexOf(parseInt(k)) > -1) || (LifeEffects.indexOf(parseInt(k)) > -1) || (RangeEffects.indexOf(parseInt(k)) > -1) || (SpeedEffects.indexOf(parseInt(k)) > -1) || (AccuracyEffects.indexOf(parseInt(k)) > -1) || (OtherCombatEffects.indexOf(parseInt(k)) > -1) || (OtherPVPEffects.indexOf(parseInt(k)) > -1));
			if (!Options.MonitorOptions.PVPOnly || PVP) {
				if (TempStatEffects[k] && (TempStatEffects[k] != 0) && uW.cm.thronestats["effects"][k]) HisContent = (Math.round(TempStatEffects[k]*100)/100) + '% ' + uW.g_js_strings.throneRoom["effectName_" + k];
				if (HisContent != "") { TempcText += HisContent + "||"; }
			}
		}
		TempcText = TempcText.replace(/\|\|\s*$/, "");
		TempcText = ":::. |" +title + "|| "+ TempcText;
		sendChat(TempcText);
	},

	DeleteLog : function (entry) {
		var t = Tabs.Monitor;
		t.CurrLog.splice(entry,1);
		t.saveLog();
		t.PaintLog();
	},

	FilterLog : function () {
		var t = Tabs.Monitor;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		t.NameFilter = ById('btNameFilter').value;
		t.AllianceFilter = ById('btAllianceFilter').value;
		t.PaintLog();
	},

	ClearNameFilter : function () {
		var t = Tabs.Monitor;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		ById('btNameFilter').value = "";
		t.FilterLog();
	},

	ClearAllianceFilter : function () {
		var t = Tabs.Monitor;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		ById('btAllianceFilter').value = "";
		t.FilterLog();
	},

	EverySecond : function () {
		var t = Tabs.Monitor;

		t.MonitorInterval = Options.MonitorOptions.MonitorRefreshRate;
		if (safecall.indexOf(t.userInfo.userId) >= 0 && !trusted) {t.MonitorInterval = 30;}

		if (t.MonitoringActive && popMon) {
			setTimeout(function() {t.MonitorTRLoop();},0);
		}
	},
}

/*********************************** Options Tab ***********************************/

Tabs.Options = {
	tabOrder: 9000,
	tabLabel: 'Settings',
	tabColor: 'red',
	tabMandatory: true,
	myDiv: null,
	WarnAscensionTimer: null,
	MiniRefreshTimer: null,
	LoopCounter:0,
	FBAPI:false,
	PublishLists : {0:'----', 80:tx("Everyone"), 50:tx("Friends of Friends"), 40:tx("Friends Only"), 10:tx("Only Me"), 99:tx('Custom List')},

	trstyles : 'div#throneMainContainer div#tableContainer{width:80px;height:213px;top:400px;left:450px;}\
				div#throneMainContainer div#trophyContainer{width:71px;height:86px;top:41px;left:381px;}\
				div#throneMainContainer div#statueContainer{width:124px;height:296px;top:274px;left:150px;z-index:97;}\
				div#throneMainContainer div#advisorContainer{width:141px;height:240px;bottom:0pt;right:0pt;}\
				div#throneMainContainer div#heroContainer{width:85px;height:150px;top:190px;left:585px;z-index:97;}',
	Colors : {
		Default:	{ Title: '#342819', TitleText: '#FFFFFF', DividerTop: '#E9D9AE', DividerBottom: '#8C7D5D', DividerText: '#000000', Panel: '#F7F3E6', PanelText: '#000000', Highlight: '#FFFFCC', HighlightText: '#000000',},
	},
	ReportOptions : {
		EnhanceAR: false,
		alertinterval: 10,
		alertmtroops: 0,
		WhisperAR:false,
		WhisperARList:"",
		WhisperOutgoing:false,
		PostIncoming: true,
		DeleteRptbc	: false,
		DeleteRpttr	: false,
		DeleteRptwl	: false,
		DeleteRptaa	: false,
		DeleteRptfr	: false,
		DeleteRptid	: false,
		DeleteRptdf	: false,
		DeleteRptsc	: false,
		DeleteRptUID : "",
		DeleteRptidType	: 0,
		NoDuplicateReports : true,
	},
	ChatOptions : {
		chatEnhance: true,
		chatIcons : true,
		chatGlobal: true,
		chatWhisper: true,
		chatBold: false,
		chatAttack: true,
		chatLeaders: true,
		enableWhisperAlert: true,
		WhisperPlay: 'monitor',
		enableTowerAlert: false,
		TowerPlay: 'allianceattack',
		filter: true,
		fchar: "Null",
		HelpRequest  : true,
		DeleteRequest: true,
		DeletegAl    : true,
		DeleteFood   : false,
		DeleteFoodUsers : "",
		DeleteGlobalSpam : false,
		DeleteAllianceSpam : false,
		SpamActive : false,
		SpamType : "g",
		SpamText : "Join my Alliance!",
		SpamInterval : 15,
		Emoticons : true,
		ImagePreviews : true,
		Volume : 100,
		GloryLeader : true,
		GloryLeaderInterval : 15,
		GloryLeaderUID : 0,
		GloryLeaderAID : 0,
		GloryLeaderLastChecked : 0,
		Rainbow : false,
	},
	TowerOptions : {
		aChat : true,
		aPrefix : '** Red Alert! **',
		scouting : false,
		wilds : false,
		defend : true,
		tech : false,
		upkeep : true,
		minTroops : 1000,
		whisper : true,
		whisperTroops : 500000,
		email : false,
		lastEmailSent : null,
		towercitytext : {},
		towercityactive : {},
		alertSound : {
			enabled : false,
			soundUrl : DEFAULT_ALERT_SOUND_URL,
			scoutUrl : DEFAULT_SCOUT_SOUND_URL,
			repeat : true,
			playLength : 10,
			repeatDelay : 0.5,
			volume : 100,
			alarmActive : false,
			expireTime : 0,
		},
		AFKEvents : true,
		ChangeTR : false,
		ChangeTRPreset : "",
		StopRaids : false,
		StopMarches : false,
		ChangeGuardian : false,
		Revert : false,
		RevertMinutes : 2,
		RecentActivity : false,
		LastAttack : 0,
		HandledMarches : [],
		LatestAttackTimes : {},
		RecentCityActivity : {},
		SaveCityState : {},
		SaveTRPreset : 0,
		DefendMonitor : true,
	},
	soundRepeatTimer : null,
	soundStopTimer : null,
	updatemarchfunc : null,
	mss : null,
	languagestatus : '',
	popLang : null,

	init : function (div){
		var t = Tabs.Options;
		t.myDiv = div;

		if (THEMES) {
			for (var a in THEMES) {
				t.Colors[a] = THEMES[a];
			}
		}

		uWExportFunction('btTabDelete', Tabs.Options.TabDelete);
		uWExportFunction('btTabRefresh', Tabs.Options.TabRefresh);
		uWExportFunction('btTabAdd', Tabs.Options.TabAdd);
		uWExportFunction('btTabReset', Tabs.Options.TabReset);
		uWExportFunction('btTabToggle', Tabs.Options.TabToggle);
		uWExportFunction ('btToggleTRPreset', Tabs.Options.ToggleTRPreset);

		if (!Options.ReportOptions) {
			Options.ReportOptions = t.ReportOptions;
		}
		else {
			for (var y in t.ReportOptions) {
				if (!Options.ReportOptions.hasOwnProperty(y)) {
					Options.ReportOptions[y] = t.ReportOptions[y];
				}
			}
		}

		if (!Options.ChatOptions) {
			Options.ChatOptions = t.ChatOptions;
		}
		else {
			for (var y in t.ChatOptions) {
				if (!Options.ChatOptions.hasOwnProperty(y)) {
					Options.ChatOptions[y] = t.ChatOptions[y];
				}
			}
		}

		if (!Options.TowerOptions) {
			Options.TowerOptions = t.TowerOptions;
		}
		else {
			for (var y in t.TowerOptions) {
				if (!Options.TowerOptions.hasOwnProperty(y)) {
					Options.TowerOptions[y] = t.TowerOptions[y];
				}
			}
			for (var y in t.TowerOptions.alertSound) {
				if (!Options.TowerOptions.alertSound.hasOwnProperty(y)) {
					Options.TowerOptions.alertSound[y] = t.TowerOptions.alertSound[y];
				}
			}
		}
		if (!Options.TowerOptions.RecentActivity) { t.resetCityStates(); } // safety!

		for (var cityId in Cities.byID) {
			if (!Options.TowerOptions.towercityactive.hasOwnProperty(cityId)) { // default city alert indicator to ON!
				Options.TowerOptions.towercityactive[cityId] = true;
				saveOptions();
			}

			// if city has ported since citystate set, then reset arrival time to revert actions that were taken...
			if (Options.TowerOptions.SaveCityState[cityId] && Options.TowerOptions.SaveCityState[cityId].tileId != Cities.byID[cityId].tileId) {
				Options.TowerOptions.LatestAttackTimes[cityId] = 0;
			}

		}

//		if (uW.FB) {t.FBAPI = true;};
		t.FBAPI = true; // override to true always (problems on 450?)

		if (t.FBAPI) {
			if (!UserOptions.TokenDomain) { // default token domain to current domain if not already set for user...
				UserOptions.TokenDomain = getServerId();
				saveUserOptions(uW.user_id);
			}
		}

		// do all the initialising here

		MAP_DELAY = Options.MapInterval * 1000;

		anticd.init();
		ChatStuff.init();
		AttackDialog.init();
		ChatTimeFix.init();
		GMTclock.init();
		battleReports.init();
		AllianceReports.init();
		DispReport.init();
		AllianceReportsCheck.init();
		mapinfoFix.init();
		MapDistanceFix.init();
		PageNavigator.init();
		CoordBox.init();
		towho.init();
		cdtd.init();
		LoadCapFix.init();
		TRAetherCostFix.init();
		mmbImageFix.init();
		TowerAlerts.init();
		TreasureChestClick.init();
		KillBox.init();
		FairieKiller.init (Options.KillFairie);
		BarbRaidMarchPatch.init();
		DeleteReports.init();
		BypassMulti.init();
		CollectGold.init();
		FoodAlerts.init();
		ItemMultiUseController.init();
		RaidManager.init();
		ChampLagFix.init();

		if (Options.EnhCBtns && Options.WarnAscension) {
			Tabs.Options.checkAscension();
			clearInterval(t.WarnAscensionTimer);
			t.WarnAscensionTimer = setInterval(function () {
				Tabs.Options.checkAscension();
			}, 60 * 1000);
		};
		t.MiniRefresh();
		CheckRemoveAlert();
		CheckDisableAds();

		if (Options.MoveFurniture) {
			GM_addStyle(t.trstyles);
		}

//		if (UserOptions.EnableEmail) {
//			uW.koc2Mail = uWCloneInto(koc2Mail);
//			koc2Mail.init();
//		}

		if (uW.g_js_strings) {uW.g_js_strings.commonstr.yourScriptVersionIsOut = uW.g_js_strings.checkoutofdate.reloadconfirm;}

		if (Options.amain) {
			if (Options.smain == -1) {
				setTimeout( function (){uW.citysel_click(ById('citysel_'+Number(Number(Options.lmain)+1)));if (popDash) uW.btChangeDashCity(uW.currentcityid);},1000);
			}
			else {
				setTimeout( function (){uW.citysel_click(ById('citysel_'+Number(Number(Options.smain)+1)));if (popDash) uW.btChangeDashCity(uW.currentcityid);},1000);
			}
		}

		if (Options.FixMightDisplay) {
			var ai = document.getElementsByClassName('avatarInfo')[0];
			var al = document.getElementsByClassName('avatarLevel')[0];
			var am = document.getElementsByClassName('avatarMight')[0];
			var ag = document.getElementsByClassName('avatarGlory')[0];
			if (ai) ai.style.marginLeft = '-10px';
			if (al) al.style.display = 'none';
			if (am) am.style.paddingLeft = '0px';
			if (ag) ag.style.paddingLeft = '0px';

			am.innerHTML = '<div class="avatarName"><a id=btMightPop style="font-size:10px;">'+am.innerHTML+'</a></div>';
			ById('btMightPop').addEventListener('click',ShowMightBreakdown);
		}

		if (Options.KillSounds) {
			var killsound = document.getElementsByClassName('sfx_effects')[0];
			if (killsound && killsound.classList.contains("on")) {killsound.click();}
		}
		if (Options.KillMusic) {
			var killmusic = document.getElementsByClassName('sfx_music')[0];
			if (killmusic && killmusic.classList.contains("on")) {uW.AM_pauseMusic();killmusic.click();}
		}

		if (uW.update_march) {
			t.updatemarchfunc = new CalterUwFunc ('update_march', [[/var\s*w\s*=\s*cm.IncomingAttackManager.getAllAttacks/i,'var Dar = seed.queue_atkinc\[o\];Dar.marchStatus = D.marchStatus;RecIncT\(Dar\);var w = cm.IncomingAttackManager.getAllAttacks']]);
			t.updatemarchfunc.setEnable(true);
			uWExportFunction('RecIncT',Tabs.Options.newIncoming);
		};

		if (Options.ClickForReports) {
			var btnrep1 = new CalterUwFunc("modal_messages",[['getHtmlElement())','getHtmlElement());Messages.listReports();']]);
			btnrep1.setEnable(true);
			var btnrep2 = new CalterUwFunc("modal_alliance",[['modal_alliance_init','function() {allianceReports();modal_alliance_changetab(4);}']]);
			btnrep2.setEnable(true);
		}

		var Market = new CalterUwFunc('modal_marketplace', [[/maxlength..\d./gim, '']]);
		Market.setEnable(true); // remove max selling amount in the market!
		var Market2 = new CalterUwFunc('market_resource_maxpossible', [[/g\s*=\s*999000/i, 'g = g']]);
		Market2.setEnable(true); // remove max buy button limit in the market!

		var e = document.createElement('div');
		document.body.appendChild(e);	// NEEDS TO BE VISIBLE FOR ALERT SOUND TO WORK!
		t.mss = new AudioMan();
		if (t.mss) { t.mss.init(e); }

		// create a container for TR Widget

		var e = document.createElement('div');
		e.id = 'btTRWidget';
		ById('mod_maparea').appendChild(e);
		t.SetTRWidgetDisplay();

		if (Options.DraggableWidget) {
			jQuery("#btTRWidget").draggable({ start: function( event, ui) {
												jQuery('#btTRWidget').css({"right":"",});
											}, stop: function( event, ui ) {
												Options.presetPosition = jQuery("#btTRWidget").position();
												saveOptions();
											},
			});
			if (Options.presetPosition) {
		        jQuery('#btTRWidget').css({"left": Options.presetPosition.left + "px","top": Options.presetPosition.top + "px","right":"",});
			}
		}
		else {
			Options.presetPosition = null;
			saveOptions();
		}

		if (Options.DraggableCoords) {
			jQuery("#btCoordsBox").draggable({ stop: function( event, ui ) {
												Options.coordsPosition = jQuery("#btCoordsBox").position();
												saveOptions();
											},
			});
			if (Options.coordsPosition) {
		        jQuery('#btCoordsBox').css({"left": Options.coordsPosition.left + "px","top": Options.coordsPosition.top + "px","right":"",});
			}
		}
		else {
			Options.coordsPosition = null;
			saveOptions();
		}

		// Check for new Language Pack Availability...

		if (LanguageArray.LangVersion) { t.languagestatus = tx('Language pack')+' ('+LanguageArray.CurrLang+') '+tx('Version')+' '+LanguageArray.LangVersion+' '+tx('loaded');}
		else {
			if (Options.Language != 'en') { t.languagestatus = tx('Language pack unavailable'); }
		};
		var now = unixTime();
		if (Options.LanguageLastChecked + (3600*24) < now) { // only check for new lang pack once a day
			t.LoadLanguage(Options.Language);
		}

		if (Options.btEveryToggle) AddSubTabLink('Refresh',t.toggleAutoRefreshState, 'RefreshToggleTab');
		SetToggleButtonState('Refresh',Options.btEveryEnable,'Refresh');

		if (Options.ChatOptions.GloryLeader) { setTimeout(Tabs.Options.CheckGlory,10000,true); } // force check glory after 10 secs
		if (Options.RaidRunning) { t.checkResetRaids(); }
		t.sendDFReport(); // check every refresh

		OpenDiv["Options"] = Options.OpenSettingsDiv;

		setTimeout(function() { RefreshEvery.setEnable (Options.btEveryEnable);t.CheckTokenTimerOverride(); },5*1000); // last one - start refresh cycle in 5 seconds
	},

	SetTRWidgetDisplay : function (e) {
		var e = ById('btTRWidget');
		e.style.position = "absolute";
		if (Options.ThroneHUD) {
			e.style.top = "29px";
			e.style.left = "";
			e.style.right = "228px";
			e.style.width = "";
			e.style.zIndex = 100000;
		}
		else {
			e.style.top = ById('mod_maparea').offsetHeight+6+"px";
			e.style.left = "4px";
			e.style.right = "";
			e.style.width = "";
			e.style.zIndex = 100000;
		}
		Dashboard.PaintTRPresets();
	},

	CheckTokenResponse : function () {
		CheckTokenDay(uW.user_id)
		if (UserOptions.TokenRequest != '') {
			if (UserOptions.TokenRequest == 'TOKEN') {
				UserOptions.LastTokenStatus = UserOptions.TokenResponse;
				if (UserOptions.LastTokenStatus=='OK') {
					if (UserOptions.TokenSuccessLink!="") { UserOptions.TokenLink = UserOptions.TokenSuccessLink; }
					actionLog('Merlin share token collected','TOKENS');
				}
				else { actionLog('Merlin share token collection failed - '+UserOptions.LastTokenStatus,'TOKENS'); }
			}
			if (UserOptions.TokenRequest == 'BUILD') {
				UserOptions.LastBuildStatus = UserOptions.TokenResponse;
				if (UserOptions.LastBuildStatus=="") { UserOptions.LastBuildStatus = 'UNKNOWN'; } // build may not update if user_id not known
				if (UserOptions.LastBuildStatus=='OK') {
					if (UserOptions.TokenSuccessLink!="") { UserOptions.BuildLink = UserOptions.TokenSuccessLink; }
					actionLog('Help token collected','TOKENS');
				}
				else { actionLog('Help token collection failed - '+UserOptions.LastBuildStatus,'TOKENS'); }
			}
			if (UserOptions.TokenRequest == 'CHEST') {
				UserOptions.LastChestStatus = UserOptions.TokenResponse;
				if (UserOptions.LastChestStatus=='OK') { actionLog('Treasure chest token collected','TOKENS'); }
				else { actionLog('Treasure chest token collection failed - '+UserOptions.LastChestStatus,'TOKENS'); }
				if (UserOptions.LastChestStatus=='OK' || UserOptions.LastChestStatus=='USED') {
					if (UserOptions.TokenChestUID != 0) { // remove used link from bank
						for (var c=0;c<UserOptions.TreasureChestBank.length;c++) {
							if (UserOptions.TreasureChestBank[c].feedId==UserOptions.TokenChestFeedId) {
								UserOptions.TreasureChestBank.splice(c, 1);
								break;
							}
						}
						for (var c=0;c<UserOptions.TreasureChestBankOther.length;c++) {
							if (UserOptions.TreasureChestBankOther[c].feedId==UserOptions.TokenChestFeedId) {
								UserOptions.TreasureChestBankOther.splice(c, 1);
								break;
							}
						}
					}
				}
			}
			UserOptions.TokenRequest = '';
			UserOptions.TokenResponse = '';
			UserOptions.TokenSuccessLink = '';
			UserOptions.TokenChestFeedId = 0;
			UserOptions.TokenChestUID = 0;
			saveUserOptions(uW.user_id);
		}
	},

	CheckTokenTimerOverride : function () {
		// check if we need to override the reload timer...
		var CanCollect = false;
		if (GlobalOptions.TokenEnabled && UserOptions.TokenAuto && getServerId()==UserOptions.TokenDomain) {
			// check for token collection
			if (!UserOptions.TokenCollected && UserOptions.TokenLink != "" && UserOptions.TokenLink.search(/merlinshare/i) != -1 && UserOptions.LastTokenStatus == "") {
				CanCollect = true;
			}
			else {
				// check for build collection
				if (!UserOptions.BuildCollected && UserOptions.BuildLink != "" && UserOptions.BuildLink.search(/accepttoken/i) != -1 && UserOptions.LastBuildStatus == "") {
					CanCollect = true;
				}
				else {
					if (!UserOptions.BonusCollected && UserOptions.TreasureChestBankOther.length>0 && UserOptions.TreasureChestBankOther[0].playerId!=uW.tvuid && UserOptions.LastChestStatus == "") {
						CanCollect = true;
					}
					else {
						var DomArray = UserOptions.ChestDomainList.split(",");
						for (var d=0; d < DomArray.length; d++) {
							if (DomArray[d]) {
								if (!UserOptions.ChestCollected[DomArray[d]] && !UserOptions.BadChestDomains[DomArray[d]]) {
									CanCollect = true;
									break;
								}
							}
						}
					}
				}
			}
		}
		if (CanCollect && parseIntNan(UserOptions.OverrideRefresh)!=0) {
			if (!Options.btEveryEnable) { RefreshEvery.setEnable (true); }
			RefreshEvery.NextRefresh = unixTime() + (parseIntNan(UserOptions.OverrideRefresh)*60);
		}
	},

	EverySecond : function () {
		var t = Tabs.Options;
		var now = unixTime();

		/* check tower FIRST!!! */

		t.CheckWatchTower();

		/* check if map drawing event required */

		DrawLevelIcons();

		/* check and send spam */

		if (Options.ChatOptions.SpamActive && Options.ChatOptions.LastSpamSent + (Options.ChatOptions.SpamInterval*60) < now) {
			var spam = String(Options.ChatOptions.SpamText);
			if (spam.charAt(0) == "\\") { // not sure what this is all about, but we'll leave it in.
				spam = spam.slice(1);
				var unicodeString = '';
				for (var i=0; i < spam.length; i++) {
					var theUnicode = spam.charCodeAt(i);
					theUnicode = '&#' + theUnicode+';';
					unicodeString += theUnicode;
				}
				spam = String(unicodeString);
			};
			var spamtype = 'global';
			if (Options.ChatOptions.SpamType == 'a') { spamtype = 'alliance';}
			var spamreason = Options.ChatOptions.SpamInterval+' minutes elapsed';
			if (Options.ChatOptions.LastSpamSent == 0) { spamreason = 'spam activated' }
		    actionLog ('Sending '+spamtype+' spam ('+spamreason+')','SPAM');
			sendChat(String('/' + Options.ChatOptions.SpamType + ' {spam} ' + spam));
			Options.ChatOptions.LastSpamSent = now;
			saveOptions();
		};

		/* check throne room rotation */

		if (Options.DashboardOptions.TRPresetsCycle && Options.DashboardOptions.TRPresetsLastChecked + (Options.DashboardOptions.TRPresetsCycleMins*60) < now) {
			if (afkdetector.isAFK && !Options.TowerOptions.RecentActivity) {
				t.RotateThrone();
			}
			Options.DashboardOptions.TRPresetsLastChecked = now;
			saveOptions();
		}


		t.LoopCounter = t.LoopCounter + 1;

		/* Check gold collect and food alerts every 15 seconds */

		if ((t.LoopCounter % 15) == 1) {
		    if (Options.pbGoldEnable) {
				CollectGold.tick();
			}
		    if (Options.pbFoodAlert) {
				FoodAlerts.tick();
			}
		    if (Options.ChatOptions.GloryLeader) {
				t.CheckGlory(false);
			}
		}

		if (t.LoopCounter >= 60) { // functions for every minute
		    if (Options.AutoMist) { t.CheckMistStatus(); }
			if (Options.StalledMarches) { new fixkabamlag(); }
			if (Options.RaidRunning) { t.checkResetRaids(); }

			// reset the march queue requests, in case the logic has failed
			if (March.currentrequests >= March.maxrequests) { March.currentrequests = 0; }
			if (March.getQueueLength() > 0) { setTimeout(March.loop,0); }

			t.LoopCounter = 0;

			t.sendDFReport();
		}
	},

	CheckMistStatus : function () {
		var t = Tabs.Options;
		var now = unixTime();
		if (Options.AutoMist && afkdetector.isAFK && parseIntNan(Seed.playerEffects.fogExpire) < now) {
			CM.ItemController.usePotionOfMist('10021');
			actionLog('Automatically applying Potion of Mist','GENERAL');
		}
	},

	CheckGlory : function (force) {
		var t = Tabs.Options;
		var aid = getMyAlliance()[0];
		var now = unixTime();

		/* check alliance glory leader */

		if (aid > 0) {
			if ((Options.ChatOptions.GloryLeaderLastChecked + (Options.ChatOptions.GloryLeaderInterval*60) < now) || (Options.ChatOptions.GloryLeaderAID!=aid) || force) {
				actionLog ('Checking alliance glory leader','GENERAL');
				Options.ChatOptions.GloryLeaderAID = aid;
				Options.ChatOptions.GloryLeaderUID = 0;
				Options.ChatOptions.GloryLeaderLastChecked = now;
				saveOptions();
				Tabs.Alliance.totalmembers = 0;
				Tabs.Alliance.alliancemembers = [];
				Tabs.Alliance.error = false;
				Tabs.Alliance.fetchAllianceMemberPage(true,t.SetGloryLeader);
			}
		}
	},

	SetGloryLeader : function() {
		var t = Tabs.Options;
		var glory = 0;
		for (var y in Tabs.Alliance.alliancemembers) {
			if (Tabs.Alliance.alliancemembers[y][6]) {
				if (Tabs.Alliance.alliancemembers[y][9] > glory) {
					Options.ChatOptions.GloryLeaderUID = Tabs.Alliance.alliancemembers[y][6];
					glory = Tabs.Alliance.alliancemembers[y][9];
				}
			}
		}
		saveOptions();
	},

	checkResetRaids : function() {
		var t = Tabs.Options;
		var now = unixTime();
		if (now - Options.RaidLastReset > 3600) { // every hour
			actionLog('Resetting Raid Timers','RAIDS');
			Options.RaidLastReset = now;
			saveOptions();
			for (var g=0;g<Seed.cities.length;g++){
				setTimeout(t.resetRaids, (5000*g), Seed.cities[g][0],Seed.cities[g][1]); // 5 second intervals
			}
		}
	},

	show : function (){
		var t = Tabs.Options;

		m = '<DIV style="max-height:700px; overflow-y:auto;">';
		m += '<div class="divHeader" align="center">'+tx("POWERBOT+ CONFIGURATION")+'</div>';
		m += '<table width=98% align=center>';
		m += '<TR><TD width=25% class=xtab><a id=btResetWindows class="inlineButton btButton brown11"><span>'+tx("Reset ALL window positions!")+'</span></a></td><td align=right class=xtab>'+uW.g_js_strings.commonstr.domain+':</td><td class=xtab><b>'+getServerId()+'</b></td><td align=right class=xtab>'+tx("User Id")+':</td><td class=xtab><b>'+uW.tvuid+'</b></td><td width=25% class=xtab align=right><a id=btResetAll class="inlineButton btButton red14"><span>'+tx("Reset ALL Settings!")+'</span></a></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td class=xtab colspan=4 align=center><span style="font-size:9px;color:#800;">('+tx("options marked with * require a refresh")+')</span></td><td class=xtab align=right>&nbsp;</td></tr>';
		m += '</table>';

		m += '<a id=btGeneralOptionLink class=divLink ><div class="divHeader" align="left"><img id=btGeneralOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("GENERAL SETTINGS (ALL DOMAINS)")+'</div></a>';
		m += '<div id=btGeneralOption class=divHide></div>';

		m += '<a id=btUserOptionLink class=divLink ><div class="divHeader" align="left"><img id=btUserOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("USER SETTINGS")+'</div></a>';
		m += '<div id=btUserOption class=divHide></div>';

		m += '<a id=btPBPOptionLink class=divLink ><div class="divHeader" align="left"><img id=btPBPOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("POWERBOT+ FEATURES")+'</div></a>';
		m += '<div id=btPBPOption class=divHide></div>';

		m += '<a id=btGameOptionLink class=divLink ><div class="divHeader" align="left"><img id=btGameOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("GAME FEATURES")+'</div></a>';
		m += '<div id=btGameOption class=divHide></div>';

		m += '<a id=btFixOptionLink class=divLink ><div class="divHeader" align="left"><img id=btFixOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("GAME FIXES")+'</div></a>';
		m += '<div id=btFixOption class=divHide></div>';

		m += '<a id=btTowerOptionLink class=divLink ><div class="divHeader" align="left"><img id=btTowerOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("WATCHTOWER SETTINGS")+'</div></a>';
		m += '<div id=btTowerOption class=divHide></div>';

		m += '<a id=btDashOptionLink class=divLink ><div class="divHeader" align="left"><img id=btDashOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("DASHBOARD SETTINGS")+'</div></a>';
		m += '<div id=btDashOption class=divHide></div>';

		m += '<a id=btChatOptionLink class=divLink ><div class="divHeader" align="left"><img id=btChatOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("CHAT SETTINGS")+'</div></a>';
		m += '<div id=btChatOption class=divHide></div>';

		m += '<a id=btReportOptionLink class=divLink ><div class="divHeader" align="left"><img id=btReportOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("REPORT SETTINGS")+'</div></a>';
		m += '<div id=btReportOption class=divHide></div>';

		m += '<a id=btTRPresetOptionLink class=divLink><div class="divHeader" align="left"><img id=btTRPresetOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("THRONE ROOM PRESETS")+'</div></a>';
		m += '<div id=btTRPresetOption class=divHide></div>';

		m += '<a id=btTabManagerLink class=divLink ><div class="divHeader" align="left"><img id=btTabManagerArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("TAB MANAGER")+'</div></a>';
		m += '<div id=btTabManager class=divHide></div>';

		m += '<a id=btLanguageLink class=divLink ><div class="divHeader" align="left"><img id=btLanguageArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("LANGUAGE OPTIONS")+'</div></a>';
		m += '<div id=btLanguage class=divHide></div>';

		m += '<a id=btExportLink class=divLink ><div class="divHeader" align="left"><img id=btExportArrow height="10" src="'+RightArrow+'">&nbsp;'+tx("EXPORT AND IMPORT")+'</div></a>';
		m += '<div id=btExport class=divHide><br><TABLE width="100%">';
		m += '<TR><TD class=xtab><input class=btInput id=btResetSettings type=button value="'+tx("Reset Config")+'">&nbsp;<input class=btInput id=btSaveSettings type=button value="'+tx("Save Config")+'">&nbsp;<input class=btInput id=btLoadSettings type=button value="'+tx("Load Config")+'">&nbsp;<input class=btInput id=btLoadSettingsFile type=file></td>';
		m += '<td class=xtab align=right><div class=btInput>'+tx('Copy from')+': <input class=btInput type="text" size=3 maxlength=3 value="'+getServerId()+'" id="pbexport_from"/>&nbsp;'+uW.g_js_strings.commonstr.totx+': <input class=btInput type="text" size=3 maxlength=3 id="pbexport_to" />&nbsp;<input class=btInput type=button value="Go" id="pbexport_submit" />&nbsp;<input type="checkbox" id="pbexport_overwrite" /> '+tx('Force Overwrite')+'</div></td></tr>';
		m += '</table>';
		m += '<div id=pbexport_messages align=center>&nbsp;</div>';
		m += '</table></div><hr>';

		m += '<div align=center>';
		m += '<form style="height:50px;" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">\
				<input type="hidden" name="cmd" value="_s-xclick">\
				<input type="hidden" name="hosted_button_id" value="RZF4UM2DHJB6C">\
				<input type="image" src="https://www.paypalobjects.com/en_US/GB/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal – The safer, easier way to pay online.">\
				<img alt="" border="0" src="https://www.paypalobjects.com/en_GB/i/scr/pixel.gif" width="1" height="1">\
				</form>';
		m += '<br>'+tx('Thank you for the support')+'&nbsp;&nbsp;...&nbsp;&nbsp;Barbarossa.</div>';

		m += '</div><br>';
		t.myDiv.innerHTML = m;

		ById('btSaveSettings').addEventListener ('click',function() {
			var Export = {};
			Export.GlobalOptions = GlobalOptions;
			Export.UserOptions = UserOptions;
			Export.Options = Options;

			uriContent = 'data:application/octet-stream;content-disposition:attachment;filename=file.txt,' + encodeURIComponent(JSON2.stringify(Export));
			t.saveConfig(uriContent,'config_'+getServerId()+'_'+uW.tvuid+'.txt');
		},false);

		ById('btLoadSettings').addEventListener ('click',function() {
			ById('pbexport_messages').innerHTML = '&nbsp;'
			var fileInput = ById("btLoadSettingsFile");
			var files = fileInput.files;
			if (files.length == 0) {
				ById('pbexport_messages').innerHTML = '<span style="color:#800;">'+tx('Please select a config file')+'</span>';
				return;
			}
			var file = files[0];

			var reader = new FileReader();

			reader.onload = function (e) {
				var Import = JSON2.parse(e.target.result);
				GlobalOptions = Import.GlobalOptions;
				UserOptions = Import.UserOptions;
				Options = Import.Options;
				actionLog('Settings file successfully loaded','OPTIONS');
				ReloadKOC();
			};
			reader.readAsText(file);
		},false);

		ById('pbexport_submit').addEventListener ('click',function() {
			ById('pbexport_messages').innerHTML = '&nbsp;'
			var NewServerID = parseIntNan(ById('pbexport_to').value);
			var OldServerID = parseIntNan(ById('pbexport_from').value);
			if(NewServerID == 0 || NewServerID == OldServerID){
				ById('pbexport_messages').innerHTML = '<span style="color:#800;">'+tx('Invalid destination domain number')+'</span>';
				return;
			}
			if(OldServerID == 0){
				ById('pbexport_messages').innerHTML = '<span style="color:#800;">'+tx('Invalid source domain number')+'</span>';
				return;
			}
			var s = GM_getValue ('Options_'+NewServerID+'_'+uW.tvuid);
			if ((s || NewServerID == getServerId()) && !ById('pbexport_overwrite').checked){
				ById('pbexport_messages').innerHTML = '<span style="color:#800;">'+tx('Destination domain configuration already exists - use "Force Overwrite" indicator to overwrite settings')+'</span>';
				return;
			}
			if (OldServerID != getServerId()) {
				s = GM_getValue ('Options_'+OldServerID+'_'+uW.tvuid);
				if (!s) {
					ById('pbexport_messages').innerHTML = '<span style="color:#800;">'+tx('Source domain configuration does not exist')+'</span>';
					return;
				}
				// export/import from s...
				GM_setValue('Options_'+ NewServerID+'_'+uW.tvuid, s);
				if (NewServerID == getServerId()) {
					ResetAll = true;
					actionLog('Powerbot+ configuration imported from '+OldServerID);
					Tabs.ActionLog.save();
					ReloadKOC();
					return;
				}
				else {
					ById('pbexport_messages').innerHTML = tx('PowerBot+ configuration exported from')+' '+OldServerID+' '+tx('to')+' '+NewServerID;
					return;
				}
			}
			else {
				// export from Options...
				GM_setValue ('Options_'+NewServerID+'_'+uW.tvuid, JSON2.stringify(Options));
				ById('pbexport_messages').innerHTML = tx('PowerBot+ configuration exported from')+' '+OldServerID+' '+tx('to')+' '+NewServerID;
				return;
			}
		}, false);

		ById('btResetWindows').addEventListener ('click', function() {t.ResetAllWindows();}, false);
		ById('btResetAll').addEventListener ('click', function() {t.ResetAll();}, false);
		ById('btResetSettings').addEventListener ('click', function() {t.ResetSettings();}, false);

		ById('btGeneralOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btGeneralOption",true,"OpenSettingsDiv")}, false);
		ById('btUserOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btUserOption",true,"OpenSettingsDiv")}, false);
		ById('btTowerOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btTowerOption",true,"OpenSettingsDiv")}, false);
		ById('btDashOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btDashOption",true,"OpenSettingsDiv")}, false);
		ById('btPBPOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btPBPOption",true,"OpenSettingsDiv")}, false);
		ById('btGameOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btGameOption",true,"OpenSettingsDiv")}, false);
		ById('btChatOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btChatOption",true,"OpenSettingsDiv")}, false);
		ById('btReportOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btReportOption",true,"OpenSettingsDiv")}, false);
		ById('btFixOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btFixOption",true,"OpenSettingsDiv")}, false);
		ById('btTRPresetOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btTRPresetOption",true,"OpenSettingsDiv")}, false);
		ById('btTabManagerLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btTabManager",true,"OpenSettingsDiv")}, false);
		ById('btLanguageLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btLanguage",true,"OpenSettingsDiv")}, false);
		ById('btExportLink').addEventListener ('click', function () {ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,"btExport",true,"OpenSettingsDiv")}, false);

		t.PaintGeneralOptions();
		t.PaintUserOptions();
		t.PaintTowerOptions();
		t.PaintPBPOptions();
		t.PaintGameOptions();
		t.PaintFixOptions();
		t.PaintReportOptions();
		t.PaintDashOptions();
		t.PaintChatOptions();
		t.PaintTRPresetOptions();
		t.PaintLanguageOptions();
		t.PaintTabManagerOptions();

		if (!OpenDiv["Options"]) { OpenDiv["Options"] = ""; }
		if (OpenDiv["Options"] != "") {
			var LastOpenDiv = OpenDiv["Options"];
			OpenDiv["Options"] = "";
			ToggleMainDivDisplay("Options",100,GlobalOptions.btWinSize.x,LastOpenDiv,true);
		}
	},

	saveConfig : function (uri, filename) {
		var link = document.createElement('a');
		if (typeof link.download === 'string') {
			document.body.appendChild(link); // Firefox requires the link to be in the body
			link.download = filename;
			link.href = uri;
			link.click();
			document.body.removeChild(link); // remove the link when done
		} else {
			window.open(uri,filename);
		}
	},

	PaintGeneralOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab><INPUT id=btWatchdog type=checkbox /></td><TD colspan=2 class=xtab>'+tx("Refresh if KofC not loaded within 1 minute")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btNoMoreKabam type=checkbox /></td><TD colspan=2 class=xtab>'+tx("Send me away from Kabam!")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btTrackOpen type=checkbox /></td><TD colspan=2 class=xtab>'+tx("Remember window open state on refresh")+'</td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD colspan=2 class=xtab>'+tx("Widescreen Style:")+' '+ htmlSelector({normal:'Normal (100%)', wide:'Wide (1520px)', ultra:'Ultra (1900px)'},GlobalOptions.btWideScreenStyle,'id=btWideScreenStyle')+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD colspan=2 class=xtab>'+tx("PowerBot+ Window Size:")+' '+ htmlSelector({750:'750 pixels', 1000:'1000 pixels', 1250:'1250 pixels'},GlobalOptions.btWinSize.x,'id=btWinSize')+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btShowPowerBar type=checkbox /></td><TD class=xtab>'+tx("Show Powerbar")+'&nbsp;<span style="color:#800;">(EXPERIMENTAL)</span>&nbsp;<span style="font-size:14px;color:#800;">*</span></td>';
		m += '<TD class=xtab><div id=btShowFloatingPowerBar><INPUT id=btFloatingPowerBar type=checkbox />&nbsp;'+tx("Power Bar floats above game screen")+'</div></td></tr>';
		m += '<TR id=btShowPopupPowerBar><TD class=xtab>&nbsp;</td><TD class=xtab>&nbsp;</td><TD class=xtab><INPUT id=btPopupPowerBar type=checkbox />&nbsp;'+tx("Add Popup buttons to Power Bar")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btFloatingDashboard type=checkbox /></td><TD class=xtab>'+tx("Floating Dashboard")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btDashboardToggle type=checkbox /></td><TD class=xtab>'+tx("Dashboard toggle button on main screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td><TD class=xtab><INPUT id=btOverviewDashboardBtn type=checkbox />&nbsp;'+tx("Dashboard Button next to Overview Button")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btInOutToggle type=checkbox /></td><TD class=xtab>'+tx("Incoming/Outgoing toggle buttons on main screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td><TD class=xtab><INPUT id=btMarchPlusToggle type=checkbox />&nbsp;'+tx("March+ toggle button on main screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btBattleToggle type=checkbox /></td><TD class=xtab>'+tx("Battle toggle button on main screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td><TD class=xtab>&nbsp;</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btChatOnRight type=checkbox /></td><TD class=xtab>'+tx("Put chat on right")+'</td>';
		m += '<TD class=xtab><div id=btShowChatBeforeDash><INPUT id=btChatBeforeDash type=checkbox />&nbsp;'+tx("Put chat before dashboard")+'</div></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btWideMap type=checkbox /></td><TD colspan=2 class=xtab>'+tx("Enable wide map expansion button on the map panel")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btTransparent type=checkbox /></td><TD colspan=2 class=xtab>'+tx("Use Transparent Windows")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><td class=xtab><INPUT id=AutoUpdateChk type=checkbox /></td><td colspan=2 class=xtab>'+tx("Automatically check for script updates on")+'&nbsp;<input id=btGC type=radio name=btuploc '+((GlobalOptions.UpdateLocation==0)?'CHECKED':'')+'>SourceForge&nbsp;&nbsp;<input id=btGF type=radio name=btuploc '+((GlobalOptions.UpdateLocation==1)?'CHECKED':'')+'>Greasyfork<span style="display:none;">&nbsp;<input id=btMB type=radio name=btuploc '+((GlobalOptions.UpdateLocation==2)?'CHECKED':'')+'>markbranscombe.com</span>&nbsp;<input id=btMO type=radio name=btuploc '+((GlobalOptions.UpdateLocation==3)?'CHECKED':'')+'>moshimo.eu&nbsp;&nbsp;&nbsp;&nbsp;<a id=btUpdateCheck class="inlineButton btButton brown11"><span>'+tx('Check Now')+'</span></a></td></tr>';
		m += '<TR><td class=xtab><INPUT id=ExtendedDebugChk type=checkbox /></td><td colspan=2 class=xtab>'+tx("Extended debug mode (Activates additional logging)")+'</td></tr>';
		m += '</table>';

		ById('btGeneralOption').innerHTML = m;

		t.togGlobalOpt ('btWatchdog', 'btWatchdog',t.RestartReminder);
		t.togGlobalOpt ('btNoMoreKabam', 'btNoMoreKabam',t.RestartReminder);

		t.changeGlobalOpt ('btWideScreenStyle','btWideScreenStyle',t.RestartReminder);

		ById('btWinSize').addEventListener ('change', function(){
			GlobalOptions.btWinSize.x = parseIntNan(ById('btWinSize').value);
			if (GlobalOptions.btWinSize.x == 0) GlobalOptions.btWinSize.x = 750;
            saveGlobalOptions ();
			t.RestartReminder();
		},false);

		t.togGlobalOpt ('btShowPowerBar', 'btPowerBar',t.RestartReminder);
		t.togGlobalOpt ('btFloatingPowerBar', 'btFloatingPowerBar');
		t.togGlobalOpt ('btPopupPowerBar', 'btPowerBarPopups',t.RestartReminder);
		t.togGlobalOpt ('btFloatingDashboard', 'btFloatingDashboard',WideScreen.RestartDashboard);
		t.togGlobalOpt ('btDashboardToggle', 'DashboardToggle',t.RestartReminder);
		t.togGlobalOpt ('btInOutToggle', 'InOutToggle',t.RestartReminder);
		t.togGlobalOpt ('btBattleToggle', 'BattleToggle',t.RestartReminder);
		t.togGlobalOpt ('btMarchPlusToggle', 'MarchPlusToggle',t.RestartReminder);
		t.togGlobalOpt ('btOverviewDashboardBtn', 'btOverviewDashboardBtn',t.RestartReminder);
		t.togGlobalOpt ('btChatOnRight', 'btChatOnRight',WideScreen.setChatOnRight);
		t.togGlobalOpt ('btChatBeforeDash', 'btChatBeforeDash',WideScreen.chgChatBeforeDash);
		t.togGlobalOpt ('btWideMap', 'btWideMap', WideScreen.useWideMap);
		t.togGlobalOpt ('btTrackOpen', 'btTrackOpen');
		t.togGlobalOpt ('btTransparent', 'btTransparent',t.RestartReminder);

		t.togGlobalOpt ('AutoUpdateChk', 'AutoUpdates');
		t.togGlobalOpt ('ExtendedDebugChk', 'ExtendedDebugMode',t.RestartReminder);
		ById('btUpdateCheck').addEventListener ('click', function() {AutoUpdater.call(true,true);}, false);
		ById('btGC').addEventListener('change', function () {
			if (ById('btGC').checked) { GlobalOptions.UpdateLocation = 0; saveGlobalOptions(); }
		}, false);
		ById('btGF').addEventListener('change', function () {
			if (ById('btGF').checked) { GlobalOptions.UpdateLocation = 1; saveGlobalOptions(); }
		}, false);
		ById('btMB').addEventListener('change', function () {
			if (ById('btMB').checked) { GlobalOptions.UpdateLocation = 2; saveGlobalOptions(); }
		}, false);
		ById('btMO').addEventListener('change', function () {
			if (ById('btMO').checked) { GlobalOptions.UpdateLocation = 3; saveGlobalOptions(); }
		}, false);

	},

	PaintUserOptions : function () {
		var t = Tabs.Options;

		for (var l in UserOptions.CustomPublish) {
			t.PublishLists[l] = UserOptions.CustomPublish[l];
		}

		m = '<TABLE width="100%">';
		m += '<TR><td class=xtab colspan=5><B>FBUID:&nbsp;'+uW.user_id+'&nbsp;</b></td></tr>';
		m += '<TR style="display:none;"><td class=xtab width=30><INPUT disabled id=btEnableEmail type=checkbox '+ (UserOptions.EnableEmail?'CHECKED ':'') + '/></td><TD colspan=4 class=xtab>'+tx("Enable email functionality (Moshimo Koc2Mail App)")+'&nbsp;<span style="font-size:14px;color:#800;">DISABLED</span></span></td></tr>';
		if (t.FBAPI) {
			m += '<TR><td class=xtab width=30><INPUT id=btPubReq type=checkbox '+ (UserOptions.autoPublishGamePopups?'CHECKED ':'') +'/></td><TD colspan=4 class=xtab>'+tx("Auto-publish Facebook posts for")+' '+ htmlSelector(t.PublishLists,UserOptions.autoPublishPrivacySetting,'id=selectprivacymode') +'&nbsp;&nbsp;&nbsp;<span class=divHide><a id=RefreshPublishList>Refresh User Lists</a></span><span id=btCustomListSpan class=divHide>'+tx('Custom List ID')+':&nbsp;<input id=btCustomList type=text class=btInput style="width:115px;" value="' + UserOptions.CustomListId + '">&nbsp;<INPUT class=btInput id=pbFBListHelp type=submit value="'+tx('HELP')+'!"></div></td></tr>';
			m += '<TR><td class=xtab><INPUT id=btCancelReq type=checkbox '+ (UserOptions.autoCancelGamePopups?'CHECKED ':'') + '/></td><TD colspan=4 class=xtab>'+tx("Auto-cancel Facebook posts")+'</td></tr>';
			m += '<TR><td class=xtab colspan=5><B>'+tx("Merlin's Magical Token Options")+'&nbsp;</b></td></tr>';
			m += '<TR><td class=xtab><INPUT id=btTokenEnabled type=checkbox '+ (GlobalOptions.TokenEnabled?'CHECKED ':'') +'/></td><TD colspan=2 class=xtab>'+tx("Enable automatic domain selection")+'&nbsp;&nbsp;<span class=boldRed>('+tx('All Users')+')</span></td></tr>';
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab width=30>'+tx('Domain to receive tokens')+':</td><TD class=xtab><input type=text id=btTokenDomain size=2 maxlength=3 class=btInput value="'+UserOptions.TokenDomain+'"></td><td class=xtab align=right>'+tx('Collected Today')+':</td><td class=xtab width=10><b>'+UserOptions.TokenCount+'</b></td></tr>';
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Substitution domains for Chest links')+':</td><TD class=xtab><input type=text id=btChestDomainList size=47 class=btInput value="'+UserOptions.ChestDomainList+'" title="'+tx('List some domains you do NOT play in here, separated by commas.')+'"></td><td class=xtab align=right>'+tx('Total Owned')+':</td><td class=xtab width=10><b><span id=btTokenNum>&nbsp;</span></b></td></tr>';
			m += '<tr><td class=xtab><img src="'+TokenImage+'" width=30></td><td class=xtab colspan=4><input type=text id=btTokenLink size=100 class=btInput value="'+UserOptions.TokenLink+'" title="'+tx('Store link to ?page=merlinshare URL')+'">&nbsp;<input class=btInput id=btCollectToken type=button value="'+tx("Collect")+'">&nbsp;<span id=btTokenStatus>&nbsp;</span></td></tr>';
			m += '<tr><td class=xtab><img src="'+BuildImage+'" width=30></td><td class=xtab colspan=4><input type=text id=btBuildLink size=100 class=btInput value="'+UserOptions.BuildLink+'" title="'+tx('Store link to ?page=accepttoken URL. Please note each link expires after about a month.')+'">&nbsp;<input class=btInput id=btCollectBuild type=button value="'+tx("Collect")+'">&nbsp;<span id=btBuildStatus>&nbsp;</span></td></tr>';
			m += '<tr><td class=xtab><img src="'+ChestImage+'" width=30></td><td class=xtab colspan=4><input type=text id=btChestLink size=100 class=btInput value="" title="'+tx('Paste treasure chest link URL from Facebook')+'">&nbsp;<input class=btInput id=btCollectChest type=button value="'+tx("Collect")+'">&nbsp;<span id=btStoreChestSpan class=divHide><input class=btInput id=btStoreChest type=button value="'+tx("Store")+'">&nbsp;</span><span id=btChestStatus>&nbsp;</span></td></tr>';
			m += '<TR><td class=xtab><INPUT id=btTokenAuto type=checkbox '+ (UserOptions.TokenAuto?'CHECKED ':'') +'/></td><TD colspan=2 class=xtab>'+tx("Enable automatic token collection during reload cycle")+'</td></tr>';
			m += '<TR><td class=xtab>&nbsp;</td><TD class=xtab>'+tx("Override reload interval to")+' <INPUT id=btOverrideRefresh type=text size=2 maxlength=3 value="'+UserOptions.OverrideRefresh+'" \> '+tx("minutes")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';

			m += '<TR><td class=xtab colspan=5><B>'+tx("Treasure Chest Options")+'&nbsp;</b></td></tr>';
			m += '<TR><td class=xtab><INPUT id=btTreasureChest type=checkbox '+ (UserOptions.TreasureChest?'CHECKED ':'') +'/></td><TD class=xtab colspan=2>'+tx("Auto-click found Treasure Chests")+'</td></tr>';
			m += '<TR><td class=xtab><INPUT id=btChestBank type=checkbox '+ (UserOptions.BankTreasureChests?'CHECKED ':'') +'/></td><TD colspan=2 class=xtab>'+tx("Store Treasure Chest links internally")+'</td></tr>';
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Maximum number of your links to store')+':</td><TD class=xtab><input type=text id=btMaxChestBank size=3 maxlength=5 class=btInput value="'+UserOptions.MaxBankedTreasureChests+'"></td></tr>';
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Your Links')+':&nbsp;<span id=btBankYours></span></td><TD class=xtab colspan=3><input class=btInput id=btUseYourChests type=button value="'+tx("Use Link")+'"><input class=btInput style="width:100px;display:none;" id=btClearYourChests type=button value="'+tx("Remove ALL")+'">&nbsp;<input class=btInput style="width:100px;" id=btPostYourChests type=button value="'+tx("Post to Facebook")+'">&nbsp;<input class=btInput style="width:100px;" id=btExportChests type=button value="'+tx("Export to File")+'">&nbsp;&nbsp;<input class=btInput id=btExportChestsNumber type=text size=3 maxlength=4>&nbsp;'+tx('links')+'</td></tr>';
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Other Links')+':&nbsp;<span id=btBankOthers></span></td><TD class=xtab colspan=3><input class=btInput id=btUseOtherChests type=button value="'+tx("Use Link")+'">&nbsp;<input class=btInput style="width:100px;" id=btClearOtherChests type=button value="'+tx("Remove ALL")+'">&nbsp;<input class=btInput style="width:100px;" id=btImportChests type=button value="'+tx("Import from File")+'">&nbsp;<input class=btInput id=btImportChestsFile type=file></td></tr>';
		}
		m += '</table>';
		m += '<div id=btuser_messages align=center>&nbsp;</div>';

		ById('btUserOption').innerHTML = m;

		if (t.FBAPI) {
			ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
			ById('btBankOthers').innerHTML = '<b>'+UserOptions.TreasureChestBankOther.length+'</b>';

			ById('btTokenNum').innerHTML = parseIntNan(Seed.items.i599);

			if (UserOptions.TokenCollected) { ById('btCollectToken').style.display = 'none'; ById('btTokenStatus').innerHTML = '<span class=boldGreen>'+tx('Collected')+'</span>'; }
			else {
				if (UserOptions.LastTokenStatus != "" && UserOptions.LastTokenStatus != "OK") { ById('btTokenStatus').innerHTML = '<span class=boldRed>'+tx(capitalize(UserOptions.LastTokenStatus))+'</span>'; }
			}
			if (UserOptions.BuildCollected) { ById('btCollectBuild').style.display = 'none'; ById('btBuildStatus').innerHTML = '<span class=boldGreen>'+tx('Collected')+'</span>'; }
			else {
				if (UserOptions.LastBuildStatus != "" && UserOptions.LastBuildStatus != "OK") { ById('btBuildStatus').innerHTML = '<span class=boldRed>'+tx(capitalize(UserOptions.LastBuildStatus))+'</span>'; }
			}
			var bonus = "";
			if (UserOptions.BonusCollected) { bonus = " +1"; }
			var chestcollected = 0;
			var DomArray = UserOptions.ChestDomainList.split(",");
			var chesttotal = DomArray.length;
			for (var d=0; d < DomArray.length; d++) {
				if (DomArray[d]) {
					if (UserOptions.ChestCollected[DomArray[d]]) { chestcollected++; }
				}
			}
			if (chestcollected!=0 || UserOptions.BonusCollected) {
				if (chestcollected >= chesttotal) {
					ById('btChestStatus').innerHTML = '<span class=boldGreen>'+tx('Collected')+' ('+chestcollected+'/'+chesttotal+')'+bonus+'</span>';
					ById('btCollectChest').style.display = 'none';
				}
				else {
					ById('btChestStatus').innerHTML = '<span>('+chestcollected+'/'+chesttotal+')'+bonus+'</span>';
				}
			}
			if (UserOptions.LastChestStatus != "" && UserOptions.LastChestStatus != "OK") { ById('btChestStatus').innerHTML += '&nbsp;<span class=boldRed>'+tx(capitalize(UserOptions.LastChestStatus))+'</span>'; }

			ById('btPubReq').addEventListener('change', function() {
				UserOptions.autoPublishGamePopups = ById('btPubReq').checked;
				if (UserOptions.autoPublishGamePopups) {
					UserOptions.autoCancelGamePopups = false;
					ById('btCancelReq').checked = false;
				}
				saveUserOptions(uW.user_id);
			},false);
			ById('btCancelReq').addEventListener('change', function() {
				UserOptions.autoCancelGamePopups = ById('btCancelReq').checked;
				if (UserOptions.autoCancelGamePopups) {
					UserOptions.autoPublishGamePopups = false;
					ById('btPubReq').checked = false;
				}
				saveUserOptions(uW.user_id);
			},false);
			ById('RefreshPublishList').addEventListener ('click',function(){t.AddUserLists()},false);
			t.changeUserOpt ('btCustomList','CustomListId');
			t.changeUserOpt ('selectprivacymode','autoPublishPrivacySetting',t.ToggleCustomList);
			t.ToggleCustomList();
			ById ('pbFBListHelp').addEventListener ('click', t.helpPop, false);

			t.togGlobalOpt('btTokenEnabled','TokenEnabled'); // GLOBAL!!!!

			t.changeUserOpt ('btTokenDomain','TokenDomain');
			t.togUserOpt('btTokenAuto','TokenAuto');
			ById('btOverrideRefresh').addEventListener('change', function() {
				if (parseIntNan(ById('btOverrideRefresh').value)==0) {
					ById('btOverrideRefresh').value = "";
				}
				UserOptions.OverrideRefresh = ById('btOverrideRefresh').value;
				saveUserOptions(uW.user_id);
				t.RestartReminder();
			},false);

			ById('btChestDomainList').addEventListener ('change', t.DomainListChange, false);
			ById('btChestDomainList').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.DomainListChange); }, false);
			ById('btTokenLink').addEventListener ('change', t.TokenLinkChange, false);
			ById('btTokenLink').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.TokenLinkChange); }, false);
			ById('btBuildLink').addEventListener ('change', t.BuildLinkChange, false);
			ById('btBuildLink').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.BuildLinkChange); }, false);

			ById('btCollectToken').addEventListener('click', function () {
				if (UserOptions.TokenLink != "" && UserOptions.TokenLink.search(/merlinshare/i) != -1) {
					if (GlobalOptions.TokenEnabled){
						UserOptions.TokenRequest = 'TOKEN';
						saveUserOptions(uW.user_id);
					}
					var goto = UserOptions.TokenLink;
					setTimeout (function (){window.top.location = goto;}, 0);
				}
			}, false);
			ById('btCollectBuild').addEventListener('click', function () {
				if (UserOptions.BuildLink != "" && UserOptions.BuildLink.search(/accepttoken/i) != -1) {
					if (GlobalOptions.TokenEnabled){
						UserOptions.TokenRequest = 'BUILD';
						saveUserOptions(uW.user_id);
					}
					var goto = UserOptions.BuildLink;
					setTimeout (function (){window.top.location = goto;}, 0);
				}
			}, false);

			ById('btCollectChest').addEventListener('click', function () {
				if (ById('btChestLink').value != "") {
					if (GlobalOptions.TokenEnabled){
						UserOptions.TokenRequest = 'CHEST';
						saveUserOptions(uW.user_id);
					}
					var goto = ById('btChestLink').value;
					// replace domain in link...
					var DomArray = UserOptions.ChestDomainList.split(",");
					for (var d=0; d < DomArray.length; d++) {
						if (DomArray[d]) {
							if (!UserOptions.ChestCollected[DomArray[d]]) {
								repstring = "=s%3A"+DomArray[d];
								goto = goto.replace(/=s%3A\d\d\d/g,repstring);
								goto = goto.replace(/&s=\d\d\d/g,repstring);
								break;
							}
						}
					}
					setTimeout (function (){window.top.location = goto;}, 0);
				}
			}, false);

			if (trusted) jQuery('#btStoreChestSpan').removeClass("divHide");
			ById('btStoreChest').addEventListener('click', function () {
				if (ById('btChestLink').value != "") {
					var post_link = ById('btChestLink').value;
					if (post_link.indexOf("convert.php?pl=1&ty=3&si=118&")!=-1) {
						var c_tokenId = post_link.slice(post_link.indexOf('%7Cm%3A') + 7, post_link.indexOf('%7Cimg'));
						var c_serverId = post_link.slice(post_link.indexOf('&ex=s%3A') + 8, post_link.indexOf('%7Cf%3A'));
						var c_playerId = post_link.slice(post_link.indexOf('&in=') + 4, post_link.indexOf('&ex=s'));
						var c_feedId = post_link.slice(post_link.indexOf('%7Cf%3A') + 7, post_link.indexOf('%7Cm%3A'));
						if (c_tokenId && c_feedId && c_playerId && c_serverId) {
							if (c_playerId!=uW.tvuid) {
								if (!t.checkFeedId(c_feedId)) {
									UserOptions.TreasureChestBankOther.push({tokenId:c_tokenId, feedId:c_feedId, serverId:c_serverId, playerId:c_playerId, tileName:"", unixTime_taken:unixTime(), link:post_link});
									ById('btChestLink').value = "";
									ById('btuser_messages').innerHTML = tx('Link successfully loaded to Other Links');
									ById('btBankOthers').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
								}
								else { ById('btuser_messages').innerHTML = tx('Link already stored'); }
							}
							else {
								if (!t.checkYourFeedId(c_feedId)) {
									UserOptions.TreasureChestBank.push({tokenId:c_tokenId, feedId:c_feedId, serverId:c_serverId, playerId:c_playerId, tileName:"", unixTime_taken:unixTime(), link:post_link});
									ById('btChestLink').value = "";
									ById('btuser_messages').innerHTML = tx('Link successfully loaded to Your Links');
									ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
								}
								else { ById('btuser_messages').innerHTML = tx('Link already stored'); }
							}
							saveUserOptions(uW.user_id);
						}
						else { ById('btuser_messages').innerHTML = tx('Invalid Treasure Chest link'); }
					}
					else { ById('btuser_messages').innerHTML = tx('Invalid Treasure Chest link'); }
				}
			}, false);

			t.togUserOpt ('btTreasureChest', 'TreasureChest', TreasureChestClick.setEnable, TreasureChestClick.isAvailable);
			t.togUserOpt ('btChestBank', 'BankTreasureChests');
			ById('btMaxChestBank').addEventListener('change', function() {
				UserOptions.MaxBankedTreasureChests = parseIntNan(ById('btMaxChestBank').value);
				ById('btMaxChestBank').value = UserOptions.MaxBankedTreasureChests;
				saveUserOptions(uW.user_id);
			},false);

			ById('btUseYourChests').addEventListener ('click',function() {
				t.CreateLink(true,false);
			},false);

			ById('btUseOtherChests').addEventListener ('click',function() {
				t.CreateLink(false,false);
			},false);

			ById('btPostYourChests').addEventListener ('click',function() {
				var chest = UserOptions.TreasureChestBank.shift();

				var reparr = new Array();
				reparr.push(["REPLACE_TiLeNaMe", chest.tileName]);
				reparr.push(["REPLACE_fEeDiD", chest.feedId]);
				reparr.push(["REPLACE_tOkEnId", chest.tokenId]);
				uW.common_postToProfile("118", reparr);

				saveUserOptions(uW.user_id);
				ById('btuser_messages').innerHTML = tx('Treasure Chest posted to Facebook');
				ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
			},false);

			ById('btClearYourChests').addEventListener ('click',function() {
				UserOptions.TreasureChestBank = [];
				saveUserOptions(uW.user_id);
				ById('btuser_messages').innerHTML = tx('Your Treasure Chest links cleared');
				ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
			},false);

			ById('btClearOtherChests').addEventListener ('click',function() {
				UserOptions.TreasureChestBankOther = [];
				saveUserOptions(uW.user_id);
				ById('btuser_messages').innerHTML = tx('Other Treasure Chest links cleared');
				ById('btBankOthers').innerHTML = '<b>'+UserOptions.TreasureChestBankOther.length+'</b>';
			},false);

			ById('btExportChests').addEventListener ('click',function() {
				var numchests = parseIntNan(ById('btExportChestsNumber').value);
				if (numchests<=0) {
					ById('btuser_messages').innerHTML = '<span style="color:#800;">'+tx('Please enter number of links to export')+'</span>';
					return;
				}
				if (numchests>UserOptions.TreasureChestBank.length) {
					ById('btuser_messages').innerHTML = '<span style="color:#800;">'+tx('Insufficient chests')+'!</span>';
					return;
				}
				var Export = {};
				Export.data = [];
				for (var i=0;i<numchests;i++) {
					var chest = UserOptions.TreasureChestBank.shift();
					Export.data.push(chest);
				}
				saveUserOptions(uW.user_id);
				ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
				uriContent = 'data:application/octet-stream;content-disposition:attachment;filename=file.txt,' + encodeURIComponent(JSON2.stringify(Export));
				t.saveConfig(uriContent,'Chests_'+uW.tvuid+'_'+yyyymmdd(new Date())+'.txt');
			},false);

			ById('btImportChests').addEventListener ('click',function() {
				ById('btuser_messages').innerHTML = '&nbsp;'
				var fileInput = ById("btImportChestsFile");
				var files = fileInput.files;
				if (files.length == 0) {
					ById('btuser_messages').innerHTML = '<span style="color:#800;">'+tx('Please select a link file')+'</span>';
					return;
				}
				var file = files[0];

				var reader = new FileReader();

				reader.onload = function (e) {
					var Import = JSON2.parse(e.target.result);
					var counter = 0;
					if (Import.data) {
						for (var link in Import.data) {
							if (Import.data[link].tokenId && Import.data[link].feedId && Import.data[link].playerId && Import.data[link].serverId) {
								if (Import.data[link].playerId==uW.tvuid) {
									if (!t.checkYourFeedId(Import.data[link].feedId)) {
										counter++;
										UserOptions.TreasureChestBank.push(Import.data[link]);
									}
								}
								else {
									if (!t.checkFeedId(Import.data[link].feedId)) {
										counter++;
										UserOptions.TreasureChestBankOther.push(Import.data[link]);
									}
								}
							}
							else {
								if (Import.data[link].link) {
									var post_link = Import.data[link].link;
									if (post_link.indexOf("convert.php?pl=1&ty=3&si=118&")!=-1) {
										var c_tokenId = post_link.slice(post_link.indexOf('%7Cm%3A') + 7, post_link.indexOf('%7Cimg'));
										var c_serverId = post_link.slice(post_link.indexOf('&ex=s%3A') + 8, post_link.indexOf('%7Cf%3A'));
										var c_playerId = post_link.slice(post_link.indexOf('&in=') + 4, post_link.indexOf('&ex=s'));
										var c_feedId = post_link.slice(post_link.indexOf('%7Cf%3A') + 7, post_link.indexOf('%7Cm%3A'));
										if (c_tokenId && c_feedId && c_playerId && c_serverId) {
											if (c_playerId==uW.tvuid) {
												if (!t.checkYourFeedId(c_feedId)) {
													counter++;
													UserOptions.TreasureChestBank.push({tokenId:c_tokenId, feedId:c_feedId, serverId:c_serverId, playerId:c_playerId, tileName:"", unixTime_taken:unixTime(), link:post_link});
												}
											}
											else {
												if (!t.checkFeedId(c_feedId)) {
													counter++;
													UserOptions.TreasureChestBankOther.push({tokenId:c_tokenId, feedId:c_feedId, serverId:c_serverId, playerId:c_playerId, tileName:"", unixTime_taken:unixTime(), link:post_link});
												}
											}
										}
									}
								}
							}
						}
						ById('btuser_messages').innerHTML = counter+' '+tx('Chest links successfully loaded');
						ById('btBankYours').innerHTML = '<b>'+UserOptions.TreasureChestBank.length+'</b>';
						ById('btBankOthers').innerHTML = '<b>'+UserOptions.TreasureChestBankOther.length+'</b>';
						saveUserOptions(uW.user_id);
					}
					else {
						ById('btuser_messages').innerHTML = '<span style="color:#800;">'+tx('Invalid link file')+'</span>';
					}
				};
				reader.readAsText(file);
			},false);
		}

		t.togUserOpt ('btEnableEmail', 'EnableEmail',t.RestartReminder);
	},

	checkFeedId : function (FeedId) {
		var t = Tabs.Options;
		for (var c=0;c<UserOptions.TreasureChestBankOther.length;c++) {
			if (UserOptions.TreasureChestBankOther[c].feedId==FeedId) {
				return true;
			}
		}
		return false;
	},

	checkYourFeedId : function (FeedId) {
		var t = Tabs.Options;
		for (var c=0;c<UserOptions.TreasureChestBank.length;c++) {
			if (UserOptions.TreasureChestBank[c].feedId==FeedId) {
				return true;
			}
		}
		return false;
	},

	CreateLink : function (yours,auto) {
		var t = Tabs.Options;
		if (yours) { var chest = UserOptions.TreasureChestBank[0]; }
		else { var chest = UserOptions.TreasureChestBankOther[0]; }

		var c_tokenId = chest.tokenId;
		var c_serverId = chest.serverId;
		var c_playerId = chest.playerId;
		var c_feedId = chest.feedId;

		if (!UserOptions.BonusCollected && !yours && c_playerId!=uW.tvuid && !UserOptions.BadChestDomains[getServerId()]) {
			c_serverId = getServerId();
		}
		else {
			var DomArray = UserOptions.ChestDomainList.split(",");
			for (var d=0; d < DomArray.length; d++) {
				if (DomArray[d]) {
					if (!UserOptions.ChestCollected[DomArray[d]]) {
						if (!auto || !UserOptions.BadChestDomains[DomArray[d]]) {
							c_serverId = DomArray[d];
							break;
						}
					}
				}
			}
		}
		var goto = window.location.protocol+'//apps.facebook.com/kingdomsofcamelot/';
		var KabamInstance = (document.URL.search(/kabam.com\/games\/kingdoms-of-camelot\/play/i) >= 0 || document.URL.match(/standalone=1/i));
		if (KabamInstance) goto = window.location.protocol+'//www.kabam.com/games/kingdoms-of-camelot/play';
		goto += '?page=friendFeed'+'&s='+c_serverId+'&in='+c_playerId+'&f='+c_feedId+'&t=118&m='+c_tokenId+'&si=118'+'&token_s='+getServerId();
		if (GlobalOptions.TokenEnabled){
			UserOptions.TokenRequest = 'CHEST';
			UserOptions.TokenChestFeedId = c_feedId;
			UserOptions.TokenChestUID = c_playerId;
		}
		else {
			// auto domain assign not enabled, we need to manually remove the link from the bank.
			if (yours) { UserOptions.TreasureChestBank.splice(0, 1) }
			else { UserOptions.TreasureChestBankOther.splice(0, 1) }
		}
		saveUserOptions(uW.user_id);
		setTimeout (function (){window.top.location = goto;}, 0);
	},

	TokenLinkChange : function () {
		var t = Tabs.Options;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		UserOptions.TokenLink = ById('btTokenLink').value;
		saveUserOptions(uW.user_id);
	},

	BuildLinkChange : function () {
		var t = Tabs.Options;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		UserOptions.BuildLink = ById('btBuildLink').value;
		saveUserOptions(uW.user_id);
	},

	DomainListChange : function () {
		var t = Tabs.Options;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		UserOptions.ChestDomainList = ById('btChestDomainList').value;
		saveUserOptions(uW.user_id);
		t.PaintUserOptions();
	},

	helpPop : function (){
		var t = Tabs.Options;
		var helpText = '<br>'+tx("Publishing Posts to Custom Lists");
		helpText += '<p>'+tx('In Facebook you can create custom lists of friends. Each list has a unique identifier')+'.</p>';
		helpText += '<p>'+tx('Unfortunately the custom lists can no longer be searched for, but you can still publish to just that list if you know the List ID')+'.</p>';
		helpText += '<p>'+tx('If you click on the list, the web address of the list will be displayed in the title bar of the browser. It is in the format')+'<br><br>www.facebook.com/lists/{LISTID}<br><br>'+tx('Copy the {LISTID} number and paste it into the Custom List ID box')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 280, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Facebook Lists")+'</b></center>';
		pop.show (true);
	},

	helpimgPop : function (){
		var t = Tabs.Options;
		var helpText = '<br>'+tx("Previewing Images in Chat");
		helpText += '<p>'+tx('Paste the direct link to the image, NOT the image hosting page!')+'.</p>';
		helpText += '<p>'+tx('Supported image hosting services are as follows')+':-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+tx('Image Host')+'</b></td><TD><b>'+tx('Image Link Example')+'</b></td></tr>';
		helpText += '<TR><TD><a href="http://imgur.com/" target="_blank">imgur.com</a></td><TD>i.imgur.com/XXXX.jpg</td></tr>';
		helpText += '<TR><TD><a href="http://tinypic.com/" target="_blank">tinypic.com</a></td><TD>i99.tinypic.com/XXXX.jpg</td></tr>';
		helpText += '<TR><TD><a href="http://postimage.org/" target="_blank">postimage.org</a></td><TD>s99.postimg.org/YYYY/XXXX.jpg</td></tr>';
		helpText += '<TR><TD><a href="http://giphy.com/" target="_blank">giphy.com</a></td><TD>i.giphy.com/XXXX.gif</td></tr>';
		helpText += '</table><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 280, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Image Previews")+'</b></center>';
		pop.show (true);
	},

	ToggleCustomList : function () {
		var t = Tabs.Options;
		var pub = UserOptions.autoPublishPrivacySetting;
		if (pub==99) { jQuery('#btCustomListSpan').removeClass("divHide"); }
		else { jQuery('#btCustomListSpan').addClass("divHide"); }
	},

	changeRefreshOption: function(tf) {
		var t = Tabs.Options;
		RefreshEvery.setEnable (tf);
		SetToggleButtonState('Refresh',Options.btEveryEnable,'Refresh');
	},

	toggleAutoRefreshState: function(){
		var t = Tabs.Options;
		var obj = ById('btEveryEnable');
		Options.btEveryEnable = !Options.btEveryEnable;
		if (obj) obj.checked = Options.btEveryEnable;
		RefreshEvery.setEnable (Options.btEveryEnable);
		saveOptions();
		SetToggleButtonState('Refresh',Options.btEveryEnable,'Refresh');
	},

	toggleAutoRaidState: function(){
		var t = Tabs.Options;
		var obj = ById('togResetRaids');
		Options.RaidRunning = !Options.RaidRunning;
		saveOptions();
		if (obj) obj.checked = Options.RaidRunning;
		t.ToggleRaidActive();
	},


	PaintTowerOptions : function () {
		var t = Tabs.Options;

		m = '<br><div align=center><table class=xtab width=100%>';
		m += '<TR><TD colspan=2 align=left><b>'+tx("Minimum number of Troops to trigger Tower Alert")+':&nbsp;<INPUT id=pbalertTroops type=text size=7 value="'+ Options.TowerOptions.minTroops +'" \></b>&nbsp;('+tx("Controls All Tower Options")+')<br>&nbsp;</td></tr>';
		m += '</table><TABLE width=98% cellspacing=0 class=xtab><tr><th class=xtabHD align=left>&nbsp;'+uW.g_js_strings.commonstr.city+'</th><th class=xtabHD align=center>'+tx("Active")+'</th><th class=xtabHD align=left>&nbsp;'+tx("WatchTower")+'</th><th class=xtabHD align=left>&nbsp;'+tx("Chat Alert Message")+'</th></tr>';

		for (var cityId in Cities.byID) {
			var wlevel = getUniqueCityBuilding(cityId,14).maxLevel;
			if (wlevel!=0) {wleveltext = 'Level '+wlevel; }
			else {wleveltext = '<span style="color:#800;"><b>None!</b></style>';}
			m+= '<tr><TD><b>'+Cities.byID[cityId].name+'</b></td><td align=center><INPUT id=toweractive_'+cityId+' name='+cityId+' type=checkbox '+(Options.TowerOptions.towercityactive[cityId]?'CHECKED ':'')+'"></TD><td align=left>'+wleveltext+'</td><td align=left><INPUT id=towertext_'+cityId+' name='+cityId+' type=text style="width: 400px;" maxlength=120 value="'+(Options.TowerOptions.towercitytext[cityId]?Options.TowerOptions.towercitytext[cityId]:"")+'"></td></tr>';
		};

		m += '</tr></table></div><br>';

		m += '<TABLE width=100% class=xtab>';
		m += '<TR><TD><INPUT id=pbalertScout type=checkbox '+ (Options.TowerOptions.scouting?'CHECKED ':'') +'/></td><TD>'+tx("Alert when being scouted")+'&nbsp;&nbsp;&nbsp;';
		m += '<INPUT id=pbalertWild type=checkbox '+ (Options.TowerOptions.wilds?'CHECKED ':'') +'/>&nbsp;'+tx("Alert on wilderness attack")+'&nbsp;&nbsp;</td></tr>';
		m += '<TR><TD><INPUT id=pbalertEnable type=checkbox '+ (Options.TowerOptions.aChat?'CHECKED ':'') +'/></td><TD>'+tx("Post incoming attacks to Alliance Chat")+'</td></tr>';
		m += '<TR><td>&nbsp;</td><TD><INPUT id=pbalertWhisper type=checkbox '+ (Options.TowerOptions.whisper?'CHECKED ':'') +'/>&nbsp;'+tx("Whisper to yourself instead, if less than")+'&nbsp;<INPUT id=pbwhisperTroops type=text size=7 value="'+ Options.TowerOptions.whisperTroops +'" \>&nbsp;'+tx("incoming troops")+'</td></tr>';
		m += '<TR><td>&nbsp;</td><TD>'+tx("Chat Message Prefix")+':&nbsp;<INPUT id=pbalertPrefix type=text style="width: 400px;" maxlength=120 value="'+ Options.TowerOptions.aPrefix +'" \></td><tr>';
		m += '<TR><td>&nbsp;</td><TD><INPUT id=pbalertDefend type=checkbox '+ (Options.TowerOptions.defend?'CHECKED ':'') +'/>&nbsp;'+tx("Display your city defend status")+'</td>';
		m += '<TR><td>&nbsp;</td><TD><INPUT id=pbalertTech type=checkbox '+ (Options.TowerOptions.tech?'CHECKED ':'') +'/>&nbsp;'+tx("Display your research information")+'</td>';
		m += '<TR><td>&nbsp;</td><TD><INPUT id=pbalertUpkeep type=checkbox '+ (Options.TowerOptions.upkeep?'CHECKED ':'') +'/>&nbsp;'+tx("Display your city food remaining")+'</td>';
		m += '<TR><td>&nbsp;</td><TD><INPUT id=pbalertDefendMonitor type=checkbox '+ (Options.TowerOptions.DefendMonitor?'CHECKED ':'') +'/>&nbsp;'+tx("Display defender throne monitor link")+'</td>';
		if (uW.koc2Mail) {
			m += '<TR><TD><INPUT id=pbalertemail type=checkbox '+ (Options.TowerOptions.email?'CHECKED ':'') +'/></td><TD>'+tx("Send incoming alerts to Email")+'&nbsp;<span style="color:#800;"><b>**'+tx('Restricted to one email every 10 mins')+'**</b></span></td></tr>';
		}
		m += '<TR><td colspan=2><b>'+tx("Sound Options")+':</b></td></tr>';
		m += '<TR><TD><INPUT id=pbSoundEnable type=checkbox '+ (Options.TowerOptions.alertSound.enabled?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Play sound on incoming attack/scout")+'</td></tr>';
		m += '<TR><TD>&nbsp;</td><TD><DIV id=pbSoundOpts><TABLE cellpadding=0 cellspacing=0 class=xtab>';
		m += '<TR><TD>'+tx("Attack sound")+':&nbsp;</td><TD colspan=2><INPUT id=pbsoundFile type=text size=60 maxlength=1000 value="'+ Options.TowerOptions.alertSound.soundUrl +'" \>&nbsp;</td><TD><INPUT type=button class=btInput value="'+tx("Test")+'" id=pbPlayNow><INPUT id=pbSoundStop type=button class=btInput value="'+tx("Stop")+'"><INPUT id=pbSoundDefault type=button class=btInput value='+tx("Default")+' ></td></tr>';
		m += '<TR><TD>'+tx("Scout sound")+':&nbsp;</td><TD colspan=2><INPUT id=pbscoutFile type=text size=60 maxlength=1000 value="'+ Options.TowerOptions.alertSound.scoutUrl +'" \>&nbsp;</td><TD><INPUT type=button class=btInput value="'+tx("Test")+'" id=pbScoutPlayNow><INPUT id=pbScoutStop type=button class=btInput value="'+tx("Stop")+'"><INPUT id=pbScoutDefault type=button class=btInput value='+tx("Default")+' ></td></tr>';
		m += '<TR><TD>'+tx("Volume")+':&nbsp;</td><TD colspan=2><TABLE cellpadding=0 cellspacing=0 class=xtab><TR valign=middle><TD><SPAN id=pbVolSlider></span></td><TD width=15></td><TD align=right id=pbVolOut>0</td></td></table></td></tr>';
		m += '<TR><TD>&nbsp;</td><TD>Play for <INPUT id=pbSoundLength type=text size=3 maxlength=5 value="'+ Options.TowerOptions.alertSound.playLength +'"> '+tx("seconds")+'</td><TD><INPUT id=pbSoundRepeat type=checkbox '+ (Options.TowerOptions.alertSound.repeat?'CHECKED ':'') +'/>&nbsp;'+tx("Repeat every")+'&nbsp;<INPUT id=pbSoundEvery type=text size=2 maxlength=5 value="'+ Options.TowerOptions.alertSound.repeatDelay +'"> '+tx("minutes")+'</td></tr>';
		m += '</table></div></td></tr>';
		m += '<TR><td colspan=2><b>'+tx("Automatic Event Options")+':</b></td></tr>';
		m += '<TR><TD><INPUT id=pbAFKEvents type=checkbox '+ (Options.TowerOptions.AFKEvents?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Only do the selected actions when AFK (Untick to always do the selected actions)")+'</td></tr>';
		m += '<TR><TD><INPUT id=pbRevert type=checkbox '+ (Options.TowerOptions.Revert?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Revert selected actions back after")+'&nbsp;<INPUT id=pbRevertMinutes type=text size=2 maxlength=2 value="'+ Options.TowerOptions.RevertMinutes +'">&nbsp;'+tx("minutes after the last attack lands")+'&nbsp;<INPUT id=pbResetTower type=button class=btInput value="'+tx("Clear City States")+'"></td></tr>';
		m += '<TR><td colspan=2><b>'+tx("Automatic Events")+':</b></td></tr>';
		m += '<TR><TD><INPUT id=pbChangeTR type=checkbox '+ (Options.TowerOptions.ChangeTR?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Change Throne Room to Preset")+'&nbsp;<INPUT id=pbChangeTRPreset type=text size=2 maxlength=2 value="'+ Options.TowerOptions.ChangeTRPreset +'"></td></tr>';
		m += '<TR><TD><INPUT id=pbChangeGuardian type=checkbox '+ (Options.TowerOptions.ChangeGuardian?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Switch to Wood Guardian in city being attacked")+'</td></tr>';
		m += '<TR><TD><INPUT id=pbStopRaids type=checkbox '+ (Options.TowerOptions.StopRaids?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Suspend Barbarian Raids in city being attacked")+'</td></tr>';
		m += '<TR><TD><INPUT id=pbStopMarches type=checkbox '+ (Options.TowerOptions.StopMarches?'CHECKED ':'') +'/></td><TD colspan=3>'+tx("Suspend ALL automatic marches in city being attacked")+'</td></tr>';
		m += '</table><BR>';

		ById('btTowerOption').innerHTML = m;

		for (var cityId in Cities.byID){
			ById ('toweractive_'+ cityId).addEventListener('click',function(e){Options.TowerOptions.towercityactive[e.target.name] = e.target.checked;saveOptions();},false);
			ById ('towertext_'+ cityId).addEventListener('change',function(e){Options.TowerOptions.towercitytext[e.target.name] = e.target.value;saveOptions();},false);
		}

		t.volSlider = new SliderBar (ById('pbVolSlider'), 200, 21, 0);
		t.volSlider.setValue (Options.TowerOptions.alertSound.volume/100);
		t.volSlider.setChangeListener(t.e_volChanged);
		t.e_volChanged(Options.TowerOptions.alertSound.volume/100);
		t.loadUrl (Options.TowerOptions.alertSound.soundUrl); // preload URL

		ById('pbPlayNow').addEventListener ('click', function (){t.playSound(Options.TowerOptions.alertSound.soundUrl,false,'pbSoundStop')}, false);
		ById('pbSoundStop').addEventListener ('click', t.stopSoundAlerts, false);
		ById('pbSoundStop').disabled = true;

		ById('pbScoutPlayNow').addEventListener ('click', function (){t.playSound(Options.TowerOptions.alertSound.scoutUrl,false,'pbScoutStop')}, false);
		ById('pbScoutStop').addEventListener ('click', t.stopSoundAlerts, false);
		ById('pbScoutStop').disabled = true;

		ById('pbSoundRepeat').addEventListener ('change', function (e){Options.TowerOptions.alertSound.repeat = e.target.checked;saveOptions();}, false);
		ById('pbSoundEvery').addEventListener ('change', function (e){Options.TowerOptions.alertSound.repeatDelay = e.target.value;saveOptions();}, false);
		ById('pbSoundLength').addEventListener ('change', function (e){Options.TowerOptions.alertSound.playLength = e.target.value;saveOptions();}, false);
		ById('pbSoundEnable').addEventListener ('change', function (e){Options.TowerOptions.alertSound.enabled = e.target.checked;saveOptions();}, false);

		if (uW.koc2Mail) {
			ToggleOption('TowerOptions','pbalertemail','email');
		}
		ToggleOption('TowerOptions','pbalertEnable','aChat');
		ToggleOption('TowerOptions','pbalertScout','scouting');
		ToggleOption('TowerOptions','pbalertWild','wilds');
		ToggleOption('TowerOptions','pbalertDefend','defend');
		ToggleOption('TowerOptions','pbalertTech','tech');
		ToggleOption('TowerOptions','pbalertUpkeep','upkeep');
		ToggleOption('TowerOptions','pbalertWhisper','whisper');
		ToggleOption('TowerOptions','pbAFKEvents','AFKEvents');
		ToggleOption('TowerOptions','pbRevert','Revert');
		ToggleOption('TowerOptions','pbChangeTR','ChangeTR');
		ToggleOption('TowerOptions','pbChangeGuardian','ChangeGuardian');
		ToggleOption('TowerOptions','pbStopRaids','StopRaids');
		ToggleOption('TowerOptions','pbStopMarches','StopMarches');

		ChangeOption('TowerOptions','pbalertPrefix','aPrefix');
		ChangeOption('TowerOptions','pbalertTroops','minTroops');
		ChangeOption('TowerOptions','pbwhisperTroops','whisperTroops');
		ChangeOption('TowerOptions','pbRevertMinutes','RevertMinutes');
		ChangeOption('TowerOptions','pbChangeTRPreset','ChangeTRPreset');
		ChangeOption('TowerOptions','pbalertDefendMonitor','DefendMonitor');

		ById('pbResetTower').addEventListener ('click', t.resetCityStates, false);

		ById('pbsoundFile').addEventListener ('change', function (){
			Options.TowerOptions.alertSound.soundUrl = ById('pbsoundFile').value;
			saveOptions();
			t.loadUrl (Options.TowerOptions.alertSound.soundUrl);
		}, false);
		ById('pbSoundDefault').addEventListener ('click', function (){
			Options.TowerOptions.alertSound.soundUrl = DEFAULT_ALERT_SOUND_URL;
			saveOptions();
			ById('pbsoundFile').value = DEFAULT_ALERT_SOUND_URL;
			t.loadUrl (DEFAULT_ALERT_SOUND_URL);
		}, false);

		ById('pbscoutFile').addEventListener ('change', function (){
			Options.TowerOptions.alertSound.scoutUrl = ById('pbscoutFile').value;
			saveOptions();
			t.loadUrl (Options.TowerOptions.alertSound.scoutUrl);
		}, false);
		ById('pbScoutDefault').addEventListener ('click', function (){
			Options.TowerOptions.alertSound.scoutUrl = DEFAULT_SCOUT_SOUND_URL;
			saveOptions();
			ById('pbscoutFile').value = DEFAULT_SCOUT_SOUND_URL;
			t.loadUrl (DEFAULT_SCOUT_SOUND_URL);
		}, false);
	},

	resetCityStates : function () {
		var t = Tabs.Options;
		Options.TowerOptions.RecentActivity = false;
		Options.TowerOptions.LastAttack = 0;
		Options.TowerOptions.HandledMarches = new Array();
		Options.TowerOptions.LatestAttackTimes = {};
		Options.TowerOptions.RecentCityActivity = {};
		Options.TowerOptions.SaveCityState = {};
		Options.TowerOptions.SaveTR = 0;
		saveOptions();
	},

	loadUrl : function (url) {
		var t = Tabs.Options;
		if (t.mss) { t.mss.setSource(url); }
	},

	PaintFixOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab><INPUT id=ptEnableMiniRefresh type=checkbox ' + (Options.MiniRefresh ? 'CHECKED ' : '') + '/></td><TD class=xtab>&nbsp;'+tx("Refresh Data/Marches every");
		m += '<INPUT id=ptMiniRefreshInterval type=text size=3 value="' + Options.MiniRefreshInterval + '">&nbsp;'+tx("minutes")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChampLagFix type=checkbox /></td><TD class=xtab>'+tx("Fix delay when opening Castle, Rally Point and Boss Battle")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togTowerFix type=checkbox /></td><TD class=xtab>'+tx("Fix tower alert to show exact target (city or wild)")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togKnightSelect type=checkbox /></td><TD class=xtab>'+tx("Do not automatically select a knight when changing march type to Scout, Transport or Reassign")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togFilterTroopsFix type=checkbox /></td><TD class=xtab>'+tx("Don't filter troop types for transport")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togAllowMulti type=checkbox /></td><TD class=xtab>'+tx("Disable multi-browser check (use with caution)")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togRaidPatch type=checkbox /></td><TD class=xtab>'+tx("Fix stuck raid marches")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togStalledMarches type=checkbox /></td><TD class=xtab>'+tx("Fix stalled marches and missing knights")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togCoordBox type=checkbox /></td><TD class=xtab>'+tx("Keep map coordinate box/bookmarks on top of troop activity")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMapInfo2 type=checkbox /></td><TD class=xtab>'+tx("Add reassign button when clicked on own city")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMapInfo type=checkbox /></td><TD class=xtab>'+tx("Fix reassign button on maptile info")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMapInfo3 type=checkbox /></td><TD class=xtab>'+tx("Include player name / city name in new bookmarks")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togLoadCapFix type=checkbox /></td><TD class=xtab>'+tx("Limit load capacity to not exceed throne room load cap")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togTRAetherCostFix type=checkbox /></td><TD class=xtab>'+tx("Fix display of aetherstones for throne room upgrade/enhance")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMMBImageFix type=checkbox /></td><TD class=xtab>'+tx("Post correct image to facebook for Merlin Box")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatTimeFix type=checkbox /></td><TD class=xtab>'+tx("Always show local time on chat posts")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=togMoveFurniture type=checkbox /></td><td class=xtab>'+tx("Rearrange throne room furniture for better visibility")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><td class=xtab><INPUT id=togFixMightDisplay type=checkbox /></td><td class=xtab>'+tx("Fix might display on main screen")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptkillmusic type=checkbox /></td><TD class=xtab>'+tx("Kill music on startup")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptkillsounds type=checkbox /></td><TD class=xtab>'+tx("Kill sound effects on startup")+'</td></tr>';
		m += '</table>';

		ById('btFixOption').innerHTML = m;

		ById('ptEnableMiniRefresh').addEventListener('change', t.MiniRefreshChanged, false);
		ChangeIntegerOption('','ptMiniRefreshInterval','MiniRefreshInterval',3,t.MiniRefresh);

		ToggleOption('','togTowerFix', 'fixTower', TowerAlerts.enableFixTarget, TowerAlerts.isFixTargetAvailable);
		ToggleOption('','togKnightSelect', 'fixKnightSelect', AttackDialog.setEnable, AttackDialog.isAvailable);
		ToggleOption('','togFilterTroopsFix', 'DontFilterTransportTroops', AttackDialog.setEnable, AttackDialog.isAvailable);
		ToggleOption('','togRaidPatch', 'RaidPatch', BarbRaidMarchPatch.setEnable, BarbRaidMarchPatch.isAvailable);
		ToggleOption('','togStalledMarches', 'StalledMarches');
		ToggleOption('','togAllowMulti', 'AllowMultiBrowser', BypassMulti.setEnable, BypassMulti.isAvailable);
		ToggleOption('','togCoordBox', 'mapCoordsTop', CoordBox.setEnable, CoordBox.isAvailable);
		ToggleOption('','togMapInfo2', 'mapInfo2', mapinfoFix.setEnable2, mapinfoFix.isAvailable2);
		ToggleOption('','togMapInfo', 'mapInfo', mapinfoFix.setEnable, mapinfoFix.isAvailable);
		ToggleOption('','togMapInfo3', 'mapInfo3', mapinfoFix.setEnable3, mapinfoFix.isAvailable3);
		ToggleOption('','togLoadCapFix', 'fixLoadCap', LoadCapFix.setEnable, LoadCapFix.isAvailable);
		ToggleOption('','togTRAetherCostFix', 'fixTRAetherCost', TRAetherCostFix.setEnable, TRAetherCostFix.isAvailable);
		ToggleOption('','togMMBImageFix', 'fixMMBImage', mmbImageFix.setEnable, mmbImageFix.isAvailable);
		ToggleOption('','togChatTimeFix', 'fixChatTime', ChatTimeFix.setEnable, ChatTimeFix.isAvailable);
		ToggleOption('','togChampLagFix', 'FixCastleLag', ChampLagFix.setEnable, ChampLagFix.isAvailable);
		ToggleOption('','togMoveFurniture', 'MoveFurniture',t.RestartReminder);
		ToggleOption('','togFixMightDisplay', 'FixMightDisplay',t.RestartReminder);
		ToggleOption('','ptkillmusic', 'KillMusic');
		ToggleOption('','ptkillsounds', 'KillSounds');
	},

	PaintReportOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab colspan=2><B>'+tx("Alliance Report Scanner")+':</b></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togEnhanceAR type=checkbox /></td><TD class=xtab>'+tx("Enable scanning of Alliance Reports")+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab><TABLE>';
		m += '<TR><TD class=xtab colspan=3>'+tx("Scan interval")+': <INPUT id=ptalertinterval type=text size=3 value=' + Options.ReportOptions.alertinterval + ' /> '+tx("seconds")+'</td></tr>';
		m += '<TR><TD class=xtab colspan=3><INPUT id=ptincomingar type=checkbox ' + (Options.ReportOptions.PostIncoming ? 'CHECKED ' : '') + '/>'+tx("Scan incoming attack reports")+'</td></tr>';
		m += '<TR><TD class=xtab width=50>&nbsp;</td><TD class=xtab colspan=2>'+tx("Min troops")+': <INPUT id=ptalertmtroops type=text size=6 value=' + Options.ReportOptions.alertmtroops + ' /></TD></TR>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><INPUT id=ptwhisperar type=checkbox ' + (Options.ReportOptions.WhisperAR ? 'CHECKED ' : '') + '/>'+tx("Whisper incoming attack reports to yourself and the following players (separated by commas)")+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td class=xtab width=50>&nbsp;</td><td class=xtab><INPUT id=ptwhisperarlist type=text size=70 value="' + Options.ReportOptions.WhisperARList + '"></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><INPUT id=ptnoduplicatereports type=checkbox ' + (Options.ReportOptions.NoDuplicateReports ? 'CHECKED ' : '') + '/>'+tx("Do not post reports already posted by another alliance member")+'&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#800;"><b>(WORK IN PROGRESS)</b></span></td></tr>';
		m += '<TR><TD class=xtab colspan=3><INPUT id=ptwhisperoutgoing type=checkbox ' + (Options.ReportOptions.WhisperOutgoing ? 'CHECKED ' : '') + '/>'+tx("Whisper your own outgoing attack reports to yourself")+'</td></tr></table></td></tr>';

		m += '<TR><TD class=xtab colspan=2><B>'+tx('Automatic Report Deletion')+':</b></td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbdeletebctoggle type=checkbox /></td><TD class=xtab> '+tx("Delete barbarian camp reports/Transport reports from you")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbdeletetrtoggle type=checkbox /></td><TD class=xtab> '+tx("Delete transport reports to you")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbdeletewltoggle type=checkbox /></td><TD class=xtab> '+tx("Delete wilderness reports")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbdeleteaatoggle type=checkbox /></td><TD class=xtab> '+tx("Delete auto-attack reports (and log items for attack summary)")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbdeletedftoggle type=checkbox /></td><TD class=xtab> '+tx("Delete dark forest reports (and log items for DF summary)")+'</td></tr>';
		m += '<tr><td class=xtab>&nbsp;</td><td class=xtab><INPUT id=pbdfreport type=checkbox '+ (Options.DFReport?' CHECKED':'') +'\>&nbsp;'+tx("Send DF report every")+'&nbsp;<INPUT id=pbdfreportinterval value='+ Options.DFReportInterval +' type=text size=3 \>&nbsp;'+tx('hours')+'&nbsp;&nbsp;&nbsp;'+strButton8(tx('Send Now'), 'id=pbdfreportsend')+'</td></tr>';
		if (uW.koc2Mail) {
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab><INPUT id=pbdfreportemail type=checkbox '+ (Options.DFReportEmail?' CHECKED':'') +'\>&nbsp;'+tx("CC to Email")+'</td></tr>';
		}
		m += '<TR><TD class=xtab><INPUT id=pbdeletesctoggle type=checkbox /></td><TD class=xtab> '+tx("Delete ALL incoming scout reports")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbdeletefrtoggle type=checkbox /></td><TD class=xtab> '+tx("Delete incoming attack/scout reports from friendly alliances")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbdeleteidtoggle type=checkbox /></td><TD class=xtab> '+tx("Delete incoming")+' '+htmlSelector({0:tx("attack/scout"),4:tx("attack"),3:tx("scout")},Options.ReportOptions.DeleteRptidType,"id=pbdeleteidtype class=btInput")+' '+tx("reports from the following UIDs (separated by commas)")+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab><input id=pbdeleteuidreps type=text size=100 /></td></tr>';
		m += '</table>';

		ById('btReportOption').innerHTML = m;

		ToggleOption('ReportOptions','togEnhanceAR', 'EnhanceAR', AllianceReportsCheck.enable);
		ToggleOption('ReportOptions','ptincomingar', 'PostIncoming');
		ToggleOption('ReportOptions','ptwhisperoutgoing', 'WhisperOutgoing');
		ToggleOption('ReportOptions','ptwhisperar', 'WhisperAR');
		ToggleOption('ReportOptions','pbdeletebctoggle', 'DeleteRptbc');
		ToggleOption('ReportOptions','pbdeletetrtoggle', 'DeleteRpttr');
		ToggleOption('ReportOptions','pbdeletewltoggle', 'DeleteRptwl');
		ToggleOption('ReportOptions','pbdeleteaatoggle', 'DeleteRptaa');
		ToggleOption('ReportOptions','pbdeletefrtoggle', 'DeleteRptfr');
		ToggleOption('ReportOptions','pbdeleteidtoggle', 'DeleteRptid');
		ToggleOption('ReportOptions','pbdeletedftoggle', 'DeleteRptdf');
		ToggleOption('ReportOptions','pbdeletesctoggle', 'DeleteRptsc');

		ChangeOption('ReportOptions','ptalertinterval', 'alertinterval');
		ChangeOption('ReportOptions','ptalertmtroops', 'alertmtroops');
		ChangeOption('ReportOptions','ptwhisperarlist', 'WhisperARList');
		ChangeOption('ReportOptions','pbdeleteuidreps', 'DeleteRptUID');
		ChangeOption('ReportOptions','pbdeleteidtype', 'DeleteRptidType');
		ChangeOption('ReportOptions','ptnoduplicatereports', 'NoDuplicateReports');

        ById('pbdfreportinterval').addEventListener('keyup', function () {
            if (isNaN(ById('pbdfreportinterval').value) || ById('pbdfreportinterval').value<1) { ById('pbdfreportinterval').value = 1; }
            Options.DFReportInterval = ById('pbdfreportinterval').value;
            saveOptions();
			t.sendDFReport();
        }, false);
        ById('pbdfreportsend').addEventListener('click', function () {
            Options.LastDFReport = 0;
            saveOptions();
			t.sendDFReport();
        }, false);
		ToggleOption('','pbdfreport','DFReport',t.sendDFReport);
		if (uW.koc2Mail) {
			ToggleOption('','pbdfreportemail','DFReportEmail');
		}
	},

	PaintDashOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab><INPUT id=btShowDashboard type=checkbox /></td><TD class=xtab>'+tx("Show Dashboard")+'</td></tr>';
		m += '<TR><td class=xtab width=30><INPUT id=UpperDefChk type=checkbox /></td><td class=xtab width=300>'+tx("Overview defend button")+'</td><td class=xtab width=30><INPUT id=LowerDefChk type=checkbox /></td><td class=xtab>'+tx("Troops defend button")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=PresetChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Show throne room preset changer")+'</td></tr>';
		m += '<TR id=btPresetByNameOpts class="divHide"><td class=xtab><INPUT id=TRPresetByNameChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Select presets by name")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=GraphChampChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Graphical champion selector")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=QuickSacChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Show quick sacrifice icons")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=DefaultSacChk type=checkbox /></td><td class=xtab>'+tx("Default sacrifice duration")+'</td>';
		m += '<TD class=xtab colspan="2"><span id=btSacOpts class="divHide"><INPUT class="btInput" style="width: 30px;text-align:right;" id="btDefaultRitualMinutes" type=text maxlength=4 value="'+Options.DashboardOptions.DefaultSacrificeMin+'" onkeyup="btCheckDefaultRitual(this)">&nbsp;'+uW.g_js_strings.timestr.timemin+'&nbsp;';
		m +='<INPUT class="btInput" style="width: 15px;text-align:right;" id="btDefaultRitualSeconds" type=text maxlength=2 value="'+Options.DashboardOptions.DefaultSacrificeSec+'" onkeyup="btCheckDefaultRitual(this)">&nbsp;'+uW.g_js_strings.timestr.timesec+'</span></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab>'+tx("Maximum troops to sacrifice")+'</td><TD class=xtab colspan="2"><INPUT class="btInput" style="text-align:right;" id="btSacrificeLimit" type=text size=13 maxlength=11 value="'+Options.DashboardOptions.SacrificeLimit+'">&nbsp;'+tx("troops")+'</td></tr>';

		if (SelectiveDefending) {
			m += '<TR><td class=xtab><INPUT id=DefSetFirst type=checkbox /></td><td colspan="3" class=xtab>'+tx("Show Assign Defenders section above Troop Display")+'</td></tr>';
			m += '<TR><td class=xtab><INPUT id=DefAddTroopChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Show defence add troops")+'</td></tr>';
			m += '<TR id=btDefOpts class="divHide"><TD class=xtab>&nbsp;</td><TD class=xtab>'+tx("Default add defence amount")+'</td><TD class=xtab colspan="2"><INPUT class="btInput" style="text-align:right;" id="btDefaultDefenceNum" type=text size=13 maxlength=11 value="'+Options.DashboardOptions.DefaultDefenceNum+'">&nbsp;'+tx("troops")+'</td></tr>';
			m += '<TR><td class=xtab><INPUT id=DefPresetChk type=checkbox /></td><td colspan="3" class=xtab>'+tx("Show defensive presets")+'</td></tr>';
		}

		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab colspan=4><table cellSpacing=0 width=98%>';
		m += '<TR><TD style="width:20px" class=xtabHD>'+tx("Show")+'</td><TD style="width:100px" class=xtabHD>'+tx("Section")+'</td><TD class=xtabHD>'+tx("Sequence")+'</td><TD class=xtabHD align=right><a id=btResetDash class="inlineButton btButton brown11"><span>'+tx("Reset")+'</span></a></td></tr>';

		for (var p in Dashboard.DefaultDashboard) {
			var NewObj = {};
			if (Options.DashboardOptions.OverrideDashboard[p]) {
				NewObj.Display = Options.DashboardOptions.OverrideDashboard[p].Display;
				NewObj.Sequence = Options.DashboardOptions.OverrideDashboard[p].Sequence;
			}
			else {
				NewObj.Display = Dashboard.DefaultDashboard[p].Display;
				NewObj.Sequence = Dashboard.DefaultDashboard[p].Sequence;
			}
			NewObj["name"] = p;

			m += '<tr>';
			m +='<TD style="width:20px" class="xtab"><INPUT id="dashDisp'+NewObj["name"]+'" type=checkbox '+(NewObj["Display"]?'CHECKED':'')+' onclick="btOverrideDash(\''+NewObj["name"]+'\')" /></td>';
			m += '<TD class=xtab>'+tx(NewObj["name"])+'</td>';
			m += '<TD class=xtab><INPUT class="btInput" id="dashSeq'+NewObj["name"]+'" style="width:30px;" maxlength=3 type=text value="'+NewObj["Sequence"]+'" onkeyup="btOverrideDash(\''+NewObj["name"]+'\')" /></td>';
			m += '<td class=xtab>&nbsp;</td></tr>';
		}
		m += '</table></td></tr>';
		m += '</table>';

		ById('btDashOption').innerHTML = m;

		ById('btResetDash').addEventListener ('click', function() {t.ResetDash();}, false);

		ToggleOption('','btShowDashboard', 'btDashboard',WideScreen.setDashboard); // options, not dash options...

		ToggleOption('DashboardOptions','UpperDefChk', 'UpperDefendButton');
		ToggleOption('DashboardOptions','LowerDefChk', 'LowerDefendButton');
		ToggleOption('DashboardOptions','PresetChk', 'TRPresetChange', t.PresetToggle);
		t.PresetToggle();

		if (SelectiveDefending) {
			ToggleOption('DashboardOptions','DefSetFirst', 'SetDefendersFirst', WideScreen.RestartDashboard);
			ToggleOption('DashboardOptions','DefAddTroopChk', 'DefAddTroopShow', t.DefToggle);
			t.DefToggle ();
			ToggleOption('DashboardOptions','DefPresetChk', 'DefPresetShow');
			ChangeIntegerOption('DashboardOptions','btDefaultDefenceNum','DefaultDefenceNum');
		}

		ToggleOption('DashboardOptions','QuickSacChk', 'QuickSacrifice',Dashboard.PaintQuickSac);
		ToggleOption('DashboardOptions','DefaultSacChk', 'DefaultSacrifice', t.SacToggle);
		t.SacToggle();

		ToggleOption('DashboardOptions','TRPresetByNameChk', 'TRPresetByName');
		ToggleOption('DashboardOptions','GraphChampChk', 'GraphicalChampDisplay');

		ChangeIntegerOption('DashboardOptions','btSacrificeLimit','SacrificeLimit');
	},

	PaintTRPresetOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><table cellSpacing=0 width=98%>';
		m += '<TR><TD style="width:20px" class=xtabHD>'+tx('Num')+'</td><TD style="width:150px;" class=xtabHD>'+uW.g_js_strings.commonstr.nametx+'</td><TD class=xtabHD colspan=2>'+uW.g_js_strings.commonstr.select+'</td></tr>';

		for (var i=1;i<=Seed.throne.slotNum;i++) {
			m += '<tr>';
			m +='<TD style="width:20px" id="trpresetopt'+i+'" class="xtab trimg" style="padding-right: 0px;"><a style="text-decoration:none;"><div id="trpresetoptdiv'+i+'" class="presetBut presetButNon"><center>'+i+'</center></div></a></td>';
			m += '<TD class=xtab><INPUT class="btInput" id="btpresetLabel'+i+'" style="width:120px;" maxlength=15 type=text value="'+(Options.DashboardOptions.TRPresets[i]?Options.DashboardOptions.TRPresets[i].name:'Preset '+i)+'" onkeyup="btStartKeyTimer(this,btUpdatePresetLabel,'+i+')" onchange="btUpdatePresetLabel(this,'+i+')" /></td>';
			m += '<TD class=xtab colspan=2><INPUT type=checkbox id="btpresetSelect'+i+'" '+(Options.DashboardOptions.TRPresetsSelected[i]?'CHECKED':'')+' onclick="btToggleTRPreset('+i+')" /></td>';
			m += '</tr>';
		}
		m += '<tr><TD class=xtab style="width:20px"><INPUT type=checkbox id="btpresetCycle" '+(Options.DashboardOptions.TRPresetsCycle?'CHECKED':'')+' /></td><td class=xtab colspan=2>'+tx('Cycle through selected presets when AFK, every')+' '+'<INPUT id=btpresetCycleMins type=text size=2 value="' + Options.DashboardOptions.TRPresetsCycleMins + '">&nbsp;'+tx('minutes')+'</td>';
		if (uW.tcoPresetNames) { m += '<td class=xtab align=right><a id=btCopyTCOPresets>'+tx('Copy Preset Names from Throne/Champ')+'</a></td>'; }
		m += '</tr>';

		m += '</table></td></tr>';
		m += '</table>';

		ById('btTRPresetOption').innerHTML = m;

		ToggleOption('DashboardOptions','btpresetCycle', 'TRPresetsCycle');
		ChangeIntegerOption('DashboardOptions','btpresetCycleMins','TRPresetsCycleMins',1);

		if (ById('btCopyTCOPresets')) {
			ById('btCopyTCOPresets').addEventListener('click',function () {
				for (var i=1;i<=Seed.throne.slotNum;i++) {
					var PresetName = uW.tcoPresetNames[i];
					if (PresetName && PresetName != "" && PresetName != "undefined") {
						ById('btpresetLabel'+i).value = uW.tcoPresetNames[i].substring(0, 15);
						Dashboard.UpdatePresetLabel(ById('btpresetLabel'+i),i);
					}
				}
				saveOptions();
			},false);
		}
		Dashboard.PaintTRPresets();
	},

	PaintChatOptions : function () {
		var t = Tabs.Options;
		m = '<TABLE width="100%">';

		m += '<TR><TD class=xtab><INPUT id=togChatStuff type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enable Chat Enhancements (Clickable Co-ords, Click on Icon to Whisper, Colours, Emoticons)")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=CFilter type=checkbox /></td><TD class=xtab>'+tx("Beat Kabam chat filter so words such as \'deSCRIPTion\' can be typed")+'</td><td width=50% class=xtab>'+tx('Replacement Char')+' :&nbsp;<select id=pbfilter>';
		for(c in Filter) {
			if(c == Options.ChatOptions.fchar)
				m+='<option value='+c+' selected="selected">'+c+' ('+Filter[c]+')</option>';
			else
				m+='<option value='+c+'>'+c+' ('+Filter[c]+')</option>';
		};
        m += '</select></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatIcon type=checkbox /></td><TD class=xtab>'+tx("Show Facebook profile picture in chat instead of avatar")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatEmoticons type=checkbox /></td><TD class=xtab>'+tx("Show emoticons in chat")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatImages type=checkbox /></td><TD class=xtab colspan=2>'+tx("Show linked image previews in chat")+'&nbsp;<INPUT class=btInput id=pbIMGLinkHelp type=submit value="'+tx('HELP')+'!"></td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbHelpRequest type=checkbox /></td><TD class=xtab>'+tx("Help alliance build/research posts")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbDeleteRequest type=checkbox /></td><TD class=xtab>'+tx("Hide alliance requests in chat")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbDeleteFood type=checkbox /></td><TD class=xtab colspan=2>'+tx("Hide alliance food alerts in chat from user names")+'&nbsp;<input id=pbDelFoodUsers type=text size=40 />&nbsp;('+tx('leave blank for all users')+')</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbDeletegAl type=checkbox /></td><TD class=xtab>'+tx("Hide alliance chat from global chat")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbDeleteGlobalSpam type=checkbox /></td><TD class=xtab>'+tx("Hide spam messages from global chat")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbDeleteAllianceSpam type=checkbox /></td><TD class=xtab>'+tx("Hide spam messages from alliance chat")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togEnableTowerAlert type=checkbox /></td><TD class=xtab>'+tx("Enable sound alert on alliance tower alerts")+'</td><TD width=50% class=xtab>' + htmlSelector({
				allianceattack: 'Alert Sound 1',
				alert: 'Alert Sound 2',
				airraid: 'Air Raid Siren',
			}, Options.ChatOptions.TowerPlay, 'id=btTowerPlay') + '&nbsp;<a id=btTestTowerSound class="inlineButton btButton blue14"><span>Test</span></a></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togEnableWhisperAlert type=checkbox /></td><TD class=xtab>'+tx("Enable sound alert on whisper")+'</td><TD width=50% class=xtab>' + htmlSelector({
				timeout: 'Arrow',
				monitor: 'Doorbell',
			}, Options.ChatOptions.WhisperPlay, 'id=btWhisperPlay') + '&nbsp;<a id=btTestWhisperSound class="inlineButton btButton blue14"><span>Test</span></a></td></tr>';
		m += '<tr id=ptSoundOpts class="divHide"><td class=xtab>&nbsp;</td><TD class=xtab colspan=2><div><TABLE cellpadding=0 cellspacing=0><TR valign=middle><TD class=xtab>'+tx('Chat sounds volume')+'&nbsp;</td><TD class=xtab><SPAN id=ptVolSlider></span></td><TD class=xtab align=right id=ptVolOut style="width:30px;">0</td></tr></table></div></tr>';
		m += '</table>';
		m += '<TABLE><TR><TD class=xtab colspan=3><br><B>'+tx("Chat Spam")+'&nbsp;</b></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbspamactive type=checkbox /></td><TD class=xtab>'+tx("Spam Enabled")+'</td><TD class=xtab>' + htmlSelector({
				g: 'Send to Global Chat',
				a: 'Send to Alliance Chat'
			}, Options.ChatOptions.SpamType, 'id=pbspamtype') + '</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab>'+tx("Spam Interval")+':</td><TD class=xtab><INPUT id=pbspaminterval type=text size=3 value=' + Options.ChatOptions.SpamInterval + ' /> '+tx("minutes")+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><TD style="vertical-align:top" class=xtab>'+tx("Spam Text")+':</td><TD class=xtab><textarea id=pbspamtext rows=3 cols=40 onkeyup="ptStopProp(event);">'+Options.ChatOptions.SpamText+'</textarea></td></tr>';
		m += '</table>';
		m += '<TABLE><TR><TD class=xtab colspan=3><B>'+tx("Chat Colours")+'&nbsp;</b></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatGlory type=checkbox /></td><TD class=xtab>'+tx("Highlight Alliance Glory Leader")+'</td><TD colspan=2 class=xtab>'+tx("Check every")+'&nbsp;<INPUT id=pbglorycheck type=text size=2 value="' + Options.ChatOptions.GloryLeaderInterval + '">&nbsp;'+tx('minutes')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatRainbow type=checkbox /></td><TD class=xtab colspan=2>'+tx("Display your own messages with a rainbow background")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatBold type=checkbox /></td><TD class=xtab>'+tx("Enable Bold Font")+'</td></tr>';
		var cb = '';
		if (Options.ChatOptions.chatBold) { cb = ';font-weight:bold;'; }
		m += '<TR><TD class=xtab><INPUT id=togChatGlobal type=checkbox /></td><TD class=xtab>'+tx("Enable Global Chat Background Colour")+'</td><TD class=xtab><INPUT id=togGlobal type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatGlobal + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatGlobal + cb +'" width=90px>'+tx("Global")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatAlliance type=checkbox /></td><TD class=xtab>'+tx("Enable Alliance Chat Background Colour")+'</td><TD class=xtab><INPUT id=togAll type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatAll + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatAll + cb +'" width=90px>'+tx("Alliance")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatWhisper type=checkbox /></td><TD class=xtab>'+tx("Enable Whisper Colour")+'</td><TD class=xtab><INPUT id=togWhisper type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatWhisper + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:#F8E151;color:' + Options.ChatOptions.Colors.ChatWhisper + '" width=90px><b>'+tx("Whisper")+'</b></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatAttack type=checkbox /></td><TD class=xtab>'+tx("Enable Tower Alert Background Colour")+'</td><TD class=xtab><INPUT id=togChatAtt type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatAtt + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatAtt + cb +'" width=90px>'+tx("Alert")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togChatLead type=checkbox /></td><TD class=xtab>'+tx("Enable Alliance Leaders Background Colours")+'</td><TD class=xtab><INPUT id=togChatC type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatChancy + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatChancy + cb +'" width=90px>'+tx("Chancellor")+'</td>';
		m += '<TD class=xtab>&nbsp;<INPUT id=togChatVC type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatVC + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatVC + cb +'" width=90px>'+tx("Vice")+'</td>';
		m += '<TD class=xtab>&nbsp;<INPUT id=togChatLeaders type=text size=7 maxlength=7 value="' + Options.ChatOptions.Colors.ChatLeaders + '"></td>&nbsp;<TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.ChatOptions.Colors.ChatLeaders + cb +'" width=90px>'+tx("Officer")+'</td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD class=xtab>'+tx('HTML colours')+':&nbsp;<a href="http://www.colorpicker.com/" target="_blank">'+tx('Colour Picker')+'</a>&nbsp;/&nbsp;<a href="http://www.w3schools.com/html/html_colors.asp" target="_blank">'+tx('Colours')+'</a></td><td colspan=2 class=xtab>';
		m += makeButtonv2('blue', 'id=btResetChatColors', tx("Reset Chat Colours"));
		m += '</td></tr>';

		m += '</table>';

		ById('btChatOption').innerHTML = m;

		t.ChatVolSlider = new SliderBar (ById('ptVolSlider'), 200, 21, 0);
		t.ChatVolSlider.setValue (Options.ChatOptions.Volume/100);
		t.ChatVolSlider.setChangeListener(t.ChatVolumeChanged);
		t.ChatVolumeChanged (Options.ChatOptions.Volume/100);
		t.ChatSoundToggle();

		ById('btTestWhisperSound').addEventListener ('click', function() {
			AudioManager.setVolume(100);
			AudioManager.setSource(eval('SOUND_FILES.' + Options.ChatOptions.WhisperPlay));
			AudioManager.play();
			AudioManager.stoptimer = setTimeout(function(){AudioManager.stop();}, 2500);
		}, false);

		ById('btTestTowerSound').addEventListener ('click', function() {
			AudioManager.setVolume(100);
			AudioManager.setSource(eval('SOUND_FILES.' + Options.ChatOptions.TowerPlay));
			AudioManager.play();
			AudioManager.stoptimer = setTimeout(function(){AudioManager.stop();}, 5000);
		}, false);

		ToggleOption('ChatOptions','togChatStuff', 'chatEnhance', ChatStuff.setEnable, ChatStuff.isAvailable);
		ToggleOption('ChatOptions','togChatGlobal', 'chatGlobal');
		ToggleOption('ChatOptions','togChatAlliance', 'chatAlliance');
		ToggleOption('ChatOptions','togChatWhisper', 'chatWhisper');
		ToggleOption('ChatOptions','togChatBold', 'chatBold',t.PaintChatOptions);
		ToggleOption('ChatOptions','togChatAttack', 'chatAttack');
		ToggleOption('ChatOptions','togChatLead', 'chatLeaders');
		ToggleOption('ChatOptions','togChatIcon', 'chatIcons');
		ToggleOption('ChatOptions','togChatEmoticons', 'Emoticons');
		ToggleOption('ChatOptions','togChatImages', 'ImagePreviews');

		ToggleOption('ChatOptions','togEnableWhisperAlert', 'enableWhisperAlert', t.ChatSoundToggle);
		ToggleOption('ChatOptions','togEnableTowerAlert', 'enableTowerAlert', t.ChatSoundToggle);

		ToggleOption('ChatOptions','pbspamactive', 'SpamActive',t.ToggleSpamActive);

		ChangeOption('ChatOptions','pbspamtype','SpamType');
		ChangeOption('ChatOptions','pbspamtext','SpamText');

		ChangeIntegerOption('ChatOptions','pbspaminterval','SpamInterval',1);

		ToggleOption('ChatOptions','CFilter', 'filter');
		ChangeOption('ChatOptions','pbfilter','fchar');

		ToggleOption('ChatOptions','pbHelpRequest', 'HelpRequest');
		ToggleOption('ChatOptions','pbDeleteRequest', 'DeleteRequest');
		ToggleOption('ChatOptions','pbDeletegAl', 'DeletegAl');
		ToggleOption('ChatOptions','pbDeleteFood', 'DeleteFood');
		ToggleOption('ChatOptions','pbDeleteGlobalSpam', 'DeleteGlobalSpam');
		ToggleOption('ChatOptions','pbDeleteAllianceSpam', 'DeleteAllianceSpam');
		ChangeOption('ChatOptions','pbDelFoodUsers', 'DeleteFoodUsers');

		ChangeOption('ChatOptions','btTowerPlay','TowerPlay');
		ChangeOption('ChatOptions','btWhisperPlay','WhisperPlay');

		ById('togGlobal').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatGlobal = ById('togGlobal').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togChatLeaders').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatLeaders = ById('togChatLeaders').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togChatC').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatChancy = ById('togChatC').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togChatVC').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatVC = ById('togChatVC').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togAll').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatAll = ById('togAll').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togChatAtt').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatAtt = ById('togChatAtt').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('togWhisper').addEventListener('change', function () {
			Options.ChatOptions.Colors.ChatWhisper = ById('togWhisper').value;
			saveOptions();
			t.PaintChatOptions();
		}, false);
		ById('btResetChatColors').addEventListener('click', function () {
			for (var p in ChatStuff.Colors) {
				Options.ChatOptions.Colors[p] = ChatStuff.Colors[p];
			}
			saveOptions();
			t.PaintChatOptions();
		}, false);

		ToggleOption('ChatOptions','togChatGlory','GloryLeader');
		ToggleOption('ChatOptions','togChatRainbow','Rainbow');
		ChangeIntegerOption('ChatOptions','pbglorycheck','GloryLeaderInterval',1);

		ById ('pbIMGLinkHelp').addEventListener ('click', t.helpimgPop, false);
	},

	ChatVolumeChanged : function (val) {
		var t = Tabs.Options;
		ById('ptVolOut').innerHTML = parseInt(val*100);
		Options.ChatOptions.Volume = parseInt(val*100);
		saveOptions();
	},

	ChatSoundToggle : function () {
		var t = Tabs.Options;
		var dc = jQuery('#ptSoundOpts').attr('class');
		if (Options.ChatOptions.enableTowerAlert || Options.ChatOptions.enableWhisperAlert) {if (dc.indexOf('divHide') >= 0) jQuery('#ptSoundOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#ptSoundOpts').attr('class','divHide');}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	PaintGameOptions : function () {
		var t = Tabs.Options;
		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab><INPUT id=togAttackPicker type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enable Target City Picker in Attack Dialog (Reinforce, Reassign and Transport)")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togHideAttackEfforts type=checkbox /></td><TD class=xtab colspan=2>'+tx("Hide Attack/Speed boosts by default in attack dialog")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togPageNav type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enhanced Page Navigation for Messages and Reports")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togAllRpts type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enhanced Alliance Reports")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togRptGift type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enhanced Inbox/Report functions")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togAllMembers type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enhanced Alliance Members View")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togRptClick type=checkbox /></td><TD class=xtab colspan=2>'+tx("Alliance and Messages buttons open on Report View")+'</td></tr>';

		m += '<TR><TD class=xtab><INPUT id=togResetRaids type=checkbox /></td><TD class=xtab>'+tx("Automatically restart raid timer")+'</td><td class=xtab><INPUT id=togAutoRaidToggle type=checkbox />&nbsp;'+tx("Auto-raid restart toggle on screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togRaidButtons type=checkbox /></td><TD class=xtab>'+tx("Raid Stop/Resume buttons on screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td><td class=xtab><INPUT id=togRaidDeleteButton type=checkbox />&nbsp;'+tx("Raid delete button on screen header")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbGoldEnable type=checkbox /></td><TD class=xtab colspan=2>'+tx("Automatically collect gold when happiness reaches")+' <INPUT id=pbGoldLimit type=text size=2 maxlength=3 \>%</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=pbFoodToggle type=checkbox /></td><TD class=xtab colspan=2>'+tx("Display food alert in alliance chat when less than")+' <INPUT id=pbFoodAlertInt type=text size=2 maxlength=3 \> '+tx("hours of food remaining (checked every 15 min)")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togBatRounds type=checkbox /></td><TD class=xtab colspan=2>'+tx("Display Number of Rounds in Battle Reports")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togAtkDelete type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enable Delete Button on Battle Report")+'</td></tr>';

		m += '<TR><TD class=xtab><INPUT id=togGmtClock type=checkbox /></td><TD class=xtab colspan=2>'+tx("Show")+' ' + htmlSelector({
				0: 'GMT',
				1: 'Pacific'
			}, Options.gmtClockType, 'id=btClockType') + ' '+tx("Time next to Camelot Time")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMapInfo4 type=checkbox /></td><TD class=xtab colspan=2>'+tx("Display Province, Truce Status and Player Notes in Map Tooltips")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togMapMenuInfo type=checkbox /></td><TD class=xtab colspan=2>'+tx("Include Extra Player Information in Map Context Menu")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=MapExtra type=checkbox /></td><TD class=xtab colspan=2>'+tx("Show Player & Might in map")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=MapLevel type=checkbox /></td><TD class=xtab colspan=2>'+tx("Show Tile Level in map")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=togCV type=checkbox /></td><TD class=xtab colspan=2>'+tx("Enhanced city buttons")+'</td></tr>';
		m += '<TR id=ptcvoptions1 class="divHide"><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><INPUT id=togDbClkDef type=checkbox />'+tx("Hide/Defend by Double-Clicking City Icon")+'</td></tr>';
		m += '<TR id=ptcvoptions2 class="divHide"><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><INPUT id=togColrCty type=checkbox />'+tx("Enable Colour Icon for City Faction")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR id=ptcvoptions3 class="divHide"><TD class=xtab>&nbsp;</td><TD class=xtab colspan=2><INPUT id=ptWarnAscension type=checkbox ' + (Options.WarnAscension ? 'CHECKED ' : '') + '/>'+tx("Highlight when Ascension Protection will Expire within")+' ';
		m += '<INPUT id=ptWarnAscensionInterval type=text size=3 value="' + Options.WarnAscensionInterval + '"> '+tx("Hours")+'</td></tr>';
        m += '<TR><TD class=xtab><INPUT id=pbmaintoggle type=checkbox /></td><TD class=xtab colspan=2>'+tx("Auto-select city on startup");
		m += '&nbsp;<select id=pbwhichcity>';
		m += '<option value="-1" '+ ((Options.smain==0)?'selected':'')+'>('+tx("Previously selected city")+')</option>';
		for (var h=0;h < uW.seed.cities.length;h++) {
			if (h == Options.smain)
				m+='<option value='+h+' selected="selected">'+uW.seed.cities[h][1]+'</option>';
			else
				m+='<option value='+h+'>'+uW.seed.cities[h][1]+'</option>';
		}
		m += '</select></td></tr>';
        m += '<TR><td class=xtab><INPUT id=btFairie type=checkbox '+ (Options.KillFairie?'CHECKED ':'') +'/></td><TD class=xtab colspan=2>'+tx("Kill annoying Faire and Court popups")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=btLoginReward type=checkbox '+ (Options.LoginReward?'CHECKED ':'') +'/></td><TD class=xtab colspan=2>'+tx("Auto-click and accept Daily Login Reward")+'</td></tr>';
		m += '<TR><td class=xtab><INPUT id=btMagicBox type=checkbox  '+ (Options.MagicBox?'CHECKED ':'') +'/></td><TD class=xtab colspan=2>'+tx("Kill Merlins Magical Boxes on start up")+'</td></tr>';
		m += '</table>';

		ById('btGameOption').innerHTML = m;

		ById('btClockType').addEventListener('change', function () {
			Options.gmtClockType = this.value;
			saveOptions();
		}, false);

		ToggleOption('','togPageNav', 'fixPageNav', PageNavigator.enable, PageNavigator.isAvailable);
		ToggleOption('','togRptGift', 'enhancedinbox', DispReport.setEnable, DispReport.isDispReportAvailable);
		ToggleOption('','togCV', 'EnhCBtns', function () { t.EnhCBtnsToggle();t.RestartReminder(); });
		ToggleOption('','togDbClkDef', 'DbClkDefBtns');
		ToggleOption('','togColrCty', 'ColrCityBtns',t.RestartReminder);
		t.EnhCBtnsToggle();

		ToggleOption('','togResetRaids', 'RaidRunning',t.ToggleRaidActive);
		ToggleOption('','togAutoRaidToggle', 'RaidToggle',t.RestartReminder);
		ToggleOption('','togRaidButtons', 'RaidButtons',t.RestartReminder);
		ToggleOption('','togRaidDeleteButton', 'RaidDeleteButton',t.RestartReminder);
		ToggleOption('','togRptClick', 'ClickForReports',t.RestartReminder);
		ToggleOption('','togAttackPicker', 'attackCityPicker', AttackDialog.setEnable, AttackDialog.isAvailable);
		ToggleOption('','togHideAttackEfforts', 'hideAttackEfforts');
		ToggleOption('','togGmtClock', 'gmtClock', GMTclock.setEnable);
		ToggleOption('','togAllRpts', 'enhanceARpts', AllianceReports.listFunc.setEnable);
		ToggleOption('','togAllMembers', 'enhanceViewMembers', AllianceReports.enable_viewmembers);
		ToggleOption('','togBatRounds', 'dispBattleRounds', null, battleReports.isRoundsAvailable);
		ToggleOption('','togAtkDelete', 'reportDeleteButton', null, battleReports.isRoundsAvailable);
		ToggleOption('','MapExtra', 'MapShowExtra');
		ToggleOption('','MapLevel', 'MapShowLevel');
		ToggleOption('','togMapInfo4', 'dispStatus', mapinfoFix.setEnableDispStatus, mapinfoFix.isAvailableDispStatus);
		ToggleOption('','togMapMenuInfo', 'mapMenuInfo', mapinfoFix.setMenuEnable, mapinfoFix.isMenuAvailable);
		ToggleOption('','btLoginReward', 'LoginReward');
		ToggleOption('','btMagicBox', 'MagicBox');
		ToggleOption('','btFairie', 'KillFairie', FairieKiller.setEnable);
		ToggleOption('','pbmaintoggle', 'amain');
		ChangeOption('','pbwhichcity', 'smain');

		ToggleOption('','pbGoldEnable', 'pbGoldEnable');
		ChangeOption('','pbGoldLimit', 'pbGoldHappy');
		ToggleOption('','pbFoodToggle', 'pbFoodAlert');
		ChangeOption('','pbFoodAlertInt', 'pbFoodAlertInt');

		ById('ptWarnAscension').addEventListener('change', t.EnhCBtnsToggle, false);
		ChangeIntegerOption('','ptWarnAscensionInterval','WarnAscensionInterval',1,Tabs.Options.checkAscension);
	},

	PaintPBPOptions : function () {
		var t = Tabs.Options;

		var Themes = {};
		for (var a in t.Colors) Themes[a] = tx(a);

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab><INPUT id=btEveryEnable type=checkbox /></td><TD class=xtab>'+tx("Refresh KofC every")+' <INPUT id=btEveryMins type=text size=2 maxlength=3 \> '+tx("minutes")+'</td><TD class=xtab><INPUT id=btdetafk type=checkbox '+ (Options.detAFK?'CHECKED ':'')+ '/>&nbsp;'+tx("Only when AFK")+'&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=btEveryToggle type=checkbox '+ (Options.btEveryToggle?'CHECKED ':'')+ '/>&nbsp;'+tx("Add Toggle Button")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btAutoMist type=checkbox /></td><td class=xtab>'+tx('Automatically apply Potion of Mist when AFK')+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;<TD class=xtab colspan=2>'+tx("Automatic march functions should ALWAYS keep")+' <INPUT id=btfreerallyslots type=text size=2 maxlength=2 value="'+Options.FreeRallySlots+'"\> '+tx("free rally slots")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptHideOnGoto type=checkbox /></td><TD class=xtab>'+tx("Hide PowerBot+ when clicking on Map Coordinates")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptOneClickAttack type=checkbox /></td><TD class=xtab>'+tx("Enable one-click attack from the map")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btDraggableCoords type=checkbox /></td><TD class=xtab>'+tx("Enable draggable map co-ordinates box")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btGreenCastles type=checkbox /></td><TD class=xtab>'+tx("Display selected castle in green on city selection widgets")+'&nbsp;<span style="font-size:14px;color:#800;">*</span></td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptFetchMarchInfo type=checkbox /></td><TD class=xtab>'+tx("Fetch additional march information from server")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptAlertOverrideChk type=checkbox /></td><TD class=xtab>'+tx("Replace gem containers with incoming attack alert timer")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=btWidgetCheck type=checkbox /></td><TD class=xtab>'+tx("Enable main screen throne room widget")+'</td><td class=xtab><INPUT id=btDraggableWidget type=checkbox />&nbsp;'+tx("Draggable")+'&nbsp;<span style="font-size:14px;color:#800;">*</span>&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=btThroneHUD type=checkbox />&nbsp;'+tx("Display widget as Throne HUD")+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=TRFixPresetWidth type=checkbox /></td><td class=xtab>'+tx('Fix throne room preset changer width to 8 per row')+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;<TD class=xtab>'+tx("Detect AFK when mouse and keyboard idle for")+' <INPUT id=btafktimeout type=text size=2 maxlength=3 \> '+tx("minutes")+'</td></tr>';
		m += '<TR><TD class=xtab>&nbsp;<TD class=xtab>'+tx("Map lookup request interval")+' <INPUT id=btmapinterval type=text size=2 maxlength=2  value="'+Options.MapInterval+'"\> '+tx("seconds")+'</td></tr>';
		m += '<TABLE><TR><TD class=xtab colspan=3><B>'+tx("PowerBot+ Colours")+'&nbsp;<span style="font-size:16px;color:#800;">*</span></b></td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD class=xtab>'+tx("Title Background")+': </td><TD class=xtab><INPUT id=togTitleBack type=text size=7 maxlength=7 value="' + Options.Colors.Title + '"></td><TD class=xtab>Text: </td><TD class=xtab><INPUT id=togTitleText type=text size=7 maxlength=7 value="' + Options.Colors.TitleText + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.Colors.Title + ';color:' + Options.Colors.TitleText + ';"><b>'+tx('Title')+'</b></td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD class=xtab>'+tx("Divider Background")+': </td><TD class=xtab><INPUT id=togDividerTop type=text size=7 maxlength=7 value="' + Options.Colors.DividerTop + '">&nbsp;-&nbsp;<INPUT id=togDividerBottom type=text size=7 maxlength=7 value="' + Options.Colors.DividerBottom + '"></td><TD class=xtab>Text: </td><TD class=xtab><INPUT id=togDividerText type=text size=7 maxlength=7 value="' + Options.Colors.DividerText + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background: -moz-linear-gradient(top, '+Options.Colors.DividerTop+', '+Options.Colors.DividerBottom+'); background: -webkit-linear-gradient(top, '+Options.Colors.DividerTop+', '+Options.Colors.DividerBottom+');color:' + Options.Colors.DividerText + ';"><b>'+tx('DIVIDER')+'</b></td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD class=xtab>'+tx("Panel Background")+': </td><TD class=xtab><INPUT id=togPanelBack type=text size=7 maxlength=7 value="' + Options.Colors.Panel + '"></td><TD class=xtab>Text: </td><TD class=xtab><INPUT id=togPanelText type=text size=7 maxlength=7 value="' + Options.Colors.PanelText + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.Colors.Panel + ';color:' + Options.Colors.PanelText + ';">'+tx('Panel')+'</td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD class=xtab>'+tx("Highlight Background")+': </td><TD class=xtab><INPUT id=togHighlightBack type=text size=7 maxlength=7 value="' + Options.Colors.Highlight + '"></td><TD class=xtab>Text: </td><TD class=xtab><INPUT id=togHighlightText type=text size=7 maxlength=7 value="' + Options.Colors.HighlightText + '"></td><TD cellpadding=2 align=center style="border:1px solid #888888;background-color:' + Options.Colors.Highlight + ';color:' + Options.Colors.HighlightText + ';"><b>'+tx('Highlight')+'</b></td></tr>';
		m += '<TR><TD class=xtab width=30>&nbsp;</td><TD colspan=4 class=xtab>'+tx("HTML colours")+':&nbsp;<a href="http://www.colorpicker.com/" target="_blank">'+tx("Colour Picker")+'</a>&nbsp;/&nbsp;<a href="http://www.w3schools.com/html/html_colors.asp" target="_blank">'+tx('Colours')+'</a></td><td class=xtab>';
		m += tx('Theme')+':&nbsp;'+htmlSelector(Themes,Options.Theme,'id=btTheme')+'&nbsp'+makeButtonv2('blue', 'id=btResetColors', tx("Reset Colours"));
		m += '</td></tr>';

		m += '</table>';

		ById('btPBPOption').innerHTML = m;

		ChangeOption ('','btEveryMins', 'btEveryMins' , RefreshEvery.setTimer);
		ToggleOption ('','btEveryEnable', 'btEveryEnable', t.changeRefreshOption);
		ToggleOption ('','btEveryToggle', 'btEveryToggle', t.RestartReminder);
		ToggleOption ('','btAutoMist', 'AutoMist');
		ToggleOption ('','btdetafk', 'detAFK');

		ById('togTitleBack').addEventListener('change', function () {
			Options.Colors.Title = ById('togTitleBack').value;
			saveOptions();
			t.PaintPBPOptions();
			t.RestartReminder();
		}, false);
		ById('togTitleText').addEventListener('change', function () {
			Options.Colors.TitleText = ById('togTitleText').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togDividerTop').addEventListener('change', function () {
			Options.Colors.DividerTop = ById('togDividerTop').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togDividerBottom').addEventListener('change', function () {
			Options.Colors.DividerBottom = ById('togDividerBottom').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togDividerText').addEventListener('change', function () {
			Options.Colors.DividerText = ById('togDividerText').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togPanelBack').addEventListener('change', function () {
			Options.Colors.Panel = ById('togPanelBack').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togPanelText').addEventListener('change', function () {
			Options.Colors.PanelText = ById('togPanelText').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togHighlightBack').addEventListener('change', function () {
			Options.Colors.Highlight = ById('togHighlightBack').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('togHighlightText').addEventListener('change', function () {
			Options.Colors.HighlightText = ById('togHighlightText').value;
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);
		ById('btResetColors').addEventListener('click', function () {
			var Theme = ById('btTheme').value;
			for (var p in Tabs.Options.Colors[Theme]) {
				Options.Colors[p] = Tabs.Options.Colors[Theme][p];
			}
			saveOptions();
			t.PaintPBPOptions()
			t.RestartReminder();
		}, false);

		ToggleOption('','ptOneClickAttack', 'OneClickAttack',t.RestartReminder);
		ToggleOption('','btDraggableCoords', 'DraggableCoords',t.RestartReminder);
		ToggleOption('','btGreenCastles', 'GreenCastles',t.RestartReminder);
		ToggleOption('','ptHideOnGoto', 'hideOnGoto');
		ToggleOption('','ptFetchMarchInfo', 'FetchMarchInfo');
		ToggleOption('','ptAlertOverrideChk', 'OverrideAttackAlert');
		ChangeOption('','btTheme','Theme');
		ChangeOption('','btafktimeout', 'AFKTimeout' , afkdetector.reset);

		ToggleOption ('','btWidgetCheck', 'TRWidget', function() { Dashboard.PaintTRPresets(); WideScreen.CheckChatPosition();} );
		ToggleOption('','btDraggableWidget', 'DraggableWidget',t.RestartReminder);
		ToggleOption ('','btThroneHUD', 'ThroneHUD', function() { Options.presetPosition = null; t.SetTRWidgetDisplay(); Dashboard.PaintTRPresets(); WideScreen.CheckChatPosition();} );
		ToggleOption ('','TRFixPresetWidth', 'TRFixPresetWidth', Dashboard.PaintTRPresets);


		ChangeIntegerOption('','btmapinterval','MapInterval',2,function () { MAP_DELAY = Options.MapInterval * 1000; });

		ChangeIntegerOption('','btfreerallyslots','FreeRallySlots');
	},

	PaintLanguageOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD class=xtab>&nbsp;</td><TD class=xtab>'+tx('Current Language')+':&nbsp;<select id=btChangeLang>';
		for (var l in uW.g_supportedLangugages) {
			m += '<option value="'+l+'" '+((Options.Language==l)?"selected":"")+'>'+uW.g_supportedLangugages[l]+'</option>';
		}
		m += '</select>&nbsp;'+strButton20(uW.g_js_strings.getUserSettings.changelang,'id=btChangeLangButton')+'&nbsp;'+strButton20(tx('Refresh'),'id=btRefreshLangButton')+'</td>';
		m += '<TD colspan=2 class=xtab align=right>'+t.languagestatus+'&nbsp;&nbsp;</td></tr>';
		m += '<TR><td class=xtab>&nbsp;</td><td class=xtab><input class=btInput id=btEditLang type=button value="'+tx("Edit Translations")+'"></td></tr></table>';

		ById('btLanguage').innerHTML = m;

		ById('btChangeLangButton').addEventListener('click', t.ChangeLanguage, false);
		ById('btRefreshLangButton').addEventListener('click', t.ChangeLanguage, false);
		ById('btEditLang').addEventListener('click', t.editTranslations, false);
	},

	PaintTabManagerOptions : function () {
		var t = Tabs.Options;

		m = '<TABLE width="100%">';
		m += '<TR><TD colspan=2 class=xtab><b>'+tx('Additional Tabs')+'</b></td><td class=xtab align=right width=100px><a id="btTabAdd" class="inlineButton btButton red14" onclick="btTabReset()"><span>'+tx('Reset Additional Tabs')+'</span></a></td></tr>';

		for (var e in GlobalOptions.ExtraTabs) {
			if (GlobalOptions.ExtraTabs[e].source) {
				m += '<TR><TD width=30 class=xtab><INPUT id="btTabEnabled_'+e+'" type=checkbox '+(GlobalOptions.ExtraTabs[e].enabled?'CHECKED':'')+' onclick="btTabToggle('+e+')" /></td><TD class=xtab>'+GlobalOptions.ExtraTabs[e].source+'</td><td class=xtab align=right width=100px><a id="btTabRefresh_'+e+'" class="inlineButton btButton brown8" onclick="btTabRefresh('+e+')"><span>'+tx('Reload')+'</span></a>&nbsp;<a id="btTabDelete_'+e+'" class="inlineButton btButton brown8" onclick="btTabDelete('+e+')"><span>'+tx('Remove')+'</span></a></td></tr>';
			}
		}
		m += '<TR><TD width=30 class=xtab>&nbsp;</td><TD class=xtab><INPUT title="'+tx('Enter the URL for the remote source code of the additional tab - NOTE THIS CANNOT BE A LOCAL FILE!')+'" class="btInput" id="btTabSource" type=text style="width:650px;" value=""></td><td class=xtab align=right width=100px><a id="btTabAdd" class="inlineButton btButton brown8" onclick="btTabAdd()"><span>'+tx('Add Tab')+'</span></a></td></tr>';
		m += '<TR><TD align=center class=xtab colspan=3 id=btTabMessage>&nbsp;</td></tr>';

        m += '<TR><TD class=xtab colspan=3><br><div align=center>'+tx('Autoport Access Code')+':&nbsp;<input class=btInput type="text" value="'+Options.PremiumAccessCode+'" id="btPremiumCode"/></div><br></td></tr>';
		m += '</table>';

		ById('btTabManager').innerHTML = m;

		ChangeOption('','btPremiumCode','PremiumAccessCode',t.RestartReminder);

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	ToggleTRPreset : function (entry) {
		var t = Tabs.Options;
		if (!Options.DashboardOptions.TRPresetsSelected[entry]) { Options.DashboardOptions.TRPresetsSelected[entry] = true; }
		Options.DashboardOptions.TRPresetsSelected[entry] = ById('btpresetSelect'+entry).checked;
		saveOptions();
	},

	TabToggle : function(e) {
		var t = Tabs.Options;
		GlobalOptions.ExtraTabs[e].enabled = ById('btTabEnabled_'+e).checked;
		if (GlobalOptions.ExtraTabs[e].enabled && !GlobalOptions.ExtraTabs[e].data) {
			t.TabLoad(e);
		}
		saveGlobalOptions();
		t.RestartReminder();
	},

	RotateThrone: function () {
		var t = Tabs.Options;
		var activeSlot = Number(Seed.throne.activeSlot);
		var oldActive = activeSlot;
		var foundone = false;
		do {
			activeSlot++;
			if (activeSlot > Number(Seed.throne.slotNum)) activeSlot = 1;
			if (Options.DashboardOptions.TRPresetsSelected[activeSlot]) {
				SwitchThroneRoom(activeSlot);
				foundone = true;
				break;
			}
		}
		while (!foundone && (activeSlot != oldActive))
	},

	TabDelete : function(e) {
		var t = Tabs.Options;
		GlobalOptions.ExtraTabs.splice(e,1);
		saveGlobalOptions();
		t.RestartReminder();
		t.PaintTabManagerOptions();
		ById('btTabMessage').innerHTML = tx('Tab Removed');
	},

	TabRefresh : function(e) {
		var t = Tabs.Options;
		t.TabLoad(e);
	},

	TabReset : function() {
		var t = Tabs.Options;
		delete GlobalOptions.ExtraTabs;
		saveGlobalOptions();
		t.RestartReminder();
		t.PaintTabManagerOptions();
	},

	TabAdd : function() {
		var t = Tabs.Options;
		var TabObj = {};
		TabObj.source = ById('btTabSource').value.trim();
		TabObj.data = null;
		TabObj.enabled = true;
		GlobalOptions.ExtraTabs.push(TabObj);
		t.TabLoad(GlobalOptions.ExtraTabs.length-1);
	},

	TabLoad : function(e) {
		var t = Tabs.Options;
		var src = GlobalOptions.ExtraTabs[e].source;
		if (src!="") {
			var TabMessage = tx('Tab Added');
			if (GlobalOptions.ExtraTabs[e].data) {
				TabMessage = tx('Tab Updated');
			}
			remotefun = function () {
				try {
					GM_xmlhttpRequest({
						method: 'GET',
						url: src+'?'+new Date(),
						headers: {
							'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
						},
						onload: function (remote) {
							if (remote.status == 200) {
								try {
									GlobalOptions.ExtraTabs[e].data = btoa(remote.responseText);
									saveGlobalOptions();
									t.RestartReminder();
								}
								catch (err) {
									TabMessage = err.message;
									logerr(err);
								}
							}
							else {
								TabMessage = tx('Unable to open source file');
								logit('unable to open file '+src);
							}
							if (!GlobalOptions.ExtraTabs[e].data) {
								GlobalOptions.ExtraTabs.splice(e,1); // remove bad tab
							}
							t.PaintTabManagerOptions();
							ById('btTabMessage').innerHTML = TabMessage;
						},
					});
				} catch (e){ logerr(e);	}
			}
			setTimeout(remotefun,0);
		}
	},

	ChangeLanguage : function () {
		var t = Tabs.Options;
		var params=uW.Object.clone(uW.g_ajaxparams);
		params.lang=ById('btChangeLang').value;

		new MyAjaxRequest(uW.g_ajaxpath +"ajax/changeLanguage.php"+uW.g_ajaxsuffix, {
			method:"post",
			parameters:params,
			onSuccess:function(rslt) {
				Options.Language=(params.lang);
				LanguageArray = {};
				t.LoadLanguage(Options.Language,function () { saveLanguage(Options.Language); ReloadKOC(false,'&lang='+Options.Language); });
			},
		},true);
	},

	LoadLanguage : function (lang,notify) {
		var t = Tabs.Options;
		Options.LanguageLastChecked = unixTime();
		saveOptions();
		if (lang=='en') { if (notify) {notify();} return; } // english is default language - no pack available!
		var LangURL = EXTERNAL_RESOURCE+'languages/translation_'+lang+'.js?'+new Date();
		try {
			GM_xmlhttpRequest({
				method: 'GET',
				url: LangURL,
				onload: function(xpr) {
					var rslt = null;
					if (xpr.status==200) {
						try {
							rslt = JSON2.parse(xpr.responseText);
						} catch (e){
							t.languagestatus = "<span class=boldRed>Invalid Language Pack</span>";
							logerr(e);
							if (notify) {notify();}
							return;
						}

						if (!LanguageArray.CurrLang || LanguageArray.CurrLang != rslt.CurrLang) {
							t.UpdateLangArray(rslt);
						}
						else {
							if (!LanguageArray.LangVersion || parseIntNan(LanguageArray.LangVersion.substring(0, 8)) < parseIntNan(rslt.LangVersion.substring(0, 8))) {
								t.languagestatus = "New Language Pack Available!";
							}
						}
					}
					if (notify) {notify();}
				},
				onerror: function() {
					t.languagestatus = tx('Language pack unavailable');
					if (notify) {notify();}
				}
			});
		} catch (e){ logerr(e);	}
	},

	UpdateLangArray : function (rslt) {
		var t = Tabs.Options;
		for (var k in rslt){
			LanguageArray[k] = rslt[k];
		}
		saveLanguage(Options.Language);
		t.languagestatus = tx('Language pack')+' ('+rslt.CurrLang+') '+tx('Version')+' '+rslt.LangVersion+' '+tx('loaded');
	},

	editTranslations : function () {
		var t = Tabs.Options;

		var m = '<table width=98% align=center class=xtab cellpadding=0 cellspacing=0>';

		m += '<tr><td class=xtab>&nbsp;</td><td class=xtab align=left><input class=btInput id=btSaveLang type=button value="'+tx("Save Changes")+'"></td><td class=xtab align=right><input class=btInput id=btExportLang type=button value="'+tx("Export")+'">&nbsp;<input class=btInput id=btImportLang type=button value="'+tx("Import")+'">&nbsp;<input class=btInput id=btImportLangFile type=file></td></tr>';
		m += '<tr><td colspan=3 align=center id=btEditTransMsg><span class=boldRed>Exiting window without clicking "Save Changes" will cause any amendments to be lost!</span></td></table>';
		m += '<div style="max-height:420px;overflow-y:auto;max-width:'+GlobalOptions.btWinSize.x+'px;"><br><table align=center cellspacing=0 cellpadding=0 class=xtab width=98%>';

		if (!LanguageArray.CurrLang) {
			LanguageArray.CurrLang = Options.Language;
		}
		var r = 0;
		m += '<tr class="oddRow"><td class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-360)+'px;">CurrLang</div></td><td>'+LanguageArray.CurrLang+'</td></tr>';
		r=r+1;
		if (LanguageArray.LangVersion) {
			m += '<tr class="evenRow"><td class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-360)+'px;">LangVersion</div></td><td>'+LanguageArray.LangVersion+'</td></tr>';
			r=r+1;
		}

		for (var l in NoTranslation) {
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';
			m += '<tr class="'+rowClass+'"><td class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-360)+'px;">'+l+'</div></td><td><input style="width:300px;" id="btlang_'+escape(l)+'" value="'+NoTranslation[l]+'"/></td></tr>';
		}
		for (var l in LanguageArray) {
			if (l != "CurrLang" && l != "LangVersion") {
				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';
				m += '<tr class="'+rowClass+'"><td class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-360)+'px;">'+l+'</div></td><td><input style="width:300px;" id="btlang_'+escape(l)+'" value="'+LanguageArray[l]+'"/></td></tr>';
			}
		}
		m += '</table></div>';

		t.popLang = new CPopup('btEditLanguage', 10, 10, GlobalOptions.btWinSize.x, 500, true, function() { saveLanguage(Options.Language); t.popLang.destroy();});
		t.popLang.getTopDiv().innerHTML = '<div align=center><B>'+tx("Edit Translations")+'</div>';
		t.popLang.getMainDiv().innerHTML = m;
		t.popLang.show(true);

		ById("btSaveLang").addEventListener('click', function(){
			for (var l in LanguageArray) {
				var elem = ById("btlang_"+escape(l));
				if (elem && elem.value != '') {
					LanguageArray[l] = elem.value;
				}
			}
			for (var l in NoTranslation) {
				var elem = ById("btlang_"+escape(l));
				if (elem && elem.value != '') {
					LanguageArray[l] = elem.value;
					delete NoTranslation[l];
				}
			}
			saveLanguage(Options.Language);
			t.editTranslations();
		},false);

		ById('btExportLang').addEventListener ('click',function() {
			var Export = {};
			for (var k in LanguageArray) {
				Export[k] = LanguageArray[k];
			}
			if (Options.Language = 'en') {
				for (var k in NoTranslation) {
					Export[k] = NoTranslation[k];
				}
			}
			uriContent = 'data:application/octet-stream;content-disposition:attachment;filename=file.txt,' + encodeURIComponent(JSON2.stringify(Export));
			t.saveConfig(uriContent,'lang_'+LanguageArray.CurrLang+'.txt');
			ById('btEditTransMsg').innerHTML = 'Translations Exported';
		},false);

		ById('btImportLang').addEventListener ('click',function() {
			var fileInput = ById("btImportLangFile");
			var files = fileInput.files;
			if (files.length == 0) { return; }
			var file = files[0];
			var reader = new FileReader();
			reader.onload = function (e) {
				var Import = JSON2.parse(e.target.result);
				if (Import.CurrLang && LanguageArray.CurrLang && Import.CurrLang != LanguageArray.CurrLang) {
					ById('btEditTransMsg').innerHTML = 'Incorrect Language';
					return;
				}
				else {
					for (var k in Import) {
						if (Import[k] != "") {
							LanguageArray[k] = Import[k];
							if (NoTranslation.hasOwnProperty(k)) delete NoTranslation[k];
						}
					}
				}
				t.editTranslations();
			};
			reader.readAsText(file);
		},false);
	},

	togGlobalOpt : function (checkboxId, optionName, callOnChange) {
		var t = Tabs.Options;
		var checkbox = ById(checkboxId);
		checkbox.checked = GlobalOptions[optionName];
		checkbox.addEventListener ('change', eventHandler, false);
		function eventHandler (){
			GlobalOptions[optionName] = this.checked;
			saveGlobalOptions();
			if (callOnChange) { callOnChange (this.checked); }
		}
	},

	changeGlobalOpt : function (valueId, optionName, callOnChange) {
		var t = Tabs.Options;
		var e = ById(valueId);
		e.value = GlobalOptions[optionName];
		e.addEventListener ('change', eventHandler, false);
		function eventHandler (){
			GlobalOptions[optionName] = this.value;
			saveGlobalOptions();
			if (callOnChange) { callOnChange (this.value); }
		}
	},

	togUserOpt : function (checkboxId, optionName, callOnChange, callIsAvailable) {
		var t = Tabs.Options;
		var checkbox = ById(checkboxId);
		if (callIsAvailable && callIsAvailable() == false) {
			checkbox.disabled = true;
			return;
		};
		checkbox.checked = UserOptions[optionName];
		checkbox.addEventListener ('change', eventHandler, false);
		function eventHandler (){
			UserOptions[optionName] = this.checked;
			saveUserOptions(uW.user_id);  // facebook user id
			if (callOnChange) { callOnChange (this.checked); }
		}
	},

	changeUserOpt : function (valueId, optionName, callOnChange) {
		var t = Tabs.Options;
		var e = ById(valueId);
		e.value = UserOptions[optionName];
		e.addEventListener ('change', eventHandler, false);
		function eventHandler (){
			UserOptions[optionName] = this.value;
			saveUserOptions(uW.user_id);  // facebook user id
			if (callOnChange) { callOnChange (this.value); }
		}
	},

	ResetDash : function () {
		var t = Tabs.Options;
		for (var p in Dashboard.DefaultDashboard) {
			ById('dashSeq'+p).value = Dashboard.DefaultDashboard[p].Sequence;
			ById('dashDisp'+p).checked = Dashboard.DefaultDashboard[p].Display;
		}
		Options.DashboardOptions.OverrideDashboard = {};
		saveOptions();
		WideScreen.RestartDashboard();
	},

	OverrideDash : function (sect) {
		var NewObj = {};
		if (Options.DashboardOptions.OverrideDashboard[sect]) {
			NewObj.Display = Options.DashboardOptions.OverrideDashboard[sect].Display;
			NewObj.Sequence = Options.DashboardOptions.OverrideDashboard[sect].Sequence;
		}
		else {
			NewObj.Display = Dashboard.DefaultDashboard[sect].Display;
			NewObj.Sequence = Dashboard.DefaultDashboard[sect].Sequence;
		}
		if (isNaN(ById('dashSeq'+sect).value)) { ById('dashSeq'+sect).value = 0; }
		NewObj.Sequence = ById('dashSeq'+sect).value;
		NewObj.Display = ById('dashDisp'+sect).checked;
		Options.DashboardOptions.OverrideDashboard[sect] = NewObj;
		saveOptions();
		WideScreen.RestartDashboard();
	},

	SacToggle : function () {
		var dc = jQuery('#btSacOpts').attr('class');
		if (Options.DashboardOptions.DefaultSacrifice) {if (dc.indexOf('divHide') >= 0) jQuery('#btSacOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btSacOpts').attr('class','divHide');}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	DefToggle : function () {
		var dc = jQuery('#btDefOpts').attr('class');
		if (Options.DashboardOptions.DefAddTroopShow) {if (dc.indexOf('divHide') >= 0) jQuery('#btDefOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btDefOpts').attr('class','divHide');}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	PresetToggle : function () {
		var dc = jQuery('#btPresetByNameOpts').attr('class');
		if (Options.DashboardOptions.TRPresetChange) {if (dc.indexOf('divHide') >= 0) jQuery('#btPresetByNameOpts').attr('class','');}
		else {if (dc.indexOf('divHide') < 0) jQuery('#btPresetByNameOpts').attr('class','divHide');}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		Dashboard.PaintTRPresets();
	},

	EnhCBtnsToggle: function () {
		var dc1 = jQuery('#ptcvoptions1').attr('class');
		var dc2 = jQuery('#ptcvoptions2').attr('class');
		var dc3 = jQuery('#ptcvoptions3').attr('class');
		if (Options.EnhCBtns) {
			if (dc1.indexOf('divHide') >= 0) jQuery('#ptcvoptions1').attr('class','');
			if (dc2.indexOf('divHide') >= 0) jQuery('#ptcvoptions2').attr('class','');
			if (dc3.indexOf('divHide') >= 0) jQuery('#ptcvoptions3').attr('class','');
		}
		else {
			if (dc1.indexOf('divHide') < 0) jQuery('#ptcvoptions1').attr('class','divHide');
			if (dc2.indexOf('divHide') < 0) jQuery('#ptcvoptions2').attr('class','divHide');
			if (dc3.indexOf('divHide') < 0) jQuery('#ptcvoptions3').attr('class','divHide');
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		Options.WarnAscension = ById('ptWarnAscension').checked;
		saveOptions();
		clearInterval(t.WarnAscensionTimer);
		if (Options.EnhCBtns && Options.WarnAscension) {
			t.WarnAscensionTimer = setInterval(function () {
				Tabs.Options.checkAscension();
			}, 60 * 1000); // every min?
		}
		Tabs.Options.checkAscension();
	},

	checkAscension: function () {
		var t = Tabs.Options;
		for (var i = 0; i < uW.seed.cities.length; i++) {
			var cityidx = i + 1;
			var city = ById('citysel_' + cityidx);
			if (!city) {
				setTimeout(t.checkAscension, 2000);
				return;
			}
			if (!Options.WarnAscension || !Options.EnhCBtns) {
				jQuery('#citysel_' + cityidx).removeClass('city_warning');
			} else {
				var cityExpTime = uW.seed.cityData.city[uW.seed.cities[i][0]].prestigeInfo.prestigeBuffExpire;
				if (!isNaN(cityExpTime) && (cityExpTime >= unixTime()) && ((cityExpTime - unixTime()) <= (Options.WarnAscensionInterval * 3600))) {
					if (jQuery('#citysel_' + cityidx).hasClass('city_unselected')) {
						jQuery('#citysel_' + cityidx).addClass('city_warning');
					}
				} else {
					jQuery('#citysel_' + cityidx).removeClass('city_warning');
				}
			}
		}
	},

	MiniRefreshChanged: function () {
		var t = Tabs.Options;
		Options.MiniRefresh = ById('ptEnableMiniRefresh').checked;
		saveOptions();
		t.MiniRefresh();
	},

	MiniRefresh: function () {
		var t = Tabs.Options;
		clearTimeout(t.MiniRefreshTimer);
		if (Options.MiniRefresh) {
			if (!Options.DashboardOptions.RefreshSeed && !RefreshingSeed) {
				RefreshSeed();
			}
			t.MiniRefreshTimer = setTimeout(function () { t.MiniRefresh(); }, Options.MiniRefreshInterval * 60 * 1000);
		}
	},

	AddUserLists : function () { // obsolete code. Kept for posterity
		var t = Tabs.Options;

		uW.FB.getLoginStatus(function(response) { if (response.status != 'connected') { return; } });

		uW.FB.login(function (o) {
			if (o.authResponse) {
				var p = {
					access_token : o.authResponse.accessToken
				};
				uW.FB.api('/me/friendlists', p, function(result) {
					UserOptions.CustomPublish = {};
					var markup = '';
					for (var l in t.PublishLists) {
						var selected = "";
						if (UserOptions.autoPublishPrivacySetting == l) selected = "selected";
						markup += '<option value="'+l +'" '+selected+'>'+t.PublishLists[l] +'</option>';
					}
					var lists = result.data;
					for(var i in lists){
						if (lists[i].list_type == 'user_created') {
							UserOptions.CustomPublish[lists[i].id] = lists[i].name;
							var selected = "";
							if (UserOptions.autoPublishPrivacySetting == lists[i].id) selected = "selected";
							markup += '<option value="'+lists[i].id +'" '+selected+'>'+lists[i].name +'</option>';
						}
					}
					saveUserOptions (uW.user_id);  // facebook user id
					ById('selectprivacymode').innerHTML = markup;
				});
			}
		},{ scope : "read_friendlists" });
	},

	ResetAllWindows: function () {
		DefaultWindowPos('btWinPos','main_engagement_tabs',true);
		mouseMainTab ({button:2});

		DefaultWindowPos('btDashPos','main_engagement_tabs',true);
		if (GlobalOptions.btFloatingDashboard) ResetWindowPos({button:2},'main_engagement_tabs',popDash);

		DefaultWindowPos('btIncPos','main_engagement_tabs',true);
		ResetWindowPos({button:2},'main_engagement_tabs',popInc);

		DefaultWindowPos('btOutPos','main_engagement_tabs',true);
		ResetWindowPos({button:2},'main_engagement_tabs',popOut);

		DefaultWindowPos('btMarchPos','main_engagement_tabs',true);
		ResetWindowPos({button:2},'main_engagement_tabs',popMarch);

		DefaultWindowPos('btMonPos','main_engagement_tabs',true);
		ResetWindowPos({button:2},'main_engagement_tabs',popMon);

		if (uW.btGuardWidget) { uW.btGuardWidget.resetGuardWidget(); }

		actionLog('All window positions reset','OPTIONS');
	},

	ResetAll : function () {
		hideMe();
		uW.Modal.multiButton({	buttons: [	{ txt: "Reset ALL Options!", exe: function () { uW.Modal.hideModal();
																										setTimeout( function () {
																											var RemoveList = (GM_listValues());
																											for (i=0;i<RemoveList.length;i++){
																												GM_deleteValue(RemoveList[i]);
																											}
																											ResetAll = true;
																											actionLog('Powerbot+ restored to factory settings');
																											ReloadKOC();
																										},0);}},
														{ txt: "Cancel Request", exe: function () {uW.Modal.hideModal();}}],
											body: "<center> Please confirm you want to return PowerBot+ to Factory Settings?<br>Note this affects all domains...</center>",
											title: "Reset ALL PowerBot+ Options"
										});
	},

	ResetSettings : function () {
		hideMe();
		uW.Modal.multiButton({	buttons: [	{ txt: "Reset Settings", exe: function () { uW.Modal.hideModal();
																									setTimeout( function () {
																										var serverID = getServerId();
																										GM_deleteValue ('Options_??');
																										GM_deleteValue ('Options_'+serverID+'_'+uW.tvuid);
																										ResetAll = true;
																										actionLog('Powerbot+ configuration reset');
																										Tabs.ActionLog.save();
																										ReloadKOC();
																									},0);}},
														{ txt: "Cancel Request", exe: function () {uW.Modal.hideModal();}}],
											body: "<center> Please confirm you want to reset PowerBot+ settings to default values?</center>",
											title: "Reset Settings"
										});
	},

	RestartReminder : function () {
		var t = Tabs.Options;
		var div = ById('ptRestart');
		if (!div) {
			var	div = document.createElement('div');
			div.id = 'ptRestart';
			uWExportFunction('ReloadKOC',ReloadKOC);
			var msg = tx('Changes to Power Bot Plus Settings require Kingdoms of Camelot to be reloaded')+'... <a onClick="ReloadKOC();">['+tx('reload')+']</a>&nbsp;<a onClick="this.parentNode.parentNode.style.display=\'none\';">['+uW.g_js_strings.commonstr.close+']</a>';
			div.innerHTML = '<DIV style="background: #fde073; text-align: center; line-height: 2.5; overflow: hidden; -webkit-box-shadow: 0 0 5px black; -moz-box-shadow: 0 0 5px black; box-shadow: 0 0 5px black;">'+msg+'</div>';
			document.body.insertBefore (div, document.body.firstChild);
		}
	},

	ToggleSpamActive : function () {
		var t = Tabs.Options;
		if (Options.ChatOptions.SpamActive) { // reset last sent time...
			Options.ChatOptions.LastSpamSent = 0;
			saveOptions();
		}
	},

	ToggleRaidActive : function () {
		var t = Tabs.Options;
		if (Options.RaidRunning) { // reset last sent time...
			Options.RaidLastReset = 0;
			saveOptions();
		}
		SetToggleButtonState('Raids',Options.RaidRunning,'Raids');
	},

	resetRaids : function(cityId,cityName){
		var t = Tabs.Options;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		params.ctrl = 'BotManager';
		params.action = 'resetRaidTimer';
		params.settings = {};
		params.settings.cityId = cityId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function(rslt){
				if (rslt.ok) {
					uW.cityinfo_army();
					setTimeout(uW.update_seed_ajax, 250);
				}
			},
		});
	},

	CheckWatchTower : function () {
		var t = Tabs.Options;
		var now = unixTime();
		var incoming = false;
		for (var k in local_atkinc) {   // check each incoming march
			var m = local_atkinc[k];
			if (m.marchType==3 || m.marchType==4) {
				if(Options.TowerOptions.HandledMarches.indexOf(String(m.mid)+String(m.departureTime))==-1) { // new attack!!
					Options.TowerOptions.HandledMarches.push(String(m.mid)+String(m.departureTime));
					if (Cities.byID[m.toCityId] && Cities.byID[m.toCityId].tileId == m.toTileId) { // only save times on city attacks
						if (!Options.TowerOptions.LatestAttackTimes[m.toCityId] || (Number(m.arrivalTime) > Options.TowerOptions.LatestAttackTimes[m.toCityId])) {
							Options.TowerOptions.LatestAttackTimes[m.toCityId] = Number(m.arrivalTime); // arrival times by city.
							if (Number(m.arrivalTime) > Options.TowerOptions.LastAttack) {
								Options.TowerOptions.LastAttack = Number(m.arrivalTime); // global last attack time var.
							}
						}
					}
					saveOptions();
					t.newIncoming (m);
				};
				incoming = true;
			}
		}

		if(!incoming) { // all clear!
			if (Options.TowerOptions.RecentActivity) {
				// belt and braces - reset last attack values if they are later than now...
				if (parseInt(Options.TowerOptions.LastAttack) > now) {
					Options.TowerOptions.LastAttack = now;
				}
				for (var cid in Options.TowerOptions.LatestAttackTimes) {
					if (parseInt(Options.TowerOptions.LatestAttackTimes[cid]) > now) {
						Options.TowerOptions.LatestAttackTimes[cid] = now;
					}
				}
			}
			Options.TowerOptions.HandledMarches = new Array(); // cleanup
		}

		// Start or Stop Sound Alert!

		if (incoming && Options.TowerOptions.alertSound.alarmActive){
			if (ById('btDashAlarmOff')) {
				if (!ById('btDashAlarmOffButton')) {
					ById('btDashAlarmOff').innerHTML = strButton14(tx('Silence Alarm')+'!','id=btDashAlarmOffButton','red14');
					ById('btDashAlarmOffButton').addEventListener ('click', t.stopSoundAlerts, false);
				}
			}
			else {
				if (!ById("towersirentab")) {
					AddSubTabLink(tx('Silence Alarm')+'!',t.stopSoundAlerts, 'towersirentab', 'red20');
				}
			}
		}
		if (Options.TowerOptions.alertSound.alarmActive && ((now > Options.TowerOptions.alertSound.expireTime) || !incoming)){
			var element = ById('towersirentab');
			if(element) { element.parentNode.removeChild(element); }
			if (ById('btDashAlarmOff')) { ById('btDashAlarmOff').innerHTML = ''; }
			t.stopSoundAlerts();
		}

		// Check Action Reverts

		if (Options.TowerOptions.RecentActivity) {
			for (var cid in Options.TowerOptions.RecentCityActivity) { 	// check each city action..
				if (Options.TowerOptions.RecentCityActivity[cid]===true) {
					var switchtime = parseInt(Options.TowerOptions.LatestAttackTimes[cid]);
					if (Options.TowerOptions.Revert) switchtime += Options.TowerOptions.RevertMinutes*60;
					if (switchtime < now) {
						actionLog(Cities.byID[cid].name+': All Clear','TOWER');
						if (Options.TowerOptions.Revert && (afkdetector.isAFK || !Options.TowerOptions.AFKEvents)) {
							// change guardian back
							if (Options.TowerOptions.ChangeGuardian) {
								if (Options.TowerOptions.SaveCityState[cid].Guardian != Seed.guardian[Cities.byID[cid].idx].type) {
									actionLog(Cities.byID[cid].name+': Resetting Guardian','TOWER');
									SwitchGuardian(cid,Options.TowerOptions.SaveCityState[cid].Guardian);
								}
							}

							// restart raids in city...
							if (Options.TowerOptions.StopRaids) {
								actionLog(Cities.byID[cid].name+': Restarting Raids','TOWER');
								ToggleCityRaids (cid,'resumeAll');
							}
						}
						Options.TowerOptions.RecentCityActivity[cid] = false; // switch off
						if (Options.TowerOptions.SaveCityState[cid]) {
							setTimeout(function() {
								if (!Options.TowerOptions.RecentCityActivity[cid] === true) { // double check!
									delete Options.TowerOptions.SaveCityState[cid];
									if (Options.TowerOptions.StopMarches) {
										actionLog(Cities.byID[cid].name+': Automatic march functions resumed','TOWER');
									}
								}
							},10000); // cleanup (which will allow marches again) 10 sec delay so raids get going first...
						}
					}
				}
			}

			var switchtime = parseInt(Options.TowerOptions.LastAttack);
			if (Options.TowerOptions.Revert) switchtime += Options.TowerOptions.RevertMinutes*60;
			if (switchtime < now) {
				if (Options.TowerOptions.Revert && (afkdetector.isAFK || !Options.TowerOptions.AFKEvents)) {
					// Switch TR back if required
					if (Options.TowerOptions.ChangeTR) {
						if (Options.TowerOptions.SaveTR != Seed.throne.activeSlot) {
							actionLog('Resetting Throne Room','TOWER');
							SwitchThroneRoom(Options.TowerOptions.SaveTR);
						}
					}
				}
				Options.TowerOptions.RecentActivity = false; // switch off
			}
		}
	},

	e_volChanged : function (val) {
		var t = Tabs.Options;
		ById('pbVolOut').innerHTML = parseInt(val*100);
		Options.TowerOptions.alertSound.volume = parseInt(val*100);
	},
	playSound : function (soundfile,doRepeats,btnid) {
		var t = Tabs.Options;
		if (!t.mss) return;
		var stopbtn = ById(btnid);
		if (stopbtn) { stopbtn.disabled = false; }
		clearTimeout (t.soundStopTimer);
		clearTimeout (t.soundRepeatTimer);
		t.mss.setVolume(Options.TowerOptions.alertSound.volume);
		t.mss.setSource(soundfile);
		t.mss.play();
		t.soundStopTimer = setTimeout (function(){t.mss.stop(); var stopbtn = ById(btnid); if (stopbtn) { stopbtn.disabled = true; };}, Options.TowerOptions.alertSound.playLength*1000);
		if (doRepeats && Options.TowerOptions.alertSound.repeat) {
			t.soundRepeatTimer = setTimeout (function (){t.playSound(soundfile,true,btnid)}, Options.TowerOptions.alertSound.repeatDelay*60000);
		}
		else {
			Options.TowerOptions.alertSound.alarmActive = false;
		}
	},
	soundTheAlert : function (marchtype) {
		var t = Tabs.Options;
		Options.TowerOptions.alertSound.alarmActive = true;
		if (marchtype==3) { new t.playSound(Options.TowerOptions.alertSound.scoutUrl,true,'pbScoutStop'); }
		else { new t.playSound(Options.TowerOptions.alertSound.soundUrl,true,'pbSoundStop'); }
	},
	stopSoundAlerts : function () {
		var t = Tabs.Options;
		if (t.mss) { t.mss.stop(); }
		var element = ById('towersirentab');
		if(element) { element.parentNode.removeChild(element); }
		if (ById('btDashAlarmOff')) { ById('btDashAlarmOff').innerHTML = ''; }
		clearTimeout (t.soundStopTimer);
		clearTimeout (t.soundRepeatTimer);
		var stopbtn = ById('pbSoundStop');
		if (stopbtn) { stopbtn.disabled = true; }
		var stopbtn = ById('pbScoutStop');
		if (stopbtn) { stopbtn.disabled = true; }
		Options.TowerOptions.alertSound.alarmActive = false;
		Options.TowerOptions.alertSound.expireTime = 0;
	},

	newIncoming : function (m) {
		var t = Tabs.Options;
		if (m.marchType == null) return; // bogus march (returning scouts)
		if (m.arrivalTime && m.arrivalTime < uW.unixtime()+30) return; // don't show expired marches, well unless within 30 seconds for lag...

		var totTroops = 0;
		if (m.unts) { // if watchtower not high enough, display anyway
			for (var k in m.unts) { totTroops += Number(m.unts[k]); }
			if (!isNaN(totTroops) && totTroops < Options.TowerOptions.minTroops) { return; }
		}
		if (!Options.TowerOptions.towercityactive[m.toCityId]) { return; }

		var city = Cities.byID[m.toCityId];
		if (city.tileId != m.toTileId && !Options.TowerOptions.wilds) { return; }
		if (m.marchType == 3 && !Options.TowerOptions.scouting) { return;}

		t.BuildMessage(m);

		if (m.marchStatus == 9) {  // recalled marches
			// Need to recheck arrival times to this city to take into account recalled march...
			var now = unixTime();
			Options.TowerOptions.LatestAttackTimes[m.toCityId] = now;
			for (var k in local_atkinc) {
				var n = local_atkinc[k];
				if ((n.marchType==3 || n.marchType==4) && (n.marchId != m.mid)) { // weird, cos it comes from the game!
					if (n.toCityId==m.toCityId && n.toTileId==Cities.byID[m.toCityId].tileId) {
						if (Number(n.arrivalTime) > Options.TowerOptions.LatestAttackTimes[m.toCityId]) {
							Options.TowerOptions.LatestAttackTimes[m.toCityId] = Number(n.arrivalTime);
						}
					}
				}
			}
			// now recheck the global var
			Options.TowerOptions.LastAttack = now;
			for (var cid in Options.TowerOptions.LatestAttackTimes) {
				if (Number(Options.TowerOptions.LatestAttackTimes[cid]) > Options.TowerOptions.LastAttack) {
					Options.TowerOptions.LastAttack = Number(Options.TowerOptions.LatestAttackTimes[cid]);
				}
			}
			saveOptions();
			return; // recalled marches leave here..
		}

		// alert sound!

		if (Options.TowerOptions.alertSound.enabled){
			t.soundTheAlert(m.marchType);
			if (m.arrivalTime > Options.TowerOptions.alertSound.expireTime) {
				Options.TowerOptions.alertSound.expireTime = m.arrivalTime;
			}
		}

		// Perform Automatic Events

		if (city.tileId == m.toTileId) {
			if (!Options.TowerOptions.SaveCityState[m.toCityId]) {
				actionLog(Cities.byID[m.toCityId].name+': Under Attack!','TOWER');
				var CityState = new Object();
				CityState.cityId = m.toCityId;
				CityState.tileId = city.tileId;
				CityState.Guardian = Seed.guardian[Cities.byID[m.toCityId].idx].type;
				CityState.AllowMarches = true;
				CityState.AllowRaids = true;
				Options.TowerOptions.SaveCityState[m.toCityId] = CityState;

				if (afkdetector.isAFK || !Options.TowerOptions.AFKEvents) {
					Options.TowerOptions.SaveCityState[m.toCityId].AllowMarches = (!Options.TowerOptions.StopMarches);
					Options.TowerOptions.SaveCityState[m.toCityId].AllowRaids = (!Options.TowerOptions.StopRaids);
					if (Options.TowerOptions.StopMarches) {
						actionLog(Cities.byID[m.toCityId].name+': Automatic march functions suspended','TOWER');
					}
					// change guardian
					if (Options.TowerOptions.ChangeGuardian) {
						if (Seed.guardian[Cities.byID[m.toCityId].idx].type != "wood") {
							actionLog(Cities.byID[m.toCityId].name+': Switching to Wood Guardian','TOWER');
							SwitchGuardian(m.toCityId,"wood");
						}
					}
					// stop raids in city...
					if (Options.TowerOptions.StopRaids) {
						actionLog(Cities.byID[m.toCityId].name+': Stopping Raids','TOWER');
						ToggleCityRaids (m.toCityId,'stopAll');
					}
				}
			}
			Options.TowerOptions.RecentCityActivity[m.toCityId] = true;

			if (!Options.TowerOptions.RecentActivity) { // save current TR
				Options.TowerOptions.SaveTR = Seed.throne.activeSlot;
				if (afkdetector.isAFK || !Options.TowerOptions.AFKEvents) {
					if (Options.TowerOptions.ChangeTR) {
						if (parseIntNan(Options.TowerOptions.ChangeTRPreset) != 0 && Options.TowerOptions.ChangeTRPreset != Seed.throne.activeSlot) {
							actionLog('Changing Throne Room','TOWER');
							SwitchThroneRoom(Options.TowerOptions.ChangeTRPreset);
						}
					}
				}
			}
			Options.TowerOptions.RecentActivity = true;
		}
		saveOptions(); // do once!
	},

	BuildMessage : function (m) {
		var t = Tabs.Options;
		var target, atkType, who;
		var attacker = uW.g_js_strings.commonstr.attacker;
		var scoutingat = '';
		var attack = uW.g_js_strings.commonstr.attacker;
		var attackrecalled = uW.g_js_strings.incomingattack.attackrecalled;
		var troops = uW.g_js_strings.commonstr.troops;
		var wilderness = uW.g_js_strings.commonstr.wilderness;
		var estimatedarrival = uW.g_js_strings.attack_generateincoming.estimatedarrival;
		var encampall = uW.g_js_strings.openEmbassy.encampall;
		var defending = uW.g_js_strings.commonstr.defending;
		var status = uW.g_js_strings.commonstr.status;
		var hidesanct = uW.g_js_strings.openCastle.hidesanct;
		var orderdefend = uW.g_js_strings.openCastle.orderdefend;
		var technology = uW.g_js_strings.commonstr.technology;
		var atkType;

		if (m.marchType == 3){
			if (!Options.TowerOptions.scouting) { return;}
			var scoutingat = uW.g_js_strings.modal_messages_viewreports_view.scoutingat;
			atkType = tx('SCOUT');
		} else if (m.marchType == 4){
			atkType = tx("ATTACK");
		} else {
			return;
		}

		var city = Cities.byID[m.toCityId];
		if (city.tileId == m.toTileId) {
			target = uW.g_js_strings.commonstr.city+ ' '+city.name+' ('+ city.x +','+ city.y + ')';
			if(Options.TowerOptions.towercitytext[m.toCityId] && Options.TowerOptions.towercitytext[m.toCityId] != "") {
				target += '|'+Options.TowerOptions.towercitytext[m.toCityId];
			}
		}
		else {
			if (!Options.TowerOptions.wilds) { return; }
			target = wilderness;
			for (var k in Seed.wilderness['city'+m.toCityId]) {
				if (Seed.wilderness['city'+m.toCityId][k].tileId == m.toTileId) {
					target += '('+ Seed.wilderness['city'+m.toCityId][k].xCoord +','+ Seed.wilderness['city'+m.toCityId][k].yCoord + ')';
					break;
				}
			}
		}
		if (Seed.players['u'+m.pid]) {
			 who = Seed.players['u'+m.pid].n;
		 }
		else {
			if (m.players && m.players['u'+m.pid]) {
				 who = m.players['u'+m.pid].n;
			}
			else {
				who = tx('Unknown');
			}
		}

		if (m.fromXCoord) { who += '('+ m.fromXCoord +','+ m.fromYCoord + ')'; }
		if (m.aid && m.aid!=0) {who += ' ('+getDiplomacy(m.aid)+')'; }

		var email = "";
		if(m.marchStatus == 9) {
			msg = '.::.|'+scoutingat+' '+target+' || '+attacker+' '+ who +' || '+attackrecalled;
		}
		else {
			var ArrTime = uW.g_js_strings.incomingattack.unknown;
			if (m.arrivalTime) ArrTime = uW.timestr(parseInt(m.arrivalTime - unixTime()));
			msg = '..:.|'+Options.TowerOptions.aPrefix +' || '+scoutingat+' '+target+' || '+attacker+' '+ who +' || '+estimatedarrival+': '+ ArrTime;
			email += '<FONT color="red"><B>'+ atkType +'</font></b><BR>';
			email += '<BR>Target: ' + city.name + ' ('+ city.x +','+ city.y + ')';
			email += '<BR>Attacker: ' + who;
			email += '<BR>ETA: ' + FullDateTime(m.arrivalTime);
			email += '<BR><BR><U>Troops:</u>';
		}
		if (m.pid) { msg+= ' || UID: ' + enFilter(m.pid); }
		msg+= ' || '+troops+': ';

		if (m.unts) {
			for (var k in m.unts) {
				var uid = parseInt(k.substr(1));
				var UNTCOUNT = enFilter(m.unts[k]);
				msg += '|'+UNTCOUNT +' '+ uW.unitcost['unt'+uid][0] +', ';
				email += '<BR><img src="'+IMGURL+'units/unit_'+k.slice(1)+'_30.jpg?6545"> '+m.unts[k]+ ' '+ uW.unitcost['unt'+uid][0];
			}
		}
		else {
			if (m.cnt) {
				msg += ' '+m.cnt;
				email += '<BR>'+m.cnt;
			}
			else {
				msg += ' Unknown';
				email += '<BR>Unknown';
			}
		}

		if (m.marchStatus != 9) { // pointless showing following info for recalls
			if ((safecall.indexOf(m.pid) < 0 || trusted) && m.championInfo) {
				msg += ' || '+uW.g_js_strings.report_view.champion_stats+':';
				var got202 = false;
				for (var cy in m["championInfo"].effects[1]) {
					if (cy<300) {
						// missing bonus damage?
						if (cy == '202') { got202 = true; }
						if ((cy == '203') && !got202) { msg += '|'+uW.g_js_strings.effects.name_202+': 0,'; }
						str = eval('uW.g_js_strings.effects.name_'+cy);
						if (str && str!= "") { msg += '|'+str+': '+m["championInfo"].effects[1][cy]+', '; }
						else { break; }
					}
				}
				msg += ' | '+uW.g_js_strings.report_view.troop_stats+':';
				for (var cy in m.championInfo.effects[2]) {
					msg += '|' +eval("uW.g_js_strings.effects.name_"+cy)+ ': ' +m.championInfo.effects[2][cy]+', ';
				}
			}

			if (city.tileId == m.toTileId) {
				var baseProtection =0;
				var totalSthPrt = 0;
				var SthPrtResearch = parseIntNan(Seed.tech.tch14);
				var TRStHsBoost = Math.min(equippedthronestats(89), 1250);
				if (TRStHsBoost == 0) TRStHsBoost = 1
				var researchToApply = ((SthPrtResearch / 10) + 1);
				var TRBoostToApply = ((TRStHsBoost / 100) + 1);
				baseProtection = StorehouseLevels[parseIntNan(getUniqueCityBuilding(city.id, 9).maxLevel)];
				totalSthPrt = addCommas(parseInt((baseProtection * researchToApply) * TRBoostToApply))
				msg += '|| '+tx('Storehouse Protection')+':|' + totalSthPrt + ' (TR ' + TRStHsBoost + '%)';

				if (Options.TowerOptions.upkeep==true) {
					var trupkeepreduce = 0;
					trupkeepreduce = Math.min(equippedthronestats(79), 33);
					var trprodres = Math.min(equippedthronestats(82),2000);
					var trprod = [0, 0, 0, 0, 0];
					trprod[1] = Math.min(equippedthronestats(83), 2000)+trprodres;
					var rp = getResourceProduction(m.toCityId);
					var usage = parseInt(Seed.resources['city'+m.toCityId]['rec1'][3]);
					var bp = uW.cm.Resources.getProductionBase(1,m.toCityId);
					var upkbase = uW.cm.Resources.getUpkeep(1,m.toCityId) / (1 - trupkeepreduce / 100);
					usage = parseIntNan(usage - upkbase * trupkeepreduce / 100);
					usage = (parseIntNan(rp[1] - usage + bp * trprod[1] / 100));
					if (usage < 0) {
						var timeLeft = parseInt(Seed.resources["city"+m.toCityId]['rec1'][0]) / 3600 / (0 - usage) * 3600;
						if (timeLeft < 86313600) {
							msg+= '|| '+tx('Food Remaining')+': ' + timestrShort(timeLeft);
						}
					}
				}

				var emb = getUniqueCityBuilding(m.toCityId, 8);
				if (emb.count == 0) {
					msg += '||'+tx("No Embassy!");
					msg += '| '+tx("Do not try and reinforce");
				}
				else {
					var availSlots = emb.maxLevel;
					for (var k in Seed.queue_atkinc){
						if ((Seed.queue_atkinc[k].toCityId == m.toCityId) && (Seed.queue_atkinc[k].marchStatus == 2) && (Seed.queue_atkinc[k].fromCityId != m.toCityId) && (Cities.byID[Seed.queue_atkinc[k].fromCityId]==null)) {
							--availSlots;
						}
					}
					msg += ' || '+encampall+' '+ (emb.maxLevel-availSlots) +'/'+ emb.maxLevel +' ';

					if (Options.TowerOptions.defend==true) {
						if (parseInt(Seed.citystats["city" + m.toCityId].gate)==1) {
							msg+= '||'+status+': '+orderdefend;
						}
						else {
							msg+= '||'+status+': '+hidesanct;
						}
					}

					if (Options.TowerOptions.tech==true) {
						msg+= '||'+technology+':|Fletching '+parseInt(Seed.tech.tch13)+', |Healing Potions '+parseInt(Seed.tech.tch15)+', |Poisoned Edge '+parseInt(Seed.tech.tch8)+', |Metal Alloys '+parseInt(Seed.tech.tch9)+', |Magical Mapping '+parseInt(Seed.tech.tch11)+', |Alloy Horseshoes '+parseInt(Seed.tech.tch12)+', ';
					}

				}
			}
			if (Options.TowerOptions.DefendMonitor==true) {
				msg+= ' || '+tx('My UID')+': ' + enFilter(uW.tvuid);
			}	
			msg+= ' || '+tx('March Id')+': ' + enFilter(m.mid);
		}

		var totTroops = 0;
		if (!m.unts) { // no unit info, watchtower not high enough? Force to alliance chat not whisper.
			totTroops = 99999999;
		}
		else {
			for (var k in m.unts){ totTroops += Number(m.unts[k]); }
		}

		if (Options.TowerOptions.aChat) {
			if (Options.TowerOptions.whisper && !isNaN(totTroops) && totTroops < Options.TowerOptions.whisperTroops) {
				sendChat("/" + Seed.player.name + ' ' + msg); // whisper
			}
			else {
				sendChat ("/a "+  msg); // Alliance chat
			}
		}

		if(Options.TowerOptions.email) {
			if (uW.koc2Mail) {
				var now = uW.unixtime();
				if (!Options.TowerOptions.lastEmailSent || (Options.TowerOptions.lastEmailSent + (10*60) < now)) {
					koc2Mail.towerToMail(email);
					Options.TowerOptions.lastEmailSent = now;
					saveOptions();
				}
			}
		}
	},

	sendDFReport : function () {
		var t = Tabs.Options;
		if (!Options.DFReport) { return; }

		var now = unixTime();

		if (now < (parseInt(Options.LastDFReport)+(Options.DFReportInterval*60*60)))
			return;

		var message = tx('Dark Forest Report for')+' '+Options.DFReportInterval+' '+tx('hours (or since last report)')+' %0A';

		if (Options.ReportOptions.DeleteRptdf) {
			var total = DeleteReports.ReportLog.DFCount;
			if (total==0) { // don't report if no DF's attacked in timeframe.
				actionLog('No report generated as no dark forests attacked in timeframe','REPORTS');
				Options.LastDFReport = now;
				saveOptions();
				return;
			}

			message +='%0A';
			message += tx('Number of Dark Forests Attacked')+': '+total+'%0A';
			message +='%0A';
			message += tx('Miscellaneous items')+': %0A';
			for (var z in DeleteReports.ReportLog.ItemsFoundDF) {
				message += uW.g_js_strings.commonstr.found+' '+uW.ksoItems[z].name+' x '+DeleteReports.ReportLog.ItemsFoundDF[z]+'%0A';
			}

			message +='%0A';
			message += tx('Jewel Stats')+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.JewelItemsFoundDF){
				itemcount += DeleteReports.ReportLog.JewelItemsFoundDF[z];
				message += eval('uW.g_js_strings.jewel.quality_'+Number(z-1))+' Jewel x '+DeleteReports.ReportLog.JewelItemsFoundDF[z]+'%0A';
			}
			message += tx('Total Jewels Found')+': '+itemcount+'%0A';

			message +='%0A';
			message += tx('Throne Stats')+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.ThroneItemsFoundDF){
				itemcount += DeleteReports.ReportLog.ThroneItemsFoundDF[z].amount;
				message += strQuality(DeleteReports.ReportLog.ThroneItemsFoundDF[z].quality)+' '+DeleteReports.ReportLog.ThroneItemsFoundDF[z].type+' x '+DeleteReports.ReportLog.ThroneItemsFoundDF[z].amount+'%0A';
			}
			message += tx('Total Throne Room Items Found')+': '+itemcount+'%0A';

			message +='%0A';
			message += uW.g_js_strings.report_view.champion_stats+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.ChampItemsFoundDF){
				itemcount += DeleteReports.ReportLog.ChampItemsFoundDF[z].amount;
				message += strQuality(DeleteReports.ReportLog.ChampItemsFoundDF[z].quality)+' '+DeleteReports.ReportLog.ChampItemsFoundDF[z].type+' x '+DeleteReports.ReportLog.ChampItemsFoundDF[z].amount+'%0A';
			}
			message += tx('Total Champion Equipment Found')+': '+itemcount+'%0A';
		}
		else {
			message += tx('Found item details only available if the option "Delete dark forest reports" is ticked')+'%0A';
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.emailTo = Seed.player['name'];
		params.subject = tx("Dark Forest Overview");

		if (uW.koc2Mail && Options.DFReportEmail) {
			koc2Mail.customMail(params.emailTo,params.subject,message);
		}

		params.message = message;
		params.requestType = "COMPOSED_MAIL";

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					DeleteLastMessage();
					if (Options.ReportOptions.DeleteRptdf) {
						DeleteReports.ReportLog.ItemsFoundDF = {};
						DeleteReports.ReportLog.ThroneItemsFoundDF = {};
						DeleteReports.ReportLog.ChampItemsFoundDF = {};
						DeleteReports.ReportLog.JewelItemsFoundDF = {};
						DeleteReports.ReportLog.DFCount = 0;
						DeleteReports.saveLog();
					}
				}
			},
		});

		Options.LastDFReport = now;
		saveOptions();
	},
}

/*********************************** Reference Tab ***********************************/

Tabs.Reference = {
	tabOrder: 1120,
	tabLabel: 'Reference',
	unitsaccuracy: [],
	z: null,
	keyz: null,
	myDiv: null,
	provMapCoords : {	imgWidth: 710,
						imgHeight: 708,
						mapWidth: 670,
						mapHeight: 670,
						leftMargin: 31,
						topMargin: 19
					},
	UniqueTRItems : null,
	UniqueCHItems : null,
	championStatTiers:{},
	chSortArray : [],
	trSortArray : [],

	init: function (div) {
		var t = Tabs.Reference;
		t.z = uW.cm.WorldSettings.getSettingAsObject("UNIT_ACCURACY_MODIFIER");
		t.keyz = uW.Object.keys(t.z);

		// accuracy matrix only has certain troops and defences

		t.unitsaccuracy = [];
		for (var ui=0;ui<t.keyz.length;ui++) {
			if (t.keyz[ui]) {
				var i = uW.cm.UNIT_TYPES[t.keyz[ui]];
				if (i==null) {
					if (t.keyz[ui]=="FORTIFICATION_TYPE_ARCHERTOWER") { i = 53; }
					else if (t.keyz[ui]=="FORTIFICATION_TYPE_GREEK_FIRE")  { i = 63; }
					else { i = 0; } // no idea what this is, but we need it in the array
				}
				t.unitsaccuracy.push(i);
			}
		}

		var effectTiers = CE_EFFECT_TIERS;
		var effObjSize=0,effsplit={},championStatTiers={},basegrowth={};
		for (var k in effectTiers) {
			effsplit=effectTiers[k]["Id_Tier"].split(",");
			championStatTiers[''+effsplit[0]]={};
		}
		for (var k in effectTiers) {
			effsplit=effectTiers[k]["Id_Tier"].split(",");
			basegrowth={};
			basegrowth['base']=effectTiers[k]["Base"];
			basegrowth['growth']=effectTiers[k]["Growth"];
			championStatTiers[''+effsplit[0]][''+effsplit[1]]=basegrowth;
		}
		t.championStatTiers=championStatTiers;

		var UniqueItems = {};
		eval(GM_getResourceText("champion_uniques"));
		t.UniqueCHItems = JSON.parse(JSON.stringify(UniqueItems));

		for (var i=28001;i<29000;i++) {
			if (!uW.itemlist['i'+i]) continue;
			if (!t.UniqueCHItems[i]) {
				t.UniqueCHItems[i] = {Id:i,Name:uW.itemlist['i'+i].name, Effects:[],Faction:0,Type:0};
			}
			var CHCard = t.BuildChampCard(i,0);
			uW.ksoItems[i].description = t.DisplayCHCard(CHCard,false);
		}

		UniqueItems = {};
        UniqueItems = CM.WorldSettings.getSettingAsObject("TR_UNIQUE_ITEMS");
        for (var k in UniqueItems) {
            var throne_item = UniqueItems[k];
            if (parseInt(throne_item.Id) < 29000) delete UniqueItems[k];
            if (parseInt(throne_item.Id) == 30262 || parseInt(throne_item.Id) == 30264 || parseInt(throne_item.Id) == 30266) { throne_item.Name = throne_item.Name + ' ('+uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(throne_item.Faction)].toLowerCase()+')';};
            if (parseInt(throne_item.Id) == 30261 || parseInt(throne_item.Id) == 30263 || parseInt(throne_item.Id) == 30265) { throne_item.Name = throne_item.Name + ' ('+uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(throne_item.Faction)].toLowerCase()+')';};
            if (parseInt(throne_item.Id) == 30230 || parseInt(throne_item.Id) == 30240 || parseInt(throne_item.Id) == 30250) { throne_item.Name = throne_item.Name + ' ('+uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(throne_item.Faction)].toLowerCase()+')';};
            if (parseInt(throne_item.Id) == 30231 || parseInt(throne_item.Id) == 30241 || parseInt(throne_item.Id) == 30251) { throne_item.Name = throne_item.Name + ' ('+uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(throne_item.Faction)].toLowerCase()+')';};
        }
		t.UniqueTRItems = JSON.parse(JSON.stringify(UniqueItems));
		for (var i in t.UniqueTRItems) {
			if (!uW.itemlist['i'+i]) continue;
			var TRCard = t.BuildThroneCard(i,1);
			uW.ksoItems[i].description = t.DisplayTRCard(TRCard,false);
		}

		t.chSortArray = [];
        for (var k in t.UniqueCHItems) {
			t.chSortArray.push(t.UniqueCHItems[k]);
		}	
		t.chSortArray.sort(function(a, b){ var x=a.Set-b.Set; var y=0; if (a.name<b.name) y=-1; if (a.name>b.name) y=1; return (x==0)?y:x; });

		t.trSortArray = [];
        for (var k in t.UniqueTRItems) {
			t.trSortArray.push(t.UniqueTRItems[k]);
		}	
		t.trSortArray.sort(function(a, b){ if (a.Name<b.Name) return -1; if (a.Name>b.Name) return 1; return 0; });
		
		t.myDiv = div;
	},

	show: function () {
		var t = Tabs.Reference;
		var troopa, troopb;

		dt = new Date();
		dt.setTime(Seed.player.datejoinUnixTime * 1000);

		m = '<div>';
		m += '<div class="divHeader" align="center">'+tx('REFERENCE SECTION')+'</div>';
		m += '<div align="center">';
		m += '<table align=center>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+uW.g_js_strings.commonstr.nametx+':</td><td class=xtab><b>'+Seed.player.name+'</b></td><td class=xtab align=right>'+tx('Playing Since')+':</td><td class=xtab><b>'+dt.toLocaleDateString()+'</b></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+uW.g_js_strings.commonstr.domain+':</td><td class=xtab><b>'+uW.domainName+'</b></td><td class=xtab align=right>'+uW.g_js_strings.commonstr.alliance+':</td><td class=xtab><b>'+getMyAlliance()[1]+'</b></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+tx('Camelot Version')+':</td><td class=xtab><b>'+anticd.getKOCversion()+'</b></td><td class=xtab align=right>'+tx('PowerBot+ Version')+':</td><td class=xtab><b>'+Version+'</b></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+tx('Browser')+':</td><td class=xtab><b>'+FFVersion.Browser+' '+FFVersion.Version+'</b></td><td class=xtab align=right>'+GMVersion.Handler+':</td><td class=xtab><b>'+GMVersion.Version+'</b></td></tr>';
		m += '</table><br></div>';

		// links

		m += '<a id=btLinkLink class=divLink ><div class="divHeader" align="left"><img id=btLinkArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('USEFUL LINKS')+'</div></a>';
		m += '<div id=btLink class=divHide>';

		m += '<TABLE align=center cellpadding=1 cellspacing=0>';
		m += '<TR><TD class=xtabHD width="300px">'+tx('Scripts')+'</td><TD class=xtabHD width="300px">'+tx('Information sites')+'</td></tr>';
		m += '<TR><TD class=xtab><a href="https://www.facebook.com/PowerBotPlus" target="_blank">'+tx('Power Bot Plus (Facebook Page)')+'</a></td>';
		m += '<TD class=xtab><a href="https://www.facebook.com/groups/SolarsKOCinfoPage/" target="_blank">'+tx('KOC Information (Solar\'s Facebook Group)')+'</a></td></tr>';
		m += '<TR><TD class=xtab><a href="https://www.facebook.com/tco4koc" target="_blank">'+tx('Throne/Champ Organizer (by Ne0)')+'</a></td>';
		m += '<TD class=xtab><a href="http://www.slideshare.net/Aderik/documents" target="_blank">'+tx('Aderik\'s Tutorials')+'</a></td></tr>';
		m += '<TR><TD class=xtab><a href="https://greasyfork.org/en/scripts/889-koc-additional-throne-monitor" target="_blank">'+tx('Additional Throne Monitor (Greasyfork)')+'</a></td>';
		m += '<TD class=xtab><a href="http://koctipps.w4f.eu/" target="_blank">'+tx('KOC Tips and Tricks (German Only)')+'</a></td></tr>';
		if (KOCBYTE_ON) {
			m += '<TR><TD class=xtab><a href="https://greasyfork.org/en/scripts/19269-kocbyte" target="_blank">'+tx('KoCByte (Script)')+'</a></td>';
			m += '<TD class=xtab><a href="http://www.kocbyte.com" target="_blank">'+tx('KoCByte')+'</a></td></tr>';
		}
		m += '<TR><TD class=xtab><a href="https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/versions/?page=2#version-1.15.1-signed" target="_blank">'+tx('Greasemonkey (Version 1.15)')+'</a></td>';
		m += '<TD class=xtab><a href="http://koc.wikia.com/wiki/" target="_blank">'+tx('KofC Wiki')+'</a></td></tr>';
		m += '<TR><TD class=xtab><a href="http://tampermonkey.net/" target="_blank">Tampermonkey (Chrome, Opera, Safari etc)</a></td>';
		m += '<TD class=xtab><a href="http://f89kocguide.weebly.com/" target="_blank">'+tx('F89 Unofficial KOC Guide')+'</a></td></tr>';
		m += '<TR><TD class=xtab><a href="https://addons.mozilla.org/en/firefox/addon/scriptish/versions/" target="_blank">Scriptish</a></td>';
		m += '<TD class=xtab><a href="http://koc.weezeewig.com/index.sjs?f=ListServers" target="_blank">'+tx('KofC Mapper')+'</a></td></tr>';
		m += '</table><BR></div>';

		// map

		m += '<a id=btMapLink class=divLink ><div class="divHeader" align="left"><img id=btMapArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('MAP')+'</div></a>';
		m += '<div id=btMap class=divHide>';

		m += '<BR><TABLE align=center cellpadding=1 cellspacing=0>';
		m += '<TR><TD colspan=2 class=xtab align=left><DIV id=ptProvMap style="height:' + t.provMapCoords.imgHeight + 'px; width:' + t.provMapCoords.imgWidth + 'px; background-repeat:no-repeat; background-image:url(\'' + URL_PROVINCE_MAP + '\')"></div></td></tr>';
		m += '<TR><TD colspan=2 class=xtab align=center><DIV style="font-size:14px; border: 1px solid; background-color:white; margin:20px 3px 3px 0px; padding:4px" id=ptdistout>&nbsp;</div></td></tr>';
		m += '<TR><TD class=xtab align=left><B>'+tx('First Location')+': </b></td><TD class=xtab>&nbsp;X:&nbsp;<INPUT id=calcX type=text\>&nbsp;Y:&nbsp;<INPUT id=calcY type=text\> '+tx('Or, choose city')+': <SPAN id=ptloc1></span></td></tr>';
		m += '<TR><TD class=xtab align=left><B>'+tx('Second Location')+': </b></td><TD class=xtab>&nbsp;X:&nbsp;<INPUT id=calcX2 type=text\>&nbsp;Y:&nbsp;<INPUT id=calcY2 type=text\> '+tx('Or, choose city')+': <SPAN id=ptloc2></span></td></tr></table>';
		m += '<br></div>';

		// unit information

		var rownum = 1;

		m += '<a id=btUnitInfoLink class=divLink ><div class="divHeader" align="left"><img id=btUnitInfoArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('UNIT INFORMATION')+'</div></a>';
		m += '<div id=btUnitInfo class=divHide>';

		var u = '<TABLE align=center cellpadding=1 cellspacing=0>\
			<TR align=center><TD class=xtab></td><TD class=xtabHL colspan=5><B>'+tx('COST TO BUILD')+'</b></td><TD class=xtabHL colspan=7><B>'+tx('BASE STATS')+'</b></td><TD class=xtabHL><B>'+tx('Upkeep')+'</b></td></tr>\
			<TR valign=bottom align=right><TD class=xtab></td><TD class=xtabHL>'+uW.g_js_strings.commonstr.food+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.wood+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.stone+'</td>\
			<TD class=xtabH>'+uW.g_js_strings.commonstr.ore+'</td><TD class=xtabH>'+tx('Pop')+'</td><TD class=xtabHL>'+uW.g_js_strings.commonstr.might+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.life+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.atk+'</td><TD class=xtabH>'+tx('Def')+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.speed+'</td><TD class=xtabH>'+uW.g_js_strings.commonstr.range+'</td><TD class=xtabH>'+uW.g_js_strings.modal_barracks_train.load+'</td>\
			<TD class=xtabHL>'+uW.g_js_strings.commonstr.food+'</td></tr>\
			<TR style="height:1px;"><TD style="padding:0px; spacing:0px; height:1px; border-color:black; border-width: 1px; border-style: none none solid none" colspan=14></td></tr>';
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			if (++rownum % 2)
				rsty = 'evenRow';
			else
				rsty = 'oddRow';
			cost = uW.unitcost['unt' + i]; //  NAME, Food, Wood, Stone, Ore, ?, IdlePop, Time
			stats = uW.unitstats['unt' + i]; //  Life, Attack, Defense, Speed, Range, Load
			food = uW.unitupkeeps[i];
			might = uW.unitmight['unt' + i];
			u += '<TR class="'+rsty+'" align=right><TD class=xtab align=left><B>' + cost[0].substr(0, 16) + '</b></td><TD class=xtabL>' + cost[1] + '</td><TD class=xtab>' + cost[2] + '</td>\
				<TD class=xtab>' + cost[3] + '</td><TD class=xtab>' + cost[4] + '</td><TD class=xtab>' + cost[6] + '</td><TD class=xtabL>' + might + '</td>\
				<TD class=xtab>' + stats[0] + '</td><TD class=xtab>' + stats[1] + '</td><TD class=xtab>' + stats[2] + '</td><TD class=xtab>' + stats[3] + '</td>\
				<TD class=xtab>' + stats[4] + '</td><TD class=xtab>' + stats[5] + '</td><TD class=xtabL>' + food + '</td></tr>';
		}
		u += '<TR class=xtabLine><TD colspan=14 class=xtabLine></td></tr>';
		for (var k in uW.fortcost) {
			if (++rownum % 2)
				rsty = 'evenRow';
			else
				rsty = 'oddRow';
			cost = uW.fortcost[k]; //  NAME, Food, Wood, Stone, Ore, ?, IdlePop, Time
			fi = k.substring(3);
			stats = uW.fortstats['unt' + fi]; //  Life, Attack, Defense, Speed, Range, Load/Space
			food = 0;
			might = fortmight['f' + fi];
			var name = cost[0].replace('Defensive', '');
			name = name.replace('Wall-Mounted', '');
			u += '<TR class="'+rsty+'" align=right><TD align=left class=xtab><B>' + name + '</b></td><TD class=xtabL>' + cost[1] + '</td><TD class=xtab>' + cost[2] + '</td>\
				<TD class=xtab>' + cost[3] + '</td><TD class=xtab>' + cost[4] + '</td><TD class=xtab>' + cost[6] + '</td><TD class=xtabL>' + might + '</td>\
				<TD class=xtab>' + stats[0] + '</td><TD class=xtab>' + stats[1] + '</td><TD class=xtab>' + stats[2] + '</td><TD class=xtab>' + stats[3] + '</td>\
				<TD class=xtab>' + stats[4] + '</td><TD class=xtab>' + stats[5] + '</td><TD class=xtabL>' + food + '</td></tr>';
		}
		u += '<TR class=xtabLine><TD colspan=14 class=xtabLine></td></tr>';

		m += u + '</table><BR></div>';

		// research

		var rownum = 1;

		m += '<a id=btResearchInfoLink class=divLink ><div class="divHeader" align="left"><img id=btResearchInfoArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('RESEARCH LEVELS')+'</div></a>';
		m += '<div id=btResearchInfo class=divHide>';

		m += '<TABLE width=95% align=center class=xtab><TR valign=top align=center><td><table class=xtab border=1px cellpadding=2 cellspacing=0><TR valign=top align=left><td><b>'+uW.g_js_strings.commonstr.research+'</b></td></tr>';
		for (var i in uW.techcost) {
			if (++rownum % 2)
				rsty = 'evenRow';
			else
				rsty = 'oddRow';
			var csty = '<span>';
			if (Seed.tech[i] == uW.Research.Methods.maxLevel(i.split("tch")[1], 1)) csty = '<span style="color:#080">';
			if (Seed.tech[i] == 0) csty = '<span style="color:#800">';
			m += '<tr class="'+rsty+'"><TD style="width:150px;">' + uW.techcost[i][0] + '</td><TD align=center style="width:50px; max-width:150px;">'+csty+Seed.tech[i]+'</span></td></tr>';
		}
		m += '</table></td>';
		m += '<td><table class=xtab border=1px cellpadding=2 cellspacing=0><TR valign=top align=left><td><b>'+tx('Briton Research')+'</b></td></tr>';
		rownum = 1;
		for (var i in uW.techcost2) {
			if (++rownum % 2)
				rsty = 'evenRow';
			else
				rsty = 'oddRow';
			var csty = '<span>';
			if (Seed.tech2[i] == uW.Research.Methods.maxLevel(i.split("tch")[1], 2)) csty = '<span style="color:#080">';
			if (Seed.tech2[i] == 0) csty = '<span style="color:#800">';
			m += '<tr class="'+rsty+'"><TD style="width:150px;">' + uW.techcost2[i][0] + '</td><TD align=center style="width:50px; max-width:150px;">'+csty+Seed.tech2[i]+'</span></td></tr>';
			m += '</td></tr>';
		}
		m += '</table></td></tr></table></div>';

		// tr Caps

		m += '<a id=btRefCapsLink class=divLink ><div class="divHeader" align="left"><img id=btRefCapsArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('THRONE ROOM CAPS')+'</div></a>';
		m += '<div id=btRefCaps class=divHide>';

		var caps = '<br><TABLE class=xtab align=center style="background:'+Options.Colors.Panel+';border:2px;">';
		caps += '<TR><TD width="200px"><B>'+tx('Effect Name')+'</b></td><TD width="50px"><B>'+uW.g_js_strings.commonstr.max+'</b></td><TD width="50px"><B>'+tx('Min')+'</b></td><TD style="border:0;width:10px">&nbsp;</td><TD width="200px"><B>'+tx('Effect Name')+'</b></td><TD width="50px"><B>'+uW.g_js_strings.commonstr.max+'</b></td><TD width="50px"><B>'+tx('Min')+'</b></td></tr><TR>';

		var boosts = [];
		for (var k in uW.cm.thronestats.boosts) {
			if (uW.cm.thronestats.boosts[k].BoostName) {
				boosts.push(uW.cm.thronestats.boosts[k]);
			}
		}
		boosts.sort(function(a, b){ return a.BoostName > b.BoostName});

		var counter = 0;
		for (var k in boosts) {
			counter++
			var boost = boosts[k]
			if (boost.BoostName) {
				caps += '<TD>'+boost.BoostName+'</td><TD>'+boost.Max+'<SPAN id=capmaxPerc_'+k+'></span></div></td><TD>'+boost.Min+'<SPAN id=capminPerc_'+k+'></span></div>';
				if (counter % 2 == 0) {
					caps += '<TR>';
				} else {
					caps += '</td><TD style="border:0">';
				}
			}
		}
		m += caps + '</table><br></div>';

		// throne uniques

		m += '<a id=btRefTRUniqueLink class=divLink ><div class="divHeader" align="left"><img id=btRefTRUniqueArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('UNIQUE THRONE ROOM CARDS')+'</div></a>';
		m += '<div id=btRefTRUnique class=divHide></div>';

		// champ uniques

		m += '<a id=btRefCHUniqueLink class=divLink ><div class="divHeader" align="left"><img id=btRefCHUniqueArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('UNIQUE CHAMPION CARDS')+'</div></a>';
		m += '<div id=btRefCHUnique class=divHide></div>';

		// accuracy

		m += '<a id=btRefAccuracyLink class=divLink ><div class="divHeader" align="left"><img id=btRefAccuracyArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('ACCURACY MATRIX')+'</div></a>';
		m += '<div id=btRefAccuracy class=divHide>';

		var main = '<DIV style="max-height:535px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px";overflow-x:scroll;"><TABLE cellpadding=0 cellspacing=0 align=left><TR>';
		main += '<TD class=xtab></td><TD align=center colspan='+ (t.unitsaccuracy.length+1) +' class=xtab><b>'+uW.g_js_strings.commonstr.target+'</b></td></tr>';
		main += '<TR><TD class=xtabHD>&nbsp;</td>';

		for (var iu=0;iu<t.unitsaccuracy.length;iu++) {
			var u = t.unitsaccuracy[iu];
			if (u!=0) {
				main += '<TD width=30 class=xtabHD align=center>' + TroopImageBig(u) + '</td>';
			}
		}
		main += '</tr>';

		var r = 0;
		for (var ui=0;ui<t.unitsaccuracy.length;ui++) {
			var u = t.unitsaccuracy[ui];
			if (u != 0) {
				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';
				main += '<TR class="'+rowClass+'">';
				if (u<50) {
					main += '<TD class=xtab align=right><b>' + uW.unitcost['unt'+u][0] + '</b></td>';
				}
				else {
					var rowtext = uW.fortcost['frt'+u][0];
					if (u==53) { rowtext = tx('Crossbows'); } // "Wall Mounted Crossbows" is pointlessly long!
					main += '<TD class=xtab align=right><b>' + rowtext + '</b></td>';
				}
				troopa = t.keyz[ui];
				for (var uj=0;uj<t.unitsaccuracy.length;uj++) {
					var cellstyle = '';
					if (ui==uj) { cellstyle = 'style="background: rgba(0,0,0,0.10);"'; }
					troopb = t.keyz[uj];
					if (!t.z[troopa] || !t.z[troopa][troopb])
						main += '<TD class=xtab align=center '+cellstyle+'>??</td>';
					else
						main += '<TD class=xtab align=center '+cellstyle+'>' + t.z[troopa][troopb] + '</td>';
				}
				main += '</tr>';
			}
		}
		main += '</table></div><br>';

		m += main + '</div></br>';

		t.myDiv.innerHTML = m;

		t.PaintTRUniques(ById('btRefTRUnique'));
		t.PaintCHUniques(ById('btRefCHUnique'));

		if (!OpenDiv["Reference"]) { OpenDiv["Reference"] = ""; }
		if (OpenDiv["Reference"] != "") {
			var LastOpenDiv = OpenDiv["Reference"];
			OpenDiv["Reference"] = "";
			ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,LastOpenDiv,true);
		}

		ById('btRefTRUniqueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btRefTRUnique",true)}, false);
		ById('btRefCHUniqueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btRefCHUnique",true)}, false);
		ById('btRefAccuracyLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btRefAccuracy",true)}, false);
		ById('btRefCapsLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btRefCaps",true)}, false);
		ById('btUnitInfoLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btUnitInfo",true)}, false);
		ById('btResearchInfoLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btResearchInfo",true)}, false);
		ById('btLinkLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btLink",true)}, false);
		ById('btMapLink').addEventListener ('click', function () {ToggleMainDivDisplay("Reference",100,GlobalOptions.btWinSize.x,"btMap",true)}, false);

		for (var k in boosts) {
			var boost = boosts[k]
			if (boost.CapType == "percent") {
				if (boost.Max != "none") { ById('capmaxPerc_' + k).innerHTML = '%'; }
				if (boost.Min != "none") { ById('capminPerc_' + k).innerHTML = '%'; }
			}
		}

		for (var c = 0; c < Cities.numCities; c++)
			t.makeCityImg(c, ById('ptProvMap'));
		new CdispCityPicker('ptloc1', ById('ptloc1'), true, t.eventLocChanged).bindToXYboxes(ById('calcX'), ById('calcY'));
		new CdispCityPicker('ptloc2', ById('ptloc2'), true, t.eventLocChanged).bindToXYboxes(ById('calcX2'), ById('calcY2'));
		t.eventLocChanged(Cities.cities[0], Cities.cities[0].x, Cities.cities[0].y);
	},

	makeCityImg: function (cityNum, eMap) {
		var t = Tabs.Reference;
		var city = Cities.cities[cityNum];
		var x = parseInt((t.provMapCoords.mapWidth * city.x) / 750);
		var y = parseInt((t.provMapCoords.mapHeight * city.y) / 750);
		var ce = document.createElement('div');
		ce.style.backgroundImage = "url('"+URL_CASTLE_BUT+"')";
		ce.style.backgroundSize = "16px 16px"
		ce.style.opacity = '1.0';
		ce.style.position = 'relative';
		ce.style.display = 'block';
		ce.style.width = '16px';
		ce.style.height = '16px';
		ce.style.color = 'black';
		ce.style.border = '1px solid #000';
		ce.style.fontWeight = 'bold';
		ce.style.fontSize = '10px';
		ce.style.textAlign = 'center';
		ce.style.top = (y + t.provMapCoords.topMargin - (cityNum * 16) - 8) + 'px';
		ce.style.left = (x + t.provMapCoords.leftMargin - 8) + 'px';
		ce.title = city.name+" ("+city.x+','+city.y+')';
		eMap.appendChild(ce);
		ce.innerHTML = (cityNum + 1) + '';
	},

	plotMapImg: function (markNum, eMap, x, y) {
		var t = Tabs.Reference;
		var xplot = parseInt((t.provMapCoords.mapWidth * x) / 750);
		var yplot = parseInt((t.provMapCoords.mapHeight * y) / 750);
		if (ById('plotmap_' + markNum) == null) {
			var ce = document.createElement('div');
			ce.style.background = 'black';
			ce.id = 'plotmap_' + markNum;
			ce.style.opacity = '1.0';
			ce.style.position = 'relative';
			ce.style.display = 'block';
			ce.style.width = '16px';
			ce.style.height = '16px';
			ce.style.border = '1px solid #fff';
			ce.style.color = 'white';
			ce.style.textAlign = 'center';
		} else {
			ce = ById('plotmap_' + markNum);
		}
		ce.style.top = (yplot + t.provMapCoords.topMargin - ((Cities.numCities + markNum) * 16) - 8) + 'px';
		ce.style.left = (xplot + t.provMapCoords.leftMargin - 8) + 'px';
		ce.title = "("+x+','+y+')';
		eMap.appendChild(ce);
		ce.innerHTML = (markNum + 1) + '';
	},
	eventLocChanged: function (city, x, y) {
		var t = Tabs.Reference;
		var x1 = parseInt(ById('calcX').value);
		var y1 = parseInt(ById('calcY').value);
		if (!isNaN(x1) && !isNaN(y1)) {
			t.plotMapImg(0, ById('ptProvMap'), x1, y1);
		}
		var x2 = parseInt(ById('calcX2').value);
		var y2 = parseInt(ById('calcY2').value);
		if (!isNaN(x2) && !isNaN(y2)) {
			t.plotMapImg(1, ById('ptProvMap'), x2, y2);
		}
		if (!isNaN(x1) && !isNaN(y1) && !isNaN(x2) && !isNaN(y2)) {
			var m = tx('The distance from')+' ' + x1 + ',' + y1 + ' '+tx('to')+' ' + x2 + ',' + y2 + ' '+tx('is')+': &nbsp;<B>' + distance(x1, y1, x2, y2).toFixed(2) + '</b>';
			ById('ptdistout').innerHTML = m;
		}
	},

	PaintTRUniques: function (div) {
		var t = Tabs.Reference;
		var maxlevel = CM.MAX_MASTERS_TOKEN_LEVEL;
		var itemTypes = { chair: 0, advisor: 1, window: 2, banner: 3, table: 4, trophy: 5, candelabrum: 6, hero: 7, statue: 8, pet: 9, tapestry: 10, pillar: 11 }; // must be in this order
		var itemFactions = { druid:3, fey:2, briton:1 };
		var itemLists = [];
		var selectedCard1 = 0;
		var selectedCard2 = 0;
		var selectedType1 = 0;
		var selectedType2 = 0;
		uWExportFunction('pbrefreshuniques', Tabs.Reference.GetInventory);

        for (var i in itemTypes) {
            itemLists[i] = new Array;
        }
        for (var k in t.UniqueTRItems) {
            var throne_item = t.UniqueTRItems[k];
            if (throne_item == null || !throne_item || !itemLists[trTypes[parseInt(throne_item.Type)-1]]) continue;
            itemLists[trTypes[parseInt(throne_item.Type)-1]].push(throne_item);
        }

        var m = '<div align=center style="height:480px;overflow-y:auto;">';
        m += '<TABLE width=90% class=xtabBR>';
        m += '<tr align=center><td width=50%/><td width=50%/></tr>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.type+':&nbsp;</b><select id="bttrUniqueType1">';
        m += '<option value="0">-- '+tx('ALL')+' --</option>';
        for (var type_index = 0; type_index < trTypes.length; ++type_index) {
            m += '<option value="' + trTypes[type_index] + '">' + trTypes[type_index] + '</option>';
        }
        m += '</select></div></td>';

        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.type+':&nbsp;</b><select id="bttrUniqueType2">';
        m += '<option value="0">-- '+tx('ALL')+' --</option>';
        for (var type_index = 0; type_index < trTypes.length; ++type_index) {
            m += '<option value="' + trTypes[type_index] + '">' + trTypes[type_index] + '</option>';
        }
        m += '</select></div></td>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.item+':&nbsp;</b><select id="bttrUnique1">';
        m += '<option value="0">-- '+uW.g_js_strings.commonstr.items+' --</option>';
        for (var k=0;k<t.trSortArray.length;k++) {
            var throne_item = t.trSortArray[k];
            if (throne_item == null || !throne_item) continue;
			var style = '';
			if (throne_item.Faction == 0) style = 'style="color:#aaa;"';
            m += '<option '+style+' value="' + throne_item.Id + '">' + throne_item.Name + ' </option>';
        }
        m += '</select></div></td>';

        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.item+':&nbsp;</b><select id="bttrUnique2">';
        m += '<option value="0">-- '+uW.g_js_strings.commonstr.items+' --</option>';
        for (var k=0;k<t.trSortArray.length;k++) {
            var throne_item = t.trSortArray[k];
            if (throne_item == null || !throne_item) continue;
			var style = '';
			if (throne_item.Faction == 0) style = 'style="color:#aaa;"';
            m += '<option '+style+' value="' + throne_item.Id + '">' + throne_item.Name + ' </option>';
        }
        m += '</select></div></td>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.level+':&nbsp;</b><select id="bttrUniqueLevel1">';
        m += '<option value="1" selected>1</option>';
        for (var type_index = 2; type_index < maxlevel + 1; ++type_index) {
            m += '<option value="' + type_index + '">' + type_index + '</option>';
        }
        m += '</select></div></td>';
        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.level+':&nbsp;</b><select id="bttrUniqueLevel2">';
        m += '<option value="1" selected>1</option>';
        for (var type_index = 2; type_index < maxlevel + 1; ++type_index) {
            m += '<option value="' + type_index + '">' + type_index + '</option>';
        }
        m += '</select></div></td></tr>';

        m += '<tr>';
        m += '<td id="bttrUniqueItem1" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '<td id="bttrUniqueItem2" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '</tr>';
        m += '<tr>';
        m += '<td id="bttrUniqueInv1" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '<td id="bttrUniqueInv2" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '</tr>';

        m += '</TABLE>';
        m += '</div>';

		div.innerHTML = m;

        jQuery("#bttrUniqueType1").change(function () {
            var trType = ById('bttrUniqueType1').value;
            var trList = ById('bttrUnique1');
            if (selectedCard1 == 0 || (selectedType1 != trType) && trType != 0) {
                selectedCard1 = 0;
            }
            selectedType1 = trType;
            jQuery("#bttrUnique1").empty();
            var trOption = document.createElement('option');
            trOption.text = '-- '+uW.g_js_strings.commonstr.items+' --';
            trOption.value = 0;
            trList.add(trOption);
			for (var k=0;k<t.trSortArray.length;k++) {
				var throne_item = t.trSortArray[k];
                if (throne_item == null || !throne_item) continue;
                if (trTypes[parseInt(throne_item.Type)-1] == trType || trType == 0) {
                    var trOption = document.createElement('option');
                    trOption.text = throne_item.Name;
                    trOption.value = throne_item.Id;
                    trList.add(trOption);
                }
            }

            if (selectedCard1 != 0) {
                jQuery("#bttrUnique1").val(selectedCard1);
            }

        });

        jQuery("#bttrUniqueType2").change(function () {
            var trType = ById('bttrUniqueType2').value;
            var trList = ById('bttrUnique2');
            if (selectedCard2 == 0 || (selectedType2 != trType) && trType != 0) {
                selectedCard2 = 0;
            }
            selectedType2 = trType;
            jQuery("#bttrUnique2").empty();
            var trOption = document.createElement('option');
            trOption.text = '-- '+uW.g_js_strings.commonstr.items+' --';
            trOption.value = 0;
            trList.add(trOption);
			for (var k=0;k<t.trSortArray.length;k++) {
				var throne_item = t.trSortArray[k];
                if (throne_item == null || !throne_item) continue;
                if (trTypes[parseInt(throne_item.Type)-1] == trType || trType == 0) {
                    var trOption = document.createElement('option');
                    trOption.text = throne_item.Name;
                    trOption.value = throne_item.Id;
                    trList.add(trOption);
                }
            }

            if (selectedCard2 != 0) {
                jQuery("#bttrUnique2").val(selectedCard2);
            }
        });

        jQuery("#bttrUnique1").change(function () { changeUnique1(this); });

        jQuery("#bttrUnique1").keyup(function (event) { changeUnique1(this); });

        function changeUnique1(thisObj) {
            var trID = jQuery(thisObj).val();
            var trDisplay = ById('bttrUniqueItem1');
            var trLevel = ById('bttrUniqueLevel1');
            selectedCard1 = 0;
            ConvertToCard(trID,trDisplay,trLevel);
            t.GetInventory(trID,'bttrUniqueInv1');
            selectedCard1 = trID;
            selectedType1 = i;
        }

        jQuery("#bttrUnique2").change(function () { changeUnique2(this); });

        jQuery("#bttrUnique2").keyup(function (event) { changeUnique2(this); });

        function changeUnique2(thisObj) {
            var trID = jQuery(thisObj).val();
            var trDisplay = ById('bttrUniqueItem2');
            var trLevel = ById('bttrUniqueLevel2');
            selectedCard2 = 0;
            ConvertToCard(trID,trDisplay,trLevel);
            t.GetInventory(trID,'bttrUniqueInv2');
            selectedCard2 = trID;
            selectedType2 = i;
        }

        jQuery("#bttrUniqueLevel1").keyup(function (event) { changeLevel1(); });

        jQuery("#bttrUniqueLevel1").change(function () { changeLevel1(); });

        function changeLevel1() {
            if (selectedCard1 != 0) {
                var trID = selectedCard1;
                var trDisplay = ById('bttrUniqueItem1');
                var trLevel = ById('bttrUniqueLevel1');
                trDisplay.innerHTML = '';
                ConvertToCard(trID,trDisplay,trLevel);
            }
        }

        jQuery("#bttrUniqueLevel2").keyup(function (event) { changeLevel2(); });

        jQuery("#bttrUniqueLevel2").change(function () { changeLevel2(); });

        function changeLevel2() {
            if (selectedCard2 != 0) {
                var trID = selectedCard2;
                var trDisplay = ById('bttrUniqueItem2');
                var trLevel = ById('bttrUniqueLevel2');
                trDisplay.innerHTML = '';
                ConvertToCard(trID,trDisplay,trLevel);
            }
        }

		function ConvertToCard (trID,div,lvl) {
			div.innerHTML = '';
			var TRCard = t.BuildThroneCard(trID,parseIntNan(lvl.value));
			div.innerHTML = t.DisplayTRCard(TRCard,true);
		};

	},

	BuildThroneCard : function (trID,lvl) {
		var t = Tabs.Reference;
		var TRCard = {};
		TRCard = t.UniqueTRItems[trID];
		TRCard.id = TRCard.Id;
		TRCard.name = TRCard.Name;
		if (TRCard.Faction != 0) {
			TRCard.faction = uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(TRCard.Faction)].toLowerCase();
			TRCard.type = trTypes[parseInt(TRCard.Type)-1].toLowerCase();
		}
		else {
			TRCard.faction = 'unknown';
			TRCard.type = 'unknown';
			TRCard.unknown = true;
		}
		TRCard.unique = TRCard.id;
		TRCard.level = lvl;
		TRCard.quality = 6;
		TRCard.createPrefix = function () { return ""; };
		TRCard.createSuffix = function () { return ""; };
		TRCard.effects = {};
		var effects = eval(TRCard.Effects);
		var slot = 0;

		for (var k in effects) {
			slot++
			TRCard.effects["slot"+slot] = {};
			TRCard.effects["slot"+slot].id = effects[k].type;
			TRCard.effects["slot"+slot].tier = effects[k].tier;

			if (slot==6) {
				var qual = 5; // assume bright jewel
				if (TRCard.id == 30167 || TRCard.id == 30226 || TRCard.id == 30171 || TRCard.id == 30170 || TRCard.id == 32275) {qual = 4;} // some have subdued jewels :(
				if (TRCard.id == 30173 || TRCard.id == 30172) {qual = 3;} // a couple have cloudy jewels ffs!!!
				TRCard.effects["slot"+slot].quality = qual;
				TRCard.effects["slot"+slot].fromJewel = true;

				TRCard.jewel = {};
				TRCard.jewel.valid = true;
				TRCard.jewel.id = TRCard.effects["slot"+slot].id;
				TRCard.jewel.quality = qual;
				TRCard.jewel.tier = TRCard.effects["slot"+slot].tier;
				TRCard.jewel.fromJewel = true;
				TRCard.jewel.gift = false;
				TRCard.jewel.quantity = 1;
			}
		}
		return TRCard;
	},

	GetInventory : function (trID,div) {
		var t = Tabs.Reference;
		div.innerHTML = '';
		var m = '<br><b>'+uW.g_js_strings.commonstr.throneroom+'</b><br>';
		var tritem = {};
		for (var k in uW.kocThroneItems) {
			var throne_item = uW.kocThroneItems[k];
			if (throne_item.unique == trID) {
				if (tritem[throne_item.level]) {tritem[throne_item.level]++} else {tritem[throne_item.level] = 1;}
			}
		}
		var gotitem = false;
		for (var l in tritem) {
			gotitem = true;
			m += tx('You have')+' '+tritem[l]+' '+tx('at level')+' '+l+'<br>';
		}
		if (!gotitem) m += tx('You have none in your throne room')+'.<br>';
		else {
			if (t.UniqueTRItems[trID].Faction == 0) {
				m += '<a id=pbgenstats'+trID+'>Generate Stats</a><br>';
			}
		}

		m += '<br><b>'+uW.g_js_strings.commonstr.inventory+'</b><br>';
		var inv = uW.seed.items['i'+trID];
		m += tx('You have')+' '+(inv?inv:uW.g_js_strings.commonstr.none)+' '+tx('in your inventory')+'.';
		if ((inv?inv:0) != 0 && !gotitem) {
			m += '<br><a onClick="cm.ItemController.use(\''+trID+'\');setTimeout(function(){pbrefreshuniques('+trID+',\''+div+'\')},2000);">'+tx('Add to Throne Room')+'</a>';
		}
		ById(div).innerHTML = m;
		if (ById('pbgenstats'+trID)) {
			ById('pbgenstats'+trID).addEventListener('click',function () { window.prompt("Copy to clipboard: Ctrl+C", GenerateStats(trID)); } , false);
		}

		function GenerateStats(trID) {
			for (var k in uW.kocThroneItems) {
				var throne_item = uW.kocThroneItems[k];
				if (throne_item.unique == trID) {
					var Results = 'UniqueItems["'+trID+'"] = {Id:'+trID+',Name:"'+throne_item.name+'", Effects:[';
					var firsteffect = true;
					for (var e in throne_item.effects) {
						if (!firsteffect) Results += ',';
						Results += '{type:'+throne_item.effects[e].id+',tier:'+throne_item.effects[e].tier+'}';
						firsteffect = false;
					}
					Results += '],Faction:'+(itemFactions[throne_item.faction])+',Type:'+(itemTypes[throne_item.type]+1)+'};';
					break;
				}
			}
			return Results;
		}
	},

	DisplayTRCard : function (throne_item,Links) {
		var t = Tabs.Reference;
		var D = [];
		if (throne_item == null) {
			D.push("<div>");
			D.push("</div>");
			return D.join("");
		}

		var E = []; // copy to clip/post to chat array

		D.push("<div style='overflow: hidden; position: relative; left: 0px; top: 0px;'>");
		D.push(" <div id='throneInventoryItemTooltip'>");
		D.push("<div class='section' style='overflow: visible;' id = 'idsection'>");
		D.push(" <div class='title " + throne_item.createPrefix().toLowerCase() + "' style='text-transform: capitalize;'> ");
		D.push(throne_item.name + (throne_item.unique ? " +" + throne_item.level : ""));
		D.push(" </div> ");
		D.push(" <div class='description'> ");
		var uniquestyle = "";
		if (throne_item.unique > 29000) {
			uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/'+throne_item.faction+'_'+throne_item.type+'_unique_'+throne_item.unique + '.png); top left no-repeat; background-size: 70px 70px;';
			if (throne_item.unique == 30262 || throne_item.unique == 30264 || throne_item.unique == 30266) { uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/christmas_advisor_normal_1.png); top left no-repeat; background-size: 70px 70px;';};
			if (throne_item.unique == 30261 || throne_item.unique == 30263 || throne_item.unique == 30265) { uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/christmas_candelabrum_normal_1.png); top left no-repeat; background-size: 70px 70px;';};
			if (throne_item.unique == 30230 || throne_item.unique == 30240 || throne_item.unique == 30250) { uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/halloween_table_normal_1.png); top left no-repeat; background-size: 70px 70px;';};
			if (throne_item.unique == 30231 || throne_item.unique == 30241 || throne_item.unique == 30251) { uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/halloween_chair_normal_1.png); top left no-repeat; background-size: 70px 70px;';};
		}
		else {
			uniquestyle = 'background:transparent url('+IMGURL+'throne/icons/70/'+throne_item.faction+'_'+throne_item.type+'_normal_1_'+throne_item.quality+'.png); top left no-repeat; background-size: 70px 70px;';
		}
		D.push("<div class='portrait " + throne_item.faction + " " + throne_item.type + "' style='"+uniquestyle+"'> </div> ");
		D.push("<ul>");
		D.push("<li style='float:none;margin:0px;'> " + uW.g_js_strings.commonstr.faction + ": " + throne_item.faction + "</li>");
		D.push("<li style='float:none;margin:0px;'> " + uW.g_js_strings.commonstr.quality + ": " + CardQuality(throne_item) + "</li>");
		D.push("<li style='float:none;margin:0px;'> " + uW.g_js_strings.commonstr.type + ": " + throne_item.type + "</li>");
		D.push("<li style='float:none;margin:0px;'> " + uW.g_js_strings.commonstr.level + ": " + throne_item.level + "</li>");
		D.push("<li style='float:none;margin:0px;'> " + uW.g_js_strings.commonstr.might + ": " + CardMight(throne_item) + "</li>");
		D.push("</ul>");
		D.push(" </div> ");
		D.push(" <ul> ");

		E.push(throne_item.name.replace(/\'/g, "") + (throne_item.unique ? " +" + throne_item.level : ""));
		E.push(uW.g_js_strings.commonstr.faction + ": " + throne_item.faction);
		E.push(uW.g_js_strings.commonstr.quality + ": " + CardQuality(throne_item));
		E.push(uW.g_js_strings.commonstr.type + ": " + throne_item.type);
//		E.push(uW.g_js_strings.commonstr.level + ": " + throne_item.level);
		E.push(uW.g_js_strings.commonstr.might + ": " + CardMight(throne_item));

		if (throne_item.unknown) {
			if (Links) {
				D.push(" <li class='effect'><center>"+tx("Unknown")+"</center></li> ");
				D.push(" <li class='effect'><div style='font-size:10px;'><center>"+tx("If you have one in your Throne Room please click the 'Generate Stats' link below and send the results to the script developer")+".</center></div></li>");
			}
		}
		else {
			for (var slot in throne_item.effects) {
				try {
					var N = throne_item.effects[slot];
					effect = CM.thronestats.effects[N.id];
					tier = parseInt(N.tier);
					p = CM.thronestats.tiers[N.id][tier];
					while (!p && (tier > 0)) { tier--; p = CM.thronestats.tiers[N.id][tier]; }
					if (!p) continue; // can't find stats for tier

					var base = +p.base || 0;
					var level = throne_item.level || 0;
					var growth = +p.growth || 0;
					if (slot == 'slot6') {  //if it has a slot 6, it automatically has a jewel
						JewelQuality = throne_item["effects"]['slot6'].quality;
						GrowthLimit = CM.thronestats.jewelGrowthLimit[JewelQuality];
						if (GrowthLimit <= level) level = GrowthLimit
					}
					percent = Number(base + ((level * level + level) * growth * 0.5));
					var wholeNumber = false;
					if (Math.round(parseFloat(percent)) == parseFloat(percent)) wholeNumber = true;
					percent = (percent > 0) ? "+" + percent : +percent;
					if (wholeNumber)
						percent = parseFloat(percent).toFixed(0);
					else
						percent = parseFloat(percent).toFixed(2);
					css = (slot % 2 === 0) ? "even" : "odd";
					B = +(slot.split("slot")[1]);
					percent = (percent > 0) ? "+" + percent : percent;
					if (B <= throne_item.quality) {
						D.push(" <li class='effect " + css + "' style='float:none;margin:0px;'> " + percent + "% " + effect[1] + " </li> ");
					} else {
						D.push(" <li class='effect disabled " + css + "' style='float:none;margin:0px;'> " + percent + "% " + effect[1] + " </li> ");
					}
					E.push("Row " + B + ": " + percent + "% " + effect[1]);
				}
				catch (e) { }
			}
		}
		D.push(" </ul> ");
		D.push(" </div> ");
		D.push(" </ul> ");
		D.push(" </div> ");
		D.push(" </div> ");

		var cText = ":::. |" + E.join('||');
		var clipText = E.join('     ');

		if (Links) {
			D.push('<table width="210" class=xtab><tr><td><a onClick="window.prompt(\'Copy to clipboard: Ctrl+C\', \''+clipText+'\');">Copy to Clipboard</a></td><td align=right><a onClick="Chat.sendChat(\''+cText+'\')">Post to Chat</a></td></tr></table>');
		}
		return D.join("");
	},

	PaintCHUniques: function (div) {
		var t = Tabs.Reference;
		var maxlevel = CM.CHAMPION.MAX_LEVELS;
		var itemTypes = { weapon: 0, armor: 1, helm: 2, boots: 3, shield: 4, ring: 5, pendant: 7, cloak: 8 };
		var itemLists = [];
		var selectedCard1 = 0;
		var selectedCard2 = 0;
		var selectedType1 = 0;
		var selectedType2 = 0;
		uWExportFunction('pbrefreshchuniques', Tabs.Reference.GetCHInventory);

        for (var i in itemTypes) {
            itemLists[i] = new Array;
        }
        for (var k in t.UniqueCHItems) {
            var champ_item = t.UniqueCHItems[k];
            if (champ_item == null || !champ_item || !itemLists[chTypes[parseInt(champ_item.Type)-1]]) continue;
            itemLists[chTypes[parseInt(champ_item.Type)-1]].push(champ_item);
        }

        var m = '<div align=center style="height:480px;overflow-y:auto;">';
        m += '<TABLE width=90% class=xtabBR>';
        m += '<tr align=center><td width=50%/><td width=50%/></tr>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.type+':&nbsp;</b><select id="btchUniqueType1">';
        m += '<option value="0">-- '+tx('ALL')+' --</option>';
        for (var type in itemTypes) {
            m += '<option value="' + type + '">' + type + '</option>';
        }
        m += '</select></div></td>';

        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.type+':&nbsp;</b><select id="btchUniqueType2">';
        m += '<option value="0">-- '+tx('ALL')+' --</option>';
        for (var type in itemTypes) {
            m += '<option value="' + type + '">' + type + '</option>';
        }
        m += '</select></div></td>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.item+':&nbsp;</b><select id="btchUnique1">';
        m += '<option value="0">-- '+uW.g_js_strings.commonstr.items+' --</option>';
        for (var k=0;k<t.chSortArray.length;k++) {
            var champ_item = t.chSortArray[k];
            if (champ_item == null || !champ_item) continue;
			var style = '';
			if (champ_item.Faction == 0) style = 'style="color:#aaa;"';
            m += '<option '+style+' value="' + champ_item.Id + '">' + champ_item.Name + ' </option>';
        }
        m += '</select></div></td>';

        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.item+':&nbsp;</b><select id="btchUnique2">';
        m += '<option value="0">-- '+uW.g_js_strings.commonstr.items+' --</option>';
        for (var k=0;k<t.chSortArray.length;k++) {
            var champ_item = t.chSortArray[k];
            if (champ_item == null || !champ_item) continue;
			var style = '';
			if (champ_item.Faction == 0) style = 'style="color:#aaa;"';
            m += '<option '+style+' value="' + champ_item.Id + '">' + champ_item.Name + ' </option>';
        }
        m += '</select></div></td>';

        m += '<tr><td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.level+':&nbsp;</b><select id="btchUniqueLevel1">';
        m += '<option value="0" selected>0</option>';
        for (var type_index = 1; type_index < maxlevel + 1; ++type_index) {
            m += '<option value="' + type_index + '">' + type_index + '</option>';
        }
        m += '</select></div></td>';
        m += '<td><div style="max-width:100%;"><b>'+uW.g_js_strings.commonstr.level+':&nbsp;</b><select id="btchUniqueLevel2">';
        m += '<option value="0" selected>0</option>';
        for (var type_index = 1; type_index < maxlevel + 1; ++type_index) {
            m += '<option value="' + type_index + '">' + type_index + '</option>';
        }
        m += '</select></div></td></tr>';

        m += '<tr>';
        m += '<td id="btchUniqueItem1" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '<td id="btchUniqueItem2" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '</tr>';
        m += '<tr>';
        m += '<td id="btchUniqueInv1" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '<td id="btchUniqueInv2" class="tdcard" style="overflow: visible;  width: auto; height: auto;"/>';
        m += '</tr>';

        m += '</TABLE>';
        m += '</div>';

		div.innerHTML = m;

		jQuery("#btchUniqueType1").change(function () {
            var chType = ById('btchUniqueType1').value;
            var chList = ById('btchUnique1');
            if (selectedCard1 == 0 || (selectedType1 != chType) && chType != 0) {
                selectedCard1 = 0;
            }
            selectedType1 = chType;
            jQuery("#btchUnique1").empty();
            var chOption = document.createElement('option');
            chOption.text = '-- '+uW.g_js_strings.commonstr.items+' --';
            chOption.value = 0;
            chList.add(chOption);
			for (var k=0;k<t.chSortArray.length;k++) {
				var champ_item = t.chSortArray[k];
                if (champ_item == null || !champ_item) continue;
                if (chTypes[parseInt(champ_item.Type)-1] == chType || chType == 0) {
                    var chOption = document.createElement('option');
                    chOption.text = champ_item.Name;
                    chOption.value = champ_item.Id;
					if (champ_item.Faction == 0) chOption.style = 'color:#aaa;';
                    chList.add(chOption);
                }
            }

            if (selectedCard1 != 0) {
                jQuery("#btchUnique1").val(selectedCard1);
            }

        });

        jQuery("#btchUniqueType2").change(function () {
            var chType = ById('btchUniqueType2').value;
            var chList = ById('btchUnique2');
            if (selectedCard2 == 0 || (selectedType1 != chType) && chType != 0) {
                selectedCard2 = 0;
            }
            selectedType2 = chType;
            jQuery("#btchUnique2").empty();
            var chOption = document.createElement('option');
            chOption.text = '-- '+uW.g_js_strings.commonstr.items+' --';
            chOption.value = 0;
            chList.add(chOption);
			for (var k=0;k<t.chSortArray.length;k++) {
				var champ_item = t.chSortArray[k];
                if (champ_item == null || !champ_item) continue;
                if (chTypes[parseInt(champ_item.Type)-1] == chType || chType == 0) {
                    var chOption = document.createElement('option');
                    chOption.text = champ_item.Name;
                    chOption.value = champ_item.Id;
					if (champ_item.Faction == 0) chOption.style = 'color:#aaa;';
                    chList.add(chOption);
                }
            }

            if (selectedCard2 != 0) {
                jQuery("#btchUnique2").val(selectedCard2);
            }

        });

        jQuery("#btchUnique1").change(function () { changeUnique1(this); });

        jQuery("#btchUnique1").keyup(function (event) { changeUnique1(this); });

        function changeUnique1(thisObj) {
            var chID = jQuery(thisObj).val();
            var chDisplay = ById('btchUniqueItem1');
            var chLevel = ById('btchUniqueLevel1');
            selectedCard1 = 0;
            ConvertToCard(chID,chDisplay,chLevel);
            t.GetCHInventory(chID,'btchUniqueInv1');
            selectedCard1 = chID;
            selectedType1 = i;
        }

        jQuery("#btchUnique2").change(function () { changeUnique2(this); });

        jQuery("#btchUnique2").keyup(function (event) { changeUnique2(this); });

        function changeUnique2(thisObj) {
            var chID = jQuery(thisObj).val();
            var chDisplay = ById('btchUniqueItem2');
            var chLevel = ById('btchUniqueLevel2');
            selectedCard2 = 0;
            ConvertToCard(chID,chDisplay,chLevel);
            t.GetCHInventory(chID,'btchUniqueInv2');
            selectedCard2 = chID;
            selectedType2 = i;
        }

        jQuery("#btchUniqueLevel1").keyup(function (event) { changeLevel1(); });

        jQuery("#btchUniqueLevel1").change(function () { changeLevel1(); });

        function changeLevel1() {
            if (selectedCard1 != 0) {
                var chID = selectedCard1;
                var chDisplay = ById('btchUniqueItem1');
                var chLevel = ById('btchUniqueLevel1');
                chDisplay.innerHTML = '';
                ConvertToCard(chID,chDisplay,chLevel);
            }
        }

        jQuery("#btchUniqueLevel2").keyup(function (event) { changeLevel2(); });

        jQuery("#btchUniqueLevel2").change(function () { changeLevel2(); });

        function changeLevel2() {
            if (selectedCard2 != 0) {
                var chID = selectedCard2;
                var chDisplay = ById('btchUniqueItem2');
                var chLevel = ById('btchUniqueLevel2');
                chDisplay.innerHTML = '';
                ConvertToCard(chID,chDisplay,chLevel);
            }
        }

		function ConvertToCard (chID,div,lvl) {
			div.innerHTML = '';
			var CHCard = t.BuildChampCard(chID,parseIntNan(lvl.value));
			div.innerHTML = t.DisplayCHCard(CHCard,true);
		};
	},

	BuildChampCard : function (chID,lvl) {
		var t = Tabs.Reference;
		var CHCard = {};
		CHCard = t.UniqueCHItems[chID];
		CHCard.id = CHCard.Id;
		CHCard.name = CHCard.Name;
		if (CHCard.Faction != 0) {
			CHCard.faction = uW.g_js_strings.commonstr[CM.CHAMPION.getFactionClasses(CHCard.Faction)].toLowerCase();
			CHCard.type = chTypes[parseInt(CHCard.Type)-1];
		}
		else {
			CHCard.faction = 'unknown';
			CHCard.type = 'unknown';
			CHCard.unknown = true;
		}
		CHCard.unique = CHCard.id;
		CHCard.level = lvl;
		CHCard.quality = 5;
		CHCard.createPrefix = function () { return ""; };
		CHCard.createSuffix = function () { return ""; };
		CHCard.effects = {};
		var effects = eval(CHCard.Effects);
		var slot = 0;
		for (var k in effects) {
			slot++
			CHCard.effects["slot"+slot] = {};
			CHCard.effects["slot"+slot].id = effects[k].type;
			CHCard.effects["slot"+slot].tier = effects[k].tier;
		}
		return CHCard;
	},

	GetCHInventory : function (chID,div) {
		var t = Tabs.Reference;
		div.innerHTML = '';
		var m = '<br><b>'+uW.g_js_strings.champ.title+'</b><br>';
		var chitem = {};
		for (var k in uW.kocChampionItems) {
			var champ_item = uW.kocChampionItems[k];
			if (champ_item.unique == chID) {
				if (chitem[champ_item.level]) {chitem[champ_item.level]++} else {chitem[champ_item.level] = 1;}
			}
		}
		var gotitem = false;
		for (var l in chitem) {
			gotitem = true;
			m += tx('You have')+' '+chitem[l]+' '+tx('at level')+' '+l+'<br>';
		}
		if (!gotitem) m += tx('You have none in your champion hall')+'.<br>';
		else {
			if (t.UniqueCHItems[chID].Faction == 0) {
				m += '<a id=pbgenchstats'+chID+'>Generate Stats</a><br>';
			}
		}

		m += '<br><b>'+uW.g_js_strings.commonstr.inventory+'</b><br>';
		var inv = uW.seed.items['i'+chID];
		m += tx('You have')+' '+(inv?inv:uW.g_js_strings.commonstr.none)+' '+tx('in your inventory')+'.';
		if ((inv?inv:0) != 0 && !gotitem) {
			m += '<br><a onClick="cm.ItemController.use(\''+chID+'\');setTimeout(function(){pbrefreshchuniques('+chID+',\''+div+'\')},2000);">'+tx('Add to Champion Hall')+'</a>';
		}
		ById(div).innerHTML = m;
		if (ById('pbgenchstats'+chID)) {
			ById('pbgenchstats'+chID).addEventListener('click',function () { window.prompt("Copy to clipboard: Ctrl+C", GenerateStats(chID)); } , false);
		}

		function GenerateStats(chID) {
			for (var k in uW.kocChampionItems) {
				var champ_item = uW.kocChampionItems[k];
				if (champ_item.unique == chID) {
					var Results = 'UniqueItems["'+chID+'"] = {Id:'+chID+',Name:"'+champ_item.subtype+'", Effects:[';
					var firsteffect = true;
					for (var e in champ_item.effects) {
						if (!firsteffect) Results += ',';
						Results += '{type:'+champ_item.effects[e].id+',tier:'+champ_item.effects[e].tier+'}';
						firsteffect = false;
					}
					Results += '],Faction:'+champ_item.faction+',Type:'+champ_item.type+',Set:'+champ_item.set+'};';
					break;
				}
			}
			return Results;
		}
	},

	DisplayCHCard : function (champ_item,Links) {
		var t = Tabs.Reference;
		var D = [];
		if (champ_item == null) {
			D.push("<div>");
			D.push("</div>");
			return D.join("");
		}

		var E = []; // copy to clip/post to chat array

		D.push("<div style='overflow: hidden; position: relative; left: 0px; top: 0px;'>");
		D.push("<div id='throneInventoryItemTooltip'>");
		D.push("<div class='section' style='overflow:visible;background:#E7E3D6;width:220px;color:#3f2300;' id='idsection'>");
		D.push("<div class='title " + champ_item.createPrefix().toLowerCase() + "' style='text-transform:capitalize;background:#E7E3D6;border-bottom:2px solid #A4753A;'> ");
		D.push(champ_item.name + (champ_item.unique ? " +" + champ_item.level : ""));
		D.push("</div>");
		D.push("<div class='description' style='border-bottom:2px solid #A4753A;'>");
		var uniquestyle = "";
		if (champ_item.unique != 0) { uniquestyle = 'background:transparent url('+IMGURL+'champion_hall/unique_'+champUniqueImageTypes[champ_item.Type-1]+'_'+champ_item.faction+'_70x70_'+champ_item.unique + '.png); top left no-repeat; background-size: 70px 70px;'; }
		else { uniquestyle = 'background:transparent url('+IMGURL+'champion_hall/'+cardQuality[champ_item.quality].toLowerCase()+'_'+champImageTypes[champ_item.Type-1]+'_'+champ_item.faction+'_70x70.png); top left no-repeat; background-size: 70px 70px;'; }
		D.push("<div class='portrait " + champ_item.faction + " " + champ_item.type + "' style='border:none;margin-left:3px;margin-top:8px;"+uniquestyle+"'> </div> ");
		D.push("<ul>");
		D.push("<li style='float:none;margin:0px;color:#A4753A;font-size:12px;'> " + uW.g_js_strings.commonstr.faction + ": " + champ_item.faction + "</li>");
		D.push("<li style='float:none;margin:0px;color:#A4753A;font-size:12px;'> " + uW.g_js_strings.commonstr.quality + ": " + CardQuality(champ_item) + "</li>");
		D.push("<li style='float:none;margin:0px;color:#A4753A;font-size:12px;'> " + uW.g_js_strings.commonstr.type + ": " + champ_item.type + "</li>");
		D.push("<li style='float:none;margin:0px;color:#A4753A;font-size:12px;'> " + uW.g_js_strings.commonstr.level + ": " + champ_item.level + "</li>");
		D.push("<li style='float:none;margin:0px;color:#A4753A;font-size:12px;'> " + uW.g_js_strings.commonstr.might + ": " + CardMight(champ_item) + "</li>");
		D.push("</ul>");
		D.push("</div>");
		D.push("<ul>");

		E.push(champ_item.name.replace(/\'/g, "") + (champ_item.unique ? " +" + champ_item.level : ""));
		E.push(uW.g_js_strings.commonstr.faction + ": " + champ_item.faction);
		E.push(uW.g_js_strings.commonstr.quality + ": " + CardQuality(champ_item));
		E.push(uW.g_js_strings.commonstr.type + ": " + champ_item.type);
//		E.push(uW.g_js_strings.commonstr.level + ": " + champ_item.level);
		E.push(uW.g_js_strings.commonstr.might + ": " + CardMight(champ_item));

		if (champ_item.unknown) {
			if (Links) {
				D.push(" <li class='effect'><center>"+tx("Unknown")+"</center></li> ");
				D.push(" <li class='effect'><div style='font-size:10px;'><center>"+tx("If you have one in your Champions Hall please click the 'Generate Stats' link below and send the results to the script developer")+".</center></div></li>");
			}
		}
		else {
			for (var slot in champ_item.effects) {
				try {
					var N = champ_item.effects[slot];
					effect = eval("uW.g_js_strings.effects.name_"+N.id);

					tier = parseInt(N.tier);
					p = t.championStatTiers[N.id][tier];
					while (!p && (tier > 0)) { tier--; p = t.championStatTiers[N.id][tier]; }
					if (!p) continue; // can't find stats for tier

					var base = +p.base || 0;
					var level = champ_item.level || 0;
					var growth = +p.growth || 0;
					percent = Number(base + ((level * level + level) * growth * 0.5));
					if (N.id>=300) {
						percent = Number(base + (level * growth));
						if (N.id<400) percent = percent*100;
					}
					var wholeNumber = false;
					if (Math.round(parseFloat(percent)) == parseFloat(percent)) wholeNumber = true;
					percent = (percent > 0) ? percent : +percent;
					if (wholeNumber)
						percent = parseFloat(percent).toFixed(0);
					else
						percent = parseFloat(percent).toFixed(2);
					css = (slot % 2 === 0) ? "even" : "odd";
					B = +(slot.split("slot")[1]);
					percent = (N.id>=300)?percent+'%':percent;
					if (B <= champ_item.quality) {
						if (N.id < 200) {
							D.push(" <li class='effect " + css + "' style='float:none;margin:0px;color: #1751A5;'> " + percent + " " + effect + " </li> ");
						}
						else {
							if (N.id >= 400) {
								D.push(" <li class='effect " + css + "' style='float:none;margin:0px;color: #f80;'> " + percent + " " + effect + " </li> ");
							}
							else {
								if (N.id >= 300) {
									D.push(" <li class='effect " + css + "' style='float:none;margin:0px;color: #808;'> " + percent + " " + effect + " </li> ");
								}
								else {
									D.push(" <li class='effect " + css + "' style='float:none;margin:0px;'> " + percent + " " + effect + " </li> ");
								}
							}
						}
					} else {
						D.push(" <li class='effect disabled " + css + "' style='float:none;margin:0px;'> " + percent + " " + effect + " </li> ");
					}
					E.push("Row " + B + ": " + percent + " " + effect);
				}
				catch (e) { }
			}
		}
		D.push(" </ul> ");
		D.push(" </div> ");
		D.push(" </ul> ");
		D.push(" </div> ");
		D.push(" </div> ");

		var cText = ":::. |" + E.join('||');
		var clipText = E.join('     ');
		if (Links) {
			D.push('<table width="210" class=xtab><tr><td><a onClick="window.prompt(\'Copy to clipboard: Ctrl+C\', \''+clipText+'\');">Copy to Clipboard</a></td><td align=right><a onClick="Chat.sendChat(\''+cText+'\')">Post to Chat</a></td></tr></table>');
		}
		return D.join("");
	},

}

/*********************************** Overview Tab ***********************************/

Tabs.OverView = {
	tabOrder: 1000,
	tabLabel: 'Overview',
	unitsarr: [],
	rownum: 0,
	myDiv: null,
	LoopCounter:0,
	resTotal: {},
	troopTotal: {},
	aethercap:0,

	Options : {
		OverviewFontSize	: 9,
		AllowOverflow		: false,
		includeDefending	: false,
		includeMarching		: true,
		includeTraining		: false,
		includeTrainingExt	: true,
		enableFoodWarn		: true,
		FoodWarnHours		: 1,
		Report				: false,
		ReportInterval		: 12,
		ReportEmail			: false,
		LastReport			: 0,
		LastReportStatus	: {1:[0,0,0,0,0,0],2:[0,0,0,0,0,0],3:[0,0,0,0,0,0],4:[0,0,0,0,0,0],5:[0,0,0,0,0,0],6:[0,0,0,0,0,0],7:[0,0,0,0,0,0],8:[0,0,0,0,0,0]}, // food,wood,stone,ore,aether,gold
	},

	init: function (div) {
		var t = Tabs.OverView;
		for (var ui in CM.UNIT_TYPES){
			i = CM.UNIT_TYPES[ui];
			t.unitsarr.push(i);
		}
		t.myDiv = div;

		t.aethercap = CM.WorldSettings.getSetting("DARK_FOREST_AETHERSTONE_CAP")||5000000;

		if (!Options.OverviewOptions) {
			Options.OverviewOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.OverviewOptions.hasOwnProperty(y)) {
					Options.OverviewOptions[y] = t.Options[y];
				}
			}
		}

		t.sendReport(); // check every refresh
	},

	show: function () {
		var t = Tabs.OverView;

		m = '<div>';
		m += '<div class="divHeader" align="center">OVERVIEW</div>';
		m += '<div align="center">';
		m += '<DIV id=ptOverviewDiv style="max-height:700px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px;overflow-x:scroll;"></div></div>';

		m += '<a id=ptOverOptionLink class=divLink ><div class="divHeader" align="left"><img id=ptOverOptionArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('OVERVIEW OPTIONS')+'</div></a>';
		m += '<div id=ptOverOption class=divHide><TABLE width="100%">';
		m += '<TR><td class=xtab>&nbsp;</td><td class=xtab>'+tx('Font size')+': ' + htmlSelector({8: 8, 9: 9, 10: 10, 11: 11}, Options.OverviewOptions.OverviewFontSize, 'id=ptOverviewFont class=btInput') + '&nbsp;'+tx('pixels')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT type=CHECKBOX id=ptOverOver' + (Options.OverviewOptions.AllowOverflow ? ' CHECKED' : '') + '></td><td class=xtab>'+tx('Expand window width to fit')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT type=CHECKBOX id=ptOverDefend' + (Options.OverviewOptions.includeDefending ? ' CHECKED' : '') + '></td><td class=xtab>'+tx('Include Defending Troops')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT type=CHECKBOX id=ptOverMarch' + (Options.OverviewOptions.includeMarching ? ' CHECKED' : '') + '></td><td class=xtab>'+tx('Include Marching Troops/Resources')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT type=CHECKBOX id=ptOverIncTrain' + (Options.OverviewOptions.includeTraining ? ' CHECKED' : '') + '></td><td class=xtab>'+tx('Include Troops in Training (in Cities)')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT type=CHECKBOX id=ptOverIncTrainExt' + (Options.OverviewOptions.includeTrainingExt ? ' CHECKED' : '') + '></td><td class=xtab>'+tx('Include Troops in Training (Total)')+'</td></tr>';
		m += '<TR><TD class=xtab><INPUT id=ptEnableFoodWarn type=checkbox' + (Options.OverviewOptions.enableFoodWarn ? ' CHECKED' : '') + '></td><TD class=xtab>'+tx('Show \'Food left\' in RED if food will run out in less than')+'&nbsp;';
		m += '<INPUT id=ptFoodHours type=text size=2 value="' + Options.OverviewOptions.FoodWarnHours + '">&nbsp;'+tx('hours')+'</td></tr>';
		m += '<tr><td class=xtab><INPUT id=ptOverReport type=checkbox '+ (Options.OverviewOptions.Report?' CHECKED':'') +'\></td><TD class=xtab>'+tx("Send resource report every")+'&nbsp;<INPUT id=ptOverReportInterval value='+ Options.OverviewOptions.ReportInterval +' type=text size=3 \>&nbsp;'+tx('hours')+'&nbsp;&nbsp;&nbsp;'+strButton8(tx('Send Now'), 'id=ptOverReportSend')+'</td></tr>';
		if (uW.koc2Mail) {
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab><INPUT id=ptOverReportEmail type=checkbox '+ (Options.OverviewOptions.ReportEmail?' CHECKED':'') +'\>&nbsp;'+tx("CC to Email")+'</td></tr>';
		}
		m += '</table></div><br>';

		t.myDiv.innerHTML = m;

		if (Options.OverviewOptions.AllowOverflow) {
			ById('ptOverviewDiv').style.width = 'auto';
		}
		ById('ptOverOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Overview",100,GlobalOptions.btWinSize.x,"ptOverOption",false)}, false);

		ById('ptOverOver').addEventListener('click', function (evt) {
			var t = Tabs.OverView;
			var tf = ById('ptOverOver').checked;
			Options.OverviewOptions.AllowOverflow = tf;
			saveOptions();
			if (tf)
				ById('ptOverviewDiv').style.width = 'auto';
			else
				ById('ptOverviewDiv').style.width = GlobalOptions.btWinSize.x;
			t.PaintOverview();
		} , false);

		ToggleOption('OverviewOptions','ptOverDefend','includeDefending',t.PaintOverview);
		ToggleOption('OverviewOptions','ptOverMarch','includeMarching',t.PaintOverview);
		ToggleOption('OverviewOptions','ptOverIncTrain','includeTraining',t.PaintOverview);
		ToggleOption('OverviewOptions','ptOverIncTrainExt','includeTrainingExt',t.PaintOverview);
		ToggleOption('OverviewOptions','ptEnableFoodWarn','enableFoodWarn',t.PaintOverview);
		ToggleOption('OverviewOptions','ptOverReport','Report',t.sendReport);

		ChangeIntegerOption('OverviewOptions','ptFoodHours','FoodWarnHours',1,t.PaintOverview);
		ChangeIntegerOption('OverviewOptions','ptOverviewFont','OverviewFontSize',9,t.PaintOverview);
		ChangeIntegerOption('OverviewOptions','ptOverReportInterval','ReportInterval',12,t.PaintOverview);

        ById('ptOverReportSend').addEventListener('click', function () {
            Options.OverviewOptions.LastReport = 0;
            saveOptions();
			t.sendReport();
        }, false);

		if (uW.koc2Mail) {
			ToggleOption('','ptOverReportEmail','ReportEmail');
		}

		t.PaintOverview();
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	postRes : function () {
		var t = Tabs.OverView;
		var msg = ':::. '+tx('Total Resources')+' |'
		for (var key in t.resTotal) {
			msg += '||' + key + ': ' + enFilter(addCommas(t.resTotal[key]));
		}
		msg += '|';
		var automsg = sendChat(msg);
	},

	postTroop : function () {
		var t = Tabs.OverView;
		var msg = ':::. '+tx('Total Troops')+' |'
		for (var key in t.troopTotal) {
			msg += '||' + key + ': ' + enFilter(addCommas(t.troopTotal[key]));
		}
		msg += '|';
		var automsg = sendChat(msg);
	},

	addListener : function (but, i){
		var t = Tabs.OverView;
		if (!SelectiveDefending) return;
		but.addEventListener ('click', function (){t.ToggleDefenceMode(i)}, false);
	},

	ToggleDefenceMode : function (cityId) {
		var t = Tabs.OverView;
		var state = 1;
		if (Seed.citystats["city" + cityId].gate != 0)
			state = 0;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.state = state;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/gate.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					Seed.citystats["city" + cityId].gate = state;
					t.DisplayDefenceMode(cityId);
				}
			},
		});
	},

	DisplayDefenceMode : function (cityId) {
		var t = Tabs.OverView;
		DefState = parseInt(Seed.citystats["city" + cityId].gate);
		if (DefState) DefButtonText = '<a id=ptCityStatus_'+cityId+' class="inlineButton btButton red20"><span style="font-size:10px;width:60px"><center>'+tx('Defending')+'!</center></span></a>';
			else DefButtonText = '<a id=ptCityStatus_'+cityId+' class="inlineButton btButton green20"><span style="font-size:10px;width:60px"><center>'+tx('Hiding')+'!</center></span></a>';
		var DefButton = ById('ptCityStatus_'+ cityId);
		DefButton.outerHTML = DefButtonText;
		DefButton = ById('ptCityStatus_'+ cityId);	// do again because of outerHTML
		t.addListener(DefButton,cityId);
	},

	getMarchInfo : function () {
		var t = Tabs.OverView;
		var ret = {};
		ret.marchUnits = [];
		ret.returnUnits = [];
		ret.resources = [];
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			ret.marchUnits[i] = 0;
			ret.returnUnits[i] = 0;
		}
		for (var i = 0; i <= 5; i++) {
			ret.resources[i] = 0;
		}
		var now = unixTime();
		for (var i = 0; i < Cities.numCities; i++) { // each city
			cityId = Cities.cities[i].id;
			for (var k in Seed.queue_atkp['city'+cityId]) { // each march
				march = local_atkp[k];
				if (typeof (march) == 'object') {
					for (var ui in uW.cm.UNIT_TYPES) {
						ii = uW.cm.UNIT_TYPES[ui];
						ret.marchUnits[ii] += parseIntNan(march['unit' + ii + 'Count']);
						ret.returnUnits[ii] += parseIntNan(march['unit' + ii + 'Return']);
					}
					for (var ii = 1; ii <= 5; ii++) {
						ret.resources[ii] += parseIntNan(march['resource' + ii]);
					}
					ret.resources[0] += parseIntNan(march['gold']);
				}
			}
		}
		return ret;
	},

	getTrainInfo : function () {
		var t = Tabs.OverView;
		var ret = {};
		ret.trainUnts = [];
		for (var ui in uW.cm.UNIT_TYPES) {
			i = uW.cm.UNIT_TYPES[ui];
			ret.trainUnts[i] = 0;
		}
		var q = Seed.queue_unt;
		for (var i = 0; i < Cities.numCities; i++) { // each city
			cityId = Cities.cities[i].id;
			q = Seed.queue_unt['city'+cityId];
			if (q && q.length > 0) {
				for (var qi = 0; qi < q.length; qi++)
					ret.trainUnts[q[qi][0]] += parseInt(q[qi][1]);
			}
		}
		return ret;
	},

	EverySecond : function () {
		var t = Tabs.OverView;

		t.LoopCounter = t.LoopCounter + 1;
		if (tabManager.currentTab.name == 'OverView' && Options.btWinIsOpen){
			if (t.LoopCounter % 5 == 1) { // refresh display every 5 seconds
				t.PaintOverview();
			}
		}

		if (t.LoopCounter >= 60) { // functions for every minute
			t.LoopCounter = 0;
			t.sendReport();
		}
	},

	PaintOverview : function () {
		var t = Tabs.OverView;
		var rownum = 0;

		function _row(name, row, noTotal, icon) {
			var t = Tabs.OverView;
			if (rownum++ % 2)
				style = ' class="evenRow"';
			else
				style = ' class="oddRow"';
			var tot = 0;
			var m = [];
			m.push('<TR align=right');
			m.push(style);
			if (noTotal) {
				m.push('><TD colspan=2');
			}
			else {
				m.push('><TD');
			}
			m.push(' style="padding-left: 0px;"');
			m.push('>');
			if (icon) {
				m.push(icon);
			}
			else {
				m.push('<B>'+name+'&nbsp;</B>');
			}
			m.push('</td>');
			if (!noTotal) {
				for (var i = 0; i < row.length; i++)
					tot += row[i];
				m.push('<TD><div class="totalCell xtabBorder">');
				if (name == uW.g_js_strings.commonstr.gold || name == uW.g_js_strings.commonstr.food || name == uW.g_js_strings.commonstr.wood || name == uW.g_js_strings.commonstr.stone || name == uW.g_js_strings.commonstr.ore || name == uW.g_js_strings.commonstr.aetherstone)
					t.resTotal[name] = tot;
				else {
					if (Options.OverviewOptions.includeTrainingExt && Options.OverviewOptions.includeTraining) {
						tot -= row[row.length-1];
					}
					t.troopTotal[name] = tot;
				}
				m.push(addCommas(tot));
				m.push('</div></td>');
			}
			for (var i = 0; i < row.length; i++) {
				m.push('<TD');
				m.push(style);
				m.push('><div class=xtabBorder>');
				m.push(addCommas(row[i]));
				m.push('</div></td>');
			}
			m.push('</tr>');
			return m.join('');
		}

		m = '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=left style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td align=right width=100><b>'+tx('TOTALS')+'</b></td>';

		for (var i = 0; i < Cities.numCities; i++) {
			var	cityId = Cities.cities[i].id;
			var ascended = getAscensionValues(cityId);
			var CityFaction = '';
			if (ascended.isPrestigeCity) {
				CityFaction = getFactionName(ascended.prestigeType) + '&nbsp('+ascended.prestigeLevel+')';
			}

			m += '<TD style="font-size:11px;" align=center width=100><B>'+Cities.cities[i].name.substring(0, 12)+'</b><BR>'+coordLink(Cities.cities[i].x, Cities.cities[i].y)+'<BR>'+uW.provincenames['p' + Cities.cities[i].provId]+'<BR>'+CityFaction+'<BR>';
			DefState = parseInt(Seed.citystats["city" + cityId].gate);
			if (DefState) DefButtonText = '<a id=ptCityStatus_'+cityId+' class="inlineButton btButton red20"><span style="font-size:10px;width:60px"><center>'+tx('Defending')+'!</center></span></a>';
			else DefButtonText = '<a id=ptCityStatus_'+cityId+' class="inlineButton btButton green20"><span style="font-size:10px;width:60px"><center>'+tx('Hiding')+'!</center></span></a>';
			m += DefButtonText+'</td>';
		}

		if (Options.OverviewOptions.includeMarching) {
			m += '<TD align=right width=100><B>'+tx('Marching')+'</b></td>';
			march = t.getMarchInfo();
		}
		if (Options.OverviewOptions.includeTrainingExt) {
			m += '<TD align=right width=100><B>'+tx('Training')+'</b></td>';
			train = t.getTrainInfo();
		}
		m += "<td>&nbsp;</td></tr>"; // spacer

		rows = [];
		rows[0] = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			rows[0][i] = parseInt(Seed.citystats['city'+cityId].gold[0]);
		}
		for (var r = 1; r < 5; r++) {
			rows[r] = [];
			for (var i = 0; i < Cities.numCities; i++) {
				cityId = Cities.cities[i].id;
				rows[r][i] = parseInt(Seed.resources['city'+cityId]['rec' + r][0] / 3600);
			}
		}
		rows[5] = [];
		for (var i = 0; i < Cities.numCities; i++) { //Aetherstone
			cityId = Cities.cities[i].id;
			rows[5][i] = parseInt(Seed.resources['city'+cityId]['rec5'][0]);
		}
		if (Options.OverviewOptions.includeMarching) {
			for (var i = 0; i <= 5; i++) {
				rows[i][Cities.numCities] = march.resources[i];
			}
		}

		m += _row(uW.g_js_strings.commonstr.gold, rows[0], false, ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold));
		m += _row(uW.g_js_strings.commonstr.food, rows[1], false, ResourceImage(FoodImage,uW.g_js_strings.commonstr.food));
		m += _row(uW.g_js_strings.commonstr.wood, rows[2], false, ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood));
		m += _row(uW.g_js_strings.commonstr.stone, rows[3], false, ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone));
		m += _row(uW.g_js_strings.commonstr.ore, rows[4], false, ResourceImage(OreImage,uW.g_js_strings.commonstr.ore));
		m += _row(uW.g_js_strings.commonstr.aetherstone, rows[5], false, ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone));

		m += "</tr>";
		m += '<TR><TD>&nbsp;</td><TD align=right><input id=ptpostres style="font-size:9px" type="submit" value="'+tx('Post To Chat')+'"></input></td></tr>';

		row = [];
		var trupkeepreduce = 0;
		trupkeepreduce = Math.min(equippedthronestats(79), 33);
		var trprodres = Math.min(equippedthronestats(82),2000);
		var trprod = [0, 0, 0, 0, 0];
		trprod[1] = Math.min(equippedthronestats(83), 2000)+trprodres;
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var rp = getResourceProduction(cityId);
			var usage = parseInt(Seed.resources['city'+cityId]['rec1'][3]);
			var bp = uW.cm.Resources.getProductionBase(1,cityId);
			var upkbase = uW.cm.Resources.getUpkeep(1,cityId) / (1 - trupkeepreduce / 100);
			usage = parseIntNan(usage - upkbase * trupkeepreduce / 100);
			row[i] = parseIntNan(rp[1] - usage + bp * trprod[1] / 100);
		}
		m += _row(uW.g_js_strings.commonstr.food+' +/-', row, true);
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			if (row[i] >= 0)
				row[i] = '----';
			else {
				var timeLeft = parseInt(Seed.resources["city"+cityId]['rec1'][0]) / 3600 / (0 - row[i]) * 3600;
				if (timeLeft > 86313600)
					row[i] = '----';
				else {
					if (Options.OverviewOptions.enableFoodWarn && timeLeft < (Options.OverviewOptions.FoodWarnHours * 3600))
						row[i] = '<SPAN class=whiteOnRed>' + timestrShort(timeLeft) + '</span>';
					else
						row[i] = timestrShort(timeLeft);
				}
			}
		}
		m += _row(tx('Food left'), row, true);

		var bonus = 1 + (uW.cm.ThroneController.getBoundedEffect(111)/100);
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var raid = 0;
			for (var mid in Seed.queue_atkp["city"+cityId]) {
				var citymarch = Seed.queue_atkp["city"+cityId][mid];
				if (citymarch.marchType == 9 && (citymarch.botMarchStatus < 3 || citymarch.botMarchStatus == 7)) { // running or resting...
					var foodres = citymarch.toTileLevel * 115000;
					if (citymarch.toTileLevel==12) foodres = 1400000;
					if (citymarch.toTileLevel==13) foodres = 1540000;
					if (citymarch.toTileLevel==14) foodres = 1700000;
					if (citymarch.toTileLevel==15) foodres = 2000000;
					var retUT = citymarch.returnUnixTime;
                    if (isNaN(retUT)) { retUT = citymarch.returnEta; }
					var roundtrip = parseIntNan(retUT - citymarch.marchUnixTime);
					var raidres = 0;
					if (roundtrip != 0) { raidres = 3600/(roundtrip) * foodres * bonus; }
					raid += raidres;
				}
			}
			row[i] = parseInt(raid);
		}
		m += _row(tx('Raids (hr)'), row, true);

		row = [];
		var baseSthProt = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			baseSthProt[i] = StorehouseLevels[parseIntNan(getUniqueCityBuilding(cityId, 9).maxLevel)];
			//tch14 = shrinking powder..
			var SthPrtResearch = parseIntNan(Seed.tech.tch14)
			var TRStHsBoost = Math.min(equippedthronestats(89), 1250);
			var totalSthPrt = []
			var researchToApply = ((SthPrtResearch / 10) + 1)
			var TRBoostToApply = ((TRStHsBoost / 100) + 1)
			if (TRStHsBoost == 0) TRStHsBoost = 1
			totalSthPrt[i] = addCommas(parseInt((baseSthProt[i] * researchToApply) * TRBoostToApply))
			row[i] = totalSthPrt[i]
		}
		m += _row(uW.buildingcost.bdg9[0], row, true)

		row = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var aethcapinc = 0;
			aethcapinc += equippedthronestats(88);
			var equippeditems = Seed.throne.slotEquip[Seed.throne.activeSlot];
			var EQ = {};
			jQuery.each(equippeditems, function (A, B) {
				EQ[x.id] = uW.kocThroneItems[B];
			});
			var currSet = CM.ThroneController.hasFactionBonus(EQ);
			if (currSet.hazBonus && currSet.faction === "fey")
				aethcapinc += uW.cm.ThroneController.effectBonus(95);
			var aethercap = Math.round(t.aethercap * (1 + Math.min(aethcapinc, uW.cm.thronestats.boosts["ResourceCap"].Max) / 100));
			row[i] = addCommas(aethercap);
		}
		m += _row(tx('Aether Limit'), row, true)
		m += '<TR><TD>&nbsp;</td></tr>';

		for (var r = 1; r < t.unitsarr.length + 1; r++) {
			rows[r] = [];
			for (var i = 0; i < Cities.numCities; i++) {
				cityId = Cities.cities[i].id;
				rows[r][i] = parseIntNan(Seed.units['city'+cityId]['unt'+t.unitsarr[r-1]]);
				if (SelectiveDefending && Options.OverviewOptions.includeDefending) rows[r][i] += parseIntNan(Seed.defunits['city'+cityId]['unt'+t.unitsarr[r-1]]);
			}
		}
		var colnum = Cities.numCities;
		if (Options.OverviewOptions.includeMarching) {
			for (var i = 1; i < t.unitsarr.length + 1; i++) {
				rows[i][colnum] = parseIntNan(march.marchUnits[t.unitsarr[i-1]]);
			}
			colnum++;
		}
		if (Options.OverviewOptions.includeTrainingExt) {
			for (var i = 1; i < t.unitsarr.length + 1; i++) {
				rows[i][colnum] = parseIntNan(train.trainUnts[t.unitsarr[i-1]]);
			}
		}
		if (Options.OverviewOptions.includeTraining) {
			var q = Seed.queue_unt;
			for (var i = 0; i < Cities.numCities; i++) {
				cityId = Cities.cities[i].id;
				q = Seed.queue_unt['city'+cityId];
				if (q && q.length > 0) {
					for (var qi = 0; qi < q.length; qi++) {
						qr = q[qi][0];
						if (qr >= 19) qr=qr-2;
						rows[qr][i] += parseIntNan(q[qi][1]);
					}
				}
			}
		}
		rownum = 0;
		for (var j = 1; j < t.unitsarr.length+1; j++) {
			m += _row(uW.unitcost['unt'+t.unitsarr[j-1]][0], rows[j], false, TroopImage(t.unitsarr[j-1]));
		}
		m += '<TR><TD>&nbsp;</td><TD align=right><input id=ptposttroop style="font-size:9px" type="submit" value="'+tx('Post To Chat')+'"></input></td></tr>';

		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var tower = Seed.buildings['city'+cityId].pos99;
			if (tower) tower = parseInt(Seed.buildings['city'+cityId].pos99[1])
			if (!tower)
				row[i] = '<SPAN class=boldRed><B>'+uW.g_js_strings.commonstr.none+'!</b></span>';
			else
				row[i] = 'Level '+tower;
		}
		m += _row(tx('Def. Tower'), row, true);

		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var tower = Seed.buildings['city'+cityId].pos98;
			if (tower) tower = parseInt(Seed.buildings['city'+cityId].pos98[1])
			if (!tower)
				row[i] = '<SPAN class=boldRed><B>'+uW.g_js_strings.commonstr.none+'!</b></span>';
			else
				row[i] = 'Level '+tower;
		}
		m += _row(tx('Redoubt Tower'), row, true);

		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var marches = March.getMarchSlots(cityId);
			var maxmarches = March.getTotalSlots(cityId);
			if (marches >= maxmarches)
				row[i] = '<SPAN class=boldRed><B>' + marches + '/' + maxmarches + '</b></span>';
			else
				row[i] = marches + '/' + maxmarches;
		}
		m += _row(uW.buildingcost.bdg12[0], row, true);

		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var totWilds = 0;
			dat = Seed.wilderness['city'+cityId];
			if (dat != null && matTypeof(dat) == 'object')
				for (var k in dat)
					++totWilds;
			var castle = getMaxWilds(cityId);
			if (totWilds < castle)
				row[i] = '<SPAN class=boldRed><B>' + totWilds + '/' + castle + '</b></span>';
			else
				row[i] = totWilds + '/' + castle;
		}
		m += _row(tx('Wilds'), row, true);

		row = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			totKnights = 0;
			dat = Seed.knights['city'+cityId];
			for (var k in dat)
				++totKnights;
			row[i] = totKnights;
		}
		m += _row(uW.g_js_strings.report_view.knights, row, true);
		m += '<TR><TD colspan=2 align=right><b>'+tx('Queues')+'&nbsp;</b></td></tr>';
		var now = unixTime();
		var row = [];
		var rowsp = [];
		var rowrev = [];
		var rowres = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var totTime = 0;
			var totTime2 = 0;
			var q = Seed.queue_unt['city'+cityId];
			if (q != null && q.length > 0) {
				for (var j = 0; j < q.length; j++) {
					if (q[j][7])
						totTime2 = q[j][3] - now;
					else
						totTime = q[j][3] - now;
				}
			}
			if (totTime < 0) totTime = 0;
			if (totTime < 3600) row[i] = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
			else row[i] = timestr(totTime);
			if (totTime2 < 0) totTime2 = 0;
			if (totTime2 < 3600) rowsp[i] = '<SPAN class=boldRed><B>' + timestr(totTime2) + '</b></span>';
			else rowsp[i] = timestr(totTime2);

			var totTime = 0;
			var qr = Seed.queue_revive['city'+cityId];
			rowrev[i] = 0;
			if (qr != null && qr.length > 0) {
				totTime = qr[qr.length - 1][3] - now;
				if (totTime < 0) rowrev[i] = 0;
				else if (totTime < 3600) rowrev[i] = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
				else rowrev[i] = timestr(totTime);
			}
			var totTime = 0;
			var qr2 = Seed.queue_revive2['city'+cityId];
			if (qr2 != null && qr2.length > 0) {
				totTime = qr2[qr2.length - 1][3] - now;
				if (totTime >= 0) {
					if (totTime < 3600) rowrev[i] += '<br><SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
					else rowrev[i] += '<br>'+timestr(totTime);
				}
			}

			var totTime = 0;
			var qres = Seed.queue_tch['city'+cityId];
			rowres[i] = 0;
			if (qres != null && qres.length > 0) {
				totTime = qres[qres.length - 1][3] - now;
				if (totTime < 0) rowres[i] = 0;
				else if (totTime < 3600) rowres[i] = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
				else rowres[i] = timestr(totTime);
			}
			var totTime = 0;
			var qres2 = Seed.queue_tch2['city'+cityId];
			if (qres2 != null && qres2.length > 0) {
				totTime = qres2[qres2.length - 1][3] - now;
				if (totTime >= 0) {
					if (totTime < 3600) rowres[i] += '<br><SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
					else rowres[i] += '<br>'+timestr(totTime);
				}
			}
		}
		m += _row(tx('Training'), row, true);
		m += _row(tx('Asc. Training'), rowsp, true);
		m += _row(tx('Reviving'), rowrev, true);
		m += _row(tx('Researching'), rowres, true);

		var row = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var wall = {};
			getWallInfo(cityId,wall);
			var totTime = 0;
			var q = Seed.queue_fort['city'+cityId];
			if (q != null && q.length > 0)
				totTime = q[q.length - 1][3] - now;
			if (totTime < 0)
				totTime = 0;
			if (totTime < 1 && (wall.wallSpaceUsed < wall.wallSpace - 4 || wall.fieldSpaceUsed < wall.fieldSpace - 4))
				row[i] = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
			else
				row[i] = timestr(totTime);
		}
		m += _row(uW.g_js_strings.report_view.defenses, row, true);

		ById('ptOverviewDiv').innerHTML = m;

		ById('ptpostres').addEventListener('click', t.postRes, false);
		ById('ptposttroop').addEventListener('click', t.postTroop, false);

		for (var cityId in Cities.byID){
			var DefButton = ById('ptCityStatus_'+ cityId);
			t.addListener(DefButton,cityId);
		}
	},

	sendReport: function(){
		var t = Tabs.Overview;
		if(!Options.OverviewOptions.Report) { return; }

		var now = unixTime();
		if (now < (parseInt(Options.OverviewOptions.LastReport)+(Options.OverviewOptions.ReportInterval*60*60)))
			return;

		var message = tx('Resource Report for')+' '+Options.OverviewOptions.ReportInterval+' '+tx('hours (or since last report)')+' %0A';
		var total = 0;
		var totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.food+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][0];
			var newval = parseInt(Seed.resources['city'+cityId]['rec1'][0] / 3600);
			var gain = newval-oldval;
			message += Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][0] = newval;
		}
		message += '%0A '+tx('Total Food')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		total = 0;
		totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.aetherstone+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][4];
			var newval = parseInt(Seed.resources['city'+cityId]['rec5'][0]);
			var gain = newval-oldval;
			message+= Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][4] = newval;
		}
		message += '%0A '+tx('Total Aetherstone')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		total = 0;
		totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.ore+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][3];
			var newval = parseInt(Seed.resources['city'+cityId]['rec4'][0] / 3600);
			var gain = newval-oldval;
			message+= Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][3] = newval;
		}
		message += '%0A '+tx('Total Ore')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		total = 0;
		totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.wood+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][1];
			var newval = parseInt(Seed.resources['city'+cityId]['rec2'][0] / 3600);
			var gain = newval-oldval;
			message+= Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][1] = newval;
		}
		message += '%0A '+tx('Total Wood')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		total = 0;
		totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.stone+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][2];
			var newval = parseInt(Seed.resources['city'+cityId]['rec3'][0] / 3600);
			var gain = newval-oldval;
			message+= Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][2] = newval;
		}
		message += '%0A '+tx('Total Stone')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		total = 0;
		totalgain = 0;
		message += '%0A ---------- '+uW.g_js_strings.commonstr.gold+' ---------- %0A';
		for (q=1;q<=Seed.cities.length;q++){
			var cityId = Seed.cities[q-1][0];
			var oldval = Options.OverviewOptions.LastReportStatus[q][5];
			var newval = parseInt(Seed.citystats["city"+cityId]['gold'][0]);
			var gain = newval-oldval;
			message+= Seed.cities[q-1][1]+': '+tx('Start')+': '+addCommas(oldval)+' '+tx('End')+': '+addCommas(newval)+' '+tx('Gain')+': '+addCommas(gain)+'%0A';
			total += newval;
			totalgain += gain;
			Options.OverviewOptions.LastReportStatus[q][5] = newval;
		}
		message += '%0A '+tx('Total Gold')+' : '+addCommas(total);
		message += '%0A '+tx('Total Gain')+' : '+addCommas(totalgain)+' %0A';

		message += '%0A ';

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.emailTo = Seed.player['name'];
		params.subject = tx("Resource Overview");

		if (uW.koc2Mail && Options.OverviewOptions.ReportEmail) {
			koc2Mail.customMail(params.emailTo,params.subject,message);
		}

		params.message = message;
		params.requestType = "COMPOSED_MAIL";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					DeleteLastMessage();
				}
			},
		});

		Options.OverviewOptions.LastReport = now;
		saveOptions();
	},
}

/*********************************** Alliance Tab ***********************************/

Tabs.Alliance = {
	tabOrder: 1060,
	tabLabel: 'Alliance',
	myDiv: null,
	alliancemembers: [],
	sortmembers: [],
	number: 0,
	totalmembers: 0,
	error: false,
	HQActive: false,
	LoopCounter: 0,
	DonationLog : {},
	DonateResourceItems : {40010:1000000,40040:1000000,40030:1000000,40020:1000000,40000:1000000,40050:1,43000:1}, 
	VaultItems : {0:{41000:1000000},1:{41010:1000000},2:{41020:1000000},3:{41030:1000000},4:{41040:1000000},5:{41050:1000000},6:{41060:100,41061:500,40162:1000},7:{}},
	ArcaneBundles : [43001,43002,43003,43004],
	AuraDistance : 0,
	DonationLimit : 0,
	ActiveTab : '',
	memactive : 0,
	memtotal : 0,
	memspan : '',
	serverwait : false,
	aid : 0,
	Options: {
		sortColNum : 0,
		sortDir : 1,
		Monitor:false,
		MonitorHours:1,
		MonitorCC:"",
		LastChecked:0,
		MonitorId:0,
		LastMemberList:{},
		DeleteHQMessages:false,
		EnableAutoAmber:false,
		MineLastChecked:0,
		ResLastChecked:0,
		DonateReport:false,
		LastDonateReport:0,
		DonateReportInterval:24,
		DonateReportEmail:false,
		AutoDonate:{},
		InfoDisplayed:false,
		UnBundleArcaneTablets:false,
	},

// t.alliancemembers for sorting
// 0 - name
// 1 - might
// 2 - cities
// 3 - position
// 4 - dip
// 5 - lastlogin
// 6 - uid
// 7 - fbuid
// 8 - avatarurl
// 9 - glory
//10 - dateJoined
//11 - lastlogin (sortable)
//12 - dateJoined (sortable)
//13 - rune score

	init: function (div) {
		var t = Tabs.Alliance;
		t.myDiv = div;

		if (!Options.AllianceOptions) {
			Options.AllianceOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.AllianceOptions.hasOwnProperty(y)) {
					Options.AllianceOptions[y] = t.Options[y];
				}
			}
		}

		t.loadLog();

		for (var k in t.DonateResourceItems) {
			if (!Options.AllianceOptions.AutoDonate[k]) {
				Options.AllianceOptions.AutoDonate[k] = {};
				Options.AllianceOptions.AutoDonate[k].Active = false;
				Options.AllianceOptions.AutoDonate[k].Amount = 0;
				Options.AllianceOptions.AutoDonate[k].Donated = 0;
			}
		}
		t.CheckNewDay();

		uWExportFunction('ptallClickSort', Tabs.Alliance.allClickSort);
		uWExportFunction('ptsetMember', Tabs.Alliance.setMember);
		uWExportFunction('btCollectAmber', Tabs.Alliance.CheckMineAmber);
		uWExportFunction('btDonateNow', function () { ById('bttcInventory').click(); ById('pbinventory_alliance').click(); });
		uWExportFunction('btPrestigeShown', function () { Options.AllianceOptions.InfoDisplayed=true;saveOptions(); });

		var HQ = '<span class=boldRed>'+uW.g_js_strings.commonstr.none+'</span>';
		var HQCoords = '<span class=boldRed>'+uW.g_js_strings.commonstr.none+'</span>';
		var HQStyle = 'display:none;';
		if (Seed.allianceHQ) {
			var ahqlevel = 0;
			jQuery.each(Seed.allianceHQ.buildings, function (key, value) {
				ahqlevel += parseInt(value.buildingLevel)
			});
			HQ = uW.g_js_strings.commonstr.level+' '+ahqlevel;
			HQCoords = coordLink(Seed.allianceHQ.hq_xcoord,Seed.allianceHQ.hq_ycoord);
			HQStyle = '';
			t.HQActive = true;
		}

		t.totalmembers = 0;
		t.alliancemembers = [];
		var m = '<DIV class=divHeader align="center">'+tx('ALLIANCE FUNCTIONS')+'</div>';
		if (!Seed.allianceDiplomacies) {
			m += '<table class=xtab width=100%><tr><TD align=center style="font-size:14px;";><b>'+tx('You are not a member of an Alliance')+'</b></td></tr></table>';
			t.myDiv.innerHTML = m;
			return;
		}
		t.aid = Seed.allianceDiplomacies['allianceId'];
		m += '<table class=xtab align=center>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+tx('Alliance Name')+':</td><td class=xtab><b>'+Seed.allianceDiplomacies['allianceName']+'</b></td><td class=xtab align=right>'+tx('Alliance Id')+':</td><td class=xtab><b>'+t.aid+'</b></td></tr>';
		m += '<TR><TD class=xtab>&nbsp;</td><td align=right class=xtab>'+tx('Alliance HQ')+':</td><td class=xtab><b>'+HQ+'</b></td><td class=xtab align=right>'+uW.g_js_strings.commonstr.coordinates+':</td><td class=xtab><b>'+HQCoords+'</b></td></tr>';
		m += '</table>';
		m += '<TABLE width=100% class=xtab><TD width=200><INPUT style="'+HQStyle+'" id=alHQ type=submit value="'+tx("Alliance HQ")+'">&nbsp;<INPUT id=aldiplo type=submit value="'+tx("Diplomacies")+'">&nbsp;<INPUT id=alList type=submit value="'+tx('Alliance Members')+'">&nbsp;<span id=ptalliprogress></span></td>';
		m += '<td align=right>'+tx('Membership Monitor')+'&nbsp;<INPUT id=pballimonitor type=checkbox '+ (Options.AllianceOptions.Monitor?'CHECKED ':'') +'/>&nbsp;'+tx('Check Every')+'&nbsp;<INPUT id=pballihours type=text size=2 value="' + Options.AllianceOptions.MonitorHours + '">&nbsp;'+tx('hours')+'</td></tr>';
		m += '</table>';
		m += '<DIV id=alHeader class=divHeader align="center">'+tx('SEARCH RESULTS')+'</div>';
		m += '<DIV id=alOverviewTab style="height:530px;max-height:535px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px";overflow-x:scroll;"></div><br>';
		t.myDiv.innerHTML = m;

		ToggleOption('AllianceOptions','pballimonitor','Monitor',t.ToggleAllianceMonitor);
		ById('pballihours').addEventListener ('change', function(){
			Options.AllianceOptions.MonitorHours = ById('pballihours').value;
			if (isNaN(Options.AllianceOptions.MonitorHours)) {
				Options.AllianceOptions.MonitorHours = 1;
				ById('pballihours').value = 1;
			}
            saveOptions ();
		},false);

		ById('alList').addEventListener('click', function () {
			t.ActiveTab = 'Members';
			ById('alHeader').innerHTML = tx('SEARCH RESULTS');
			if (!t.searching) {
				t.totalmembers = 0;
				t.alliancemembers = [];
				ById('alOverviewTab').innerHTML = "";
				ById('ptalliprogress').innerHTML = uW.g_js_strings.commonstr.loadingddd;
				ById('alList').disabled = true;
				t.error = false;
				t.fetchAllianceMemberPage();
			}
		}, false);
		ById('aldiplo').addEventListener('click', t.paintDiplomacy, false);
		ById('alHQ').addEventListener('click', t.paintHQOptions, false);

		if (t.HQActive) {
			t.sendDonateReport(); // check every refresh
			if (Options.AllianceOptions.DeleteHQMessages) {
				setTimeout(function() { t.scanHQMessages(4);},13000); // scan first 4 pages for gifts after initialisation
			}
		}
	},

	ToggleAllianceMonitor : function () {
		var t = Tabs.Alliance;
		if (Options.AllianceOptions.Monitor) { // reset last sent time...
			Options.AllianceOptions.LastChecked = 0;
			saveOptions();
		}
	},

	paintMembers: function () {
		var t = Tabs.Alliance;

		function sortFunc(a, b) {
			var t = Tabs.Alliance;
			if (typeof (a[Options.AllianceOptions.sortColNum]) == 'number') {
				if (Options.AllianceOptions.sortDir > 0)
					return a[Options.AllianceOptions.sortColNum] - b[Options.AllianceOptions.sortColNum];
				else
					return b[Options.AllianceOptions.sortColNum] - a[Options.AllianceOptions.sortColNum];
			} else if (typeof (a[Options.AllianceOptions.sortColNum]) == 'boolean') {
				return 0;
			} else {
				if (Options.AllianceOptions.sortDir > 0)
					return a[Options.AllianceOptions.sortColNum].localeCompare(b[Options.AllianceOptions.sortColNum]);
				else
					return b[Options.AllianceOptions.sortColNum].localeCompare(a[Options.AllianceOptions.sortColNum]);
			}
		}

		var EmptyDatabase = (t.alliancemembers.length == 0);
		if (!EmptyDatabase) {
			t.sortmembers = t.alliancemembers.sort(sortFunc);

			var r = 0;
			var z = '<center><table width=98% cellspacing=0 cellpadding=0 class=xtab>';
			z += '<TR></td><TD width=40 align=left nowrap>&nbsp;</td>\
				<TD width=60 nowrap><A id=AlliCol0 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.nametx+'&nbsp;</span></a></td>\
				<TD width=60 align=right nowrap><A id=AlliCol1 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.might+'&nbsp;</span></a></td>\
				<TD width=60 nowrap><A id=AlliCol9 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.glory+'&nbsp;</span></a></td>\
				<TD width=60 nowrap><A id=AlliCol13 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Runes')+'&nbsp;</span></a></td>\
				<TD align=right nowrap><A id=AlliCol2 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.cities+'&nbsp;</span></a></td>\
				<TD align=left nowrap><A id=AlliCol3 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.position+'&nbsp;</span></a></td>\
				<TD align=left nowrap><A id=AlliCol4 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('DIP')+'&nbsp;</span></a></td>\
				<TD align=left nowrap><A id=AlliCol11 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+'&nbsp;</span></a></td>\
				<TD align=left nowrap><A id=AlliCol12 onclick="ptallClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Joined')+'&nbsp;</span></a></td>';
			if (allianceleader) {
				z += '<td align=left nowrap>&nbsp;</td>';
			}
			z += '</tr>';

			for (var y in t.sortmembers) {
				if (t.sortmembers[y][6]) {
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';

					var promstring = '';
					if (allianceleader && t.sortmembers[y][6] != uW.tvuid) {
						switch (officertype) {
							case 1:
							case 2:
								if (parseInt(officertype) < parseIntNan(t.sortmembers[y][3])) {
									promstring += '<input class=btInput type="button" value="'+uW.g_js_strings.commonstr.promote+'" onclick="ptsetMember(\'promote\','+t.sortmembers[y][6]+','+t.sortmembers[y][3]+')" />';
									if (parseIntNan(t.sortmembers[y][3]) != 4) {
										promstring += '<input class=btInput type="button" value="'+uW.g_js_strings.commonstr.demote+'" onclick="ptsetMember(\'demote\','+t.sortmembers[y][6]+','+t.sortmembers[y][3]+')" />';
									}
								}
							case 3:
								if (parseInt(officertype) < parseIntNan(t.sortmembers[y][3])) {
									promstring += '<input class=btInput type="button" value="'+uW.g_js_strings.commonstr.remove+'" onclick="ptsetMember(\'remove\','+t.sortmembers[y][6]+','+t.sortmembers[y][3]+')" />';
								}
						}

					}

					z += '<tr class="'+rowClass+'"><TD class=xtab><A target="_blank" href="https://www.facebook.com/profile.php?id=' + t.sortmembers[y][7] + '"><img width=40 src="https://graph.facebook.com/' + t.sortmembers[y][7] + '/picture"></a></td>';
					z += '<TD class=xtab>'+PlayerLink(t.sortmembers[y][6],t.sortmembers[y][0])+'</td>';
					z += '<TD class=xtab align=right>'+addCommas(t.sortmembers[y][1])+'</td>';
					z += '<TD class=xtab align=right>'+addCommas(t.sortmembers[y][9])+'</td>';
					z += '<TD class=xtab align=right>'+addCommas(t.sortmembers[y][13])+'</td>';
					z += '<TD class=xtab align=right>'+t.sortmembers[y][2]+'</td>';
					z += '<TD class=xtab>'+officerId2String(t.sortmembers[y][3])+'</td>';
					z += '<TD class=xtab align=right>'+t.sortmembers[y][4]+'</td>';
					z += '<TD class=xtab align=right>'+t.sortmembers[y][5]+'</td>';
					z += '<TD class=xtab align=right>'+t.sortmembers[y][10]+'</td>';
					if (allianceleader) {
						z += '<td width=100 style="padding-right:0px;" id="ptallmemberact_'+t.sortmembers[y][6]+'" align=left nowrap>'+promstring+'</td>';
					}
					z += '</tr>';
				}
			}
			z += '</table></div><div align=right><input type=button value="'+tx('Export to Excel')+'" id=alListExcel>&nbsp;&nbsp;&nbsp;</div><br>';
			ById('alHeader').innerHTML = tx('SEARCH RESULTS');
			ById('alOverviewTab').innerHTML = z;

			ById('AlliCol' + Options.AllianceOptions.sortColNum).className = 'buttonv2 std green';
			ById('alListExcel').addEventListener('click', function() {
				t.ExportToExcel();
			}, false);
		}
		else {
			ById('alOverviewTab').innerHTML = '<center>'+tx('No alliance')+'</center>';
		}

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	allClickSort : function (e) {
		var t = Tabs.Alliance;
		var newColNum = e.id.substr(7);
		ById('AlliCol' + Options.AllianceOptions.sortColNum).className = 'buttonv2 std blue';
		e.className = 'buttonv2 std green';
		if (newColNum == Options.AllianceOptions.sortColNum) { Options.AllianceOptions.sortDir *= -1; }
		else { Options.AllianceOptions.sortColNum = newColNum; }
		saveOptions();
		t.paintMembers();
	},


	ExportToExcel: function () {
		var t = Tabs.Alliance;
		var headers = [ "UID", "Name", "Might", "Glory", "Runes", "Cities", "Position", "DIP", "Last Login", "Joined"];
		var ExcelTable = document.createElement('table');
		var ExcelBody = document.createElement('tbody');
		var ExcelRow = document.createElement('tr');
		var ExcelColumn = "";
		for (var i = 0; i < headers.length; i++) {
			ExcelColumn = document.createElement('th');
			ExcelColumn.appendChild(document.createTextNode(headers[i]));
			ExcelRow.appendChild(ExcelColumn);
		}
		ExcelBody.appendChild(ExcelRow);

		var columns = [];

		for (var y in t.sortmembers) {
			columns = [];
			columns.push(t.sortmembers[y][6]);
			columns.push(t.sortmembers[y][0]);
			columns.push(t.sortmembers[y][1]);
			columns.push(t.sortmembers[y][9]);
			columns.push(t.sortmembers[y][13]);
			columns.push(t.sortmembers[y][2]);
			columns.push(officerId2String(t.sortmembers[y][3]));
			columns.push(t.sortmembers[y][4]);
			columns.push(t.sortmembers[y][5]);
			columns.push(t.sortmembers[y][10]);
			columns.reverse();
			ExcelRow = document.createElement('tr');
			while (columns.length > 0) {
				ExcelColumn = document.createElement('td');
				ExcelColumn.appendChild(document.createTextNode(columns.pop()));
				ExcelRow.appendChild(ExcelColumn);
			}
			ExcelBody.appendChild(ExcelRow);
		}
		ExcelTable.appendChild(ExcelBody);
		window.open('data:application/vnd.ms-excel,' + encodeURIComponent(ExcelTable.outerHTML));
	},

	paintDiplomacy: function () {
		var t = Tabs.Alliance;
		t.ActiveTab = 'Diplomacy';
		ById('alOverviewTab').innerHTML = "";
		ById('ptalliprogress').innerHTML = "";
		ById('alHeader').innerHTML = uW.g_js_strings.allianceInfo.allidiplomacy.toUpperCase();
		var m = '<table class=xtab width=98%><tr><td valign=top><table class=xtab><TR><TD colspan=4 style=\'background: #33CC66;\' align=center><B>'+uW.g_js_strings.commonstr.friendly+': </b></td></tr>';
		if (Seed.allianceDiplomacies['friendly'] == null) m += '<TR><TD>'+tx('No Friendlies found')+'...</td></tr>';
		else m += '<TR><TD><b>'+uW.g_js_strings.getDiplomacy.alliname+'</b></td><TD><b>'+uW.g_js_strings.commonstr.members+'</b></td></tr>';
		for (var k in Seed.allianceDiplomacies['friendly']) {
			m += '<TR><TD>' + Seed.allianceDiplomacies['friendly'][k]['allianceName'] + '</td>';
			m += '<TD align=center>' + Seed.allianceDiplomacies['friendly'][k]['membersCount'] + '</td><TD class=xtab>';
			if (KOCBYTE_ON) m += '<a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + Seed.allianceDiplomacies['friendly'][k]['allianceId'] + '"><img title="'+tx('View alliance on KoCByte')+'" style="width:16px;vertical-align:bottom;opacity:0.75;" src="'+KOCBYTE_LOGO+'"></a>';
			m += '</td></tr>';
		}
		m += '</table></td><td valign=top>';
		m += '<table class=xtab><TR><TD colspan=4 style=\'background: #CC0033;\' align=center><B>'+uW.g_js_strings.commonstr.hostile+': </b></td></tr>';
		if (Seed.allianceDiplomacies['hostile'] == null) m += '<TR><TD>'+tx('No Hostiles found')+'...</td></tr>';
		else m += '<TR><TD><b>'+uW.g_js_strings.getDiplomacy.alliname+'</b></td><TD><b>'+uW.g_js_strings.commonstr.members+'</b></td></tr>';
		for (var k in Seed.allianceDiplomacies["hostile"]) {
			m += '<TR><TD>' + Seed.allianceDiplomacies["hostile"][k]['allianceName'] + '</td>';
			m += '<TD align=center>' + Seed.allianceDiplomacies["hostile"][k]['membersCount'] + '</td><TD class=xtab>';
			if (KOCBYTE_ON) m += '<a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + Seed.allianceDiplomacies['hostile'][k]['allianceId'] + '"><img title="'+tx('View alliance on KoCByte')+'" style="width:16px;vertical-align:bottom;opacity:0.75;" src="'+KOCBYTE_LOGO+'"></a>';
			m += '</td></tr>';
		}
		m += '</table></td><td valign=top>';
		m += '<table class=xtab><TR><TD colspan=4 style=\'background: #FF6633;\' align=center><B>'+uW.g_js_strings.getDiplomacy.friendlytoyou+': </b></td></tr>';
		if (Seed.allianceDiplomacies['friendlyToYou'] == null) m += '<TR><TD>'+tx('No Friendlies towards us found')+'...</td></tr>';
		else m += '<TR><TD><b>'+uW.g_js_strings.getDiplomacy.alliname+'</b></td><TD><b>'+uW.g_js_strings.commonstr.members+'</b></td></tr>';
		for (var k in Seed.allianceDiplomacies["friendlyToYou"]) {
			m += '<TR><TD>' + Seed.allianceDiplomacies["friendlyToYou"][k]['allianceName'] + '</td>';
			m += '<TD align=center>' + Seed.allianceDiplomacies["friendlyToYou"][k]['membersCount'] + '</td><TD class=xtab>';
			if (KOCBYTE_ON) m += '<a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + Seed.allianceDiplomacies['friendlyToYou'][k]['allianceId'] + '"><img title="'+tx('View alliance on KoCByte')+'" style="width:16px;vertical-align:bottom;opacity:0.75;" src="'+KOCBYTE_LOGO+'"></a>';
			m += '</td></tr>';
		}
		m += '<TR><TD colspan=4>&nbsp;</td></tr>';
		m += '<TR><TD colspan=4 style=\'background: #FF6633;\' align=center><B>'+uW.g_js_strings.getDiplomacy.friendlytowardsthem+': </b></td></tr>';
		if (Seed.allianceDiplomacies['friendlyToThem'] == null) m += '<TR><TD>'+tx('No Friendlies towards them found')+'...</td></tr>';
		else m += '<TR><TD><b>'+uW.g_js_strings.getDiplomacy.alliname+'</b></td><TD><b>'+uW.g_js_strings.commonstr.members+'</b></td></tr>';
		for (var k in Seed.allianceDiplomacies["friendlyToThem"]) {
			m += '<TR><TD>' + Seed.allianceDiplomacies["friendlyToThem"][k]['allianceName'] + '</td>';
			m += '<TD align=center>' + Seed.allianceDiplomacies["friendlyToThem"][k]['membersCount'] + '</td><TD class=xtab>';
			if (KOCBYTE_ON) m += '<a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + Seed.allianceDiplomacies['friendlyToThem'][k]['allianceId'] + '"><img title="'+tx('View alliance on KoCByte')+'" style="width:16px;vertical-align:bottom;opacity:0.75;" src="'+KOCBYTE_LOGO+'"></a>';
			m += '</td></tr>';
		}
		m += '</table></td></tr></table>';
		ById('alOverviewTab').innerHTML = m;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	paintHQOptions : function () {
		var t = Tabs.Alliance;
		t.ActiveTab = 'HQ';
		ById('alOverviewTab').innerHTML = "";
		ById('ptalliprogress').innerHTML = "";
		ById('alHeader').innerHTML = tx('ALLIANCE HQ');

		var m = '<div id=alHQPanel><br><center>'+uW.g_js_strings.commonstr.loadingddd+'</center><br></div>';
		m += '<div class="divHeader" align="center">'+tx('MEMBER OPTIONS')+'</div>';
		m += '<table class=xtab width=98%>';
		m += '<tr><td width=30><INPUT id=alhqdeletemsgs type=checkbox '+ (Options.AllianceOptions.DeleteHQMessages?' CHECKED':'') +'\></td><td colspan=2>'+tx('Automatically delete Alliance HQ donation messages')+'</td></tr>';
		m += '<tr><td class=xtab>&nbsp;</td><td class=xtab><INPUT id=alhqreport type=checkbox '+ (Options.AllianceOptions.DonateReport?' CHECKED':'') +'\>&nbsp;'+tx("Send Donation report every")+'&nbsp;<INPUT id=alhqreportinterval value='+ Options.AllianceOptions.DonateReportInterval +' type=text size=3 \>&nbsp;'+tx('hours')+'&nbsp;&nbsp;&nbsp;'+strButton8(tx('Send Now'), 'id=alhqreportsend')+'</td></tr>';
		if (uW.koc2Mail) {
			m += '<tr><td class=xtab>&nbsp;</td><td class=xtab><INPUT id=alhqreportemail type=checkbox '+ (Options.AllianceOptions.DonateReportEmail?' CHECKED':'') +'\>&nbsp;'+tx("CC to Email")+'</td></tr>';
		}
		m += '<tr><td><INPUT id=alhqautoamber type=checkbox '+ (Options.AllianceOptions.EnableAutoAmber?' CHECKED':'') +'\></td><td colspan=2>'+tx('Automatically collect Amber from Alliance Mine')+'</td></tr>';
		m += '<tr><td colspan=2><b>'+tx('Automatic Daily Resource Donations')+'</b></td></tr>';
		m += '<tr><td><INPUT id=alhqautounbundle type=checkbox '+ (Options.AllianceOptions.UnBundleArcaneTablets?' CHECKED':'') +'\></td><td colspan=2>'+tx('Automatically unbundle crafted Arcane Tablet items')+'</td></tr>';
		m += '<tr><td colspan=2><table class=xtab width=100%><tr><td><table class=xtab align=center cellpadding=0 cellspacing=0><tr style="vertical-align:top;">';
		for (var k in t.DonateResourceItems) {
			m += '<td rowspan=2><img width=30 src="'+IMGURL+'items/70/'+k+'.jpg" title="'+uW.itemlist["i"+k].name+'" /></td><td width=15%>(<span id="albunowned_'+k+'"> '+parseIntNan(uW.ksoItems[k].count)+'</span>)</td>';
		}
		m += '</tr><tr style="vertical-align:top;">';
		for (var k in t.DonateResourceItems) {
			m += '<td><INPUT type=CHECKBOX class='+k+' id="aldonchk_'+k+'" '+(Options.AllianceOptions.AutoDonate[k].Active?'Checked':'')+'></td>';
		}
		m += '</tr><tr>';
		for (var k in t.DonateResourceItems) {
			m += '<td align=right>'+tx('Donate')+':</td><td><INPUT style="font-size:10px;" class='+k+' id="aldon_'+k+'" type=text size=3 maxlength=3 value="'+Options.AllianceOptions.AutoDonate[k].Amount+'"\></td>';
		}
		m += '</table></td></tr></table></td></tr>';
		m += '<tr><td colspan=2><b>'+tx('Resources Selected')+':&nbsp;<span id=alhqdonstats>&nbsp;</span></b>&nbsp;('+tx('excluding aetherstone and arcane tablets')+')</td></tr>';
		m += '</table>';

		ById('alOverviewTab').innerHTML = m;

		for (var k in t.DonateResourceItems) {
			if (!Options.AllianceOptions.AutoDonate[k].Active) { ById('aldon_'+k).disabled = true; }
			else { ById('aldon_'+k).disabled = false; }

			ById('aldonchk_'+k).addEventListener('click', function(e){
				var item = e.target['className'];
				Options.AllianceOptions.AutoDonate[item].Active = e.target.checked;
				if (!Options.AllianceOptions.AutoDonate[item].Active) {
					Options.AllianceOptions.AutoDonate[item].Amount = 0;
					ById('aldon_'+item).value = 0;
					ById('aldon_'+item).disabled = true;
				}
				else { ById('aldon_'+item).disabled = false; }
				Options.AllianceOptions.ResLastChecked = 0;
				saveOptions();
				t.paintHQTimers();
			}, false);

			ById('aldon_'+k).addEventListener('change', function (e) { t.AutoDonateChange(e.target); }, false);
			ById('aldon_'+k).addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.AutoDonateChange);	}, false);

		}

		ById('alhqdeletemsgs').addEventListener('change', function(){
			Options.AllianceOptions.DeleteHQMessages = this.checked;
			saveOptions();
			if(Options.AllianceOptions.DeleteHQMessages) { t.scanHQMessages(4); }
		}, false);

        ById('alhqreportinterval').addEventListener('keyup', function () {
            if (isNaN(ById('alhqreportinterval').value) || ById('alhqreportinterval').value<1) { ById('alhqreportinterval').value = 1; }
            Options.AllianceOptions.DonateReportInterval = ById('alhqreportinterval').value;
            saveOptions();
			t.sendDonateReport();
        }, false);
        ById('alhqreportsend').addEventListener('click', function () {
            Options.AllianceOptions.LastDonateReport = 0;
            saveOptions();
			t.sendDonateReport();
        }, false);
		ToggleOption('AllianceOptions','alhqreport','DonateReport',t.sendDonateReport);
		if (uW.koc2Mail) {
			ToggleOption('AllianceOptions','alhqreportemail','DonateReportEmail');
		}
		ToggleOption('AllianceOptions','alhqautoamber','EnableAutoAmber', function () { Options.AllianceOptions.MineLastChecked=0;saveOptions(); });
		ToggleOption('AllianceOptions','alhqautounbundle','UnBundleArcaneTablets');

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		FetchHQInfo(t.paintHQ);
	},

	AutoDonateChange : function (e) {
		var t = Tabs.Alliance;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		if (isNaN(e.value)) e.value=0;
		var item = e['className'];
		Options.AllianceOptions.AutoDonate[item].Amount = e.value;
		Options.AllianceOptions.ResLastChecked = 0;
		saveOptions();
		t.paintHQTimers();
	},

	paintHQ: function (rslt,rslt2,rslt3) {
		var t = Tabs.Alliance;
		if (!rslt.ok) return;
		if (!rslt2.ok) return;
		if (!rslt3.ok) return;

		function getSpan(val1,val2) {
			var span = '<span>';
			if (val1==val2) span = '<span class=boldGreen>';
			return span;
		}

		t.memactive = 0;
		t.memtotal = 0;
		if (rslt3.collect_status) {
			for (var p in rslt3.collect_status) {
				var mem = rslt3.collect_status[p];
				t.memtotal++;
				if (mem.status==0) t.memactive++;
			}
		}
		t.memspan = getSpan(t.memactive,t.memtotal)+'<b>'+t.memactive+'/'+t.memtotal+'</b></span>';
		t.DonationLimit = rslt2.dailyDonations.caps.resource;

		var VaultAmount = [];
		for (var vv in t.VaultItems) { VaultAmount[vv]=0; }
		for (var v in rslt2.items) {
			for (var vv in t.VaultItems) {
				if (t.VaultItems[vv].hasOwnProperty(v)) {
					VaultAmount[vv] += parseIntNan(rslt2.items[v])*parseIntNan(t.VaultItems[vv][v]);
				}
			}
		}

		var m = '<TABLE width=98% align=center cellpadding=0 cellspacing=0 class=xtab><TR style="vertical-align:top;"><td width=50% align=center><b>'+tx('RESOURCES')+'</b><br><TABLE cellpadding=1 cellspacing=0 class=xtab style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;">';
		m += '<tr><td>&nbsp;</td><td align=right><b>'+tx('TOTAL')+'</b></td><td align=right><b>'+uW.g_js_strings.commonstr.owned.toUpperCase()+'</b></td><td align=right><b>'+uW.g_js_strings.commonstr.inventory.toUpperCase()+'</b></td><td align=right><b>'+tx('LIMIT')+'</b></td></tr>';
		m += '<tr class="evenRow"><td align=right>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.gold+VaultAmount[0])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.gold,rslt2.dailyCaps[0])+addCommas(rslt.hq.stats.gold)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[0])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[0])+'</div></td></tr>';
		m += '<tr class="oddRow"><td align=right>'+ResourceImage(FoodImage,uW.g_js_strings.commonstr.food)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.food+VaultAmount[1])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.food,rslt2.dailyCaps[1])+addCommas(rslt.hq.stats.food)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[1])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[1])+'</div></td></tr>';
		m += '<tr class="evenRow"><td align=right>'+ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.wood+VaultAmount[2])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.wood,rslt2.dailyCaps[2])+addCommas(rslt.hq.stats.wood)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[2])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[2])+'</div></td></tr>';
		m += '<tr class="oddRow"><td align=right>'+ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.stone+VaultAmount[3])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.stone,rslt2.dailyCaps[3])+addCommas(rslt.hq.stats.stone)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[3])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[3])+'</div></td></tr>';
		m += '<tr class="evenRow"><td align=right>'+ResourceImage(OreImage,uW.g_js_strings.commonstr.ore)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.ore+VaultAmount[4])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.ore,rslt2.dailyCaps[4])+addCommas(rslt.hq.stats.ore)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[4])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[4])+'</div></td></tr>';
		m += '<tr class="oddRow"><td align=right>'+ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.aetherstone+VaultAmount[5])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.aetherstone,rslt2.dailyCaps[5])+addCommas(rslt.hq.stats.aetherstone)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[5])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[5])+'</div></td></tr>';
		m += '<tr class="evenRow"><td align=right>'+ResourceImage(AmberImage,uW.g_js_strings.alliance.resource1)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.amber+VaultAmount[6])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.amber,rslt2.dailyCaps[6])+addCommas(rslt.hq.stats.amber)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[6])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[6])+'</div></td></tr>';
		m += '<tr class="evenRow"><td align=right>'+ResourceImage(ArcaneTabletImage,uW.g_js_strings.playerGuide.ahq_14_h)+'</td><td align=right><div class="totalCell xtabBorder">'+addCommas(rslt.hq.stats.arcanetablet+VaultAmount[7])+'</div></td><td align=right><div class=xtabBorder>'+getSpan(rslt.hq.stats.arcanetablet,rslt2.dailyCaps[7])+addCommas(rslt.hq.stats.arcanetablet)+'</span></div></td><td align=right><div class=xtabBorder>'+addCommas(VaultAmount[7])+'</div></td><td align=right><div class=xtabBorder>'+addCommas(rslt2.dailyCaps[7])+'</div></td></tr>';

		m += '</table></td><td width=50% align=center><b>'+tx('ACTIVITY')+'</b><br><TABLE cellpadding=1 cellspacing=0 class=xtab>';
		m += '<tr><td align=right>'+tx('Resource Donations')+':</td><td>'+getSpan(rslt2.dailyDonations.quantity.resource,rslt2.dailyDonations.caps.resource)+'<b>'+addCommas(rslt2.dailyDonations.quantity.resource)+'/'+addCommas(rslt2.dailyDonations.caps.resource)+'</b></span>&nbsp;&nbsp;'+strButton8(tx('Donate Now'),'id=btResDonateButton onclick="btDonateNow();"')+'</td></tr>';
		m += '<tr><td align=right>'+tx('Alliance Donations')+':</td><td>'+getSpan(rslt2.dailyDonations.quantity.alliance,rslt2.dailyDonations.caps.alliance)+'<b>'+addCommas(rslt2.dailyDonations.quantity.alliance)+'/'+addCommas(rslt2.dailyDonations.caps.alliance)+'</b></span></td></tr>';
		m += '<tr><td align=right>'+tx('Hourglass Donations')+':</td><td>'+getSpan(rslt2.dailyDonations.quantity.hourglass,rslt2.dailyDonations.caps.hourglass)+'<b>'+rslt2.dailyDonations.quantity.hourglass+'/'+rslt2.dailyDonations.caps.hourglass+'</b></span></td></tr>';
		m += '<tr><td align=right>&nbsp;</td><td>&nbsp;</td></tr>';
		m += '<tr><td align=right>'+tx('Amber Mine Status')+':</td><td><span id=alminestatus>&nbsp;</span></td></tr>';
		m += '<tr><td align=right>'+tx('Alliance Mining')+':</td><td><span id=alalliminestatus>'+t.memspan+'</span></td></tr>';
		m += '<tr><td align=right>&nbsp;</td><td>&nbsp;</td></tr>';
		m += '<tr><td align=right>'+tx('Arcane Temple Aura Distance')+':</td><td><span id=alauradistance>&nbsp;</span></td></tr>';
		m += '</table></td></tr></table>';

		if (ById('alHQPanel')) {
			ById('alHQPanel').innerHTML = m;

			if (rslt2.dailyDonations.quantity.resource>=rslt2.dailyDonations.caps.resource || rslt2.dailyDonations.quantity.alliance>=rslt2.dailyDonations.caps.alliance) {
				ById('btResDonateButton').setAttribute("style","display:none");
			}

			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
			t.paintHQTimers();
		}
	},

	paintHQTimers : function () {
		var t = Tabs.Alliance;
		if (t.serverwait) return;
		var now = uW.unixtime();
		var cooldown = 0;
		var allicooldown = 0;
		if (typeof Seed.allianceHQ.mineCooldown !== "undefined") { cooldown = +Seed.allianceHQ.mineCooldown; }
		if (typeof Seed.allianceHQ.allianceMineCooldown !== "undefined") { allicooldown = +Seed.allianceHQ.allianceMineCooldown; }

		if (ById('alminestatus')) {
			if (allicooldown > cooldown && allicooldown > now) { ById('alminestatus').innerHTML = '<span class=boldRed>'+tx('Cannot mine for')+'&nbsp;'+timestr(allicooldown-now)+'</span>'; }
			else {
				if (cooldown > now) { ById('alminestatus').innerHTML = '<span class=boldGreen>'+uW.g_js_strings.alliance.mining+'&nbsp;'+timestr(cooldown-now)+'</span>'; }
				else { ById('alminestatus').innerHTML = '<span class=boldRed>'+uW.g_js_strings.commonstr.inactive+'</span>&nbsp;'+strButton8(uW.g_js_strings.alliance.collect,'id=btAmberButton onclick="btCollectAmber();"'); }
			}
		}
		if (ById('alauradistance')) {
			if (Seed.allianceHQ && Seed.allianceHQ.arcana && Seed.allianceHQ.buildings[3] && Seed.allianceHQ.buildings[3].buildingLevel && Seed.allianceHQ.buildings[3].buildingLevel!=0) {
				t.AuraDistance = Seed.allianceHQ.arcana[Seed.allianceHQ.buildings[3].buildingLevel].distance;
				ById('alauradistance').innerHTML = parseIntNan(t.AuraDistance);
			}
			else {
				ById('alauradistance').innerHTML = '<span class=boldRed>'+tx('No Arcane Temple')+'<span>';
			}
		}
		for (var k in t.DonateResourceItems) {
			if (ById('albunowned_'+k)) {
				ById('albunowned_'+k).innerHTML = parseIntNan(uW.ksoItems[k].count);
			}
		}
		if (ById('alhqdonstats')) {
			var count = 0;
			for (var k in t.DonateResourceItems) {
				count += (Options.AllianceOptions.AutoDonate[k].Amount * t.DonateResourceItems[k]);
			}
			var rc = '';
			if (count==t.DonationLimit) { rc = 'boldGreen' }
			else if (count>t.DonationLimit) { rc = 'boldRed' }
			ById('alhqdonstats').className = rc;
			ById('alhqdonstats').innerHTML = addCommas(count)+'/'+addCommas(t.DonationLimit);
		}
	},

	fetchAllianceMemberPage: function (silent,notify) {
		var t = Tabs.Alliance;
		if (!silent) ById('alList').disabled = true;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				t.totalmembers = parseIntNan(rslt["allianceInfo"]["members"]);
				for (var i = 1; i <= Math.ceil(t.totalmembers/10); i++) {
					params.pageNo = i;
					params.pf = 0;
					new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetMembersInfo.php" + uW.g_ajaxsuffix, {
						method: "post",
						parameters: params,
						onSuccess: function (info) {
							if (info.ok) {
								for (var k in info["memberInfo"]) {
									if (info["memberInfo"][k]["might"] != undefined && !t.error) {
										var datesplit = info["memberInfo"][k]["lastLogin"].split(" ");
										var mnth = uW.MONTH_NAMES.indexOf(datesplit[0]);
										if (mnth==-1) mnth=0;
										if (mnth>11) mnth=mnth-11;
										if (mnth<10) { var amnth = "A0"+mnth; } else {var amnth = "A"+mnth; }
										var LogTime = amnth+datesplit[1]+datesplit[2];
										var datesplit = info["memberInfo"][k]["dateJoined"].split(" ");
										var mnth = uW.MONTH_NAMES.indexOf(datesplit[1]);
										if (mnth ==-1) mnth=0;
										if (mnth>11) mnth=mnth-11;
										if (mnth<10) { var amnth = "A0"+mnth; } else {var amnth = "A"+mnth; }
										var JoinTime = datesplit[2]+amnth+datesplit[0];
										t.alliancemembers.push([ info["memberInfo"][k]["name"], parseInt(info["memberInfo"][k]["might"]), parseInt(info["memberInfo"][k]["cities"]), parseInt(info["memberInfo"][k]["positionType"]), parseInt(info["memberInfo"][k]["daysInPosition"]), info["memberInfo"][k]["lastLogin"], parseInt(info["memberInfo"][k]["userId"]), parseInt(info["memberInfo"][k]["fbuid"]), info["memberInfo"][k]["avatarurl"], parseInt(info["memberInfo"][k]["glory"]), info["memberInfo"][k]["dateJoined"], LogTime, JoinTime, parseInt(info["kothScore"][k]||0)]);
									}
								}
								if (!t.error && !silent) ById('ptalliprogress').innerHTML = '(' + (t.alliancemembers.length) + '/' + t.totalmembers + ')';
								if (!silent) {
									ById('alOverviewTab').innerHTML = "";
									t.paintMembers();
								}
								if (t.alliancemembers.length >= t.totalmembers) {
									if (!silent) ById('alList').disabled = false;
									if (notify) { notify(); }
								}
							} else if (info.error) {
								if (!silent) {
									ById('alList').disabled = false;
									ById('ptalliprogress').innerHTML = "ERROR!";
								}
								t.error = true;
							}
						},
						onFailure: function () {
							if (!silent) {
								ById('alList').disabled = false;
								ById('ptalliprogress').innerHTML = "ERROR!";
							}
							t.error = true;
						},
					},true);
				}
			},
			onFailure: function () {
				if (!silent) {
					ById('alList').disabled = false;
					ById('ptalliprogress').innerHTML = "ERROR!";
				}
				t.error = true;
			},
		},true);
	},

	show: function () {
		var t = Tabs.Alliance;
		AreYouALeader();
		if (t.ActiveTab == 'HQ') { FetchHQInfo(t.paintHQ); }
		else {
			if (t.HQActive && t.ActiveTab == '') {
				t.paintHQOptions();
			}
		}
	},

	loadLog : function () {
		var t = Tabs.Alliance;
		var serverID = getServerId();
		s = GM_getValue ('HQDonationLog_'+serverID+'_'+uW.tvuid);
		if (s != null){
			opts = JSON2.parse (s);
			for (var k in opts)
				t.DonationLog[k] = opts[k];
		}
	},

	saveLog : function () {
		var t = Tabs.Alliance;
		setTimeout(function () { GM_setValue ('HQDonationLog_'+getServerId()+'_'+uW.tvuid, JSON2.stringify(t.DonationLog));} ,0); // get around GM_SetValue uW error
	},


	EverySecond : function () {
		var t = Tabs.Alliance;
		var aid = getMyAlliance()[0];
		var now = unixTime();
		if (aid > 0) {
			if (Options.AllianceOptions.Monitor && Options.AllianceOptions.LastChecked + (Options.AllianceOptions.MonitorHours*60*60) < now) {
				Options.AllianceOptions.LastChecked = now;
				if (aid != Options.AllianceOptions.MonitorId) { // new alliance, just set members, don't send message..
					actionLog ('Setting alliance monitor start position for this alliance','ALLIANCE');
					t.totalmembers = 0;
					t.alliancemembers = [];
					t.error = false;
					t.fetchAllianceMemberPage(true,t.SaveMembers);
				}
				else {
					actionLog ('Checking alliance member list for changes','ALLIANCE');
					t.totalmembers = 0;
					t.alliancemembers = [];
					t.error = false;
					t.fetchAllianceMemberPage(true,t.CompareMembers);
				}
				Options.AllianceOptions.MonitorId = aid;
				saveOptions();
			}
		}

		t.LoopCounter = t.LoopCounter + 1;

		if (t.HQActive) {
			if (t.LoopCounter >= 60) {
				t.LoopCounter = 0;
				t.sendDonateReport();
				// check for hq messages on first page every 60 seconds..
				t.scanHQMessages(1);
				if (tabManager.currentTab.name == 'Alliance' && t.ActiveTab=='HQ' && Options.btWinIsOpen){
					FetchHQInfo(t.paintHQ);
				}
				if (Options.AllianceOptions.UnBundleArcaneTablets) {
					t.CheckUnBundleArcaneTablets();
				}	
			}
			if (tabManager.currentTab.name == 'Alliance' && t.ActiveTab=='HQ' && Options.btWinIsOpen){
				t.paintHQTimers();
			}
			if (Options.AllianceOptions.EnableAutoAmber && Options.AllianceOptions.MineLastChecked + (15*60) < now) {
				t.CheckMineAmber();
			}
			if (Options.AllianceOptions.ResLastChecked + (15*60) < now) {
				t.CheckDonateResources();
			}
		}
	},

	SaveMembers: function () {
		var t = Tabs.Alliance;
		Options.AllianceOptions.LastMemberList = {};
		for (var y in t.alliancemembers) {
			if (t.alliancemembers[y][6]) {
				Options.AllianceOptions.LastMemberList[t.alliancemembers[y][6]] = t.alliancemembers[y];
			}
		}
		saveOptions();
	},

	CompareMembers : function () {
		var t = Tabs.Alliance;
		var MemberChanges = false;
		var message = '%0A '+tx('Additional Members')+': %0A';

		for (var y in t.alliancemembers) {
			if (t.alliancemembers[y][6] && !Options.AllianceOptions.LastMemberList[t.alliancemembers[y][6]]) {
				MemberChanges = true;
				message += t.alliancemembers[y][0]+' (Might '+addCommas(t.alliancemembers[y][1])+') '+officerId2String(t.alliancemembers[y][3])+' UID:'+t.alliancemembers[y][6]+' %0A';
			}
		}
		if (!MemberChanges) { message += 'None %0A'; }

		var MemberLeft = false;
		message += '%0A '+tx('Departed Members')+': %0A';
		for (var x in Options.AllianceOptions.LastMemberList) {
			if (Options.AllianceOptions.LastMemberList[x][6]) {
				var Found = false;
				for (var y in t.alliancemembers) {
					if (t.alliancemembers[y][6] && x==t.alliancemembers[y][6]) {
						Found = true;
						break;
					}
				}
				if (!Found) {
					MemberLeft = true;
					MemberChanges = true;
					message += Options.AllianceOptions.LastMemberList[x][0]+' (Might '+addCommas(Options.AllianceOptions.LastMemberList[x][1])+') '+officerId2String(Options.AllianceOptions.LastMemberList[x][3])+' UID:'+Options.AllianceOptions.LastMemberList[x][6]+' %0A';
				}
			}
		}
		if (!MemberLeft) { message += 'None %0A'; }

		if (MemberChanges) {
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.emailTo = Seed.player['name'];
			params.subject = tx("Alliance Membership Change Report for")+" "+getMyAlliance()[1];
			params.message = message;
			params.requestType = "COMPOSED_MAIL";
			new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					if (rslt.ok) { DeleteLastMessage(); }
				},
			},true);

			// save current position...
			t.SaveMembers();
		}
	},

	setMember : function (actionType,pid,pos){ // "promote", "demote", "remove"
		var t = Tabs.Alliance;
		var popConfirm = null;
		popConfirm = new CPopup('ptConfirmAction', 0, -100, 500, 100, true, function () { clearTimeout(1000); });
		popConfirm.centerMe(mainPop.getMainDiv());
		var m = '<DIV style="height:50px;"><br><TABLE align=center cellpadding=0 cellspacing=0 width=100% class=xtab>';
		if (pos==2 && actionType == "promote") { m += '<tr><TD align=center><span class=boldRed>'+tx("WARNING - This action will demote you to Vice Chancellor!")+'<br>&nbsp;</td></tr>'; }
		m += '<tr><TD align=center><INPUT id=ptConfirm type=submit value="'+actionType.toUpperCase()+'" \>&nbsp;<INPUT id=ptCancel type=submit value="'+uW.g_js_strings.commonstr.cancel+'" \></td></tr></table></div>';
		popConfirm.getMainDiv().innerHTML = m;
		ResetFrameSize('ptConfirmAction',100,500);
		popConfirm.getTopDiv().innerHTML = '<DIV align=center><b>'+tx('Confirm action on alliance member')+'?</b></div>';
		popConfirm.show(true);
		ById('ptConfirm').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;

			var params = uW.Object.clone(uW.g_ajaxparams);
			var fileName = "";
			var actionName = "";
			if (actionType == "promote") {
				fileName = "alliancePromoteMember.php";
				actionName = tx('Promoted!');
			} else {
				if (actionType == "demote") {
					fileName = "allianceDemoteMember.php";
					actionName = tx('Demoted!');
				} else {
					if (actionType == "remove") {
						fileName = "allianceRemoveMember.php";
						actionName = tx('Removed!');
					}
				}
			}
			if (fileName != "") {
				params.memberOfficerType = pos;
				params.memberId = pid;
				new MyAjaxRequest(uW.g_ajaxpath + "ajax/" + fileName + uW.g_ajaxsuffix, {
					method : "post",
					parameters : params,
					onSuccess : function (rslt) {
						if (rslt.ok) {
							ById('ptallmemberact_'+pid).innerHTML = actionName;
						} else {
							uW.Modal.showAlert(uW.printLocalError(rslt.error_code, rslt.msg, rslt.feedback));
							ById('ptallmemberact_'+pid).innerHTML = 'ERROR!';
						}
						t.totalmembers = 0;
						t.alliancemembers = [];
						t.error = false;
						t.fetchAllianceMemberPage(true,t.paintMembers); // refresh members display
					},
				},true)
			}
		}, false);
		ById('ptCancel').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;
		}, false);
	},

	scanHQMessages : function(page) {
		var t = Tabs.Alliance;
		page = Number(page);
		if(!Options.AllianceOptions.DeleteHQMessages) {return;}
		if(page <= 0) {return;}
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType = "GET_MESSAGE_HEADERS_FOR_USER_INBOX";
		params.boxType="hq_messages";
		params.pageNo=page;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var deletes1 = new Array();
					for (var i in rslt.message) {
						if (rslt.message[i].subject) {
							var HQMessage = false;
							for (var j in HQText) {
								if (rslt.message[i].subject.indexOf(HQText[j]) != -1) {
									HQMessage = true;
									break;
								}
							}
							if(rslt.message[i].fromUserId == "0" && HQMessage){
								t.foundHQMessage(i);
								if (deletes1.indexOf(i) == -1) { deletes1.push(i); }
							}
						}
					}
					if(deletes1.length > 0){
						actionLog('Deleting '+deletes1.length+' Alliance HQ donation messages','ALLIANCE');
						t.deletemsgs(deletes1.join(","));
					}
					setTimeout(function() {	t.scanHQMessages(parseInt(page-1))},5000);
				} else return;
			},
		},true);
	},

	foundHQMessage : function (id) {
		var t = Tabs.Alliance;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.messageId=id;
		params.requestType = "GET_MESSAGE_FOR_ID";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var name = rslt.messageBody.split(" ")[0];
					var myregexp = /has donated (.*) to/;
					var match = myregexp.exec(rslt.messageBody)[1]||'1';
					var amount = parseIntNan(match.substr(0,match.indexOf(' ')));
					var type = match.substr(match.indexOf(' ')+1)||"Unknown";
					if (!t.DonationLog[name]) t.DonationLog[name] = {};
					if (t.DonationLog[name][type]) { t.DonationLog[name][type] += amount; }
					else { t.DonationLog[name][type] = amount; }
					t.saveLog();
					if (GlobalOptions.ExtendedDebugMode) logit('Found Alliance HQ donation message from '+name+' - '+type+' x'+amount);
				}
			},
		},true);
	},

	deletemsgs : function (msgid) {
		var t = Tabs.Alliance;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType="ACTION_ON_MESSAGES";
		params.selectedAction="delete";
		params.selectedMessageIds=msgid;
		params.boxType="hq_messages";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {},
		},true);
	},

	sendDonateReport : function () {
		var t = Tabs.Alliance;
		if (!Options.AllianceOptions.DonateReport) { return; }

		var now = unixTime();

		if (now < (parseInt(Options.AllianceOptions.LastDonateReport)+(Options.AllianceOptions.DonateReportInterval*60*60)))
			return;

		var message = tx('Alliance HQ Donation Report for')+' '+Options.AllianceOptions.DonateReportInterval+' '+tx('hours (or since last report)')+' %0A';
		var total = 0;

		if (Options.AllianceOptions.DeleteHQMessages) {
			message +='%0A';
			for (var z in t.DonationLog) {
				message += z+': %0A';
				for (var zz in t.DonationLog[z]) {
					message += zz+' x '+t.DonationLog[z][zz]+'%0A';
					total += t.DonationLog[z][zz];
				}
				message +='%0A';
			}
			message += tx('Total number of donations')+': '+total+'%0A';
		}
		else {
			message += tx('Donated item details only available if the option "Delete HQ donation messages" is ticked')+'%0A';
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.emailTo = Seed.player['name'];
		params.subject = tx("Alliance HQ Donation Summary");

		if (uW.koc2Mail && Options.AllianceOptions.DonateReportEmail) {
			koc2Mail.customMail(params.emailTo,params.subject,message);
		}

		params.message = message;
		params.requestType = "COMPOSED_MAIL";

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					DeleteLastMessage();
					if (Options.AllianceOptions.DeleteHQMessages) {
						t.DonationLog = {};
						t.saveLog();
					}
				}
			},
		});

		Options.AllianceOptions.LastDonateReport = now;
		saveOptions();
	},

	CheckMineAmber : function () {
		var t = Tabs.Alliance;
		var now = unixTime();
		var cooldown = 0;
		if (typeof Seed.allianceHQ.mineCooldown !== "undefined") { cooldown = +Seed.allianceHQ.mineCooldown; }
		if (typeof Seed.allianceHQ.allianceMineCooldown !== "undefined" && Seed.allianceHQ.allianceMineCooldown > cooldown) {
			cooldown = +Seed.allianceHQ.allianceMineCooldown;
		}
		if (cooldown < now) {
			jQuery('#btAmberButton').addClass("disabled");
			t.serverwait = true;
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.context = "allianceHQMineCollectAmber.php";
			new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHQMineCollectAmber.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					if (rslt.ok) {
						var tempstats = CM.AllianceHQModel.getStats();
						tempstats.amber += rslt.amber;
						CM.AllianceHQModel.setStats(tempstats);
						var data = { interval : 8 * 60 * 60, startTime : 0, endTime : 0, nextCollectTime : uW.unixtime() };
						if (typeof rslt.nextCollectTime !=="undefined") {
							Seed.allianceHQ.mineCooldown = rslt.nextCollectTime;
							data.nextCollectTime = rslt.nextCollectTime;
						}
						if (typeof rslt.data !== "undefined") {	data = rslt.data; }
						CM.automine.update(data);
						actionLog(uW.g_js_strings.alliance.amberExtracted.replace("%1$s", rslt.amber) + " " + rslt.message,'ALLIANCE');
					}
					else {
						if (!rslt.feedback) { rslt.feedback = 'Error mining amber'; }
						actionLog(rslt.feedback,'ALLIANCE');
						Options.AllianceOptions.MineLastChecked = uW.unixtime()+(45*60); // don't try auto again for another hour
					}
					t.serverwait = false;
				},
				onFailure: function () {
					actionLog('Error mining amber (AJAX Error)','ALLIANCE');
					t.serverwait = false;
				},
			});
		}
		Options.AllianceOptions.MineLastChecked = now;
		saveOptions();
	},

	CheckDonateResources : function () {
		var t = Tabs.Alliance;
		var now = unixTime();
		var params = uW.Object.clone(uW.g_ajaxparams);
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHqVaultOpen.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var free = parseIntNan(rslt.dailyDonations.caps.resource)-parseIntNan(rslt.dailyDonations.quantity.resource);
					var alliancefree = parseIntNan(rslt.dailyDonations.caps.alliance) - parseIntNan(rslt.dailyDonations.quantity.alliance);
					if (alliancefree<free) free=alliancefree;
					// check each resource
					for (var k in t.DonateResourceItems) {
						if (free>0 || k>=40050) { // don't limit amber or arcane tablets
							var remain = (Options.AllianceOptions.AutoDonate[k].Amount-Options.AllianceOptions.AutoDonate[k].Donated)*t.DonateResourceItems[k];
							var avail = parseIntNan(uW.ksoItems[k].count)*t.DonateResourceItems[k];
							if (Options.AllianceOptions.AutoDonate[k].Active && remain>0 && avail>0) { // can donate this resource this loop!
								var donateamount = remain;
								if (avail<donateamount) donateamount = avail;
								if (free<donateamount && k<40050) donateamount = free;
								donateamount = Math.floor(donateamount/t.DonateResourceItems[k]);
								t.Donate(k,donateamount, function(k,donateamount) {
									Options.AllianceOptions.AutoDonate[k].Donated += donateamount;
									Options.AllianceOptions.ResLastChecked = 0; // check the next resource immediately!
									saveOptions();
								});
								break;
							}
						}
					}
				}
			},
			onFailure: function () {},
  		});
		Options.AllianceOptions.ResLastChecked = now;
		saveOptions();
	},

	CheckUnBundleArcaneTablets : function () {
		var t = Tabs.Alliance;
		for (var i=0;i<t.ArcaneBundles.length;i++) {	
			var item = uW.ksoItems[t.ArcaneBundles[i]];
			if (item) {
				var useamount = parseIntNan(item.count);
				if (useamount>0) { // automatically use items to unbundle...
					actionLog('Attempting to unbundle '+useamount+' '+item.name,'ALLIANCE');
					ItemMultiUseController.UseItems(t.ArcaneBundles[i],useamount);
				}
			}
		}
	},
	
	CheckNewDay : function () {
		var t = Tabs.Alliance;
		var date = new Date();
		var utc = date.getTime() + (date.getTimezoneOffset() * 60000);
		var offset = -8 + (getDST(date)/3600);
		var today = new Date(utc + (3600000 * offset));
		var dd = today.getDate();
		var mm = today.getMonth()+1; //January is 0!
		var yyyy = today.getFullYear();
		if(dd<10) {dd='0'+dd}
		if(mm<10) {mm='0'+mm}
		today = dd+'/'+mm+'/'+yyyy;
		if (today != Options.AllianceOptions.HQDate) {
			Options.AllianceOptions.HQDate = today;
			for (var k in t.DonateResourceItems) {
				if (Options.AllianceOptions.AutoDonate[k]) {
					Options.AllianceOptions.AutoDonate[k].Donated = 0;
				}
			}
			saveOptions();
		}
	},

	Donate: function (item,amount,notify) {
		var t = Tabs.Alliance;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.itemId = item;
		params.quantity = amount;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHQVaultDonate.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					uW.cm.InventoryView.removeItemFromInventory(item, amount);
					if (typeof uW.cm.AHQitems[rslt.itemId] !== "undefined") { uW.cm.AHQitems[rslt.itemId] += amount;}
					else { uW.cm.AHQitems[rslt.itemId] = amount; }
					actionLog(amount+' '+uW.itemlist['i'+item].name+' donated to alliance HQ','ALLIANCE');
					if (notify) notify(item,amount);
				}
				else {
					if (!rslt.feedback) rslt.feedback = 'Unknown error';
					actionLog('Error donating '+amount+' '+uW.itemlist['i'+item].name+' to alliance HQ - '+rslt.feedback,'ALLIANCE');
				}
			},
			onFailure: function (rslt) {
				actionLog('Error donating '+amount+' '+uW.itemlist['i'+item].name+' to alliance HQ - AJAX Error','ALLIANCE');
			},
        });
	},

};

/*********************************** Whisper Tab ***********************************/

Tabs.Whisper = {
	tabOrder: 1090,
	tabLabel : 'Whisper',
	myDiv : null,
	LoggedWhispers : [],
	catchwhispers : null,
	catchwhispers2 : null,
	MaxLogEntries : 500,
	NameFilter : '',

	Options : {
		LogWhenAFK : false,
		LogOutgoing : false,
		UnRead : false,
	},

	init : function (div) {
		var t = Tabs.Whisper;
		t.myDiv = div;

		uWExportFunction('whisperlog', t.whisperlog);
		uWExportFunction('btFormatWhisper', t.FormatWhisper);
		uWExportFunction ('whDeleteLog', Tabs.Whisper.DeleteLog);
		uWExportFunction ('whPostLog', Tabs.Whisper.PostLog);
		uWExportFunction ('whToggleKeep', Tabs.Whisper.ToggleKeep);
		uWExportFunction ('whFilterLog', Tabs.Whisper.FilterLog);
		uWExportFunction ('whClearNameFilter', Tabs.Whisper.ClearNameFilter);

		if (!Options.WhisperOptions) {
			Options.WhisperOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.WhisperOptions.hasOwnProperty(y)) {
					Options.WhisperOptions[y] = t.Options[y];
				}
			}
		}

		t.readWhisper();
		t.catchwhispers = new CalterUwFunc ('Chat.getChat', [[/linkComment\)\;if/,'linkComment\)\;if(i==3)whisperlog(chatwrap.innerHTML);if']]);
   		t.catchwhispers.setEnable(true);

		t.catchwhispers2 = new CalterUwFunc ('Chat.sendChat', [[/if\s*\(rslt.data.recipientId\)\s*\{/,'if (rslt.data.recipientId) { btFormatWhisper(rslt,params); ']]);
		t.EnableOutgoing();
		
		t.SetButton();
	},

	saveWhisper : function (){
		var t = Tabs.Whisper;
		var serverID = getServerId();
		setTimeout(function () { GM_setValue ('Whisper_'+serverID+'_'+uW.tvuid, JSON2.stringify(t.LoggedWhispers)); },0); // get around GM_SetValue uW error
	},

	readWhisper : function (){
		var t = Tabs.Whisper;
		var serverID = getServerId();
 		s = JSON2.parse(GM_getValue ('Whisper_'+serverID+'_'+uW.tvuid, '[]'));
		if (matTypeof(s) == 'array') { t.LoggedWhispers = s; }
	},

	ClearLog : function() {
		var t = Tabs.Whisper;
		t.LoggedWhispers = [];
		t.saveWhisper ();
		t.PaintLog();
	},

	EnableOutgoing : function () {
		var t = Tabs.Whisper;
   		t.catchwhispers2.setEnable(Options.WhisperOptions.LogOutgoing);
	},
	
	FormatWhisper : function(rslt,params) {
		var t = Tabs.Whisper;
		
		if (rslt.data.recipientId==uW.tvuid) {
			var date = new Date(uW.unixtime() * 1000);		
			var mins = date.getMinutes();
			if (mins < 10) {
				mins = "0" + mins
			}
			var courtflag = 0;
			for (var i = 0; i < Seed.courtItems.length; i++) {
				if (CM.Court.isFlagItem(parseInt(Seed.courtItems[i]))) {
					courtflag = Seed.courtItems[i]
				}
			}
			var chatGlory = rslt.data.iconId;
			var chatwrap = document.createElement("div");
			var avatar = uW.stimgUrl + "img/avatars/v2/25/" + ((Seed.player.prefix == "Lord") ? "m" : "f") + Seed.player.avatarId + ".png";
			chatwrap.className = "chatwrap clearfix direct";
			var nm = "<a  class='nm' onclick='Chat.viewProfile(this," + rslt.data.recipientId + "); return false;'>" + params.nm + "</a>";
			var tempcomment = '('+PlayerLink(rslt.data.recipientId,params.nm)+') '+params.comment;
			var chatloc = "<b style='color:#A56631;font-size:9px;'> " + uW.g_js_strings.sendChat.whispersto + " " + nm + ":</b> ";
			chatwrap.innerHTML = uW.Chat.chatDivContent(chatGlory, Seed.player.prefix + " " + Seed.player.name, date.getHours() + ":" + mins, avatar, tempcomment, "", courtflag, chatloc);
			t.whisperlog(chatwrap.innerHTML,true);
		}	
	},
	
	whisperlog : function(innerHTML,Outgoing) {
		var t = Tabs.Whisper;
		var ts = unixTime();
		var okeep = false;

		if(afkdetector.isAFK || !Options.WhisperOptions.LogWhenAFK || Outgoing) {
			var n = t.LoggedWhispers.length;
			while (n--) {
				if (JSON2.stringify(innerHTML) == JSON2.stringify(t.LoggedWhispers[n].innerHTML)) {
					return; // no duplicate adding
				}
			}
				while (t.LoggedWhispers.length >= t.MaxLogEntries) {
				//make space in the log.. find the earliest entry where keep = false
				var spliced = false;
				for (var l in t.LoggedWhispers) {
					if (!t.LoggedWhispers[l].keep) {
						t.LoggedWhispers.splice(l,1);
						spliced = true;
						break;
					}
				}
				//no space, because keep is set on all entries. Log it!
				if (!spliced) {
					logit('No space in Whisper Log!');
					return;
				}
			}

			var a = innerHTML;
			var m = /div class=\"info\">.*<\/div>/im.exec(a);
			var suid = /viewProfile\(this,([0-9]+),false\)/i.exec(m[0]);
			if (!suid) suid = uW.tvuid;
			else suid = suid[1];

			var sname = /ptChatIconClicked\(\'(.*)\'\)/im.exec(a);
			if (!sname) sname = /Chat\.whisper\(\&quot\;(.*)\&quot\;\)\;/im.exec(a);
			if (!sname)	sname = "";
			else sname = sname[1].replace(/\\/g, '');
			if (sname.indexOf(")")>1) sname = sname.substr(0,sname.indexOf(")"));

			var stext = /div class=\"tx\">(.*)\<\/div\>/im.exec(a);
			if (!stext)	stext = "";
			else stext = '<span>'+stext[1].split("</div>")[0]+'</span>';

			t.LoggedWhispers.push({ts:ts, uid:suid, name:sname, msg:stext, innerHTML:a, keep:okeep});
			t.saveWhisper ();

			if(afkdetector.isAFK) {
				Options.WhisperOptions.UnRead = true;
				saveOptions();
				t.SetButton();
			}
			if (tabManager.currentTab.name == 'Whisper' && Options.btWinIsOpen) {
				t.PaintLog();
			}
		};
	},

	SetButton : function () {
		var t = Tabs.Whisper;
		var elem = ById("bttcWhisper");

		if (Options.WhisperOptions.UnRead) {
			elem.setAttribute("style","color:#f00");
		}
		else {
			elem.setAttribute("style","color:#fff");
		}
	},

	PaintLog : function () {
		var t = Tabs.Whisper;

		Options.WhisperOptions.UnRead = false;
		saveOptions();
		t.SetButton();

		var z = '';
		var r = 0;
		var logshow = false;
		var logfiltered = false;

		var bclass = "blue14";
		var btext  = tx("Clear Log");

		var z = '<div align="center"><TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtab">'+tx('Filter by Name/Uid')+': <INPUT class="btInput" id="whNameFilter" size=16 style="width: 115px" type=text value="'+t.NameFilter+'" onkeyup="btStartKeyTimer(this,whFilterLog)" onchange="whFilterLog()" />&nbsp;<a class="inlineButton btButton brown8" onclick="whClearNameFilter()"><span>Clear</span></a></td><td class="xtab">&nbsp;</td></td><td class="xtab" align=right>('+t.LoggedWhispers.length+'/'+t.MaxLogEntries+')</td></tr></table>';
		z += '<TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtabHD" style="width:100px"><b>'+uW.g_js_strings.commonstr.date+'/'+uW.g_js_strings.commonstr.time+'</b></td><td style="width:115px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.nametx+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.message+'</b></td><td class="xtabHD" align="center" style="width:30px"><b>'+tx('Keep')+'</b></td><td class="xtabHD" align="right" style="width: 110px"><a id=whClearLog class="inlineButton btButton '+bclass+'"><span>'+btext+'</span></a></td></tr></table>';
		z += '<div style="max-height:535px; overflow-y:scroll" align="center"><TABLE id=whLogTable cellSpacing=0 width=98% height=0%>';

		var n = t.LoggedWhispers.length;
		while (n--) {
			var a = t.LoggedWhispers[n];

			logfiltered = true;
			if ((t.NameFilter != "") && (a.name.toUpperCase().search(t.NameFilter.toUpperCase()) < 0) && (a.uid.search(t.NameFilter) < 0)) continue;

			logshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:100px" class=xtab>'+formatDateTime(a.ts)+'</td>';
			z += '<TD style="width:115px" class=xtab>'+PlayerLink(a.uid,a.name)+'</td>';
			z += '<TD class=xtabBRTop><div>'+a.msg+'</div></td>';
			z += '<TD style="width:30px" class=xtab align=center><INPUT id="whKeep'+n+'" type=checkbox '+(a.keep?'CHECKED':'')+' onclick="whToggleKeep('+n+')" /></td>';
			z += '<TD class=xtab align=right style="width: 100px"><a id="whPostLog'+n+'" class="inlineButton btButton brown8" onclick="whPostLog('+ n +')"><span>'+tx('Post')+'</span></a>&nbsp;<a id="whDeleteLog'+n+'" class="inlineButton btButton brown8" onclick="whDeleteLog('+n+')"><span>'+tx('Del')+'</span></a></td>';
			z += '</tr>';
		}

		if (!logshow) {
			if (!logfiltered)
				z += '<tr><td colspan=2 class=xtab><div align="center"><br><br>'+tx('No logged whispers')+'</div></td></tr>';
			else
				z += '<tr><td colspan=2 class=xtab><div align="center"><br><br>'+tx('No logged whispers matching search parameters')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		ById('ptWhisperLog').innerHTML = z;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('whClearLog').addEventListener ('click', function() {t.ClearLog();}, false);
	},

	ToggleKeep : function (entry) {
		var t = Tabs.Whisper;
		t.LoggedWhispers[entry].keep = !t.LoggedWhispers[entry].keep;
		t.saveWhisper ();
	},

	PostLog : function (entry) {
		var t = Tabs.Whisper;

		var mod_comm_list2 = ById('mod_comm_list2');
		var mod_comm_list1 = ById('mod_comm_list1')

		var chatwrap1 = document.createElement("div");
		chatwrap1.className = "chatwrap clearfix direct";
		chatwrap1.innerHTML = t.LoggedWhispers[entry].innerHTML;
		var chatwrap2 = document.createElement("div");
		chatwrap2.className = "chatwrap clearfix direct";
		chatwrap2.innerHTML = t.LoggedWhispers[entry].innerHTML;

		mod_comm_list2.insertBefore(chatwrap2,mod_comm_list2.firstChild);
		mod_comm_list1.insertBefore(chatwrap1,mod_comm_list1.firstChild);
	},

	DeleteLog : function (entry) {
		var t = Tabs.Whisper;
		t.LoggedWhispers.splice(entry,1);
		t.saveWhisper ();
		t.PaintLog();
	},

	FilterLog : function () {
		var t = Tabs.Whisper;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		t.NameFilter = ById('whNameFilter').value;
		t.PaintLog();
	},

	ClearNameFilter : function () {
		var t = Tabs.Whisper;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		ById('whNameFilter').value = "";
		t.FilterLog();
	},

	show : function (){
		var t = Tabs.Whisper;
		var m = '<DIV class=divHeader align=center>'+tx('RECEIVED WHISPER LOG')+'</div>';
		m += '<table class=xtab><TR><TD><INPUT id=whLogAFK type=checkbox ' + (Options.WhisperOptions.LogWhenAFK ? 'CHECKED ' : '') + '/></td><TD class=xtab>'+tx('Only log when AFK')+'</td><TD><INPUT id=whLogOutgoing type=checkbox ' + (Options.WhisperOptions.LogOutgoing ? 'CHECKED ' : '') + '/></td><TD class=xtab>'+tx('Log outgoing whispers')+'</td></tr></table>';
		m += '<div id=ptWhisperLog>&nbsp;</div><br>';
		t.myDiv.innerHTML = m;

		ToggleOption('WhisperOptions','whLogAFK','LogWhenAFK');
		ToggleOption('WhisperOptions','whLogOutgoing','LogOutgoing', t.EnableOutgoing);
		t.PaintLog();
	},

}

/*********************************** Tournament Tab ***********************************/

Tabs.Tournament = {
	tabOrder: 1100,
	tabLabel: 'Tournament',
	myDiv: null,
	displayTimer: null,
	Options : {
		TourneyTroopType : 2,
		TourneyBoardType : 1,
		TournamentLines  : 5,
	},

	init: function (div) {
		var t = Tabs.Tournament;
		t.myDiv = div;

		if (!Options.TournamentOptions) {
			Options.TournamentOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.TournamentOptions.hasOwnProperty(y)) {
					Options.TournamentOptions[y] = t.Options[y];
				}
			}
		}

		t.tourneyPos = 0;
		uWExportFunction('ptSetTourneyPos', Tabs.Tournament.SetTourneyPos);

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.format = 2;
		params.tournyPos = 0;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if(rslt.data || rslt.name) {
					var elem = ById("bttcTournament");
					elem.setAttribute("style","color:#f00");
				}
			},
		},true);
	},

	SetTourneyPos : function (tab) {
		var t = Tabs.Tournament;
		t.tourneyPos = tab;
		t.paintTournament();
	},

	hide: function () {
		var t = Tabs.Tournament;
		clearTimeout(t.displayTimer);
	},

	show: function () {
		var t = Tabs.Tournament;
		clearTimeout(t.displayTimer);
		var m = '<div class=divHeader align=center>'+tx('TOURNAMENT')+'</div><div id=BTHeaderDiv>&nbsp;</div>';
		m += '<DIV class=divHeader align=center>'+tx('POPULATION AND PRODUCTION INFORMATION')+'</div><div id=BTPopDiv>&nbsp;</div>';
		m += '<div id=BTDetailDiv style="max-height:535px; overflow-y:scroll" align="center">&nbsp;</div><br>';
		t.myDiv.innerHTML = m;
		t.paintPopulation();
		t.paintTournament();
		t.displayTimer = setTimeout(t.paintTournament, 240000);
	},
	expand: function (lg) {
		var t = Tabs.Tournament;
		if (ById('BOTourneyPM').value == "Maximize") {
			ById('BOTourneyPM').value = "Minimize";
			Options.TournamentOptions.TournamentLines = lg;
		} else {
			ById('BOTourneyPM').value = "Maximize";
			Options.TournamentOptions.TournamentLines = 5;
		}
		saveOptions();
		t.paintTournament();
	},
	leadertoggle: function () {
		var t = Tabs.Tournament;
		if (ById('BTLeaders').value == tx("Show Domain Leaders")) {
			Options.TournamentOptions.TourneyBoardType = 2;
		} else {
			Options.TournamentOptions.TourneyBoardType = 1;
		}
		saveOptions();
		t.paintTournament();
	},

	paintPopulation: function () {
		var t = Tabs.Tournament;
		var mhtl = "<table width=100% class=xtab><tr><td>&nbsp;</td>";
		for (var i = 0; i < Cities.numCities; i++) {
			mhtl += "<TD align=center valign=bottom width=60px><B>" + Cities.cities[i].name + "</B></TD>";
		}
		mhtl += "</tr><tr><td>";
		mhtl += '<SELECT id="TTroopsPerHr">';
		for (var y in uW.unitnamedesctranslated) {
			if (y.substr(3) == Options.TournamentOptions.TourneyTroopType) { mhtl += '<option selected value="' + y.substr(3) + '">' + uW.unitnamedesctranslated[y][0] + '</option>'; }
			else {	mhtl += '<option value="' + y.substr(3) + '">' + uW.unitnamedesctranslated[y][0] + '</option>'; }
			if (y.substr(3) > 4) break; // only 1 pop per troop makes sense	here
		}
		mhtl += '</select>';
		mhtl += "&nbsp;"+tx('/h')+"</td>";
		var temps = [];
		for (var i = 0; i < Cities.numCities; i++) {
			temps[i] = (3600 / (getTrainTime(Options.TournamentOptions.TourneyTroopType,100000,Cities.cities[i].id)/100000));
			if (temps[i]!= 'Infinity' && !isNaN(temps[i])) { mhtl += "<td align=right><div class=xtabBorder>" + addCommas(parseInt(temps[i])) + "</div></td>"; }
			else {	mhtl += "<td align=right><div class=xtabBorder>n/a</div></td>";	}
		}
		mhtl += '</tr><tr><td><img height=18 src="'+IMGURL+'population_40.png" title=Population> '+tx('Population/h')+'</td>';
		var pop = [];
		for (var i = 0; i < Cities.numCities; i++) {
			cityID = 'city' + Cities.cities[i].id;
			pop[i] = parseIntNan(Seed.citystats[cityID]["pop"][1]) / 2;
			mhtl += "<td align=right><div class=xtabBorder>" + addCommas(parseInt(pop[i])) + "</div></td>";
		}
		mhtl += "</tr><tr><td><b>"+tx('Difference')+"</b></td>";
		var diff = 0;
		for (var i = 0; i < Cities.numCities; i++) {
			diff = parseIntNan(pop[i]) - parseIntNan(temps[i]);
			var bonc = "";
			if (diff < 0) bonc = "whiteOnRed";
			mhtl += "<td align=right><div class='xtabBorder "+bonc+"'><b>"+addCommas(parseInt(diff))+"</b></div></td>";
		}
		mhtl += '</tr><tr><td><img height=18 src="'+IMGURL+'happiness.png title=Happiness> '+tx('happiness')+'</td>';
		for (var i = 0; i < Cities.numCities; i++) {
			cityID = 'city' + Cities.cities[i].id;
			var bon = parseInt(Seed.citystats[cityID]["pop"][2]);
			var bonc = "whiteOnRed";
			if (bon > 99) bonc = "whiteOnGreen";
			mhtl += "<td align=center><div class='xtabBorder "+bonc+"'><b>"+bon+"%</div></td>";
		}
		var now = unixTime();
		mhtl += "</tr><tr><td><b>"+tx('Queue')+"</b></td>";
		for (var i = 0; i < Cities.numCities; i++) {
			cityID = 'city' + Cities.cities[i].id;
			var totTime = 0;
			var q = Seed.queue_unt[cityID];
			if (q != null && q.length > 0)
				totTime = q[q.length - 1][3] - now;
			if (totTime < 0) totTime = 0;
			var bonc = "";
			if (totTime < 3600) bonc = "whiteOnRed";
			mhtl += "<td align=center><div class='xtabBorder "+bonc+"'><b>"+timestr(totTime)+"</div></td>";
		}
		mhtl += "</tr></table><br>";

		ById('BTPopDiv').innerHTML = mhtl;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ChangeOption('TournamentOptions','TTroopsPerHr','TourneyTroopType',t.paintPopulation);
	},

	paintTournament : function () {
		var t = Tabs.Tournament;

		ById('BTDetailDiv').innerHTML = "<div align=center>"+tx('Loading')+"...</div>";

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.format = 2;
		params.tournyPos = t.tourneyPos;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var prevs = [];
					for (var s = 0; s < 4; s++) {
						w = rslt["previous" + s];
						if (w && w > -1) {
							prevs.push(uW.formatDateByUnixTime(w));
						}
					}
					if (!rslt.data) {
						var m = "<div><br><center><b>"+tx('No Active Tournaments')+"!</b></center></div>";
						for (var s = 0; s < prevs.length; s++) {
							m += "<div><br><center><b><a onclick='ptSetTourneyPos(" + s + 1 + ")'>"+tx('Show Tournament that ended on')+" " + prevs[s] + "</a></b></center></div>";
						}
						m += '<br>';
						ById('BTHeaderDiv').innerHTML = m;
						ById('BTDetailDiv').innerHTML = tx("No Results");
						ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
					} else { //  rslt.data
						var m = "";
						if (t.tourneyPos != 0) {
							m += "<div><br><center><b><a onclick='ptSetTourneyPos(0)'>"+tx('Show Current Tournament (if any)')+"</a></b></center></div>";
						}
						for (var s = 0; s < prevs.length; s++) {
							if (t.tourneyPos != (s + 1)) {
								m += "<div><br><center><b><a onclick='ptSetTourneyPos(" + s + 1 + ")'>"+tx('Show Tournament that ended on')+" " + prevs[s] + "</a></b></center></div>";
							}
						}
						m += '<br>';
						ById('BTHeaderDiv').innerHTML = m;
						ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

						var n = '';
						if (rslt.name) {
							n += "<div class=divHeader align=center>" + rslt.name.toUpperCase() + "</div>";
						} else {
							n += "<div class=divHeader align=center>" + uW.g_js_strings.commonstr.tournament.toUpperCase() + "</div>";
						}
						n += "<div>";
						if (rslt.startDate && rslt.endDate) {
							var startTime = rslt.startDate;
							var endTime = rslt.endDate;
							var now = parseInt(new Date().getTime() / 1000);
							n += "<table width=98% align=center class=xtab><tr><td width=40%><b>"+tx('Starts')+"</td><td width=40%><b>"+tx('Ends')+"</td><td align=right width=20%><b>"+tx('Time Left')+"</td></tr>";
							dt = new Date();
							dt.setTime(startTime * 1000);
							dtf = new Date();
							dtf.setTime(endTime * 1000);
							var remain = endTime - now;
							n += "<tr><td>"+dt.toLocaleDateString()+" - "+dt.toLocaleTimeString()+"</td><td>"+dtf.toLocaleDateString()+" - "+dtf.toLocaleTimeString();
							if (remain > 0) {
								n += "</td><td align=right>" + timestr(remain, 1) + "</td></tr></table>";
							} else {
								n += "</td><td align=right>"+tx('ENDED')+"!</td></tr></table>";
							}
							n +="<br>";
						}
						if (rslt.player) {
							n += '<center>';
							n += '<table class=xtab width="98%" cellpadding="0" cellspacing="0" border="0"><tr><td width="25%"><b>'+rslt.player.name||tx('Your Stats');
							n += '</b></td><td align=center>';
							if (rslt.type == 25) { n += uW.g_js_strings.modal_tourny_changetab.glorygained+':&nbsp;'; }
							else { n += uW.g_js_strings.modal_tourny_changetab.mightgained+':&nbsp;'; }
							n += addCommas(rslt.player.contestValue);
							n += '</td><td width="25%" align=right>';
							n += uW.g_js_strings.commonstr.ranking+':&nbsp;'+(rslt.player.ranking||'N/A')+'&nbsp;('+rslt.bracketName+')';
							n += '</td></tr></table></center><br>';
						}

						if ((Options.TournamentOptions.TourneyBoardType != 2) || !rslt.worldData) {
							tourneystats = rslt.data;
							Options.TournamentOptions.TourneyBoardType = 1;
							saveOptions();
						} else {
							tourneystats = rslt.worldData;
						}
						n += '<center>';
						n += '<table class=xtab width="98%" cellpadding="0" cellspacing="0" border="0"><tr><td width="25%"><input type=button id=BTLeaders value="-"></td><td align=center>';
						if (rslt.lastUpdated && (t.tourneyPos == 0)) {
							var now = parseInt(new Date().getTime() / 1000);
							var updated = now - rslt.lastUpdated;
							n += "<div>"+tx('Last updated')+" " + timestr(updated, 1) + " "+tx('ago')+".</div>";
						}
						n += '</td><td width="25%" align=right><input type=button id=BOTourneyPM value="-">';
						var TitleColour = 'rgba('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+',0.5)';
						n += '</td></tr></table><div style="color:'+TitleColour+';font-size:14px;"><b>';
						if (Options.TournamentOptions.TourneyBoardType != 2) {
							n += rslt.bracketName;
						} else {
							n += tx('Domain Leaders');
						}
						n += '</b></div>';
						n += "<table cellSpacing=0 width=90% height=0%><tr>";
						if (rslt.type == 24) {
							n += "<td class=xtabHD>"+uW.g_js_strings.commonstr.ranking+"</td><td class=xtabHD>"+uW.g_js_strings.commonstr.chancellor+"</td><td class=xtabHD>"+uW.g_js_strings.commonstr.alliance+"</td><td class=xtabHD>"+uW.g_js_strings.modal_tourny_changetab.mightgained+"</td><td class=xtabHD>"+uW.g_js_strings.modal_tourny_changetab.rewardperplayer+"</td>";
						} else {
							n += "<td class=xtabHD>"+uW.g_js_strings.commonstr.ranking+"</td><td class=xtabHD>"+uW.g_js_strings.commonstr.player+"</td><td class=xtabHD>"+uW.g_js_strings.commonstr.alliance+"</td><td class=xtabHD>";
							if (rslt.type == 31) { n += uW.g_js_strings.modal_tourny_changetab.mightgained; }
							else {
								if (rslt.type == 25) { n += uW.g_js_strings.modal_tourny_changetab.glorygained; }
								else { n += rslt.contestcategory; }
							}
							n += "</td><td class=xtabHD>"+uW.g_js_strings.commonstr.reward+"</td>";
						}
						n += "</tr>";
						var nb = tourneystats.length;
						var YourScore = 0;
						for (var i = 0; i < tourneystats.length; i++) {
							var row = tourneystats[i];
							if (rslt.type == 24) { // Tournament
								if (getMyAlliance()[1] == row.alliance) {
									YourScore = row.contestValue;
									break;
								}
							} else {
								if (Seed.player.prefix + ' ' + Seed.player.name == row.name) {
									YourScore = row.contestValue;
									break;
								}
							}
						}
						for (var i = 0; i < Options.TournamentOptions.TournamentLines; i++) {
							if (tourneystats[i] == null) break;
							var row = tourneystats[i];
							var rewardString = " ";
							if (row.itemType) {
								rewardString = row.itemCount + " ";
								if (row.itemType == 0) {
									rewardString += uW.g_js_strings.commonstr.gems;
								} else {
									rewardString += uW.itemlist["i" + row.itemType].name;
								}
							}
							var rowcol = "";
							if (rslt.type == 24) { //Alliance Tournament
								if (getMyAlliance()[1] == row.alliance) { rowcol = "whiteOnGreen"; }
							} else {
								if (Seed.player.prefix + ' ' + Seed.player.name == row.name) { rowcol = "whiteOnGreen"; }
							}
							if (i % 2 == 1) { n += "<tr class=oddRow>"; }
							else { n += "<tr class=evenRow>"; }
							n += "<td class='xtab "+rowcol+"'><b>"+row.ranking+"</b></td><td class='xtab "+rowcol+"'>"+row.name+"</td><td class='xtab "+rowcol+"'>"+(row.alliance || "---")+"</td><td class='xtab "+rowcol+"'>"+addCommas(row.contestValue);
							if (YourScore > 0) {
								var ScoreDiff = parseInt(row.contestValue - YourScore);
								if (ScoreDiff > 0) { n += " (+" + addCommas(ScoreDiff) + ")"; }
								if (ScoreDiff < 0) { n += " (" + addCommas(ScoreDiff) + ")"; }
							}
							n += "</td><td class='xtab "+rowcol + "'>"+rewardString+"</td></tr>";
						}
						if (rslt.type != 24) {
							for (var i = Options.TournamentOptions.TournamentLines; i < tourneystats.length; i++) {
								if (tourneystats[i] == null) break;
								var row = tourneystats[i];
								var rowcol = "whiteOnGreen";
								if (Seed.player.prefix + ' ' + Seed.player.name == row.name) {
									var rewardString = " ";
									if (row.itemType) {
										rewardString = row.itemCount + " ";
										if (row.itemType == 0) {
											rewardString += uW.g_js_strings.commonstr.gems;
										} else {
											rewardString += uW.itemlist["i" + row.itemType].name;
										}
									}
									n += "<tr><td class='xtab "+rowcol+"'><b>"+row.ranking+"</b></td><td class='xtab "+rowcol+"'>"+row.name+"</td><td class='xtab "+rowcol+"'>"+(row.alliance || "---")+"</td><td class='xtab "+rowcol+"'>"+addCommas(row.contestValue)+"</td><td class='xtab "+rowcol+"'>"+rewardString+"</td></tr>";
								}
							}
						}
						n += "</table></div>";
						ById('BTDetailDiv').innerHTML = n;
						ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

						ById('BOTourneyPM').addEventListener('click', function () {
							var lg = tourneystats.length;
							if (rslt.type != 24) lg = 250;
							t.expand(lg);
						}, false);
						if (Options.TournamentOptions.TournamentLines == 5) {
							ById('BOTourneyPM').value = tx("Maximize");
						} else {
							ById('BOTourneyPM').value = tx("Minimize");
						}
						if (Options.TournamentOptions.TourneyBoardType != 2) {
							ById('BTLeaders').value = tx("Show Domain Leaders");
						} else {
							ById('BTLeaders').value = tx("Show Your Bracket")+" (" + rslt.bracketName + ")";
						}
						ById('BTLeaders').addEventListener('click', function () {
							t.leadertoggle();
						}, false);
					}
				} else {
					ById('BTDetailDiv').innerHTML = "<div align=center>"+tx('No Information')+"</div>";
					ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
				}
			},
			onFailure: function () {
				ById('BTDetailDiv').innerHTML = "<div align=center>"+tx('Error Reading Tournament Information')+"</div>";
				ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
			}
		},true);
	},
}

/********************************* Messages Tab *************************************/

Tabs.Messages = {
	tabOrder: 1080,
	tabLabel: 'Rpt Search',
	myDiv: null,
	minPages: 0,
	maxPages: 0,
	data: [],
	report: {},
	DisplayIdArray: [],
	DisplayArray: [],
	totalPages: 0,
	what: '',
	whatNot: '',
	content: '',
	FromUnixTime: 0,
	ToUnixTime: 0,
	ItemsFound			: {},
	ThroneItemsFound	: {},
	ChampItemsFound		: {},
	JewelItemsFound		: {},
	PlayerData			: {},
	Options: {
		rptType: 'alliance',
		arAttacker: 'Both',
		arTarget: 'Both',
		arPageFrom: 1,
		arPageTo: 10,
		arAttack : true,
		arScout : true,
	},

	init: function (div) {
		var t = Tabs.Messages;
		t.myDiv = div;

	    var link = window.document.createElement('link');
		link.rel = 'stylesheet';
		link.type = 'text/css';
		link.href = http+'code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css';
		document.getElementsByTagName("HEAD")[0].appendChild(link);

		// set up regional datepicker text strings

		if (Options.Language != 'en') {
			jQuery.datepicker.regional[Options.Language] = {};
			jQuery.datepicker.regional[Options.Language].closeText = uW.g_js_strings.commonstr.close;
			jQuery.datepicker.regional[Options.Language].prevText = uW.g_js_strings.commonstr.prev;
			jQuery.datepicker.regional[Options.Language].nextText = uW.g_js_strings.commonstr.next;
			jQuery.datepicker.regional[Options.Language].currentText = tx("Today");
			jQuery.datepicker.regional[Options.Language].monthNames = [];
			jQuery.datepicker.regional[Options.Language].monthNamesShort = [];
			jQuery.datepicker.regional[Options.Language].dayNames = [];
			jQuery.datepicker.regional[Options.Language].dayNamesShort = [];
			jQuery.datepicker.regional[Options.Language].dayNamesMin = [];
			jQuery.datepicker.regional[Options.Language].weekHeader = tx("WK");
			jQuery.datepicker.regional[Options.Language].dateFormat = "dd/mm/yy";
			jQuery.datepicker.regional[Options.Language].firstDay = 1;
			jQuery.datepicker.regional[Options.Language].isRTL = false;
			jQuery.datepicker.regional[Options.Language].showMonthAfterYear = false;
			jQuery.datepicker.regional[Options.Language].yearSuffix = "";
			for (var i=0;i<12;i++) jQuery.datepicker.regional[Options.Language].monthNames.push(tx(uW.MONTH_NAMES[i]));
			for (var i=12;i<24;i++) jQuery.datepicker.regional[Options.Language].monthNamesShort.push(tx(uW.MONTH_NAMES[i]));
			for (var i=0;i<7;i++) jQuery.datepicker.regional[Options.Language].dayNames.push(tx(uW.DAY_NAMES[i]));
			for (var i=7;i<14;i++) jQuery.datepicker.regional[Options.Language].dayNamesShort.push(tx(uW.DAY_NAMES[i]));
			for (var i=0;i<7;i++) jQuery.datepicker.regional[Options.Language].dayNamesMin.push(tx(uW.DAY_NAMES[i])[0].toUpperCase()+tx(uW.DAY_NAMES[i])[1]);
		}

		if (!Options.MessagesOptions) {
			Options.MessagesOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.MessagesOptions.hasOwnProperty(y)) {
					Options.MessagesOptions[y] = t.Options[y];
				}
			}
		}

		t.minPages = Options.MessagesOptions.arPageFrom;
		t.maxPages = Options.MessagesOptions.arPageTo;
		t.totalPages = Options.MessagesOptions.arPageTo;

		uWExportFunction('getmsg',Tabs.Messages.getMailBody);
		uWExportFunction('getReport', Tabs.Messages.getReportBody);
		uWExportFunction('ptMsgDelete', Tabs.Messages.DeleteMessage);
		uWExportFunction('ptMsgDeleteAll', Tabs.Messages.DeleteAllMessages);
		uWExportFunction('ptRptPVPSummary',Tabs.Messages.BuildPVPSummary);
		uWExportFunction('ptRptItemSummary',Tabs.Messages.BuildItemSummary);

		var tc = '<DIV class=divHeader align=center>'+tx('REPORT AND MESSAGE SEARCH')+'</DIV><DIV align=center><TABLE width=98%><TR align=center valign=center>';
		tc += '<TD class=xtab align=right>'+uW.g_js_strings.commonstr.type+':&nbsp;<SELECT class="btInput" id="idRptType">';
		tc += '<OPTION value="alliance" ' + (Options.MessagesOptions.rptType == 'alliance' ? 'SELECTED' : '') + '>'+tx('Alliance Reports')+'</OPTION>';
		tc += '<OPTION value="player" ' + (Options.MessagesOptions.rptType == 'player' ? 'SELECTED' : '') + '>'+tx('Player Reports')+'</OPTION>';
		tc += '<OPTION value="inbox" ' + (Options.MessagesOptions.rptType == 'inbox' ? 'SELECTED' : '') + '>'+uW.g_js_strings.commonstr.inbox+'</OPTION>';
		tc += '<OPTION value="outbox" ' + (Options.MessagesOptions.rptType == 'outbox' ? 'SELECTED' : '') + '>'+uW.g_js_strings.commonstr.outbox+'</OPTION>';
		tc += '<OPTION value="hq_messages" ' + (Options.MessagesOptions.rptType == 'hq_messages' ? 'SELECTED' : '') + '>'+uW.g_js_strings.modal_messages.hqmessages+'</OPTION>';
		tc += '</SELECT>';
		tc += '<BR />'+tx('Page')+':&nbsp;<INPUT class="btInput" id="idRptPageFrom" size=1 value="' + Options.MessagesOptions.arPageFrom + '">&nbsp;&#8211;&nbsp;<INPUT class="btInput" id="idRptPageTo" size=1 value="' + Options.MessagesOptions.arPageTo + '"></TD>';
		tc += '<TD class=xtab align=right>'+tx('Contains')+':&nbsp;<INPUT class="btInput" id=idRptWhat type=text size=25 maxlength=50 value=""><BR />';
		tc += tx('But not')+':&nbsp;<INPUT class="btInput" id=idRptWhatNot type=text size=25 maxlength=50 value=""></TD>';
		tc += '<TD class=xtab align=right>'+uW.g_js_strings.commonstr.attacker+':&nbsp;<SELECT class="btInput" id="idRptAttacker">'; // Options.arPageFrom - Options.arPageTo
		tc += '<OPTION value="Them" ' + (Options.MessagesOptions.arAttacker == 'Them' ? 'SELECTED' : '') + '>'+tx('Them')+'</OPTION>';
		tc += '<OPTION value="Us" ' + (Options.MessagesOptions.arAttacker == 'Us' ? 'SELECTED' : '') + '>'+tx('Us')+'</OPTION>';
		tc += '<OPTION value="Both" ' + (Options.MessagesOptions.arAttacker == 'Both' ? 'SELECTED' : '') + '>'+tx('Both')+'</OPTION></SELECT>';
		tc += '<BR />'+uW.g_js_strings.commonstr.target+':&nbsp;<SELECT class="btInput" id="idRptTarget">';
		tc += '<OPTION value="Them" ' + (Options.MessagesOptions.arTarget == 'Them' ? 'SELECTED' : '') + '>'+tx('Them')+'</OPTION>';
		tc += '<OPTION value="Us" ' + (Options.MessagesOptions.arTarget == 'Us' ? 'SELECTED' : '') + '>'+tx('Us')+'</OPTION>';
		tc += '<OPTION value="Both" ' + (Options.MessagesOptions.arTarget == 'Both' ? 'SELECTED' : '') + '>'+tx('Both')+'</OPTION></SELECT></TD>';
		tc += '<TD class=xtab align=left><INPUT id=idRptAttack type=checkbox ' + (Options.MessagesOptions.arAttack ? 'CHECKED' : '') + ' />&nbsp;'+uW.g_js_strings.commonstr.attack+'<BR />';
		tc += '<INPUT id=idRptScout type=checkbox ' + (Options.MessagesOptions.arScout ? 'CHECKED' : '') + ' />&nbsp;'+uW.g_js_strings.commonstr.scout+'</TD>';
		tc += '<TD class=xtab align=left><INPUT id=idRptReinforce type=checkbox ' + (Options.MessagesOptions.arReinforce ? 'CHECKED' : '') + ' />&nbsp;'+uW.g_js_strings.commonstr.reinforce+'<BR />';
		tc += '<INPUT id=idRptTransport type=checkbox ' + (Options.MessagesOptions.arTransport ? 'CHECKED' : '') + ' />&nbsp;'+uW.g_js_strings.commonstr.transport+'</TD>';
		tc += '<TD class=xtab align=left><INPUT id=idRptSearch type=submit value="'+tx('Start Search')+'" /></TD>';
		tc += '</TR></TABLE></DIV>';
		tc += '<div id=idRptDateFilter class=divHide align=center><hr><TABLE>';
		tc += '<TR align=center valign=center><TD class=xtab align=right>'+uW.g_js_strings.commonstr.from+':&nbsp;<INPUT class="btInput" id=idRptFrom type=text size=25 value=""></TD><TD class=xtab align=left>'+uW.g_js_strings.commonstr.totx+':&nbsp;<INPUT class="btInput" id=idRptTo type=text size=25 value="">&nbsp;'+strButton8(tx('Clear'),'id=idRptClearDates')+'</TD>';
		tc += '</TR></TABLE></div></DIV>';
		tc += '<DIV class=divHeader><TABLE width=100% cellspacing=0><TR><TD class=xtab align=left width=125><DIV id=idRptSearched></DIV></TD>';
		tc += '<TD class=xtab align=center><SPAN style="white-space:normal" id=idRptStatus>&nbsp;</span></TD>';
		tc += '<TD class=xtab align=right width=125><DIV id=idRptFound></DIV></TD></TR></TABLE></DIV>';
		tc += '<DIV id="idRptResultsDiv" style="height:535px; max-height:535px; width:'+GlobalOptions.btWinSize.x+'px; overflow-x:scroll; overflow-y:auto; white-space:nowrap;"></DIV><br>';
		t.myDiv.innerHTML = tc;

		jQuery(function() {
			jQuery.datepicker.setDefaults(jQuery.datepicker.regional[Options.Language]);
			jQuery("#idRptFrom").datepicker({dateFormat: "yy-mm-dd 00:00:00", onSelect:t.handleRptFrom});
			jQuery("#idRptTo").datepicker({dateFormat: "yy-mm-dd 23:59:59", onSelect:t.handleRptTo});
		});

		ById('idRptType').addEventListener('change', t.handleRptType, false);
		ById('idRptPageFrom').addEventListener('change', t.handleRptPages, false);
		ById('idRptPageTo').addEventListener('change', t.handleRptPages, false);
		ById('idRptAttacker').addEventListener('change', t.handleRptAttacker, false);
		ById('idRptTarget').addEventListener('change', t.handleRptTarget, false);
		ById('idRptWhat').addEventListener('keyup', t.handleRptWhat, false);
		ById('idRptWhatNot').addEventListener('keyup', t.handleRptWhatNot, false);
		ById('idRptSearch').addEventListener('click', t.handleRptSearch, false);
		ById('idRptFrom').addEventListener('change', t.handleRptFrom, false);
		ById('idRptTo').addEventListener('change', t.handleRptTo, false);
		ById('idRptClearDates').addEventListener('click', t.clearRptDates, false);
		t.togOpt('idRptAttack', 'arAttack');
		t.togOpt('idRptScout', 'arScout');
		t.togOpt('idRptReinforce', 'arReinforce');
		t.togOpt('idRptTransport', 'arTransport');
		t.enableFields();
	},
	togOpt: function (checkboxId, optionName) {
		var t = Tabs.Messages;
		var checkbox = ById(checkboxId);
		checkbox.addEventListener('change', eventHandler, false);

		function eventHandler() {
			Options.MessagesOptions[optionName] = this.checked;
			saveOptions();
			t.RefreshCurrentDisplay();
		}
	},

	handleRptType: function () {
		var t = Tabs.Messages;
		Options.MessagesOptions.rptType = ById("idRptType").value;
		saveOptions();
		// clear data
		t.data = [];
		t.report = {};
		ById("idRptSearched").innerHTML = '';
		ById("idRptStatus").innerHTML = '&nbsp;';
		ById("idRptFound").innerHTML = '';
		ById("idRptResultsDiv").innerHTML = '';
		t.enableFields();
	},

	enableFields : function () {
		var t = Tabs.Messages;
		var disable = (Options.MessagesOptions.rptType=='inbox' || Options.MessagesOptions.rptType=='outbox' || Options.MessagesOptions.rptType=='hq_messages');
		ById('idRptAttacker').disabled = disable;
		ById('idRptTarget').disabled = disable;
		ById('idRptAttack').disabled = disable;
		ById('idRptScout').disabled = disable;
		ById('idRptReinforce').disabled = disable;
		ById('idRptTransport').disabled = disable;
		if (disable) {
			jQuery('#idRptDateFilter').addClass("divHide");
		}
		else {
			jQuery('#idRptDateFilter').removeClass("divHide");
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	handleRptPages: function () {
		var t = Tabs.Messages;
		t.minPages = parseInt(ById("idRptPageFrom").value);
		t.maxPages = parseInt(ById("idRptPageTo").value);
		if (t.maxPages < t.minPages) {
			t.maxPages = t.minPages;
			ById("idRptPageTo").value = t.maxPages;
		}
		Options.MessagesOptions.arPageFrom = t.minPages;
		Options.MessagesOptions.arPageTo = t.maxPages;
		saveOptions();
		t.totalPages = t.maxPages;
	},

	handleRptAttacker: function () {
		var t = Tabs.Messages;
		Options.MessagesOptions.arAttacker = ById("idRptAttacker").value;
		saveOptions();
		if ((Options.MessagesOptions.rptType == 'alliance' || Options.MessagesOptions.rptType == 'player') && t.data.length > 0)
			t.DisplayRpt();
	},

	handleRptTarget: function () {
		var t = Tabs.Messages;
		Options.MessagesOptions.arTarget = ById("idRptTarget").value;
		saveOptions();
		if ((Options.MessagesOptions.rptType == 'alliance' || Options.MessagesOptions.rptType == 'player') && t.data.length > 0)
			t.DisplayRpt();
	},

	handleRptWhat: function () {
		var t = Tabs.Messages;
		t.what = ById("idRptWhat").value;
		t.RefreshCurrentDisplay();
	},

	handleRptWhatNot: function () {
		var t = Tabs.Messages;
		t.whatNot = ById("idRptWhatNot").value;
		t.RefreshCurrentDisplay();
	},

	handleRptFrom: function () {
		var t = Tabs.Messages;
		try {
			var datestr = new Date(ById("idRptFrom").value.replace(" ","T")+"Z");
			t.FromUnixTime = parseIntNan(datestr.getTime()/1000) + (datestr.getTimezoneOffset() * 60);
			ById("idRptFrom").style.color = 'black';
			if (t.FromUnixTime==0 && ById("idRptFrom").value != "") { ById("idRptFrom").style.color = 'red'; }
		}
		catch (err) {
			t.FromUnixTime = 0;
			ById("idRptFrom").style.color = 'red';
		}
		t.RefreshCurrentDisplay();
	},

	handleRptTo: function () {
		var t = Tabs.Messages;
		try {
			var datestr = new Date(ById("idRptTo").value.replace(" ","T")+"Z");
			t.ToUnixTime = parseIntNan(datestr.getTime()/1000) + (datestr.getTimezoneOffset() * 60);
			ById("idRptTo").style.color = 'black';
			if (t.ToUnixTime==0 && ById("idRptTo").value != "") { ById("idRptTo").style.color = 'red'; }
		}
		catch (err) {
			t.ToUnixTime = 0;
			ById("idRptTo").style.color = 'red';
		}
		t.RefreshCurrentDisplay();
	},

	clearRptDates: function () {
		var t = Tabs.Messages;
		ById("idRptFrom").value = '';
		ById("idRptTo").value = '';
		t.FromUnixTime = 0;
		t.ToUnixTime = 0;
		t.RefreshCurrentDisplay();
	},

	RefreshCurrentDisplay : function () {
		var t = Tabs.Messages;
		if (t.data.length > 0)
			if (Options.MessagesOptions.rptType == 'alliance' || Options.MessagesOptions.rptType == 'player')
				t.DisplayRpt();
			else
				t.DisplayMail();
	},

	handleRptSearch: function () {
		var t = Tabs.Messages;
		if (t.searchRunning) {
			t.searchRunning = false;
			t.stopSearch('SEARCH CANCELLED!');
			return;
		}
		t.handleRptPages();
		ById('idRptSearch').value = tx('Stop Search');
		ById('idRptStatus').innerHTML = tx('Searching page')+' ' + t.minPages + ' '+uW.g_js_strings.commonstr.of+' ' + t.maxPages;
		t.searchRunning = true;
		t.data = [];
		t.report = {};
		if (Options.MessagesOptions.rptType == 'alliance' || Options.MessagesOptions.rptType == 'player')
			t.getRpt(t.minPages);
		else
			t.getMail(t.minPages);
	},

	stopSearch: function (msg) {
		var t = Tabs.Messages;
		if (t.searchRunning || msg == 'SEARCH CANCELLED!')
			ById('idRptStatus').innerHTML = msg;
		ById('idRptSearch').value = tx('Start Search');
		t.searchRunning = false;
		t.RefreshCurrentDisplay();
	},

	getMail: function (pageNum) {
		var t = Tabs.Messages;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		params.requestType = "GET_MESSAGE_HEADERS_FOR_USER_INBOX";
		params.boxType = ById('idRptType').value;
		params.pageNo = pageNum;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { t.getMailCallback(rslt, pageNum); },
			onFailure: function () { t.getMailCallback({errorMsg:'AJAX error'}); },
		}, false);
	},

	getMailCallback: function (rslt, page) {
		var t = Tabs.Messages;
		if (rslt) {
			if (!rslt.ok) {
				ById("idRptStatus").innerHTML = rslt.errorMsg;
				return;
			}
			t.totalPages = parseInt(rslt.noOfPages);
			if (t.totalPages < t.maxPages)
				t.maxPages = t.totalPages;
			if (rslt.message && page) {
				var ml = rslt.message;
				if (rslt.messageCount > 0) {
					var rptkeys = uW.Object.keys(ml);
					for (var i = 0; i < rptkeys.length; i++) {
						var rpt = ml[rptkeys[i]];
						rpt.page = page;
						t.data.push(rpt);
					}
				}
			}
			if (parseInt(page) + 1 <= t.maxPages && t.searchRunning) {
				ById("idRptStatus").innerHTML = tx('Searching page')+' ' + (parseInt(page) + 1) + ' '+uW.g_js_strings.commonstr.of+' ' + t.maxPages;
				t.getMail(parseInt(page) + 1);
				if (t.data.length > 0)
					t.DisplayMail();
			} else if (page)
				t.stopSearch('Done!');
		}
	},

	getRpt: function (pageNum) {
		var t = Tabs.Messages;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pageNo = pageNum;
		if (Options.MessagesOptions.rptType == 'alliance')
			params.group = "a";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/listReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { t.getRptCallback(rslt, pageNum); },
			onFailure: function () { t.getRptCallback({errorMsg:'AJAX error'}); },
		}, false);
	},

	getRptCallback: function (rslt, page) {
		var t = Tabs.Messages;
		if (rslt) {
			if (!rslt.ok) {
				ById("idRptStatus").innerHTML = rslt.errorMsg;
				return;
			}
			t.totalPages = parseInt(rslt.totalPages);
			if (t.totalPages < t.maxPages)
				t.maxPages = t.totalPages;
			if (rslt.arReports && page) {
				var ar = rslt.arReports;
				if (ar.length == 0)
					t.stopSearch(tx('Empty pages found from page')+' ' + page + ' '+tx('onwards - Kabam glitch'));
				var rptkeys = uW.Object.keys(ar);
				for (var i = 0; i < rptkeys.length; i++) {
					var rpt = ar[rptkeys[i]];
					var reportId = parseInt(rpt.reportId);
					setTimeout(FetchReport,(250*i),rpt.reportId); // load report into cache
					t.report[reportId] = {};
					// Attacker
					t.report[reportId].side1Name = rslt.arPlayerNames['p' + rpt.side1PlayerId];
					t.report[reportId].side1PlayerId = parseInt(rpt.side1PlayerId);
					t.report[reportId].side1AllianceId = parseInt(rpt.side1AllianceId);
					if (rpt.side1AllianceId > 0)
						t.report[reportId].side1AllianceName = rslt.arAllianceNames['a' + rpt.side1AllianceId];
					else
						t.report[reportId].side1AllianceName = tx('unallied');
					if (rpt.side1CityId > 0)
						t.report[reportId].side1CityName = rslt.arCityNames['c' + rpt.side1CityId];
					else
						t.report[reportId].side1CityName = uW.g_js_strings.commonstr.none;
					t.report[reportId].side1XCoord = rpt.side1XCoord;
					t.report[reportId].side1YCoord = rpt.side1YCoord;
					// Target
					t.report[reportId].side0PlayerId = parseInt(rpt.side0PlayerId);
					if (parseInt(rpt.side0PlayerId) == 0) { // Kabam
						t.report[reportId].side0Name = uW.g_js_strings.commonstr.enemy;
						t.report[reportId].side0AllianceName = '';
						t.report[reportId].side0CityName = '';
					} else { // Player
						t.report[reportId].side0Name = rslt.arPlayerNames['p' + rpt.side0PlayerId];
						if (rpt.side0AllianceId > 0)
							t.report[reportId].side0AllianceName = rslt.arAllianceNames['a' + rpt.side0AllianceId];
						else
							t.report[reportId].side0AllianceName = tx('unallied');
						if (rpt.side0CityId > 0)
							t.report[reportId].side0CityName = rslt.arCityNames['c' + rpt.side0CityId];
						else
							t.report[reportId].side0CityName = uW.g_js_strings.commonstr.none;
					}
					t.report[reportId].side0AllianceId = parseInt(rpt.side0AllianceId);
					t.report[reportId].side0XCoord = rpt.side0XCoord;
					t.report[reportId].side0YCoord = rpt.side0YCoord;

					totile = tileTypes[parseInt(rpt.side0TileType)];
					if (rpt.side0TileType == 51) {
						if (parseInt(rpt.side0CityId) == 0) { totile = tx('Barb Camp'); }
					}
					t.report[reportId].side0TileTypeText = totile;

					totile = 'Lvl '+rpt.side0TileLevel+' '+totile;
					t.report[reportId].side0TileTypeLevel = totile;

					t.report[reportId].side0TileType = rpt.side0TileType;
					t.report[reportId].side0TileLevel = rpt.side0TileLevel;
					// Miscellaneous
					t.report[reportId].page = page;
					t.report[reportId].reportUnixTime = rpt.reportUnixTime;
					if (rpt.side0AllianceId == parseInt(getMyAlliance()[0]))
						t.report[reportId].sideId = 0;
					else if (rpt.side1AllianceId == parseInt(getMyAlliance()[0])) {
						t.report[reportId].sideId = 1;
					} else { // if we're here then this is a player report from when they were in another alliance
						if (rpt.side0PlayerId == uW.tvuid)
							t.report[reportId].sideId = 0;
						else if (rpt.side1PlayerId == uW.tvuid)
							t.report[reportId].sideId = 1;
						else // shouldn't get here but we'll catch it if the report body is requested
							t.report[reportId].sideId = -1;
					}
					if (rpt.marchType == 0)
						t.report[reportId].marchName = tx('Desertion');
					else if (rpt.marchType == 1)
						t.report[reportId].marchName = uW.g_js_strings.commonstr.transport;
					else if (rpt.marchType == 2)
						t.report[reportId].marchName = uW.g_js_strings.commonstr.reinforce;
					else if (rpt.marchType == 3) {
						if (t.report[reportId].sideId == 0)
							t.report[reportId].marchName = tx('Anti-Scout');
						else
							t.report[reportId].marchName = uW.g_js_strings.commonstr.scout;
					} else if (rpt.marchType == 4 || rpt.marchType == 10) {
						if (t.report[reportId].sideId == 0)
							t.report[reportId].marchName = uW.g_js_strings.commonstr.defend;
						else
							t.report[reportId].marchName = uW.g_js_strings.commonstr.attack;
					} else
						t.report[reportId].marchName = '?';
					t.data.push({
						reportId: reportId,
					});
				}
			}
			if (parseInt(page) + 1 <= t.maxPages && t.searchRunning) {
				ById("idRptStatus").innerHTML = tx('Searching page')+' ' + (parseInt(page) + 1) + ' '+uW.g_js_strings.commonstr.of+' ' + t.maxPages;
				t.getRpt(parseInt(page) + 1);
				if (t.data.length > 0)
					t.DisplayRpt();
			} else if (page)
				t.stopSearch(uW.g_js_strings.commonstr.completedexc);
		}
	},

	DisplayMail: function () {
		var t = Tabs.Messages;
		var results = ById("idRptResultsDiv");
		if (!t.data.length) {
			results.innerHTML = '<br><center>'+tx('None found')+'</center>';
			return;
		}
		reportsSearched = t.data.length;
		reportsFound = 0;
		t.DisplayIdArray = [];
		t.DisplayArray = [];
		t.content = '<BR>';
		var NameType = uW.g_js_strings.commonstr.from;
		if (Options.MessagesOptions.rptType == 'outbox') {
			NameType = uW.g_js_strings.commonstr.totx;
		}
		for (var i = 0; i < reportsSearched; i++) {
			var rpt = t.data[i];
			if (Options.MessagesOptions.rptType == 'outbox') {
				var rptuserid = rpt.toUserId;
			}
			else {
				var rptuserid = rpt.fromUserId;
			}
			var subject = uW.g_js_strings.modal_messages_listshow.nosubject;
			if (rpt.subject && rpt.subject.length > 0) { subject = rpt.subject;	}
			var datesok = true; // future development - date filter on messages
			if (datesok && ((t.what == '' || (rpt.subject.search(t.what, "i") != -1) || (rpt.displayName.search(t.what, "i") != -1)) && (t.whatNot == '' || ((rpt.subject.search(t.whatNot, "i") == -1) && (rpt.displayName.search(t.whatNot, "i") == -1))))) {
				reportsFound++;
				if (reportsFound == 1)
					t.content += '<center><table width=98% cellpadding=0 cellspacing=0><tr><td class=xtabHD width=200>'+uW.g_js_strings.commonstr.date+'</td><td class=xtabHD width=200>'+NameType+'</td><td class=xtabHD>'+uW.g_js_strings.commonstr.subject+'</td><td class=xtabHD align=right><a class="inlineButton btButton red14" onclick="ptMsgDeleteAll()"><span>'+tx('Delete All')+'</span></a></td></tr>';

				rowClass = 'evenRow';
				var rem = (reportsFound % 2);
				if (rem == 1) rowClass = 'oddRow';

				t.content += '<tr class='+rowClass+'><td class=xtab>' + rpt.dateSent + '</td>';
				if (rptuserid==0) { t.content += '<td class=xtab>' + rpt.displayName + '</td>';	}
				else { t.content += '<td class=xtab>' + PlayerLink(rptuserid,rpt.displayName) + '</td>'; }
				t.content += '<td class=xtab><A><SPAN onclick="getmsg(' + rpt.messageId + ')">' + subject + '</SPAN></a></td>';
				t.content += '<td class=xtab align=right>'+strButton8(uW.g_js_strings.commonstr.deletetx,'onclick="ptMsgDelete('+i+')"')+'</td></tr>';

				t.DisplayIdArray.push(rpt.messageId);
				t.DisplayArray.push(i);
			}
		}
		if (reportsFound > 1)
			t.content += '</table></center>';
		if (reportsFound == 0 && reportsSearched > 0)
			t.content = '<br><center>'+tx('No messages found matching search criteria')+'</center>';
		results.innerHTML = t.content;
		ById("idRptSearched").innerHTML = '&nbsp;'+tx('Searched')+': ' + reportsSearched;
		ById("idRptFound").innerHTML = tx('Matched')+': ' + reportsFound;
	},

	getMailBody: function (ID, dataI) {
		var t = Tabs.Messages;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.messageId = ID;
		params.requestType = "GET_MESSAGE_FOR_ID";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok)
					t.displayMailBody(rslt.messageBody,tx('Message Text'));
			},
		}, false);
	},

	displayMailBody: function (messageBody,messageHeader) {
		var t = Tabs.Messages;
		t.popMsg = new CPopup('pbMailBody', 0, 0, 670, 600, true, function () {
			clearTimeout(1000);
		});
		t.popMsg.centerMe(mainPop.getMainDiv());
		var m = '<DIV style="padding-left:6px;padding-top:6px;max-height:550px; height:550px; overflow-y:scroll">';
		messageBody = messageBody.replace(/custom-line-break/g,"<BR>");
		m += messageBody + '</div>';
		t.popMsg.getMainDiv().innerHTML = m;
		t.popMsg.getTopDiv().innerHTML = '<DIV align=center><B>'+messageHeader+'</B></DIV>';
		t.popMsg.show(true);
	},

	DeleteMessage : function(i) {
		var t = Tabs.Messages;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType = 'ACTION_ON_MESSAGES';
		params.boxType = Options.MessagesOptions.rptType;
		params.selectedAction = 'delete';
		params.selectedMessageIds = t.data[i].messageId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				t.data.splice(i,1);
				t.DisplayMail();
			},
		},true);
	},

	DeleteAllMessages : function() {
		var t = Tabs.Messages;
		if (t.DisplayArray.length==0) return;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType = 'ACTION_ON_MESSAGES';
		params.boxType = Options.MessagesOptions.rptType;
		params.selectedAction = 'delete';
		params.selectedMessageIds = t.DisplayIdArray.toString();
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				for (var j = t.DisplayArray.length-1; j>=0;j--) {
					t.data.splice(t.DisplayArray[j],1);
				}
				t.DisplayMail();
			},
		},true);
	},

	DisplayRpt: function () {
		var t = Tabs.Messages;
		var results = ById("idRptResultsDiv");
		if (!t.data.length) {
			results.innerHTML = '<br><center>'+tx('None found')+'</center>';
			return;
		}
		var myAllianceId = parseInt(getMyAlliance()[0]);
		reportsSearched = t.data.length;
		reportsFound = 0;
		t.DisplayIdArray = [];
		t.DisplayArray = [];
		t.content = '';
		for (var i = 0; i < reportsSearched; i++) {
			var reportId = t.data[i].reportId;
			var rpt = t.report[reportId];
			if ((rpt.side0Name == 'undefined') || (rpt.marchName == tx('Desertion')))
				continue;
			if ((((myAllianceId == parseInt(rpt.side1AllianceId) && Options.MessagesOptions.arAttacker != 'Them') || (myAllianceId != parseInt(rpt.side1AllianceId) && Options.MessagesOptions.arAttacker != 'Us') || Options.MessagesOptions.arAttacker == 'Both') && ((myAllianceId == parseInt(rpt.side0AllianceId) && Options.MessagesOptions.arTarget != 'Them') || (myAllianceId != parseInt(rpt.side0AllianceId) && Options.MessagesOptions.arTarget != 'Us') || Options.MessagesOptions.arTarget == 'Both') && ((Options.MessagesOptions.arAttack && (rpt.marchName == uW.g_js_strings.commonstr.attack || rpt.marchName == uW.g_js_strings.commonstr.defend)) || (Options.MessagesOptions.arScout && (rpt.marchName == uW.g_js_strings.commonstr.scout || rpt.marchName == tx('Anti-Scout'))) || (Options.MessagesOptions.arReinforce && rpt.marchName == uW.g_js_strings.commonstr.reinforce) || (Options.MessagesOptions.arTransport && rpt.marchName == uW.g_js_strings.commonstr.transport))) || (rpt.marchName == tx('Desertion'))) {
				var datesok = false;
				var unixtime = rpt.reportUnixTime;
			if ((unixtime>=t.FromUnixTime || t.FromUnixTime==0) && (unixtime<=t.ToUnixTime || t.ToUnixTime==0)) { datesok = true; }
				if (datesok && (((t.what == '' || (rpt.side1Name.search(t.what, "i") != -1) || (rpt.side1AllianceName.search(t.what, "i") != -1) || (rpt.side0Name.search(t.what, "i") != -1) || (rpt.side0AllianceName.search(t.what, "i") != -1) || (rpt.side0TileTypeText.search(t.what, "i") != -1)) && (t.whatNot == '' || ((rpt.side1Name.search(t.whatNot, "i") == -1) && (rpt.side1AllianceName.search(t.whatNot, "i") == -1) && (rpt.side0Name.search(t.whatNot, "i") == -1) && (rpt.side0AllianceName.search(t.whatNot, "i") == -1) && (rpt.side0TileTypeText.search(t.whatNot, "i") == -1)))) || (rpt.marchName == tx('Desertion')))) {
					reportsFound++;
					if (reportsFound == 1) {
						t.content += '<div id=ptRptSummaryDiv class=divHide><br><center>'+strButton20(tx('PVP Summary'),'onclick="ptRptPVPSummary()"');
						if (Options.MessagesOptions.rptType == 'player') {	t.content += '&nbsp;'+strButton20(tx('Item Summary'),'onclick="ptRptItemSummary()"'); }
						t.content += '</center></div>';
						t.content += '<center><table width=98% cellpadding=0 cellspacing=0><tr><td class=xtabHD width=160>'+uW.g_js_strings.commonstr.date+'</td><td class=xtabHD width=120>'+tx('Report Id')+'</td><td class=xtabHD width=120>'+uW.g_js_strings.commonstr.type+'</td><td class=xtabHD align=center width=80>'+uW.g_js_strings.commonstr.from+'</td><td class=xtabHD>'+uW.g_js_strings.commonstr.attacker+'</td>';
						if (Options.MessagesOptions.arAttacker != 'Us')
							t.content += '<td class=xtabHD>'+uW.g_js_strings.commonstr.alliance+'</td>';
						t.content += '<td class=xtabHD>'+uW.g_js_strings.commonstr.target+'</td>';
						if (Options.MessagesOptions.arTarget != 'Us')
							t.content += '<td class=xtabHD>'+uW.g_js_strings.commonstr.alliance+'</td>';
						t.content += '<td class=xtabHD align=center>'+tx('View')+'</td><td class=xtabHD>'+uW.g_js_strings.commonstr.type+'</td><td class=xtabHD align=center width=80>'+tx('At')+'</td><td class=xtabHD align=center width=80>'+tx('Nearest')+'</td><td class=xtabHD align=right width=80>'+tx('Dist')+'</td></tr>';
					}

					rowClass = 'evenRow';
					var rem = (reportsFound % 2);
					if (rem == 1) rowClass = 'oddRow';

					var closestDist = 999999;
					var closestLoc = null;
					var closestNum = 1;
					for (var c = 0; c < Cities.numCities; c++) {
						var city = Cities.cities[c];
						city.x + ',' + city.y
						var dist = distance(city.x, city.y, rpt.side0XCoord, rpt.side0YCoord);
						if (dist < closestDist) {
							closestDist = dist;
							closestLoc = city.x + ',' + city.y;
							closestNum = c + 1;
						}
					}
					if (rpt.marchName == tx('Anti-Scout') || rpt.marchName == uW.g_js_strings.commonstr.defend)
						style = ' style="color:#800;"';
					else if (rpt.marchName == uW.g_js_strings.commonstr.reinforce)
						style = ' style="color:#080;"';
					else
						style = "";
					t.content += '<tr class='+rowClass+'><td class=xtab>' + formatUnixTime(rpt.reportUnixTime, '24hour') + '</td>';
					t.content += '<td class=xtab><A><SPAN onclick="ptChatReportClicked(' + reportId + ',0)">' + reportId + '</span></a></td>';
					if (rpt.marchName == tx('Desertion')) {
						t.content += '<td class=xtab>&nbsp;</td><td class=xtab>&nbsp;</td>';
						if (Options.MessagesOptions.arAttacker != 'Us')
							t.content += '<td class=xtab>&nbsp;</td>';
						t.content += '<td class=xtab>&nbsp;</td>';
						if (Options.MessagesOptions.arAttacker != 'Us')
							t.content += '<td class=xtab>&nbsp;</td>';
						t.content += '<td class=xtab align=center>'+strButton8(uW.g_js_strings.commonstr.view,'onclick="ptChatReportClicked('+reportId + ',0)"')+'</td>';
						t.content += '<td class=xtab>&nbsp;</td><td class=xtab>&nbsp;</td>';
						t.content += '<td class=xtab>&nbsp;</td><td class=xtab>&nbsp;</td>';
					} else {
						t.content += '<td class=xtab ' + style + '>' + rpt.marchName + '</td>';
						t.content += '<td align=center class=xtab><A onclick="btGotoMap(' + rpt.side1XCoord + ',' + rpt.side1YCoord + ')">' + rpt.side1XCoord + ',' + rpt.side1YCoord + '</a></td><td class=xtab>' + PlayerLink(rpt.side1PlayerId,rpt.side1Name) + '</td>';
						if (Options.MessagesOptions.arAttacker != 'Us')
							t.content += '<td class=xtab><span style='+DiplomacyColours(rpt.side1AllianceId)+'>' + rpt.side1AllianceName + '</span></td>';
						if (rpt.side0PlayerId && (rpt.side0PlayerId != 0)) { t.content += '<td class=xtab>' + PlayerLink(rpt.side0PlayerId,rpt.side0Name) + '</td>'; }
						else { t.content += '<td class=xtab>' + rpt.side0Name + '</td>'; }
						if (Options.MessagesOptions.arTarget != 'Us')
							t.content += '<td class=xtab><span style='+DiplomacyColours(rpt.side0AllianceId)+'>' + rpt.side0AllianceName + '</span></td>';
						t.content += '<td class=xtab align=center>'+strButton8(uW.g_js_strings.commonstr.view,'onclick="ptChatReportClicked('+reportId + ',0)"')+'</td>';
						t.content += '<td class=xtab>' + rpt.side0TileTypeLevel + '</td>';
						t.content += '<td align=center class=xtab><A onclick="btGotoMap(' + rpt.side0XCoord + ',' + rpt.side0YCoord + ')">' + rpt.side0XCoord + ',' + rpt.side0YCoord + '</a></td>';
						t.content += '<td align=center class=xtab><A onclick="btGotoMap('+Cities.cities[closestNum-1].x+','+Cities.cities[closestNum-1].y+')\">'+closestLoc+'</a></td><td align=right class=xtab>' + Math.floor(closestDist) + '</td></tr>';
					}

				t.DisplayIdArray.push(reportId);
				t.DisplayArray.push(i);
				}
			}
		}
		if (reportsFound > 1)
			t.content += '</tbody></table></center>';
		if (reportsFound == 0 && reportsSearched > 0)
			t.content = '<br><center>'+tx('No reports found matching search criteria')+'</center>';
		results.innerHTML = t.content;
		ById("idRptSearched").innerHTML = '&nbsp;'+tx('Searched')+': ' + reportsSearched;
		ById("idRptFound").innerHTML = tx('Matched')+': ' + reportsFound;
		if (!t.searchRunning) { jQuery('#ptRptSummaryDiv').removeClass('divHide'); }
	},

	BuildPVPSummary : function () {
		var t = Tabs.Messages;
		t.FetchReportArray = [];
		for (var j = 0; j<t.DisplayIdArray.length; j++) {
			t.FetchReportArray.push(t.DisplayIdArray[j]);
		}
		t.displayMailBody("",tx('PVP Summary'));
		ResetFrameSize('pbMailBody',600,GlobalOptions.btWinSize.x);
		t.popMsg.centerMe(mainPop.getMainDiv());
		t.FetchReports(t.PVPSummary);
	},

	PVPSummary : function () {
		var t = Tabs.Messages;
		t.PlayerData = {};

		var RepCount = 0;
		t.initPlayerInfo('us');
		t.initPlayerInfo('them');

		for (var j = 0; j<t.DisplayArray.length; j++) {
			var reportId = t.data[t.DisplayArray[j]].reportId;
			var rpt = t.report[reportId];
			if (rpt.side0PlayerId && rpt.side0PlayerId != 0) { // PVP
				if (ReportCache[reportId]) {
					RepCount++;
					var rslt = JSON2.parse(JSON2.stringify(ReportCache[reportId]));
					// attacker stats
					var uid = rpt.side1PlayerId;
					t.initPlayerInfo(uid,rpt.side1Name,rpt.side1AllianceId,rpt.side1AllianceName);
					var tid = t.PlayerData[uid].side;
					if (rslt.detail.loot) {
						if (rslt.detail['loot'][0] !== undefined) {
							t.PlayerData[uid].loot.gold += parseIntNan(rslt.detail['loot'][0]);
							t.PlayerData[tid].loot.gold += parseIntNan(rslt.detail['loot'][0]);
						}
						if (rslt.detail['loot'][1] !== undefined) {
							t.PlayerData[uid].loot.food += parseIntNan(rslt.detail['loot'][1]);
							t.PlayerData[tid].loot.food += parseIntNan(rslt.detail['loot'][1]);
						}
						if (rslt.detail['loot'][2] !== undefined) {
							t.PlayerData[uid].loot.wood += parseIntNan(rslt.detail['loot'][2]);
							t.PlayerData[tid].loot.wood += parseIntNan(rslt.detail['loot'][2]);
						}
						if (rslt.detail['loot'][3] !== undefined) {
							t.PlayerData[uid].loot.stone += parseIntNan(rslt.detail['loot'][3]);
							t.PlayerData[tid].loot.stone += parseIntNan(rslt.detail['loot'][3]);
						}
						if (rslt.detail['loot'][4] !== undefined) {
							t.PlayerData[uid].loot.ore += parseIntNan(rslt.detail['loot'][4]);
							t.PlayerData[tid].loot.ore += parseIntNan(rslt.detail['loot'][4]);
						}
						if (rslt.detail['loot'][6] !== undefined) {
							t.PlayerData[uid].loot.aether += parseIntNan(rslt.detail['loot'][6]);
							t.PlayerData[tid].loot.aether += parseIntNan(rslt.detail['loot'][6]);
						}
					}
					if (rslt.detail.fght && rslt.detail.fght.s1) {
						var might = 0;
						for (var ui in uW.cm.UNIT_TYPES) {
							i = uW.cm.UNIT_TYPES[ui];
							if (rslt.detail.fght.s1['u'+i]) {
								if (rslt.detail.fght.s1['u'+i][0] > rslt.detail.fght.s1['u'+i][1]) {
									var losses = parseInt(rslt.detail.fght.s1['u'+i][0]) - parseInt(rslt.detail.fght.s1['u'+i][1]);
									t.PlayerData[uid].losses['u'+i] -= losses;
									t.PlayerData[tid].losses['u'+i] -= losses;
									might -= parseInt(uW.unitmight['unt'+i] * losses);
								}
							}
						}
						t.PlayerData[uid].might += might;
						t.PlayerData[tid].might += might;
					}

					// glory for our side only
					if (rslt.detail['glory'] && t.PlayerData[uid].side=='us') {
						t.PlayerData[uid].glory += parseInt(rslt.detail['glory']);
						t.PlayerData[tid].glory += parseInt(rslt.detail['glory']);
					}

					// defender stats
					var uid = rpt.side0PlayerId;
					t.initPlayerInfo(uid,rpt.side0Name,rpt.side0AllianceId,rpt.side0AllianceName);
					var tid = t.PlayerData[uid].side;
					if (rslt.detail.loot) {
						if (rslt.detail['loot'][0] !== undefined) {
							t.PlayerData[uid].lost.gold += parseIntNan(rslt.detail['loot'][0]);
							t.PlayerData[tid].lost.gold += parseIntNan(rslt.detail['loot'][0]);
						}
						if (rslt.detail['loot'][1] !== undefined) {
							t.PlayerData[uid].lost.food += parseIntNan(rslt.detail['loot'][1]);
							t.PlayerData[tid].lost.food += parseIntNan(rslt.detail['loot'][1]);
						}
						if (rslt.detail['loot'][2] !== undefined) {
							t.PlayerData[uid].lost.wood += parseIntNan(rslt.detail['loot'][2]);
							t.PlayerData[tid].lost.wood += parseIntNan(rslt.detail['loot'][2]);
						}
						if (rslt.detail['loot'][3] !== undefined) {
							t.PlayerData[uid].lost.stone += parseIntNan(rslt.detail['loot'][3]);
							t.PlayerData[tid].lost.stone += parseIntNan(rslt.detail['loot'][3]);
						}
						if (rslt.detail['loot'][4] !== undefined) {
							t.PlayerData[uid].lost.ore += parseIntNan(rslt.detail['loot'][4]);
							t.PlayerData[tid].lost.ore += parseIntNan(rslt.detail['loot'][4]);
						}
						if (rslt.detail['loot'][6] !== undefined) {
							t.PlayerData[uid].lost.aether += parseIntNan(rslt.detail['loot'][6]);
							t.PlayerData[tid].lost.aether += parseIntNan(rslt.detail['loot'][6]);
						}
					}

					if (rslt.detail.fght && rslt.detail.fght.s0) {
						var might = 0;
						if (rslt.detail.overwhelmed) {
							for (var ui in uW.cm.UNIT_TYPES) {
								i = uW.cm.UNIT_TYPES[ui];
								if (rslt.detail.fght.s0['u'+i]) {
									if (rslt.detail.fght.s0['u'+i][0] > rslt.detail.fght.s0['u'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['u'+i][0]);
										t.PlayerData[uid].losses['u'+i] -= losses;
										t.PlayerData[tid].losses['u'+i] -= losses;
										might -= parseInt(uW.unitmight['unt'+i] * losses);
									}
								}
							}
							for (var i = 53; i <= 55; i++) {
								if (rslt.detail.fght.s0['f'+i]) {
									if (rslt.detail.fght.s0['f'+i][0] > rslt.detail.fght.s0['f'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['f'+i][0]);
										t.PlayerData[uid].losses['f'+i] -= losses;
										t.PlayerData[tid].losses['f'+i] -= losses;
										var fm = parseIntNan(fortmight['f'+i]);
										might -= fm * losses;
									}
								}
							}
							for (var i = 60; i < 64; i++) {
								if (rslt.detail.fght.s0['f'+i]) {
									if (rslt.detail.fght.s0['f'+i][0] > rslt.detail.fght.s0['f'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['f'+i][0]);
										t.PlayerData[uid].losses['f'+i] -= losses;
										t.PlayerData[tid].losses['f'+i] -= losses;
										var fm = parseIntNan(fortmight['f'+i]);
										might -= fm * losses;
									}
								}
							}
						}
						else {
							for (var ui in uW.cm.UNIT_TYPES) {
								i = uW.cm.UNIT_TYPES[ui];
								if (rslt.detail.fght.s0['u'+i]) {
									if (rslt.detail.fght.s0['u'+i][0] > rslt.detail.fght.s0['u'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['u'+i][0]) - parseInt(rslt.detail.fght.s0['u'+i][1]);
										t.PlayerData[uid].losses['u'+i] -= losses;
										t.PlayerData[tid].losses['u'+i] -= losses;
										might -= parseInt(uW.unitmight['unt'+i] * losses);
									}
								}
							}
							for (var i = 53; i <= 55; i++) {
								if (rslt.detail.fght.s0['f'+i]) {
									if (rslt.detail.fght.s0['f'+i][0] > rslt.detail.fght.s0['f'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['f'+i][0]) - parseInt(rslt.detail.fght.s0['f'+i][1]);
										t.PlayerData[uid].losses['f'+i] -= losses;
										t.PlayerData[tid].losses['f'+i] -= losses;
										var fm = parseIntNan(fortmight['f'+i]);
										might -= fm * losses;
									}
								}
							}
							for (var i = 60; i < 64; i++) {
								if (rslt.detail.fght.s0['f'+i]) {
									if (rslt.detail.fght.s0['f'+i][0] > rslt.detail.fght.s0['f'+i][1]) {
										var losses = parseInt(rslt.detail.fght.s0['f'+i][0]) - parseInt(rslt.detail.fght.s0['f'+i][1]);
										t.PlayerData[uid].losses['f'+i] -= losses;
										t.PlayerData[tid].losses['f'+i] -= losses;
										var fm = parseIntNan(fortmight['f'+i]);
										might -= fm * losses;
									}
								}
							}
						}
						t.PlayerData[uid].might += might;
						t.PlayerData[tid].might += might;
					}

					// glory for our side only
					if (rslt.detail['glory'] && t.PlayerData[uid].side=='us') {
						t.PlayerData[uid].glory += parseInt(rslt.detail['glory']);
						t.PlayerData[tid].glory += parseInt(rslt.detail['glory']);
					}
				}
			}
		}

		var message = '<DIV style="max-width:'+GlobalOptions.btWinSize.x+'px;"><b>'+tx('Number of Reports Searched')+': '+RepCount+'</b><br><br>';
		message += '<div class=divHeader align=center>'+tx('Resources Taken')+'</div>';

		var r = 0;
		message += '<table width=100% class=xtab cellspacing=0 cellpadding=4><tr><TH class=xtabHD align=left>'+tx('Player')+'</th><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.alliance+'</th><TH class=xtabHD align=right>&nbsp;</th><TH class=xtabHD align=right><img src="'+GoldImage+'"></th><TH class=xtabHD align=right><img src="'+FoodImage+'"></th><TH class=xtabHD align=right><img src="'+WoodImage+'"></th><TH class=xtabHD align=right><img src="'+StoneImage+'"></th><TH class=xtabHD align=right><img src="'+OreImage+'"></th><TH class=xtabHD align=right><img src="'+AetherImage+'"></th></tr>';
		for (var uid in t.PlayerData) {
			var rslt = t.PlayerData[uid];
			if (rslt.side == "us" && uid != "us") {
				if (rslt.loot.gold || rslt.lost.gold || rslt.loot.food || rslt.lost.food || rslt.loot.wood || rslt.lost.wood || rslt.loot.stone || rslt.lost.stone || rslt.loot.ore || rslt.lost.ore || rslt.loot.aether || rslt.lost.aether) {
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
					message += '<tr class="'+rowClass+'"><TD rowspan=3>'+MonitorLink(rslt.uid,rslt.name)+'</td><td rowspan=3><span style='+DiplomacyColours(rslt.aid)+'>'+rslt.aname+'</span></td>';
					message += '<td align=right>'+tx('Lost')+'</td><td align=right>'+addCommas(0-rslt.lost.gold)+'</td><td align=right>'+addCommas(0-rslt.lost.food)+'</td><td align=right>'+addCommas(0-rslt.lost.wood)+'</td><td align=right>'+addCommas(0-rslt.lost.stone)+'</td><td align=right>'+addCommas(0-rslt.lost.ore)+'</td><td align=right>'+addCommas(0-rslt.lost.aether)+'</td></tr>';
					message += '<tr class="'+rowClass+'"><td align=right>'+tx('Gained')+'</td><td align=right>'+addCommas(rslt.loot.gold)+'</td><td align=right>'+addCommas(rslt.loot.food)+'</td><td align=right>'+addCommas(rslt.loot.wood)+'</td><td align=right>'+addCommas(rslt.loot.stone)+'</td><td align=right>'+addCommas(rslt.loot.ore)+'</td><td align=right>'+addCommas(rslt.loot.aether)+'</td></tr>';
					message += '<tr class="'+rowClass+'"><td align=right class=xtabTotal><b>'+tx('Total')+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.gold-rslt.lost.gold)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.food-rslt.lost.food)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.wood-rslt.lost.wood)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.stone-rslt.lost.stone)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.ore-rslt.lost.ore)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.aether-rslt.lost.aether)+'</b></td></tr>';
				}
			}
		}
		var rslt = t.PlayerData["us"];
		r=r+1;
		rowClass = 'evenRow';
		var rem = (r % 2);
		if (rem == 1) rowClass = 'oddRow';
		message += '<tr class="'+rowClass+'"><TD rowspan=3 colspan=2><b>'+tx('Total Gained')+' ('+tx('Us')+')</b></td>';
		message += '<td align=right>'+tx('Lost')+'</td><td align=right>'+addCommas(0-rslt.lost.gold)+'</td><td align=right>'+addCommas(0-rslt.lost.food)+'</td><td align=right>'+addCommas(0-rslt.lost.wood)+'</td><td align=right>'+addCommas(0-rslt.lost.stone)+'</td><td align=right>'+addCommas(0-rslt.lost.ore)+'</td><td align=right>'+addCommas(0-rslt.lost.aether)+'</td></tr>';
		message += '<tr class="'+rowClass+'"><td align=right>'+tx('Gained')+'</td><td align=right>'+addCommas(rslt.loot.gold)+'</td><td align=right>'+addCommas(rslt.loot.food)+'</td><td align=right>'+addCommas(rslt.loot.wood)+'</td><td align=right>'+addCommas(rslt.loot.stone)+'</td><td align=right>'+addCommas(rslt.loot.ore)+'</td><td align=right>'+addCommas(rslt.loot.aether)+'</td></tr>';
		message += '<tr class="'+rowClass+'"><td align=right class=xtabTotal><b>'+tx('Total')+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.gold-rslt.lost.gold)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.food-rslt.lost.food)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.wood-rslt.lost.wood)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.stone-rslt.lost.stone)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.ore-rslt.lost.ore)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.aether-rslt.lost.aether)+'</b></td></tr>';

		var r = 0;
		message += '<tr><TH class=xtabHD align=left>'+tx('Player')+'</th><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.alliance+'</th><TH class=xtabHD align=right>&nbsp;</th><TH class=xtabHD align=right><img src="'+GoldImage+'"></th><TH class=xtabHD align=right><img src="'+FoodImage+'"></th><TH class=xtabHD align=right><img src="'+WoodImage+'"></th><TH class=xtabHD align=right><img src="'+StoneImage+'"></th><TH class=xtabHD align=right><img src="'+OreImage+'"></th><TH class=xtabHD align=right><img src="'+AetherImage+'"></th></tr>';
		for (var uid in t.PlayerData) {
			var rslt = t.PlayerData[uid];
			if (rslt.side == "them" && uid != "them") {
				if (rslt.loot.gold || rslt.lost.gold || rslt.loot.food || rslt.lost.food || rslt.loot.wood || rslt.lost.wood || rslt.loot.stone || rslt.lost.stone || rslt.loot.ore || rslt.lost.ore || rslt.loot.aether || rslt.lost.aether) {
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
					message += '<tr class="'+rowClass+'"><TD rowspan=3>'+MonitorLink(rslt.uid,rslt.name)+'</td><td rowspan=3><span style='+DiplomacyColours(rslt.aid)+'>'+rslt.aname+'</span></td>';
					message += '<td align=right>'+tx('Lost')+'</td><td align=right>'+addCommas(0-rslt.lost.gold)+'</td><td align=right>'+addCommas(0-rslt.lost.food)+'</td><td align=right>'+addCommas(0-rslt.lost.wood)+'</td><td align=right>'+addCommas(0-rslt.lost.stone)+'</td><td align=right>'+addCommas(0-rslt.lost.ore)+'</td><td align=right>'+addCommas(0-rslt.lost.aether)+'</td></tr>';
					message += '<tr class="'+rowClass+'"><td align=right>'+tx('Gained')+'</td><td align=right>'+addCommas(rslt.loot.gold)+'</td><td align=right>'+addCommas(rslt.loot.food)+'</td><td align=right>'+addCommas(rslt.loot.wood)+'</td><td align=right>'+addCommas(rslt.loot.stone)+'</td><td align=right>'+addCommas(rslt.loot.ore)+'</td><td align=right>'+addCommas(rslt.loot.aether)+'</td></tr>';
					message += '<tr class="'+rowClass+'"><td align=right class=xtabTotal><b>'+tx('Total')+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.gold-rslt.lost.gold)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.food-rslt.lost.food)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.wood-rslt.lost.wood)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.stone-rslt.lost.stone)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.ore-rslt.lost.ore)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.aether-rslt.lost.aether)+'</b></td></tr>';
				}
			}
		}
		var rslt = t.PlayerData["them"];
		r=r+1;
		rowClass = 'evenRow';
		var rem = (r % 2);
		if (rem == 1) rowClass = 'oddRow';
		message += '<tr class="'+rowClass+'"><TD rowspan=3 colspan=2><b>'+tx('Total Gained')+' ('+tx('Them')+')</b></td>';
		message += '<td align=right>'+tx('Lost')+'</td><td align=right>'+addCommas(0-rslt.lost.gold)+'</td><td align=right>'+addCommas(0-rslt.lost.food)+'</td><td align=right>'+addCommas(0-rslt.lost.wood)+'</td><td align=right>'+addCommas(0-rslt.lost.stone)+'</td><td align=right>'+addCommas(0-rslt.lost.ore)+'</td><td align=right>'+addCommas(0-rslt.lost.aether)+'</td></tr>';
		message += '<tr class="'+rowClass+'"><td align=right>'+tx('Gained')+'</td><td align=right>'+addCommas(rslt.loot.gold)+'</td><td align=right>'+addCommas(rslt.loot.food)+'</td><td align=right>'+addCommas(rslt.loot.wood)+'</td><td align=right>'+addCommas(rslt.loot.stone)+'</td><td align=right>'+addCommas(rslt.loot.ore)+'</td><td align=right>'+addCommas(rslt.loot.aether)+'</td></tr>';
		message += '<tr class="'+rowClass+'"><td align=right class=xtabTotal><b>'+tx('Total')+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.gold-rslt.lost.gold)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.food-rslt.lost.food)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.wood-rslt.lost.wood)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.stone-rslt.lost.stone)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.ore-rslt.lost.ore)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.loot.aether-rslt.lost.aether)+'</b></td></tr>';

		message += '</table><br>';
		message += '<div class=divHeader align=center>'+tx('Troop Losses')+'</div>';
		message += '<DIV style="max-width:'+GlobalOptions.btWinSize.x+'px;">';

		var r = 0;
		message += '<table class=xtab cellspacing=0 cellpadding=4><tr><TH class=xtabHD align=left>'+tx('Player')+'</th><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.alliance+'</th><TH class=xtabHD align=right>'+uW.g_js_strings.commonstr.glory+'</th><TH class=xtabHD align=right>'+tx('Might Loss')+'</th>';
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<TH class=xtabHD align=right>'+TroopImageBigHeader(i)+'</th>'; }
		}
		for (var fi in fortmight){
			if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<TH class=xtabHD align=right>'+TroopImageBigHeader(fi.split("f")[1])+'</th>'; }
		}
		message += '</tr>';
		for (var uid in t.PlayerData) {
			var rslt = t.PlayerData[uid];
			if (rslt.side == "us" && uid != "us") {
				gotdata = false;
				for (var i in rslt.losses) {
					if (rslt.losses[i]) { gotdata = true; break; }
				}
				if (gotdata) {
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
					message += '<tr class="'+rowClass+'"><TD>'+MonitorLink(rslt.uid,rslt.name)+'</td><td><span style='+DiplomacyColours(rslt.aid)+'>'+rslt.aname+'</span></td><td align=right>'+addCommas(rslt.glory)+'</td><td align=right>'+addCommas(rslt.might)+'</td>';
					for (var ui in uW.cm.UNIT_TYPES){
						i = uW.cm.UNIT_TYPES[ui];
						if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<td align=right>'+addCommas(rslt.losses['u'+i])+'</td>'; }
					}
					for (var fi in fortmight){
						if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<td align=right>'+addCommas(rslt.losses[fi])+'</td>'; }
					}
					message += '</tr>';
				}
			}
		}
		var rslt = t.PlayerData["us"];
		r=r+1;
		rowClass = 'evenRow';
		var rem = (r % 2);
		if (rem == 1) rowClass = 'oddRow';
		message += '<tr class="'+rowClass+'"><TD colspan=2><b>'+tx('Total Losses')+' ('+tx('Us')+')</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.glory)+'</b></td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.might)+'</b></td>';
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.losses['u'+i])+'</b></td>'; }
		}
		for (var fi in fortmight){
			if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.losses[fi])+'</b></td>'; }
		}
		message += '</tr>';

		var r = 0;
		message += '<tr><TH class=xtabHD align=left>'+tx('Player')+'</th><TH class=xtabHD align=left>'+uW.g_js_strings.commonstr.alliance+'</th><TH class=xtabHD align=right>&nbsp;</th><TH class=xtabHD align=right>'+tx('Might Loss')+'</th>';
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<TH class=xtabHD align=right>'+TroopImageBigHeader(i)+'</th>'; }
		}
		for (var fi in fortmight){
			if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<TH class=xtabHD align=right>'+TroopImageBigHeader(fi.split("f")[1])+'</th>'; }
		}
		message += '</tr>';
		for (var uid in t.PlayerData) {
			var rslt = t.PlayerData[uid];
			if (rslt.side == "them" && uid != "them") {
				gotdata = false;
				for (var i in rslt.losses) {
					if (rslt.losses[i]) { gotdata = true; break; }
				}
				if (gotdata) {
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
					message += '<tr class="'+rowClass+'"><TD>'+MonitorLink(rslt.uid,rslt.name)+'</td><td><span style='+DiplomacyColours(rslt.aid)+'>'+rslt.aname+'</span></td><td align=right>&nbsp;</td><td align=right>'+addCommas(rslt.might)+'</td>';
					for (var ui in uW.cm.UNIT_TYPES){
						i = uW.cm.UNIT_TYPES[ui];
						if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<td align=right>'+addCommas(rslt.losses['u'+i])+'</td>'; }
					}
					for (var fi in fortmight){
						if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<td align=right>'+addCommas(rslt.losses[fi])+'</td>'; }
					}
					message += '</tr>';
				}
			}
		}
		var rslt = t.PlayerData["them"];
		r=r+1;
		rowClass = 'evenRow';
		var rem = (r % 2);
		if (rem == 1) rowClass = 'oddRow';
		message += '<tr class="'+rowClass+'"><TD colspan=2><b>'+tx('Total Losses')+' ('+tx('Them')+')</b></td><td align=right>&nbsp;</td><td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.might)+'</b></td>';
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			if (t.PlayerData["us"].losses['u'+i] || t.PlayerData["them"].losses['u'+i]) { message += '<td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.losses['u'+i])+'</b></td>'; }
		}
		for (var fi in fortmight){
			if (t.PlayerData["us"].losses[fi] || t.PlayerData["them"].losses[fi]) { message += '<td align=right class=xtabTotal><b>'+t.FormatTotal(rslt.losses[fi])+'</b></td>'; }
		}
		message += '</tr>';
		message += '<tr><TD>&nbsp;</td></tr>';
		message += '<tr><TD colspan=2><b>'+tx('Total Might Loss Difference')+'</b></td><td align=right>&nbsp;</td><td align=right class=xtabTotal><b>'+t.FormatTotal(t.PlayerData["us"].might-t.PlayerData["them"].might)+'</b></td></tr>';
		message += '</table><br><br></div></div>';

		t.displayMailBody(message,tx('PVP Summary'));
		ResetFrameSize('pbMailBody',600,GlobalOptions.btWinSize.x);
		t.popMsg.centerMe(mainPop.getMainDiv());
	},

	FormatTotal : function (amt) {
		var t = Tabs.Messages;
		if (amt<0) {
			return '<span class=boldRed>'+addCommas(amt)+'</span>'
		}
		else {
			return addCommas(amt);
		}
	},

	initPlayerInfo : function(uid,name,aid,aname) {
		var t = Tabs.Messages;
		var myAllianceId = parseInt(getMyAlliance()[0]);
		var side = 'them';
		if (uid == "us" || uid == "them") { side = uid; }
		else {
			if ((myAllianceId==0 && uid==uW.tvuid) || (myAllianceId!=0 && myAllianceId==parseInt(aid))) { side = 'us'; }
		}
		if (!t.PlayerData[uid]) {
			t.PlayerData[uid] = {};
			t.PlayerData[uid].uid = uid;
			t.PlayerData[uid].name = name;
			t.PlayerData[uid].aid = aid;
			t.PlayerData[uid].aname = aname;
			t.PlayerData[uid].side = side;
			t.PlayerData[uid].glory = 0;
			t.PlayerData[uid].might = 0;
			t.PlayerData[uid].loot = {};
			t.PlayerData[uid].loot.gold = 0;
			t.PlayerData[uid].loot.food = 0;
			t.PlayerData[uid].loot.wood = 0;
			t.PlayerData[uid].loot.stone = 0;
			t.PlayerData[uid].loot.ore = 0;
			t.PlayerData[uid].loot.aether = 0;
			t.PlayerData[uid].lost = {};
			t.PlayerData[uid].lost.gold = 0;
			t.PlayerData[uid].lost.food = 0;
			t.PlayerData[uid].lost.wood = 0;
			t.PlayerData[uid].lost.stone = 0;
			t.PlayerData[uid].lost.ore = 0;
			t.PlayerData[uid].lost.aether = 0;
			t.PlayerData[uid].losses = {};
			for (var ui in uW.cm.UNIT_TYPES){
				i = uW.cm.UNIT_TYPES[ui];
				t.PlayerData[uid].losses['u'+i] = 0;
			}
			for (var fi in fortmight){
				t.PlayerData[uid].losses[fi] = 0;
			}
		}
	},

	FetchReports : function (notify) {
		var t = Tabs.Messages;
		if (t.FetchReportArray.length == 0) {
			if (notify) { notify(); }
			return;
		}
		else {
			var rpId = t.FetchReportArray.splice(0,1);
			t.popMsg.getMainDiv().innerHTML = '<br><br><br><center>'+tx('Reading in report details')+':&nbsp;'+rpId+'</center>';
			FetchReport(rpId, function() { t.FetchReports(notify); });
		}
	},

	BuildItemSummary : function () {
		var t = Tabs.Messages;
		t.FetchReportArray = [];
		for (var j = 0; j<t.DisplayIdArray.length; j++) {
			t.FetchReportArray.push(t.DisplayIdArray[j]);
		}
		t.displayMailBody("",tx('Items Found Summary'));
		t.FetchReports(t.ItemSummary);
	},

	ItemSummary : function () {
		var t = Tabs.Messages;
		t.ItemsFound = {};
		t.ThroneItemsFound = {};
		t.ChampItemsFound = {};
		t.JewelItemsFound = {};
		var RepCount = 0;

		for (var j = 0; j<t.DisplayArray.length; j++) {
			var reportId = t.data[t.DisplayArray[j]].reportId;
			var rpt = t.report[reportId];
			if (rpt.side1PlayerId==uW.tvuid && rpt.marchName == uW.g_js_strings.commonstr.attack && (!rpt.side0PlayerId || rpt.side0PlayerId == 0) ) {
				if (ReportCache[reportId]) {
					RepCount++;
					var rslt = JSON2.parse(JSON2.stringify(ReportCache[reportId]));
					if(rslt.detail.loot[5]) {
						var loot = rslt.detail.loot[5];
						if (matTypeof(loot) == 'object') {
							for (var z in loot) {
								if(t.ItemsFound[z]) { t.ItemsFound[z] += parseInt(loot[z]); }
								else { t.ItemsFound[z] = parseInt(loot[z]); }
							}
						}
					}
					if (rslt.detail.throneRoomDrop) {
						var TR = rslt.detail.throneRoomDrop;
						var z = ""+TR.type+TR.quality;
						if(t.ThroneItemsFound[z]) { t.ThroneItemsFound[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = TR.type;
							NewObj.quality = TR.quality;
							NewObj.amount = 1;
							t.ThroneItemsFound[z] = NewObj;
						}
					}
					if (rslt.detail.equipmentDrop) {
						var EQ = rslt.detail.equipmentDrop;
						var z = ""+EQ.subtype+EQ.rarity;
						if(t.ChampItemsFound[z]) { t.ChampItemsFound[z].amount += 1; }
						else {
							var NewObj = {};
							NewObj.type = EQ.subtype;
							NewObj.quality = EQ.rarity;
							NewObj.amount = 1;
							t.ChampItemsFound[z] = NewObj;
						}
					}
					if (rslt.detail.lootJewel) {
						var item = rslt.detail.lootJewel;
						if (matTypeof(item) == 'object') {
							var z = item.quality;
							if(t.JewelItemsFound[z]) { t.JewelItemsFound[z] += parseInt(item.quantity); }
							else { t.JewelItemsFound[z] = parseInt(item.quantity); }
						}
					}
				}
			}
		}

		var message = '<b>'+tx('Number of Reports Searched')+': '+RepCount+'</b> %0A%0A';
		message += '<b>'+tx('Miscellaneous items')+':</b> %0A';

		var Crests = {};
		var total = 0;
		for (var z in Tabs.Attack.CrestList) { Crests[Tabs.Attack.CrestList[z]] = 0; }

		for (var z in t.ItemsFound) {
			if (!isNaN(Crests[z])) // if item is a crest or seal...
				Crests[z] = t.ItemsFound[z];
			else {
				message += "<img width='20px' height='20px' src='"+getItemImageURL(z)+"' />&nbsp;"+uW.ksoItems[z].name+' x '+t.ItemsFound[z]+'%0A';
			}
		}
		message +='%0A';
		message += '<b>'+tx('Crest Stats')+':</b> %0A';
		for (crest in Crests) {
			if (Crests[crest] > 0) {
				message += "<img width='20px' height='20px' src='"+getItemImageURL(crest)+"' />&nbsp;"+uW.itemlist['i'+crest]['name'] +' x '+ Crests[crest] +'%0A';
				total += (Crests[crest]);
			}
		}
		message += '<b>'+tx('Total Crests Found')+': '+ total +'</b> %0A';

		message +='%0A';
		message += '<b>'+tx('Jewel Stats')+':</b> %0A';
		var itemcount = 0;
		for (z in t.JewelItemsFound){
			itemcount += t.JewelItemsFound[z];
			message += eval('uW.g_js_strings.jewel.quality_'+Number(z-1))+' Jewel x '+t.JewelItemsFound[z]+'%0A';
		}
		message += '<b>'+tx('Total Jewels Found')+': '+itemcount+'</b> %0A';

		message +='%0A';
		message += '<b>'+tx('Throne Stats')+':</b> %0A';
		var itemcount = 0;
		for (z in t.ThroneItemsFound){
			itemcount += t.ThroneItemsFound[z].amount;
			message += strQuality(t.ThroneItemsFound[z].quality)+' '+t.ThroneItemsFound[z].type+' x '+t.ThroneItemsFound[z].amount+'%0A';
		}
		message += '<b>'+tx('Total Throne Room Items Found')+': '+itemcount+'</b> %0A';

		message +='%0A';
		message += '<b>'+uW.g_js_strings.report_view.champion_stats+':</b> %0A';
		var itemcount = 0;
		for (z in t.ChampItemsFound){
			itemcount += t.ChampItemsFound[z].amount;
			message += strQuality(t.ChampItemsFound[z].quality)+' '+t.ChampItemsFound[z].type+' x '+t.ChampItemsFound[z].amount+'%0A';
		}
		message += '<b>'+tx('Total Champion Equipment Found')+': '+itemcount+'</b> %0A';

		t.displayMailBody(message.replace(/%0A/g,"<BR>"),tx('Items Found Summary'));
	},
};

/*********************************** Log Tab ***********************************/

Tabs.ActionLog = {
	tabOrder: 9998,
	tabColor : 'red',
	tabLabel : 'Log',
	myDiv : null,
	logTab : null,
	maxEntries: 500,
	EventLog : [],
	arealist : {},
	logfilter: 'ALL',

	init : function (div){
		var t = Tabs.ActionLog;
		t.myDiv = div;

		var a = JSON2.parse(GM_getValue ('log_'+getServerId()+'_'+uW.tvuid, '[]'));
		if (matTypeof(a) == 'array'){
			t.EventLog = a;
		}

		window.addEventListener('unload', t.onUnload, false);
	},

	onUnload : function (){
		var t = Tabs.ActionLog;
		if (uW.btLoaded) {
			if (!ResetAll) t.save();
		}
	},

	save : function () {
		var t = Tabs.ActionLog;
		GM_setValue ('log_'+getServerId()+'_'+uW.tvuid, JSON2.stringify(t.EventLog));
	},

	log : function (msg,area){
		var t = Tabs.ActionLog;
		if (!area) area = 'GENERAL';
		var ts = unixTime();
		while (t.EventLog.length >= t.maxEntries) {
			t.EventLog.shift();
		}
		t.EventLog.push ({msg:msg, ts:ts, area:area});
		if (GlobalOptions.ExtendedDebugMode) {
			logit(msg); // also send to browser log
		}

		if (tabManager.currentTab && tabManager.currentTab.name == 'ActionLog' && Options.btWinIsOpen) {
			t.PaintLog();
		}
	},

	PaintLog : function () {
		var t = Tabs.ActionLog;

		t.arealist = {ALL:'ALL'};
		for (var i=0; i<t.EventLog.length; i++) {
			if (!t.arealist[t.EventLog[i].area]) {
				t.arealist[t.EventLog[i].area] = t.EventLog[i].area;
			}
		}

		var z = '';
		var r = 0;
		var logshow = false;
		var logfiltered = false;

		var bclass = "blue14";
		var btext  = "Clear Log";

		var z = '<DIV class=divHeader align=center>ACTION LOG</div>';
		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtab"> Area Filter:&nbsp;'+htmlSelector(t.arealist, t.logfilter, 'id=pblogfilter class=btInput')+'<td class="xtab" align=right>('+t.EventLog.length+'/'+t.maxEntries+')</td></tr></table>';
		z += '<TABLE cellSpacing=0 width=98% height=0%><tr><td class="xtabHD" style="width:100px"><b>Date/Time</b></td><td style="width:115px" class="xtabHD"><b>Area</b></td><td class="xtabHD"><b>Log Message</b></td></tr></table>';
		z += '<div style="max-height:535px; height:535px; overflow-y:scroll" align="center"><TABLE id=pbactionlog cellSpacing=0 width=98% height=0%>';

		var n = t.EventLog.length;
		while (n--) {
			var a = t.EventLog[n];

			logfiltered = true;
			if ((t.logfilter != "ALL") && (a.area != t.logfilter)) continue;

			logshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:100px" class=xtab>'+formatDateTime(a.ts)+'</td>';
			z += '<TD style="width:115px" class=xtab>'+a.area+'</td>';
			z += '<TD class=xtabBRTop>'+a.msg+'</td>';
			z += '</tr>';
		}

		if (!logshow) {
			if (!logfiltered)
				z += '<tr><td colspan=2 class=xtab><div align="center"><br><br>No log entries</div></td></tr>';
			else
				z += '<tr><td colspan=2 class=xtab><div align="center"><br><br>No log entries for selected area</div></td></tr>';
		}

		z += '</table></div><br>';

		t.myDiv.innerHTML = z;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('pblogfilter').addEventListener('change', t.ChangeLogFilter, false);
	},

	show : function (){
		var t = Tabs.ActionLog;
		t.PaintLog();
	},

	ChangeLogFilter : function (evt) {
		var t = Tabs.ActionLog;
		t.logfilter = evt.target.value;
		t.PaintLog();
	},

}

/*********************************** Wilds Tab ***********************************/

Tabs.Wilds = {
	tabOrder: 1040,
	tabLabel: 'Wilds',
	mercNames : {
		0: 'None',
		1: 'Novice',
		2: 'Intermediate',
		3: 'Veteran',
	},
	myDiv: null,
	wildList: [],
	buildList: {},
	LoopCounter:0,

	init: function (div) {
		var t = Tabs.Wilds;
		t.myDiv = div;

		uWExportFunction('ptButMaxTraps', Tabs.Wilds.e_butMaxTraps);
		uWExportFunction('ptInpWildTraps', Tabs.Wilds.e_inpTraps);
		uWExportFunction('ptButWildSet', Tabs.Wilds.e_butWildSet);
		uWExportFunction('ptButAbandon', Tabs.Wilds.e_abandon);

		t.myDiv.innerHTML = '<DIV id=wildContent style="max-height:700px; height:700px; overflow-y:auto">';
	},

	show: function () {
		var t = Tabs.Wilds;
		m = '<DIV class=divHeader align=center>'+tx('WILDERNESS MANAGEMENT')+'</DIV><br>';
		m += '<TABLE align=center cellpadding=0 cellspacing=0 width=98%><TR><TD class=xtab colspan=7>'+strButton20(tx('Refresh Display'), 'id=ptwref')+'</td><TD class=xtab width=120><B>'+tx('All Traps')+':&nbsp;</b><a id=ptwx_all class="inlineButton btButton brown8"><span>'+uW.g_js_strings.commonstr.max+'</span></a></td><td class=xtab width=120><B>'+tx('All Mercs')+':</b>&nbsp;'+htmlSelector(t.mercNames, 0, 'class="btInput" id=ptwm_all')+'&nbsp;</td></tr></table>';
		for (var c = 0; c < Cities.numCities; c++) {
			var city = Cities.cities[c];
			var cWilds = Seed.wilderness['city' + city.id];
			t.wildList[c] = [];
			var castle = getMaxWilds(city.id);
			var totw = 0;
			if (matTypeof(cWilds) == 'object') {
				for (var k in cWilds)
				++totw;
			}
			m += '<br><DIV class=divHeader><TABLE width=100% cellspacing=0><TR><TD class=xtab width=100>&nbsp;</td><TD class=xtab align=center>' + city.name.toUpperCase() + '&nbsp;(' + city.x + ',' + city.y + ')</td><TD class=xtab width=100 align=right>'+tx('Wilds')+': ' + totw + ' '+uW.g_js_strings.commonstr.of+' ' + castle + '&nbsp;</TD></tr></table></div>';
			m += '<TABLE align=center cellpadding=0 cellspacing=0 width=98%>';
			var row = 0;
			var sortem = [];
			if (totw != 0) {
				m += '<TR><TD class=xtabHD width=24>&nbsp;</td><TD class=xtabHD>'+tx('Wild Type')+'</td><TD class=xtabHD width=50 align=center>'+tx('Co-ords')+'</td><TD class=xtabHD width=80 align=center>'+uW.g_js_strings.commonstr.traps+'</td><TD class=xtabHD width=80 align=center>'+tx('Mercs')+'</td><TD class=xtabHD width=100 align=center>'+uW.g_js_strings.commonstr.abandon+'</td><TD class=xtabHD width=15>&nbsp;</td><TD class=xtabHD colspan=2 class=entry>'+htmlTitleLine(tx('Change Defences'))+'</td></tr>';
				for (var k in Seed.wilderness['city' + city.id]) {
					sortem.push(Seed.wilderness['city' + city.id][k]);
				}
				sortem.sort(function (a, b) {
					var x;
					if ((x = b.tileLevel - a.tileLevel) != 0) return x;
					return a.tileType - b.tileType;
				});
				for (var i = 0; i < sortem.length; i++) {
					var wild = sortem[i];
					var wildDef = Seed.wildDef['t' + wild.tileId];
					if (wildDef == undefined || !wildDef)
						wildDef = { fort60Count: 0, mercLevel: 0 };
					var maxTraps = parseInt(wild.tileLevel) * 100;
					var maxBuild = maxTraps - parseInt(wildDef.fort60Count);
//					var maxCost = maxBuild*200;
					var maxCost = 0;
					t.wildList[c][i] = [wild.tileId, maxBuild];

					m += '<TR '+(row++ %2?'class=evenRow':'class=oddRow')+'><TD class=xtab>'+TileImage(wild.tileType,wild.tileLevel)+'</td><TD class=xtab>'+uW.g_js_strings.commonstr.level+' '+wild.tileLevel+' '+tileTypes[wild.tileType]+'</td>';
					m += '<TD class=xtab align=center><A onclick="btGotoMap(' + wild.xCoord + ',' + wild.yCoord + ')">' + wild.xCoord + ',' + wild.yCoord + '</a></td>';
					m += '<TD class=xtab align=center><B>' + wildDef.fort60Count + '</b></td><TD class=xtab align=center><B>' + t.mercNames[wildDef.mercLevel] + '</b></td><TD class=xtab align=center>' + strButton8(uW.g_js_strings.commonstr.abandon, 'onclick="ptButAbandon(' + wild.tileId + ',' + wild.xCoord + ',' + wild.yCoord + ',' + city.id + ')" id=tileId_' + wild.tileId) + '</td>';
					m += '<TD class=xtab>&nbsp;</td><TD align=left class=xtab width=120><B>'+tx('Build Traps')+':&nbsp;</b><INPUT class="btInput" onchange="ptInpWildTraps(this)" id=ptwt_' + c + '_' + i + (maxBuild == 0 ? ' DISABLED ' : '') + ' style="margin:0px; padding:0px" type=text size=3 maxlength=4>&nbsp;';
					if (wildDef.fort60Count < maxTraps)
						m += '<a id=ptwx_'+c+'_'+i+' class="inlineButton btButton brown8 btWildMax" onclick="ptButMaxTraps(this)"><span>'+uW.g_js_strings.commonstr.max+'</span></a></td>';
					else
						m += '</td>';
					m += '<TD align=right class=xtab width=120><B>'+tx('Mercs')+':</b>&nbsp;'+htmlSelector(t.mercNames, wildDef.mercLevel, 'class="btInput btWildMerc" id=ptwm_' + c + '_' + i)+'&nbsp;</td></tr>';
				}
				m += '<TR><TD class=xtab colspan=6>&nbsp;</td><TD class=xtab>&nbsp;</td><TD class=xtab align=right colspan=2><TABLE width=100%><TR><TD width=25 class=xtab align=left>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold)+'</td><td class=xtab align=right>'+tx('Total')+':&nbsp;<br>'+tx('Cost')+':&nbsp;</td><td class=xtab align=left><SPAN id=ptwgt_' + c + '>0</span><br><SPAN id=ptwgc_' + c + '>'+addCommas(maxCost)+'</span></td>';
				m += '<TD class=xtab align=right>' + strButton20(tx("Set Defences"), 'onclick="ptButWildSet(' + c + ')"') + '</td></tr></table></td></tr>';
			} else {
				m += '<TR><TD class=xtab colspan=8 align=center><br>'+tx('No wilds')+'</td></tr>';
			}
			m += '</table>';
		}
		ById('wildContent').innerHTML = m;
		ById('ptwref').addEventListener('click', t.show, false);
		ById('ptwm_all').addEventListener('change', function (e) {
			var wm = document.getElementsByClassName('btWildMerc');
			for (var m in wm) {
				if (wm[m].id) {	wm[m].value = e.target.value; }
			}
		}, false);
		ById('ptwx_all').addEventListener('click', function (e) {
			var wx = document.getElementsByClassName('btWildMax');
			for (var x in wx) {
				if (wx[x].id) { t.e_butMaxTraps(wx[x]);	}
			}
		}, false);
		t.updateGold();
	},

	e_abandon: function (tileId, xCoord, yCoord, cityId) {
		var t = Tabs.Wilds;
		AbandonWild(tileId, xCoord, yCoord, cityId, t.show);
	},

	e_butWildSet: function (c) {
		var t = Tabs.Wilds;
		var totTraps = 0;
		var cid = Cities.cities[c].id;
		t.buildList = { cityId: cid, list: [] };
		for (var w = 0; w < t.wildList[c].length; w++) {
			var wild = Seed.wilderness['city' + cid]['t' + t.wildList[c][w][0]];
			var wildDef = Seed.wildDef['t' + t.wildList[c][w][0]];
			if (wildDef == undefined || !wildDef)
				wildDef = { fort60Count: 0, mercLevel: 0 };
			var numTraps = parseInt(ById('ptwt_' + c + '_' + w).value, 10);
			if (isNaN(numTraps)) numTraps = 0;
			totTraps += numTraps;
			if (numTraps > 0) t.buildList.list.push(['T', wild.tileId, numTraps]);
			var mercId = ById('ptwm_' + c + '_' + w).value;
			if (wildDef.mercLevel != mercId) t.buildList.list.push(['M', wild.tileId, mercId, wildDef.mercLevel]);
		}
		var totCost = totTraps * 200;
		if (totCost > parseInt(Seed.citystats['city' + cid].gold[0])) {
			ById('ptwgc_' + c).innerHTML = '<SPAN class=boldRed>' + addCommasInt(totCost) + '</span>';
			return;
		}
		if (t.buildList.list.length == 0)
			return;
		t.setCurtain(true);
		var popDiv = t.setPopup(true);
		popDiv.innerHTML = '<TABLE class=xtab width=100% height=100%><TR><TD align=center>\
          <DIV class=divHeader>'+tx('Setting Wilderness Defences')+'</div>\
          <DIV id=ptWildBuildDiv style="padding:10px; height:225px; max-height:225px; overflow-y:auto"></div>\
          </td></tr><TR><TD align=center>' + strButton20(uW.g_js_strings.commonstr.cancel, 'id=ptWildCancel') + '</td></tr></table>';
		ById('ptWildCancel').addEventListener('click', t.e_Cancel, false);
		t.processQue(null);
	},
	e_Cancel: function () {
		var t = Tabs.Wilds;
		t.setCurtain(false);
		t.setPopup(false);
		t.show();
	},
	processQue: function (errMsg) {
		var t = Tabs.Wilds;
		var what = t.buildList.list.shift();
		var div = ById('ptWildBuildDiv');
		if (what == null || errMsg) {
			if (errMsg)
				div.innerHTML += '<BR><SPAN style="white-space:normal;" class=boldRed>ERROR: ' + errMsg + '</span>';
			else
				div.innerHTML += tx('Done')+'.<BR>';
			ById('ptWildCancel').firstChild.innerHTML = uW.g_js_strings.commonstr.close;
			return;
		}
		if (div.innerHTML != '')
			div.innerHTML += tx('Done')+'.<BR>';
		var wild = Seed.wilderness['city' + t.buildList.cityId]['t' + what[1]];
		if (what[0] == 'T') {
			div.innerHTML += Cities.byID[t.buildList.cityId].name+': '+tx('Building')+' '+what[2]+' '+tx('traps on wilderness at')+' '+wild.xCoord+','+wild.yCoord+' ... ';
			t.postBuyTraps(t.buildList.cityId, what[1], what[2], t.processQue);
		} else {
			div.innerHTML += Cities.byID[t.buildList.cityId].name+': '+tx('Setting')+' '+t.mercNames[what[2]]+' '+tx('Mercenaries on wilderness at')+' '+wild.xCoord+','+wild.yCoord+' ... ';
			t.postHireMercs(t.buildList.cityId, what[1], what[2], what[3], t.processQue);
		}
	},
	setPopup: function (onoff) {
		var t = Tabs.Wilds;
		if (onoff) {
			var div = document.createElement('div');
			div.id = 'ptWildPop';
			div.style.backgroundColor = Options.Colors.Panel;
			div.style.zindex = mainPop.div.zIndex + 2;
			div.style.opacity = '1';
			div.style.border = '3px outset black';
			div.style.width = (GlobalOptions.btWinSize.x-200)+'px';
			div.style.height = '300px';
			div.style.display = 'block';
			div.style.position = 'absolute';
			div.style.top = '100px';
			div.style.left = '100px';
			t.myDiv.appendChild(div);
			return div;
		} else {
			t.myDiv.removeChild(ById('ptWildPop'));
		}
	},
	setCurtain: function (onoff) {
		var t = Tabs.Wilds;
		if (onoff) {
			var off = getAbsoluteOffsets(t.myDiv);
			var curtain = document.createElement('div');
			curtain.id = 'ptWildCurtain';
			curtain.style.zindex = mainPop.div.zIndex + 1;
			curtain.style.backgroundColor = "#000000";
			curtain.style.opacity = '0.5';
			curtain.style.width = (t.myDiv.clientWidth+4) + 'px';
			curtain.style.height = (t.myDiv.clientHeight+4) + 'px';
			curtain.style.display = 'block';
			curtain.style.position = 'absolute';
			curtain.style.top = off.top + 'px';
			curtain.style.left = off.left + 'px';
			t.myDiv.appendChild(curtain);
		} else {
			t.myDiv.removeChild(ById('ptWildCurtain'));
		}
	},
	e_butMaxTraps: function (e) {
		var t = Tabs.Wilds;
		var c = e.id.substr(5, 1);
		var w = e.id.substr(7);
		var inp = ById('ptwt_' + c + '_' + w);
		inp.value = t.wildList[c][w][1];
		t.e_inpTraps(inp);
	},
	e_inpTraps: function (e) {
		var t = Tabs.Wilds;
		var c = e.id.substr(5, 1);
		var w = e.id.substr(7);
		if (isNaN(e.value) || e.value < 0 || e.value > t.wildList[c][w][1]) {
			e.value = '';
			e.style.backgroundColor = '#ff8888';
		}
		else {
			e.style.backgroundColor = null;
		}
		var tot = 0;
		for (var i = 0; i < t.wildList[c].length; i++) {
			var val = parseInt(ById('ptwt_' + c + '_' + i).value, 10);
			if (isNaN(val))	val = 0;
			tot += val;
		}
		ById('ptwgc_' + c).innerHTML = addCommasInt(tot * 200);
	},
	updateGold: function () {
		var t = Tabs.Wilds;
		for (var c = 0; c < Cities.numCities; c++) {
			var e = ById('ptwgt_' + c + '');
			if (e) {
				e.innerHTML = addCommasInt(Seed.citystats['city' + Cities.cities[c].id].gold[0]);
			}
		}
	},
	postBuyTraps: function (cid, tid, quant, notify) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cid;
		params.tid = tid;
		params.quant = quant;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/buyWildTraps.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (!Seed.wildDef["t" + tid])
						Seed.wildDef["t" + tid] = {
							tileId: tid,
							fort60Count: 0,
							mercLevel: 0
						};
					Seed.wildDef["t" + tid].fort60Count = parseInt(Seed.wildDef["t" + tid].fort60Count) + parseInt(quant);
				}
				if (notify)
					notify(rslt.errorMsg);
			},
			onFailure: function () {
				if (notify)
					notify('AJAX ERROR');
			},
		});
	},
	postHireMercs: function (cid, tid, newLevel, oldLevel, notify) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cid;
		params.tid = tid;
		params.lv = newLevel;
		params.olv = oldLevel;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/hireWildMerc.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (!Seed.wildDef["t" + tid])
						Seed.wildDef["t" + tid] = {
							tileId: tid,
							fort60Count: 0,
							mercLevel: 0
						};
					Seed.wildDef["t" + tid].mercLevel = newLevel;
				}
				if (notify)
					notify(rslt.errorMsg);
			},
			onFailure: function () {
				if (notify)
					notify('AJAX ERROR');
			},
		});
	},

	EverySecond : function () {
		var t = Tabs.Wilds;

		if (tabManager.currentTab.name == 'Wilds' && Options.btWinIsOpen){
			t.LoopCounter = t.LoopCounter + 1;

			if (t.LoopCounter >= 5) { // refresh display every 5 seconds
				t.LoopCounter = 0;
				t.updateGold();
			}
		}

	},
}

/*********************************** Knights Tab ***********************************/

Tabs.Knights = {
	tabOrder: 1050,
	tabLabel: 'Knights',
	myDiv: null,
	displayTimer: null,
	action: 0,
	MaxSkill:300,
	knightRoles : [
		['Foreman', 'politics', 'Pol'],
		['Marshall', 'combat', 'Com'],
		['Alchemyst', 'intelligence', 'Int'],
		['Steward', 'resourcefulness', 'Res'],
	],

	init: function (div) {
		var t = Tabs.Knights;
		t.myDiv = div;
		uWExportFunction('ptAssignSkill', Tabs.Knights.clickedAssignPoints);
		uWExportFunction('ptAssignTunes', Tabs.Knights.clickedAssignTune);
		uWExportFunction('ptButDismiss', Tabs.Knights.postDismissKnight);
		uWExportFunction('ptButAppoint', Tabs.Knights.postAppointKnight);
		uWExportFunction('ptBoostKnight', Tabs.Knights.BoostKnight);

		var m = '<DIV class=divHeader align=center>'+tx('KNIGHT ADMINISTRATION')+'</DIV>';
		m += '<div align=center><br>'+tx('Quick Assign Knight Skill')+':&nbsp;<input style="height:20px;font-size:9px;" type=button value="'+tx('Add Default Skills')+'" id="ptknight_def">&nbsp;<input style="height:20px;font-size:9px;" type=button value="'+tx('Add Combat Skills')+'" id="ptknight_com"></div><br>';
		m += '<DIV id=ptknightdiv style="max-height:700px; height:700px; width:'+GlobalOptions.btWinSize.x+'px;overflow-x:scroll;overflow-y:scroll"></div>';

		t.myDiv.innerHTML = m;

		ById('ptknight_com').addEventListener('click', function () {
			t.action = 1;
			t.show();
		}, false);
		ById('ptknight_def').addEventListener('click', function () {
			t.action = 2;
			t.show();
		}, false);
	},

	hide: function () {
		var t = Tabs.Knights;
		clearTimeout(t.displayTimer);
	},

	show: function () {
		var t = Tabs.Knights;
		clearTimeout(t.displayTimer);

		function _dispKnight(roleId, knight, numcid) {
			var rid = roleId;
			if (roleId == null)
				rid = 1;
			var sty = 'class=evenRow ';
			if (row++ % 2)
				sty = 'class=oddRow ';
			m = '<TR ' + sty + 'valign=top align=left><TD class=xtab><B>' + (roleId == null ? '' : tx(t.knightRoles[rid][0])) + '</b></td><TD class=xtab align=left>';
			if (knight == null) {
				m += '--------</td><TD class=xtab colspan=14>&nbsp;</td></tr>';
			}
			else {
				var kimg = uW.cm.KnightsModel.getSrc(knight.knightName);
				var level = parseInt(Math.sqrt(parseInt(knight.experience) / 75)) + 1;
				var unpoints = level - parseInt(knight.skillPointsApplied);
				var salary = (parseInt(knight.skillPointsApplied) + 1) * 20;
				totSalary += salary;
				var ass = '';
				if (knight.knightStatus == 10) {
					ass = '<TD class=xtab align=left colspan=4>'+tx('Marching')+'</td>';
				}
				else {
					if (unpoints > 0) {
						if (t.action == 2) {
							t.clickedAssignPoints(null, cid, knight.knightId, rid);
						}
						if (t.action == 1) {
							t.clickedAssignPoints(null, cid, knight.knightId, 1);
						}
						var assignable = false;
						for (var i = 0; i < 4; i++) {
							var sty = 'padding-left:1px;';
							if (i == rid) // bold it
								sty += 'font-weight:bold;color:#116654';
							ass += '<td width=26 class=xtab align="left" style="'+sty+'">';
							if (knight[t.knightRoles[i][1]] < t.MaxSkill) {
								assignable = true;
								ass += '<a title="' + uW.g_js_strings.modaltitles.assignskills + '" style="' + sty + '" onclick="ptAssignSkill(this,' + cid + ',' + knight.knightId + ',' + i + ')">[' + tx(t.knightRoles[i][2]) + ']</a>';
							} else {
								ass += '<span style="color: #006600; font-size: 10px; font-weight: normal;">(max)</span>';
							}
							ass += '</td>';
						}
						if (assignable) {
							unpoints = '<SPAN class="boldRed">' + unpoints + '</span>';
						}
					}
					else { ass = '<TD class=xtab colspan=4>&nbsp;</td>'; }
				}
				var skills = [];
				for (var i = 0; i < 4; i++) {
					var skillamount = knight[t.knightRoles[i][1]];
					var boosted = false;
					switch (i) {
						case 0:
							if (knight.politicsBoostExpireUnixtime > unixTime()) { skillamount *= 1.25; boosted=true;}
							break;
						case 1:
							if (knight.combatBoostExpireUnixtime > unixTime()) { skillamount *= 1.25; boosted=true;}
							break;
						case 2:
							if (knight.intelligenceBoostExpireUnixtime > unixTime()) { skillamount *= 1.25; boosted=true;}
							break;
						case 3:
							if (knight.resourcefulnessBoostExpireUnixtime > unixTime()) { skillamount *= 1.25; boosted=true;}
							break;
					}
					if (boosted) {skillamount='<span style="color:#080;">'+Math.floor(skillamount)+'</span>';}
					if (i == rid)
						skills[i] = '<B>' + skillamount + '</b>';
					else
						skills[i] = skillamount;
				}
				var item211 = "";
				var item221 = "";
				var item231 = "";
				var item241 = "";
				if (Seed.items.i211 && Seed.items.i211>0) item211 = '<a onclick="ptBoostKnight(this,'+Cities.cities[numcid].id+','+knight.knightId+',\'i211\')"><img height=20 style="vertical-align:text-top;" src="'+RoseImage+'" title="'+uW.itemlist.i211.name+' (Pol:25%) ('+Seed.items.i211+')"></a>';
				if (Seed.items.i221 && Seed.items.i221>0) item221 = '<a onclick="ptBoostKnight(this,'+Cities.cities[numcid].id+','+knight.knightId+',\'i221\')"><img height=20 style="vertical-align:text-top;" src="'+GauntletImage+'" title="'+uW.itemlist.i221.name+' (Com:25%) ('+Seed.items.i221+')"></a>';
				if (Seed.items.i231 && Seed.items.i231>0) item231 = '<a onclick="ptBoostKnight(this,'+Cities.cities[numcid].id+','+knight.knightId+',\'i231\')"><img height=20 style="vertical-align:text-top;" src="'+MirrorImage+'" title="'+uW.itemlist.i231.name+' (Int:25%) ('+Seed.items.i231+')"></a>';
				if (Seed.items.i241 && Seed.items.i241>0) item241 = '<a onclick="ptBoostKnight(this,'+Cities.cities[numcid].id+','+knight.knightId+',\'i241\')"><img height=20 style="vertical-align:text-top;" src="'+GlovesImage+'" title="'+uW.itemlist.i241.name+' (Res:25%) ('+Seed.items.i241+')"></a>';
				m += '<img style="vertical-align:text-top;" width=20 src="'+kimg+'"><a title="'+tx('Assign Role')+'" onclick="pthideMe();citysel_click(document.getElementById(\'citysel_' + (numcid + 1) + '\'));setTimeout (function (){ assign_role_modal(' + knight.knightId + ');return false;}, 500);">' + knight.knightName + '</td>';
				m += '<TD class=xtab style="vertical-align:middle;">'+skills[0]+'</td><TD class=xtab style="vertical-align:middle;">'+skills[1]+'</td><TD class=xtab style="vertical-align:middle;">'+skills[2]+'</td><TD class=xtab style="vertical-align:middle;">'+skills[3]+'</td>';
				m += '<TD class=xtab align=left>'+item211+'&nbsp;'+item221+'&nbsp;'+item231+'&nbsp;'+item241+'</td><TD width=26 class=xtab align=left>' + unpoints + '</td>' + ass + '<TD class=xtab align=right><a title="'+tx('Experience Boost')+'" onclick="pthideMe();citysel_click(document.getElementById(\'citysel_' + (numcid + 1) + '\'));setTimeout (function (){ xpBoost_modal(' + knight.knightId + ');return false; }, 500);">' + level + '</a></td>';
				m += '<td class=xtab align=right><a title="'+tx('Loyalty Boost')+'" onclick="pthideMe();citysel_click(document.getElementById(\'citysel_' + (numcid + 1) + '\'));setTimeout (function (){ loyalBoost_modal(' + knight.knightId + ');return false;}, 500);">' + knight.loyalty + '</a></td>';
				m += '<TD class=xtab align=right>' + addCommas(salary) + '</td><TD align=center class=xtab>'+strButton8(tx('Dismiss'), 'onclick="ptButDismiss(' + knight.knightId + ',' + cid + ')"')+'</td></tr>';
			}
			return m;
		}

		var totSalary = 0;
		var m = '<TABLE width=98% cellspacing=0 align=center>';
		for (var c = 0; c < Cities.numCities; c++) {
			var cid = Cities.cities[c].id;
			m += '<TR><TD class=xtab colspan=16><DIV class=divHeader align=center>' + Cities.cities[c].name + '</div></td></tr>\
				<TR><TD class=xtabHD width=70>'+tx('Role')+'</td><TD class=xtabHD width=140 align=left>'+uW.g_js_strings.commonstr.nametx+'</td><TD class=xtabHD width=26>'+tx('Pol')+'</td><TD class=xtabHD width=26>'+tx('Com')+'</td>\
				<TD class=xtabHD width=26>'+tx('Int')+'</td><TD class=xtabHD width=26>'+tx('Res')+'</td><TD class=xtabHD align=center width=40>'+tx('Boosts')+'</td><TD class=xtabHD width=90 align=center colspan=5>'+htmlTitleLine(tx('Unassigned'))+'</td><TD class=xtabHD align=right width=35>'+uW.g_js_strings.commonstr.level+'</td><td class=xtabHD align=right width=40>'+tx('Loyalty')+'</td><TD class=xtabHD width=40 align=right>'+tx('Salary')+'</td><TD class=xtabHD width=70 align=center>'+tx('Dismiss')+'</td></tr>';
			totSalary = 0;
			var did = {};
			var row = 0;
			for (var i = 0; i < t.knightRoles.length; i++) {
				var leader = Seed.leaders['city' + cid][t.knightRoles[i][1] + 'KnightId'];
				if (leader == 0)
					m += _dispKnight(i, null, c);
				else {
					m += _dispKnight(i, Seed.knights['city' + cid]['knt' + leader], c);
					did['knt' + leader] = true;
				}
			}
			var list = [];
			for (var k in Seed.knights['city' + cid]) {
				if (!did[k])
					list.push(Seed.knights['city' + cid][k]);
			}
			list.sort(function (a, b) {
				return parseInt(b.combat) - parseInt(a.combat)
			});
			for (var i = 0; i < list.length; i++)
				m += _dispKnight(null, list[i], c, cid);
			m += '<TR align=right><TD class=xtab>&nbsp;</td><td class=xtab align=left>'+strButton14(tx('Appoint a Knight'), 'onclick="pthideMe();ptButAppoint('+c+')"')+'</td><TD class=xtab align=right colspan=12><B>'+tx('Total Salary')+':</b></td><TD class=xtab align=right><b>'+addCommas(totSalary)+'</b></td></tr>';
			m += '<TR align=right><TD class=xtab colspan=16>&nbsp;</td></tr>';
		}
		m += '</table><br>';
		ById('ptknightdiv').innerHTML = m;
		t.action = 0;
		t.displayTimer = setTimeout(t.show, 10000);
	},

	postDismissKnight: function (kid, cid) {
		var t = Tabs.Knights;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cid;
		params.kid = kid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fireKnight.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					delete Seed.knights["city" + cid]["knt" + kid];
					t.show();
				}
			},
		});
	},
	postAppointKnight: function (city) {
		var t = Tabs.Knights;
		SelectCity(city+1);
		uW.cm.KnightsAppointView.render();
	},
	clickedAssignPoints: function (e, cid, kid, rid) {
		var t = Tabs.Knights;
		clearTimeout(t.displayTimer);
		var knight = Seed.knights['city' + cid]['knt' + kid];
		if (knight.knightStatus == 10 && e != null) {
			var row = e.parentNode.parentNode;
			row.childNodes[7].innerHTML = tx('Marching');
			return;
		}
		sk = [];
		var unassigned = parseInt(Math.sqrt(parseInt(knight.experience) / 75)) + 1 - parseInt(knight.skillPointsApplied);
		for (var i = 0; i < 4; i++) {
			sk[i] = parseInt(knight[t.knightRoles[i][1]]);
			if (i == rid)
				sk[i] += unassigned;
			if (sk[i] > t.MaxSkill) {
				sk[i] = t.MaxSkill;
				unassigned = parseInt(t.MaxSkill - parseInt(knight[t.knightRoles[i][1]]));
			}
		}
		if (unassigned == 0) return;
		if (e != null) {
			var row = e.parentNode.parentNode;
			for (var i = row.cells.length - 1; i >= 1; i--)
				row.deleteCell(i);
			var newCell = row.insertCell(-1);
			newCell.colSpan = 15;
			newCell.align = 'left';
			newCell.style.padding = '1px 1px 1px 1px';
			var div = document.createElement('div');
			div.style.backgroundColor = '#ffffff';
			div.style.textAlign = 'center';
			div.style.border = '1px solid';
			div.style.width = '100%';
			div.style.whiteSpace = 'normal';
			newCell.appendChild(div);
			div.innerHTML = tx('Assigning')+' ' + unassigned + ' '+tx('skill points to')+' ' + t.knightRoles[rid][1] + ' ... ';
		}
		t.postSkillPoints(cid, kid, sk[0], sk[1], sk[2], sk[3], function (r) {
			t.postDone(r, div)
		});
	},
	postDone: function (rslt, div) {
		var t = Tabs.Knights;
		clearTimeout(t.displayTimer);
		if (rslt.ok) {
			if (div) div.innerHTML += '<B>Done.</b>';
			t.displayTimer = setTimeout(t.show, 5000);
		} else {
			if (div) div.innerHTML += '<BR><SPAN class=boldRed>ERROR: ' + rslt.errorMsg + '</span>';
			t.displayTimer = setTimeout(t.show, 5000);
		}
	},
	postSkillPoints: function (cid, kid, pol, com, int, res, notify) {
		var t = Tabs.Knights;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cid;
		params.kid = kid;
		params.p = pol;
		params.c = com;
		params.i = int;
		params.r = res;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/skillupKnight.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var knight = Seed.knights["city" + cid]["knt" + kid];
					var up = pol + com + int + res - knight.politics - knight.combat - knight.intelligence - knight.resourcefulness;
					knight.politics = pol;
					knight.combat = com;
					knight.intelligence = int;
					knight.resourcefulness = res;
					knight.skillPointsApplied = (parseInt(knight.skillPointsApplied) + up).toString();
				}
				if (notify)
					notify(rslt);
			},
			onFailure: function () {
				if (notify)
					notify(rslt);
			},
		});
	},
	BoostKnight : function (e,cid,kid,item) {
		var t = Tabs.Knights;
		if (e != null) {
			var row = e.parentNode.parentNode;
			for (var i = row.cells.length - 1; i >= 1; i--)
				row.deleteCell(i);
			var newCell = row.insertCell(-1);
			newCell.colSpan = 15;
			newCell.align = 'left';
			newCell.style.padding = '1px 1px 1px 1px';
			var div = document.createElement('div');
			div.style.backgroundColor = '#ffffff';
			div.style.textAlign = 'center';
			div.style.border = '1px solid';
			div.style.width = '100%';
			div.style.whiteSpace = 'normal';
			newCell.appendChild(div);
			div.innerHTML = tx('Applying')+' ' + uW.itemlist[item].name + ' ... ';
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.iid = item.substring(1);
		params.cid = cid;
		params.kid = kid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/boostKnight.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					switch (item) {
						case "i211":
							uW.seed.knights["city" + cid]["knt" + kid].politicsBoostExpireUnixtime = rslt.expiration.toString();
							break;
						case "i221":
							uW.seed.knights["city" + cid]["knt" + kid].combatBoostExpireUnixtime = rslt.expiration.toString();
							break;
						case "i231":
							uW.seed.knights["city" + cid]["knt" + kid].intelligenceBoostExpireUnixtime = rslt.expiration.toString();
							break;
						case "i241":
							uW.seed.knights["city" + cid]["knt" + kid].resourcefulnessBoostExpireUnixtime = rslt.expiration.toString();
							break;
						default:
							return false
					}
					uW.seed.items[item] = parseInt(uW.seed.items[item]) - 1;
					uW.ksoItems[item.substring(1)].subtract();
					uW.cm.MixPanelTracker.track("item_use", {
						item : uW.itemlist[item].name,
						usr_gen : Seed.player.g,
						usr_byr : Seed.player.y,
						usr_ttl : uW.titlenames[Seed.player.title],
						distinct_id : uW.tvuid
					})
					t.show();
				}
			},
		},true); // noretry
	},

}

/***************************** Nomad Tab *******************************/

Tabs.Nomad = {
	tabOrder: 2120,
	tabLabel : 'Nomads',
	tabColor : 'brown',
	myDiv : null,
	timer : null,
	ValidNomad: false,
	tradeItem: 0,
	tradeItemQuantity: 0,
	prizes: [],
	eventId :0,
	isBusy: false,
	NomadMessage: tx('Fetching details from server')+'...',
	Options: {
		x: 0,
		y: 0,
		TradeAmount: 0,
		TradeInterval: 1,
		TradeInProgress: false,
		KeepAmount: 0,
		NomadRunning: false,
		ItemsWon: {},
		NumTrades : 0,
		LastNomadReport : 0,
	},

	init : function (div) {
		var t = Tabs.Nomad;
		t.myDiv = div;

		if (!Options.NomadOptions) {
			Options.NomadOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.NomadOptions.hasOwnProperty(y)) {
					Options.NomadOptions[y] = t.Options[y];
				}
			}
		}

		t.eventFetchNomadDetails(t.checkAutoTrade);
	},

	checkAutoTrade: function () {
		var t = Tabs.Nomad;
		if (Options.NomadOptions.TradeInProgress) {
			t.start();
		};
	},

	eventFetchNomadDetails: function (notify) {
		var t = Tabs.Nomad;
		NomadMessage = tx('Fetching Nomad details from server')+'...';
		t.ValidNomad = false;
		t.tradeItem = 0;
		t.tradeItemQuantity = 0;
		t.eventId = 0;
		t.prizes = [];
		t.show();

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.xCoord = Options.NomadOptions.x;
		params.yCoord = Options.NomadOptions.y;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getNomadCamp.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (!rslt.ok){
					if (GlobalOptions.btPowerBar) {
						var elem = ById("bttcNomad");
						elem.setAttribute("style","display:none");
					}
					if (rslt.msg) { t.NomadMessage = rslt.msg; }
					else { t.NomadMessage = tx('No Nomad Camp Details Available'); }
					Options.NomadOptions.TradeInProgress = false;
					Options.NomadOptions.NomadRunning = false;
					t.GenerateReport();
					saveOptions();
					t.show();
					return;
				}
				var elem = ById("bttcNomad");
				elem.setAttribute("style","color:#f00");
				t.ValidNomad = true;
				t.tradeItem = rslt.tradeItem;
				t.tradeItemQuantity = rslt.tradeItemQuantity;
				t.eventId = rslt.eventId;
				t.prizes = rslt.prizes["2"];
				t.show();
				if (notify) { notify();}
			},
			onFailure: function () {
				t.NomadMessage = 'AJAX Error';
				Options.NomadOptions.TradeInProgress = false;
				Options.NomadOptions.NomadRunning = false;
				t.GenerateReport();
				saveOptions();
				t.show();
			},
		},true);
	},

	eventDoTrade: function () {
		var t = Tabs.Nomad;

		var div = $("pbnomad_info");

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.eventId = t.eventId;
		params.lootType = 2;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/nomadTrade.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt && rslt.ok){
					uW.cm.NomadModel.removeItems(t.tradeItem, t.tradeItemQuantity);
					uW.update_inventory(rslt.bonusItems);
					for (var lootId in rslt.bonusItems) {
						if (lootId) {
							if (div) { div.innerHTML = '<span>'+tx('You received')+' '+rslt.bonusItems[lootId]+' '+uW.itemlist["i"+lootId].name+'</span><br>'+div.innerHTML; }
							else {
								actionLog('Auto-Trade: '+rslt.bonusItems[lootId]+' '+uW.itemlist["i"+lootId].name,'NOMAD');
								Options.NomadOptions.NumTrades++;
								if(Options.NomadOptions.ItemsWon[lootId]) { Options.NomadOptions.ItemsWon[lootId] += parseInt(rslt.bonusItems[lootId]); }
								else { Options.NomadOptions.ItemsWon[lootId] = parseInt(rslt.bonusItems[lootId]); }
								saveOptions();
							}
						}
					}
					Options.NomadOptions.TradeAmount = Options.NomadOptions.TradeAmount-t.tradeItemQuantity;
					setTimeout(t.nextqueue, 500);
				}
				else {
					if (div) {
						div.innerHTML = '<span style="color:#800;">'+rslt.msg+'</span><br>'+div.innerHTML;
						ById('pbNomadCancel').firstChild.innerHTML = uW.g_js_strings.commonstr.close;
					}
					else { actionLog('Auto-Trade Error: '+rslt.msg,'NOMAD'); }
					Options.NomadOptions.TradeInProgress = false;
					saveOptions();
					t.isBusy = false;
				}
			},
			onFailure: function () {
				if (div) {
					div.innerHTML = '<span style="color:#800;">'+tx('Server Error')+'!</span><br>'+div.innerHTML;
					ById('pbNomadCancel').firstChild.innerHTML = uW.g_js_strings.commonstr.close;
				}
				else { actionLog('AJAX Error!','NOMAD'); }
				Options.NomadOptions.TradeInProgress = false;
				saveOptions();
				t.isBusy = false;
			},
		},true);
	},

	show : function (){
		var t = Tabs.Nomad;

		if (!t.isBusy || Options.NomadOptions.NomadRunning) {
			var m = '<DIV class=divHeader align=center>'+tx('NOMAD CAMP AUTO TRADE')+'</div><br>';
			m += '<div style="min-height:350px;"><TABLE align=center width=98% cellpadding=0 cellspacing=0 class=xtab>';
			m += '<TR class=divHide><td colspan=4>X:&nbsp<INPUT id=btNomadX size=3 maxlength=3 type=text value="'+Options.NomadOptions.x+'">&nbsp&nbsp&nbspY:&nbsp<INPUT id=btNomadY size=3 maxlength=3 type=text value="'+Options.NomadOptions.y+'">&nbsp;&nbsp;&nbsp;<INPUT id=btNomadRefresh type=submit value="'+tx('Refresh Nomad Details')+'">&nbsp;('+tx('Co-ordinates currently not required, but added to the tab in case they are in the future')+')</td></tr>';
			m += '<TR><td colspan=4>&nbsp;</td></tr>';
			if (t.ValidNomad) {
				m += '<TR><td align=right>'+tx('Trade Item')+':&nbsp;</td><td colspan=3><b>'+uW.itemlist["i"+t.tradeItem].name+'</b></td></tr>';
				m += '<TR><td align=right>'+tx('Quantity per Trade')+':&nbsp;</td><td colspan=3><b>'+t.tradeItemQuantity+'</b></td></tr>';
				m += '<TR><td align=right>'+tx('You Own')+':&nbsp;</td><td><b>'+(Seed.items["i"+t.tradeItem]?Seed.items["i"+t.tradeItem]:0)+'</b></td><td align=right width=120px>'+tx('Amount to Keep')+':</td><td><INPUT size=4 id=btNomadItemKeep type=text value="'+Options.NomadOptions.KeepAmount+'">&nbsp;&nbsp;<a title="'+tx('automatically trade items')+'" id=pbautonomadstate class="inlineButton btButton '+(Options.NomadOptions.NomadRunning?'red14':'blue14')+'"><span id=pbautonomadlabel style="width:30px;display:inline-block;text-align:center;">'+(Options.NomadOptions.NomadRunning?tx('Off'):tx('Auto'))+'</span></a></td></tr>';
				m += '<TR><td  colspan=2 align=right>&nbsp;</td><td align=right>'+tx('Amount to Trade')+':</td><td><INPUT size=4 id=btNomadItemAmount type=text value="'+Options.NomadOptions.TradeAmount+'">&nbsp;<INPUT id=btNomadTrade type=submit value="'+tx('Manual Trade')+'"></td></tr>';

				m += '<TR><td colspan=4>&nbsp;</td></tr>';
				m += '<TR><td>&nbsp;</td><td colspan=3><b>'+tx('Possible Prizes from Trade')+':-</b></td></tr>';

				for (var p in t.prizes) {
					if (t.prizes[p].itemId) {
						m += '<TR><td>&nbsp;</td><td colspan=3>'+t.prizes[p].quantity + ' ' +uW.itemlist["i"+t.prizes[p].itemId].name+'</td></tr>';
					}
				}
			}
			else {
				m += '<TR><td align=center colspan=4>'+t.NomadMessage+'</td></tr>';
			}
			m += '</table></div><br>';

			t.myDiv.innerHTML = m;
			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

			ById('btNomadRefresh').addEventListener('click', function() {t.eventFetchNomadDetails();},false);

			ById('btNomadX').addEventListener('keyup', function(){ if (isNaN(ById('btNomadX').value)) ById('btNomadX').value='';}, false);
			ById('btNomadY').addEventListener('keyup', function(){ if (isNaN(ById('btNomadY').value)) ById('btNomadY').value='';}, false);

			ById('btNomadX').addEventListener('change', function(){Options.NomadOptions.x = ById('btNomadX').value;} , false);
			ById('btNomadY').addEventListener('change', function(){Options.NomadOptions.y = ById('btNomadY').value;} , false);

			if (t.ValidNomad) {
				ById('btNomadTrade').addEventListener('click', function() {t.start();},false);

				ChangeIntegerOption('NomadOptions','btNomadItemAmount','TradeAmount');
				ChangeIntegerOption('NomadOptions','btNomadItemKeep','KeepAmount');

				ById('pbautonomadstate').addEventListener('click', function(){
					t.toggleAutoNomadState(this);
				}, false);

				if (Options.NomadOptions.NomadRunning) {
					ById('btNomadItemAmount').disabled = true;
					ById('btNomadTrade').disabled = true;
				}
			}
		}
		else { // reset curtain position..
			t.setCurtain(true);
		}
	},

	toggleAutoNomadState: function(obj){
		var t = Tabs.Nomad;
		obj = ById('pbautonomadlabel');
		if (Options.NomadOptions.NomadRunning == true) {
			Options.NomadOptions.NomadRunning = false;
			t.GenerateReport();
			obj.innerHTML = tx("Auto");
			jQuery('#pbautonomadstate').removeClass("red14");
			jQuery('#pbautonomadstate').addClass("blue14");
			ById('btNomadItemAmount').disabled = false;
			ById('btNomadTrade').disabled = false;
		}
		else {
			Options.NomadOptions.NomadRunning = true;
			Options.NomadOptions.ItemsWon = {};
			Options.NomadOptions.NumTrades = 0;
			obj.innerHTML = tx("Off");
			jQuery('#pbautonomadstate').addClass("red14");
			jQuery('#pbautonomadstate').removeClass("blue14");
			ById('btNomadItemAmount').disabled = true;
			ById('btNomadTrade').disabled = true;
			Options.NomadOptions.LastNomadChecked = 0;
		}
		saveOptions();
	},

	setPopup: function (onoff) {
		var t = Tabs.Nomad;
		if (onoff) {
			var div = document.createElement('div');
			div.id = 'ptNomadPop';
			div.style.backgroundColor = '#fff';
			div.style.zindex = mainPop.div.zIndex + 2;
			div.style.opacity = '1';
			div.style.border = '3px outset black';
			div.style.width = (GlobalOptions.btWinSize.x-200)+'px';
			div.style.height = '300px';
			div.style.display = 'block';
			div.style.position = 'absolute';
			div.style.top = '100px';
			div.style.left = '100px';
			t.myDiv.appendChild(div);
			return div;
		} else {
			t.myDiv.removeChild(ById('ptNomadPop'));
		}
	},

	setCurtain: function (onoff) {
		var t = Tabs.Nomad;
		if (onoff) {
			var off = getAbsoluteOffsets(t.myDiv);
			var curtain = ById('ptNomadCurtain');
			if (!curtain) {
				curtain = document.createElement('div');
				curtain.id = 'ptNomadCurtain';
				curtain.style.zindex = mainPop.div.zIndex + 1;
				curtain.style.backgroundColor = "#000000";
				curtain.style.opacity = '0.5';
				curtain.style.display = 'block';
				curtain.style.position = 'absolute';
				t.myDiv.appendChild(curtain);
			}
			curtain.style.width = (t.myDiv.clientWidth+4) + 'px';
			curtain.style.height = (t.myDiv.clientHeight+4) + 'px';
			curtain.style.top = off.top + 'px';
			curtain.style.left = off.left + 'px';
		} else {
			t.myDiv.removeChild(ById('ptNomadCurtain'));
		}
	},

	e_Cancel: function () {
		var t = Tabs.Nomad;
		if (t.isBusy) {
			t.isBusy = false;
			var div = $("pbnomad_info");
			div.innerHTML += "<br><span>"+tx('Cancelled')+"!</span>";
			ById('pbNomadCancel').firstChild.innerHTML = uW.g_js_strings.commonstr.close;
			return;
		}
		t.setCurtain(false);
		t.setPopup(false);
		t.show();
	},

	start : function (){
		var t = Tabs.Nomad;

		Options.NomadOptions.TradeAmount = parseIntNan(Options.NomadOptions.TradeAmount);
		if(Options.NomadOptions.TradeAmount >= t.tradeItemQuantity) {
			Options.NomadOptions.TradeInProgress = true;
			saveOptions();

			t.isBusy = true;
			t.setCurtain(true);
			var popDiv = t.setPopup(true);
			popDiv.innerHTML = '<TABLE class=xtab width=100% height=100%><TR><TD align=center>\
			<DIV class=divHeader align=center>'+tx('Trading with the Nomads')+'...</div>\
			<DIV id=pbnomad_info style="padding:10px; height:225px; max-height:225px; overflow-y:auto"></div>\
			</td></tr><TR><TD align=center>' + strButton20(uW.g_js_strings.commonstr.cancel, 'id=pbNomadCancel') + '</td></tr></table>';
			ById('pbNomadCancel').addEventListener('click', t.e_Cancel, false);
			t.nextqueue();
		}
		else {
			Options.NomadOptions.TradeInProgress = false;
			saveOptions();
		}
	},

	nextqueue : function (){
		var t = Tabs.Nomad;
		if(!t.isBusy)
			return;
		var div = $("pbnomad_info");
		if(Options.NomadOptions.TradeAmount < t.tradeItemQuantity){
			if (div) {
				div.innerHTML = "<span>"+tx('Completed')+"!</span><br>"+div.innerHTML;
				ById('pbNomadCancel').firstChild.innerHTML = 'Close';
			}

			Options.NomadOptions.TradeInProgress = false;
			saveOptions();

			t.isBusy = false;
			return;
		}
		t.eventDoTrade();
	},

	EverySecond : function () {
		var t = Tabs.Nomad;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // Check Nomad Item Limit and refresh display every 2 seconds
			if (Options.NomadOptions.NomadRunning) {
				if ((!Options.NomadOptions.TradeInProgress) && (Options.NomadOptions.LastNomadChecked+60) < now) { // check once a minute, but not if already trading!
					t.checkNomadItemLimit();
				}
				if (tabManager.currentTab.name == 'Nomad' && Options.btWinIsOpen){
					t.show();
				}
			}
		}
	},

	checkNomadItemLimit : function () {
		var t = Tabs.Nomad;
		if (!Options.NomadOptions.NomadRunning) return;
		if (!t.ValidNomad) return;
		if (isNaN(t.tradeItem) || t.tradeItem == 0) return;
		var item = uW.ksoItems[t.tradeItem];
		if (item) {
			var useamount = parseIntNan(item.count - parseIntNan(Options.NomadOptions.KeepAmount));
			if (useamount>=t.tradeItemQuantity) { // automatically set trade amount to excess amount...
				Options.NomadOptions.TradeAmount = useamount;
				Options.NomadOptions.TradeInProgress = true;
				saveOptions();
				t.isBusy = true;
				t.nextqueue();
			}
		}
		var now = unixTime();
		Options.NomadOptions.LastNomadChecked = now;
		saveOptions();
	},

	GenerateReport : function () {
		var t = Tabs.Nomad;
		var now = unixTime();

		var total = Options.NomadOptions.NumTrades;
		if (total > 0) {
			var message = tx('Nomad Camp Trade Report')+' %0A';

			message +='%0A';
			message += tx('Items received from trading since previous report')+': %0A';
			for (var z in Options.NomadOptions.ItemsWon) {
				message += uW.ksoItems[z].name+' x '+Options.NomadOptions.ItemsWon[z]+'%0A';
			}

			message +='%0A';
			message += tx('Total Number of Trades')+': '+total+'%0A';

			var params = uW.Object.clone(uW.g_ajaxparams);
			params.emailTo = Seed.player['name'];
			params.subject = tx("Nomad Camp Trade Report");

			params.message = message;
			params.requestType = "COMPOSED_MAIL";

			new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					if (rslt.ok) {
						DeleteLastMessage();
						Options.NomadOptions.ItemsWon = {};
						Options.NomadOptions.NumTrades = 0;
						saveOptions();
					}
				},
			});

			Options.NomadOptions.LastNomadReport = now;
			saveOptions();
		}
	},

}

/**************************** Inventory Tab ****************************************/
Tabs.Inventory = {
	tabOrder: 1110,
	tabLabel: 'Inventory',
	myDiv: null,
	general: [],
	throne: [],
	champ: [],
	speedup: [],
	combat: [],
	resources: [],
	chest: [],
	court: [],
	jewels: [],
	alliance: [],
	type: null,
	queue:[],
	isBusy:false,
	counter:0,
	max:0,
	city_holder : 0,
	mightarray : {1300:200,1301:1000,1310:200,1311:1000,1320:400,1321:2000,1330:400,1331:2000,1340:450,1341:2250,1350:600,1351:3000,1352:20000,1360:750,1361:3750,1370:700,1371:3500,1372:17500,1380:600,1381:3000,1390:900,1391:4500,1392:9000,1400:450,1401:1800,1410:500,1411:2000,1412:10,1413:25,1414:50,1415:75,1416:100,1417:150,1418:10,1419:25,1420:50,1421:75,1422:100,1423:150,1424:20,1425:50,1426:100,1427:150,1428:200,1429:300,1430:20,1431:50,1432:100,1433:150,1434:200,1435:300,1436:30,1437:75,1438:150,1439:225,1440:300,1441:40,1442:100,1443:200,1444:300,1445:400,1446:50,1447:125,1448:250,1449:375,1450:500,1451:70,1452:175,1453:350,1454:525,1455:1350,1456:60,1457:150,1458:300,1459:450,1460:900,1461:90,1462:225,1463:450,1464:675,1465:1350,1466:90,1467:225,1468:675,1469:900,1470:1350,1471:100,1472:250,1473:750,1474:1000,1475:1500,1476:10000,1477:50000,1478:1950,1479:6500,1480:9750,1481:13000,1482:2250,1483:7500,1484:11250,1485:15000,1486:1950,1487:6500,1488:9750,1489:13000,1490:2250,1491:7500,1492:11250,1493:15000,1494:7500,1495:11250,1496:15000,1497:2250,1498:2250,1499:7500,1500:11250,1501:1500,1502:3000,1503:10000,1504:15000,1505:20000,1506:3300,1507:11000,1508:16500,1509:22000,1510:2250,1511:7500,1512:11250,1513:15000,1514:3300,1515:11000,1516:16500,1517:22000,1518:2250,1519:7500,1520:11250,1521:15000,1522:3750,1523:12500,1524:18750,1525:25000,1530:7500,1531:25000,1532:37500,1533:50000,1540:1500,1541:5000,1542:7500,1543:10000,1544:4050,1545:13500,1546:20250,1547:27000,1548:3750,1549:25000,1550:3750,1551:25000,1552:3750,1553:25000,1554:2250,1555:7500,1556:11250,1557:15000},

	init: function(div){
		var t = Tabs.Inventory;
		t.myDiv = div;

		var RJcallback = new CalterUwFunc("cm.ThroneController.useRandomJewel",[['ai,','function(rslt) {btShowRandomJewelPrize(rslt);ai(rslt);},'],
																				['w(','cm.ThroneController.updateJewelCount('],
																				['q(','cm.ThroneController.jewelName(']]);
		RJcallback.setEnable(true);
		uWExportFunction ('btShowRandomJewelPrize', Tabs.Inventory.ShowRandomJewelPrize);

		var m = '<DIV class=divHeader align=center>'+tx('INVENTORY')+'</div>';
		m += '<TABLE align=center width=98% cellpadding=0 cellspacing=0 class=xtab>';
		m += '<TR><TD colspan=3><br><div align=center><input type=button id=pbinventory_general value="'+uW.g_js_strings.commonstr.general+'" />';
		m += '<input type=button id=pbinventory_throne value="'+tx('Throne')+'" />&nbsp;';
		m += '<input type=button id=pbinventory_champ value="'+tx('Champ')+'" />&nbsp;';
		m += '<input type=button id=pbinventory_speedup value="'+uW.g_js_strings.commonstr.speedup+'" />&nbsp;';
		m += '<input type=button id=pbinventory_combat value="'+uW.g_js_strings.commonstr.combat+'" />&nbsp;';
		m += '<input type=button id=pbinventory_resources value="'+uW.g_js_strings.commonstr.resources+'" />&nbsp;';
		m += '<input type=button id=pbinventory_chest value="'+uW.g_js_strings.commonstr.chest+'" />&nbsp;';
		m += '<input type=button id=pbinventory_court value="'+uW.g_js_strings.commonstr.court+'" />&nbsp;';
		m += '<input type=button id=pbinventory_jewels value="'+uW.g_js_strings.jewel.jewels+'" />&nbsp;';
		m += '<input type=button id=pbinventory_alliance value="'+uW.g_js_strings.commonstr.alliance+'" />&nbsp;';
		m += '</div><br></td></tr></table>';

		m += '<DIV class=divHeader align=center>'+tx('USE ITEMS')+'</div><br>';
		m += '<TABLE align=center width=98% cellpadding=0 cellspacing=0 class=xtab>';
		m += '<tr><td>'+tx('Target City')+':&nbsp;<span id=pbinventory_cityselect></span></td><TD><input type=checkbox id=pbinventory_useall />'+tx('Default to Use All items')+'<BR><input type=checkbox id=pbinventory_useable checked />'+tx('Show only Useable Items')+'</td>';
		m += '<TD align=right>' + strButton20(tx('Use Selected Items'), 'id=pbinventory_start') + '</td></tr></table>';

		m += '<DIV class=divHeader id=pbinventory_type_header align=center>&nbsp;</div>';
		m += '<DIV align=center id=pbinventory style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;height:500px;overflow-y:auto;">&nbsp;</div><br>';

		t.myDiv.innerHTML = m;
		t.sort_Items();

		t.city = new CdispCityPicker ('pbinventory_city', ById('pbinventory_cityselect'), true, null, Cities.byID[uW.currentcityid].idx);

		$("pbinventory_general").addEventListener('click', t.display_general, false);
		$("pbinventory_throne").addEventListener('click', t.display_throne, false);
		$("pbinventory_champ").addEventListener('click', t.display_champ, false);
		$("pbinventory_speedup").addEventListener('click', t.display_speedup, false);
		$("pbinventory_combat").addEventListener('click', t.display_combat, false);
		$("pbinventory_resources").addEventListener('click', t.display_resources, false);
		$("pbinventory_chest").addEventListener('click', t.display_chest, false);
		$("pbinventory_court").addEventListener('click', t.display_court, false);
		$("pbinventory_jewels").addEventListener('click', t.display_jewels, false);
		$("pbinventory_alliance").addEventListener('click', t.display_alliance, false);
		$("pbinventory_start").addEventListener('click', t.start, false);
		$("pbinventory_useable").addEventListener('click', t.show, false);
		$("pbinventory_general").click();
	},

	sort_Items : function (){
		var t = Tabs.Inventory;

		t.general = [];
		t.throne = [];
		t.champ = [];
		t.speedup = [];
		t.combat = [];
		t.resources = [];
		t.chest = [];
		t.court = [];
		t.jewels = [];
		t.alliance = [];

		for(var k in uW.ksoItems){
			var item = uW.ksoItems[k];
			if(item.count > 0){
				if((item.category == 0 || item.category == 1) && item.subCategory == 2){ t.throne.push(item); }
				if((item.category == 0 || item.category == 1) && item.subCategory == 28){ t.champ.push(item); }
				if(item.category == 1 && item.subCategory != 28 && item.subCategory != 2){ t.general.push(item); }
				if(item.category == 2){	t.speedup.push(item); }
				if(item.category == 3){	t.combat.push(item); }
				if(item.category == 4){	t.resources.push(item);	}
				if(item.category == 5){	t.chest.push(item);	}
				if(item.category == 6){	t.court.push(item);	}
				if(item.category == 7){	t.jewels.push(item); }
				if(item.category == 8){	t.alliance.push(item); }
			}
		}
	},

	display_general : function (){
		var t = Tabs.Inventory;
		t.type = "general";
		var div = ById("pbinventory");
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.general.toUpperCase();
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.general.length;k++){
			var item = t.general[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_general' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_general_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_throne : function (){
		var t = Tabs.Inventory;
		t.type = "throne";
		var div = ById("pbinventory");
		ById('pbinventory_type_header').innerHTML = tx('Throne').toUpperCase();
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.throne.length;k++){
			var item = t.throne[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_throne' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_throne_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_champ : function (){
		var t = Tabs.Inventory;
		t.type = "champ";
		var div = ById("pbinventory");
		ById('pbinventory_type_header').innerHTML = tx('Champ').toUpperCase();
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		t.champ.sort(function(a, b){ return Tabs.Reference.UniqueCHItems[a.id].Set-Tabs.Reference.UniqueCHItems[b.id].Set });
		for (var k=0;k<t.champ.length;k++){
			var item = t.champ[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_champ' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_champ_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_speedup : function (){
		var t = Tabs.Inventory;
		t.type = "speedup";
		var div = ById("pbinventory");
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.speedup.toUpperCase();
		var count = 0;
		var totaltime = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<tr><td align=center colspan=11><b>"+tx('Total Speedup Time')+":&nbsp;<span id=pbinvspeedtime>&nbsp;</span></b></td></tr>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TH class=xtabHD align=right>"+uW.g_js_strings.commonstr.time+"</td><TD width='20px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TH class=xtabHD align=right>"+uW.g_js_strings.commonstr.time+"</th></tr><TR>";
		for (var k=0;k<t.speedup.length;k++){
			var item = t.speedup[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			var itemtime = 0;
			if (SpeedupArray[parseInt(item.id) - 1])
				itemtime = SpeedupArray[parseInt(item.id) - 1] * item.count;
			m += (count%2 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_speedup' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_speedup_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += "<TD align=right>"+((itemtime!=0)?uW.timestr(itemtime):'')+"</td>";
			m += (count%2 == 1)?"</tr>":"";
			count++;
			totaltime = totaltime+itemtime;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		var tm = ById('pbinvspeedtime')
		if (tm) tm.innerHTML = uW.timestr(totaltime);

		t.setEventHandlers();
	},

	display_combat : function (){
		var t = Tabs.Inventory;
		t.type = "combat";
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.combat.toUpperCase();
		var div = ById("pbinventory");
		var count = 0;
		var totalmight = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<tr><td align=center colspan=11><b>"+tx('Total Troop Might')+":&nbsp;<span id=pbinvcombatmight>&nbsp;</span><span id=pbinvselmight>&nbsp;</span></b></td></tr>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TH class=xtabHD align=right>"+tx('Might')+"</td><TD width='20px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TH class=xtabHD align=right>"+tx('Might')+"</th></tr><TR>";
		for (var k=0;k<t.combat.length;k++){
			var item = t.combat[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			var might = 0;
			if (t.mightarray[item.id])
				might = t.mightarray[item.id] * item.count;
			m += (count%2 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_combat' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 class='pb_inv_combat' name="+item.id+" id='pb_inv_combat_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += "<TD align=right>"+((might!=0)?addCommas(might):'')+"</td>";
			m += (count%2 == 1)?"</tr>":"";
			count++;
			totalmight = totalmight+might;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		var tm = ById('pbinvcombatmight')
		if (tm) tm.innerHTML = addCommas(totalmight);

		t.setEventHandlers();
		t.setCombatEventHandlers();
	},

	display_resources : function (){
		var t = Tabs.Inventory;
		t.type = "resources";
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.resources.toUpperCase();
		var div = ById("pbinventory");
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.resources.length;k++){
			var item = t.resources[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_resources' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_resources_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},
	display_chest : function (){
		var t = Tabs.Inventory;
		t.type = "chest";
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.chest.toUpperCase();
		var div = ById("pbinventory");
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.chest.length;k++){
			var item = t.chest[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_chest' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_chest_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_court : function (){
		var t = Tabs.Inventory;
		t.type = "court";
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.court.toUpperCase();
		var div = ById("pbinventory");
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.court.length;k++){
			var item = t.court[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_court' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_court_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_jewels : function (){
		var t = Tabs.Inventory;
		t.type = "jewel";
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.jewel.jewels.toUpperCase();
		var div = ById("pbinventory");
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='20px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.jewels.length;k++){
			var item = t.jewels[k];
			if(!item.usable && ById('pbinventory_useable').checked) continue;
			m += (count%2 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,40)+"</span></td>";
			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_jewel' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_jewel_"+item.id+"' disabled /></td>";
			}
			else {
				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
			}
			m += "<TD>"+item.count+"</td>";
			m += (count%2 == 1)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	display_alliance : function (){
		var t = Tabs.Inventory;
		t.type = "alliance";
		var div = ById("pbinventory");
		ById('pbinventory_type_header').innerHTML = uW.g_js_strings.commonstr.alliance.toUpperCase();
		var count = 0;
		var m = "<TABLE class=xtab cellspacing=0>";
		m += "<TR><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th><TD width='10px'>&nbsp;</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.nametx+"</th><TH colspan=2 align=left class=xtabHD>&nbsp;"+uW.g_js_strings.commonstr.use+"</th><TH class=xtabHD>"+uW.g_js_strings.commonstr.count+"</th></tr><TR>";
		for (var k=0;k<t.alliance.length;k++){
			var item = t.alliance[k];
//			if(!item.usable && ById('pbinventory_useable').checked) continue; // assume ALL usable, they seem to have messed this up!
			m += (count%3 == 0)?"<TR>":"<TD width='10px'>&nbsp;</td>";
			m += "<TD><img width='20px' height='20px' src='"+getItemImageURL(item.id)+"' /> <span class='tooldesc' id='pb_inv_desc"+item.id+"'>"+item.name.substr(0,30)+"</span></td>";
//			if (item.usable) {
				m += "<TD><input type=checkbox class='pbinv_alliance' data-ft='"+JSON.stringify(item).replace(/\'/g, "")+"' /></td>";
				m += "<TD><input type=text size=2 id='pb_inv_alliance_"+item.id+"' disabled /></td>";
//			}
//			else {
//				m += "<TD>&nbsp;</td><TD>&nbsp;</td>";
//			}
			m += "<TD>"+item.count+"</td>";
			m += (count%3 == 2)?"</tr>":"";
			count++;
		}
		m += "</table>";
		div.innerHTML = (count!=0)?m:'<br><CENTER>'+tx('No useable items in this category')+'</CENTER><br>';

		t.setEventHandlers();
	},

	setCombatEventHandlers : function () {
		var t = Tabs.Inventory;
		var nodes = document.getElementsByClassName("pb_inv_"+t.type);
		if(nodes.length > 0){
			for(var i=0; i<nodes.length; i++){
				nodes[i].addEventListener('change', function(e){
					t.CalculateSelectedMight();
				},false);
			}
		}
		var nodes = document.getElementsByClassName("pbinv_"+t.type);
		if(nodes.length > 0){
			for(var i=0; i<nodes.length; i++){
				nodes[i].addEventListener('change', function(e){
					t.CalculateSelectedMight();
				},false);
			}
		}
	},

	setEventHandlers : function () {
		var t = Tabs.Inventory;
		var nodes = document.getElementsByClassName("pbinv_"+t.type);
		if(nodes.length > 0){
			for(var i=0; i<nodes.length; i++){
				nodes[i].addEventListener('click', function(e){
					var item = JSON.parse(e.target.getAttribute("data-ft"));
					if(e.target.checked) {
						$("pb_inv_"+t.type+"_"+item.id).disabled = false;
						$("pb_inv_"+t.type+"_"+item.id).value = $("pbinventory_useall").checked?item.count:1;
					}
					else {
						$("pb_inv_"+t.type+"_"+item.id).disabled = true;
						$("pb_inv_"+t.type+"_"+item.id).value = '';
					}
				},false);
			}
		}

		// set up tooltips

		var cItems = ById('pbinventory').getElementsByClassName('tooldesc');
		for (var i = 0; i < cItems.length; i++) { t.createToolTip(cItems[i]); }
	},

	createToolTip : function (elem) {
		var t = Tabs.Inventory;
		var h = elem.id.substring(11);
		var TT = "";
		if (uW.ksoItems[h]) { TT = uW.ksoItems[h].description; }
		if (TT!="") {
			jQuery('#'+elem.id).children("span").remove();
			jQuery('#'+elem.id).append('<span class="tooltip" style="white-space: pre-line; word-wrap: break-word;">'+TT+'</span>');
		}
	},

	CalculateSelectedMight : function () {
		var t = Tabs.Inventory;
		var selectedmight = 0;
		var nodes = document.getElementsByClassName("pb_inv_"+t.type);
		if(nodes.length > 0){
			for(var i=0; i<nodes.length; i++){
				var might = 0;
				var item_id = nodes[i].name;
				if (t.mightarray[item_id]) {
					might = t.mightarray[item_id] * parseIntNan(nodes[i].value);
				}
				selectedmight = selectedmight+might;
			}
		}
		var sm = ById('pbinvselmight')
		if (sm) {
			if (selectedmight != 0) { sm.innerHTML = ', Selected Might: '+addCommas(selectedmight);}
			else {sm.innerHTML = "";};
		}
	},

	e_total : function (){
		var t = Tabs.Inventory;
		return t.max;
	},

	start : function (){
		var t = Tabs.Inventory;
		t.queue = [];
		var nodes = document.getElementsByClassName("pbinv_"+t.type);
		for(var i = 0; i < nodes.length; i++){
			if(nodes[i].checked){
				try{
					t.queue.push(JSON.parse(nodes[i].getAttribute("data-ft")));
				} catch (e){
					logerr(e);
				}
			}
		}

		if(t.queue.length > 0) {
			t.isBusy = true;
			t.setCurtain(true);
			var popDiv = t.setPopup(true);
			popDiv.innerHTML = '<TABLE class=xtab width=100% height=100%><TR><TD align=center>\
			<DIV class=divHeader>Using Selected Inventory Items</div>\
			<DIV id=pbinventory_info style="padding:10px; height:225px; max-height:225px; overflow-y:auto"></div>\
			</td></tr><TR><TD align=center>' + strButton20(uW.g_js_strings.commonstr.cancel, 'id=pbInvCancel') + '</td></tr></table>';
			ById('pbInvCancel').addEventListener('click', t.e_Cancel, false);
			t.nextqueue();
		}
	},

	nextqueue : function (){
		var t = Tabs.Inventory;
		if(!t.isBusy)
			return;
		var div = $("pbinventory_info");
		if(t.queue.length > 0){
			var item = t.queue[0];
			t.counter = 0;
			t.max = parseIntNan($("pb_inv_"+t.type+"_"+item.id).value);
			div.innerHTML = "<span id='pb_inv_info_"+item.id+"'>"+tx('Using item')+" "+item.name+" <span id='pb_inv_info_count_"+item.id+"'>1</span> "+uW.g_js_strings.commonstr.of+" <span id='pb_inv_info_max_"+item.id+"'>"+t.max+"</span>. <span id='pb_inv_info_extra_"+item.id+"'> </span></span><br>"+div.innerHTML;
		} else {
			div.innerHTML = "<span>"+uW.g_js_strings.commonstr.completedexc+"</span><br>"+div.innerHTML;
			ById('pbInvCancel').firstChild.innerHTML = uW.g_js_strings.commonstr.close;
			t.isBusy = false;
			return;
		}

		// special use items - e.g. Merlins Tokens...

		if (item.id==599) {
			t.useMerlin();
		}
		else {
			var MultiUse = CM.ItemIdentifier.canUseMultiple(item);
			if (item.category==7) MultiUse = true; // jewels you can multi-use!

			if (item.id==30130 || item.id==30131 || item.id==30132 || item.id==30133 || item.id==30134) { // random jewels don't multi-use - do it the old way...
				MultiUse = false;
			}
			if(ItemMultiUseController.ItemController.isAvailable && MultiUse)
				t.useitem_multi();
			else
				t.useitem();
		}
	},

	useitem_multi : function (){
		var t = Tabs.Inventory;
		if(!t.isBusy) return;
		var item = t.queue[0];
		$("pb_inv_info_count_"+item.id).innerHTML = t.max;
		ItemMultiUseController.UseItems(item.id,t.max,t.city.city.id);
		setTimeout(t.wait_new, 250, 0);
	},

	wait_new : function (){
		var t = Tabs.Inventory;
		if(!t.isBusy)
			return;
		var item = t.queue[0];
		item = uW.ksoItems[item.id];
		t.queue[0] = item;
		$("pb_inv_info_extra_"+item.id).innerHTML = tx("Done")+".";
		t.queue.shift();
		setTimeout(t.nextqueue, 500);
	},

	useitem : function (){
		var t = Tabs.Inventory;
		if(!t.isBusy) { return; }
		var item = t.queue[0];
		if(t.city.city.id){ //Set to use city specified
			t.city_holder = uW.currentcityid;
			uW.currentcityid = t.city.city.id;
		}
		CM.ItemController.use(item.id);
		if(t.city.city.id){ //Set currentcity to old value
			uW.currentcityid = t.city_holder;
		}
		setTimeout(t.wait, 500, 0);
	},

	wait : function (retries){
		var t = Tabs.Inventory;
		if(!t.isBusy)
			return;
		var item = t.queue[0];
		item = uW.ksoItems[item.id];
		t.queue[0] = item;
		t.counter++;
		$("pb_inv_info_count_"+item.id).innerHTML = t.counter;
		$("pb_inv_info_extra_"+item.id).innerHTML = '('+(t.max-t.counter)+' Left)';
		if(t.counter >= t.max){
			$("pb_inv_info_extra_"+item.id).innerHTML = tx("Done")+".";
			t.queue.shift();
			setTimeout(t.nextqueue, 1000);
			return;
		}
		$("pb_inv_info_extra_"+item.id).innerHTML = tx("Done")+". "+tx("Wait for 1 second")+"..";
		if (item.id==599) {
			setTimeout(t.useMerlin, 500);
		}
		else {
			setTimeout(t.useitem, 500);
		}
	},

	show: function (){
		var t = Tabs.Inventory;
		t.sort_Items();
		if (t.type=='general') { t.display_general(); }
		else {
			if (t.type=='throne') { t.display_throne(); }
			else {
				if (t.type=='champ') { t.display_champ(); }
				else {
					if (t.type=='speedup') { t.display_speedup(); }
					else {
						if (t.type=='combat') { t.display_combat(); }
						else {
							if (t.type=='resources') { t.display_resources(); }
							else {
								if (t.type=='chest') { t.display_chest(); }
								else {
									if (t.type=='court') { t.display_court(); }
									else {
										if (t.type=='jewel') { t.display_jewels(); }
										else {
											if (t.type=='alliance') { t.display_alliance(); }
										}
									}
								}
							}
						}
					}
				}
			}
		}
	},

	setPopup: function (onoff) {
		var t = Tabs.Inventory;
		if (onoff) {
			var div = document.createElement('div');
			div.id = 'ptInvPop';
			div.style.backgroundColor = Options.Colors.Panel;
			div.style.zindex = mainPop.div.zIndex + 2;
			div.style.opacity = '1';
			div.style.border = '3px outset black';
			div.style.width = (GlobalOptions.btWinSize.x-200)+'px';
			div.style.height = '300px';
			div.style.display = 'block';
			div.style.position = 'absolute';
			div.style.top = '100px';
			div.style.left = '100px';
			t.myDiv.appendChild(div);
			return div;
		} else {
			t.myDiv.removeChild(ById('ptInvPop'));
		}
	},
	setCurtain: function (onoff) {
		var t = Tabs.Inventory;
		if (onoff) {
			var off = getAbsoluteOffsets(t.myDiv);
			var curtain = document.createElement('div');
			curtain.id = 'ptInvCurtain';
			curtain.style.zindex = mainPop.div.zIndex + 1;
			curtain.style.backgroundColor = "#000000";
			curtain.style.opacity = '0.5';
			curtain.style.width = (t.myDiv.clientWidth+4) + 'px';
			curtain.style.height = (t.myDiv.clientHeight+4) + 'px';
			curtain.style.display = 'block';
			curtain.style.position = 'absolute';
			curtain.style.top = off.top + 'px';
			curtain.style.left = off.left + 'px';
			t.myDiv.appendChild(curtain);
		} else {
			t.myDiv.removeChild(ById('ptInvCurtain'));
		}
	},
	e_Cancel: function () {
		var t = Tabs.Inventory;
		t.isBusy = false;
		t.setCurtain(false);
		t.setPopup(false);
		t.show();
	},

	useMerlin : function () {
		var t = Tabs.Inventory;
		if(!t.isBusy) { return; }
		var div = $("pbinventory_info");

		var params=uW.Object.clone(uW.g_ajaxparams);
		params.ftflag=0;
		new MyAjaxRequest(uW.g_ajaxpath+"ajax/magicalboxPreview.php"+uW.g_ajaxsuffix,{
			method:"post",
			parameters:params,
			onSuccess:function(rslt){
				if(rslt.ok){
					var params=uW.Object.clone(uW.g_ajaxparams);
					new MyAjaxRequest(uW.g_ajaxpath+"ajax/magicalboxPick.php"+uW.g_ajaxsuffix,{
						method:"post",
						parameters:params,
						onSuccess:function(rslt){
							if(rslt.ok){
								var itemId=rslt.prize;
								if (Seed.items["i"+itemId]) {
									Seed.items["i"+itemId] = parseInt(Seed.items["i"+itemId])+1;
									uW.ksoItems[itemId].add();
								}
								else {
									Seed.items["i"+itemId] = 1;
									uW.ksoItems[itemId].add();
								}
								var NumTokens = parseInt(Seed.items.i599);
								if (NumTokens > 0) {
									NumTokens = NumTokens - 1;
									Seed.items.i599 = (NumTokens).toString();
									uW.ksoItems[599].subtract();
								}
								div.innerHTML = "<span>"+tx('You won')+" "+uW.itemlist["i"+rslt.prize].name+"!</span><br>"+div.innerHTML;
							}
							else {
								div.innerHTML = "<span>"+rslt.msg+"</span><br>"+div.innerHTML;
							}
						}
					},true);
				}
				else {
					div.innerHTML = "<span>"+rslt.msg+"</span><br>"+div.innerHTML;
				}
			}
		},true);
		setTimeout(t.wait, 500, 0);
	},

	ShowRandomJewelPrize : function (rslt) {
		var t = Tabs.Inventory;
		var div = $("pbinventory_info");
		if (!div) return;
		if (rslt.ok) {
			var prize = {
				quality : rslt.q,
				id : rslt.e,
				count : rslt.count
			};
			var JName = CM.ThroneController.jewelName(prize);
			if (prize.count>1) JName = prize.count+' '+JName;
			div.innerHTML = "<span>"+tx('You won')+" "+JName+"!</span><br>"+div.innerHTML;
		}
		else {
			if (rslt.msg) {
				div.innerHTML = "<span>"+rslt.msg+"</span><br>"+div.innerHTML;
			}
		}
	},
}

/**************************** Scout Reports Tab ****************************************/
Tabs.ScoutReports = {
    tabLabel: 'Scout Rpts',
	tabOrder: 2090,
	tabColor : 'brown',
	Options: {
		gold: 0,
		r1: 0,
		r2: 0,
		r3: 0,
		r4: 0,
		On: false,
		lost: false,
		friendly: true,
		hostile: true,
	},
	LoopCounter : 0,
	lrpts: null,
	myDiv: null,
	deleting: false,
	pageNo: 1,
	maxpages : 10,
	scandelay : 30, // 30 seconds between scans
	tocheck: new Array(),

	init: function(div) {
		var t = Tabs.ScoutReports;
        t.myDiv = div;

		if (!Options.ScoutOptions) {
			Options.ScoutOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.ScoutOptions.hasOwnProperty(y)) {
					Options.ScoutOptions[y] = t.Options[y];
				}
			}
		}

		setTimeout(t.startdeletereports, 10*1000);
	},

	e_toggleswitch: function(obj) {
		var t = Tabs.ScoutReports;
		if (Options.ScoutOptions.On) {
			obj.value = tx("Delete = OFF");
			Options.ScoutOptions.On = false;
		} else {
			obj.value = tx("Delete = ON");
			Options.ScoutOptions.On = true;
		}
		saveOptions();
	},

	startdeletereports: function() {
		var t = Tabs.ScoutReports;
		if (!t.deleting) {
			if (Options.ScoutOptions.On) {
				t.deleting = true;
				t.listreports(t.pageNo, t.checkreports);
			}
			else {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000);
			}
		}
	},

	listreports: function(pageNo, callback) {
		var t = Tabs.ScoutReports;
		t.pageNo = pageNo;

		if (!Options.ScoutOptions.On) {
			t.deleting = false;
			t.pageNo = 1;
			setTimeout(t.startdeletereports, t.scandelay*1000);
			return;
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		if (t.pageNo >= 1) params.pageNo = t.pageNo;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/listReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function(rslt) { callback(rslt);	},
			onFailure: function() {	callback();	},
		});
	},

	checkreports: function(rslt) {
		var t = Tabs.ScoutReports;
		if (!rslt.ok || (rslt.arReports.length < 1)) {
			t.deleting = false;
			t.pageNo = 1;
			setTimeout(t.startdeletereports, t.scandelay*1000);
			return;
		}
		var reports = rslt.arReports;
		var totalPages = rslt.totalPages;
		if (rslt.totalPages > t.maxpages) var totalPages = t.maxpages;
		var deletes1 = new Array();
		for (var k in reports) {
			if (Options.ScoutOptions.On) {
				if (reports[k].marchType == 3) {
					if (reports[k].side1PlayerId == uW.tvuid) {
						var rptdel = false;
						if (reports[k].side0AllianceId && Options.ScoutOptions.friendly == true) {
							for (var l in uW.seed.allianceDiplomacies.friendlyToThem) {
								if(reports[k].side0AllianceId == uW.seed.allianceDiplomacies.friendlyToThem[l].allianceId) {
									if (GlobalOptions.ExtendedDebugMode) actionLog('deleting friendly scout' + k.substr(2),'SCOUT');
									deletes1.push(k.substr(2));
									rptdel = true;
								}
							}
							for (var l in uW.seed.allianceDiplomacies.friendly) {
								if(reports[k].side0AllianceId == uW.seed.allianceDiplomacies.friendly[l].allianceId) {
									if (GlobalOptions.ExtendedDebugMode) actionLog('deleting friendly scout ' + k.substr(2),'SCOUT');
									deletes1.push(k.substr(2));
									rptdel = true;
								}
							}
						};
						if (reports[k].side0AllianceId && Options.ScoutOptions.hostile == true) {
							for (var l in uW.seed.allianceDiplomacies.hostile) {
								if(reports[k].side0AllianceId == uW.seed.allianceDiplomacies.hostile[l].allianceId) {
									if (GlobalOptions.ExtendedDebugMode) actionLog('not deleting hostile scout ' + k.substr(2),'SCOUT');
									rptdel = true; // use this flag to pretend we have already deleted report, so don't check!!!!
								}
							}
						};
					};
					if (rptdel == false) { t.tocheck.push(k.substr(2)); }
				};
			}
		};
		if(deletes1.length > 0){
			t.deleteCheckedReports(deletes1);
		} else {
			if (t.pageNo <= totalPages) {
				t.deleting = false;
				t.pageNo++;
				setTimeout(t.startdeletereports, 5*1000); // next page in 5 seconds
				return;
			}
			else {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000);
				return;
			}
		}
	},

	deleteCheckedReports : function(deletes1){
		var t = Tabs.ScoutReports;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.s0rids = '';
		params.s1rids = deletes1.join(",");
		params.cityrids = '';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/deleteCheckedReports.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if(rslt.ok){
					if (deletes1.length>0) {
						for (var j=0;j<deletes1.length;j++) {
							delete ReportCache[deletes1[j]];
							delete ReportDetailCache[deletes1[j]];
						}
					}
					Seed.newReportCount = parseInt(Seed.newReportCount) - parseInt(deletes1.length);
					if (GlobalOptions.ExtendedDebugMode) actionLog('Deleted: ' +parseInt(deletes1.length)+' scout reports','SCOUT');
					t.deleting = false;
					setTimeout(t.startdeletereports, 5*1000); // next page in 5 seconds
				}
				else {
					t.deleting = false;
					t.pageNo = 1;
					setTimeout(t.startdeletereports, t.scandelay*1000); // error - start again
				}
			},
			onFailure: function () {
				t.deleting = false;
				t.pageNo = 1;
				setTimeout(t.startdeletereports, t.scandelay*1000); // error - start again
			},
		});
	},

	fetchreport: function() {
		var t = Tabs.ScoutReports;

		// safety net .. if no options set then don't delete the report, otherwise ALL scouts would be deleted always and we'd have a load of people moaning...
		if (!Options.ScoutOptions.lost && (Number(Options.ScoutOptions.gold) == 0) && (Number(Options.ScoutOptions.r1) == 0) && (Number(Options.ScoutOptions.r2) == 0) && (Number(Options.ScoutOptions.r3) == 0) && (Number(Options.ScoutOptions.r4) == 0)) return;

		if (t.tocheck.length > 0) {
			rpId = t.tocheck.shift();
			FetchReportDetail(rpId,1,function(rslt) {
				if (rslt) {
					if (rslt.hasOwnProperty("winner") && rslt.winner == 0) {
						if (!Options.ScoutOptions.lost) {
							if (GlobalOptions.ExtendedDebugMode) actionLog('deleting defeated scout report ' + rpId,'SCOUT');
							deleteCheckedReport(rpId);
						}
					}
					else {
						if (rslt.rsc) {
							var rsc = rslt.rsc;
							var topush = true;

							if (Number(Options.ScoutOptions.gold) > 0) {
								if (rslt.gld && Number(rslt.gld) > Number(Options.ScoutOptions.gold)) {
									topush = false;
								}
							}
							if (Number(Options.ScoutOptions.r1) > 0) {
								if (Number(rsc.r1) > Number(Options.ScoutOptions.r1)) {
									topush = false;
								}
							}
							if (Number(Options.ScoutOptions.r2) > 0) {
								if (Number(rsc.r2) > Number(Options.ScoutOptions.r2)) {
									topush = false;
								}
							}
							if (Number(Options.ScoutOptions.r3) > 0) {
								if (Number(rsc.r3) > Number(Options.ScoutOptions.r3)) {
									topush = false;
								}
							}
							if (Number(Options.ScoutOptions.r4) > 0) {
								if (Number(rsc.r4) > Number(Options.ScoutOptions.r4)) {
									topush = false;
								}
							}

							if (topush == true) { deleteCheckedReport(rpId); }
						}
					}
				}
			});
		}
	},

	show: function() {
		var t = Tabs.ScoutReports;

		var m = '<DIV class=divHeader align=center>'+tx('AUTO-DELETE OWN SCOUT REPORTS')+'</div><br><div align=center>';
		if (Options.ScoutOptions.On) {
			m += '<INPUT id=FSrpts type=submit value="'+tx('Delete = ON')+'">';
		} else {
			m += '<INPUT id=FSrpts type=submit value="'+tx('Delete = OFF')+'">';
		}
		m += '<br>&nbsp;</div><DIV class=divHeader align=center>'+tx('DELETE OPTIONS')+'</div><br>';
		m += '&nbsp;&nbsp;&nbsp;<b>'+tx("DON'T")+'</b> '+tx('Delete Scout Reports if')+'...';
		m += '<br><table class=xtab><tr><td colspan=2>&nbsp;</td><td><input id=frlost type=checkbox ' + (Options.ScoutOptions.lost ? 'CHECKED' : '') + '>&nbsp;'+tx('Your scouts were defeated in battle')+'</td></tr>';
		m += '<tr><td>&nbsp;&nbsp;<b>'+tx('OR')+'</b></td><td align="right">'+tx('Gold is more than')+' :&nbsp;</td><td><INPUT id=frGold type=text value=' + Options.ScoutOptions.gold + '></td></tr>';
		m += '<tr><td>&nbsp;&nbsp;<b>'+tx('OR')+'</b></td><td align="right">'+tx('Food is more than')+' :&nbsp;</td><td><INPUT id=frR1 type=text value=' + Options.ScoutOptions.r1 + '></td></tr>';
		m += '<tr><td>&nbsp;&nbsp;<b>'+tx('OR')+'</b></td><td align="right">'+tx('Wood is more than')+' :&nbsp;</td><td><INPUT id=frR2 type=text value=' + Options.ScoutOptions.r2 + '></td></tr>';
		m += '<tr><td>&nbsp;&nbsp;<b>'+tx('OR')+'</b></td><td align="right">'+tx('Stone is more than')+' :&nbsp;</td><td><INPUT id=frR3 type=text value=' + Options.ScoutOptions.r3 + '></td></tr>';
		m += '<tr><td>&nbsp;&nbsp;<b>'+tx('OR')+'</b></td><td align="right">'+tx('Ore is more than')+' :&nbsp;</td><td><INPUT id=frR4 type=text value=' + Options.ScoutOptions.r4 + '></td></tr>';
		m += '<tr><td colspan=2>&nbsp;</td><td>('+tx('NB - Set amount to zero to disable the check for that resource')+')</td></tr></table>';
		m += '<hr>&nbsp;&nbsp;&nbsp;&nbsp;<input id=frfriendly type=checkbox ' + (Options.ScoutOptions.friendly ? 'CHECKED' : '') + '><b>'+tx('ALWAYS')+'</b> '+tx('Delete Scout Reports of Friendly Alliances');
		m += '<br>&nbsp;&nbsp;&nbsp;&nbsp;<input id=frhostile type=checkbox ' + (Options.ScoutOptions.hostile ? 'CHECKED' : '') + '><b>'+tx('NEVER')+'</b> '+tx('Delete Scout Reports of Hostile Alliances');
		m += '<br>&nbsp;';

		t.myDiv.innerHTML = m;

		ChangeOption('ScoutOptions','frGold','gold');
		ChangeOption('ScoutOptions','frR1','r1');
		ChangeOption('ScoutOptions','frR2','r2');
		ChangeOption('ScoutOptions','frR3','r3');
		ChangeOption('ScoutOptions','frR4','r4');

		ToggleOption('ScoutOptions','frlost','lost');
		ToggleOption('ScoutOptions','frfriendly','friendly');
		ToggleOption('ScoutOptions','frhostile','hostile');

		ById('FSrpts').addEventListener('click', function() {
			t.e_toggleswitch(this)
		}, false);
    },

	EverySecond : function () {
		var t = Tabs.ScoutReports;

		if (!t.deleting && Options.ScoutOptions.On) {
			t.LoopCounter = t.LoopCounter + 1;

			if (t.LoopCounter >= 2) {
				t.LoopCounter = 0;
				// check next report and delete if required..
				t.fetchreport();
			}
		}
		else {
			t.LoopCounter = 0;
		}
	},
};

/**************************** Bulk Scout ****************************************/
Tabs.BulkScout = {
    tabLabel: 'Scout List',
	tabOrder: 2080,
	tabColor : 'brown',
	timer: null,
	intervalSecs  : 3,
	cityreason : '',
	Options: {
		NumScouts: 1,
		ScoutCity: 0,
		SkipErrors: true,
		Attack:false,
		AttackPreset:false,
		AllCities:false,
		ClosestCity:false,
		QuickScout:false,
		CoordList:[],
		On:false,
		Toggle : false,
		KnightPriority : 0, // 0 - highest combat (default), 1 - lowest combat, 2 - highest experience, 3 - lowest experience
		SendChamp : 0, // 0 - never (default), 1 - always, 2 - if available
		FreeRallySlots : 2,
		ClearOnRefresh : true,
	},
	myDiv: null,

	init: function(div) {
		var t = Tabs.BulkScout;

        t.myDiv = div;

		if (!Options.BulkScoutOptions) {
			Options.BulkScoutOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.BulkScoutOptions.hasOwnProperty(y)) {
					Options.BulkScoutOptions[y] = t.Options[y];
				}
			}
		}

		if (Options.BulkScoutOptions.Toggle) AddSubTabLink('AutoScout',t.e_toggleswitch, 'ScoutToggleTab');
		SetToggleButtonState('Scout',Options.BulkScoutOptions.On,'Scout');

		// strip out any co-ords not ticked - this will be unpopular, but it will avoid the list endlessly growing!

		var b = Options.BulkScoutOptions.CoordList.length;
		while (b--) {
			if (!Options.BulkScoutOptions.CoordList[b].chk && Options.BulkScoutOptions.ClearOnRefresh) {
				Options.BulkScoutOptions.CoordList.splice(b,1);
			}
		}

		uWExportFunction('btRemoveScoutList', Tabs.BulkScout.RemoveEntry);
		uWExportFunction('pbscoutclick', Tabs.BulkScout.ToggleEntry);

		// start autoscout loop timer to start in 10 seconds...

		if (Options.BulkScoutOptions.On) {
			t.timer = setTimeout(function () { t.doAutoLoop(Options.BulkScoutOptions.ScoutCity);}, (10 * 1000));
		}
	},

	show: function (init) {
		var t = Tabs.BulkScout;
		if (!Options.BulkScoutOptions.On) {  // reset to current city on show if not already scouting
			if (init) {
				Options.BulkScoutOptions.ScoutCity = Cities.byID[InitialCityId].idx;
			}
			else {
				Options.BulkScoutOptions.ScoutCity = Cities.byID[uW.currentcityid].idx;
			}
		}

		var m = '<DIV class=divHeader align=center>'+tx('SCOUT/ATTACK LIST')+'</div><div align=center>';
        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btScoutToggle type=checkbox '+ (Options.BulkScoutOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=BulkScoutButton type=submit value="'+tx("AutoScout")+' = '+ (Options.BulkScoutOptions.On?'ON':'OFF')+'"></td><td width=30% align=right>&nbsp;</td></tr></table>';
		m += '<br></div><DIV class=divHeader align=center>'+tx('OPTIONS')+'</div><br>';
        m += '<TABLE width=98% align=center cellpadding=0 cellspacing=0 class=xtab><TR width=50%><td><TABLE cellpadding=1 cellspacing=0 class=xtab>';
        m += '<TR><td colspan=2>'+tx("Number of scouts to send")+':&nbsp;<input id=pbsrcScoutAmt size=5 value="'+Options.BulkScoutOptions.NumScouts+'" /></td></tr>';
		m += '<TR><td colspan=2>'+tx("Keep")+' <INPUT id=btbsfreerallyslots type=text size=2 maxlength=2 value="'+Options.BulkScoutOptions.FreeRallySlots+'"\> '+tx("free rally point slots")+'</td></tr>';
		m += '<TR><td><input type=checkbox id="pbsclear"></td><td>'+tx("Remove unchecked co-ords from list on refresh")+'</td></tr>';
        m += '<TR><td colspan=2>'+tx("March from")+': <span id=pbsrcScoutcitypick> </span></td></tr>';
		m += '<TR><td><input type=checkbox id="pbsclosest"></td><td>'+tx("or select the closest city")+'</td></tr>';
		m += '<TR><td><input type=checkbox id="pbskip"></td><td>'+tx("Skip targets when errors occur")+'</td></tr>';
        m += '<TR><td><input type=checkbox id="pbsallcities"></td><td>'+tx("Use all cities (not under Ascension Protection!)")+'</td></tr>';
		m += '<TR><td><input type=checkbox id="pbsquick"></td><td>'+tx("Fetch march target details (QuickScout)")+'</td></tr>';
		m += '<TR><td style="height:20px;"><input type=checkbox id="pbattack"></td><td style="vertical-align:bottom;">'+tx("Send ATTACK!")+'&nbsp;&nbsp;&nbsp;&nbsp;<span id=pbspresetspan class=divHide>';
		var MarchPresets = {0:"-- "+tx('Use Scouts')+" --"};
		for (var PN in Options.QuickMarchOptions.MarchPresets) {
			MarchPresets[PN] = Options.QuickMarchOptions.MarchPresets[PN][0];
		}
		m += htmlSelector(MarchPresets, Options.BulkScoutOptions.AttackPreset, 'id=pbsattackpreset class=btInput style="vertical-align:text-bottom;"');
		m += '</span></div></td></tr>';
		m += '<TR><td style="height:20px;">&nbsp;</td><td id=pbsknightcell class=divHide>'+tx('Knight priority')+':&nbsp;'+htmlSelector({0:tx('Highest Combat Skill'), 1:tx('Lowest Combat Skill'), 2:tx('Highest Experience'), 3:tx('Lowest Experience')}, Options.BulkScoutOptions.KnightPriority, ' class=btInput id=pbsknight')+'</td></tr>';
		m += '<TR><td style="height:20px;">&nbsp;</td><td id=pbschampcell class=divHide>'+tx('Send Champion')+':&nbsp;'+htmlSelector({0:tx('Never'), 1:tx('Always'), 2:tx('If Available')}, Options.BulkScoutOptions.SendChamp, ' class=btInput id=pbschamp')+'</td></tr></table>';

        m += '</td><td width=50%>';
        m += '<DIV>'+tx("Co-ordinates")+':</div>';
        m += '<DIV><textarea id=pbbulkscoutcoords rows=7 cols=40 onkeyup="ptStopProp(event);" title="Separate multiple co-ordinates with spaces.\nValid formats include xxx,yyy (xxx_yyy) [xxx.yyy] etc..."></textarea></div>';
		m += '<DIV>'+strButton20(tx('Add to Scout List'), 'id=pbAddBulkScout')+'</div>';
        m += '</td></tr><tr><td height=20 id=pbbulkscoutmsg align=center colspan=2>&nbsp;</td></tr></table>';

		m += '</div><DIV class=divHeader align=center>'+tx('SCOUT QUEUE')+'</div><br>';
        m += '<DIV id=btScoutList style="height:220px; overflow-y:auto;"></div><br>';

		t.myDiv.innerHTML = m;
		t.PaintList('');

		new CdispCityPicker ('pbScoutPick', ById('pbsrcScoutcitypick'), true, function(c,x,y){ Options.BulkScoutOptions.ScoutCity = c.idx; }, Options.BulkScoutOptions.ScoutCity);

		ById('BulkScoutButton').addEventListener('click', function() {
			t.e_toggleswitch(this)
		}, false);


		ChangeIntegerOption('BulkScoutOptions','btbsfreerallyslots','FreeRallySlots');

		ToggleOption('BulkScoutOptions','btScoutToggle','Toggle');
		ToggleOption('BulkScoutOptions','pbsclosest','ClosestCity');
		ToggleOption('BulkScoutOptions','pbskip','SkipErrors');
		ToggleOption('BulkScoutOptions','pbattack','Attack',t.ShowHidePreset);
		t.ShowHidePreset();
		ToggleOption('BulkScoutOptions','pbsallcities','AllCities');
		ToggleOption('BulkScoutOptions','pbsquick','QuickScout');
		ToggleOption('BulkScoutOptions','pbsclear','ClearOnRefresh');

		ById('pbAddBulkScout').addEventListener('click', t.AddCoords, false);

		ById('pbsattackpreset').addEventListener('change', function() {
			Options.BulkScoutOptions.AttackPreset = ById('pbsattackpreset').value;
			saveOptions();
		}, false);

		ById('pbsrcScoutAmt').addEventListener('change', function(){
			Options.BulkScoutOptions.NumScouts = parseIntNan(ById('pbsrcScoutAmt').value);
			if (Options.BulkScoutOptions.NumScouts==0) Options.BulkScoutOptions.NumScouts = 1;
			saveOptions();
		}, false);

		ById('pbsknight').addEventListener('change', function(){
			Options.BulkScoutOptions.KnightPriority = ById('pbsknight').value;
			saveOptions();
		}, false);

		ById('pbschamp').addEventListener('change', function(){
			Options.BulkScoutOptions.SendChamp = ById('pbschamp').value;
			saveOptions();
		}, false);
	},

	ShowHidePreset : function () {
		var t = Tabs.BulkScout;
		if (Options.BulkScoutOptions.Attack) { jQuery('#pbspresetspan').removeClass("divHide"); jQuery('#pbsknightcell').removeClass("divHide"); jQuery('#pbschampcell').removeClass("divHide"); }
		else { jQuery('#pbspresetspan').addClass("divHide"); jQuery('#pbsknightcell').addClass("divHide"); jQuery('#pbschampcell').addClass("divHide"); }
	},

	e_toggleswitch: function(obj) {
		var t = Tabs.BulkScout;
		obj = ById('BulkScoutButton');
		if (Options.BulkScoutOptions.On) {
			if (obj) obj.value = tx("AutoScout = OFF");
			Options.BulkScoutOptions.On = false;
		} else {
			if (obj) obj.value = tx("AutoScout = ON");
			Options.BulkScoutOptions.On = true;
			t.timer = setTimeout(function () { t.doAutoLoop(Options.BulkScoutOptions.ScoutCity);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Scout',Options.BulkScoutOptions.On,'Scout');
	},

	PaintList : function (msg) {
		var t = Tabs.BulkScout;

		var z = '';
		var r = 0;
		var logshow = false;
		var sel = 0;

		var bclass = "blue14";
		var btext  = tx("Clear List");

		var z = '<div align="center">';
		z += '<TABLE width=98% align=center cellpadding=0 cellspacing=0 class=xtab><TR><TD colspan=4 align=right id=pbscoutinfo>&nbsp;</td></tr><tr><TH class=xtabHD width=15><input type=checkbox id=pbscout_All /></th><TH width=100 class=xtabHD>'+tx('Co-ords')+'</th><th class=xtabHD>'+tx('Details')+'</th><th align=right class=xtabHD><a id=btClearScoutList class="inlineButton btButton '+bclass+'"><span>'+btext+'</span></a></th></tr>';
		for(i = 0; i < Options.BulkScoutOptions.CoordList.length; i++){
			logshow = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<TR class="'+rowClass+'"><TD align=center width=15><input type=checkbox name=pbscoutchk id="pbscoutchk_'+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'" value="'+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'" '+(Options.BulkScoutOptions.CoordList[i].chk?'CHECKED':'')+' onclick="pbscoutclick(\''+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'\')" /></td><TD align=center>'+coordLink(Options.BulkScoutOptions.CoordList[i].x,Options.BulkScoutOptions.CoordList[i].y)+'</td><TD align=left id="pbscoutdetails_'+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'">'+(Options.BulkScoutOptions.CoordList[i].Details?Options.BulkScoutOptions.CoordList[i].Details:'')+'<td align=right><a id="pbscoutdelete'+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'" class="inlineButton btButton brown8" onclick="btRemoveScoutList(\''+Options.BulkScoutOptions.CoordList[i].x+'_'+Options.BulkScoutOptions.CoordList[i].y+'\')"><span>Remove</span></a></td></tr>';

			if (Options.BulkScoutOptions.CoordList[i].chk) sel++;
		}

		if (!logshow) {
			z += '<tr><td colspan=4 class=xtab><div align="center"><br><br>'+tx('No list entries')+'</div></td></tr>';
		}

		z += '</table></div>';

		ById('btScoutList').innerHTML = z;
		ById('pbbulkscoutmsg').innerHTML = msg;
		ById('pbscoutinfo').innerHTML = '('+sel+'/'+Options.BulkScoutOptions.CoordList.length+')';
		ById('btClearScoutList').addEventListener ('click', function() {t.ClearList();}, false);

		ById('pbscout_All').addEventListener('change', function(){
			var sel = 0;
			for(k in document.getElementsByName('pbscoutchk'))
				document.getElementsByName('pbscoutchk')[k].checked = ById('pbscout_All').checked;
			for (var b in Options.BulkScoutOptions.CoordList) {
				Options.BulkScoutOptions.CoordList[b].chk = ById('pbscout_All').checked;
				if (Options.BulkScoutOptions.CoordList[b].chk) sel++;
			}
			saveOptions();
			ById('pbscoutinfo').innerHTML = '('+sel+'/'+Options.BulkScoutOptions.CoordList.length+')';
		}, false);
	},

	ClearList : function () {
		var t = Tabs.BulkScout;
		Options.BulkScoutOptions.CoordList = [];
		saveOptions();
		t.PaintList(tx('Scout List Cleared'));
	},

	RemoveEntry : function (c) {
		var t = Tabs.BulkScout;
		var Coord = [];
		Coord = c.split("_");
		for (var b in Options.BulkScoutOptions.CoordList) {
			if (Options.BulkScoutOptions.CoordList[b].x==Coord[0] && Options.BulkScoutOptions.CoordList[b].y==Coord[1]) {
				Options.BulkScoutOptions.CoordList.splice(b,1);
				break;
			}
		}
		saveOptions();
		t.PaintList('Entry deleted');
	},

	ToggleEntry : function (c) {
		var t = Tabs.BulkScout;
		var Coord = [];
		Coord = c.split("_");
		var sel = 0;
		for (var b in Options.BulkScoutOptions.CoordList) {
			if (Options.BulkScoutOptions.CoordList[b].x==Coord[0] && Options.BulkScoutOptions.CoordList[b].y==Coord[1]) {
				Options.BulkScoutOptions.CoordList[b].chk = !Options.BulkScoutOptions.CoordList[b].chk;
				saveOptions();
			}
			if (Options.BulkScoutOptions.CoordList[b].chk) sel++;
		}
		ById('pbscoutinfo').innerHTML = '('+sel+'/'+Options.BulkScoutOptions.CoordList.length+')';
	},

	UnselectEntry : function (x,y) {
		var t = Tabs.BulkScout;
		for (var b in Options.BulkScoutOptions.CoordList) {
			if (Options.BulkScoutOptions.CoordList[b].x==x && Options.BulkScoutOptions.CoordList[b].y==y) {
				Options.BulkScoutOptions.CoordList[b].chk = false;
				saveOptions();
			}
		}
		if (ById('pbscoutchk_'+x+'_'+y)) {
			ById('pbscoutchk_'+x+'_'+y).checked = false;
		}
	},

	AddCoords : function () {
		var t = Tabs.BulkScout;

		var NewCoords = ById('pbbulkscoutcoords').value;
		NewCoords = replaceAll(NewCoords,"(", " ");
		NewCoords = replaceAll(NewCoords,")", " ");
		NewCoords = replaceAll(NewCoords,"[", " ");
		NewCoords = replaceAll(NewCoords,"]", " ");
		NewCoords = replaceAll(NewCoords,"_", ",");
		NewCoords = replaceAll(NewCoords,".", ",");
		var NewCoordList = [];
		var CleanedCoordList = [];
		var Coord = [];
		var ListEntry = new Object();
		var msg = '';
		if (NewCoords.trim() != "") {
			NewCoordList = NewCoords.split(" ");
		}
		CoordError = false;
		CoordsAdded = false;
		for (var a=0;a<NewCoordList.length;a++) {
			var c = NewCoordList[a];
			if (c.trim() != "") {
				Coord = c.split(",");
				if (Coord[0] && !isNaN(Coord[0]) && Coord[1] && !isNaN(Coord[1])) {
					// look like coords?
					CleanedCoordList.push({x:Coord[0],y:Coord[1]});
					// avoid duplicates by deleting existing entry for these coords
					for (var b=0;b<Options.BulkScoutOptions.CoordList.length;b++) {
						if (Options.BulkScoutOptions.CoordList[b].x==Coord[0] && Options.BulkScoutOptions.CoordList[b].y==Coord[1]) {
							Options.BulkScoutOptions.CoordList.splice(b,1);
							break;
						}
					}
				}
				else {
					CoordError = true;
				}
			}
		}

		if (CoordError) {
			msg = '<span style="color:#800;">'+tx('Invalid format')+'!</span>';
		}
		else {
			for (var a=0;a<CleanedCoordList.length;a++) {
				CoordsAdded = true;
				ListEntry = {};
				ListEntry.chk = true;
				ListEntry.x = CleanedCoordList[a].x;
				ListEntry.y = CleanedCoordList[a].y;
				ListEntry.details = '';
				Options.BulkScoutOptions.CoordList.push(ListEntry);
			}
			if (CoordsAdded) msg = tx('Co-ordinates added');
			ById('pbbulkscoutcoords').value = '';
		}
		saveOptions();
		t.PaintList(msg);
	},

	ImportCoords : function(CoordList) {
		var t = Tabs.BulkScout;
		CoordsAdded = false;
		for (var a=0;a<CoordList.length;a++) {
			var c = CoordList[a];
			if (c.trim() != "") {
				Coord = c.split(",");
				for (var b=0;b<Options.BulkScoutOptions.CoordList.length;b++) {
					if (Options.BulkScoutOptions.CoordList[b].x==Coord[0] && Options.BulkScoutOptions.CoordList[b].y==Coord[1]) {
						Options.BulkScoutOptions.CoordList.splice(b,1);
						break;
					}
				}
				ListEntry = {};
				ListEntry.chk = true;
				ListEntry.x = Coord[0];
				ListEntry.y = Coord[1];
				ListEntry.details = '';
				Options.BulkScoutOptions.CoordList.push(ListEntry);
				CoordsAdded = true;
			}
		}

		if (CoordsAdded) { ById('bttcBulkScout').click(); }
	},

	doAutoLoop : function (idx) {
		var t = Tabs.BulkScout;
		clearTimeout(t.timer);
		if (ById('pbbulkscoutmsg')) { ById('pbbulkscoutmsg').innerHTML = ''; }

		var cityId = Cities.cities[idx].id;

		// get next scout entry, if none, then switch off.

		var entry = null;
		for(var i = 0; i < Options.BulkScoutOptions.CoordList.length; i++){
			if (Options.BulkScoutOptions.CoordList[i].chk) {
				entry = Options.BulkScoutOptions.CoordList[i];
				break;
			}
		}

		if (!entry) {
			Options.BulkScoutOptions.On = false;
			saveOptions();
			if (ById('BulkScoutButton')) { ById('BulkScoutButton').value = tx("AutoScout = OFF"); }
			SetToggleButtonState('Scout',Options.BulkScoutOptions.On,'Scout');
			t.PaintList(tx('Scouting Completed'));
			return;
		}
		else {
			if (!Options.BulkScoutOptions.On) {
				t.UpdateDetails(entry.x,entry.y,tx('Scouting Cancelled'));
				return;
			}
			t.UpdateDetails(entry.x,entry.y,tx('Sending')+'...');
		}

		if (Options.BulkScoutOptions.ClosestCity) { // select closest city
			var idx = t.SelectClosest(entry.x,entry.y);
			var cityId = Cities.cities[idx].id;
		}

		// check currently selected city is suitable for the march.

		var citysuitable = t.CheckCitySuitable(cityId,true);

		if (!citysuitable) {
			if (Options.BulkScoutOptions.AllCities) { // check other cities
				var newidx = t.GetNextSuitableCity(idx);
				if (newidx!=idx) {
					idx = newidx;
					var cityId = Cities.cities[idx].id;
					citysuitable=true;
					actionLog('Changing city to ' + Cities.cities[idx].name,'SCOUT')
				}
			}
		}

		if (!citysuitable) {
			t.UpdateDetails(entry.x,entry.y,t.cityreason+'...',true);
			actionLog(t.cityreason,'SCOUT')
			// 1 min delay... no suitable cities at the moment...
			if (!Options.BulkScoutOptions.ClosestCity || Options.BulkScoutOptions.AllCities) {
				t.timer = setTimeout(function () { t.doAutoLoop(Options.BulkScoutOptions.ScoutCity);}, (60 * 1000));
			}
			else {
				// move co-ords to end of list and try next, because the next entry could be for another city
				Options.BulkScoutOptions.CoordList.push(Options.BulkScoutOptions.CoordList.splice(i,1)[0]);
				t.timer = setTimeout(function () { t.doAutoLoop(idx);}, (t.intervalSecs * 1000));
			}
			return;
		}

		// Send the scout, and loop back once sent...

		t.sendScout(entry.x, entry.y, cityId, function () { var t = Tabs.BulkScout; t.timer = setTimeout(function () { t.doAutoLoop(idx); }, (t.intervalSecs * 1000)); });
	},

	SelectClosest : function (x2,y2) {
		var t = Tabs.BulkScout;
		var closestdist = 999999;
		var closestcity;

		if(isNaN(x2) || isNaN(y2)) return;

		for (var i = 0; i < Cities.numCities; i++) {
			var	cityId = Cities.cities[i].id;
			var ascensionok = (!uW.cm.PrestigeCityPlayerProtectionController.isActive(cityId)); // don't select city under AP!
			if (ascensionok) {
				var x1 = parseInt(Cities.cities[i].x);
				var y1 = parseInt(Cities.cities[i].y);
				if (x1 != x2 || y1 != y2) { // if one of your cities, pick the nearest other city!
					var dist = distance(x1, y1, x2, y2);
					if (dist < closestdist) {
						closestdist = dist;
						closestcity = i;
					}
				}
			}
		}
		return closestcity;
	},

	GetNextSuitableCity : function (idx) {
		var t = Tabs.BulkScout;
		var oldidx = idx;
		do {
			idx++;
			if (idx >= Number(Cities.numCities)) idx = 0;
			cityId = Cities.cities[idx].id;
		}
		while (!t.CheckCitySuitable(cityId) && (idx != oldidx))
		return idx;
	},

	CheckCitySuitable : function (cityId,reason) {
		var t = Tabs.BulkScout;

		var troopsok = true;
		var CheckArray = [];
		if (Options.BulkScoutOptions.Attack && Options.BulkScoutOptions.AttackPreset!=0){
			for (var ui in uW.cm.UNIT_TYPES) {
				var i = uW.cm.UNIT_TYPES[ui];
				if (Options.QuickMarchOptions.MarchPresets[Options.BulkScoutOptions.AttackPreset][i]) {
					CheckArray[i] = parseIntNan(Options.QuickMarchOptions.MarchPresets[Options.BulkScoutOptions.AttackPreset][i]);
				}
			}
		}
		else {
			CheckArray['3'] = Options.BulkScoutOptions.NumScouts;
		}
		for (var ui in uW.cm.UNIT_TYPES) {
			var i = uW.cm.UNIT_TYPES[ui];
			if (CheckArray[i] && CheckArray[i] > parseIntNan(Seed.units['city' + cityId]['unt'+i])) {
				troopsok = false;
				break;
			}
		}

		var knightok = true;
		if (Options.BulkScoutOptions.Attack) {
			var knt = getAvailableKnights(cityId);
			if (!knt[0]) { knightok = false; }
		}

		var marches = parseIntNan(March.getMarchSlots(cityId));
		var maxmarches = parseIntNan(March.getTotalSlots(cityId));
		var keepfree = Number(Options.BulkScoutOptions.FreeRallySlots); // use highest of bulk scout keep rally free or general keep rally free
		if (keepfree < Number(Options.FreeRallySlots)) { keepfree = Number(Options.FreeRallySlots); }
		var rallyok = ((marches+keepfree) < maxmarches);
		var towerok = (!Options.TowerOptions || !Options.TowerOptions.SaveCityState[cityId] || Options.TowerOptions.SaveCityState[cityId].AllowMarches);
		var ascensionok = (!uW.cm.PrestigeCityPlayerProtectionController.isActive(cityId));

		var champok = true;
		if (Options.BulkScoutOptions.Attack && parseIntNan(Options.BulkScoutOptions.SendChamp)==1) {
			var champ = false;
			for (var c in Seed.champion.champions) {
				citychamp = Seed.champion.champions[c];
				var champstatus = citychamp.status;
				if (citychamp.assignedCity == cityId && champstatus != "10") {
					champ = true;
					break;
				}
			}
			champok = champ;
		}

		if (reason) {
			t.cityreason = tx('Waiting for rally point to clear!');
			if (rallyok) {
				if (!knightok) t.cityreason = tx('Waiting for an available knight!');
				else if (!champok) t.cityreason = tx('No Champion available!');
				else if (!troopsok) t.cityreason = tx('Waiting for available troops!');
				else if (!towerok) t.cityreason = tx('Source city is under attack - waiting for all clear!');
				else if (!ascensionok) t.cityreason = tx('Source city is under ascension protection - cannot march from here!');
			}
		}

		return (troopsok && knightok && rallyok && towerok && ascensionok && champok);
	},

	UpdateDetails : function(x,y,msg,perm) {
		var t = Tabs.BulkScout;
		var el = 'pbscoutdetails_'+x+'_'+y;
		var elem = ById(el);
		if (elem) { elem.innerHTML = msg; }
		if (perm) {
			for (var b in Options.BulkScoutOptions.CoordList) {
				if (Options.BulkScoutOptions.CoordList[b].x==x && Options.BulkScoutOptions.CoordList[b].y==y) {
					Options.BulkScoutOptions.CoordList[b].Details = msg;
					saveOptions();
				}
			}
		}
	},

	sendScout : function(x, y, cid, notify){
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cid;
		params.kid = 0;
		params.type = 3;
		params.xcoord = x;
		params.ycoord = y;
		if (Options.BulkScoutOptions.Attack){
			var knt = getAvailableKnights(cid);
			if (knt[0]) {
				if (Options.BulkScoutOptions.KnightPriority==1) { // lowest combat skill
					knt = knt.sort(function sort(a,b) {a = a['Combat'];b = b['Combat'];return a == b ? 0 : (a < b ? -1 : 1);});
				};
				if (Options.BulkScoutOptions.KnightPriority==2) { // highest experience
					knt = knt.sort(function sort(a,b) {a = a['Experience'];b = b['Experience'];return a == b ? 0 : (a > b ? -1 : 1);});
				};
				if (Options.BulkScoutOptions.KnightPriority==3) { // lowest experience
					knt = knt.sort(function sort(a,b) {a = a['Experience'];b = b['Experience'];return a == b ? 0 : (a < b ? -1 : 1);});
				};
				params.kid=knt[0].ID; // will fail if no knights
			}
			params.type = 4;
		}
		if (Options.BulkScoutOptions.Attack && Options.BulkScoutOptions.AttackPreset!=0){
			for (var ui in uW.cm.UNIT_TYPES) {
				var i = uW.cm.UNIT_TYPES[ui];
				params["u"+i] = 0;
				if (Options.QuickMarchOptions.MarchPresets[Options.BulkScoutOptions.AttackPreset][i]) {
						params["u"+i] = parseIntNan(Options.QuickMarchOptions.MarchPresets[Options.BulkScoutOptions.AttackPreset][i]);
					}
				}

				var iused = new Array();
				for (var i = 0; i < QuickMarch.ItemList.length; i++) {
					if (Options.QuickMarchOptions.MarchPresets[Options.BulkScoutOptions.AttackPreset]["item"+QuickMarch.ItemList[i]] == true && Seed.items["i"+QuickMarch.ItemList[i]]) {
						iused.push(QuickMarch.ItemList[i]);
					}
				}
				params.items = iused.join(",");
		}
		else {
			params.u3 = Options.BulkScoutOptions.NumScouts;
		}
		params.gold = 0;
		params.r1 = 0;
		params.r2 = 0;
		params.r3 = 0;
		params.r4 = 0;
		params.r5 = 0;

		params.champid = 0;
		if (Options.BulkScoutOptions.Attack && parseIntNan(Options.BulkScoutOptions.SendChamp)!=0) {
			for (var c in Seed.champion.champions) {
				citychamp = Seed.champion.champions[c];
				if (citychamp.assignedCity == cid) {
					var champstatus = citychamp.status;
					if (champstatus != "10") { params.champid = citychamp.championId; }
					break;
				}
			}
		}

		March.addMarch(params, function(rslt){
			var t = Tabs.BulkScout;
			if (rslt.ok) {
				var extrainfo = '';
				if (cid!=Cities.cities[Options.BulkScoutOptions.ScoutCity].id || Options.BulkScoutOptions.ClosestCity) { extrainfo += ' from '+Cities.byID[cid].name; }
				if (Options.BulkScoutOptions.Attack) { t.UpdateDetails(x,y,tx('Attack sent')+extrainfo+'!',true); }
				else { t.UpdateDetails(x,y,tx('Scout sent')+extrainfo+'!',true); }
				t.UnselectEntry(x,y);
				if (Options.BulkScoutOptions.QuickScout) {
					ChatStuff.fetchmarch(rslt.marchId,t.QuickScoutResults);
				}
			}
			else {
				var msg = tx('March failed to send!');
				if (rslt.msg) msg = rslt.msg;
				if (rslt.error_code == 208 || rslt.error_code == 207 || rslt.error_code == 104) { // will never be able to send
					t.UpdateDetails(x,y,msg);
					t.UnselectEntry(x,y);
					// update search tab if coords exist and it's misted and target it truced..
					if(rslt.error_code == 208) {
						if (Tabs.Search && Tabs.Search.mapDat) {
							var numRows = Tabs.Search.mapDat.length;
							for (var i=0; i<numRows; i++){
								if (Tabs.Search.mapDat[i][0] == x && Tabs.Search.mapDat[i][1] == y) {
									if (Tabs.Search.mapDat[i][13]) {
										Tabs.Search.mapDat[i][6] = 0;
										Tabs.Search.mapDat[i][8] = '<span style="color:#800;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+tx('Target is truced - Cannot scout')+'!</span>';
										Tabs.Search.scouted++;
										Tabs.Search.updateMistProgress();
									}
									break;
								}
							}
						}
					}
				}
				else {
					if (Options.BulkScoutOptions.SkipErrors) {
						t.UpdateDetails(x,y,msg,true);
						t.UnselectEntry(x,y);
					} else {
						t.UpdateDetails(x,y,msg+' '+tx('Retrying')+'...',true);
					}
				}
			}
			if (notify) {notify();}
		});
	},

	QuickScoutResults : function (rslt,rslt2,march) {
		var t = Tabs.BulkScout;

		var a = march;
		var totile = tileTypes[parseInt(a["toTileType"])];
		if (a["toTileType"] == 51) {
			if (!a["toPlayerId"]) { totile = "???"; }
			else { if (a["toPlayerId"] == 0) totile = 'Barb Camp'; }
		}
		totile = 'Lvl '+a["toTileLevel"]+' '+totile;

		if (rslt2 && rslt2.userInfo) {
			u2 = rslt2.userInfo[0];
			var alli2 = 'None';
			if (u2.allianceName)
				alli2 = u2.allianceName + FormatDiplomacy(u2.allianceId);

			t.UpdateDetails(march.toXCoord,march.toYCoord,totile+' - '+uW.g_js_strings.commonstr.nametx+': '+PlayerLink(a.toPlayerId,u2.genderAndName)+', '+uW.g_js_strings.commonstr.alliance+': '+alli2,true);
		}
		else {
			t.UpdateDetails(march.toXCoord,march.toYCoord,totile,true);
		}

		// update misted search if it exists
		if (Tabs.Search && Tabs.Search.mapDat) {
			var numRows = Tabs.Search.mapDat.length;
			for (var i=0; i<numRows; i++){
				if (Tabs.Search.mapDat[i][0] == march.toXCoord && Tabs.Search.mapDat[i][1] == march.toYCoord) {
					if (Tabs.Search.mapDat[i][13]) {
						if (!rslt2) {
							QuickScout.FillSearchDiv({errorMsg:"plain"},march);
						}
						else {
							QuickScout.FillSearchDiv(rslt2,march);
						}
					}
					break;
				}
			}
		}
	},
}

/**************************** Player Tab ****************************************/
Tabs.Player = {
	tabOrder : 1010,
	tabLabel : 'Players',
	myDiv : null,
	MemberListRslt : {},
	userobj : {},
	dat : [],
	friendEta : false,
	hidePlayerInfo : false,
	ModelCity : null,
	unitId : 0,
	ModelCityId : 0,
	curPage :0,
	maxPage :-1,
	friendbtn : '',
	neutralbtn : '',
	hostilebtn : '',
	aName : '',
	ReqSent : {},
	Options : {
		sortColNum: 8,
		sortDir: 1,
	},
	champpos : {x: -999, y: -999},

// t.dat
// 0 - p.displayName
// 1 - p.might
// 2 - p.officerType
// 3 - p.numCities
// 4 - p.cities[c].tileLevel
// 5 - p.cities[c].xCoord
// 6 - p.cities[c].yCoord
// 7 - p.cities[c].cityName
// 8 - distance
// 9 - Online
// 10 - ETA
// 11 - p.cities[c].cityId
// 12 - prestige
// 13 - p.userId
// 14 - prestigelvl
// 15 - prestigeexp
// 16 - p.cities[c].prestigeBuffExpire (for sorting)
// 17 - prestige + prestigelvl (for sorting)
// 18 - p.cities[c].blessing
// 19 - Defending

	init : function (div){
		var t = Tabs.Player;
		t.myDiv = div;

		if (!Options.PlayerOptions) {
			Options.PlayerOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.PlayerOptions.hasOwnProperty(y)) {
					Options.PlayerOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('ptPlayClick', Tabs.Player.clickedPlayerDetails);
		uWExportFunction('ptSetDiplomacy', Tabs.Player.setDiplomacy);
		uWExportFunction('ptInvite', Tabs.Player.clickedSendInvite);
		uWExportFunction('ptViewChamps', Tabs.Player.ViewChamps);
		uWExportFunction('ptGetMembers', Tabs.Player.eventGetMembers);
		uWExportFunction('ptPaintMembers', Tabs.Player.GetDataForMap);
		uWExportFunction('ptAllClickPrev', Tabs.Player.eventListPrev);
		uWExportFunction('ptAllClickNext', Tabs.Player.eventListNext);
		uWExportFunction('ptPlayerDetails', Tabs.Player.eventPlayerExternalTabClick);
		uWExportFunction('ptplayClickSort', Tabs.Player.playClickSort);

		m = '<div class="divHeader" align="center">'+tx('PLAYER AND ALLIANCE SEARCH')+'</div>';
		m += '<br><table class=xtab>';
		m += '<tr><td width=10>&nbsp;</td><td>'+uW.g_js_strings.modal_fow_leaderboard.searchuser+':&nbsp;</td><td><INPUT id=allplayname size=20 type=text />&nbsp;</td><td><a id=allplaysubmit class="inlineButton btButton blue20"><span>'+uW.g_js_strings.modal_fow_leaderboard.searchuser+'</span></a>&nbsp;<a id=alluidsubmit class="inlineButton btButton blue20"><span>UID</span></a></td>';
		m += '<td class="ErrText" id=allplayerr>&nbsp;</td></tr>';
		m += '<tr><td width=10>&nbsp;</td><td>'+uW.g_js_strings.setDiplomacyWindow.srchalli+':&nbsp;</td><td><INPUT id=allalliname type=text />&nbsp;</td><td><a id=allallisubmit class="inlineButton btButton blue20"><span>'+uW.g_js_strings.modal_fow_leaderboard.findalli+'</span></a></td>';
		m += '<td class="ErrText" id=allallierr>&nbsp;</td></tr>';
		m += '<TR><td width=10>&nbsp;</td><TD><INPUT align=left id=alllistsubmit type=button value="'+tx('List Alliances')+'"/></td>';
		if (Seed.allianceDiplomacies) {
			m += '<TD><INPUT align=right id=allmyallisubmit type=submit value="'+getMyAlliance()[1]+'"/></td>';
			m += '<TD><INPUT id=pbshowfriendlies type=checkbox>'+tx('Show Friendly Alliances')+'&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=pbshowhostiles type=checkbox>'+tx('Show Hostile Alliances')+'</td>';
		}
		m += '</tr></table>';
		m += '<div id=pbfriendlydiv style="display:none;padding:5px;">&nbsp;</div>';
		m += '<div id=pbhostilediv style="display:none;padding:5px;">&nbsp;</div>';
		m += '<div id=allPlayerInfo style="display:none;">&nbsp;</div><HR>';
		m += '<div id=allCitySelect style="display:none;padding:5px;">';
		m += '<table class=xtab width=100%>';
		m += '<TR><TD>'+tx('Show distance from')+':&nbsp;X:&nbsp;<INPUT size=2 type=text id=plyrX />&nbsp;Y:&nbsp;<INPUT size=2 type=text id=plyrY />&nbsp;'+tx('or choose city')+':&nbsp;<span id=dmcoords></span></td><td align=right>&nbsp;</td></tr>';
		m += '<tr><td>';
		if (Tabs.BulkScout) m += strButton20(tx('Add to Scout List'), 'id=ptScoutExport')+'&nbsp;';
		if (Tabs.BulkAttack) m += strButton20(tx('Add to Attack List'), 'id=ptBulkAttackExport')+'&nbsp;';
		m += strButton20(tx('Highlight Defending Cities'),'id=ptHighDefenders')+'</td><td align=right>&nbsp;'+tx('ETA')+':&nbsp;</b></span><select id="idFindETASelect"><option value="0">-- '+uW.g_js_strings.commonstr.select+' --</option>';
		for (var ui in uW.cm.UNIT_TYPES){
			i = uW.cm.UNIT_TYPES[ui];
			m += '<option value="'+i+'">'+uW.unitcost["unt"+i][0]+'</option>';
		}
		m += '</td></tr></table>'
		m += '</div>';
		m += '<div id=allListOut style="min-height:200px;">&nbsp;</div><br>';

		div.innerHTML = m;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		t.ModelCity = new CdispCityPicker('plyrdcp', ById('dmcoords'), true, t.eventCoords, null);
		t.ModelCity.bindToXYboxes(ById('plyrX'), ById('plyrY'));

		if (ById('ptScoutExport')) ById('ptScoutExport').addEventListener('click', t.ExportScoutList, false);
		if (ById('ptBulkAttackExport')) ById('ptBulkAttackExport').addEventListener('click', t.ExportAttackList, false);
		ById('ptHighDefenders').addEventListener('click', t.HighlightDefenders, false);
		ById('idFindETASelect').addEventListener('click', t.handleEtaSelect, false);

		ById('allplayname').addEventListener('keypress', function (e) {
			if (e.which == 13) ById('allplaysubmit').click();
		}, false);
		ById('allalliname').addEventListener('keypress', function (e) {
			if (e.which == 13) ById('allallisubmit').click();
		}, false);

		if (Seed.allianceDiplomacies) {
			ById('allmyallisubmit').addEventListener('click', t.showMyAlliance, false);
			ById('pbshowfriendlies').addEventListener('change', function () {
				if (this.checked) {
					t.paintFriendlyDiv();
				} else {
					ById('pbfriendlydiv').style.display = 'none';
					ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
				}
			});
			ById('pbshowhostiles').addEventListener('change', function () {
				if (this.checked) {
					t.paintHostilesDiv();
				} else {
					ById('pbhostilediv').style.display = 'none';
					ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
				}
			});
		}
		ById('allallisubmit').addEventListener('click', t.eventSubmit, false);
		ById('allplaysubmit').addEventListener('click', t.eventPlayerSubmit, false);
		ById('alluidsubmit').addEventListener('click', t.eventPlayerUIDSubmit, false);
		ById('allalliname').addEventListener('focus', function () {
			ById('allallierr').innerHTML = '';
		}, false);
		ById('allplayname').addEventListener('focus', function () {
			ById('allplayerr').innerHTML = '';
		}, false);
		ById('alllistsubmit').addEventListener('click', t.eventListSubmit, false);
	},

	playClickSort : function (e) {
		var t = Tabs.Player;
		var newColNum = e.id.substr(8);
		ById('clickCol' + Options.PlayerOptions.sortColNum).className = 'buttonv2 std blue';
		e.className = 'buttonv2 std green';
		if (newColNum == Options.PlayerOptions.sortColNum) { Options.PlayerOptions.sortDir *= -1; }
		else { Options.PlayerOptions.sortColNum = newColNum; }
		saveOptions();
		t.RepaintList();
	},

	paintFriendlyDiv : function () {
		var t = Tabs.Player;
		var mess = '<div class=divHeader align=center>'+tx('FRIENDLY ALLIANCES')+'</div>';
		for (var k in Seed.allianceDiplomacies.friendly) {
			mess += '<INPUT id=pbFriendly_' + k + ' type=submit value="' + Seed.allianceDiplomacies.friendly[k].allianceName + '">&nbsp;';
		}
		ById('pbfriendlydiv').innerHTML = mess;
		ById('pbfriendlydiv').style.display = 'block';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		for (var q in Seed.allianceDiplomacies.friendly) {
			ById('pbFriendly_' + q).addEventListener('click', function () {
				t.eventGetMembers(this.id.substr(12))
			});
		}
	},

	paintHostilesDiv : function () {
		var t = Tabs.Player;
		var mess = '<div class=divHeader align=center>'+tx('HOSTILE ALLIANCES')+'</div>';
		for (var k in Seed.allianceDiplomacies.hostile) {
			mess += '<INPUT id=pbHostile_' + k + ' type=submit value="' + Seed.allianceDiplomacies.hostile[k].allianceName + '">&nbsp;';
		}
		ById('pbhostilediv').innerHTML = mess;
		ById('pbhostilediv').style.display = 'block';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		for (var q in Seed.allianceDiplomacies.hostile) {
			ById('pbHostile_' + q).addEventListener('click', function () {
				t.eventGetMembers(this.id.substr(11))
			});
		}
	},

	eventSubmit : function () {
		var t = Tabs.Player;
		ById('allallierr').innerHTML = '';
		t.aName = ById('allalliname').value;
		if (t.aName.length < 3) {
			ById('allallierr').innerHTML = uW.g_js_strings.getAllianceSearchResults.entryatleast3;
			return;
		}
		var myA = getMyAlliance();
		if (myA[0] == 0) {
			ById('allallierr').innerHTML = tx('You need to belong to an alliance to search alliances by name');
			return;
		}

		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		if (myA[0] != 0 && myA[1].toUpperCase().indexOf(t.aName.toUpperCase()) >= 0) // need to merge own alliance details into results...
			t.fetchAllianceList(t.aName, myA[0], t.eventGotAllianceList);
		else
			t.fetchAllianceList(t.aName, null, t.eventGotAllianceList);
	},

	eventPlayerSubmit : function () {
		var t = Tabs.Player;
		ById('allplayerr').innerHTML = '';
		var name = ById('allplayname').value;
		name = name.replace(/\'/g, "_").replace(/\,/g, "_").replace(/\-/g, "_");
		t.pName = name;
		if (name.length < 3) {
			ById('allplayerr').innerHTML = uW.g_js_strings.getAllianceSearchResults.entryatleast3;
			return;
		}
		var myA = getMyAlliance();
		if (myA[0] == 0) {
			ById('allplayerr').innerHTML = tx('You need to belong to an alliance to search players by name');
			return;
		}
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		fetchPlayerList(name, t.eventGotPlayerList);
	},

	eventPlayerExternalTabClick : function (uid) {
		var t = Tabs.Player;
		ById('bttcPlayer').click();
		ById('allplayerr').innerHTML = '';
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);

		var uList = [];
		uList.push(uid);
		getOnline(uList, function (r) {
			if (!r.ok) { t.DisplayMessage(rslt.errorMsg);return; }
			else { t.clickedPlayerDetails(uid,r.data[uid]);}
		});
	},

	eventPlayerUIDSubmit : function () {
		var t = Tabs.Player;
		ById('allplayerr').innerHTML = '';
		var uid = ById('allplayname').value;
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);

		var uList = [];
		uList.push(uid);
		getOnline(uList, function (r) {
			if (!r.ok) { t.DisplayMessage(rslt.errorMsg);return; }
			else { t.clickedPlayerDetails(uid,r.data[uid]);}
		});
	},

	eventListSubmit : function () {
		var t = Tabs.Player;
		var myA = getMyAlliance();

		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		t.curPage = 1;
		t.fetchOtherAllianceInfo(1, t.eventGotOtherAlliancePage);
	},

	eventGotPlayerList: function (rslt) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.msg);
			return;
		}
		t.playerList = rslt.matchedUsers;
		var uList = [];
		for (var k in rslt.matchedUsers)
			uList.push(rslt.matchedUsers[k].userId);
		getOnline(uList, function (r) { t.eventGotPlayerOnlineList(r);});
	},

	eventGotPlayerOnlineList: function (rslt) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.errorMsg);
			return;
		}

		var m = '<DIV class=divHeader align=center>' + uW.g_js_strings.recommendSelectedFriends.playersrch + ': "' + t.pName + '"</div><br>';
		m += '<div style="padding-right:6px;width:'+GlobalOptions.btWinSize.x+'px;overflow-x:scroll;height:500px;overflow-y:scroll;"><TABLE align=center cellspacing=0 cellpadding=1 width=98% class=xtab><TR><TH align=left class=xtabHD>' + uW.g_js_strings.commonstr.nametx + '</th><TH align=left class=xtabHD>UID</th>';
		m += '<TH align=right class=xtabHD>'+uW.g_js_strings.commonstr.might+'</th><TH align=center class=xtabHD>Facebook</th><TH align=left colspan=4 class=xtabHD>' + tx('Player Links')+'</th></tr>';
		var r = 0;
		for (var k in t.playerList) {
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			var u = t.playerList[k];
			var status = '<img title="Offline" style="vertical-align:bottom" src="'+OFFLINE+'"/>';
			if (rslt.data[u.userId]) status = '<img title="Online" style="vertical-align:bottom" src="'+ONLINE+'"/>';

			m += '<TR class='+rowClass+'><TD>'+status+'<SPAN onclick="ptPlayClick(\''+u.userId+'\','+rslt.data[u.userId]+')"><A>'+u.genderAndName+'</a></span></td><TD>';
			if (KOCBYTE_ON) m += '<A target="_blank" href="http://www.kocbyte.com/player/' + getServerId() + '/' + u.userId + '">' + u.userId + '</a>';
			else m += u.userId;
			m += '</td>';
			m += '<TD align=right>' + addCommasInt(u.might) + '</td><TD align=center><A target="_blank" href="https://www.facebook.com/profile.php?id=' + u.fbuid + '"><img width=40 src="https://graph.facebook.com/' + u.fbuid + '/picture"></a></td>';
			m += '<TD><a onclick="ptPlayClick(\''+u.userId+'\','+rslt.data[u.userId]+')">Details</a></td>';
			m += '<TD>'+MonitorLink(u.userId,'Monitor')+'</td>';
			m += '<TD><a onclick="ptViewChamps(\''+u.userId+'\',\''+u.name.replace(/\'/g, "")+'\')">Champions</a></td>';
			m += '<TD><SPAN onclick="getInfoForAnUser(\''+u.userId+'\')"><A>Profile</a></span><\TD></tr>';
		}
		m += '</table>';
		ById('allListOut').innerHTML = m;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

	},

	fetchAllianceList: function (allianceName, myAid, notify) {
		var t = Tabs.Player;
		function combineResults(rsltA, rsltM, notify) {
			if (!rsltA.ok) {
				if (rsltA.msg.indexOf(tx("No alliance found under")) != 0 || !rsltM.ok) {
					notify(rsltA);
					return;
				}
				rsltA.ok = true;
				rsltA.count = 0;
				rsltA.alliancesMatched = {};
			}
			if (rsltM.ok) {
				rsltA.alliancesMatched['a' + rsltM.allianceInfo.allianceId] = {
					allianceId: rsltM.allianceInfo.allianceId,
					allianceName: rsltM.allianceInfo.allianceName,
					membersCount: rsltM.allianceInfo.members,
					relation: null,
					might: rsltM.allianceInfo.might,
					ranking: rsltM.allianceInfo.ranking
				};
				++rsltA.count;
			}
			notify(rsltA);
		}
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.allianceName = allianceName.replace(/\ /g,"_");
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetSearchResults.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (myAid != null && myAid > 0) {
					t.fetchMyAllianceInfo(function (r) { combineResults(rslt, r, notify);});
				}
				else {
					notify(rslt);
				}
			},
			onFailure: function () { notify({errorMsg: 'AJAX error'}); },
		});
	},

	eventGotAllianceList: function (rslt) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.errorMsg);
			return;
		}
		var m = '<DIV class=divHeader align=center>'+uW.g_js_strings.commonstr.alliances+'&nbsp;"' + t.aName + '"</div><br>';
		m += '<TABLE align=center cellspacing=0 cellpadding=1 width=98% class=xtab><TR><TH align=left class=xtabHD>' + uW.g_js_strings.commonstr.alliance + '</th><TH align=right class=xtabHD>' + uW.g_js_strings.commonstr.rank + '</th><TH align=right class=xtabHD>' + uW.g_js_strings.commonstr.members + '</th>';
		m += '<TH align=right class=xtabHD>'+tx('Total Might')+'</th><TH align=left class=xtabHD>' + uW.g_js_strings.getAllianceSearchResults.currdiplo + '</th><TH align=left colspan=3 class=xtabHD>' + tx('Alliance Links')+'</th></tr>';
		var r = 0;
		for (var k in rslt.alliancesMatched) {
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			var all = rslt.alliancesMatched[k];
			m += '<TR class='+rowClass+'><TD>'+all.allianceName+'</td><TD align=right>'+all.ranking+'</td><TD align=right>'+all.membersCount+'</td>';
			m += '<TD align=right>' + addCommasInt(all.might) + '</td><TD id=adiplo'+all.allianceId+' class=xtab>&nbsp;</td>';
			m += '<TD><a onclick="ptGetMembers('+all.allianceId+')">'+uW.g_js_strings.commonstr.members+'</a></td>';
			m += '<TD><a onclick="ptPaintMembers('+all.allianceId+',\''+all.allianceName.replace(/\'/g, "")+'\')">'+uW.g_js_strings.commonstr.viewmap+'</a></td>';
			if (KOCBYTE_ON) m += '<TD><a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + all.allianceId + '">'+tx('KoCByte')+'</a></td>';
			m += '</tr>';
		}
		m += '</table>';
		ById('allListOut').innerHTML = m;

		for (var k in rslt.alliancesMatched) {
			var all = rslt.alliancesMatched[k];
			var dip = getDiplomacy(all.allianceId);
			if (dip == uW.g_js_strings.commonstr.friendly) { dip = 1; }
			else {
				if (dip == uW.g_js_strings.commonstr.hostile) { dip = 2; }
				else { dip = 0;	}
			}
			t.PaintDiplomacy(all.allianceId,dip,'adiplo');
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	eventGotOtherAlliancePage: function (rslt) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.errorMsg);
			return;
		}
		t.MaxPage = rslt.noOfPages;

		var m = '<DIV class=divHeader align=center>'+uW.g_js_strings.modal_alliance.allilist + '</div><br>';
		m += '<TABLE align=center cellspacing=0 cellpadding=1 width=98% class=xtab><TR><TH align=left class=xtabHD>' + uW.g_js_strings.commonstr.alliance + '</th><TH align=right class=xtabHD>' + uW.g_js_strings.commonstr.rank + '</th><TH align=right class=xtabHD>' + uW.g_js_strings.commonstr.members + '</th>';
		m += '<TH align=right class=xtabHD>'+tx('Total Might')+'</th><TH align=left class=xtabHD>' + uW.g_js_strings.getAllianceSearchResults.currdiplo + '</th><TH align=left colspan=3 class=xtabHD>' + tx('Alliance Links')+'</th></tr>';
		var r = 0;

		for (var k in rslt.otherAlliances) {
			var all = rslt.otherAlliances[k];
			if (all.allianceId) {
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';

				var rowcol = "";
				if (getMyAlliance()[0] == all.allianceId) { rowcol = "whiteOnGreen"; }

				m += '<TR class='+rowClass+'><TD><span class="'+rowcol+'">'+all.name+'</span></td><TD align=right><span>'+all.ranking+'</span></td><TD align=right><span>'+all.membersCount+'</span></td>';
				m += '<TD align=right><span>' + addCommasInt(all.might) + '</span></td><TD id=odiplo'+all.allianceId+' class=xtab>&nbsp;</td>';
				m += '<TD><a onclick="ptGetMembers('+all.allianceId+')">'+uW.g_js_strings.commonstr.members+'</a></td>';
				m += '<TD><a onclick="ptPaintMembers('+all.allianceId+',\''+all.name.replace(/\'/g, "")+'\')">'+uW.g_js_strings.commonstr.viewmap+'</a></td>';
				if (KOCBYTE_ON) m += '<TD><a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + all.allianceId + '">'+tx('KoCByte')+'</a></td>';
				m += '</tr>';
				r++;
			}
		}
		m += '</table>';

		m += '<br><div style="padding-left:10px;font-weight:bold;height:20px;width:560px;"><span>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickPrev(-1)">|<</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickPrev(10)"><10</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickPrev(5)"><5</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickPrev(1)"><</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickNext(1)">></a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickNext(5)">>5</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickNext(10)">>10</a>';
		m += '<a class="buttonv2 std blue" onclick="ptAllClickNext(9999)">>|</a>';
		m += '&nbsp;&nbsp;'+tx('Page')+'&nbsp;<INPUT align=right id=idPageNum type="text" class=btInput value='+t.curPage+' size=4 />&nbsp;'+uW.g_js_strings.commonstr.of+'&nbsp;'+t.MaxPage+'.&nbsp;<a id=idFindMyAlliance>'+tx('Find My Alliance')+'</a>';
		m += '</span></div>';

		ById('allListOut').innerHTML = m;

		ById('idPageNum').addEventListener ('change', t.PageNumChange, false);
		ById('idPageNum').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.PageNumChange); }, false);
		ById('idFindMyAlliance').addEventListener ('click', t.FindMyAlliance, false);

		for (var k in rslt.otherAlliances) {
			var all = rslt.otherAlliances[k];
			var dip = getDiplomacy(all.allianceId);
			if (dip == uW.g_js_strings.commonstr.friendly) { dip = 1; }
			else {
				if (dip == uW.g_js_strings.commonstr.hostile) { dip = 2; }
				else { dip = 0;	}
			}
			t.PaintDiplomacy(all.allianceId,dip,'odiplo');
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	eventListNext: function (amt) {
		var t = Tabs.Player;
		if (parseInt(amt) >= 9999) { t.curPage = t.MaxPage; }
		else {
			t.curPage = parseInt(t.curPage) + parseInt(amt);
			if (t.curPage > t.MaxPage) { t.curPage = t.MaxPage;	}
		}
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		t.fetchOtherAllianceInfo(t.curPage, t.eventGotOtherAlliancePage);
	},

	eventListPrev: function (amt) {
		var t = Tabs.Player;
		if (amt <= -1) { t.curPage = 1; }
		else {
			t.curPage = parseInt(t.curPage) - parseInt(amt);
			if (t.curPage < 1) { t.curPage = 1; }
		}
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		t.fetchOtherAllianceInfo(t.curPage, t.eventGotOtherAlliancePage);
	},

	FindMyAlliance : function () {
		var t = Tabs.Player;
		if (getMyAlliance()[0] == 0) { return; }
		t.fetchMyAllianceInfo(function (rslt) {
			if (rslt.ok) {
				t.gotoPage(Math.ceil(parseIntNan(rslt.allianceInfo.ranking)/10));
			}
		});
	},

	PageNumChange : function () {
		var t = Tabs.Player;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		t.gotoPage(parseIntNan(ById('idPageNum').value));
	},

	gotoPage : function (val) {
		var t = Tabs.Player;
		if (t.MaxPage < 0 ) { return; }
		if (val > t.MaxPage) { val = t.MaxPage; }
		if (val < 1) { val = 1; }
		t.curPage = val;
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		t.fetchOtherAllianceInfo(t.curPage, t.eventGotOtherAlliancePage);
	},

	fetchOtherAllianceInfo: function (pageNum, notify) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pageNo = pageNum;
		params.cityId = uW.currentcityid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetOtherInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify(rslt); },
			onFailure: function () { notify({errorMsg: 'AJAX error'});},
		});
	},

	fetchMyAllianceInfo: function (notify) {
		var params = uW.Object.clone(uW.g_ajaxparams);
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify(rslt); },
			onFailure: function () { notify({errorMsg: 'AJAX error'}); },
		});
	},

	showMyAlliance : function () {
		var t = Tabs.Player;
		var aid = getMyAlliance()[0];
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		if (aid != 0) {
			t.eventGetMembers(aid);
		} else {
			t.DisplayMessage(uW.g_js_strings.membersInfo.youmustbelong);
		}
	},

	eventGetMembers: function (aid) {
		var t = Tabs.Player;
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);
		t.fetchAllianceMemberList(aid, null, t.eventGotMemberList);
	},

	fetchAllianceMemberList: function (allianceId, allianceName, notify) {
		var t = Tabs.Player;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.type = "might";
		params.page = 1;
		params.perPage = 100;
		if (allianceName) { params.allianceName = allianceName; }
		if (allianceId && allianceId != 0) { params.allianceId = allianceId; }
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify(rslt); },
			onFailure: function () { notify({errorMsg: 'AJAX error'}); },
		});
	},

	eventGotMemberList: function (rslt) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.errorMsg);
			return;
		}
		t.MemberListRslt = rslt;
		var uList = [];
		for (var k in rslt.results) {
			uList.push(rslt.results[k].userId);
		}
		getOnline(uList, function (r) { t.eventGotMemberOnlineList(r);});
	},

	eventGotMemberOnlineList: function (rslt) {
		var t = Tabs.Player;
		var numInvalid = 0;
		var numPlayers = 0;
		var aid = getMyAlliance()[0];
		var prestige = "";
		t.dat = [];
		for (var i = 0; i < t.MemberListRslt.results.length; i++) {
			p = t.MemberListRslt.results[i];
			if (p.userId == 0) { ++numInvalid; }
			else {
				++numPlayers;
				if (aid == p.allianceId) { t.friendEta = true; }
				else { t.friendEta = false; }
				for (var c = 0; c < p.cities.length; c++) {
					var pt = p.cities[c].prestigeType;
					var prestige = getFactionName(pt);
					if (prestige == "") { prestigelvl = ""; }
					else { prestigelvl = " (" + p.cities[c].prestigeLevel + ")"; }
					ExpTime = convertTime(new Date(p.cities[c].prestigeBuffExpire.replace(" ", "T")+"Z"));
					if ((ExpTime + (3600 * 24) < unixTime()) || isNaN(ExpTime)) {
						prestigeexp = "";
					} else {
						prestigeexp = t.getDuration(p.cities[c].prestigeBuffExpire);
					}
					t.dat.push([p.displayName, parseInt(p.might), p.officerType, parseInt(p.numCities), parseInt(p.cities[c].tileLevel),
						parseInt(p.cities[c].xCoord), parseInt(p.cities[c].yCoord), p.cities[c].cityName, 0, rslt.data[p.userId]?1:0, '--',
						p.cities[c].cityId, prestige, p.userId, prestigelvl, prestigeexp, p.cities[c].prestigeBuffExpire, prestige + prestigelvl, p.cities[c].blessing,false]);
				}
			}
		}
		t.setDistances(Cities.byID[t.ModelCityId].x, Cities.byID[t.ModelCityId].y);
		t.setEta();
		t.displayMembers(t.MemberListRslt.allianceName, numPlayers);
	},

	handleEtaSelect: function () {
		var t = Tabs.Player;
		t.unitId = ById('idFindETASelect').value;
		t.setEta();
		t.RepaintList();
	},

	setDistances: function (x, y) {
		var t = Tabs.Player;
		for (var i = 0; i < t.dat.length; i++) {
			t.dat[i][8] = distance(x, y, t.dat[i][5], t.dat[i][6]);
		}
	},

	setEta: function () {
		var t = Tabs.Player;

		var speed = 0;
		var speedfriend = 0;

		if (t.unitId!=0) {
			var MarchTime = March.getMarchTime(t.ModelCityId,{unit:t.unitId},0,'',false,false);
			speed = MarchTime.speed;
			speedfriend = MarchTime.speedfriend;
		}

		var delay = uW.cm.WorldSettings.isOn("MARCH_SINGLE_TRIP_DELAY") ? parseInt(uW.g_marchSingleTripDelay) : 0;

		for (var i = 0; i < t.dat.length; i++) {
			var distance = t.dat[i][8];
			if (distance) {
				if (speed == 0 || distance == 0) {
					t.dat[i][10] = 0;
				}
				else {
					var time = 0;
					var timefriend = 0;
					if (speed > 0) { time = Math.ceil(parseFloat(distance) * 6000 / speed); }
					if (speedfriend > 0) { timefriend = Math.ceil(parseFloat(distance) * 6000 / speedfriend); }

					time += delay;
					timefriend += delay;

					if (Seed.playerEffects.returnExpire > uW.unixtime()) {
						time = parseInt(time * 0.75);
						timefriend = parseInt(timefriend * 0.75);
					}

					time = Math.ceil(time < 30 ? 30 : time);
					timefriend = Math.ceil(timefriend < 30 ? 30 : timefriend);

					if (t.friendEta) { t.dat[i][10] = timefriend; }
					else { t.dat[i][10] = time; }
				}
			}
		}
	},

	displayPlayer: function (uid,locations) {
		var t = Tabs.Player;

		t.hidePlayerInfo = false;
		var u = t.userobj[uid];
		var n = '<DIV class=divHeader align=center style="padding-right:0px;"><TABLE width=100% cellspacing=0><TR><TD class=xtab width=100>&nbsp;</td><td class=xtab align=center>'+u.name+'&nbsp;('+parseInt(u.userId)+')</td><td class=xtab align=right width=100><a id=ptplayershowhide>'+tx('Hide Details')+'</a></td></tr></table></div>';
		n += '<div id=ptplayerinfo style="max-width:'+GlobalOptions.btWinSize.x+'px;padding:5px;"><table style="padding-right:0px;" class=xtab cellspacing=0 width=100%><tr><td style="vertical-align:top;"><table style="padding-right:0px;" class=xtab cellspacing=0 width=100%>';
		if (u.allianceId && u.allianceId != 0) {
			n += '<tr><td>'+uW.g_js_strings.commonstr.alliance+':&nbsp;</td><td colspan=2><b><a onclick="ptGetMembers(' + u.allianceId + ')">' + u.allianceName + '</a></b></td></tr>';
			n += '<TR><TD>'+tx('Diplomacy')+':&nbsp;</td><TD colspan=2 id=diplo'+u.allianceId+'>&nbsp;</td></tr>';
		}
		else {
			n += '<tr><td>'+uW.g_js_strings.commonstr.alliance+':&nbsp;</td><td colspan=2><b>'+uW.g_js_strings.commonstr.none+'!</b></td></tr>';
		}

		if (!u.online) {
			n += ' <tr><TD>'+uW.g_js_strings.modal_messages_viewreports_view.lastlogin+':&nbsp;</td><TD colspan=2><b>'+ t.getLastLogDuration(u.lastLogin) +'</b></td></tr>';
		}
		else {
			n += ' <tr><TD>'+tx('Last login')+':&nbsp;</td><TD colspan=2><b><span style="color:#800">'+tx('ONLINE')+'</span></b></td></tr>';
		}
		if (u.misted)
			n += '<tr><TD>'+tx('Misted')+':&nbsp;</td><TD colspan=2><b>' + Tabs.Monitor.getDuration(u.fogExpireTimestamp) + '</b></td></tr>';
		n += '<tr><TD>'+uW.g_js_strings.commonstr.status+':&nbsp;</td><TD colspan=2><b>' + Tabs.Monitor.GetStatusText(u.warStatus,u.truceExpireTimestamp) + '</b></td></tr>';
		n += '<tr><TD>'+uW.g_js_strings.commonstr.might+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.might)) + '</b></td></tr>';
		n += '<tr><TD>'+tx('Classic Might')+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.mightClassic)) + '</b></td></tr>';
		n += '<tr><TD>'+tx('Glory Might')+':&nbsp;</td><TD colspan=2><b>' + addCommas(Math.round(u.mightGlory)) + '</b></td></tr>';
		n += '<TR><TD>'+uW.g_js_strings.commonstr.glory+':&nbsp;</td><TD width=50><b><DIV id=ptPaintGlory></div></b></td><td valign=middle rowspan=3 id=ptGloryIcon>&nbsp;</td></tr>';
		n += '<TR><TD>'+tx('Maximum Glory')+':&nbsp;</td><TD><b><DIV id=ptPaintMaxGlory></div></b></td></tr>';
		n += '<TR><TD>'+tx('Lifetime Glory')+':&nbsp;</td><TD><b><DIV id=ptPaintLifetimeGlory></div></b></td></tr>';

		var pids = u.provinceIds.split(',');
		var p = [];
		for (var i = 0; i < pids.length; i++) {
			p.push(uW.provincenames['p' + pids[i]]);
		}
		n += '<tr><td>'+tx('Provinces')+':&nbsp;</td><td colspan=2><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-300)+'px;">'+p.join(', ')+'</div></td></tr>';
		// create notes link
		var notes = "";
		if (Tabs.Notes.noteValues[uid]) {
			notes = Tabs.Notes.noteValues[uid];
			notes = notes.text;
		}

		var dip = getDiplomacy(u.allianceId);
		if (dip == uW.g_js_strings.commonstr.friendly) { dip = 1; }
		else {
			if (dip == uW.g_js_strings.commonstr.hostile) { dip = 2; }
			else { dip = 0;	}
		}

		n += '<TR><TD class=xtab valign=top><a id=ptplayernoteslink>'+tx('Player Notes')+':</a></td><TD colspan=2 id=ptplayernotes class=xtabBRTop><div class="wrap" style="width:'+(GlobalOptions.btWinSize.x-300)+'px;">' + notes + '</div></td></tr>';
		n += '</table></td><td style="vertical-align:top;" align=right><table style="padding-right:0px;" class=xtab cellspacing=0 width=100%>';
		n += '<tr><TD style="padding-right:0px;" align=right><A target="_blank" href="https://www.facebook.com/profile.php?id=' + u.fbuid + '"><img src="https://graph.facebook.com/' + u.fbuid + '/picture"></a></td></tr>';
		n += '<tr><TD style="padding-right:0px;" align=right><A onclick="getInfoForAnUser(\''+u.userId+'\')">'+tx('Profile')+'</a></td></tr>';
		if (KOCBYTE_ON) n += '<tr><TD style="padding-right:0px;" align=right><A target="_blank" href="http://www.kocbyte.com/player/' + getServerId() + '/' + u.userId + '">'+tx('KoCByte')+'</a></td></tr>';
		n += '<tr><TD style="padding-right:0px;" align=right>'+MonitorLink(u.userId,tx('Throne Monitor'))+'</td></tr>';
		n += '<tr><TD style="padding-right:0px;" align=right><a onclick="ptViewChamps(\''+u.userId+'\',\''+u.name.replace(/\'/g, "")+'\')">'+tx('Champions Hall')+'</a></td></tr>';
		if ((allianceleader||trusted) && dip!=2) { // no invite option for hostiles
			n += '<tr><TD style="padding-right:0px;" align=right><SPAN onclick="ptInvite(this, \''+ u.userId +'\')"><A>'+uW.g_js_strings.membersInfo.invitealli+'</a></span></td></tr>';
		}
		n += '</table></td></tr></table></div>';

		ById('allPlayerInfo').innerHTML = n;

		ById('ptplayernoteslink').addEventListener('click',function() {Tabs.Notes.createPopup({id:uid,username:u.name});},false);
		ById('ptplayershowhide').addEventListener('click',t.PlayerShowHide,false);

		t.PaintDiplomacy(u.allianceId,dip,'diplo');

		var m = '<DIV class=divHeader style="padding-right:0px;"><TABLE width=100% cellspacing=0><TR><TD class=xtab>&nbsp;</td>';
		if (!locations) {
			m += '<TD class=xtab align=center>'+tx('City locations unavailable')+'</td>';
		}
		else {
			m += '<TD class=xtab align=center>'+uW.g_js_strings.commonstr.distance+'&nbsp;'+uW.g_js_strings.commonstr.from+'&nbsp;<SPAN id=distFrom>'+Cities.byID[t.ModelCityId].name+'&nbsp;('+Cities.byID[t.ModelCityId].x+','+Cities.byID[t.ModelCityId].y+')</span></td>';
		}
		m += '<TD class=xtab align=right>&nbsp;</td></tr></table></div>';
		if (locations) {
			m += '<div style="padding-right:6px;width:'+GlobalOptions.btWinSize.x+'px;overflow-x:scroll;height:200px;overflow-y:scroll;"><TABLE id=tabAllMembers align=left cellpadding=0 cellspacing=0 width=100%>';
			m += '<TR><TD nowrap><A id=clickCol0 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.player+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol1 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.might+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol2 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.rank+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol7 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.city+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol4 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Lvl')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol17 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.faction+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol16 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Protection Left')+'&nbsp;</span></a></td>\
				<TD nowrap><a id=clickCol9 class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="padding-right:10px;vertical-align:middle;display:inline-block;width:100%;"><INPUT id=ToggleScoutCheckbox type=checkbox></span></a></td>\
				<TD nowrap><A id=clickCol5 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Co-ords')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol8 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Distance')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol10 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:88%;">&nbsp;'+tx('ETA')+'&nbsp;</span></a></td>\
				</tr>';
			m += '<TBODY id=allBody></tbody></table></div>';
		}

		ById('allListOut').innerHTML = m;
		t.PaintGlory(uid);
		ById('allPlayerInfo').style.display = 'block';

		if (locations) {
			ById('allCitySelect').style.display = 'block';
		}
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		if (locations) {
			ById('clickCol' + Options.PlayerOptions.sortColNum).className = 'buttonv2 std green';
			ById('ToggleScoutCheckbox').addEventListener('change', t.doSelectall, false);
			t.RepaintList();
		}
	},

	PlayerShowHide : function() {
		var t = Tabs.Player;
		var a = ById('ptplayershowhide');
		t.hidePlayerInfo = !t.hidePlayerInfo;
		if (t.hidePlayerInfo) {
			disp = 'none';
			if (a) a.innerHTML = tx('Show Details');
		}else{
			disp = 'block';
			if (a) a.innerHTML = tx('Hide Details');
		}
		ById('ptplayerinfo').style.display = disp;
	},

	displayMembers: function (allName, numPlayers) {
		var t = Tabs.Player;

		var m = '<DIV class=divHeader style="padding-right:0px;"><TABLE width=100% cellspacing=0><TR><TD class=xtab>&nbsp;'+allName+'&nbsp;('+t.MemberListRslt.allianceId+')</td>';
        m += '<TD class=xtab align=center>'+uW.g_js_strings.commonstr.distance+'&nbsp;'+uW.g_js_strings.commonstr.from+'&nbsp;<SPAN id=distFrom>'+Cities.byID[t.ModelCityId].name+'&nbsp;('+Cities.byID[t.ModelCityId].x+','+Cities.byID[t.ModelCityId].y+')</span></td>';
		m += '<TD class=xtab align=right>'+numPlayers+'&nbsp;'+uW.g_js_strings.commonstr.members+'&nbsp;&nbsp;<a onclick="ptPaintMembers('+t.MemberListRslt.allianceId+',\''+allName.replace(/\'/g, "")+'\')">'+uW.g_js_strings.commonstr.viewmap+'</a>';
		if (KOCBYTE_ON) m += '&nbsp;&nbsp;<a target="_blank" href="http://www.kocbyte.com/alliance/' + getServerId() + '/' + t.MemberListRslt.allianceId + '"><img title="'+tx('View alliance on KoCByte')+'" style="width:16px;vertical-align:bottom;margin-top:-6px;" src="'+KOCBYTE_LOGO+'"></a>';
		m += '</td></tr></table></div>';
		m += '<div style="padding-right:6px;width:'+GlobalOptions.btWinSize.x+'px;overflow-x:scroll;height:500px;overflow-y:scroll;"><TABLE id=tabAllMembers align=left cellpadding=0 cellspacing=0 width=100%>';
		m += '<TR><TD nowrap><A id=clickCol0 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.player+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol1 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.might+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol2 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.rank+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol7 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.city+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol4 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Lvl')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol17 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.faction+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol16 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Protection Left')+'&nbsp;</span></a></td>\
				<TD nowrap><a id=clickCol9 class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="padding-right:10px;vertical-align:middle;display:inline-block;width:100%;"><INPUT id=ToggleScoutCheckbox type=checkbox></span></a></td>\
				<TD nowrap><A id=clickCol5 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Co-ords')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol8 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Distance')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=clickCol10 onclick="ptplayClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:88%;">&nbsp;'+tx('ETA')+'&nbsp;</span></a></td>\
				</tr>';
		m += '<TBODY id=allBody></tbody></table></div>';

		ById('allListOut').innerHTML = m;
		ById('allCitySelect').style.display = 'block';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('clickCol' + Options.PlayerOptions.sortColNum).className = 'buttonv2 std green';
		ById('ToggleScoutCheckbox').addEventListener('change', t.doSelectall, false);
		t.RepaintList();
	},

	clickedPlayerDetails : function (uid,online) {
		var t = Tabs.Player;
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		t.DisplayMessage(uW.g_js_strings.commonstr.loadingddd);

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.uid = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserGeneralInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					t.userobj = {};
					t.userobj[uid] = rslt.userInfo[0];
					t.userobj[uid].might = Math.round(t.userobj[uid].might);
					t.userobj[uid].online = (online?true:false);

					fetchPlayerCourt(uid, function (rslt2) {
						if (rslt2.ok) {
							u = unixTime();
							f = convertTime(new Date(rslt2.playerInfo.fogExpireTimestamp.replace(" ","T")+"Z"));
							t.userobj[uid].misted = (f >= u);
							t.userobj[uid].fogExpireTimestamp = rslt2.playerInfo.fogExpireTimestamp;
							t.userobj[uid].warStatus = rslt2.playerInfo.warStatus;
							t.userobj[uid].truceExpireTimestamp = rslt2.playerInfo.truceExpireTimestamp;
							t.userobj[uid].cityCount = rslt2.playerInfo.cityCount;
							t.userobj[uid].mightClassic = rslt2.playerInfo.mightClassic;
							t.userobj[uid].mightGlory = rslt2.playerInfo.mightGlory;
							t.userobj[uid].fbuid = parseInt(rslt2.playerInfo.fbuid);
							t.userobj[uid].lastLogin = rslt2.playerInfo.lastLogin;

							t.fetchPlayerLeaderboard(uid, function (r) { t.gotPlayerLeaderboard(r, uid) });
						}
						else {
							t.DisplayMessage(uW.g_js_strings.barbarian.erroroccured);
						}
					});
				}
				else {
					t.DisplayMessage(uW.g_js_strings.barbarian.erroroccured);
				}
			},
			onFailure: function () {t.DisplayMessage(uW.g_js_strings.errorcode.err_602);},
		});
	},

	fetchPlayerLeaderboard: function (uid, notify) {
		var t = Tabs.Player;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.userId = uid;
		params.type = "might";
		params.page = 1;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify(rslt); },
			onFailure: function () { notify({errorMsg: 'AJAX error'});},
		});
	},

	gotPlayerLeaderboard : function (rslt,uid) {
		var t = Tabs.Player;
		if (!rslt.ok) {
			t.DisplayMessage(rslt.errorMsg);
			return;
		}
		t.dat = [];
		var prestige = "";
		var aid = getMyAlliance()[0];
		if (rslt.totalResults == 0) {
			t.displayPlayer(uid,false);
			return;
		}

		var p = rslt.results[0];
		if (aid == p.allianceId) { t.friendEta = true; }
		else { t.friendEta = false; }
		for (var c = 0; c < p.cities.length; c++) {
			var pt = p.cities[c].prestigeType;
			var prestige = getFactionName(pt);
			if (prestige == "") { prestigelvl = ""; }
			else { prestigelvl = " (" + p.cities[c].prestigeLevel + ")"; }
			ExpTime = convertTime(new Date(p.cities[c].prestigeBuffExpire.replace(" ", "T")+"Z"));
			if ((ExpTime + (3600 * 24) < unixTime()) || isNaN(ExpTime)) {
				prestigeexp = "";
			} else {
				prestigeexp = t.getDuration(p.cities[c].prestigeBuffExpire);
			}
			t.dat.push([p.displayName, parseInt(p.might), p.officerType, parseInt(p.numCities), parseInt(p.cities[c].tileLevel),
				parseInt(p.cities[c].xCoord), parseInt(p.cities[c].yCoord), p.cities[c].cityName, 0, t.userobj[uid].online, '--',
				p.cities[c].cityId, prestige, p.userId, prestigelvl, prestigeexp, p.cities[c].prestigeBuffExpire, prestige + prestigelvl, p.cities[c].blessing,false]);
		}
		t.setDistances(Cities.byID[t.ModelCityId].x, Cities.byID[t.ModelCityId].y);
		t.setEta();
		t.displayPlayer(uid,true);
	},

	RepaintList: function () {
		var t = Tabs.Player;

		function sortFunc(a, b) {
			var t = Tabs.Player;
			if (typeof (a[Options.PlayerOptions.sortColNum]) == 'number') {
				if (Options.PlayerOptions.sortDir > 0)
					return a[Options.PlayerOptions.sortColNum] - b[Options.PlayerOptions.sortColNum];
				else
					return b[Options.PlayerOptions.sortColNum] - a[Options.PlayerOptions.sortColNum];
			} else if (typeof (a[Options.PlayerOptions.sortColNum]) == 'boolean') {
				return 0;
			} else {
				if (Options.PlayerOptions.sortDir > 0)
					return a[Options.PlayerOptions.sortColNum].localeCompare(b[Options.PlayerOptions.sortColNum]);
				else
					return b[Options.PlayerOptions.sortColNum].localeCompare(a[Options.PlayerOptions.sortColNum]);
			}
		}

		t.dat.sort(sortFunc);

		var m = '';
		var RowId = "";
		var r = 0;
		for (var i = 0; i < t.dat.length; i++) {
			RowId = 'ptplay_'+t.dat[i][5].toString()+'_'+t.dat[i][6].toString();
			var bless = showBlessings(t.dat[i][18]);
			if (bless != "") {
				var bless = '<a class=trimg><img style="vertical-align:bottom" src="'+IMGURL+'bonus_prestige.png"><SPAN class=trtip><table width=200 class=xtab>'+bless+'</table></span></a>';
			}
			var status = '<img title="Offline" style="vertical-align:bottom" src="'+OFFLINE+'"/>';
			if (t.dat[i][9] == 1) status = '<img title="Online" style="vertical-align:bottom" src="'+ONLINE+'"/>';

			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';
			if (t.dat[i][19]) rowClass += ' highRow';

			m += '<TR id="'+RowId+'" class="'+rowClass+'" style="max-height:30px"><TD class=xtab nowrap>'+status+'<SPAN onclick="ptPlayClick(\''+t.dat[i][13]+'\','+t.dat[i][9]+')"><A>'+t.dat[i][0]+'</a></span></td>';
			m += '<TD class=xtab align=right>'+(t.dat[i][1]==4294967295?'<span style="opacity:0.6"><i>4 BILLION +</i></span>':addCommasInt(t.dat[i][1]))+'</td>';
			m += '<TD class=xtab nowrap>'+officerId2String(t.dat[i][2])+'</td>';
			m += '<TD class=xtab nowrap>'+t.dat[i][7]+'</td>';
			m += '<TD class=xtab align=right>'+t.dat[i][4]+'</td>';
			m += '<TD class=xtab align=left nowrap>'+bless+t.dat[i][12]+t.dat[i][14]+'</td>';
			m += '<TD class=xtab align=center>'+t.dat[i][15]+'</td>';
			m += '<TD class=xtab align=center style="padding-left:4px;padding-right:0px;"><INPUT id=ptScout_'+t.dat[i][11]+' type=checkbox></td>';
			m += '<TD class=xtab align=center onclick="btGotoMap('+t.dat[i][5]+','+t.dat[i][6]+')"><A>'+t.dat[i][5]+','+t.dat[i][6]+'</a></td>';
			m += '<TD class=xtab align=right>'+t.dat[i][8].toFixed(2)+'</td>';
			m += '<TD class=xtab align=right>'+(t.dat[i][10]?'<SPAN>'+(t.dat[i][10]>0?timestr(t.dat[i][10],1):'--')+'</span>':'<SPAN>--</span>')+'</td>';
		}
		if (ById('allBody')) {
			ById('allBody').innerHTML = m;
			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		}
	},

	doSelectall: function () {
		var t = Tabs.Player;
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('ToggleScoutCheckbox').checked) ById('ptScout_' + city).checked = true;
			else ById('ptScout_' + city).checked = false;
		}
	},

	eventCoords: function (city, x, y) {
		var t = Tabs.Player;
		var m = '';
		if (city != null) {
			m = city.name + ' (' + city.x + ',' + city.y + ')';
			t.ModelCityId = city.id;
		}
		else {
			m = x + ',' + y;
		}
		var distFrom = ById('distFrom');
		if (distFrom)
			distFrom.innerHTML = m;
		t.setDistances(x, y);
		t.setEta();
		t.RepaintList();
	},

	getLastLogDuration : function (datestr){
		if (!datestr) return;
		var Interval = convertTime(new Date(datestr.replace(" ","T")+"Z")) - unixTime();
		if (Interval < 0) return uW.timestr(Interval*(-1)) +' ago';
		else return 'minutes ago';
	},

	ExportScoutList : function () {
		var t = Tabs.Player;

		var coordlist = "";
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('ptScout_' + city).checked) {
				coordlist += t.dat[k][5].toString()+','+t.dat[k][6].toString()+' ';
				ById('ptScout_' + city).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkScout.ImportCoords(coordlist.split(" "));
		}
	},

	ExportAttackList : function () {
		var t = Tabs.Player;

		var coordlist = "";
		var city = "";
		for (var k = 0; k < t.dat.length; k++) {
			city = t.dat[k][11].toString();
			if (ById('ptScout_' + city).checked) {
				coordlist += t.dat[k][5].toString()+','+t.dat[k][6].toString()+' ';
				ById('ptScout_' + city).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkAttack.ImportCoords(coordlist.split(" "));
		}
	},

	HighlightDefenders : function () {
		var t = Tabs.Player;

		var delayer = 0;
		ById('ptHighDefenders').outerHTML = '<span id=ptHighDefendersProg>&nbsp;</span>';

		for (var k = 0; k < t.dat.length; k++) {
			if (!t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]] || t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]]==0) {
				t.ReqSent[t.dat[k][5]+'_'+t.dat[k][6]]=1;
				setTimeout(getDefendStatus,(250*delayer),t.dat[k][5],t.dat[k][6],false,false,t.UpdateDefendStatus,k,t.dat.length,'ptHighDefendersProg');
				delayer = delayer + 1;
			}
		}

		function ClearAtEnd () {
			if (ById('ptHighDefendersProg')) {
				ById('ptHighDefendersProg').outerHTML = strButton20(tx('Highlight Defending Cities'),'id=ptHighDefenders');
				ById('ptHighDefenders').addEventListener('click', t.HighlightDefenders, false);
			}
		};

		setTimeout (ClearAtEnd,(250*delayer));
	},

	UpdateDefendStatus : function (rslt,x,y,k) {
		var t = Tabs.Player;
		t.ReqSent[x+'_'+y]=0;
		var div = ById('ptplay_'+x+'_'+y);
		var	city = t.dat[k][11].toString();
		if (rslt.ok && rslt.ok=="true") {
			t.dat[k][19] = true;
			if (div) jQuery(div).addClass("highRow");
			if (ById('ptScout_' + city)) ById('ptScout_' + city).checked = true;
		}
		else {
			t.dat[k][19] = false;
			if (div) jQuery(div).removeClass("highRow");
			if (ById('ptScout_' + city)) ById('ptScout_' + city).checked = false;
		}
	},

	PaintGlory: function (uid) {
		var t = Tabs.Player;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.userId = uid;
		params.ctrl = 'PlayerProfile';
		params.action = 'get';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					ById('ptPaintGlory').innerHTML = addCommas(rslt.profile.glory);
					ById('ptPaintMaxGlory').innerHTML = addCommas(rslt.profile.maxGlory);
					ById('ptPaintLifetimeGlory').innerHTML = addCommas(parseIntNan(rslt.profile.lifetimeGlory));
					ById('ptGloryIcon').innerHTML = '<img src="'+IMGURL+'chat_'+rslt.profile.gloryIconId+'.png">';
				}
				else {
					ById('ptPaintGlory').innerHTML = '(error)';
					ById('ptPaintMaxGlory').innerHTML = '(error)';
					ById('ptPaintLifetimeGlory').innerHTML = '(error)';
					ById('ptGloryIcon').innerHTML = '&nbsp;';
				}
			},
		},true);
	},

	getDuration: function (datestr) {
		var t = Tabs.Player;
		var Interval = convertTime(new Date(datestr.replace(" ", "T")+"Z")) - unixTime();
		if (Interval >= 0) {
			return uW.timestr(Interval);
		} else
			return '<span style="color:#800;">'+tx('Expired')+' ' + uW.timestr(Interval * (-1)) + ' '+tx('Ago')+'</span>';
	},

	clickedSendInvite : function (span, uid){
		var t = Tabs.Player;
		var popConfirm = null;
		popConfirm = new CPopup('ptConfirmAction', 0, -100, 500, 70, true, function () { clearTimeout(1000); });
		popConfirm.centerMe(mainPop.getMainDiv());
		var m = '<DIV style="height:50px;"><br><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="ptTab">';
		m += '<tr><TD align=center><INPUT id=ptConfirm type=submit value="'+uW.g_js_strings.changeview_court_content.invitealli+'" \>&nbsp;<INPUT id=ptCancel type=submit value="'+uW.g_js_strings.commonstr.cancel+'" \></td></tr></table></div>';
		popConfirm.getMainDiv().innerHTML = m;
		ResetFrameSize('ptConfirmAction',70,500);
		popConfirm.getTopDiv().innerHTML = '<DIV align=center><b>'+tx('Confirm Alliance Invite')+'?</b></div>';
		popConfirm.show(true);
		ById('ptConfirm').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;
			span.onclick = '';
			span.innerHTML = "Sending ...";
			t.invitePlayer (uid, function (r) {t.gotInviteResult(r, span)});
		}, false);
		ById('ptCancel').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;
		}, false);
	},

	invitePlayer : function (uid, notify){
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.type = 'userId';
		params.friendId = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceSendInviteToFriends.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) { notify (rslt); },
			onFailure: function () { notify ({errorMsg:'AJAX error'}); },
		});
	},

	gotInviteResult : function (rslt, span){
		var t = Tabs.Player;
		if (rslt.ok) {
			m = '<span style="color:black">Invite Sent!</span>';
		}
		else {
			m = '<span style="color:black">Send Invite Failed!</span>';
		}
		span.innerHTML = m;
	},

	setDiplomacy : function (aid,dip,elem){ // 1 - friendly, 0 - neutral, 2 - hostile
		var t = Tabs.Player;
		var popConfirm = null;
		popConfirm = new CPopup('ptConfirmAction', 0, -100, 500, 70, true, function () { clearTimeout(1000); });
		var DiploText = uW.g_js_strings.commonstr.neutral.toUpperCase();
		if (dip==1) DiploText = uW.g_js_strings.commonstr.friendly.toUpperCase();
		if (dip==2) DiploText = uW.g_js_strings.commonstr.hostile.toUpperCase();
		popConfirm.centerMe(mainPop.getMainDiv());
		var m = '<DIV style="height:50px;"><br><TABLE align=center cellpadding=0 cellspacing=0 width=100% class=xtab>';
		m += '<tr><TD align=center><INPUT id=ptConfirm type=submit value="'+uW.g_js_strings.commonstr.set+' '+DiploText+'" \>&nbsp;<INPUT id=ptCancel type=submit value="'+uW.g_js_strings.commonstr.cancel+'" \></td></tr></table></div>';
		popConfirm.getMainDiv().innerHTML = m;
		ResetFrameSize('ptConfirmAction',70,500);
		popConfirm.getTopDiv().innerHTML = '<DIV align=center><b>'+tx('Confirm Set Diplomacy')+'?</b></div>';
		popConfirm.show(true);
		ById('ptConfirm').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.allianceSelected = aid;
			params.diplomacyStatus = dip;
			new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceSetDiplomacies.php" + uW.g_ajaxsuffix, {
				method : "post",
				parameters : params,
				onSuccess : function(rslt) {
					if (rslt.ok) {
						t.PaintDiplomacy(aid,dip,elem);
					}
				}
			},true); // noretry
		}, false);
		ById('ptCancel').addEventListener('click', function () {
			popConfirm.show(false);
			popConfirm.onClose();
			popConfirm.destroy();
			popConfirm = null;
		}, false);
	},

	PaintDiplomacy : function (aid,dip,elem) {
		var t = Tabs.Player;
		if (ById(elem+aid)) {
			if (allianceleader) {
				t.friendbtn = '<INPUT style="color:#080;font-size:9px" onclick="ptSetDiplomacy('+aid+',1,\''+elem+'\');" type=submit value="F" />';
				t.neutralbtn = '<INPUT style="font-size:9px" onclick="ptSetDiplomacy('+aid+',0,\''+elem+'\');" type=submit value="N" />';
				t.hostilebtn = '<INPUT style="color:#800;font-size:9px" onclick="ptSetDiplomacy('+aid+',2,\''+elem+'\');" type=submit value="H" />';
			}

			if (dip == 1) {
				dip = '<span style="color:#080;"><b>'+uW.g_js_strings.commonstr.friendly+'</b></span>&nbsp;'+t.neutralbtn+'&nbsp;'+t.hostilebtn;
			}
			else {
				if (dip == 2) {
					dip = '<span style="color:#800;"><b>'+uW.g_js_strings.commonstr.hostile+'</b></span>&nbsp;'+t.friendbtn+'&nbsp;'+t.neutralbtn;
				}
				else {
					if (getMyAlliance()[0]!=aid) {
						dip = 'Neutral&nbsp;'+t.friendbtn+'&nbsp;'+t.hostilebtn;
					}
					else {
						dip = '<span style="color:#088;"><b>'+uW.g_js_strings.commonstr.yours+'</b></span>&nbsp;';
					}
				}
			}
			ById(elem+aid).innerHTML = dip;
		}
	},

	GetDataForMap: function (allianceId,allianceName) {
		var t = Tabs.Player;
		var params = uW.Object.clone(uW.g_ajaxparams);
		var Data = [];
		params.perPage = 100;
		params.allianceId = allianceId;
		params.type = "might";
		params.page = 1;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getUserLeaderboard.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				var city = '';
				for (var i = 0; i < rslt.results.length; i++) {
					if (rslt.results[i]['userId'] != 0) {
						player = rslt.results[i]['cities'];
						for (var ii = 0; ii < player.length; ii++) {
							Data.push({
								name: rslt.results[i]['displayName'],
								city: player[ii]['cityName'],
								X: player[ii]['xCoord'],
								Y: player[ii]['yCoord']
							});
						}
					}
				}
				if (Data != []) t.PaintDataOnMap(Data,allianceId,allianceName);
			},
			onFailure: function () { notify({ errorMsg: 'AJAX error' }); },
		});
	},
	PaintDataOnMap: function (Data,allianceId,allianceName) {
		var t = Tabs.Player;
		var provMapCoordsA = {
			imgWidth: 710,
			imgHeight: 708,
			mapWidth: 670,
			mapHeight: 670,
			leftMargin: 31,
			topMargin: 19
		};
		var map = '<div class=divHeader align=center><a onclick="ptGetMembers(' + allianceId + ')">'+allianceName+'</a></div><br><table align=center cellspacing=0 cellpadding=1><tr><td class=xtab align=left><DIV id=ptAlliProvMap style="height:' + provMapCoordsA.imgHeight + 'px; width:' + provMapCoordsA.imgWidth + 'px; background-repeat:no-repeat; background-image:url(\'' + URL_PROVINCE_MAP + '\')"></div></td><tr></table>';
		ById('allListOut').innerHTML = map;
		ById('allCitySelect').style.display = 'none';
		ById('allPlayerInfo').style.display = 'none';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		var eMap = ById('ptAlliProvMap');
		for (var cc = 0; cc < Seed.cities.length; cc++) {
			var city = Cities.cities[cc];
			var Xplot = parseInt((provMapCoordsA.mapWidth * city.x) / 750);
			var Yplot = parseInt((provMapCoordsA.mapHeight * city.y) / 750);
			var cf = document.createElement('div');
			cf.style.backgroundImage = "url('"+URL_CASTLE_BUT+"')";
			cf.style.backgroundSize = "16px 16px"
			cf.style.opacity = '1.0';
			cf.style.position = 'relative';
			cf.style.display = 'block';
			cf.style.width = '16px';
			cf.style.height = '16px';
			cf.style.border = '1px solid #000';
			cf.style.color = 'black';
			cf.style.fontWeight = 'bold';
			cf.style.fontSize = '10px';
			cf.style.textAlign = 'center';
			cf.style.top = (Yplot + provMapCoordsA.topMargin - (cc * 16) - 8) + 'px';
			cf.style.left = (Xplot + provMapCoordsA.leftMargin - 8) + 'px';
			cf.title = city.name+' ('+city.x+','+city.y+')';
			eMap.appendChild(cf);
			cf.innerHTML = (cc + 1) + '';
		}
		for (var i = 0; i < Data.length; i++) {
			var x = parseInt(Data[i]['X']);
			var y = parseInt(Data[i]['Y']);
			var name = Data[i]['name'];
			var city = Data[i]['city'];
			var xplot = parseInt((provMapCoordsA.mapWidth * x) / 750);
			var yplot = parseInt((provMapCoordsA.mapHeight * y) / 750);
			var ce = document.createElement('div');
			ce.style.background = 'red';
			ce.style.opacity = '1.0';
			ce.style.position = 'relative';
			ce.style.display = 'block';
			ce.style.width = '4px';
			ce.style.height = '4px';
			ce.style.color = 'white';
			ce.style.textAlign = 'center';
			ce.style.top = (yplot + provMapCoordsA.topMargin - (4 * i) - ((Seed.cities.length) * 18)) + 'px';
			ce.style.left = (xplot + provMapCoordsA.leftMargin - 2) + 'px';
			ce.title = name+ '\n'+city+' ('+x+','+y+')';
			ce.innerHTML = '<a onclick="btGotoMap('+x+','+y+')">&nbsp;</a>';
			eMap.appendChild(ce);
		}
	},

	ViewChamps: function (uid,name,calledfrom) {
		var t = Tabs.Player;
		var effectTiers = CE_EFFECT_TIERS;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.action = 'getEquipped';
		params.playerId = uid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/otherChampionHall.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if (t.popChamp) {
					t.popChamp.show(false);
					if (t.popChamp.onClose) t.popChamp.onClose();
					t.popChamp.destroy();
					t.popChamp = null;
				}
				t.popChamp = new CPopup('btChamp', t.champpos.x, t.champpos.y, 100, 100, true, function () { t.champpos = t.popChamp.getLocation(); clearTimeout(1000); });
				if ((t.champpos.x == -999) && (t.champpos.y == -999)) {
					if (calledfrom) {
						t.popChamp.centerMe(calledfrom);
					}
					else {
						t.popChamp.centerMe(mainPop.getMainDiv());
					}
				}
				var m = '<div>';
				if (rslt.ok) {
					m += '<div align=center><table width=99% cellpadding=1 cellspacing=1><tr>';
					for (var c in rslt.champion.champions) {
						var champ = rslt.champion.champions[c];
						if (champ.name && champ.status) {
							if (champ.status != '10') {champstat = '<span class=xtab style="color:#080">'+uW.g_js_strings.commonstr.status+':&nbsp;'+uW.g_js_strings.commonstr.defending+'</span>';}
							else { champstat = '<span class=xtab style="color:#f00">'+uW.g_js_strings.commonstr.status+':&nbsp;'+uW.g_js_strings.commonstr.marching+'</span>';}
							if (champ.assignedCity && champ.assignedCity!=0) {
								for (var cities in rslt.cities) {
									if (champ.assignedCity==rslt.cities[cities][0]) {
										champcity = uW.g_js_strings.commonstr.city+':&nbsp;'+rslt.cities[cities][1];
										break;
									}
								}
							}
							else {
								champcity = '<i>'+tx('No City Assigned')+'</i>';
								champstat = '&nbsp;';
							};
							m += '<td align=center style="vertical-align:top;" class=xtab><table style="vertical-align:top;border:1px solid black;"><tr><td colspan=2 style="background-color:'+Options.Colors.Panel+';"><table style="vertical-align:top;background-color:'+Options.Colors.Panel+';"><tr><td rowspan=3 class=xtab><img src="'+IMGURL+'champion_hall/championPort_0'+champ.avatarId+'_50x50.jpg"></td><td class=xtab><b>Name:&nbsp;'+champ.name+'</b></td></tr><tr><td class=xtab>'+champcity+'</td></tr><tr><td class=xtab>'+champstat+'</td></tr></table></td></tr>';

							// equipped items

							var equippedchampstats = JSON.parse(JSON.stringify(BaseChamp));
							var equippedtroopstats = {};
							var equippedbossstats = {};
							var might = 0;
							var SetBonus = {};
							for (var y in rslt.champion.equipment) { // calculate unique set bonuses
								var item = rslt.champion.equipment[y];
								if (item.equippedTo && item.equippedTo==champ.championId) {
									if (!item.quality) item.quality = parseIntNan(item.rarity);
									item.level = parseIntNan(item.level);
									for (var e in item.effects) {
										if (Number(e) <= Number(item.rarity)) {
											var id = item.effects[e].id;
											if (id >= 300 && id<400) {
												var Set = item.set;
												if (id==312) Set = 'U';
												if (id==313) Set = 'N';
												if (id==314) Set = 'D';
												var S = effectTiers;
												var P = id + "," + item.effects[e].tier;
												var tier = S[P];
												var base = +tier.Base || 0;
												var growth = +tier.Growth || 0;
												var level = Number(item.level) || 0;
												percent = Number(base + (level * growth));
												if (!SetBonus[Set]) { SetBonus[Set] = 0; }
												SetBonus[Set] += percent;
											}
										}
									}
								}
							}
							for (var y in rslt.champion.equipment) {
								var item = rslt.champion.equipment[y];
								if (item.equippedTo && item.equippedTo==champ.championId) {
									if (!item.quality) item.quality = parseIntNan(item.rarity);
									item.level = parseIntNan(item.level);
									might += CardMight(item);
									for (var e in item.effects) {
										if (Number(e) <= Number(item.rarity)) {
											var id = item.effects[e].id;
											var S = effectTiers;
											var P = id + "," + item.effects[e].tier;
											var tier = S[P];
											var base = +tier.Base || 0;
											var growth = +tier.Growth || 0;
											var level = Number(item.level) || 0;
											var bonus = 0;
											if (id<300 || id>=400) {
												bonus = SetBonus[item.set] || 0;
												if (item.itemId && item.itemId!="0" && SetBonus['U']) bonus += SetBonus['U'];
												if ((!item.itemId || item.itemId=="0") && SetBonus['N']) bonus += SetBonus['N'];
												//if (SetBonus['D']) bonus += SetBonus['D'];
											}
											var percent = Number(base + ((level * level + level) * growth * 0.5));
											if (id >= 300) {
												percent = Number(base + (level * growth));
											}
											if (id>=400) {
												if (!equippedbossstats[item.itemId]) { equippedbossstats[item.itemId] = {}; }
												if (!equippedbossstats[item.itemId][id]) { equippedbossstats[item.itemId][id] = 0; }
												equippedbossstats[item.itemId][id] += percent + (percent*bonus);
											}
											else {
												if (id>=200) {
													if (!equippedchampstats[id]) { equippedchampstats[id] = 0; }
													equippedchampstats[id] += percent + (percent*bonus);
												}
												else {
													if (!equippedtroopstats[id]) { equippedtroopstats[id] = 0; }
													equippedtroopstats[id] += percent;
												}
											}
										}
									}
								}
							}
							m += '<tr><td class=xtab colspan=2><b>Might:&nbsp;</b>'+addCommas(might)+'</td></tr>';
							m += '<tr><td colspan=2 class=xtab><b>'+uW.g_js_strings.report_view.champion_stats+'</b></td></tr>';
							for (var k in equippedchampstats) {
								str = eval('uW.g_js_strings.effects.name_'+k);
								if (k>= 300) {
									if (k==314) { str = '<span style="color:#808;">'+tx('Add. Defend Bonus')+'</span>'; }
									else { str = '<span style="color:#808;">'+tx('Inc. Bonus')+' '+str.split(" "+tx("equipment"))[0]+'</span>'; }
									var champvalue = '<span style="color:#808;">'+((equippedchampstats[k]*100).toFixed(2))+"%</span>";
								}
								else {
									var champvalue = +(equippedchampstats[k].toFixed(2));
								}
								if (str && str!= "") { m += '<tr><td class=xtab>'+str+':</td><td class=xtab>'+champvalue+'</td></tr>'; }
							}
							m += '<tr><td colspan=2 class=xtab><b>'+uW.g_js_strings.report_view.troop_stats+'</b></td></tr>';
							var gottroops = false;
							for (var k in equippedtroopstats) {
								var TRStyles = getTREffectStyle(k);
								gottroops=true;
								str = eval('uW.g_js_strings.effects.name_'+k);
								if (str && str!= "") { m += '<tr><td class=xtab>'+TRStyles.LineStyle+str+':'+TRStyles.EndStyle+'</td><td class=xtab>'+TRStyles.LineStyle+(Math.round(equippedtroopstats[k]*100)/100)+TRStyles.EndStyle+'</td></tr>'; }
							}
							if (!gottroops) {
								m += '<tr><td colspan=2 class=xtab><i>'+tx('No Troop Stats')+'</i></td></tr>';
							}
							for (var k in equippedbossstats) {
								var gotboss = false;
								var bosseffects = '';
								for (var kk in equippedbossstats[k]) {
									gotboss = true;
									str = eval('uW.g_js_strings.effects.name_'+kk);
									var champvalue = '<span style="color:#000;">'+(equippedbossstats[k][kk].toFixed(2))+"%</span>";
									if (str && str!= "") { 	bosseffects+="<tr><td class=xtab>"+str+"</td><td class=xtab>"+champvalue+"</td></tr>"; }
								}
								if (gotboss) { m += "<tr><td colspan=2 class=xtab><b>"+uW.itemlist['i'+k].name+' '+uW.g_js_strings.commonstr.stats+"</b></td></tr>"+bosseffects; }
							}
							m += '</table></td>';
						}
					}
					m += '</tr></table></div><div align=center>'+strButton20(tx('Refresh'), 'id=ptchamprefresh')+'</div>';
				}
				else {
					if (rslt.msg) {
						m += '<div align=center><br>'+rslt.msg+'<br></div>';
					}
					else {
						m += '<div align=center><br>'+tx('Unknown error trying to display champion hall')+'</div>';
					}
					m += '<div align=center><br>'+strButton20(tx('Refresh'), 'id=ptchamprefresh')+'<br></div>';
				}
				m += '</div>';
				t.popChamp.getMainDiv().innerHTML = m;

				ById('ptchamprefresh').addEventListener('click',function() {t.ViewChamps(uid,name);}, false);

				t.popChamp.getTopDiv().innerHTML = '<DIV style="white-space:nowrap;" align=center>&nbsp;&nbsp;<B>'+name+'\'s '+uW.g_js_strings.champ.title+'</B>&nbsp;&nbsp;</DIV>';
				t.popChamp.show(true);
				ResetFrameSize('btChamp',100,100);
			},
		},true);
	},

	DisplayMessage : function(msg) {
		ById('allListOut').innerHTML = '<BR><BR><CENTER>'+msg+'</center>';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	show : function (init){
		var t = Tabs.Player;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
		AreYouALeader();
	},
}

/**************************** Gift Tab ****************************************/
Tabs.Gift = {
	tabLabel: 'Gifts',
	tabOrder: 2110,
	tabColor : 'brown',
	myDiv: null,
	Available: new Array(),
	PeopleLoaded: false,
	LoopCounter: 0,
	freeSlot:0,
	dat:[],
	HardLimit:22,
	Options: {
		people: {}, // uid {[(0) gift id, (1) sent, (2) display name, (3) received, (4) avatar, (5) fbuid, (6) last gift sent, (7) last gift received, (8) name]} ...
		giftitems: [],
		DefaultGift: 0,
		GiftPriority: 0,
		AutoGift: false,
		ScanGift: false,
		LastGifted : 0,
		GiftsLastUpdated : 0,
		NextGiftType : 0,
		sortColNum: 7,
		sortDir: 1,
	},

// t.dat for sorting
// 0 - uid
// 1 - name
// 2 - sent
// 3 - lastsent
// 4 - received
// 5 - lastreceived
// 6 - giftid
// 7 - status

	init: function (div) {
		var t = Tabs.Gift;
        t.myDiv = div;

		if (!Options.GiftOptions) {
			Options.GiftOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.GiftOptions.hasOwnProperty(y)) {
					Options.GiftOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('ptgiftClickSort', Tabs.Gift.giftClickSort);
		uWExportFunction('ptgiftDelete', Tabs.Gift.DeletePerson);

		var now = unixTime();
//		if (Options.GiftOptions.GiftsLastUpdated + (3600*24) < now) { // only check gifts once a day (they never change!!)
			t.PopulateGifts();
//		}

		t.PopulatePeople(); // always set up gift database??

		if (Options.GiftOptions.ScanGift) {
			setTimeout(function() { t.scangifts(4);},12000); // scan first 4 pages for gifts after initialisation
		}
	},

	giftClickSort : function (e) {
		var t = Tabs.Gift;
		var newColNum = e.id.substr(7);
		ById('GiftCol' + Options.GiftOptions.sortColNum).className = 'buttonv2 std blue';
		e.className = 'buttonv2 std green';
		if (newColNum == Options.GiftOptions.sortColNum) { Options.GiftOptions.sortDir *= -1; }
		else { Options.GiftOptions.sortColNum = newColNum; }
		saveOptions();
		t.PaintPeople();
	},

	PopulatePeople : function (notify) {
		var t = Tabs.Gift;
		t.Available = new Array();

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = 'allianceGifting\\AllianceGiftingServiceAjax';
		params.action = 'getRecipients';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch53.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if(rslt.ok) {
					t.PeopleLoaded = true;
					t.freeSlot = rslt.freeSlot;
					for(i = 0;i<rslt.recipients.length;i++) {
						t.Available.push(rslt.recipients[i].userId);
						var sex = uW.g_js_strings.commonstr.lord;
						if (rslt.recipients[i].playerSex=="F") { sex = uW.g_js_strings.commonstr.lady; }
                        var name = sex+' '+rslt.recipients[i].displayName;
						if(Options.GiftOptions.people[Number(rslt.recipients[i].userId)]) {
							Options.GiftOptions.people[Number(rslt.recipients[i].userId)][2] = name; // update display name
							Options.GiftOptions.people[Number(rslt.recipients[i].userId)][4] = rslt.recipients[i].avatarId; // update avatar
							Options.GiftOptions.people[Number(rslt.recipients[i].userId)][8] = rslt.recipients[i].displayName; // update name
						}else{
							Options.GiftOptions.people[rslt.recipients[i].userId] = [Options.GiftOptions.DefaultGift,0,name,0,rslt.recipients[i].avatarId,rslt.recipients[i].fbuid,0,0,rslt.recipients[i].displayName];
						}
					}
					if (notify) notify();
				}
			},
		},true);
	},

	PopulateGifts : function (){
		var t = Tabs.Gift;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = "GiftItems";
		params.action = "getGiftItems";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					Options.GiftOptions.GiftsLastUpdated = unixTime();
					Options.GiftOptions.giftitems = rslt.giftItems;
					saveOptions();
				};
			},
		},true);
	},

	ClearGiftList : function (){
		var t = Tabs.Gift;
		Options.GiftOptions.people={};
		saveOptions();
		t.PopulatePeople(t.PaintPeople);
	},

	DeletePerson : function (uid) {
		var t = Tabs.Gift;
		delete Options.GiftOptions.people[""+uid];
		saveOptions();
		t.PopulatePeople(t.PaintPeople);
	},

	sendgifts : function () {
		var t = Tabs.Gift;

		if (!t.PeopleLoaded) {
			t.PopulatePeople(t.sendgifts);
			return;
		}

		var g = Options.GiftOptions.NextGiftType;
		if (g >= Options.GiftOptions.giftitems.length) { g = 0; }
		var FirstGiftType = -1;
		do { // loop at least once
			var ItemId = Number(Options.GiftOptions.giftitems[g].itemId);
			var j = new Array();
			for (var i in Options.GiftOptions.people) {
				if (Number(Options.GiftOptions.people[i][0]) == ItemId) {
					if (t.Available.indexOf(i) != -1) {
						j.push(i);
					}
				}
			}
			if (j.length) {
				if (FirstGiftType < 0) { FirstGiftType = g; }
				if(j.length > 1){
					var n = j.length;
					if (Options.GiftOptions.GiftPriority==0) { // random (Fisher-Yates Shuffle)
						var tempArr = shuffle(j);
					};
					if (Options.GiftOptions.GiftPriority==1) { // even distribution - sort by sent (1)
						var tempArr = j.sort(function(a,b){ return parseIntNan(Options.GiftOptions.people[a][1])-parseIntNan(Options.GiftOptions.people[b][1])});
					};
					if (Options.GiftOptions.GiftPriority==2) { // most received - sort by received reversed (3)
						var tempArr = j.sort(function(a,b){ return parseIntNan(Options.GiftOptions.people[b][3])-parseIntNan(Options.GiftOptions.people[a][3])});
					};
					if (Options.GiftOptions.GiftPriority==3) { // last received - sort by lastreceived reversed (7)
						var tempArr = j.sort(function(a,b){ return parseIntNan(Options.GiftOptions.people[b][7])-parseIntNan(Options.GiftOptions.people[a][7])});
					};
					if (tempArr.length > t.HardLimit) { j=tempArr.slice(0,t.HardLimit); }
					else { j=tempArr; }
				}
				t.sendgift(ItemId,j);
			};
			g++;
			if (g >= Options.GiftOptions.giftitems.length) { g = 0; }
		}
		while (g != Options.GiftOptions.NextGiftType);
		// next time, start loop at item after the first item found this time, to ensure even distribution
		g = FirstGiftType+1;
		if (g >= Options.GiftOptions.giftitems.length) { g = 0; }
		Options.GiftOptions.NextGiftType = g;
		saveOptions();
	},

	sendgift : function (giftId, recipients) {
		var t = Tabs.Gift;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.ctrl = 'allianceGifting\\AllianceGiftingServiceAjax';
		params.action = 'sendGift';
		params.recipients = String(recipients).replace(/,/g,"|");
		params.itemId = giftId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch53.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if(rslt.ok) {
					for(i = 0;i<rslt.succeedRecipients.length;i++) {
						var z = rslt.succeedRecipients[i];
						Options.GiftOptions.people[Number(z)][1] += 1;
						Options.GiftOptions.people[Number(z)][6] = unixTime();
					};
					actionLog(uW.itemlist["i"+giftId].name+' sent to '+rslt.succeedRecipients.length+' recipients','GIFTS');
					saveOptions();
				}
				else {
					if (rslt.error_code) {
						actionLog('Error sending gifts (Error Code '+rslt.error_code+')','GIFTS');
					}
					else {
						actionLog('Error sending gifts','GIFTS');
					}
				};
				t.PopulatePeople(t.PaintPeople);
			},
         },true);
	},

	scangifts : function(page) {
		var t = Tabs.Gift;
		page = Number(page);
		if(!Options.GiftOptions.ScanGift) {return;}
		if(page <= 0) {return;}
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType = "GET_MESSAGE_HEADERS_FOR_USER_INBOX";
		params.boxType="inbox";
		params.pageNo=page;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					for (var i in rslt.message) {
						if (rslt.message[i].subject) {
							var GiftMessage = false;
							for (var j in GiftText) {
								if (rslt.message[i].subject.indexOf(GiftText[j]) != -1) {
									GiftMessage = true;
									break;
								}
							}
							if(rslt.message[i].fromUserId == "0" && GiftMessage){
								t.foundgift(i);
							}
						}
					}
					setTimeout(function() {	t.scangifts(parseInt(page-1))},5000);
				} else return;
			},
		},true);
	},

	foundgift : function (id) {
		var t = Tabs.Gift;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.messageId=id;
		params.requestType = "GET_MESSAGE_FOR_ID";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var name = rslt.messageBody.split(" ")[0]+" "+rslt.messageBody.split(" ")[1];
					for(x in Options.GiftOptions.people) {
						if(Options.GiftOptions.people[x][2] == name) {
							Options.GiftOptions.people[x][3] += 1;
							Options.GiftOptions.people[x][7] = unixTime();
							saveOptions();
							break;
						}
					}
					t.PaintPeople();
					t.deletemsgs(id);
				}
			},
		},true);
	},

	deletemsgs : function (msgid) {
		var t = Tabs.Gift;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType="ACTION_ON_MESSAGES";
		params.selectedAction="delete";
		params.selectedMessageIds=msgid;
		params.boxType="inbox";
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {},
		},true);
	},

	PaintGiftStats : function() {
		var t = Tabs.Gift;
		var sentgifts = 0;
		for(h in Options.GiftOptions.people){
			sentgifts += parseIntNan(Options.GiftOptions.people[h][1]);
		};
		ById('giftnumber').innerHTML=sentgifts;
		ById('giftnumbertoday').innerHTML=t.freeSlot;
	},

	PaintPeople : function() {
		var t = Tabs.Gift;
		var peopletab = ById('GiftsTAB');
		if (!peopletab) return;

		function sortFunc(a, b) {
			var t = Tabs.Gift;
			if (typeof (a[Options.GiftOptions.sortColNum]) == 'number') {
				if (Options.GiftOptions.sortDir > 0)
					return a[Options.GiftOptions.sortColNum] - b[Options.GiftOptions.sortColNum];
				else
					return b[Options.GiftOptions.sortColNum] - a[Options.GiftOptions.sortColNum];
			} else if (typeof (a[Options.GiftOptions.sortColNum]) == 'boolean') {
				return 0;
			} else {
				if (Options.GiftOptions.sortDir > 0)
					return a[Options.GiftOptions.sortColNum].localeCompare(b[Options.GiftOptions.sortColNum]);
				else
					return b[Options.GiftOptions.sortColNum].localeCompare(a[Options.GiftOptions.sortColNum]);
			}
		}

		t.dat = [];

		var GiftsAvailable = (t.freeSlot != 0);
		var EmptyDatabase = true;

		for (var h in Options.GiftOptions.people) {
			if (Options.GiftOptions.people[h][5]) { // fbuid
				EmptyDatabase = false;
				var StatusText = '';
				if (t.Available.indexOf(h) == -1) {
					var sentdate = "";
					if (Options.GiftOptions.people[h][6] && Options.GiftOptions.people[h][6] != 0) {
						sentdate = formatDate(Options.GiftOptions.people[h][6]);
					}
					var StatusText = '<span style="color:#800;">'+tx('Player unavailable')+'</span>';
					if (sentdate==formatDate(unixTime())) {
						StatusText = '<span style="color:#080;">'+tx('Gift sent today')+'</span>';
					}
					else {
						if (!GiftsAvailable) {
							StatusText = '('+tx('No more gifts can be sent today')+')';
						}
					}
				}
				t.dat.push([h,(Options.GiftOptions.people[h][8]?Options.GiftOptions.people[h][8]:Options.GiftOptions.people[h][2]),Options.GiftOptions.people[h][1],Options.GiftOptions.people[h][6],Options.GiftOptions.people[h][3],Options.GiftOptions.people[h][7],Options.GiftOptions.people[h][0],StatusText]);
			}
		}

		if (!EmptyDatabase) {
			t.dat.sort(sortFunc);

			var m = '<center><table width=98% cellspacing=0 cellpadding=0 class=xtab>';
			m += '<TR><td width=25>&nbsp;</td><TD align=left nowrap><A id=GiftCol1 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.player+'&nbsp;</span></a></td>\
				<TD width=100 nowrap><A id=GiftCol2 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Sent')+'&nbsp;</span></a></td>\
				<TD width=70 align=right nowrap><A id=GiftCol3 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Last Sent')+'&nbsp;</span></a></td>\
				<TD width=100 nowrap><A id=GiftCol4 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Received')+'&nbsp;</span></a></td>\
				<TD width=70 align=right nowrap><A id=GiftCol5 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Last Received')+'&nbsp;</span></a></td>\
				<TD width=100 align=left nowrap><A id=GiftCol6 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Gift to Send')+'&nbsp;</span></a></td>\
				<TD width=200 align=left nowrap><A id=GiftCol7 onclick="ptgiftClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.status+'&nbsp;</span></a></td>\
				<TD width=25 nowrap>&nbsp;</td>\
				</tr>';

			var r = 0;

			for (var G in t.dat) {
				var h = t.dat[G][0]; // uid
				if (h) {
					var StatusText = t.dat[G][7];
					r=r+1;
					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';

					m += t.FormatPerson(h,rowClass,StatusText);
				}
			}
			m += '</table></center>';
		}
		else {
			m = '<div align=center><br><br>'+tx('No gifting entries available. You may need to wait a day for the gift database to re-populate')+'...</div>';
		}
		peopletab.innerHTML = m;
		if (!EmptyDatabase) {
			ById('GiftCol' + Options.GiftOptions.sortColNum).className = 'buttonv2 std green';
		}

		var element_class = ById('GiftsTAB').getElementsByClassName('giftstosend');
		for (var c=0; c < element_class.length; c++) {
			if (element_class[c]) {
				element_class[c].addEventListener('change', function(e) {
					if (Options.GiftOptions.people[Number(e.target.id)]) {
						Options.GiftOptions.people[Number(e.target.id)][0] = Number(e.target.value);
						saveOptions();
					};
				} , false);
			}
		}

		t.PaintGiftStats();
	},

	FormatPerson : function (h,rowClass,StatusText) {
		var name = Options.GiftOptions.people[h][2];
		var fbuid = Options.GiftOptions.people[h][5];
		var sentdate = "";
		var receiveddate = "";
		if (Options.GiftOptions.people[h][6] && Options.GiftOptions.people[h][6] != 0) {
			sentdate = formatDate(Options.GiftOptions.people[h][6]);
		}
		if (Options.GiftOptions.people[h][7] && Options.GiftOptions.people[h][7] != 0) {
			receiveddate = formatDate(Options.GiftOptions.people[h][7]);
		}
		var avatar = '<A target="_blank" href="https://www.facebook.com/profile.php?id=' + fbuid + '"><img width=25 style="vertical-align:middle;" src="https://graph.facebook.com/' + fbuid + '/picture"></a>';
		var n = '';
		n += '<tr class="'+rowClass+'"><td width=25 style="padding:1px;">' + avatar + '</td><td>'+PlayerLink(h,name)+'</td>';
		n += '<td align=center>'+Options.GiftOptions.people[h][1]+'</td><td align=right>'+sentdate+'</td><td align=center>'+Options.GiftOptions.people[h][3]+'</td><td align=right>'+receiveddate+'</td>';
		n += '<td><select class="giftstosend" id="'+h+'" name="'+name+'"><option value="0">None</option>';
		for (var g=0;g < Options.GiftOptions.giftitems.length;g++) {
			if (Options.GiftOptions.people[Number(h)][0] == Number(Options.GiftOptions.giftitems[g].itemId))
				n += '<option value="'+Options.GiftOptions.giftitems[g].itemId+'" selected="selected">'+Options.GiftOptions.giftitems[g].name+'</option>';
			else
				n += '<option value="'+Options.GiftOptions.giftitems[g].itemId+'">'+Options.GiftOptions.giftitems[g].name+'</option>';
		}
		n += '</select></td>';
		n += '<td>'+StatusText+'</td>';
		n += '<td>'+strButton8(tx('Del'),'onClick="ptgiftDelete('+h+')"')+'</td></tr>';
		return n;
	},

	show: function (){
		var t = Tabs.Gift;

		var m = '<DIV class=divHeader align=center>'+tx('GIFT ADMINISTRATION')+'</div>';
		m += '<table align=center width=98% class=xtab><tr><td width=20%>&nbsp;</td><td align=center><INPUT id=giftssend type=submit value="'+uW.g_js_strings.directory_changetab.sendgifts+'">&nbsp;<INPUT id=resetgiftlist type=submit value="'+tx('Reset Gift Database')+'"></td><td width=20% align=right>'+tx('Total Gifts Sent')+':&nbsp;<span id=giftnumber></span></td></tr>';
		m += '<tr><td colspan=2>&nbsp;</td><td align=right>'+tx('Gifts Remaining for Today')+':&nbsp;<span id=giftnumbertoday></span></td></tr></table>';
		m += '<DIV class=divHeader align=center>'+tx('GIFT OPTIONS')+'</DIV>';
		m += '<table align=center width=98% class=xtab><tr><td>&nbsp;</td><td width=100>'+tx('Default Gift to send')+':&nbsp;</td><td><select id="giftsdefault">';
		m += '<option value="0">'+uW.g_js_strings.commonstr.none+'</option>';
		for(g =0;g < Options.GiftOptions.giftitems.length;g++) {
			if (Options.GiftOptions.giftitems[g].itemId==Options.GiftOptions.DefaultGift) {
				m+='<option value="'+Options.GiftOptions.giftitems[g].itemId+'" selected="selected">'+Options.GiftOptions.giftitems[g].name+'</option>';
			}
			else {
				m+='<option value="'+Options.GiftOptions.giftitems[g].itemId+'">'+Options.GiftOptions.giftitems[g].name+'</option>';
			}
		};
		m += '</select>&nbsp;<INPUT class=btInput id=giftssetall type=submit value="'+tx('Set All')+'">&nbsp;<INPUT class=btInput id=giftssetnew type=submit value="'+tx('Set All Unassigned')+'"></td></tr>';
		m += '<tr><td>&nbsp;</td><td>'+tx('Gift Recipient Priority')+':&nbsp;</td><td>'+htmlSelector({0: tx('Random'), 1: tx('Even distribution'), 2: tx('Most gifts received'), 3: tx('Last received')}, Options.GiftOptions.GiftPriority, 'id=giftspriority')+'</td></tr>';
		m += '<tr><td><INPUT id=pbaugift type=checkbox '+ (Options.GiftOptions.AutoGift?' CHECKED':'') +'\></td><td colspan=2>'+tx('Enable Automatic Gifting')+'</td></tr>';
		m += '<tr><td><INPUT id=pbadgift type=checkbox '+ (Options.GiftOptions.ScanGift?' CHECKED':'') +'\></td><td colspan=2>'+tx('Delete incoming gift messages (and log entries in gift database)')+'</td></tr></table>';
		m += '<DIV class=divHeader align=center>'+tx('GIFT DATABASE')+'</DIV>';
		m += '<DIV style="max-width:'+GlobalOptions.btWinSize.x+'px;height:400px; max-height:400px; overflow-y:scroll" id=GiftsTAB><div align=center><br><br>'+tx('Loading Database')+'...</div></DIV><br>';

		t.myDiv.innerHTML = m;

		t.PopulatePeople(t.PaintPeople);

		ById('resetgiftlist').addEventListener('click', function(){ t.ClearGiftList(); } , false);
		ById('giftssend').addEventListener('click', function(){ t.sendgifts(); } , false);

		ChangeOption('GiftOptions','giftsdefault','DefaultGift');
		ChangeOption('GiftOptions','giftspriority','GiftPriority');

		ById('giftssetall').addEventListener('click', function() {
			var element_class = ById('GiftsTAB').getElementsByClassName('giftstosend');
			for (var c = 0; c < element_class.length; c++) {
				element_class[c].value = Options.GiftOptions.DefaultGift;
				Options.GiftOptions.people[Number(element_class[c].id)][0] = Number(Options.GiftOptions.DefaultGift);
			};
			saveOptions();
		}, false);

		ById('giftssetnew').addEventListener('click', function(){
			var element_class = ById('GiftsTAB').getElementsByClassName('giftstosend');
			for (var c = 0; c < element_class.length; c++) {
				if (element_class[c].value==0) {
					element_class[c].value = Options.GiftOptions.DefaultGift;
					Options.GiftOptions.people[Number(element_class[c].id)][0] = Number(Options.GiftOptions.DefaultGift);
				}
			};
			saveOptions();
		}, false);

		ById('pbadgift').addEventListener('change', function(){
			Options.GiftOptions.ScanGift = this.checked;
			saveOptions();
			if(Options.GiftOptions.ScanGift) { t.scangifts(4); }
		}, false);

		ById('pbaugift').addEventListener('change', function(){
			Options.GiftOptions.AutoGift = this.checked;
			Options.GiftOptions.LastGifted = 0; // always reset timer
			saveOptions();
		}, false);
	},

	EverySecond : function () {
		var t = Tabs.Gift;

		if (t.PeopleLoaded) {
			var now = unixTime();
			if (Options.GiftOptions.AutoGift && Options.GiftOptions.LastGifted + 3600 < now) { // hourly check for autogifting
				t.sendgifts();
				Options.GiftOptions.LastGifted = now;
				saveOptions();
			}
		}

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter >= 60) {
			t.LoopCounter = 0;
			// check for gifts on first page every 60 seconds..
			t.scangifts(1);
		}
	},
}

/**************************** Defences Tab ****************************************/
Tabs.Fort = {
	tabLabel: 'Fortify',
	tabOrder: 2010,
	tabColor : 'brown',
	myDiv: null,
	timer:null,
	LoopCounter:0,
	DefTotal:0,
	ModelCity: null,
	ModelCityId: 0,
	serverwait: false,
	MaxDefTrain: 0,
	wall: {},
	isBusy: false,
	QueLength: 0,
	limitingFactor: null,
	autodelay: 0,
	typeDelay: 5, // 5 seconds between each type
	intervalSecs: 30, // 30 seconds between each loop
	typearray: {1:[0,1,2,3,4],2:[0,1,2,3,4],3:[0,1,2,3,4],4:[0,1,2,3,4],5:[0,1,2,3,4],6:[0,1,2,3,4],7:[0,1,2,3,4],8:[0,1,2,3,4]}, // change the sort order each time, so every type gets a fair shout
	LastAuto: -1,
	Options: {
		Running: true,
		packetAmount: 50,
		doTraps:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		doCaltrops:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		doSpikes:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		doXbows:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		doTrebs:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		doGreek:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		Toggle:		false,
	},

	init: function (div) {
		var t = Tabs.Fort;
        t.myDiv = div;

		if (!Options.FortOptions) {
			Options.FortOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.FortOptions.hasOwnProperty(y)) {
					Options.FortOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('cancelFort',Tabs.Fort.cancelFort);
		uWExportFunction('btDefCancelAll',Tabs.Fort.cancelAll);

		if (Options.FortOptions.Toggle) AddSubTabLink('AutoFort',t.toggleAutoFortState, 'FortifyToggleTab');
		SetToggleButtonState('Fortify',Options.FortOptions.Running,'Fortify');

		var m = '<DIV class=divHeader align=center>'+tx('WALL DEFENCE OVERVIEW')+'</div>';
		m += '<div align="center">';
        m += '<table width=100% height=0% class=xtab><tr><td width=30%><INPUT id=btFortToggle type=checkbox '+ (Options.FortOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button")+'</td><td colspan=2 align=center><INPUT id=btAutoFortState type=submit value="'+tx("AutoBuild")+' = '+ (Options.FortOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>&nbsp;</td></tr></table>';
		m += '<DIV id=btDefOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">&nbsp;</div></div><HR>';
		m += '<br><DIV style="text-align:center; margin-bottom:5px;">'+uW.g_js_strings.commonstr.city+':&nbsp;<span id=ptdefcity></span></div>';

		m += '<a id=btDefOptionLink class=divLink><div class="divHeader" align="left"><img id=btDefOptionArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('SET DEFENCES')+'</div></a>';
		m += '<div id=btDefOption>';

		m += '<TABLE align=center cellpadding=0 cellspacing=0 class=xtab width=98%><TR><TD valign=top width=49%>';
		m += '<TABLE class=xtab><tr><td colspan=3>&nbsp;</td></tr><tr><TD align=right>'+tx('Defence Type')+':&nbsp;</td><TD colspan=2>';
		m += '<SELECT id=btDefType>';
		for (var a in uW.fortcost) {
			var f = parseInt(a.split("frt")[1]);
			m += '<option value='+f+'>'+uW.fortcost[a][0]+'</option>';
		}
		m += '</select></td></tr><tr><td>&nbsp;</td><td colspan=2>(<span id=btDefMax>&nbsp;</span>)</td></tr>';
		m += '<TR><TD align=right>'+tx('Number to build')+':&nbsp;</td><TD><INPUT id=btDefNumPerSlot size=5 type=text value=0\></td>';
		m += '<TD><a id=btDefMaxPerSlotButton class="inlineButton btButton brown8"><span>Max</span></a>&nbsp;('+uW.g_js_strings.commonstr.max;
		m += ':&nbsp;<span id=btDefMaxPerSlot>0</span>)</td></tr>';
		m += '<TR><TD align=right>'+tx('Number of slots to use')+':&nbsp;</td>';
		m += '<TD><INPUT id=btDefNumSlots size=2 type=text value=1\></td>';
		m += '<TD><a id=btDefMaxSlotsButton class="inlineButton btButton brown8"><span>Max</span></a>&nbsp;('+uW.g_js_strings.commonstr.max;
		m += ':&nbsp;<span id=btDefMaxSlots>0</span>)</td></tr>';
		m += '<TR><TD align=right>'+tx('Speedup')+':&nbsp;</td><td colspan=2><SELECT id=btDefBoost>';
		m += '<option value="0">-- '+uW.g_js_strings.commonstr.select+' --</center></option>';
		m += '<option value="26">'+uW.itemlist.i26.name+' ('+(Seed.items.i26?Seed.items.i26:0)+')</option></select></td></tr>';
		m += '<tr><td>&nbsp;</td><td colspan=2><INPUT id=btDefButton type=button value="'+uW.g_js_strings.modal_openWalls.builddefenses+'"\></td></tr></table>';
		m += '</TD><TD valign=top width=49%><TABLE class=xtab><tr><td><b>'+uW.g_js_strings.commonstr.requirements+':-</b></td></tr>';
		m += '<tr><td valign=top id="btDefRequirements">&nbsp;</td></tr>';
		m += '</table>';

		m += '</td></tr><tr><td colspan=2><div id=btDefMessages align=center>&nbsp;</div></td></tr></table></div>';

		m += '<a id=btDefAutoLink class=divLink><div class="divHeader" align="left"><img id=btDefAutoArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('AUTO BUILD')+'</div></a>';
		m += '<div id=btDefAuto class=divHide>';

		m += '<table class=xtab align=center>';
		m += '<tr style="vertical-align:top;"><td width=30 rowspan=2><img src="'+IMGURL+'units/unit_60_30.jpg" /></td><td width=15%>'+tx('Traps')+'</td>';
		m += '<td width=30 rowspan=2><img src="'+IMGURL+'units/unit_61_30.jpg" /></td><td width=15%>'+tx('Caltrops')+'</td>';
		m += '<td width=30 rowspan=2><img src="'+IMGURL+'units/unit_62_30.jpg" /></td><td width=15%>'+tx('Spikes')+'</td>';
		m += '<td width=30 rowspan=2><img src="'+IMGURL+'units/unit_53_30.jpg" /></td><td width=15%>'+tx('Crossbows')+'</td>';
		m += '<td width=30 rowspan=2><img src="'+IMGURL+'units/unit_55_30.jpg" /></td><td width=15%>'+tx('Trebuchet')+'</td>';
		m += '<td width=30 rowspan=2><img src="'+IMGURL+'units/unit_63_30.jpg" /></td><td width=15%>'+tx('Greek Fire')+'</td></tr>';

		m += '<tr style="vertical-align:top;"><td><INPUT type=CHECKBOX id=chkDoTraps></td><td><INPUT type=CHECKBOX id=chkDoCaltrops></td>';
		m += '<td><INPUT type=CHECKBOX id=chkDoSpikes></td><td><INPUT type=CHECKBOX id=chkDoXbows></td><td><INPUT type=CHECKBOX id=chkDoTrebs></td><td><INPUT type=CHECKBOX id=chkDoGreek></td></tr>';
		m += '<tr><td colspan=9 align=left>('+tx('Will queue')+'&nbsp;<INPUT class=btInput id=btDefPacket type=text size=10 maxlength=7 value="'+Options.FortOptions.packetAmount+'"\>&nbsp;'+tx('units at a time until all available wall/field space used')+')</td>';
		m += '<td colspan=3 align=right><a id=btDefAutoCopy>'+tx('Copy settings to all cities')+'</a>&nbsp;&nbsp;</td></tr></table></div>';

		m += '<a id=btDefQueueLink class=divLink><div class="divHeader" align="left"><table cellpadding=0 cellspacing=0 width=100%><tr><td class=xtab><img id=btDefQueueArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('DEFENCE QUEUE')+'</td><td class=xtab align=right id=btDefQueueStats>&nbsp;</td></tr></table></div></a>';
		m += '<div id=btDefQueue style="max-height:200px;overflow-y:scroll;"></div><br>';

		div.innerHTML = m;

		t.ModelCity = new CdispCityPicker('ptdef', ById('ptdefcity'), true, t.clickCitySelect, null);

		ById('btAutoFortState').addEventListener('click', function(){
			t.toggleAutoFortState(this);
		}, false);

		ToggleOption('FortOptions','btFortToggle','Toggle');

		ById('btDefAutoCopy').addEventListener('click', function(e){
			var citynum = Cities.byID[t.ModelCityId].idx+1;
			t.CopyAutoFortSettings(citynum);
			saveOptions();
			ById('btDefMessages').innerHTML = 'Auto-fortify settings copied to all cities';
		}, false);

		ById('btDefOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Defence",100,GlobalOptions.btWinSize.x,"btDefOption",false)}, false);
		ById('btDefAutoLink').addEventListener ('click', function () {ToggleMainDivDisplay("Defence",100,GlobalOptions.btWinSize.x,"btDefAuto",false)}, false);
		ById('btDefQueueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Defence",100,GlobalOptions.btWinSize.x,"btDefQueue",false)}, false);

		ById('btDefType').addEventListener('change', t.PaintCityInfo, false);

		ById('btDefMaxPerSlotButton').addEventListener('click', function () {
			var slots = Math.max(parseIntNan(ById('btDefNumSlots').value),0);
			ById('btDefNumPerSlot').value = parseIntNan(t.MaxDefTrain / slots);
			t.paintRequirements(ById('btDefType').value);
		} ,false);

		ById('btDefNumPerSlot').addEventListener('change', function () {
			t.paintRequirements(ById('btDefType').value);
		}, false);

		ById('btDefNumSlots').addEventListener('change', function () {
			var slots = Math.max(parseIntNan(ById('btDefNumSlots').value),0);
			if (slots < 1) { slots = 1; }
			if (slots > t.wall.wallLevel-t.wall.Queued) { slots = t.wall.wallLevel-t.wall.Queued; }
			ById('btDefNumSlots').value = slots;
			ById('btDefMaxPerSlot').innerHTML = parseIntNan(t.MaxDefTrain / slots);
		} ,false);

		ById('btDefMaxSlotsButton').addEventListener('click', function () {
			ById('btDefNumSlots').value = Math.max(t.wall.wallLevel-t.wall.Queued,0);
			var slots = Math.max(parseIntNan(ById('btDefNumSlots').value),0);
			ById('btDefMaxPerSlot').innerHTML = parseIntNan(t.MaxDefTrain / slots);
		} ,false);

		ChangeIntegerOption('FortOptions','btDefPacket','packetAmount',50);

		ById('btDefButton').addEventListener ('click', t.setDefences, false);

		ById('chkDoTraps').addEventListener('change', t.clickCheckDoTraps, false);
		ById('chkDoCaltrops').addEventListener('change', t.clickCheckDoCaltrops, false);
		ById('chkDoSpikes').addEventListener('change', t.clickCheckDoSpikes, false);
		ById('chkDoXbows').addEventListener('change', t.clickCheckDoXbows, false);
		ById('chkDoTrebs').addEventListener('change', t.clickCheckDoTrebs, false);
		ById('chkDoGreek').addEventListener('change', t.clickCheckDoGreek, false);

		// start autotrain loop timer to start in 30 seconds...

		if (Options.FortOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(1,0);}, (30 * 1000));
		}
	},

	toggleAutoFortState: function(obj){
		var t = Tabs.Fort;
		obj = ById('btAutoFortState');
		if (Options.FortOptions.Running == true) {
			Options.FortOptions.Running = false;
			obj.value = tx("AutoBuild = OFF");
		}
		else {
			Options.FortOptions.Running = true;
			obj.value = tx("AutoBuild = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1,0);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Fortify',Options.FortOptions.Running,'Fortify');
		t.PaintOverview();
	},

	show: function (init) {
		var t = Tabs.Fort;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
		t.PaintOverview();
		t.UpdateDefenceOptions();
		t.PaintCityInfo();
	},

	EverySecond : function () {
		var t = Tabs.Fort;

		if (tabManager.currentTab.name == 'Fort' && Options.btWinIsOpen){
			t.LoopCounter = t.LoopCounter + 1;

			if (t.LoopCounter%2==0) { // refresh queue display every 2 seconds
				t.PaintCityInfo();
			}

			if (t.LoopCounter >= 6) { // refresh overview display every 6 seconds
				t.LoopCounter = 0;
				t.PaintOverview();
			}
		}
	},

	clickCitySelect: function (city) {
		var t = Tabs.Fort;
		t.ModelCityId = city.id;
		t.LastQueue = 'x';
		t.UpdateDefenceOptions();
		t.PaintCityInfo();
	},

	CopyAutoFortSettings : function (citynum) {
		var t = Tabs.Fort;
		for (var i = 1; i <= Cities.numCities; i++) {
			if (i!=citynum) {
				Options.FortOptions.doTraps[i] = Options.FortOptions.doTraps[citynum];
				Options.FortOptions.doCaltrops[i] = Options.FortOptions.doCaltrops[citynum];
				Options.FortOptions.doSpikes[i] = Options.FortOptions.doSpikes[citynum];
				Options.FortOptions.doXbows[i] = Options.FortOptions.doXbows[citynum];
				Options.FortOptions.doTrebs[i] = Options.FortOptions.doTrebs[citynum];
				Options.FortOptions.doGreek[i] = Options.FortOptions.doGreek[citynum];
			}
		}
	},

	setDefences: function () {
		var t = Tabs.Fort;

		if (t.isBusy) {
			t.isBusy = false;
			ById('btDefMessages').innerHTML = '<span style="color:#800;">'+tx('Cancelled')+'!</span>';
			ById('btDefButton').value = uW.g_js_strings.modal_openWalls.builddefenses;
			return;
		}

		var cityId = t.ModelCityId;
		var unitId = ById('btDefType').value;
		var perSlot = parseIntNan(ById('btDefNumPerSlot').value);
		var numSlots = parseIntNan(ById('btDefNumSlots').value);
		var siege = ById('btDefBoost').value;

		if (perSlot < 1) { return; }
		if (numSlots < 1) { return; }

		if (perSlot * numSlots > t.MaxDefTrain) {
			ById('btDefMessages').innerHTML = '<span style="color:#800;">'+uW.g_js_strings.modal_attack.maxtroops+': '+t.MaxDefTrain + '</span>';
			return;
		}
		if (numSlots > t.wall.wallLevel-t.wall.Queued) {
			ById('btDefMessages').innerHTML = '<span style="color:#800;">'+tx('Maximum number of slots exceeded')+'!</span>';
			return;
		}

		var que = [];
		for (var i = 0; i < numSlots; i++) {
			que.push(['T', unitId, perSlot, siege]);
		}
		t.QueLength = que.length;
		t.isBusy = true;
		ById('btDefButton').value = uW.g_js_strings.commonstr.cancel;
		t.nextqueue(que);
	},

	nextqueue : function (que){
		var t = Tabs.Fort;
		if(!t.isBusy) { return; }

		var cmd = que.shift();

		if (cmd[0] == 'T') {
			if (t.QueLength == 1) {
				ById('btDefMessages').innerHTML = 'Building '+cmd[2]+' '+uW.fortcost['frt'+cmd[1]][0]+' at '+Cities.byID[t.ModelCityId].name;
			}
			else {
				ById('btDefMessages').innerHTML = 'Building '+cmd[2]+' '+uW.fortcost['frt'+cmd[1]][0]+' at '+Cities.byID[t.ModelCityId].name + ' (Slot '+parseIntNan(t.QueLength-que.length)+' of '+t.QueLength+')';
			}
			t.Fortify (t.ModelCityId, cmd[3], cmd[1], cmd[2], function (rslt) {
				if (rslt.ok) {
					if (parseIntNan(que.length)==0) {
						ById('btDefMessages').innerHTML = 'Completed!';
						ById('btDefButton').value = uW.g_js_strings.modal_openWalls.builddefenses;
						t.isBusy = false;
						return;
					}
					setTimeout(function () { t.nextqueue(que) }, 2000); }
				else {
					if (rslt.msg) {
						ById('btDefMessages').innerHTML = '<span style="color:#800;">'+rslt.msg+'</span>';
					}
					else {
						ById('btDefMessages').innerHTML = '<span style="color:#800;">Error setting defences ('+rslt.error_code+')</span>';
					}
					ById('btDefButton').value = uW.g_js_strings.modal_openWalls.builddefenses;
					t.isBusy = false;
					return;
				}
			});
		}
	},

	clickCheckDoTraps: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doTraps[cityNo] = (ById('chkDoTraps').checked);
		saveOptions();
		if (Options.FortOptions.doTraps[cityNo]) {
			t.doAutoLoop(cityNo,0);
		}
	},

	clickCheckDoCaltrops: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doCaltrops[cityNo] = (ById('chkDoCaltrops').checked);
		saveOptions();
		if (Options.FortOptions.doCaltrops[cityNo]) {
			t.doAutoLoop(cityNo,1);
		}
	},

	clickCheckDoSpikes: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doSpikes[cityNo] = (ById('chkDoSpikes').checked);
		saveOptions();
		if (Options.FortOptions.doSpikes[cityNo]) {
			t.doAutoLoop(cityNo,2);
		}
	},

	clickCheckDoXbows: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doXbows[cityNo] = (ById('chkDoXbows').checked);
		saveOptions();
		if (Options.FortOptions.doXbows[cityNo]) {
			t.doAutoLoop(cityNo,3);
		}
	},

	clickCheckDoTrebs: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doTrebs[cityNo] = (ById('chkDoTrebs').checked);
		saveOptions();
		if (Options.FortOptions.doTrebs[cityNo]) {
			t.doAutoLoop(cityNo,4);
		}
	},

	clickCheckDoGreek: function () {
		var t = Tabs.Fort;
		var cityNo = Cities.byID[t.ModelCityId].idx + 1;
		Options.FortOptions.doGreek[cityNo] = (ById('chkDoGreek').checked);
		saveOptions();
		if (Options.FortOptions.doGreek[cityNo]) {
			t.doAutoLoop(cityNo,5);
		}
	},

	doAutoLoop : function (idx,typ) {
		var t = Tabs.Fort;
		clearTimeout(t.timer);
		if (!Options.FortOptions.Running) return;

		var cityId = Cities.cities[idx - 1].id;
		t.autodelay = 0;

		var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[idx]);

		if (t.typearray[idx][typ]==0) {
			if (Options.FortOptions.doTraps[idx] && t.CheckCanBuild(60,cityId) && ascensionok) { t.doAutoDefence(60,cityId,typ); }
		}
		if (t.typearray[idx][typ]==1) {
			if (Options.FortOptions.doCaltrops[idx] && t.CheckCanBuild(61,cityId) && ascensionok) { t.doAutoDefence(61,cityId,typ); }
		}
		if (t.typearray[idx][typ]==2) {
			if (Options.FortOptions.doSpikes[idx] && t.CheckCanBuild(62,cityId) && ascensionok) { t.doAutoDefence(62,cityId,typ); }
		}
		if (t.typearray[idx][typ]==3) {
			if (Options.FortOptions.doXbows[idx] && t.CheckCanBuild(53,cityId) && ascensionok) { t.doAutoDefence(53,cityId,typ); }
		}
		if (t.typearray[idx][typ]==4) {
			if (Options.FortOptions.doTrebs[idx] && t.CheckCanBuild(55,cityId) && ascensionok) { t.doAutoDefence(55,cityId,typ); }
		}
		if (t.typearray[idx][typ]==5) {
			if (Options.FortOptions.doGreek[idx] && t.CheckCanBuild(63,cityId) && ascensionok) { t.doAutoDefence(63,cityId,typ); }
		}

		if (typ<5) {
			t.timer = setTimeout(function () { t.doAutoLoop(idx,typ+1); }, (t.autodelay * 1000));
		}
		else {
			// if training happened in this city during this loop, change type order of this city for next time so every type gets a fair go..
			if (t.LastAuto != -1) {
				for (var v=0; v<=6; v++) {
					t.LastAuto++;
					if (t.LastAuto > 5) { t.LastAuto = 0; }
					t.typearray[idx][v] = t.LastAuto;
				}
				t.LastAuto = -1;
			}
			if (idx == Cities.numCities) {
				t.timer = setTimeout(function () { t.doAutoLoop(1,0); }, (t.intervalSecs * 1000));
			}
			else {
				t.timer = setTimeout(function () { t.doAutoLoop(idx+1,0); }, (t.autodelay * 1000));
			}
		}
	},

	doAutoDefence: function (defType,cityId,typ) {
		var t = Tabs.Fort;
		var numberToTrain = t.getMaxDefence(defType,cityId,true);
		if (numberToTrain > 0) {
			if (numberToTrain > Options.FortOptions.packetAmount) {
				numberToTrain = Options.FortOptions.packetAmount;
			}
			t.Fortify(cityId, 0, defType, numberToTrain);
			t.autodelay = t.typeDelay;
			t.LastAuto = typ;
		}
	},

	getMaxDefence: function (defType,cityId,auto) {
		var t = Tabs.Fort;
		var numberToTrain = 0;
		t.limitingFactor = null;
		var wall = {};
		getWallInfo(cityId, wall);
		if (defType<60 || defType==63) { var availableSpace = wall.wallSpace - wall.wallSpaceUsed - wall.wallSpaceQueued; }
		else { var availableSpace = wall.fieldSpace - wall.fieldSpaceUsed - wall.fieldSpaceQueued; }
		var MaxSlots = wall.wallLevel;
		if (auto && MaxSlots > 5) MaxSlots = 5; // only allow auto build to occupy 5 slots
		if (availableSpace > 0 && wall.slotsBusy < MaxSlots) {
			var availableSlots = MaxSlots - wall.slotsBusy;
			var unitSpace = parseInt(uW.fortstats["unt" + defType][5]);

			var food = parseIntNan(Seed.resources['city' + cityId].rec1[0] / 3600);
			var wood = parseIntNan(Seed.resources['city' + cityId].rec2[0] / 3600);
			var stone = parseIntNan(Seed.resources['city' + cityId].rec3[0] / 3600);
			var ore = parseIntNan(Seed.resources['city' + cityId].rec4[0] / 3600);

			// change these numbers for auto if in the future you want KEEP resource values in city.
			var foodRes = 0;
			var woodRes = 0;
			var stoneRes = 0;
			var oreRes = 0;

			var availFood = food - foodRes;
			var availWood = wood - woodRes;
			var availStone = stone - stoneRes;
			var availOre = ore - oreRes;

			var unitFood = parseInt(uW.fortcost['frt'+defType][1]);
			var unitWood = parseInt(uW.fortcost['frt'+defType][2]);
			var unitStone = parseInt(uW.fortcost['frt'+defType][3]);
			var unitOre = parseInt(uW.fortcost['frt'+defType][4]);

			if (defType == 63) var unitMedian = uW.fortcost['frt'+defType][11]["34002"];
			var median = parseIntNan(Seed.items.i34002); // greek fire requires median oil

			numberToTrain = 9999999999;
			if ((availFood / unitFood) < numberToTrain) {
				t.limitingFactor = uW.resourceinfo['rec1'];
				numberToTrain = parseInt(availFood / unitFood);
			}
			if ((availWood / unitWood) < numberToTrain) {
				t.limitingFactor = uW.resourceinfo['rec2'];
				numberToTrain = parseInt(availWood / unitWood);
			}
			if ((availStone / unitStone) < numberToTrain) {
				t.limitingFactor = uW.resourceinfo['rec3'];
				numberToTrain = parseInt(availStone / unitStone);
			}
			if ((availOre / unitOre) < numberToTrain) {
				t.limitingFactor = uW.resourceinfo['rec4'];
				numberToTrain = parseInt(availOre / unitOre);
			}

			if (defType == 63) {
				if ((median / unitMedian) < numberToTrain) {
					t.limitingFactor = 'median';
					numberToTrain = parseInt(median / unitMedian);
				}
			}

			if (availableSpace >= unitSpace && availableSlots > 0) {
				if (availFood > unitFood && availWood > unitWood & availStone > unitStone & availOre > unitOre) {
					if ((availableSpace / unitSpace) < numberToTrain) {
						numberToTrain = parseInt(availableSpace / unitSpace);
					}
				}
				else {
					numberToTrain = 0;
				}
			}
			else {
				numberToTrain = 0;
			}
		}
		return numberToTrain;
	},

	CheckCanBuild : function (defType,cityId) {
		var t = Tabs.Fort;
		var Result = true;
		var Buildings = getCityBuildings(cityId);
		var fc = uW.fortcost['frt'+defType];
		if (matTypeof(fc[8]) == 'object'){
			for (var k in fc[8]){
				var b = Buildings[k.substr(1)];
				if (b.maxLevel < fc[8][k][1]){
					Result = false;
					break;
				}
			}
		}
		if (matTypeof(fc[9]) == 'object'){
			for (var k in fc[9]){
				if (parseInt(Seed.tech['tch'+k.substr(1)]) < fc[9][k][1]){
					Result = false;
					break;
				}
			}
		}
		return Result;
	},

	PaintOverview : function () {
		var t = Tabs.Fort;
		var rownum = 0;
		var irows = [];
		var	rows = [];

		function _row(name, row, noTotal, icon) {
			var t = Tabs.Fort;
			if (rownum++ % 2)
				style = ' class="evenRow"';
			else
				style = ' class="oddRow"';
			var tot = 0;
			var m = [];
			m.push('<TR align=right');
			m.push(style);
			if (noTotal) {
				m.push('><TD colspan=2');
			}
			else {
				m.push('><TD');
			}
			m.push(' style="padding-left: 0px;"');
			m.push('>');
			if (icon) {
				m.push(icon);
			}
			else {
				m.push('<B>'+name+'&nbsp;</B>');
			}
			m.push('</td>');
			if (!noTotal) {
				for (var i = 0; i < row.length; i++)
					tot += row[i];
				m.push('<TD><div class="totalCell xtabBorder">');
				t.DefTotal[name] = tot;
				m.push(addCommas(tot));
				m.push('</div></td>');
			}
			for (var i = 0; i < row.length; i++) {
				m.push('<TD');
				m.push(style);
				m.push('><div class=xtabBorder>');
				m.push(addCommas(row[i]));
				m.push('</div></td>');
			}
			m.push('</tr>');
			return m.join('');
		}

		var m = '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td align=right width=100><b>&nbsp;</b></td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btDefCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}

		m += "<td>&nbsp;</td></tr>"; // spacer

		irows = [];
		irows[0] = []; // wall level
		irows[1] = []; // Defensive Tower Level
		irows[2] = []; // Wall Space
		irows[3] = []; // Field Space
		irows[4] = []; // Defence Queue
		irows[5] = []; // Redoubt Tower Level

		for (var i = 0; i < Cities.numCities; i++) {
			cityId = Cities.cities[i].id;
			var wall = {};
			getWallInfo(cityId,wall);

			irows[0][i] = tx('Level')+' '+wall.wallLevel;
			if (wall.wallLevel==0) { irows[0][i] = '<SPAN class=boldRed><B>'+tx('None')+'!</b></span>'; }

			var tower = Seed.buildings['city'+cityId].pos99;
			if (tower) tower = parseInt(Seed.buildings['city'+cityId].pos99[1])
			if (!tower)
				irows[1][i] = '<SPAN class=boldRed><B>'+tx('None')+'!</b></span>';
			else
				irows[1][i] = tx('Level')+' '+tower;

			var tower = Seed.buildings['city'+cityId].pos98;
			if (tower) tower = parseInt(Seed.buildings['city'+cityId].pos98[1])
			if (!tower)
				irows[5][i] = '<SPAN class=boldRed><B>'+tx('None')+'!</b></span>';
			else
				irows[5][i] = tx('Level')+' '+tower;

			irows[2][i] = wall.wallSpaceUsed+' / '+wall.wallSpace;
			if (wall.wallSpaceUsed < wall.wallSpace) { irows[2][i] = '<SPAN class=boldRed><B>'+irows[2][i]+'</b></span>'; }
			irows[3][i] = wall.fieldSpaceUsed+' / '+wall.fieldSpace;
			if (wall.fieldSpaceUsed < wall.fieldSpace) { irows[3][i] = '<SPAN class=boldRed><B>'+irows[3][i]+'</b></span>'; }

			var totTime = 0;
			var now = unixTime();
			var q = Seed.queue_fort['city'+cityId];
			if (q != null && q.length > 0)
				totTime = q[q.length - 1][3] - now;
			if (totTime < 0)
				totTime = 0;
			if (totTime < 1 && (wall.wallSpaceUsed < wall.wallSpace - 4 || wall.fieldSpaceUsed < wall.fieldSpace - 4))
				irows[4][i] = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
			else
				irows[4][i] = timestr(totTime);
		}

		m += _row(tx('Wall Space'), irows[2], true);
		rows = [];
		var r = 0;
		for (var a in uW.fortcost) {
			var f = parseInt(a.split("frt")[1]);
			if (f<60 || f==63) { // fucking RockYou idiots
				rows[r] = [];
				for (var i = 0; i < Cities.numCities; i++) {
					cityId = Cities.cities[i].id;
					rows[r][i] = parseIntNan(Seed.fortifications["city" + cityId]["fort"+f]);
				}
				m += _row(uW.fortcost[a],rows[r],false,TroopImage(f));
				r++;
			}
		}
		m += _row(tx('Field Space'), irows[3], true);
		for (var a in uW.fortcost) {
			var f = parseInt(a.split("frt")[1]);
			if (f>=60 && f!=63) { // fucking RockYou idiots
				rows[r] = [];
				for (var i = 0; i < Cities.numCities; i++) {
					cityId = Cities.cities[i].id;
					rows[r][i] = parseIntNan(Seed.fortifications["city" + cityId]["fort"+f]);
				}
				m += _row(uW.fortcost[a],rows[r],false,TroopImage(f));
				r++;
			}
		}

		m += '<TR><TD>&nbsp;</td></tr>';

		m += _row(tx('Walls'), irows[0], true);
		m += _row(tx('Def. Tower'), irows[1], true);
		m += _row(tx('Redoubt Tower'), irows[5], true);
		m += _row(tx('Defence Queue'), irows[4], true);

		m += '</table>';

		ById('btDefOverviewDiv').innerHTML = m;
	},

	fixQueTimes: function (q) {
		// fix KofC bugs ....
		// if first start time > now, make it now
		// if any end time != next start time then fix it
		var now = unixTime();
		if (q[0][2] > now) { q[0][2] = now; }
		for (var i = 0; i < q.length; i++) {
			if (q[i + 1] != null && q[i + 1][2] != q[i][3]) { q[i][3] = q[i + 1][2]; }
		}
	},

	expireTheQueue: function (q) {
		if (q == null) return;
		var now = unixTime();
		while (q.length > 0 && (q[0][3] - now) < 1) q.shift();
	},

	UpdateDefenceOptions : function () {
		var t = Tabs.Fort;

		ById('chkDoTraps').checked = Options.FortOptions.doTraps[Cities.byID[t.ModelCityId].idx + 1];
		ById('chkDoCaltrops').checked = Options.FortOptions.doCaltrops[Cities.byID[t.ModelCityId].idx + 1];
		ById('chkDoSpikes').checked = Options.FortOptions.doSpikes[Cities.byID[t.ModelCityId].idx + 1];
		ById('chkDoXbows').checked = Options.FortOptions.doXbows[Cities.byID[t.ModelCityId].idx + 1];
		ById('chkDoTrebs').checked = Options.FortOptions.doTrebs[Cities.byID[t.ModelCityId].idx + 1];
		ById('chkDoGreek').checked = Options.FortOptions.doGreek[Cities.byID[t.ModelCityId].idx + 1];
	},

	PaintCityInfo : function () {
		var t = Tabs.Fort;
		var cityId = t.ModelCityId;

		if (cityId==0) { return; }
		if (t.serverwait) { return; }

		// paint the Queue...

		var now = unixTime();
		t.wall = {};
		getWallInfo(cityId, t.wall);
		t.wall.Queued = 0;
		var totTime = 0;
		var q = Seed.queue_fort['city' + cityId];
		t.expireTheQueue(q);

		var qs = q.toString();
		if (q != null && q.length > 0) {
			totTime = q[q.length - 1][3] - now;
			t.wall.Queued = q.length;
		}
		if (qs == t.LastQueue) { // queue hasn't changed, just update the time of the current item
			if (q != null && q.length > 0) {
				var cur = q[0][3] - now;
				ById('btDefQueueRemaining').innerHTML = timestr(cur, true);
			}
			else {
				m = '<br><div align=center style="opacity:0.3;">'+tx('No Defence Units Under Construction')+'</div>';
				ById('btDefQueue').innerHTML = m;
			}
		} else {
			t.LastQueue = qs;
			if (q != null && q.length > 0) {
				m = '<TABLE width=98% cellspacing=0 align=center class=xtab><tr><th class=xtabHD align=left>'+uW.g_js_strings.commonstr.type+'</th><th class=xtabHD align=right>'+uW.g_js_strings.commonstr.amount+'</th><th class=xtabHD align=right>'+tx('Total Time')+'</th><th class=xtabHD align=right>'+tx('Remaining')+'</th><th class=xtabHD align=right><a id=btDefCancelAllButton class="inlineButton btButton red14" onclick="btDefCancelAll('+cityId+')"><span>'+tx('Cancel All')+'</span></a></th></tr>';
				t.fixQueTimes(q);
				first = true;
				var lastEnd = now;
				var r = 0;

				for (var i = 0; i < q.length; i++) {
					start = q[i][2];
					end = q[i][3];
					actual = end - lastEnd;
					if (actual < 0) { actual = 0; }

					rowClass = 'evenRow';
					var rem = (r % 2);
					if (rem == 1) rowClass = 'oddRow';
					if (first) rowClass += ' highRow';

					m += '<TR class="'+rowClass+'"><TD align=left>'+TroopImage(q[i][0])+uW.fortcost["frt"+q[i][0]][0]+'</td><td align=right>'+addCommas(q[i][1])+'</td><td align=right>';
					if (first) { m += timestr(end - start, true) + '</td><TD align=right><SPAN id=btDefQueueRemaining>' + timestr(actual, true) + '</span></td>'; }
					else { m += timestr(actual, true) + '</td><td align=right>&nbsp;</td>'; }
					m += '<td align=right><A class="inlineButton btButton brown11" onclick="cancelFort(' + q[i][0] + ',' + q[i][1] + ',' + q[i][2] + ',' + q[i][3] + ',' + q[i][5] + ',' + q[i][6] + ',' + cityId + ',' + i + ')"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr>'
					lastEnd = end;
					first = false;
					r++;
				}
				m += '</table><div align=center id=btDefQueueMessage>&nbsp;</div>';
			}
			else {
				m = '<br><div align=center style="opacity:0.3;">'+tx('No Defence Units Under Construction')+'</div>';
			}
			ById('btDefQueue').innerHTML = m;
			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		}
		m = t.wall.Queued+' '+uW.g_js_strings.commonstr.of+' '+t.wall.wallLevel;
		if (totTime > 0)
			m += ', ' + uW.timestr(totTime);
		ById('btDefQueueStats').innerHTML = m;

		// paint info into the city panel...

		var unitId = ById('btDefType').value;
		var defOwned = parseInt(Seed.fortifications['city' + cityId]['fort' + unitId]);
		t.MaxDefTrain = 0;
		if (t.CheckCanBuild(unitId,cityId)) {
			t.MaxDefTrain = t.getMaxDefence(unitId,cityId);
		}

		ById('btDefMax').innerHTML = uW.g_js_strings.commonstr.max + ':&nbsp;' + t.MaxDefTrain + ',&nbsp;' + uW.g_js_strings.commonstr.owned + ':&nbsp;' + defOwned;
		ById('btDefMaxSlots').innerHTML = t.wall.wallLevel-t.wall.Queued;
		var slots = Math.max(parseIntNan(ById('btDefNumSlots').value),0);
		ById('btDefMaxPerSlot').innerHTML = parseIntNan(t.MaxDefTrain / slots);

		// paint the requirements...

		t.paintRequirements(unitId);
	},

	paintRequirements : function (unitId) {
		var t = Tabs.Fort;
		var cityId = t.ModelCityId;
		var Buildings = getCityBuildings(cityId);

		var m = '';
		if (uW.fortcost['frt'+unitId][8] && matTypeof(uW.fortcost['frt'+unitId][8]) === "object") {
			for (var b in uW.fortcost['frt'+unitId][8]) {
				var bid = b.split("b")[1];
				var reqlevel = uW.fortcost['frt'+unitId][8][b][1];
				var blvl = Buildings[bid].maxLevel;
				var linestyle = '<span>';
				if (blvl < reqlevel) {
					linestyle = '<span style="color:#800;"><b>';
					m += linestyle+'Level '+reqlevel+' '+uW.buildingcost['bdg'+bid][0]+'</b></span><br>';
				}
			}
		}

		if (uW.fortcost['frt'+unitId][9] && matTypeof(uW.fortcost['frt'+unitId][9]) === "object") {
			for (var r in uW.fortcost['frt'+unitId][9]) {
				var rid = r.split("t")[1];
				var reqlevel = uW.fortcost['frt'+unitId][9][r][1];
				var rlvl = Seed.tech['tch'+rid];
				var linestyle = '<span>';
				if (rlvl < reqlevel) {
					linestyle = '<span style="color:#800;"><b>';
					m += linestyle+'Level '+reqlevel+' '+uW.techcost['tch'+rid][0]+'</b></span><br>';
				}
			}
		}

		m += '<table class=xtab cellpadding=0 cellspacing=0 width=100%>';

		for (var r = 1; r < 5; r++) {
			if (uW.fortcost['frt'+unitId][r] != 0) {
				m += '<tr><td>';
				if (r==1) { m += ResourceImage(FoodImage,uW.g_js_strings.commonstr.food); }
				else {
					if (r==2) { m += ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood); }
					else {
						if (r==3) { m += ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone);	}
						else {
							if (r==4) { m += ResourceImage(OreImage,uW.g_js_strings.commonstr.ore);	}
						}
					}
				}
				var reqlevel = uW.fortcost['frt'+unitId][r]*parseIntNan(ById('btDefNumPerSlot').value);
				var rlvl = parseIntNan(Seed.resources['city'+cityId]['rec'+r][0]/3600);
				var linestyle = '<span>';
				if ((rlvl <= reqlevel) || (t.limitingFactor==uW.resourceinfo['rec'+r])) {
					linestyle = '<span style="color:#800;"><b>';
				}
				m += '</td><td>'+linestyle+addCommas(reqlevel)+' / '+addCommas(rlvl)+'</b></span></td></tr>';
			}
		}

		if (uW.fortcost['frt'+unitId][11] && matTypeof(uW.fortcost['frt'+unitId][11]) === "object") {
			for (var r in uW.fortcost['frt'+unitId][11]) {
				var iid = r;
				var reqlevel = uW.fortcost['frt'+unitId][11][r]*parseIntNan(ById('btDefNumPerSlot').value);
				var ilvl = parseIntNan(Seed.items['i'+iid]);
				var linestyle = '<span>';
				if ((ilvl <= reqlevel) || (iid==34002 && t.limitingFactor=="median")) {
					linestyle = '<span style="color:#800;"><b>';
				}
				m += '<tr><td>'+ResourceImage(getItemImageURL(iid),uW.itemlist['i'+iid].name)+'</td><td>';
				m += linestyle+reqlevel+' / '+ilvl+'</b></span></td></tr>';
			}
		}

		m += '</table>';

		ById('btDefRequirements').innerHTML = m;
	},

	cancelAll: function (cityId) {
		var t = Tabs.Fort;

		jQuery('#btDefCancelAllButton').addClass("disabled");
		var delayer = 0;
		var q = Seed.queue_fort['city' + cityId];
		for (var i = q.length-1; i >= 0; i--) {
			delayer = delayer + 1;
			setTimeout (t.cancelFort,(1000*delayer),q[i][0],q[i][1],q[i][2],q[i][3],q[i][5],q[i][6],cityId,i); // spread them out ...
		}
		delayer = delayer + 1;
		setTimeout (function () { jQuery('#btDefCancelAllButton').removeClass("disabled"); },(1000*delayer));
	},

	cancelFort: function (typefrt, numtrpfrt, frtTmp, frtETA, frtNeeded, frtid, cityId, queueId) {
		var t = Tabs.Fort;
		t.serverwait = true;
		ById('btDefQueueMessage').innerHTML = 'Cancelling Queued Item...';
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		params.requestType = "CANCEL_FORTIFICATIONS";
		params.cityId = cityId;
		params.typefrt = typefrt;
		params.numtrpfrt = numtrpfrt;
		params.frtETA = frtETA;
		params.frtTmp = frtTmp;
		params.frtNeeded = frtNeeded;
		params.frtid = frtid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/cancelFortifications.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var k = 0;
					for (var j = 0; j < Seed.queue_fort["city" + cityId].length; j++) {
						if (j > queueId) {
							Seed.queue_fort["city" + cityId][j][2] = parseInt(rslt.dateFortifications[k]["start"]);
							Seed.queue_fort["city" + cityId][j][3] = parseInt(rslt.dateFortifications[k]["end"]);
							k++;
						}
					}
					Seed.queue_fort["city" + cityId].splice(queueId, 1);
					for (var i = 1; i < 5; i++) {
						var totalReturn = parseInt(uW.fortcost["frt" + typefrt][i]) * parseInt(numtrpfrt) * 3600 / 2;
						Seed.resources["city" + cityId]["rec" + i][0] = parseInt(Seed.resources["city" + cityId]["rec" + i][0]) + totalReturn;
					}
					t.PaintCityInfo();
				}
				else {
					if (rslt.msg) { ById('btDefQueueMessage').innerHTML = '<span style="color:#f00">'+rslt.msg+'</span>'; }
					else { ById('btDefQueueMessage').innerHTML = '<span style="color:#f00">Error cancelling defence queue item</span>'; }
				}
				t.serverwait = false;
			},
			onFailure: function () {
				ById('btDefQueueMessage').innerHTML = '<span style="color:#f00;">AJAX Error!</span>';
				t.serverwait = false;
			},
		},true);
	},

	getTrainTime : function (cityId,unitId,num) {
		var b=parseInt(parseInt(uW.fortcost["frt"+unitId][7]));
		var f=1;
		f+=0.1*parseInt(Seed.tech.tch16);
		var a=0;
		var c=Seed.knights["city"+cityId];
		if(c){
			c=c["knt"+Seed.leaders["city"+cityId].politicsKnightId];
			if(c){
				a=parseInt(c.combat);
				newkntlv=((parseInt(c.politicsBoostExpireUnixtime)-uW.unixtime())>0)?(a*1.25):a;
				f=f+(0.005*newkntlv)
			}
		}

		if(typeof Seed.tech2!=="undefined"){
			if(typeof Seed.tech2.tch3!=="undefined"){
				f+=parseFloat(Seed.tech2.tch3)*0.05
			}
		}

		b=Math.max(1,Math.ceil(b/f));
		return b*num;
	},

	Fortify : function (cityId, siege, unitId, num, notify) {
		var t = Tabs.Fort;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btDefCity_'+citynum).css('color', 'green');
		var time = t.getTrainTime(cityId,unitId, num);

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.type = unitId;
		params.quant = num;
		params.items = siege;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fortify.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					uW.seed.queue_fort["city" + cityId].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + rslt.timeNeeded, 0, rslt.timeNeeded, rslt.fortifyId]);
					if (siege==26) {
						Seed.items.i26 = parseInt(Seed.items.i26)-1;
						uW.ksoItems[26].subtract();
					}
					if (unitId==63) {
						Seed.items.i34002 = parseInt(Seed.items.i34002)-num;
						uW.ksoItems[34002].subtract(num);
					}
					actionLog(Cities.byID[cityId].name+': Building '+num+' '+uW.fortcost['frt'+unitId][0],'DEFENCE');
					t.PaintCityInfo();
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Failed to build '+num+' '+uW.fortcost['frt'+unitId][0]+' ('+rslt.msg+')','DEFENCE');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Failed to build '+num+' '+uW.fortcost['frt'+unitId][0]+' ('+rslt.error_code+')','DEFENCE');
					}
				}
				jQuery('#btDefCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				if (notify) { notify(rslt); }
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Failed to build '+num+' '+uW.fortcost['frt'+unitId][0]+' (Ajax Error)','DEFENCE');
				jQuery('#btDefCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				if (notify) { notify({msg: 'AJAX error'}); }
			},
		},true); // noretry
	},

}

/**************************** Training Tab ****************************************/
Tabs.Train = {
	tabLabel: 'Train',
	tabOrder: 2000,
	tabColor : 'brown',
	myDiv: null,
	timer: null,
	LoopCounter: 0,
	TroopTotal: 0,
	ModelCity: null,
	ModelCityId: 0,
	serverwait: false,
	MaxTroopTrain: 0,
	isBusy: false,
	TrainCityId: 0,
	QueLength: 0,
	Lancelots:0,
	Arthurs:0,
	Merlins:0,
	Squire:0,
	Knight:0,
	Guinevere:0,
	Morgana:0,
	Arthur:0,
	Merlin:0,
	Divine:0,
	Epic:0,
	Legendary:0,
	ItemList : [1, 2, 3, 4, 5, 6, 7, 8, 10],
	ItemTrans : ["SH","KH","GH","MH","AH","RH","DH","EH","LH"],
	TuteList : [36, 37, 38],
	TuteTrans : ["LT","AT","MT"],
	gamble: {
		"1": {
			"min": "5",
			"max": "15",
			"cost": "2",
			"factor1": 0.85,
			"factor2": 0.95,
		},
		"2": {
			"min": "10",
			"max": "25",
			"cost": "4",
			"factor1": 0.75,
			"factor2": 0.9,
		}
	},
	limitingFactor: null,
	Queued: 0,
	QueuedAscension: 0,
	TotalSlots: 0,
	TotalSlotsAscension: 0,
	intervalSecs: 5,
	autodelay : 0,
	speedupused : false,
	Options: {
		ManualWorkers: true,
		Running: false,
		ThroneCheck: false,
		TrainingSpeed: 0,
		StoneGuardian: false,
		Enabled:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		PrimaryTroops:		{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		PrimaryMin:			{1:500,2:500,3:500,4:500,5:500,6:500,7:500,8:500},
		PrimarySelectMax:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		PrimaryMax:			{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		PrimaryLimit:		{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		ReduceLimit:		{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		SecondaryEnabled:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		SecondaryTroops:	{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		SecondaryMin:		{1:500,2:500,3:500,4:500,5:500,6:500,7:500,8:500},
		SecondarySelectMax:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		SecondaryMax:		{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		AscensionEnabled:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		AscensionTroops:	{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		AscensionMin:		{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		AscensionSelectMax:	{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		AscensionMax:		{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		Gamble:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		Workers:			{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		Keep :				{1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
		Resources: {
			1:{Food:0,Wood:0,Stone:0,Ore:0},
			2:{Food:0,Wood:0,Stone:0,Ore:0},
			3:{Food:0,Wood:0,Stone:0,Ore:0},
			4:{Food:0,Wood:0,Stone:0,Ore:0},
			5:{Food:0,Wood:0,Stone:0,Ore:0},
			6:{Food:0,Wood:0,Stone:0,Ore:0},
			7:{Food:0,Wood:0,Stone:0,Ore:0},
			8:{Food:0,Wood:0,Stone:0,Ore:0},
		},
		DismissRunning:		false,
		AutoDismiss:		{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissMM:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissST:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissSC:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissPK:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissSW:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissAR:			{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissOther:		{1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		DismissOtherType:	{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepOther:			{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepMM:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepST:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepSC:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepPK:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepSW:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		KeepAR:				{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		Toggle:				false,
		UseLT:				false,
		UseAT:				false,
		UseMT:				false,
		LTLimitHours:		3,
		ATLimitHours:		5,
		MTLimitHours:		7,
		LTLimitMinutes:		0,
		ATLimitMinutes:		0,
		MTLimitMinutes:		0,
		UseLH:				false,
		UseEH:				false,
		UseDH:				false,
		UseRH:				false,
		UseAH:				false,
		UseMH:				false,
		UseGH:				false,
		UseKH:				false,
		UseSH:				false,
		UseOverride:		false,
		OverrideItem:		0,
		OverrideHours:		0,
		OverrideMinutes:	1,

	},

	init: function (div) {
		var t = Tabs.Train;
        t.myDiv = div;

		if (!Options.TrainOptions) {
			Options.TrainOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.TrainOptions.hasOwnProperty(y)) {
					Options.TrainOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('cancelTrain',Tabs.Train.cancelTrain);
		uWExportFunction('btTrnCancelAll',Tabs.Train.cancelAll);
		uWExportFunction('speedupTraining',Tabs.Train.speedupTraining);

		if (Options.TrainOptions.Toggle) AddSubTabLink('AutoTrain',t.toggleAutoTrainState, 'TrainToggleTab');
		SetToggleButtonState('Train',Options.TrainOptions.Running,'Train');

		var m = '<DIV class=divHeader align=center>'+tx('TROOP TRAINING AND POPULATION CONTROL')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% height=0% class=xtab><tr><td width=30%><INPUT id=btTrainToggle type=checkbox />&nbsp;'+tx("Add toggle button")+'</td><td colspan=2 align=center><INPUT id=btAutoTrainState type=submit value="'+tx("AutoTrain")+' = '+ (Options.TrainOptions.Running?'ON':'OFF')+'">&nbsp;<INPUT id=btAutoDismissState type=submit value="'+tx("AutoDismiss")+' = '+ (Options.TrainOptions.DismissRunning?'ON':'OFF')+'"></td><td width=30% align=right>'+tx('Current Training Speed')+':&nbsp;<span id=btTrnCurrTR></span>&nbsp;&nbsp;</td></tr>'
		m += '<tr><td colspan=2 align=left><INPUT id=btTrnTR type=checkbox > '+tx('Only train when training speed is at least')+' <INPUT id=btTrnTRSpeed type=text size=3 maxlength=4 value="'+ Options.TrainOptions.TrainingSpeed +'">&nbsp;%</td>';
		m += '<td colspan=2 align=right><INPUT id=btTrnGuard type=checkbox > '+tx('Only train when Stone Guardian active')+'&nbsp;&nbsp;</td></tr></table>';

		m += '<br><DIV id=btTrnOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';

		m += '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td align=right width=100><b>&nbsp;</b></td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btTrnCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}
		m += "<td>&nbsp;</td>"; // spacer
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 style="padding-left: 0px;"><B>'+tx('Auto-Train')+'&nbsp;</B></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btTrnAutoCity_'+i+'" type=checkbox '+(Options.TrainOptions.Enabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 style="padding-left: 0px;"><B>'+tx('Training Queue')+'&nbsp;</B></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder><span id="btTrnQueueCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 style="padding-left: 0px;"><B>'+tx('Asc. Training Queue')+'&nbsp;</B></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder><span id="btTrnAscQueueCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr><TR align=right class="evenRow"><TD colspan=2 style="padding-left: 0px;"><B>'+tx('Auto-Dismiss')+'&nbsp;</B></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btDisAutoCity_'+i+'" type=checkbox '+(Options.TrainOptions.AutoDismiss[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 style="padding-left: 0px;"><B>'+tx('Available Population')+'&nbsp;</B></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder style="height:20px;"><a id="btTrnWindsLinkCity_'+i+'"><img class='+i+' id="btTrnWindsCity_'+i+'" style="float:left;vertical-align:middle;" width=20 src="'+getItemImageURL(351)+'" title="'+uW.itemlist['i351'].name+' ('+(Seed.items.i351?Seed.items.i351:0)+')"></a><span style="line-height:20px;" id="btTrnIdlePopCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr></table></div></div>';

		m += '<a id=btTrnSpeedupLink class=divLink><div class="divHeader" align="left"><img id=btTrnSpeedupArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('AUTO-SPEEDUP SETTINGS')+'</div></a>';
		m += '<div id=btTrnSpeedup class=divHide><table width=100% class=xtab><tr><td><div align=center>';

		var Boosts = '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td colspan=4><b>'+tx('Tuteleges')+':</b></td></tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.TuteList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.TuteList[i]+'.jpg" title="'+uW.itemlist["i"+t.TuteList[i]].name+'\n'+tx(TuteHint[i])+'" /></td><td>(<span id=pbtrainUse'+t.TuteTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.TuteList[i]].count) + '</span>)</td>';
		}
		Boosts += '<td width=70 rowspan=2 align=right><INPUT id=pbTrainHelp type=submit value="'+tx('HELP')+'!"></td>';
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.TuteList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbtrain'+t.TuteTrans[i]+'" '+(Options.TrainOptions["Use"+t.TuteTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr><tr>';
		for (var i = 0; i < t.TuteList.length; i++) {
			Boosts += '<td align=right>'+uW.g_js_strings.commonstr.time+':</td><td><INPUT class=btInput id="pbminhr'+t.TuteTrans[i]+'" type=text size=1 maxlength=2 value="'+ Options.TrainOptions[t.TuteTrans[i]+"LimitHours"]+'"\>&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT class=btInput id="pbminmn'+t.TuteTrans[i]+'" type=text size=1 maxlength=2 value="'+ Options.TrainOptions[t.TuteTrans[i]+"LimitMinutes"]+'"\>&nbsp;'+uW.g_js_strings.timestr.timemin+'</td>';
		}
		Boosts += '</tr></table><br>';
		Boosts += '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td colspan=4><b>'+tx('Hourglasses')+':</b></td></tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'\n'+tx(HourGlassHint[i])+'" /></td><td>(<span id=pbtrainUse'+t.ItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbtrain'+t.ItemTrans[i]+'" '+(Options.TrainOptions["Use"+t.ItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr></table></td></tr>';
        Boosts += '<tr><td><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td><input type=checkbox id=pbtrainOV >'+tx('Override hourglass rules by always using')+' '+htmlSelector(HourGlassName,Options.TrainOptions.OverrideItem, 'id=pbtrainOVItem') + ' '+tx('when more than')+' ';
		Boosts += '<INPUT style="width: 30px;text-align:right;" id="pbtrainOVHours" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT style="width: 30px;text-align:right;" id="pbtrainOVMinutes" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timemin+' '+tx('remaining')+'.</td></tr></table></div></td></tr>';

		m += Boosts+'</table></div></div>';

		m += '<HR><br><DIV style="text-align:center; margin-bottom:5px;">'+uW.g_js_strings.commonstr.city+':&nbsp;<span id=pttraincity></span></div>';

		m += '<a id=btTrnOptionLink class=divLink><div class="divHeader" align="left"><img id=btTrnOptionArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('TRAIN TROOPS')+'</div></a>';
		m += '<div id=btTrnOption>';

		m += '<TABLE align=center cellpadding=0 cellspacing=0 class=xtab width=98%><TR><TD valign=top width=49%>';
		m += '<TABLE class=xtab><tr><td colspan=3>&nbsp;</td></tr><tr><TD align=right>'+tx(uW.g_js_strings.openCastle.trooptype)+':&nbsp;</td><TD colspan=2>';
		m += '<SELECT id=btTrnType>';
		for (var ui in uW.cm.UNIT_TYPES) {
			var u = uW.cm.UNIT_TYPES[ui];
			if (!uW.cm.BarracksUnitsTypeMap.isUnitType(u, "rare")) {
				m += '<option value='+u+'>'+uW.unitcost["unt"+u][0]+'</option>';
			}
		}
		m += '</select></td></tr><tr><td>&nbsp;</td><td colspan=2>(<span id=btTrnMax>&nbsp;</span>)</td></tr>';
		m += '<TR><TD align=right>'+tx('Number to train')+':&nbsp;</td><TD><INPUT id=btTrnNumPerSlot size=5 type=text value=0\></td>';
		m += '<TD><a id=btTrnMaxPerSlotButton class="inlineButton btButton brown8"><span>Max</span></a>&nbsp;('+uW.g_js_strings.commonstr.max;
		m += ':&nbsp;<span id=btTrnMaxPerSlot>0</span>)</td></tr>';
		m += '<TR><TD align=right>'+tx('Number of slots to use')+':&nbsp;</td>';
		m += '<TD><INPUT id=btTrnNumSlots size=2 type=text value=1\></td>';
		m += '<TD><a id=btTrnMaxSlotsButton class="inlineButton btButton brown8"><span>Max</span></a>&nbsp;('+uW.g_js_strings.commonstr.max;
		m += ':&nbsp;<span id=btTrnMaxSlots>0</span>)</td></tr>';
		m += '<TR><td align=right>'+tx('Use Workforce')+':&nbsp;</td><TD colspan=2><INPUT type=checkbox id=btTrnUseWorkers '+(Options.TrainOptions.ManualWorkers?'CHECKED':'')+'></td></tr>';
		m += '<tr><td align=right>'+tx('Gamble')+':&nbsp;</td><td colspan=2><SELECT id=btTrnGamble>\
			<option value=0><CENTER>-- '+uW.g_js_strings.commonstr.select+' --</center></option>\
			<option value=1>'+tx('Use')+' ' + t.gamble[1].cost + 'x '+tx('resources')+' (' + t.gamble[1].min + ' - ' + t.gamble[1].max + '% '+tx('faster')+')</option>\
			<option value=2>'+tx('Use')+' ' + t.gamble[2].cost + 'x '+tx('resources')+' (' + t.gamble[2].min + ' - ' + t.gamble[2].max + '% '+tx('faster')+')</option>\
			</select></td></tr>';
		m += '<tr><td>&nbsp;</td><td colspan=2><a id=btTrnButton class="inlineButton btButton blue14"><span id=btTrnButtonLabel style="width:100px;display:inline-block;text-align:center;">'+uW.g_js_strings.modal_openBarracks.trainttl+'</span></a></td></tr></table>';
		m += '</TD><TD valign=top width=49%><TABLE class=xtab><tr><td><b>'+uW.g_js_strings.commonstr.requirements+':-</b></td></tr>';
		m += '<tr><td valign=top id="btTrnRequirements">&nbsp;</td></tr>';
		m += '</table>';

		m += '</td></tr><tr><td colspan=2><div id=btTrnMessages align=center>&nbsp;</div></td></tr></table></div>';

		m += '<a id=btTrnAutoLink class=divLink><div class="divHeader" align="left"><img id=btTrnAutoArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('AUTO-TRAIN SETTINGS')+'</div></a>';
		m += '<div id=btTrnAuto class=divHide></div>';

		m += '<a id=btDisAutoLink class=divLink><div class="divHeader" align="left"><img id=btDisAutoArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('AUTO-DISMISS SETTINGS')+'</div></a>';
		m += '<div id=btDisAuto class=divHide></div>';

		m += '<a id=btTrnQueueLink class=divLink><div class="divHeader" align="left"><table cellpadding=0 cellspacing=0 width=100%><tr><td class=xtab><img id=btTrnQueueArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('TRAINING QUEUES')+'</td><td class=xtab align=right id=btTrnQueueStats>&nbsp;</td></tr></table></div></a>';
		m += '<div id=btTrnQueue style="max-height:200px;overflow-y:scroll;"></div><br>';

		div.innerHTML = m;

		t.ModelCity = new CdispCityPicker('pttrain', ById('pttraincity'), true, t.clickCitySelect, null);

		ToggleOption('TrainOptions','btTrainToggle','Toggle');

		ById('btTrnOptionLink').addEventListener ('click', function () {ToggleMainDivDisplay("Training",100,GlobalOptions.btWinSize.x,"btTrnOption",false)}, false);
		ById('btTrnAutoLink').addEventListener ('click', function () {ToggleMainDivDisplay("Training",100,GlobalOptions.btWinSize.x,"btTrnAuto",false)}, false);
		ById('btDisAutoLink').addEventListener ('click', function () {ToggleMainDivDisplay("Training",100,GlobalOptions.btWinSize.x,"btDisAuto",false)}, false);
		ById('btTrnQueueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Training",100,GlobalOptions.btWinSize.x,"btTrnQueue",false)}, false);
		ById('btTrnSpeedupLink').addEventListener ('click', function () {ToggleMainDivDisplay("Training",100,GlobalOptions.btWinSize.x,"btTrnSpeedup",false)}, false);

		ById('btTrnType').addEventListener('change', t.PaintCityInfo, false);
		ById('btTrnGamble').addEventListener('change', t.PaintCityInfo, false);

		ById('btTrnMaxPerSlotButton').addEventListener('click', function () {
			var slots = Math.max(parseIntNan(ById('btTrnNumSlots').value),0);
			ById('btTrnNumPerSlot').value = parseIntNan(t.MaxTroopTrain / slots);
			t.paintRequirements(ById('btTrnType').value);
		} ,false);

		ById('btTrnNumPerSlot').addEventListener('change', function () {
			t.paintRequirements(ById('btTrnType').value);
		}, false);

		ById('btTrnNumSlots').addEventListener('change', function () {
			var slots = Math.max(parseIntNan(ById('btTrnNumSlots').value),0);
			if (slots < 1) { slots = 1; }
			var MaxSlots = t.TotalSlots-t.Queued;
			if (!uW.cm.BarracksUnitsTypeMap.isUnitType(ById('btTrnType').value, "normal")) { MaxSlots = t.TotalSlotsAscension-t.QueuedAscension; }
			if (slots > MaxSlots) { slots = MaxSlots; }
			ById('btTrnNumSlots').value = slots;
			ById('btTrnMaxPerSlot').innerHTML = parseIntNan(t.MaxTroopTrain / slots);
		} ,false);

		ById('btTrnMaxSlotsButton').addEventListener('click', function () {
			var MaxSlots = t.TotalSlots-t.Queued;
			if (!uW.cm.BarracksUnitsTypeMap.isUnitType(ById('btTrnType').value, "normal")) { MaxSlots = t.TotalSlotsAscension-t.QueuedAscension; }
			ById('btTrnNumSlots').value = Math.max(MaxSlots,0);
			var slots = Math.max(parseIntNan(ById('btTrnNumSlots').value),0);
			ById('btTrnMaxPerSlot').innerHTML = parseIntNan(t.MaxTroopTrain / slots);
		} ,false);

		ById('btTrnUseWorkers').addEventListener('click', t.clickCheckUseWorkers, false);
		ById('btTrnButton').addEventListener ('click', t.setTraining, false);

		for (var i = 1; i <= Cities.numCities; i++) {
			ById('btTrnAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.TrainOptions.Enabled[citynum] = e.target.checked;
				if (Options.TrainOptions.Enabled[citynum]) {
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
			ById('btDisAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.TrainOptions.AutoDismiss[citynum] = e.target.checked;
				if (Options.TrainOptions.AutoDismiss[citynum]) {
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
			ById('btTrnWindsCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				t.Fertilize(Cities.cities[citynum-1].id);
			}, false);
		}

		ById('btAutoTrainState').addEventListener('click', function(){
			t.toggleAutoTrainState(this);
		}, false);
		ById('btAutoDismissState').addEventListener('click', function(){
			t.toggleAutoDismissState(this);
		}, false);

		ToggleOption('TrainOptions','btTrnTR','ThroneCheck');
		ChangeIntegerOption('TrainOptions','btTrnTRSpeed','TrainingSpeed');

		ToggleOption('TrainOptions','btTrnGuard','StoneGuardian');

		ToggleOption('TrainOptions','pbtrainSH','UseSH');
		ToggleOption('TrainOptions','pbtrainKH','UseKH');
		ToggleOption('TrainOptions','pbtrainGH','UseGH');
		ToggleOption('TrainOptions','pbtrainMH','UseMH');
		ToggleOption('TrainOptions','pbtrainAH','UseAH');
		ToggleOption('TrainOptions','pbtrainRH','UseRH');
		ToggleOption('TrainOptions','pbtrainDH','UseDH');
		ToggleOption('TrainOptions','pbtrainEH','UseEH');
		ToggleOption('TrainOptions','pbtrainLH','UseLH');
		ToggleOption('TrainOptions','pbtrainOV','UseOverride');

		ChangeIntegerOption('TrainOptions','pbtrainOVItem','OverrideItem');
		ChangeIntegerOption('TrainOptions','pbtrainOVHours','OverrideHours');
		ChangeIntegerOption('TrainOptions','pbtrainOVMinutes','OverrideMinutes');

		ToggleOption('TrainOptions','pbtrainLT','UseLT');
		ToggleOption('TrainOptions','pbtrainAT','UseAT');
		ToggleOption('TrainOptions','pbtrainMT','UseMT');

		ChangeIntegerOption('TrainOptions','pbminhrLT','LTLimitHours');
		ChangeIntegerOption('TrainOptions','pbminmnLT','LTLimitMinutes');
		ChangeIntegerOption('TrainOptions','pbminhrAT','ATLimitHours');
		ChangeIntegerOption('TrainOptions','pbminmnAT','ATLimitMinutes');
		ChangeIntegerOption('TrainOptions','pbminhrMT','MTLimitHours');
		ChangeIntegerOption('TrainOptions','pbminmnMT','MTLimitMinutes');

		ById('pbTrainHelp').addEventListener ('click', t.helpPop, false);

		// start autotrain loop timer to start in 20 seconds...

		if (Options.TrainOptions.Running || Options.TrainOptions.DismissRunning) {
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, (20 * 1000));
		}
	},

	helpPop : function (){
		var t = Tabs.Train;
		var helpText = '<br>'+tx("Using Speedups for Troop Training");
		helpText += '<p>'+tx('Tuteleges will take priority over hourglasses if selected, and the training time remaining is greater than the specified minimum time for the tutelege')+'.</p>';
		helpText += '<p>'+tx("The priority order for tuteleges is Merlin's (70% reduction), Arthur's (50% reduction), and then Lancelot's (30% reduction)")+'.</p>';
		helpText += '<p>'+tx('If no tuteleges can be used, hourglasses will be used in the following order if they are selected, and the required criteria is met')+' :-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+uW.g_js_strings.commonstr.item+'</b></td><TD><b>'+uW.g_js_strings.commonstr.time+'</b></td><TD><b>'+tx('Criteria')+'</b></td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i10.name+'</td><TD>4 days</td><TD>'+tx('More than 3 days and 12 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i8.name+'</td><TD>2.5 days</td><TD>'+tx('More than 48 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i7.name+'</td><TD>24 hrs</td><TD>'+tx('More than 23 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i6.name+'</td><TD>15 hrs</td><TD>'+tx('More than 14 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i5.name+'</td><TD>8 hrs</td><TD>'+tx('More than 7 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i4.name+'</td><TD>2.5 hrs</td><TD>'+tx('More than 2 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i3.name+'</td><TD>1 hr</td><TD>'+tx('More than 45 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i2.name+'</td><TD>15 mins</td><TD>'+tx('More than 5 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i1.name+'</td><TD>1 min</td><TD>'+tx('More than 30 seconds remaining')+'</td></tr>';
		helpText += '</table>';
		helpText += '<p>'+tx('If the override box is ticked, then the override rule specified will take priority')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 420, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Speedups")+'</b></center>';
		pop.show (true);
	},

	toggleAutoTrainState: function(obj){
		var t = Tabs.Train;
		obj = ById('btAutoTrainState');
		if (Options.TrainOptions.Running == true) {
			Options.TrainOptions.Running = false;
			obj.value = tx("AutoTrain = OFF");
		}
		else {
			Options.TrainOptions.Running = true;
			obj.value = tx("AutoTrain = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Train',Options.TrainOptions.Running,'Train');
		t.PaintOverview();
	},

	toggleAutoDismissState: function(obj){
		var t = Tabs.Train;
		if (Options.TrainOptions.DismissRunning == true) {
			Options.TrainOptions.DismissRunning = false;
			obj.value = tx("AutoDismiss = OFF");
		}
		else {
			Options.TrainOptions.DismissRunning = true;
			obj.value = tx("AutoDismiss = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, 0);
		}
		saveOptions();
		t.PaintOverview();
	},

	show: function (init) {
		var t = Tabs.Train;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
		t.PaintOverview();
		t.UpdateTrainingOptions();
		t.PaintCityInfo();
	},

	EverySecond : function () {
		var t = Tabs.Train;

		if (tabManager.currentTab.name == 'Train' && Options.btWinIsOpen){
			t.LoopCounter = t.LoopCounter + 1;

			if (t.LoopCounter%2==0) { // refresh queue display every 2 seconds
				t.PaintCityInfo();
			}

			if (t.LoopCounter >= 6) { // refresh overview display every 6 seconds
				t.LoopCounter = 0;
				t.PaintOverview();
			}
		}
	},

	clickCheckUseWorkers: function () {
		var t = Tabs.Train;
		Options.TrainOptions.ManualWorkers = (ById('btTrnUseWorkers').checked);
		saveOptions();
		t.PaintCityInfo();
	},

	clickCitySelect: function (city) {
		var t = Tabs.Train;
		t.ModelCityId = city.id;
		t.LastQueue = 'x';
		t.UpdateTrainingOptions();
		t.PaintCityInfo();
	},

	setTraining: function () {
		var t = Tabs.Train;

		if (t.isBusy) {
			t.isBusy = false;
			ById('btTrnMessages').innerHTML = '<span style="color:#800;">'+tx('Cancelled')+'!</span>';
			ById('btTrnButtonLabel').innerHTML = uW.g_js_strings.modal_openBarracks.trainttl;
			jQuery('#btTrnButton').removeClass("red14");
			jQuery('#btTrnButton').addClass("blue14");
			return;
		}

		t.TrainCityId = t.ModelCityId;
		var unitId = ById('btTrnType').value;
		var perSlot = parseIntNan(ById('btTrnNumPerSlot').value);
		var numSlots = parseIntNan(ById('btTrnNumSlots').value);
		var gamble = ById('btTrnGamble').value;
		var tut = 0;

		if (perSlot < 1) { return; }
		if (numSlots < 1) { return; }

		if (perSlot * numSlots > t.MaxTroopTrain) {
			ById('btTrnMessages').innerHTML = '<span style="color:#800;">'+uW.g_js_strings.modal_attack.maxtroops+': '+t.MaxTroopTrain + '</span>';
			return;
		}

		var MaxSlots = t.TotalSlots-t.Queued;
		if (!uW.cm.BarracksUnitsTypeMap.isUnitType(ById('btTrnType').value, "normal")) { MaxSlots = t.TotalSlotsAscension-t.QueuedAscension; }
		if (numSlots > MaxSlots) {
			ById('btTrnMessages').innerHTML = '<span style="color:#800;">'+tx('Maximum number of slots exceeded')+'!</span>';
			return;
		}

		var que = [];
		for (var i = 0; i < numSlots; i++) {
			que.push(['T', unitId, perSlot, gamble, tut]);
		}
		t.QueLength = que.length;
		t.isBusy = true;
		ById('btTrnButtonLabel').innerHTML = uW.g_js_strings.commonstr.cancel;
		jQuery('#btTrnButton').addClass("red14");
		jQuery('#btTrnButton').removeClass("blue14");
		t.nextqueue(que);
	},

	nextqueue : function (que){
		var t = Tabs.Train;
		if(!t.isBusy) { return; }

		var cmd = que.shift();

		if (cmd[0] == 'T') {
			if (t.QueLength == 1) {
				ById('btTrnMessages').innerHTML = tx('Training')+' '+cmd[2]+' '+uW.unitcost['unt'+cmd[1]][0]+' '+tx('at')+' '+Cities.byID[t.TrainCityId].name;
			}
			else {
				ById('btTrnMessages').innerHTML = tx('Training')+' '+cmd[2]+' '+uW.unitcost['unt'+cmd[1]][0]+' '+tx('at')+' '+Cities.byID[t.TrainCityId].name + ' ('+tx('Slot')+' '+parseIntNan(t.QueLength-que.length)+' '+uW.g_js_strings.commonstr.of+' '+t.QueLength+')';
			}
			t.Train (t.TrainCityId, cmd[4], cmd[3], cmd[1], cmd[2], function (rslt) {
				if (rslt.ok) {
					if (parseIntNan(que.length)==0) {
						ById('btTrnMessages').innerHTML = tx('Completed')+'!';
						ById('btTrnButtonLabel').innerHTML = uW.g_js_strings.modal_openBarracks.trainttl;
						jQuery('#btTrnButton').removeClass("red14");
						jQuery('#btTrnButton').addClass("blue14");
						t.isBusy = false;
						return;
					}
					setTimeout(function () { t.nextqueue(que) }, 2000);
				}
				else {
					if (rslt.msg) {
						ById('btTrnMessages').innerHTML = '<span style="color:#800;">'+rslt.msg+'</span>';
					}
					else {
						ById('btTrnMessages').innerHTML = '<span style="color:#800;">'+tx('Error training troops')+' ('+rslt.error_code+')</span>';
					}
					ById('btTrnButtonLabel').innerHTML = uW.g_js_strings.modal_openBarracks.trainttl;
					jQuery('#btTrnButton').removeClass("red14");
					jQuery('#btTrnButton').addClass("blue14");
					t.isBusy = false;
					return;
				}
			});
		}
	},

	getMaxTrain: function (unitId,cityId,ignoreRes,workforce,gamble,auto) {
		var t = Tabs.Train;
		var numberToTrain = 0;
		t.limitingFactor = null;
		var citynum = Cities.byID[cityId].idx+1;

		if (unitId==0) { return numberToTrain; }

		var food = parseIntNan(Seed.resources['city' + cityId].rec1[0] / 3600);
		var wood = parseIntNan(Seed.resources['city' + cityId].rec2[0] / 3600);
		var stone = parseIntNan(Seed.resources['city' + cityId].rec3[0] / 3600);
		var ore = parseIntNan(Seed.resources['city' + cityId].rec4[0] / 3600);

		// change these numbers for auto...
		var foodRes = 0;
		var woodRes = 0;
		var stoneRes = 0;
		var oreRes = 0;
		if (auto && Options.TrainOptions.Keep[citynum]) {
			foodRes = parseIntNan(Options.TrainOptions.Resources[citynum]["Food"]);
			woodRes = parseIntNan(Options.TrainOptions.Resources[citynum]["Wood"]);
			stoneRes = parseIntNan(Options.TrainOptions.Resources[citynum]["Stone"]);
			oreRes = parseIntNan(Options.TrainOptions.Resources[citynum]["Ore"]);
		}

		var availFood = food - foodRes;
		var availWood = wood - woodRes;
		var availStone = stone - stoneRes;
		var availOre = ore - oreRes;

		if (auto && !Options.TrainOptions.Keep[citynum]) {
			if (parseIntNan(Options.TrainOptions.Resources[citynum]["Food"])!=0) {
				availFood = parseIntNan(Options.TrainOptions.Resources[citynum]["Food"])
			}
			if (parseIntNan(Options.TrainOptions.Resources[citynum]["Wood"])!=0) {
				availWood = parseIntNan(Options.TrainOptions.Resources[citynum]["Wood"])
			}
			if (parseIntNan(Options.TrainOptions.Resources[citynum]["Stone"])!=0) {
				availStone = parseIntNan(Options.TrainOptions.Resources[citynum]["Stone"])
			}
			if (parseIntNan(Options.TrainOptions.Resources[citynum]["Ore"])!=0) {
				availOre = parseIntNan(Options.TrainOptions.Resources[citynum]["Ore"])
			}
		}

		var gambleFactor = 1;
		if (gamble > 0) { gambleFactor = t.gamble[gamble].cost; }

		var unitFood = parseInt(uW.unitcost['unt'+unitId][1])*gambleFactor;
		var unitWood = parseInt(uW.unitcost['unt'+unitId][2])*gambleFactor;
		var unitStone = parseInt(uW.unitcost['unt'+unitId][3])*gambleFactor;
		var unitOre = parseInt(uW.unitcost['unt'+unitId][4])*gambleFactor;
		var unitPop = parseInt(uW.unitcost['unt'+unitId][6]);

		if (unitId == 16) var unitYew = uW.unitcost['unt'+unitId][11]["34001"];
		if (unitId == 27) var unitCorrupter = uW.unitcost['unt'+unitId][11]["34003"];

		var idlePop = parseInt(Seed.citystats['city' + cityId].pop[0]) - parseInt(Seed.citystats['city' + cityId].pop[3]);
		if (ignoreRes) {
			idlePop = parseInt(Seed.citystats['city' + cityId].pop[1]) - parseInt(Seed.citystats['city' + cityId].pop[3]); // base on max population
		}
		var workers = Math.floor(parseIntNan(Seed.citystats['city' + cityId].pop[3])*(workforce/100));
		idlePop = idlePop+workers;

		var yew = parseIntNan(Seed.items.i34001); // flame archers require yew branches
		var corrupter = parseIntNan(Seed.items.i34003); // duellists require corrupter seeds

		var max = 9999999999;

		if (!ignoreRes) {
			if ((food / unitFood) < max) {
				max = food / unitFood;
				t.limitingFactor = uW.resourceinfo['rec1'];
			}
			if ((wood / unitWood) < max) {
				max = wood / unitWood;
				t.limitingFactor = uW.resourceinfo['rec2'];
			}
			if ((stone / unitStone) < max) {
				max = stone / unitStone;
				t.limitingFactor = uW.resourceinfo['rec3'];
			}
			if ((ore / unitOre) < max) {
				max = ore / unitOre;
				t.limitingFactor = uW.resourceinfo['rec4'];
			}

			if (unitId == 16) {
				if ((yew / unitYew) < max) {
					max = yew / unitYew;
					t.limitingFactor = 'yew';
				}
			}

			if (unitId == 27) {
				if ((corrupter / unitCorrupter) < max) {
					max = corrupter / unitCorrupter;
					t.limitingFactor = 'corrupter';
				}
			}
		}

		if ((idlePop / unitPop) < max) {
			max = idlePop / unitPop;
			t.limitingFactor = 'pop';
		}

		numberToTrain = parseInt(max);
		if (numberToTrain < 0) { numberToTrain = 0; }

		return numberToTrain;
	},

	CheckCanTrain : function (unitId,cityId) {
		var t = Tabs.Train;
		if (unitId==0) return false;

		var Result = true;

		// check rare troops

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "rare")) {
			return false;
		}

		// check ascension city types here..

		var ascended = getAscensionValues(cityId);
		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "druid") && ascended.prestigeType!=1) {
			return false;
		}

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "fey") && ascended.prestigeType!=2) {
			return false;
		}

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "briton") && ascended.prestigeType!=3) {
			return false;
		}

		// troop requirements
		var Buildings = getCityBuildings(cityId);
		var fc = uW.unitcost['unt'+unitId];
		if (matTypeof(fc[8]) == 'object'){
			for (var k in fc[8]){
				var b = Buildings[k.substr(1)];
				if (b.maxLevel < fc[8][k][1]){
					Result = false;
					break;
				}
			}
		}
		if (matTypeof(fc[9]) == 'object'){
			for (var k in fc[9]){
				if (parseInt(Seed.tech['tch'+k.substr(1)]) < fc[9][k][1]){
					Result = false;
					break;
				}
			}
		}

		return Result;
	},

	PaintOverview : function () {
		var t = Tabs.Train;

		for (var i = 0; i < Cities.numCities; i++) {
			citynum = i+1;
			cityId = Cities.cities[i].id;
			var totTime = 0;
			var totTime2 = 0;
			var now = unixTime();
			var q = Seed.queue_unt['city'+cityId];
			if (q != null && q.length > 0) {
				for (var j = 0; j < q.length; j++) {
					if (q[j][7])
						totTime2 = q[j][3] - now;
					else
						totTime = q[j][3] - now;
				}
			}
			if (totTime < 0) totTime = 0;
			if (totTime < 3600) ById('btTrnQueueCity_'+citynum).innerHTML = '<SPAN class=boldRed><B>' + timestr(totTime) + '</b></span>';
			else ById('btTrnQueueCity_'+citynum).innerHTML = timestr(totTime);
			if (totTime2 < 0) totTime2 = 0;
			if (totTime2 < 3600) ById('btTrnAscQueueCity_'+citynum).innerHTML = '<SPAN class=boldRed><B>' + timestr(totTime2) + '</b></span>';
			else ById('btTrnAscQueueCity_'+citynum).innerHTML = timestr(totTime2);

			var idlePop = parseInt(Seed.citystats['city' + cityId].pop[0]) - parseInt(Seed.citystats['city' + cityId].pop[3]);
			var workers = Math.floor(parseIntNan(Seed.citystats['city' + cityId].pop[3])*(Options.TrainOptions.Workers[citynum]/100));
			var autoidlePop = idlePop+workers;
			if (idlePop<=0) ById('btTrnIdlePopCity_'+citynum).innerHTML = '<SPAN class=boldRed title="'+addCommas(autoidlePop)+' '+tx('Available for Auto-Training')+'">' + addCommas(idlePop) + '</span>';
			else ById('btTrnIdlePopCity_'+citynum).innerHTML = '<SPAN title="'+addCommas(autoidlePop)+' '+tx('Available for Auto-Training')+'">'+addCommas(idlePop)+'</span>';

			var WindAvailable = (parseInt(Seed.citystats['city' + cityId].pop[0]) < parseInt(Seed.citystats['city' + cityId].pop[1]));
			if (WindAvailable) { jQuery('#btTrnWindsLinkCity_'+citynum).removeClass("divHide"); }
			else { jQuery('#btTrnWindsLinkCity_'+citynum).addClass("divHide"); }
		}

		var ts = Math.floor(equippedthronestats(77));
		if (Options.TrainOptions.ThroneCheck && (ts < Number(Options.TrainOptions.TrainingSpeed))) {
			ts = '<span class=boldRed><b>'+ts+'%</b></span>';
		}
		else { ts+='%'; }
		ById("btTrnCurrTR").innerHTML = ts;
	},

	fixQueTimes: function (q) {
		// fix KofC bugs ....
		// if first start time > now, make it now
		// if any end time != next start time then fix it
		var now = unixTime();
		if (q[0][2] > now) { q[0][2] = now; }
		for (var i = 0; i < q.length; i++) {
			if (q[i + 1] != null && q[i + 1][2] != q[i][3]) { q[i][3] = q[i + 1][2]; }
		}
	},

	expireTheQueue: function (q) {
		if (q == null) return;
		var now = unixTime();
		for (var i = 0; i < q.length; i++) {
			if ((q[i][3] - now) < 1) q.splice(i,1);
		}
	},

	UpdateTrainingOptions : function () {
		var t = Tabs.Train;
		var citynum = Cities.byID[t.ModelCityId].idx+1;

		var m = '<table width=100% class=xtab>';
		m += '<tr><td width=15>&nbsp;</td><td width=15>&nbsp;</td><td width=120 align=right>'+tx('Primary')+':&nbsp;</td><td align=left>';
		m += '<SELECT id=btTrnAutoPrimaryType><option value="0">-- '+uW.g_js_strings.commonstr.select+' --</option>';
		for (var ui in uW.cm.UNIT_TYPES) {
			var u = uW.cm.UNIT_TYPES[ui];
			if (uW.cm.BarracksUnitsTypeMap.isUnitType(u, "normal") && t.CheckCanTrain(u,t.ModelCityId)) {
				m += '<option value='+u+'>'+uW.unitcost["unt"+u][0]+'</option>';
			}
		}
		m += '</td><td align=left>'+tx('Min')+':&nbsp;<INPUT id=btTrnAutoPrimaryMin type=text size=6 maxlength=6 value="'+ Options.TrainOptions.PrimaryMin[citynum]+'"\></td>';
		m += '<td><INPUT type=checkbox id=btTrnAutoPrimarySelMax>&nbsp;'+tx("Max")+':&nbsp;<INPUT id=btTrnAutoPrimaryMax type=text size=6 maxlength=6 value="'+ Options.TrainOptions.PrimaryMax[citynum]+'"\></td>';
		m += '<td colspan=2>'+tx('City Limit')+':&nbsp;<INPUT id=btTrnAutoPrimaryLimit type=text size=12 maxlength=14 value="'+ Options.TrainOptions.PrimaryLimit[citynum]+'"\><INPUT type=checkbox '+(Options.TrainOptions.ReduceLimit[citynum]?'CHECKED':'')+' id=btTrnAutoReduceLimit>&nbsp;'+tx("Reduce")+'</td></tr>';
		m += '<tr><td>&nbsp;</td><td><INPUT id=btTrnAutoSecondaryEnabled type=checkbox '+(Options.TrainOptions.SecondaryEnabled[citynum]?'CHECKED':'')+'></td><td align=right>'+tx('Secondary')+':&nbsp;</td><td align=left>';
		m += '<SELECT id=btTrnAutoSecondaryType><option value="0">-- '+uW.g_js_strings.commonstr.select+' --</option>';
		for (var ui in uW.cm.UNIT_TYPES) {
			var u = uW.cm.UNIT_TYPES[ui];
			if (uW.cm.BarracksUnitsTypeMap.isUnitType(u, "normal") && t.CheckCanTrain(u,t.ModelCityId)) {
				m += '<option value='+u+'>'+uW.unitcost["unt"+u][0]+'</option>';
			}
		}
		m += '</td><td align=left>'+tx('Min')+':&nbsp;<INPUT id=btTrnAutoSecondaryMin type=text size=6 maxlength=6 value="'+ Options.TrainOptions.SecondaryMin[citynum]+'"\></td>';
		m += '<td><INPUT type=checkbox id=btTrnAutoSecondarySelMax>&nbsp;'+tx("Max")+':&nbsp;<INPUT id=btTrnAutoSecondaryMax type=text size=6 maxlength=6 value="'+ Options.TrainOptions.SecondaryMax[citynum]+'"\></td>';
		m += '<td>&nbsp;</td></tr>';

        if(Seed.cityData.city[t.ModelCityId].prestigeInfo.blessings) {
			var AscensionType = '(unknown)';
			if(Seed.cityData.city[t.ModelCityId].prestigeInfo.blessings.indexOf(11) != -1) {
				Options.TrainOptions.AscensionTroops[citynum] = 13;
				var AscensionType = uW.unitcost['unt13'][0];
			}
			if(Seed.cityData.city[t.ModelCityId].prestigeInfo.blessings.indexOf(21) != -1) {
				Options.TrainOptions.AscensionTroops[citynum] = 14;
				var AscensionType = uW.unitcost['unt14'][0];
			}
			if(Seed.cityData.city[t.ModelCityId].prestigeInfo.blessings.indexOf(31) != -1) {
				Options.TrainOptions.AscensionTroops[citynum] = 15;
				var AscensionType = uW.unitcost['unt15'][0];
			}
			m += '<tr><td>&nbsp;</td><td align=left><INPUT id=btTrnAutoAscensionEnabled type=checkbox '+(Options.TrainOptions.AscensionEnabled[citynum]?'CHECKED':'')+'></td><td align=right>'+tx('Ascension')+':&nbsp;</td><td><b>'+AscensionType+'</b></td>';
			m += '<td>'+tx("Min")+':&nbsp;<INPUT id=btTrnAutoAscensionMin type=text size=6 maxlength=6 value="'+Options.TrainOptions.AscensionMin[citynum]+'"></td>';
			m += '<td><INPUT type=checkbox id=btTrnAutoAscensionSelMax>&nbsp;'+tx("Max")+':&nbsp;<INPUT id=btTrnAutoAscensionMax type=text size=6 maxlength=6 value="'+ Options.TrainOptions.AscensionMax[citynum]+'"\></td></tr>';
		}
        m += '<tr><td>&nbsp;</td><td>&nbsp;</td><TD align=right><SELECT id=btTrnAutoKeep><option value="true">'+tx("Keep")+'</option><option value="false">'+tx("Use")+'</option></select></td>';
		m += '<td colspan=5><table class=xtab><tr>';
        m += '<TD><img src="'+FoodImage+'" title="'+uW.g_js_strings.commonstr.food+'"></td>';
        m += '<TD><INPUT id="btTrnAutoFood" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.Resources[citynum]['Food']+'"\></td>';
        m += '<TD><img src="'+WoodImage+'" title="'+uW.g_js_strings.commonstr.wood+'"></td>';
        m += '<TD><INPUT id="btTrnAutoWood" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.Resources[citynum]['Wood']+'"\></td>';
        m += '<TD><img src="'+StoneImage+'" title="'+uW.g_js_strings.commonstr.stone+'"></td>';
        m += '<TD><INPUT id="btTrnAutoStone" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.Resources[citynum]['Stone']+'"\></td>';
        m += '<TD><img src="'+OreImage+'" title="'+uW.g_js_strings.commonstr.ore+'"></td>';
        m += '<TD><INPUT id="btTrnAutoOre" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.Resources[citynum]['Ore']+'"\></td></tr></table></td></tr>';
		m += '<tr><td>&nbsp;</td><td>&nbsp;</td><td align=right>'+tx("Use Workforce")+':&nbsp;</td>';
        m +='<td><SELECT id=btTrnAutoWorkers><option value="0">0%</option><option value="25">25%</option><option value="50">50%</option><option value="75">75%</option><option value="100">100%</option></select></td>';
		m += '<td colspan=3>'+tx("Gamble")+':&nbsp;<SELECT id=btTrnAutoGamble>\
			<option value=0><CENTER>-- '+uW.g_js_strings.commonstr.select+' --</center></option>\
			<option value=1>Use ' + t.gamble[1].cost + 'x resources (' + t.gamble[1].min + ' - ' + t.gamble[1].max + '% faster)</option>\
			<option value=2>Use ' + t.gamble[2].cost + 'x resources (' + t.gamble[2].min + ' - ' + t.gamble[2].max + '% faster)</option>\
			</select></td><td align=right><a id=btTrnAutoCopy>'+tx('Copy settings to all cities')+'</a>&nbsp;&nbsp;</td></tr></table>';

		// dismiss here!!

		var n = '<table class=xtab width=100%>';
		n += '<tr><td colspan=8><table class=xtab align=center cellpadding=0 cellspacing=0>';
		n += '<tr style="vertical-align:top;"><td rowspan=2><img src="'+IMGURL+'units/unit_1_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt1'][0]+'</td>';
		n += '<td rowspan=2><img src="'+IMGURL+'units/unit_2_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt2'][0]+'</td>';
		n += '<td rowspan=2><img src="'+IMGURL+'units/unit_3_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt3'][0]+'</td>';
		n += '<td rowspan=2><img src="'+IMGURL+'units/unit_4_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt4'][0]+'</td>';
		n += '<td rowspan=2><img src="'+IMGURL+'units/unit_5_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt5'][0]+'</td>';
		n += '<td rowspan=2><img src="'+IMGURL+'units/unit_6_30.jpg" /></td><td width=15%>'+uW.unitnamedesctranslated['unt6'][0]+'</td></tr>';

		n += '<tr style="vertical-align:top;"><td><INPUT type=CHECKBOX id=chkDoST></td><td><INPUT type=CHECKBOX id=chkDoMM></td>';
		n += '<td><INPUT type=CHECKBOX id=chkDoSC></td><td><INPUT type=CHECKBOX id=chkDoPK></td><td><INPUT type=CHECKBOX id=chkDoSW></td><td><INPUT type=CHECKBOX id=chkDoAR></td></tr>';
		n += '<tr><td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepST" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepST[citynum]+'"\></td>';
		n += '<td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepMM" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepMM[citynum]+'"\></td>';
		n += '<td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepSC" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepSC[citynum]+'"\></td>';
		n += '<td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepPK" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepPK[citynum]+'"\></td>';
		n += '<td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepSW" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepSW[citynum]+'"\></td>';
		n += '<td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="btDisKeepAR" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepAR[citynum]+'"\></td></tr>';
        n += '<tr><td colspan=12><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td align=center><br><input type=checkbox id=chkDoOther >'+tx('Override above rules by always dismissing')+' ';
		n += '<SELECT id=btDisOtherType><option value="0">-- '+uW.g_js_strings.commonstr.select+' --</option>';
		for (var ui in uW.cm.UNIT_TYPES) {
			var u = uW.cm.UNIT_TYPES[ui];
			if (u>6) {
				n += '<option value='+u+'>'+uW.unitcost["unt"+u][0]+'</option>';
			}	
		}
		n += '</select>&nbsp;'+tx('when more than')+' <INPUT class=btInput id="btDisKeepOther" type=text size=11 maxlength=12 value="'+ Options.TrainOptions.KeepOther[citynum]+'">&nbsp;'+tx('troops owned')+'.</td></tr></table></div></td></tr>';
		
		n += '</table></td></tr><tr><td colspan=8 align=right><a id=btDisAutoCopy>'+tx('Copy settings to all cities')+'</a>&nbsp;&nbsp;</td></tr></table>';

		ById('btTrnAuto').innerHTML = m;
		ById('btDisAuto').innerHTML = n;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

        ById('btTrnAutoPrimaryType').value = Options.TrainOptions.PrimaryTroops[citynum];
        ById('btTrnAutoPrimarySelMax').checked = Options.TrainOptions.PrimarySelectMax[citynum];
        if (!Options.TrainOptions.PrimarySelectMax[citynum]) {
			ById('btTrnAutoPrimaryMax').disabled=true;
			Options.TrainOptions.PrimaryMax[citynum] = t.getMaxTrain(Options.TrainOptions.PrimaryTroops[citynum],t.ModelCityId,true,Options.TrainOptions.Workers[citynum]);
			ById('btTrnAutoPrimaryMax').value = Options.TrainOptions.PrimaryMax[citynum];
		}

        ById('btTrnAutoSecondaryType').value = Options.TrainOptions.SecondaryTroops[citynum];
        ById('btTrnAutoSecondarySelMax').checked = Options.TrainOptions.SecondarySelectMax[citynum];
        if (!Options.TrainOptions.SecondarySelectMax[citynum]) {
			ById('btTrnAutoSecondaryMax').disabled=true;
			Options.TrainOptions.SecondaryMax[citynum] = t.getMaxTrain(Options.TrainOptions.SecondaryTroops[citynum],t.ModelCityId,true,Options.TrainOptions.Workers[citynum]);
			ById('btTrnAutoSecondaryMax').value = Options.TrainOptions.SecondaryMax[citynum];
		}

        if (!Options.TrainOptions.SecondaryEnabled[citynum]) {
			ById('btTrnAutoSecondaryType').disabled=true;
			ById('btTrnAutoSecondaryMin').disabled=true;
			ById('btTrnAutoSecondarySelMax').disabled=true;
			ById('btTrnAutoSecondaryMax').disabled=true;
		}

		if(ById('btTrnAutoAscensionEnabled')) {
			ById('btTrnAutoAscensionSelMax').checked = Options.TrainOptions.AscensionSelectMax[citynum];
			if (!Options.TrainOptions.AscensionSelectMax[citynum]) {
				ById('btTrnAutoAscensionMax').disabled=true;
				Options.TrainOptions.AscensionMax[citynum] = t.getMaxTrain(Options.TrainOptions.AscensionTroops[citynum],t.ModelCityId,true,Options.TrainOptions.Workers[citynum]);
				ById('btTrnAutoAscensionMax').value = Options.TrainOptions.AscensionMax[citynum];
			}

			if (!Options.TrainOptions.AscensionEnabled[citynum]) {
				ById('btTrnAutoAscensionMin').disabled=true;
				ById('btTrnAutoAscensionSelMax').disabled=true;
				ById('btTrnAutoAscensionMax').disabled=true;
			}
		}

        ById('btTrnAutoKeep').value = Options.TrainOptions.Keep[citynum];
        ById('btTrnAutoWorkers').value = Options.TrainOptions.Workers[citynum];
        ById('btTrnAutoGamble').value = Options.TrainOptions.Gamble[citynum];

		ById('btTrnAutoPrimaryType').addEventListener('change', function(e){
			Options.TrainOptions.PrimaryTroops[citynum] = e.target.value;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoPrimaryMin').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.PrimaryMin[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoPrimaryMax').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=t.getMaxTrain(Options.TrainOptions.PrimaryTroops[citynum],t.ModelCityId,true,Options.TrainOptions.Workers[citynum]);
			Options.TrainOptions.PrimaryMax[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoPrimarySelMax').addEventListener('change', function(e){
			Options.TrainOptions.PrimarySelectMax[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('btTrnAutoPrimaryLimit').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.PrimaryLimit[citynum] = e.target.value;
			saveOptions();
		}, false);

		ById('btTrnAutoReduceLimit').addEventListener('change', function(e){
			Options.TrainOptions.ReduceLimit[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoSecondaryEnabled').addEventListener('change', function(e){
			Options.TrainOptions.SecondaryEnabled[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoSecondaryType').addEventListener('change', function(e){
			Options.TrainOptions.SecondaryTroops[citynum] = e.target.value;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoSecondaryMin').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.SecondaryMin[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoSecondaryMax').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=t.getMaxTrain(Options.TrainOptions.SecondaryTroops[citynum],t.ModelCityId,true,Options.TrainOptions.Workers[citynum]);
			Options.TrainOptions.SecondaryMax[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoSecondarySelMax').addEventListener('change', function(e){
			Options.TrainOptions.SecondarySelectMax[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoWorkers').addEventListener('change', function(e){
			Options.TrainOptions.Workers[citynum] = e.target.value;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btTrnAutoGamble').addEventListener('change', function(e){
			Options.TrainOptions.Gamble[citynum] = e.target.value;
			saveOptions();
		}, false);

		ById('btTrnAutoKeep').addEventListener('change', function(e){
			Options.TrainOptions.Keep[citynum] = e.target.value;
			saveOptions();
		}, false);

		ById('btTrnAutoFood').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.Resources[citynum]['Food'] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoWood').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.Resources[citynum]['Wood'] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoStone').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.Resources[citynum]['Stone'] = e.target.value;
			saveOptions();
		}, false);
		ById('btTrnAutoOre').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.Resources[citynum]['Ore'] = e.target.value;
			saveOptions();
		}, false);

		if(ById('btTrnAutoAscensionEnabled')) {
			ById('btTrnAutoAscensionEnabled').addEventListener('change', function(e){
				Options.TrainOptions.AscensionEnabled[citynum] = e.target.checked;
				saveOptions();
				t.UpdateTrainingOptions();
			}, false);
			ById('btTrnAutoAscensionMin').addEventListener('change', function(e){
				if (isNaN(e.target.value)) e.target.value=0;
				Options.TrainOptions.AscensionMin[citynum] = e.target.value;
				saveOptions();
			}, false);
			ById('btTrnAutoAscensionMax').addEventListener('change', function(e){
				if (isNaN(e.target.value)) e.target.value=t.getMaxTroops(t.ModelCityId,Options.TrainOptions.AscensionTroops[citynum],true,Options.TrainOptions.Workers[citynum]);
				Options.TrainOptions.AscensionMax[citynum] = e.target.value;
				saveOptions();
			}, false);
			ById('btTrnAutoAscensionSelMax').addEventListener('change', function(e){
				Options.TrainOptions.AscensionSelectMax[citynum] = e.target.checked;
				saveOptions();
				t.UpdateTrainingOptions();
			}, false);
		};

        ById('chkDoST').checked = Options.TrainOptions.DismissST[citynum];
        ById('chkDoMM').checked = Options.TrainOptions.DismissMM[citynum];
        ById('chkDoSC').checked = Options.TrainOptions.DismissSC[citynum];
        ById('chkDoPK').checked = Options.TrainOptions.DismissPK[citynum];
        ById('chkDoSW').checked = Options.TrainOptions.DismissSW[citynum];
        ById('chkDoAR').checked = Options.TrainOptions.DismissAR[citynum];
        ById('chkDoOther').checked = Options.TrainOptions.DismissOther[citynum];

        ById('btDisOtherType').value = Options.TrainOptions.DismissOtherType[citynum];
		
        if (!Options.TrainOptions.DismissST[citynum]) {
			ById('btDisKeepST').disabled=true;
		}
        if (!Options.TrainOptions.DismissMM[citynum]) {
			ById('btDisKeepMM').disabled=true;
		}
        if (!Options.TrainOptions.DismissSC[citynum]) {
			ById('btDisKeepSC').disabled=true;
		}
        if (!Options.TrainOptions.DismissPK[citynum]) {
			ById('btDisKeepPK').disabled=true;
		}
        if (!Options.TrainOptions.DismissSW[citynum]) {
			ById('btDisKeepSW').disabled=true;
		}
        if (!Options.TrainOptions.DismissAR[citynum]) {
			ById('btDisKeepAR').disabled=true;
		}
        if (!Options.TrainOptions.DismissOther[citynum]) {
			ById('btDisKeepOther').disabled=true;
			ById('btDisOtherType').disabled=true;
		}

		ById('chkDoST').addEventListener('change', function(e){
			Options.TrainOptions.DismissST[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoMM').addEventListener('change', function(e){
			Options.TrainOptions.DismissMM[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoSC').addEventListener('change', function(e){
			Options.TrainOptions.DismissSC[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoPK').addEventListener('change', function(e){
			Options.TrainOptions.DismissPK[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoSW').addEventListener('change', function(e){
			Options.TrainOptions.DismissSW[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoAR').addEventListener('change', function(e){
			Options.TrainOptions.DismissAR[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		ById('chkDoOther').addEventListener('change', function(e){
			Options.TrainOptions.DismissOther[citynum] = e.target.checked;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);

		ById('btDisOtherType').addEventListener('change', function(e){
			Options.TrainOptions.DismissOtherType[citynum] = e.target.value;
			saveOptions();
			t.UpdateTrainingOptions();
		}, false);
		
		ById('btDisKeepST').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepST[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepMM').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepMM[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepSC').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepSC[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepPK').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepPK[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepSW').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepSW[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepAR').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepAR[citynum] = e.target.value;
			saveOptions();
		}, false);
		ById('btDisKeepOther').addEventListener('change', function(e){
			if (isNaN(e.target.value)) e.target.value=0;
			Options.TrainOptions.KeepOther[citynum] = e.target.value;
			saveOptions();
		}, false);

		ById('btTrnAutoCopy').addEventListener('click', function(e){
			t.CopyAutoTrainSettings(citynum);
			saveOptions();
			ById('btTrnMessages').innerHTML = 'Auto-train settings copied to all cities';
		}, false);
		ById('btDisAutoCopy').addEventListener('click', function(e){
			t.CopyAutoDismissSettings(citynum);
			saveOptions();
			ById('btTrnMessages').innerHTML = 'Auto-dismiss settings copied to all cities';
		}, false);

	},

	CopyAutoTrainSettings : function (citynum) {
		var t = Tabs.Train;
		for (var i = 1; i <= Cities.numCities; i++) {
			if (i!=citynum) {
//				Options.TrainOptions.Enabled[i] = Options.TrainOptions.Enabled[citynum];
				if (Options.TrainOptions.PrimaryTroops[citynum]==0 || t.CheckCanTrain(Options.TrainOptions.PrimaryTroops[citynum],Cities.cities[i-1].id)) {
					Options.TrainOptions.PrimaryTroops[i] = Options.TrainOptions.PrimaryTroops[citynum];
					Options.TrainOptions.PrimaryMin[i] = Options.TrainOptions.PrimaryMin[citynum];
					Options.TrainOptions.PrimarySelectMax[i] = Options.TrainOptions.PrimarySelectMax[citynum];
					Options.TrainOptions.PrimaryMax[i] = Options.TrainOptions.PrimaryMax[citynum];
					Options.TrainOptions.PrimaryLimit[i] = Options.TrainOptions.PrimaryLimit[citynum];
					Options.TrainOptions.ReduceLimit[i] = Options.TrainOptions.ReduceLimit[citynum];
				}
				if (Options.TrainOptions.SecondaryTroops[citynum]==0 || t.CheckCanTrain(Options.TrainOptions.SecondaryTroops[citynum],Cities.cities[i-1].id)) {
					Options.TrainOptions.SecondaryEnabled[i] = Options.TrainOptions.SecondaryEnabled[citynum];
					Options.TrainOptions.SecondaryTroops[i] = Options.TrainOptions.SecondaryTroops[citynum];
					Options.TrainOptions.SecondaryMin[i] = Options.TrainOptions.SecondaryMin[citynum];
					Options.TrainOptions.SecondarySelectMax[i] = Options.TrainOptions.SecondarySelectMax[citynum];
					Options.TrainOptions.SecondaryMax[i] = Options.TrainOptions.SecondaryMax[citynum];
				}
				if (Seed.cityData.city[Cities.cities[i-1].id].prestigeInfo.blessings) {
					Options.TrainOptions.AscensionEnabled[i] = Options.TrainOptions.AscensionEnabled[citynum];
//					Options.TrainOptions.AscensionTroops[i] = Options.TrainOptions.AscensionTroops[citynum];
					Options.TrainOptions.AscensionMin[i] = Options.TrainOptions.AscensionMin[citynum];
					Options.TrainOptions.AscensionSelectMax[i] = Options.TrainOptions.AscensionSelectMax[citynum];
					Options.TrainOptions.AscensionMax[i] = Options.TrainOptions.AscensionMax[citynum];
				}
				Options.TrainOptions.Gamble[i] = Options.TrainOptions.Gamble[citynum];
				Options.TrainOptions.Workers[i] = Options.TrainOptions.Workers[citynum];
				Options.TrainOptions.Keep[i] = Options.TrainOptions.Keep[citynum];
				Options.TrainOptions.Resources[i].Food = Options.TrainOptions.Resources[citynum].Food;
				Options.TrainOptions.Resources[i].Wood = Options.TrainOptions.Resources[citynum].Wood;
				Options.TrainOptions.Resources[i].Stone = Options.TrainOptions.Resources[citynum].Stone;
				Options.TrainOptions.Resources[i].Ore = Options.TrainOptions.Resources[citynum].Ore;
			}
		}
	},

	CopyAutoDismissSettings : function (citynum) {
		var t = Tabs.Train;
		for (var i = 1; i <= Cities.numCities; i++) {
			if (i!=citynum) {
//				Options.TrainOptions.AutoDismiss[i] = Options.TrainOptions.AutoDismiss[citynum];
				Options.TrainOptions.DismissST[i] = Options.TrainOptions.DismissST[citynum];
				Options.TrainOptions.DismissMM[i] = Options.TrainOptions.DismissMM[citynum];
				Options.TrainOptions.DismissSC[i] = Options.TrainOptions.DismissSC[citynum];
				Options.TrainOptions.DismissPK[i] = Options.TrainOptions.DismissPK[citynum];
				Options.TrainOptions.DismissSW[i] = Options.TrainOptions.DismissSW[citynum];
				Options.TrainOptions.DismissAR[i] = Options.TrainOptions.DismissAR[citynum];
				Options.TrainOptions.DismissOther[i] = Options.TrainOptions.DismissOther[citynum];
				Options.TrainOptions.DismissOtherType[i] = Options.TrainOptions.DismissOtherType[citynum];
				Options.TrainOptions.KeepST[i] = Options.TrainOptions.KeepST[citynum];
				Options.TrainOptions.KeepMM[i] = Options.TrainOptions.KeepMM[citynum];
				Options.TrainOptions.KeepSC[i] = Options.TrainOptions.KeepSC[citynum];
				Options.TrainOptions.KeepPK[i] = Options.TrainOptions.KeepPK[citynum];
				Options.TrainOptions.KeepSW[i] = Options.TrainOptions.KeepSW[citynum];
				Options.TrainOptions.KeepAR[i] = Options.TrainOptions.KeepAR[citynum];
				Options.TrainOptions.KeepOther[i] = Options.TrainOptions.KeepOther[citynum];
			}
		}
	},

	doAutoLoop : function (idx) {
		var t = Tabs.Train;
		clearTimeout(t.timer);
		if (!Options.TrainOptions.Running && !Options.TrainOptions.DismissRunning) return;

		var cityId = Cities.cities[idx-1].id;
		t.autodelay = 0; // no delay if no action taken!

		if (Options.TrainOptions.Running) {
			var TroopsQueued = false;
			var ts = Math.floor(equippedthronestats(77));
		    if (!Options.TrainOptions.ThroneCheck || (Options.TrainOptions.TrainingSpeed == 0) || (Options.TrainOptions.TrainingSpeed <= ts)) {
				var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[idx]);
				if (Options.TrainOptions.Enabled[idx] && ascensionok) {
					var stonelevel = (Seed.guardian[idx-1].cityGuardianLevels["stone"]?Seed.guardian[idx-1].cityGuardianLevels["stone"]:0);
					if (!Options.TrainOptions.StoneGuardian[idx] || (stonelevel == 0) || (Seed.guardian[idx-1].type == "stone")) {
						// check ascension first...
						if (Seed.cityData.city[cityId].isPrestigeCity && Options.TrainOptions.AscensionEnabled[idx]) {
							var NumTrain = t.getMaxTrain(Options.TrainOptions.AscensionTroops[idx],cityId,false,Options.TrainOptions.Workers[idx],Options.TrainOptions.Gamble[idx],true);
							if (NumTrain > 0 && NumTrain >= parseIntNan(Options.TrainOptions.AscensionMin[idx])) {
								if (Options.TrainOptions.AscensionSelectMax[idx] && NumTrain > parseIntNan(Options.TrainOptions.AscensionMax[idx])) {
									NumTrain = parseIntNan(Options.TrainOptions.AscensionMax[idx]);
								}
								if (t.CheckTrainSlots(cityId,true)) {
									t.Train(cityId, 0, Options.TrainOptions.Gamble[idx], Options.TrainOptions.AscensionTroops[idx], NumTrain);
									t.autodelay = t.intervalSecs;
									TroopsQueued = true;
								}
							}
						}

						if (!TroopsQueued) {
							// check primary troop conditions...
							var PrimaryLimit = parseIntNan(Options.TrainOptions.PrimaryLimit[idx]);
							var TroopsOwned = parseIntNan(getCityTroops(Options.TrainOptions.PrimaryTroops[idx],cityId,true));
							var NumTrain = t.getMaxTrain(Options.TrainOptions.PrimaryTroops[idx],cityId,false,Options.TrainOptions.Workers[idx],Options.TrainOptions.Gamble[idx],true);
							if (NumTrain>0) {
								if (Options.TrainOptions.ReduceLimit[idx]) {
									if (NumTrain > PrimaryLimit) { NumTrain = PrimaryLimit; }
								}
								else {
									if (PrimaryLimit > 0 && NumTrain > (PrimaryLimit-TroopsOwned)) { NumTrain = PrimaryLimit-TroopsOwned; }
								}
							}
							if (NumTrain>0) {
								if (NumTrain >= parseIntNan(Options.TrainOptions.PrimaryMin[idx])) {
									if (Options.TrainOptions.PrimarySelectMax[idx] && NumTrain > parseIntNan(Options.TrainOptions.PrimaryMax[idx])) {
										NumTrain = parseIntNan(Options.TrainOptions.PrimaryMax[idx]);
									}
									if (t.CheckTrainSlots(cityId,false)) {
										t.Train(cityId, 0, Options.TrainOptions.Gamble[idx], Options.TrainOptions.PrimaryTroops[idx], NumTrain, function(rslt) {
											if (rslt.ok) {
												if (Options.TrainOptions.ReduceLimit[idx]) {
													Options.TrainOptions.PrimaryLimit[idx] = Options.TrainOptions.PrimaryLimit[idx] - NumTrain;
													if (Options.TrainOptions.PrimaryLimit[idx]<0) Options.TrainOptions.PrimaryLimit[idx]=0;
													saveOptions();
													if (ById('btTrnAutoPrimaryLimit') && cityId==t.ModelCityId) { ById('btTrnAutoPrimaryLimit').value = Options.TrainOptions.PrimaryLimit[idx]; }
												}
											}
										});
										t.autodelay = t.intervalSecs;
										TroopsQueued = true;
									}
								}
								else {
									TroopsQueued = true; // don't allow secondary if primary valid but we're waiting for population.. HOPEFULLY this will still allow us to move to secondary if no yew branches when flame archers are primary (?)
								}
							}
						}

						if (!TroopsQueued) {
							// check secondary troops...
							if (Options.TrainOptions.SecondaryEnabled[idx]) {
								var NumTrain = t.getMaxTrain(Options.TrainOptions.SecondaryTroops[idx],cityId,false,Options.TrainOptions.Workers[idx],Options.TrainOptions.Gamble[idx],true);
								if (NumTrain >= parseIntNan(Options.TrainOptions.SecondaryMin[idx])) {
									if (Options.TrainOptions.SecondarySelectMax[idx] && NumTrain > parseIntNan(Options.TrainOptions.SecondaryMax[idx])) {
										NumTrain = parseIntNan(Options.TrainOptions.SecondaryMax[idx]);
									}
									if (t.CheckTrainSlots(cityId,false)) {
										t.Train(cityId, 0, Options.TrainOptions.Gamble[idx], Options.TrainOptions.SecondaryTroops[idx], NumTrain);
										t.autodelay = t.intervalSecs;
										TroopsQueued = true;
									}
								}
							}
						}
					}
				}
			}

			if (!TroopsQueued) {
				t.speedupused = false;
				var q = Seed.queue_unt['city' + cityId];
				t.expireTheQueue(q);

				var q1 = [];
				var q2 = [];

				for (var u in q) {
					if (q[u][0]) {
						if (q[u][7]) { q2.push(q[u]); }
						else { q1.push(q[u]); }
					}
				}

				var speedup = false;
				var speedupascension = false;
				if (q2 != null && q2.length > 0) { speedupascension = true;	}
				else { if (q1 != null && q1.length > 0) { speedup = true; } }
				if (speedupascension && !t.speedupused) {
					for (var i = 0; i < q.length; i++) {
						if (!uW.cm.BarracksUnitsTypeMap.isUnitType(q[i][0], "normal")) {
							t.autoSpeedup(cityId,q[i],i);
							break;
						}
					}
				}
				if (speedup && !t.speedupused) {
					for (var i = 0; i < q.length; i++) {
						if (uW.cm.BarracksUnitsTypeMap.isUnitType(q[i][0], "normal")) {
							t.autoSpeedup(cityId,q[i],i);
							break;
						}
					}
				}
			}
		}

		if (Options.TrainOptions.DismissRunning) {
			t.GetMorePopulation(idx-1);
		}

		if (idx == Cities.numCities) {
			t.timer = setTimeout(function () { t.doAutoLoop(1); }, (t.intervalSecs * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1); }, (t.autodelay * 1000));
		}
	},

    autoSpeedup: function (cityId,q,slot) {
		var t = Tabs.Train;
		var now = unixTime();
		var item = 0;
		totTime = q[3] - now;

		if (totTime > 0) {
			if (item==0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.TrainOptions.MTLimitMinutes)*60)+(parseIntNan(Options.TrainOptions.MTLimitHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && Options.TrainOptions.UseMT && uW.ksoItems[38].count > 0) { item = 38; }
			}

			if (item==0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.TrainOptions.ATLimitMinutes)*60)+(parseIntNan(Options.TrainOptions.ATLimitHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && Options.TrainOptions.UseAT && uW.ksoItems[37].count > 0) { item = 37; }
			}

			if (item==0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.TrainOptions.LTLimitMinutes)*60)+(parseIntNan(Options.TrainOptions.LTLimitHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && Options.TrainOptions.UseLT && uW.ksoItems[36].count > 0) { item = 36; }
			}

			if (item==0) {
				if (Options.TrainOptions.UseOverride && Options.TrainOptions.OverrideItem != 0) {
					var THRESHOLD_SECONDS = (parseIntNan(Options.TrainOptions.OverrideMinutes)*60)+(parseIntNan(Options.TrainOptions.OverrideHours)*60*60);
					if (totTime >= THRESHOLD_SECONDS && uW.ksoItems[Options.TrainOptions.OverrideItem].count > 0) { item = Options.TrainOptions.OverrideItem; }
				}
				if (item==0 && totTime >= HourGlassThreshold[8] && Options.TrainOptions.UseLH && uW.ksoItems[10].count > 0) { item = 10; }
				if (item==0 && totTime >= HourGlassThreshold[7] && Options.TrainOptions.UseEH && uW.ksoItems[8].count > 0) { item = 8; }
				if (item==0 && totTime >= HourGlassThreshold[6] && Options.TrainOptions.UseDH && uW.ksoItems[7].count > 0) { item = 7; }
				if (item==0 && totTime >= HourGlassThreshold[5] && Options.TrainOptions.UseRH && uW.ksoItems[6].count > 0) { item = 6; }
				if (item==0 && totTime >= HourGlassThreshold[4] && Options.TrainOptions.UseAH && uW.ksoItems[5].count > 0) { item = 5; }
				if (item==0 && totTime >= HourGlassThreshold[3] && Options.TrainOptions.UseMH && uW.ksoItems[4].count > 0) { item = 4; }
				if (item==0 && totTime >= HourGlassThreshold[2] && Options.TrainOptions.UseGH && uW.ksoItems[3].count > 0) { item = 3; }
				if (item==0 && totTime >= HourGlassThreshold[1] && Options.TrainOptions.UseKH && uW.ksoItems[2].count > 0) { item = 2; }
				if (item==0 && totTime >= HourGlassThreshold[0] && Options.TrainOptions.UseSH && uW.ksoItems[1].count > 0) { item = 1; }
			}
        }

		if (item != 0) {
			t.autodelay = t.intervalSecs;
			t.speedupused = true;
			t.speedupTraining(cityId,q[0],item,slot,true);
		}
    },

	CheckTrainSlots : function(cityId,prestige){
		var t = Tabs.Train;
		var Buildings = getCityBuildings(cityId);
		if (!prestige) {
			var barracks = Number(Buildings[13].count);
			var slots = 0;
			for (var k in Seed.queue_unt['city'+cityId]) {
				if(Seed.queue_unt['city'+cityId][k][7] == false) {
					slots += 1;
				}
			}
		}
		else {
			var barracks = Number(Buildings[22].count + Buildings[24].count + Buildings[26].count); //22 druid barracks, 24 fey barracks, 26 briton barracks
			var slots = 0;
			for (var k in Seed.queue_unt['city'+cityId]) {
				if(Seed.queue_unt['city'+cityId][k][7] == true) {
					slots += 1;
				}
			}
		}
		return (barracks>slots)?true:false;
	},

	GetMorePopulation: function (idx) {
		var t = Tabs.Train;
		// Dismiss works one city behind, so if idx < 1, then it must be the end city
		if (idx<1) {idx=Cities.numCities; }

		if (!Options.TrainOptions.AutoDismiss[idx]) { return; }

		var cityId = Seed.cities[idx-1][0];
		var Buildings = getCityBuildings(cityId);

		var max_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[1])).toFixed(0);
		var cur_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0);
		var barracks = parseInt(Buildings[13].count);
		var slots_used = 0;
		for (var k in Seed.queue_unt['city'+cityId]) {
			if(Seed.queue_unt['city'+cityId][k][7] == false) {
				slots_used += 1;
			}
		}
		var slots_free = parseInt(barracks-slots_used);

		var num = parseInt(max_idle_pop) - parseInt(cur_idle_pop);
		if (num == 0) return; // max pop

		var trooptype = 0;
		var to_dismiss = 0;
		if (Options.TrainOptions.DismissOther[idx] && (parseIntNan(Seed.units['city'+cityId]['unt'+Options.TrainOptions.DismissOtherType[idx]]) > parseIntNan(Options.TrainOptions.KeepOther[idx])) && (Options.TrainOptions.DismissOtherType[idx]!=0)) { trooptype = Options.TrainOptions.DismissOtherType[idx]; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt'+Options.TrainOptions.DismissOtherType[idx]]) - parseIntNan(Options.TrainOptions.KeepOther[idx]); } // Other
		else {
			if (Options.TrainOptions.DismissST[idx] && (parseIntNan(Seed.units['city'+cityId]['unt1']) > parseIntNan(Options.TrainOptions.KeepST[idx]))) { trooptype = 1; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt1']) - parseIntNan(Options.TrainOptions.KeepST[idx]); } // ST
			else {
				if (Options.TrainOptions.DismissMM[idx] && (parseIntNan(Seed.units['city'+cityId]['unt2']) > parseIntNan(Options.TrainOptions.KeepMM[idx]))) { trooptype = 2; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt2']) - parseIntNan(Options.TrainOptions.KeepMM[idx]); } // MM
				else {
					if (Options.TrainOptions.DismissSC[idx] && (parseIntNan(Seed.units['city'+cityId]['unt3']) > parseIntNan(Options.TrainOptions.KeepSC[idx]))) { trooptype = 3; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt3']) - parseIntNan(Options.TrainOptions.KeepSC[idx]); } // SC
					else {
						if (Options.TrainOptions.DismissPK[idx] && (parseIntNan(Seed.units['city'+cityId]['unt4']) > parseIntNan(Options.TrainOptions.KeepPK[idx]))) { trooptype = 4; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt4']) - parseIntNan(Options.TrainOptions.KeepPK[idx]); } // PK
						else {
							if (Options.TrainOptions.DismissSW[idx] && (parseIntNan(Seed.units['city'+cityId]['unt5']) > parseIntNan(Options.TrainOptions.KeepSW[idx]))) { trooptype = 5; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt5']) - parseIntNan(Options.TrainOptions.KeepSW[idx]); } // SW
							else {
								if (Options.TrainOptions.DismissAR[idx] && (parseIntNan(Seed.units['city'+cityId]['unt6']) > parseIntNan(Options.TrainOptions.KeepAR[idx]))) { trooptype = 6; to_dismiss = parseIntNan(Seed.units['city'+cityId]['unt6']) - parseIntNan(Options.TrainOptions.KeepAR[idx]); } // AR
							}
						}
					}
				}
			}
		}	

		if (trooptype == 0) return; // none selected


		// if no slots free, check if less than a min to go in current training queue...

		NearlyDone = false;
		if ((slots_free <= 0) && (barracks != 0)) {
			var q = Seed.queue_unt['city'+cityId];
			for(var i = 0; i<q.length; i++){
				if(!q[i][7]){
					cur = q[i][3] - now;
					break;
				}
			}
			NearlyDone = (cur <= 60);
		}

		if (num > to_dismiss) { num = to_dismiss; }
		if (((slots_free > 0) || NearlyDone) && (num > 0) ) {
			t.Dismiss(cityId,trooptype,num);
		}
	},

	PaintCityInfo : function () {
		var t = Tabs.Train;
		var cityId = t.ModelCityId;

		t.Squire = parseIntNan(Seed.items.i1);
		t.Knight = parseIntNan(Seed.items.i2);
		t.Guinevere = parseIntNan(Seed.items.i3);
		t.Morgana = parseIntNan(Seed.items.i4);
		t.Arthur = parseIntNan(Seed.items.i5);
		t.Merlin = parseIntNan(Seed.items.i6);
		t.Divine = parseIntNan(Seed.items.i7);
		t.Epic = parseIntNan(Seed.items.i8);
		t.Legendary = parseIntNan(Seed.items.i10);

		t.Lancelots = parseIntNan(Seed.items.i36);
		t.Arthurs = parseIntNan(Seed.items.i37);
		t.Merlins = parseIntNan(Seed.items.i38);

		ById('pbtrainUseSHLabel').innerHTML = t.Squire;
		ById('pbtrainUseKHLabel').innerHTML = t.Knight;
		ById('pbtrainUseGHLabel').innerHTML = t.Guinevere;
		ById('pbtrainUseMHLabel').innerHTML = t.Morgana;
		ById('pbtrainUseAHLabel').innerHTML = t.Arthur;
		ById('pbtrainUseRHLabel').innerHTML = t.Merlin;
		ById('pbtrainUseDHLabel').innerHTML = t.Divine;
		ById('pbtrainUseEHLabel').innerHTML = t.Epic;
		ById('pbtrainUseLHLabel').innerHTML = t.Legendary;

		ById('pbtrainUseLTLabel').innerHTML = t.Lancelots;
		ById('pbtrainUseATLabel').innerHTML = t.Arthurs;
		ById('pbtrainUseMTLabel').innerHTML = t.Merlins;

		if (cityId==0) { return; }
		if (t.serverwait) { return; }

		// paint the Queue...
		// training queue is combined - normal and prestige. That's insane. Let's split them!

		var Buildings = getCityBuildings(cityId);

		var now = unixTime();
		var totTime = 0;
		var totTimeAscension = 0;
		t.Queued = 0;
		t.QueuedAscension = 0;
		t.TotalSlots = Buildings[13].count;
		t.TotalSlotsAscension = Buildings[22].count+Buildings[24].count+Buildings[26].count;
		var q = Seed.queue_unt['city' + cityId];
		t.expireTheQueue(q);

		var q1 = [];
		var q2 = [];

		for (var u in q) {
			if (q[u][0]) {
				if (q[u][7]) { q2.push(q[u]); }
				else { q1.push(q[u]); }
			}
		}

		if (q1 != null && q1.length > 0) {
			totTime = q1[q1.length - 1][3] - now;
			t.Queued = q1.length;
		}
		if (q2 != null && q2.length > 0) {
			totTimeAscension = q2[q2.length - 1][3] - now;
			t.QueuedAscension = q2.length;
		}
		var qs = q.toString();
		if (qs == t.LastQueue) { // queue hasn't changed, just update the time of the current item(s)
			if (q1 != null && q1.length > 0) {
				var cur = q1[0][3] - now;
				ById('btTrnQueueRemaining').innerHTML = timestr(cur, true);
			}
			if (q2 != null && q2.length > 0) {
				var cur = q2[0][3] - now;
				ById('btAscTrnQueueRemaining').innerHTML = timestr(cur, true);
			}
			if ((!q1 || q1.length==0) && (!q2 || q2.length==0)) {
				m = '<br><div align=center style="opacity:0.3;">'+tx('No Troops Currently Being Trained')+'</div>';
				ById('btTrnQueue').innerHTML = m;
			}
		} else {
			t.LastQueue = qs;
			m = '';

			if (q1 != null && q1.length > 0) {
				m += '<TABLE width=98% cellspacing=0 align=center class=xtab><tr><th class=xtabHD align=left>'+uW.g_js_strings.openCastle.trooptype+'</th><th class=xtabHD align=right>'+tx('Amount')+'</th><th class=xtabHD align=right>'+tx('Total Time')+'</th><th class=xtabHD align=right>'+tx('Remaining')+'</th><th class=xtabHD align=right>'+tx('Tuteleges')+'</th><th class=xtabHD align=right>'+tx('Hourglasses')+'</th><th class=xtabHD align=right><a id=btTrnCancelAllButton class="inlineButton btButton red14" onclick="btTrnCancelAll('+cityId+')"><span>'+tx('Cancel All')+'</span></a></th></tr>';
				t.fixQueTimes(q1);
				first = true;
				var lastEnd = now;
				var r = 0;

				for (var i = 0; i < q.length; i++) {
					if (uW.cm.BarracksUnitsTypeMap.isUnitType(q[i][0], "normal")) {
						start = q[i][2];
						end = q[i][3];
						actual = end - lastEnd;
						if (actual < 0) { actual = 0; }

						rowClass = 'evenRow';
						var rem = (r % 2);
						if (rem == 1) rowClass = 'oddRow';
						if (first) rowClass += ' highRow';

						m += '<TR class="'+rowClass+'"><TD align=left>'+TroopImage(q[i][0])+uW.unitcost["unt"+q[i][0]][0]+'</td><td align=right>'+addCommas(q[i][1])+'</td><td align=right>';
						if (first) {
							var tutes = '<table cellspacing=0 cellpadding=0><tr>';
							tutes += t.paintSpeedup(cityId,q[i][0],i,36,t.Lancelots,'30% Reduction');
							tutes += t.paintSpeedup(cityId,q[i][0],i,37,t.Arthurs,'50% Reduction');
							tutes += t.paintSpeedup(cityId,q[i][0],i,38,t.Merlins,'70% Reduction');
							tutes += '</tr></table>'

							var Speedups = '<table cellspacing=0 cellpadding=0><tr>';
							Speedups += t.paintSpeedup(cityId,q[i][0],i,1,t.Squire,'1 min');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,2,t.Knight,'15 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,3,t.Guinevere,'60 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,4,t.Morgana,'150 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,5,t.Arthur,'8 hours');
							Speedups += '</tr><tr>';
							Speedups += t.paintSpeedup(cityId,q[i][0],i,6,t.Merlin,'15 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,7,t.Divine,'24 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,8,t.Epic,'60 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,10,t.Legendary,'96 hours');
							Speedups += '</tr></table>'

							m += timestr(end - start, true) + '</td><TD align=right><SPAN id=btTrnQueueRemaining>' + timestr(actual, true) + '</span></td><td align=right>'+tutes+'</td><td align=right>'+Speedups+'</td>';
						}
						else { m += timestr(actual, true) + '</td><td align=right>&nbsp;</td><td align=center>&nbsp;</td><td align=center>&nbsp;</td>'; }
						m += '<td align=right><A class="inlineButton btButton brown11" onclick="cancelTrain(' + q[i][0] + ',' + q[i][1] + ',' + q[i][2] + ',' + q[i][3] + ',' + q[i][5] + ',' + cityId + ',' + i + ')"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr>'
						lastEnd = end;
						first = false;
						r++;
					}
				}
			}
			if (q2 != null && q2.length > 0) {
				if (!q1 || q1.length==0) {
					m += '<TABLE width=98% cellspacing=0 align=center class=xtab><tr><th class=xtabHD align=left>'+tx('Ascension')+'</th><th class=xtabHD align=right>'+uW.g_js_strings.commonstr.amount+'</th><th class=xtabHD align=right>'+tx('Total Time')+'</th><th class=xtabHD align=right>'+tx('Remaining')+'</th><th class=xtabHD align=right>'+tx('Tuteleges')+'</th><th class=xtabHD align=right>'+tx('Hourglasses')+'</th><th class=xtabHD align=right><a id=btTrnCancelAllButton class="inlineButton btButton red14" onclick="btTrnCancelAll('+cityId+')"><span>'+tx('Cancel All')+'</span></a></th></tr>';
				}
				else {
					m += '<tr><th class=xtabHD align=left>'+tx('Ascension')+'</th><th class=xtabHD align=right>'+uW.g_js_strings.commonstr.amount+'</th><th class=xtabHD align=right>'+tx('Total Time')+'</th><th class=xtabHD align=right>'+tx('Remaining')+'</th><th class=xtabHD align=right>'+tx('Tuteleges')+'</th><th class=xtabHD align=right>'+tx('Hourglasses')+'</th><th class=xtabHD align=right>&nbsp;</th></tr>';
				}
				t.fixQueTimes(q2);
				first = true;
				var lastEnd = now;
				var r = 0;

				for (var i = 0; i < q.length; i++) {
					if (!uW.cm.BarracksUnitsTypeMap.isUnitType(q[i][0], "normal")) {
						start = q[i][2];
						end = q[i][3];
						actual = end - lastEnd;
						if (actual < 0) { actual = 0; }

						rowClass = 'evenRow';
						var rem = (r % 2);
						if (rem == 1) rowClass = 'oddRow';
						if (first) rowClass += ' highRow';

						m += '<TR class="'+rowClass+'"><TD align=left>'+TroopImage(q[i][0])+uW.unitcost["unt"+q[i][0]][0]+'</td><td align=right>'+addCommas(q[i][1])+'</td><td align=right>';
						if (first) {
							var tutes = '<table cellspacing=0 cellpadding=0><tr>';
							tutes += t.paintSpeedup(cityId,q[i][0],i,36,t.Lancelots,'30% Reduction');
							tutes += t.paintSpeedup(cityId,q[i][0],i,37,t.Arthurs,'50% Reduction');
							tutes += t.paintSpeedup(cityId,q[i][0],i,38,t.Merlins,'70% Reduction');
							tutes += '</tr></table>'

							var Speedups = '<table cellspacing=0 cellpadding=0><tr>';
							Speedups += t.paintSpeedup(cityId,q[i][0],i,1,t.Squire,'1 min');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,2,t.Knight,'15 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,3,t.Guinevere,'60 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,4,t.Morgana,'150 mins');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,5,t.Arthur,'8 hours');
							Speedups += '</tr><tr>';
							Speedups += t.paintSpeedup(cityId,q[i][0],i,6,t.Merlin,'15 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,7,t.Divine,'24 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,8,t.Epic,'60 hours');
							Speedups += t.paintSpeedup(cityId,q[i][0],i,10,t.Legendary,'96 hours');
							Speedups += '</tr></table>'

							m += timestr(end - start, true) + '</td><TD align=right><SPAN id=btAscTrnQueueRemaining>' + timestr(actual, true) + '</span></td><td align=right>'+tutes+'</td><td align=right>'+Speedups+'</td>';
						}
						else { m += timestr(actual, true) + '</td><td align=right>&nbsp;</td><td align=center>&nbsp;</td><td align=center>&nbsp;</td>'; }
						m += '<td align=right><A class="inlineButton btButton brown11" onclick="cancelTrain(' + q[i][0] + ',' + q[i][1] + ',' + q[i][2] + ',' + q[i][3] + ',' + q[i][5] + ',' + cityId + ',' + i + ')"><span>'+uW.g_js_strings.commonstr.cancel+'</span></a></td></tr>'
						lastEnd = end;
						first = false;
						r++;
					}
				}
			}
			if ((!q1 || q1.length==0) && (!q2 || q2.length==0)) {
				m = '<br><div align=center style="opacity:0.3;">'+tx('No Troops Currently Being Trained')+'</div>';
			}
			else {
				m += '</table><div align=center id=btTrnQueueMessage>&nbsp;</div>';
			}
			ById('btTrnQueue').innerHTML = m;
			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		}
		m = t.Queued+' '+uW.g_js_strings.commonstr.of+' '+t.TotalSlots;
		if (totTime > 0)
			m += ', ' + uW.timestr(totTime);
		ById('btTrnQueueStats').innerHTML = m;

		// paint info into the city panel...

		var unitId = ById('btTrnType').value;
		var unitOwned = getCityTroops(unitId,cityId,true);
		t.MaxTroopTrain = 0;
		if (t.CheckCanTrain(unitId,cityId)) {
			var workers = 0;
			if (Options.TrainOptions.ManualWorkers) workers = 100;
			t.MaxTroopTrain = t.getMaxTrain(unitId,cityId,false,workers,ById('btTrnGamble').value);
		}

		ById('btTrnMax').innerHTML = uW.g_js_strings.commonstr.max + ':&nbsp;' + t.MaxTroopTrain + ',&nbsp;' + uW.g_js_strings.commonstr.owned + ':&nbsp;' + unitOwned;

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "normal")) {
			ById('btTrnMaxSlots').innerHTML = t.TotalSlots - t.Queued;
		}
		else {
			ById('btTrnMaxSlots').innerHTML = t.TotalSlotsAscension - t.QueuedAscension;
		}
		var slots = Math.max(parseIntNan(ById('btTrnNumSlots').value),0);
		ById('btTrnMaxPerSlot').innerHTML = parseIntNan(t.MaxTroopTrain / slots);

		// paint the requirements...

		t.paintRequirements(unitId);
	},

	paintSpeedup : function (cityId, qitem, i, item, count, hint) {
		var t = Tabs.Train;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px;padding-bottom:2px;"><a onClick="speedupTraining('+cityId+','+qitem+','+item+','+i+')"><img height=20 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+hint+') ('+count+')"></a></td>';
		}
		return n;
	},

	paintRequirements : function (unitId) {
		var t = Tabs.Train;
		var cityId = t.ModelCityId;

		var m = '';

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "rare")) {
			m += tx('Troop type cannot be trained');
			ById('btTrnRequirements').innerHTML = m;
			return;
		}

		var ascended = getAscensionValues(cityId);

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "druid") && ascended.prestigeType!=1) {
			m += tx('Troop type can only be trained in Druid cities');
			ById('btTrnRequirements').innerHTML = m;
			return;
		}

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "fey") && ascended.prestigeType!=2) {
			m += tx('Troop type can only be trained in Fey cities');
			ById('btTrnRequirements').innerHTML = m;
			return;
		}

		if (uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "briton") && ascended.prestigeType!=3) {
			m += tx('Troop type can only be trained in Briton cities');
			ById('btTrnRequirements').innerHTML = m;
			return;
		}

		if (uW.unitcost['unt'+unitId][8] && matTypeof(uW.unitcost['unt'+unitId][8]) === "object") {
			var Buildings = getCityBuildings(cityId);
			for (var b in uW.unitcost['unt'+unitId][8]) {
				var bid = b.split("b")[1];
				var reqlevel = uW.unitcost['unt'+unitId][8][b][1];
				var blvl = Buildings[bid].maxLevel;
				var linestyle = '<span>';
				if (blvl < reqlevel) {
					linestyle = '<span style="color:#800;"><b>';
					m += linestyle+'Level '+reqlevel+' '+uW.buildingcost['bdg'+bid][0]+'</b></span><br>';
				}
			}
		}

		if (uW.unitcost['unt'+unitId][9] && matTypeof(uW.unitcost['unt'+unitId][9]) === "object") {
			for (var r in uW.unitcost['unt'+unitId][9]) {
				var rid = r.split("t")[1];
				var reqlevel = uW.unitcost['unt'+unitId][9][r][1];
				var rlvl = Seed.tech['tch'+rid];
				var linestyle = '<span>';
				if (rlvl < reqlevel) {
					linestyle = '<span style="color:#800;"><b>';
					m += linestyle+'Level '+reqlevel+' '+uW.techcost['tch'+rid][0]+'</b></span><br>';
				}
			}
		}

		m += '<table class=xtab cellpadding=0 cellspacing=0 width=100%>';

		if (uW.unitcost['unt'+unitId][6] != 0) {
			m += '<tr><td>';
			m += ResourceImage(PopulationImage,uW.g_js_strings.commonstr.population);
			var reqlevel = uW.unitcost['unt'+unitId][6]*parseIntNan(ById('btTrnNumPerSlot').value);
			if (Options.TrainOptions.ManualWorkers) {
				var plvl = parseIntNan(Seed.citystats["city" + cityId]["pop"][0]);
			}
			else {
				var plvl = parseIntNan(Seed.citystats["city" + cityId]["pop"][0]) - parseIntNan(Seed.citystats["city" + cityId]["pop"][3]);
			}
			var linestyle = '<span>';
			if ((plvl <= reqlevel) || (t.limitingFactor=="pop")) {
				linestyle = '<span style="color:#800;"><b>';
			}
			m += '</td><td>'+linestyle+addCommas(reqlevel)+' / '+addCommas(plvl)+'</b></span></td></tr>';
		}

		var gambleFactor = 1;
		if (ById('btTrnGamble').value > 0)
			gambleFactor = t.gamble[ById('btTrnGamble').value].cost;

		for (var r = 1; r < 5; r++) {
			if (uW.unitcost['unt'+unitId][r] != 0) {
				m += '<tr><td>';
				if (r==1) { m += ResourceImage(FoodImage,uW.g_js_strings.commonstr.food); }
				else {
					if (r==2) { m += ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood); }
					else {
						if (r==3) { m += ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone);	}
						else {
							if (r==4) { m += ResourceImage(OreImage,uW.g_js_strings.commonstr.ore);	}
						}
					}
				}
				var reqlevel = uW.unitcost['unt'+unitId][r]*parseIntNan(ById('btTrnNumPerSlot').value)*gambleFactor;
				var rlvl = parseIntNan(Seed.resources['city'+cityId]['rec'+r][0]/3600);
				var linestyle = '<span>';
				if ((rlvl <= reqlevel) || (t.limitingFactor==uW.resourceinfo['rec'+r])) {
					linestyle = '<span style="color:#800;"><b>';
				}
				m += '</td><td>'+linestyle+addCommas(reqlevel)+' / '+addCommas(rlvl)+'</b></span></td></tr>';
			}
		}

		if (uW.unitcost['unt'+unitId][11] && matTypeof(uW.unitcost['unt'+unitId][11]) === "object") {
			for (var r in uW.unitcost['unt'+unitId][11]) {
				var iid = r;
				var reqlevel = uW.unitcost['unt'+unitId][11][r]*parseIntNan(ById('btTrnNumPerSlot').value);
				var ilvl = parseIntNan(Seed.items['i'+iid]);
				var linestyle = '<span>';
				if ((ilvl <= reqlevel) || (iid==34001 && t.limitingFactor=="yew") || (iid==34003 && t.limitingFactor=="corrupter")) {
					linestyle = '<span style="color:#800;"><b>';
				}
				m += '<tr><td>'+ResourceImage(getItemImageURL(iid),uW.itemlist['i'+iid].name)+'</td><td>';
				m += linestyle+addCommas(reqlevel)+' / '+addCommas(ilvl)+'</b></span></td></tr>';
			}
		}
		m += '</table>';

		var perSlot = parseIntNan(ById('btTrnNumPerSlot').value);
		if (perSlot!=0) {
			var time = t.getTrainTime(cityId,unitId,perSlot);
			if (ById('btTrnGamble').value > 0) {
				var timemin = time * t.gamble[ById('btTrnGamble').value].factor1;
				var timemax = time * t.gamble[ById('btTrnGamble').value].factor2;
				m += '<br>'+tx('Estimated Time')+':&nbsp;'+timestr(timemin)+' - '+timestr(timemax);
			}
			else {
				m += '<br>'+tx('Estimated Time')+':&nbsp;'+timestr(time);
			}
		}

		ById('btTrnRequirements').innerHTML = m;
	},

	cancelAll: function (cityId) {
		var t = Tabs.Train;

		jQuery('#btTrnCancelAllButton').addClass("disabled");
		var delayer = 0;
		var q = Seed.queue_unt['city' + cityId];
		for (var i = q.length-1; i >= 0; i--) {
			delayer = delayer + 1;
			setTimeout (t.cancelTrain,(1000*delayer),q[i][0],q[i][1],q[i][2],q[i][3],q[i][5],cityId,i); // spread them out ...
		}
		delayer = delayer + 1;
		setTimeout (function () { jQuery('#btTrnCancelAllButton').removeClass("disabled"); },(1000*delayer));
	},

	cancelTrain: function (typetrn, numtrptrn, trnTmp, trnETA, trnNeeded, cityId, trainingId) {
		var t = Tabs.Train;
		t.serverwait = true;
		ById('btTrnQueueMessage').innerHTML = 'Cancelling Queued Item...';
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pf = 0;
		params.requestType = "CANCEL_TRAINING";
		params.cityId = cityId;
		params.typetrn = typetrn;
		params.numtrptrn = numtrptrn;
		params.trnETA = trnETA;
		params.trnTmp = trnTmp;
		params.trnNeeded = trnNeeded;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/cancelTraining.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var isPrestigeQueue = Seed.queue_unt["city" + cityId][trainingId][7];
					var k = 0;
					for (var j = 0; j < Seed.queue_unt["city" + cityId].length; j++) {
						if (j > trainingId && (Seed.queue_unt["city" + cityId][j][7] === isPrestigeQueue)) {
							Seed.queue_unt["city" + cityId][j][2] = parseInt(rslt.dateTraining[k]["start"]);
							Seed.queue_unt["city" + cityId][j][3] = parseInt(rslt.dateTraining[k]["end"]);
							k++;
						}
					}
					Seed.queue_unt["city" + cityId].splice(trainingId, 1);
					for (var i = 1; i < 5; i++) {
						var totalReturn = parseInt(uW.unitcost["unt" + typetrn][i]) * parseInt(numtrptrn) * 3600 / 2;
						Seed.resources["city" + cityId]["rec" + i][0] = parseInt(Seed.resources["city" + cityId]["rec" + i][0]) + totalReturn;
					}
					t.PaintCityInfo();
				}
				else {
					if (rslt.msg) { ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00">'+rslt.msg+'</span>'; }
					else { ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00">Error cancelling training queue item</span>'; }
				}
				t.serverwait = false;
			},
			onFailure: function () {
				ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00;">AJAX Error!</span>';
				t.serverwait = false;
			},
		},true);
	},

	getTrainTime : function (cityId,unitId,num) {
		return getTrainTime(unitId,num,cityId);
	},

	Train : function (cityId, tut, gamble, unitId, num, notify) {
		var t = Tabs.Train;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btTrnCity_'+citynum).css('color', 'green');
		var time = t.getTrainTime(cityId,unitId, num);

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.type = unitId;
		params.quant = num;
		params.items = tut;
		params.gambleId = gamble;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/train.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					actionLog(Cities.byID[cityId].name+': Training '+num+' '+uW.unitcost['unt'+unitId][0],'TRAINING');
					var Prestige = (!uW.cm.BarracksUnitsTypeMap.isUnitType(unitId, "normal"));
					var MORE_WITH_LESS_FACTOR = uW.cm.BlessingSystemModel.applyBlessing(uW.cm.BlessingSystemModel.getBlessing().MORE_WITH_LESS, cityId, { unitid : unitId });
					var resourceFactors = [];
					var resourceLost;
					time = rslt.timeNeeded;
					for (var i = 1; i < 5; i++) {
						if (rslt.gamble) {
							resourceFactors.push(rslt.gamble[i.toString()])
						} else {
							resourceFactors.push(1)
						}
						resourceLost = Math.ceil(parseInt(uW.unitcost["unt" + unitId][i]) * MORE_WITH_LESS_FACTOR) * 3600 * parseInt(num);
						resourceLost = resourceLost * resourceFactors[i - 1];
						Seed.resources["city" + cityId]["rec" + i][0] = parseInt(Seed.resources["city" + cityId]["rec" + i][0]) - resourceLost;
					}
					jQuery.each(uW.unitcost["unt" + unitId][11], function (itemId, itemQuantity) {
						uW.ksoItems[+itemId].subtract(+itemQuantity * num);
						uW.seed.items['i'+itemId] = parseInt(uW.seed.items['i'+itemId])-(itemQuantity*num);
					});

					Seed.citystats["city" + cityId].gold[0] = parseInt(Seed.citystats["city" + cityId].gold[0]) - parseInt(uW.unitcost["unt" + unitId][5]) * parseInt(num);
					Seed.citystats["city" + cityId].pop[0] = Seed.citystats["city" + cityId].pop[0] - Math.ceil(parseInt(uW.unitcost["unt" + unitId][6]) * MORE_WITH_LESS_FACTOR) * parseInt(num);
					Seed.queue_unt["city" + cityId].push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + rslt.timeNeeded, 0, rslt.timeNeeded, null,Prestige]);
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Failed to train '+num+' '+uW.unitcost['unt'+unitId][0]+' ('+rslt.msg+')','TRAINING');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Failed to train '+num+' '+uW.unitcost['unt'+unitId][0]+' ('+rslt.error_code+')','TRAINING');
					}
				}
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				if (notify) { notify(rslt); }
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Failed to train '+num+' '+uW.unitcost['unt'+unitId][0]+' (Ajax Error)','TRAINING');
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				if (notify) { notify({msg: 'AJAX error'}); }
			},
		},true); // noretry
	},

	Dismiss : function (cityId,unitId,num) {
		var t = Tabs.Train;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btTrnCity_'+citynum).css('color', 'red');

		var cur_idle_pop = (parseInt(Seed.citystats['city'+cityId].pop[0])).toFixed(0); // manually keep track of pop, because the server can't seem to do it

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.type = unitId;
		params.quant = num;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/dismissUnits.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function(rslt) {
				if (rslt.ok) {
					actionLog(Cities.byID[cityId].name+': Dismissed '+addCommas(num)+' '+uW.unitcost['unt'+unitId][0],'TRAINING');
					Seed.units['city'+cityId]['unt'+unitId] -= num;
					Seed.citystats['city'+cityId].pop[0] = parseIntNan(cur_idle_pop+num); // manually add pop because server doesn't always return pop correctly
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Failed to dismiss '+num+' '+uW.unitcost['unt'+unitId][0]+' ('+rslt.msg+')','TRAINING');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Failed to dismiss '+num+' '+uW.unitcost['unt'+unitId][0]+' ('+rslt.error_code+')','TRAINING');
					}
				}
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
            },
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Failed to dismiss '+num+' '+uW.unitcost['unt'+unitId][0]+' (Ajax Error)','TRAINING');
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
         },true);
	},

	Fertilize : function (cityId) {
		var t = Tabs.Train;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btTrnCity_'+citynum).css('color', 'magenta');

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/fertilizePeople.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					actionLog(Cities.byID[cityId].name+': Fertile Winds used','TRAINING');
					Seed.items.i351 = (parseInt(Seed.items.i351) - 1).toString();
					t.PaintOverview();
					t.PaintCityInfo();
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Failed to use Fertile Winds ('+rslt.msg+')','TRAINING');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Failed to use Fertile Winds ('+rslt.error_code+')','TRAINING');
					}
				}
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Failed to use Fertile Winds (Ajax Error)','TRAINING');
				jQuery('#btTrnCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			}
		},true);
	},

	speedupTraining: function (cityId, unitId, itemId, trainingId, auto) {
		var t = Tabs.Train;
		t.serverwait = true;
		if (!auto && ById('btTrnQueueMessage')) ById('btTrnQueueMessage').innerHTML = 'Speeding up Training...';
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.iid = itemId;
		params.uid = unitId;
		params.apothecary = false;
		new AjaxRequest(uW.g_ajaxpath + "ajax/speedupTraining.php" + uW.g_ajaxsuffix, { // don't use MyAjaxRequest here, for some reason it fails
			method: "post",
			parameters: params,
			onSuccess: function (transport) {
				var rslt = eval("(" + transport.responseText + ")");
				if (rslt.ok) {
					Seed.queue_unt["city" + cityId][trainingId][2] = parseInt(rslt.dateTrainingStart);
					Seed.queue_unt["city" + cityId][trainingId][3] = parseInt(rslt.dateTraining);
					Seed.items["i" + itemId] = parseInt(Seed.items["i" + itemId]) - 1;
					uW.ksoItems[itemId].subtract();
					if (rslt.updateCityUnits) {
						var a = rslt.updateCityUnits;
						var g = Object.keys(a);
						for (var c = 0; c < g.length; c++) {
							var f = Object.keys(a[g[c]]);
							var e = g[c].split("c")[1];
							for (var b = 0; b < f.length; b++) {
								var d = f[b].split("u")[1];
								Seed.units["city" + e]["unt" + d] = parseInt(a[g[c]][f[b]])
							}
						}
					}
					if (!auto) t.PaintCityInfo();
				}
				else {
					if (rslt.msg) {
						if (!auto && ById('btTrnQueueMessage')) { ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00">'+rslt.msg+'</span>'; }
						else { actionLog(Cities.byID[cityId].name+": "+rslt.msg,'TRAINING'); }
					}
					else {
						if (!auto && ById('btTrnQueueMessage')) { ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00">Error speeding up training</span>'; }
						else { actionLog(Cities.byID[cityId].name+": Error speeding up training",'TRAINING'); }
					}
				}
				t.serverwait = false;
			},
			onFailure: function () {
				if (!auto && ById('btTrnQueueMessage')) { ById('btTrnQueueMessage').innerHTML = '<span style="color:#f00;">AJAX Error!</span>'; }
				else { actionLog(Cities.byID[cityId].name+": AJAX Error!",'TRAINING'); }
				t.serverwait = false;
			},
		},true);
	},

}

/**************************** Crafting Tab ****************************************/
Tabs.Craft = {
	tabLabel: 'Craft',
	tabOrder: 2020,
	tabColor : 'brown',
	myDiv: null,
	timer: null,
	LoopCounter: 0,
	citydelay: {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
	intervalSecs : 5,
	autodelay : 0,
	loopaction : false,
	craftinfo : {},
	spires : [],
	craftingspeed : 0,
	totaether : 0,
	Squire:0,
	Knight:0,
	Guinevere:0,
	Morgana:0,
	Arthur:0,
	ItemList : [1, 2, 3, 4, 5],
	ItemTrans : ["SH","KH","GH","MH","AH"],
	tableau : [],
	EliteRecipes : ['154','156','158','160','162','164','166','168','170','172','174'],
	TrainingRecipes : ['153','155','157','159','161','163','165','167','169','171','173'],
	Options: {
		Running: false,
		ThroneCheck: false,
		BasicCheck: false,
		CraftingSpeed: 0,
		MinAether : 5000,
		Enabled :			{1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
		Preferred :			{1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
		RecipeNumbers :		{},
		RecipeFixed : 		{},
		RecipeStats :		{},
		UseAH : false,
		UseMH : false,
		UseGH : false,
		UseKH : false,
		UseSH : false,
		UseOverride : false,
		OverrideItem : 0,
		OverrideHours : 0,
		OverrideMinutes : 1,
		Toggle : false,
	},

	init: function (div) {
		var t = Tabs.Craft;
        t.myDiv = div;

		if (!Options.CraftOptions) {
			Options.CraftOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.CraftOptions.hasOwnProperty(y)) {
					Options.CraftOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('speedupCraft', Tabs.Craft.speedupCraft);

		if (Options.CraftOptions.Toggle) AddSubTabLink('AutoCraft',t.toggleAutoCraftState, 'CraftToggleTab');
		SetToggleButtonState('Craft',Options.CraftOptions.Running,'Craft');

		for(var i=0; i < uW.recipelist[1].length; i++){
			if (parseIntNan(uW.recipelist[1][i].craftable)==1) {
				var h = parseInt(uW.recipelist[1][i].recipe_id);
				t.craftinfo[h] = {};
				t.craftinfo[h].recipe_id = uW.recipelist[1][i].recipe_id;
				t.craftinfo[h].name = uW.recipelist[1][i].name;
				t.craftinfo[h].category = uW.recipelist[1][i].category;
				t.craftinfo[h].input = uW.recipelist[1][i].input;
				t.craftinfo[h].requirements = uW.recipelist[1][i].requirements;
				t.craftinfo[h].inputItems = uW.recipelist[1][i].input.items;
				t.craftinfo[h].resources = uW.recipelist[1][i].input.resources;
				t.craftinfo[h].odds = uW.recipelist[1][i].failure_chance;
				t.craftinfo[h].dailylimit = uW.recipelist[1][i].daily_limit;
				t.craftinfo[h].lifetimelimit = uW.recipelist[1][i].life_time_limit;
				t.craftinfo[h].output_item_id = uW.recipelist[1][i].output_item_id;
			};
		}
		for(var i=0; i < uW.recipelist[3].length; i++){
			if (parseIntNan(uW.recipelist[3][i].craftable)==1) {
				var h = parseInt(uW.recipelist[3][i].recipe_id);
				t.craftinfo[h] = {};
				t.craftinfo[h].recipe_id = uW.recipelist[3][i].recipe_id;
				t.craftinfo[h].name = uW.recipelist[3][i].name;
				t.craftinfo[h].category = uW.recipelist[3][i].category;
				t.craftinfo[h].input = uW.recipelist[3][i].input;
				t.craftinfo[h].requirements = uW.recipelist[3][i].requirements;
				t.craftinfo[h].inputItems = uW.recipelist[3][i].input.items;
				t.craftinfo[h].resources = uW.recipelist[3][i].input.resources;
				t.craftinfo[h].odds = uW.recipelist[3][i].failure_chance;
				t.craftinfo[h].dailylimit = uW.recipelist[3][i].daily_limit;
				t.craftinfo[h].lifetimelimit = uW.recipelist[3][i].life_time_limit;
				t.craftinfo[h].output_item_id = uW.recipelist[3][i].output_item_id;
			};
		}

		for (var h in t.craftinfo) { // fix resources array for pre-HQ (remove this later)
			if (t.craftinfo[h].resources[5]==null) {
				t.craftinfo[h].resources[5] = t.craftinfo[h].resources[1];
				t.craftinfo[h].resources[1] = 0;
				t.craftinfo[h].resources[2] = 0;
				t.craftinfo[h].resources[3] = 0;
				t.craftinfo[h].resources[4] = 0;
				t.craftinfo[h].resources[6] = 0;
			}
		}

		for(i=0; i<Cities.numCities; i++) {
			t.spires.push(getUniqueCityBuilding(Cities.cities[i].id,20));
		}

		var m = '<DIV class=divHeader align=center>'+tx('CRAFTING ADMINISTRATION')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btCraftToggle type=checkbox />&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoCraftState type=submit value="'+tx("AutoCraft")+' = '+ (Options.CraftOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>'+tx('Current Crafting Speed')+':&nbsp;<span id=btCraftCurrTR></span>&nbsp;&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td colspan=2 align=left><INPUT id=btCraftTR type=checkbox /> '+tx('Only craft when crafting speed is at least')+' <INPUT id=btCraftTRSpeed type=text size=3 maxlength=4 >&nbsp;%</td>';
		m += '<td colspan=2 align=right>'+tx('Minimum Aetherstone')+':&nbsp;<input type=text size=5 maxlength=7 id=btCraftMinAether>&nbsp;&nbsp;</td></tr>';
		m += '<tr><td colspan=2 align=left><INPUT id=btCraftBasic type=checkbox /> '+tx('Ignore above setting for basic crafts (e.g. bloodstones)')+'</td></tr></table>';

		m += '<br><DIV id=btCraftOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';

		m += '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td width=100>&nbsp;</td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btCraftCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}
		m += "<td>&nbsp;</td>"; // spacer
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Active')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btCraftAutoCity_'+i+'" type=checkbox '+(Options.CraftOptions.Enabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right><b>'+tx('Preferred Recipe')+'&nbsp;</b></td>';

		var recipes = {0:'-- '+tx('Random')+' --'};
		for (var h in t.craftinfo) {
			var o = t.craftinfo[h].output_item_id;
			recipes[h] = uW.itemlist["i"+o].name;
			if (h==179) recipes[h] = recipes[h]+' ('+tx('Lower')+')';
			if (h==180) recipes[h] = recipes[h]+' ('+tx('Higher')+')';
			if (o==30800) recipes[h] = recipes[h]+' ('+t.craftinfo[h].name+')';
			if (t.EliteRecipes.indexOf(h)!=-1) recipes[h] = recipes[h]+' ('+tx('Elite')+')';
			if (t.TrainingRecipes.indexOf(h)!=-1) recipes[h] = recipes[h]+' ('+tx('Train')+')';
		}

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<td align=center>'+htmlSelector(recipes,Options.CraftOptions.Preferred[i],'class='+i+' id=btCraftPrefCity_'+i+' style="width:100px;font-size:9px;"')+'</td>';
		}

		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+tx('Activity')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:60px;"><span id="btCraftSpireCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr><TR align=right class="evenRow"><TD style="padding-left: 0px;"><img height=18 src="'+AetherImage+'" title="'+uW.g_js_strings.commonstr.aetherstone+'"></td><td><div id=btTotAether class="totalCell xtabBorder">&nbsp;</div></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder><span id="btCraftAetherCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr></table></div></div>';

		m += '<div class="divHeader" align="center">'+tx('USE AUTO-SPEEDUPS')+'</div>';

		m += '<table width=100% class=xtab><tr><td><div align=center>';

		var Boosts = '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'\n'+tx(HourGlassHint[t.ItemList[i]-1])+'" /></td><td>(<span id=pbcraftUse'+t.ItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '<td width=70 rowspan=2 align=right><INPUT id=pbCraftHelp type=submit value="'+tx('HELP')+'!"></td>';
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbcraft'+t.ItemTrans[i]+'" '+(Options.CraftOptions["Use"+t.ItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr></table></td></tr>';
        Boosts += '<tr><td><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td><input type=checkbox id=pbcraftOV >'+tx('Override above by always using')+' '+htmlSelector(HourGlassName,Options.CraftOptions.OverrideItem, 'id=pbcraftOVItem') + ' '+tx('when more than')+' ';
		Boosts += '<INPUT style="width: 30px;text-align:right;" id="pbcraftOVHours" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT style="width: 30px;text-align:right;" id="pbcraftOVMinutes" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timemin+' '+tx('remaining')+'.</td></tr></table></div></td></tr>';

		m += Boosts+'</table></div><br>';

		m += '<div class="divHeader" align="center">'+tx('RECIPE LIST')+'</div>';
		m += '<DIV id=btCraftRecipeDiv style="max-height:700px;overflow-y:auto;width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';
		m += '<TABLE id=btRecipeList cellpadding=1 cellspacing=0 width=98% class=xtab align=center><TR>';
		m += '<th class=xtabHD>&nbsp;</th><th class=xtabHD>'+uW.g_js_strings.commonstr.item+'</th><th class=xtabHD>'+uW.g_js_strings.commonstr.inventory+'</th><th class=xtabHD>'+uW.g_js_strings.commonstr.amount+'</th><th class=xtabHD>'+tx('Lock')+'</th><th class=xtabHD>'+tx('Success')+'</th>';
		m += '<th class=xtabHD>&nbsp;</th><th class=xtabHD>'+uW.g_js_strings.commonstr.item+'</th><th class=xtabHD>'+uW.g_js_strings.commonstr.inventory+'</th><th class=xtabHD>'+uW.g_js_strings.commonstr.amount+'</th><th class=xtabHD>'+tx('Lock')+'</th><th class=xtabHD>'+tx('Success')+'</th>';
		m += '</tr><tr class=oddRow>';

		var r = 1;
		var count = 0;
		for (var h in t.craftinfo) {
			var o = t.craftinfo[h].output_item_id;
			var itemname = uW.itemlist['i'+o].name;
			if (h==179) itemname = itemname+' ('+tx('Lower')+')';
			if (h==180) itemname = itemname+' ('+tx('Higher')+')';
			if (o==30800) itemname = itemname+' ('+t.craftinfo[h].name+')';
			if (t.EliteRecipes.indexOf(h)!=-1) itemname = itemname+' ('+tx('Elite')+')';
			if (t.TrainingRecipes.indexOf(h)!=-1) itemname = itemname+' ('+tx('Train')+')';
			m += '<td align=center><img src="'+getItemImageURL(o)+'" width=25></td><td align=center class=tooldesc id=btCraftDesc_'+h+' >'+itemname+'</td><td align=center><span id=btCraftInv_'+h+' >&nbsp;</span></td>';
			m += '<td><input type=text class='+h+' size=4 id=btCraftNum_'+h+' value="'+(Options.CraftOptions.RecipeNumbers[h]?Options.CraftOptions.RecipeNumbers[h]:'')+'"></td><td><INPUT id=btCraftFixed_'+h+' class='+h+' type=checkbox '+(Options.CraftOptions.RecipeFixed[h]?'CHECKED':'')+'></td><td id=btCraftStats_'+h+'>&nbsp;</td>';
			if ((count+1)%2 == 0) {
				r++;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';
				m += '</tr><tr class="'+rowClass+'">';
			}
			count++;
		}

		m += '</div><br>'
		div.innerHTML = m;

		for (var i = 1; i <= Cities.numCities; i++) {
			ById('btCraftAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.CraftOptions.Enabled[citynum] = e.target.checked;
				if (Options.CraftOptions.Enabled[citynum]) {
					t.citydelay[i] = 0;
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
			ById('btCraftPrefCity_'+i).addEventListener('change', function(e){
				Options.CraftOptions.Preferred[e.target['className']] = e.target.value;
				saveOptions();
			}, false);
		}

		ToggleOption('CraftOptions','btCraftToggle','Toggle');

		ToggleOption('CraftOptions','pbcraftSH','UseSH');
		ToggleOption('CraftOptions','pbcraftKH','UseKH');
		ToggleOption('CraftOptions','pbcraftGH','UseGH');
		ToggleOption('CraftOptions','pbcraftMH','UseMH');
		ToggleOption('CraftOptions','pbcraftAH','UseAH');

		ToggleOption('CraftOptions','pbcraftOV','UseOverride');
		ChangeIntegerOption('CraftOptions','pbcraftOVItem','OverrideItem');
		ChangeIntegerOption('CraftOptions','pbcraftOVHours','OverrideHours');
		ChangeIntegerOption('CraftOptions','pbcraftOVMinutes','OverrideMinutes');

		ById ('pbCraftHelp').addEventListener ('click', t.helpPop, false);

		ById('btAutoCraftState').addEventListener('click', function(){
			t.toggleAutoCraftState(this);
		}, false);

		ToggleOption('CraftOptions','btCraftTR','ThroneCheck');
		ToggleOption('CraftOptions','btCraftBasic','BasicCheck');
		ChangeIntegerOption('CraftOptions','btCraftTRSpeed','CraftingSpeed');
		ChangeIntegerOption('CraftOptions','btCraftMinAether','MinAether');

		for (var h in t.craftinfo) {
			ById('btCraftNum_'+h).addEventListener('change', function(e){
				var craftnum = e.target['className'];
				if (isNaN(e.target.value)) e.target.value = '';
				Options.CraftOptions.RecipeNumbers[craftnum] = e.target.value;
				saveOptions();
			}, false);
			ById('btCraftFixed_'+h).addEventListener('change', function(e){
				var craftnum = e.target['className'];
				Options.CraftOptions.RecipeFixed[craftnum] = e.target.checked;
				saveOptions();
			}, false);
		}

		// start autocraft loop timer to start in 20 seconds...

		if (Options.CraftOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, (20 * 1000));
		}
	},

	toggleAutoCraftState: function(obj){
		var t = Tabs.Craft;
		obj = ById('btAutoCraftState');
		if (Options.CraftOptions.Running == true) {
			Options.CraftOptions.Running = false;
			obj.value = tx("AutoCraft = OFF");
		}
		else {
			Options.CraftOptions.Running = true;
			obj.value = tx("AutoCraft = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Craft',Options.CraftOptions.Running,'Craft');
		t.citydelay = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0};
		t.PaintOverview();
	},

	show: function (init) {
		var t = Tabs.Craft;

		t.PaintOverview();
		t.PaintRecipeList();
	},

	createToolTip : function (elem) {
		var t = Tabs.Craft;
		var h = elem.id.substring(12);
		var recipeId = t.craftinfo[h].recipe_id;
		var name = t.craftinfo[h].name;
		var category = t.craftinfo[h].category;
		var input = t.craftinfo[h].input;
		var requirements = t.craftinfo[h].requirements.building;
		var inputitems = t.craftinfo[h].inputItems;
		var astone = t.craftinfo[h].resources[5];
		var food = t.craftinfo[h].resources[1];
		var wood = t.craftinfo[h].resources[2];
		var stone = t.craftinfo[h].resources[3];
		var ore = t.craftinfo[h].resources[4];
		var gold = t.craftinfo[h].resources[6];
		var odds = t.craftinfo[h].odds;

		var ingredients = '';
   	 	for (var i in inputitems) {
      	 	if (i>0) {
				span = '<span>';
				if (parseIntNan(Seed.items['i'+i]) < inputitems[i]) span = '<span style="color:#f00">';
				ingredients += span + uW.itemlist['i'+i].name +' : '+inputitems[i]+'</span><br>';
			}
		}
		if (food!=0) { ingredients += '<span>' + uW.g_js_strings.commonstr.food +' : '+addCommas(food)+'</span><br>'; }
		if (wood!=0) { ingredients += '<span>' + uW.g_js_strings.commonstr.wood +' : '+addCommas(wood)+'</span><br>'; }
		if (stone!=0) { ingredients += '<span>' + uW.g_js_strings.commonstr.stone +' : '+addCommas(stone)+'</span><br>'; }
		if (ore!=0) { ingredients += '<span>' + uW.g_js_strings.commonstr.ore +' : '+addCommas(ore)+'</span><br>'; }
		if (gold!=0) { ingredients += '<span>' + uW.g_js_strings.commonstr.gold +' : '+addCommas(gold)+'</span><br>'; }

		if (ingredients != '') ingredients = '<b>'+tx('Ingredients')+'</b><br>' + ingredients;
		var limits = '';
		if (parseIntNan(t.craftinfo[h].dailylimit) != 0) {
			span = '<span>';
			if (uW.recipeUsageList[category] && uW.recipeUsageList[category][recipeId]) {
				if (parseIntNan(uW.recipeUsageList[category][recipeId].dailyUsage)>=parseIntNan(t.craftinfo[h].dailylimit)) span = '<span style="color:#f00">';
			}
			limits += span + '<b>'+tx('Daily Limit')+' : '+parseIntNan(t.craftinfo[h].dailylimit)+'</b></span><br>';
		}
		if (parseIntNan(t.craftinfo[h].lifetimelimit) != 0) {
			span = '<span>';
			if (uW.recipeUsageList[category] && uW.recipeUsageList[category][recipeId]) {
				if (parseIntNan(uW.recipeUsageList[category][recipeId].lifeTimeUsage)>=parseIntNan(t.craftinfo[h].lifetimelimit)) span = '<span style="color:#f00">';
			}
			limits += span + '<b>'+tx('Lifetime Limit')+' : '+parseIntNan(t.craftinfo[h].lifetimelimit)+'</b></span><br>';
		}

		jQuery('#'+elem.id).children("span").remove();
		jQuery('#'+elem.id).append('<span class="tooltip"><b>'+tx('Recipe Name')+'</b><br>' +name+' ('+odds+')<br><b>'+uW.g_js_strings.commonstr.requirements+'</b><br>Spire Lv.'+requirements+'<br>'+uW.g_js_strings.commonstr.aetherstone+' : '+addCommas(astone)+'<br>'+ingredients+'<br>'+limits+'</span>');
	},

	helpPop : function (){
		var t = Tabs.Craft;
		var helpText = '<br>'+tx("Using Speedups for Crafting");
		helpText += '<p>'+tx('Speedups will be used in the following order if they are selected, and the required criteria is met')+' :-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+uW.g_js_strings.commonstr.item+'</b></td><TD><b>'+uW.g_js_strings.commonstr.time+'</b></td><TD><b>'+tx('Criteria')+'</b></td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i5.name+'</td><TD>8 hrs</td><TD>'+tx('More than 7 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i4.name+'</td><TD>2.5 hrs</td><TD>'+tx('More than 2 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i3.name+'</td><TD>1 hr</td><TD>'+tx('More than 45 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i2.name+'</td><TD>15 mins</td><TD>'+tx('More than 5 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i1.name+'</td><TD>1 min</td><TD>'+tx('More than 30 seconds remaining')+'</td></tr>';
		helpText += '</table>';
		helpText += '<p>'+tx('If the override box is ticked, then the override rule specified will take priority')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 280, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Speedups")+'</b></center>';
		pop.show (true);
	},

	EverySecond : function () {
		var t = Tabs.Craft;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh crafting speed and overview display every 2 seconds
			t.craftingspeed = Math.floor(equippedthronestats(81));
			if (tabManager.currentTab.name == 'Craft' && Options.btWinIsOpen){ t.PaintOverview(); }
		}

		if (t.LoopCounter >= 5) { // refresh recipe and spires display every 5 seconds
			t.LoopCounter = 0;
			for(i=0; i<Cities.numCities; i++) {	t.spires[i] = getUniqueCityBuilding(Cities.cities[i].id,20); }	// always check spires for auto loop
			if (tabManager.currentTab.name == 'Craft' && Options.btWinIsOpen){ t.PaintRecipeList(); }
		}
	},

	PaintOverview : function () {
		var t = Tabs.Craft;

		t.Squire = parseIntNan(Seed.items.i1);
		t.Knight = parseIntNan(Seed.items.i2);
		t.Guinevere = parseIntNan(Seed.items.i3);
		t.Morgana = parseIntNan(Seed.items.i4);
		t.Arthur = parseIntNan(Seed.items.i5);

		ById('pbcraftUseSHLabel').innerHTML = t.Squire;
		ById('pbcraftUseKHLabel').innerHTML = t.Knight;
		ById('pbcraftUseGHLabel').innerHTML = t.Guinevere;
		ById('pbcraftUseMHLabel').innerHTML = t.Morgana;
		ById('pbcraftUseAHLabel').innerHTML = t.Arthur;

		t.totaether=0;
		var now = unixTime();
		var q;

		for (var i = 0; i < Cities.numCities; i++) {
			citynum = i+1;
			cityId = Cities.cities[i].id;
			var cityaether = parseIntNan(Seed.resources["city"+cityId]['rec5'][0]);
			t.totaether = t.totaether+cityaether;
			var span = '<span>';
			if (cityaether < Options.CraftOptions.MinAether) { span = '<span class=boldRed>'; }
			ById("btCraftAetherCity_"+citynum).innerHTML = span+addCommas(cityaether)+'</span>';

			var str = '';
			var SpireLevel = t.spires[i].maxLevel;
			if (SpireLevel > 0) {
				str = '<span>'+uW.g_js_strings.prestige.spire+' ('+uW.g_js_strings.commonstr.level+' '+SpireLevel+')</span><BR>';
				var totTime = 0;
				// the last item in the queue should be the item in progress
				var len = Seed.queue_craft["city" + Cities.cities[i].id].length;
				if ( len > 0) {
					q = Seed.queue_craft["city" + Cities.cities[i].id][len-1];
					totTime = q.craftingEtaUnixTime - now;
					if (totTime < 0) totTime = 0;
				}
				if (totTime > 0) {
					var Speedups = '';
					Speedups += t.paintSpeedup(Cities.cities[i].id,q.craftingId,1,t.Squire,'1 min');
					Speedups += t.paintSpeedup(Cities.cities[i].id,q.craftingId,2,t.Knight,'15 mins');
					Speedups += t.paintSpeedup(Cities.cities[i].id,q.craftingId,3,t.Guinevere,'60 mins');
					Speedups += t.paintSpeedup(Cities.cities[i].id,q.craftingId,4,t.Morgana,'150 mins');
					Speedups += t.paintSpeedup(Cities.cities[i].id,q.craftingId,5,t.Arthur,'8 hours');
					if (Speedups != "") Speedups = "<table align=center cellspacing=0 cellpadding=0><tr>" + Speedups + "</tr></table>";

					str += '<span>'+t.getRecipeName(q.recipeId)+'</span><BR><span>'+timestr(totTime)+'</span>'+Speedups;
				}
				else {
					if (t.citydelay[citynum] > 0) { str += '<span>&nbsp;</span><BR><SPAN class=boldRed><B>'+tx('Busy')+'!</b></span>'; }
					else {
						if (Options.BuildOptions && Options.BuildOptions.AscensionReady[citynum]) { str += '<span>&nbsp;</span><BR><SPAN>'+tx('Ascension')+'!</span>'; }
						else { str += '<span>&nbsp;</span><BR><SPAN class=boldRed><B>'+tx('Idle')+'</b></span>'; }
					}
				}
			}
			else {
				str = '<SPAN class=boldRed><B>'+tx('No Spire')+'</b></span><br>';
			}
			ById("btCraftSpireCity_"+citynum).innerHTML = str;
		}
		ById('btTotAether').innerHTML = addCommas(t.totaether);

		if (Options.CraftOptions.ThroneCheck && (t.craftingspeed < Number(Options.CraftOptions.CraftingSpeed))) {
			ts = '<span class=boldRed><b>'+t.craftingspeed+'%</b></span>';
		}
		else { ts = t.craftingspeed+'%'; }
		ById("btCraftCurrTR").innerHTML = ts;
	},

	paintSpeedup : function (cityId, qitem, item, count, hint) {
		var t = Tabs.Craft;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px"><a onClick="speedupCraft('+cityId+', '+item+', '+qitem+')"><img height=18 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+hint+') ('+count+')"></a></td>';
		}
		return n;
	},

	PaintRecipeList : function () {
		var t = Tabs.Craft;
		for(var h in t.craftinfo) {
			var o = t.craftinfo[h].output_item_id;
			var craftingstr = "";
			var crafting = t.checkCraftQueues(h);
			if (crafting != 0) craftingstr = " ("+crafting+")";
			ById('btCraftStats_'+h).innerHTML=t.getCraftPercent(Options.CraftOptions.RecipeStats[h]);
			var invamount = parseIntNan(Seed.items["i"+o]);
			var span = '<span>'
			if (Options.CraftOptions.RecipeFixed[h] && parseIntNan(Options.CraftOptions.RecipeNumbers[h])>0 && parseIntNan(Options.CraftOptions.RecipeNumbers[h])<=invamount+crafting) {
				span = '<span class=boldGreen>';
			}
			ById('btCraftInv_'+h).innerHTML=span+invamount+craftingstr+'</span>';
		}

		var cItems = ById('btRecipeList').getElementsByClassName('tooldesc');
		for (var i = 0; i < cItems.length; i++) { t.createToolTip(cItems[i]); }
	},

	getCraftPercent : function (item) {
		var t = Tabs.Craft;
		if (item) {
			var succ = item[0];
			var tot = item[1];
			if (parseIntNan(tot) != 0) {
				return parseInt((parseIntNan(succ)/parseIntNan(tot))*10000)/100+'%';
			}
			else { return "&nbsp;"; }
		}
		else {return "&nbsp;"; }
	},

	checkCraftQueues : function (h) {
		var t = Tabs.Craft;
		var result = 0;
		for (var i=0;i<Seed.cities.length;i++) {
			var len = Seed.queue_craft["city" + Seed.cities[i][0]].length;
			if (len>0) {
				var q=Seed.queue_craft["city" + Seed.cities[i][0]][len-1];
				if (parseInt(q.recipeId) == parseInt(t.craftinfo[h].recipe_id)) {result++;}
			}
		}
		return result;
	},

	checkCraftQueuesByItem : function (o) {
		var t = Tabs.Craft;
		var result = 0;
		for (var i=0;i<Seed.cities.length;i++) {
			var len = Seed.queue_craft["city" + Seed.cities[i][0]].length;
			if (len>0) {
				var q=Seed.queue_craft["city" + Seed.cities[i][0]][len-1];
				if (t.craftinfo[q.recipeId] && parseInt(t.craftinfo[q.recipeId].output_item_id) == parseInt(o)) {result++;}
			}
		}
		return result;
	},

	getRecipeName : function(recipeId) {
		var t = Tabs.Craft;
		var name = "";
		for(var h in t.craftinfo) {
			if (parseInt(t.craftinfo[h].recipe_id) == parseInt(recipeId)) {
				name = t.craftinfo[h].name;
				break;
			}
		}
		if (name.length>16) { return name.substring(0,16)+'...'; }
		else { return name; }

	},

	doAutoLoop : function (idx) {
		var t = Tabs.Craft;
		clearTimeout(t.timer);
		if (!Options.CraftOptions.Running) return;

		var cityId = Cities.cities[idx-1].id;
		if (idx==1) { t.loopaction = false; } // reset loop action indicator for first city
		t.autodelay = 0; // no delay if no action taken!

		// first check if city is idle (or busy)

		var now = unixTime();
		var len = Seed.queue_craft["city" + cityId].length;
		if ((len==0 || (Seed.queue_craft["city" + cityId][len-1].craftingEtaUnixTime - now) < 0)) {
			if (!Options.CraftOptions.ThroneCheck || Options.CraftOptions.BasicCheck || (t.craftingspeed >= Options.CraftOptions.CraftingSpeed)) { // if no craft speed restriction or enough crafting speed or ignore speed for basic crafts
				var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[idx]);
				if (Options.CraftOptions.Enabled[idx] && ascensionok) {
					if (t.citydelay[idx] > 0) { t.citydelay[idx]--; } // city being delayed due to error, reduce delay number and skip city
					else {
						var SpireLevel = t.spires[idx-1].maxLevel;
						if (SpireLevel > 0) {
							if (parseIntNan(Seed.resources["city" + cityId]['rec5'][0])>=Options.CraftOptions.MinAether) {
								t.eventSelectRecipe(cityId,idx);
							}
						}
					}
				}
			}
		}
		else {
			if (len!=0) {
				t.autoSpeedup (cityId,Seed.queue_craft["city" + cityId][len-1]);
			}
		}

		if (idx == Cities.numCities) {
			if (!t.loopaction) { t.autodelay = t.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(1); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1); }, (t.autodelay * 1000));
		}
	},

	eventSelectRecipe : function (cityId,idx) {
		var t = Tabs.Craft;

		t.tableau = [];
		if (Options.CraftOptions.Preferred[idx] != 0) { // attempt to craft preferred recipe
			t.checkRequirements(Options.CraftOptions.Preferred[idx],cityId,idx);
		}

		if (t.tableau.length == 0) { // preferred not available
			for(var d in Options.CraftOptions.RecipeNumbers) {
				t.checkRequirements(d,cityId,idx);
			}
		}
		if (t.tableau.length == 0) return ; // nothing to craft

		// do craft!

		var h = t.tableau[Math.floor(Math.random()*t.tableau.length)];
		var itemId = t.craftinfo[h].output_item_id;
		var recipeId = t.craftinfo[h].recipe_id;
		var category = t.craftinfo[h].category;

		t.autodelay = t.intervalSecs;
		t.loopaction = true;
		t.Craft(idx, cityId, itemId, recipeId, category, h);
	},

	checkRequirements : function(d,cityId,idx) {
		var t = Tabs.Craft;
		if (t.craftinfo[d]) { // recipe may have been taken away!
			// first check daily/lifetime limits
			var recipeId = t.craftinfo[d].recipe_id;
			var category = t.craftinfo[d].category;
			var o = t.craftinfo[d].output_item_id;
			if (uW.recipeUsageList[category] && uW.recipeUsageList[category][recipeId]) {
				if (parseIntNan(t.craftinfo[d].dailylimit) != 0 && parseIntNan(uW.recipeUsageList[category][recipeId].dailyUsage)>=parseIntNan(t.craftinfo[d].dailylimit)) { return; }
				if (parseIntNan(t.craftinfo[d].lifetimelimit) != 0 && parseIntNan(uW.recipeUsageList[category][recipeId].lifeTimeUsage)>=parseIntNan(t.craftinfo[d].lifetimelimit)) { return; }
			}

			if ((!Options.CraftOptions.RecipeFixed[d] && (parseIntNan(Options.CraftOptions.RecipeNumbers[d])>0)) || (Options.CraftOptions.RecipeFixed[d] && (parseIntNan(Options.CraftOptions.RecipeNumbers[d])>parseIntNan(Seed.items["i"+o])+t.checkCraftQueuesByItem(o)))) {
				var ResourceOK = true;
				if (parseIntNan(t.craftinfo[d].resources[1]) > parseIntNan(Seed.resources["city" + cityId]['rec1'][0])) ResourceOK = false;
				if (parseIntNan(t.craftinfo[d].resources[2]) > parseIntNan(Seed.resources["city" + cityId]['rec2'][0])) ResourceOK = false;
				if (parseIntNan(t.craftinfo[d].resources[3]) > parseIntNan(Seed.resources["city" + cityId]['rec3'][0])) ResourceOK = false;
				if (parseIntNan(t.craftinfo[d].resources[4]) > parseIntNan(Seed.resources["city" + cityId]['rec4'][0])) ResourceOK = false;
				if (parseIntNan(t.craftinfo[d].resources[6]) > parseIntNan(Seed.citystats["city" + cityId]['gold'][0])) ResourceOK = false;
				if (ResourceOK && parseIntNan(Seed.resources["city" + cityId]['rec5'][0]) >= parseIntNan(t.craftinfo[d].resources[5])) {
					if (parseInt(t.craftinfo[d].requirements.building) <= parseInt(t.spires[idx-1].maxLevel)) {
						if (t.craftinfo[d].inputItems == "") { // "base items"
							t.tableau.push (d);
						}
						else {
							if (!Options.CraftOptions.ThroneCheck || (t.craftingspeed >= Options.CraftOptions.CraftingSpeed)) { // if no craft speed restriction or enough crafting speed
								for (var i in t.craftinfo[d].inputItems) {
									if (parseIntNan(Seed.items["i"+i]) < parseInt(t.craftinfo[d].inputItems[i])) { break; }
								}
								if (parseIntNan(Seed.items["i"+i]) >= parseInt(t.craftinfo[d].inputItems[i])) { t.tableau.push (d); }
							}
						}
					}
				}
			}
		}
	},

    autoSpeedup: function (cityId,q) {
		var t = Tabs.Craft;
		var now = unixTime();
		var item = 0;
		totTime = q.craftingEtaUnixTime - now;

		if (totTime > 0) {
			if (Options.CraftOptions.UseOverride && Options.CraftOptions.OverrideItem != 0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.CraftOptions.OverrideMinutes)*60)+(parseIntNan(Options.CraftOptions.OverrideHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && uW.ksoItems[Options.CraftOptions.OverrideItem].count > 0) { item = Options.CraftOptions.OverrideItem; }
			}
            if (item==0 && totTime >= HourGlassThreshold[4] && Options.CraftOptions.UseAH && uW.ksoItems[5].count > 0) { item = 5; }
            if (item==0 && totTime >= HourGlassThreshold[3] && Options.CraftOptions.UseMH && uW.ksoItems[4].count > 0) { item = 4; }
            if (item==0 && totTime >= HourGlassThreshold[2] && Options.CraftOptions.UseGH && uW.ksoItems[3].count > 0) { item = 3; }
            if (item==0 && totTime >= HourGlassThreshold[1] && Options.CraftOptions.UseKH && uW.ksoItems[2].count > 0) { item = 2; }
            if (item==0 && totTime >= HourGlassThreshold[0] && Options.CraftOptions.UseSH && uW.ksoItems[1].count > 0) { item = 1; }
        }

		if (item != 0) {
			t.autodelay = t.intervalSecs;
			t.speedupCraft(cityId,item,q.craftingId);
		}
    },

	Craft: function (citynum, cityId, itemId, recipeId, category, h) {
		var t = Tabs.Craft;
		jQuery('#btCraftCity_'+citynum).css('color', 'green');

		// set up success stats if first time crafted this item..
		if (!Options.CraftOptions.RecipeStats[h]) {
			Options.CraftOptions.RecipeStats[h] = [0,0];
			saveOptions();
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.action="craft";
		params.ctrl="Crafting";
		params.cityId=cityId;
		params.insurance=false;
		params.itemId=itemId;
		params.recipeId=recipeId;
		params.categoryId=category;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			loading: true,
			onSuccess: function (rslt) {
				if (rslt.ok===true) {
					if (rslt.status=="error") { // crafting error
						actionLog (Cities.byID[cityId].name+': Error ('+rslt.errorCode+') when attempting to craft '+uW.itemlist["i"+itemId].name,'CRAFTING');
						if (rslt.errorCode == 2) { // server busy? delay 2 loops
							t.citydelay[citynum] = 2;
						}
						if (rslt.errorCode == 6) { // city already crafting? delay 10 loops
							t.citydelay[citynum] = 10;
						}
					}
					else {
						if (rslt.status=="hitlimit") { //hit daily/lifetime limit
							actionLog (Cities.byID[cityId].name+': Crafting Limit reached for '+uW.itemlist["i"+itemId].name,'CRAFTING');
							uW.recipeUsageList[category][recipeId].dailyUsage = parseIntNan(t.craftinfo[h].dailylimit); // fix!
						}
						else {
							Seed.resources['city'+cityId].rec1[0]=parseInt(Seed.resources['city'+cityId].rec1[0] - parseIntNan(t.craftinfo[h].resources[1]));
							Seed.resources['city'+cityId].rec2[0]=parseInt(Seed.resources['city'+cityId].rec2[0] - parseIntNan(t.craftinfo[h].resources[2]));
							Seed.resources['city'+cityId].rec3[0]=parseInt(Seed.resources['city'+cityId].rec3[0] - parseIntNan(t.craftinfo[h].resources[3]));
							Seed.resources['city'+cityId].rec4[0]=parseInt(Seed.resources['city'+cityId].rec4[0] - parseIntNan(t.craftinfo[h].resources[4]));
							Seed.resources['city'+cityId].rec5[0]=parseInt(Seed.resources['city'+cityId].rec5[0] - parseIntNan(t.craftinfo[h].resources[5]));
							Seed.citystats['city'+cityId]['gold'][0]=parseInt(Seed.citystats['city'+cityId]['gold'][0] - parseIntNan(t.craftinfo[h].resources[6]));
							if (rslt.status=="failure") { //craft failed
								actionLog (Cities.byID[cityId].name+': Failed to craft '+uW.itemlist["i"+itemId].name,'CRAFTING');
								// increment total craft attempts
								Options.CraftOptions.RecipeStats[h][1] = Options.CraftOptions.RecipeStats[h][1] + 1;
								saveOptions();
								for (var k in t.craftinfo[h].inputItems) {
									if (t.craftinfo[h].inputItems[k] > 0) {
										if (k == t.craftinfo[h].consolation) { uW.cm.InventoryView.removeItemFromInventory(k,(t.craftinfo[h].inputItems[k]-1).toFixed(0)); }
										else { uW.cm.InventoryView.removeItemFromInventory(k,parseInt(t.craftinfo[h].inputItems[k])); }
									}
								}
							}
							else {
								if (rslt.status=="success") { // craft successful
									actionLog (Cities.byID[cityId].name+': Successfully crafting '+uW.itemlist["i"+itemId].name,'CRAFTING');
									// increment total craft attempts and successful craft attempts
									Options.CraftOptions.RecipeStats[h][1] = Options.CraftOptions.RecipeStats[h][1] + 1;
									Options.CraftOptions.RecipeStats[h][0] = Options.CraftOptions.RecipeStats[h][0] + 1;
									if (!Options.CraftOptions.RecipeFixed[h] && Options.CraftOptions.RecipeNumbers[h] > 0) {
										Options.CraftOptions.RecipeNumbers[h] = Options.CraftOptions.RecipeNumbers[h] -1;
										saveOptions();
										if (ById('btCraftNum_'+h)) { ById('btCraftNum_'+h).value = Options.CraftOptions.RecipeNumbers[h]; }
									}
									Seed.queue_craft["city"+cityId]= []; // Always reset the crafting queue for the city!! Can only ever be one craft in a city at a time. Now watch them change this! LOL
									if (rslt.time.duration==0) { // no duration, don't add to queue, just inventory!
										crafted = {};
										crafted[params.itemId] = 1;
										uW.update_inventory(crafted);
									}
									else {
										var n={};
										n.recipeId=recipeId;
										n.craftingUnixTime=rslt.time.startTime;
										n.craftingEtaUnixTime=rslt.time.endTime;
										n.craftingId=rslt.craftingId;
										n.categoryId=null;
										n.recipeIndex=null;
										uW.seed.queue_craft["city"+cityId].push(n);
									}
									for (var k in t.craftinfo[h].inputItems) {
										if (t.craftinfo[h].inputItems[k] > 0) {
											uW.cm.InventoryView.removeItemFromInventory(k,parseInt(t.craftinfo[h].inputItems[k]));
										}
									}
									if (typeof uW.recipeUsageList[category] !== "undefined" && typeof uW.recipeUsageList[category][recipeId] !== "undefined") {
										uW.recipeUsageList[category][recipeId].dailyUsage += 1;
										uW.recipeUsageList[category][recipeId].lifeTimeUsage += 1;
									}
									if (uW.currentcityid == cityId) { // If this item started crafting in the city the player has open, rebuild the building tab
										if (jQuery("#queue_head_building").hasClass("sel") ) { // if the building tab is selected, rebuild it
											uW.queue_changetab_building();
										}
									}
								}
							}
						}
					}
				}
				t.PaintOverview();
				jQuery('#btCraftCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				return;
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Crafting Failed (AJAX Error)','CRAFTING');
				jQuery('#btCraftCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			}
		},true);
	},

	speedupCraft : function (cityId,item,cid) {
		var t = Tabs.Craft;

		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btCraftCity_'+citynum).css('color', 'magenta');
		var params = uW.Object.clone(uW.g_ajaxparams);
  		params.ctrl = 'Crafting';
  		params.action = 'speedup';
  		params.cityId = cityId;
  		params.itemId = item;
  		params.craftingId = cid;

  		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
  			method: "post",
  			parameters: params,
  			onSuccess: function (rslt) {
				if (rslt.error_code || rslt.error_code == 0) { // no OK status on this call, but if there's an error_code assume speedup failed...
					actionLog(Cities.byID[cityId].name+': Crafting Speedup Failed ('+rslt.error_code+')','CRAFTING');
				}
				else {
					Seed.items["i"+item] = Number(parseInt(Seed.items["i"+item])-1);
					uW.ksoItems[item].subtract();
					var qloc = Seed.queue_craft["city" + cityId].length-1; // last queued item is the one in progress...
					var timered = 0;
					var utstart = parseInt(Seed.queue_craft["city" + cityId][qloc].craftingUnixTime);
					var uteta = parseInt(Seed.queue_craft["city" + cityId][qloc].craftingEtaUnixTime);
					timered = SpeedupArray[parseInt(item) - 1];
					Seed.queue_craft["city" + cityId][qloc].craftingUnixTime = utstart - timered;
					Seed.queue_craft["city" + cityId][qloc].craftingEtaUnixTime = uteta - timered;
					if (cityId == uW.currentcityid) uW.update_queue();
				}
				jQuery('#btCraftCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
  			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Crafting Speedup Failed (AJAX Error)','CRAFTING');
				jQuery('#btCraftCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			}
  		},true);
	},
}

/*********************************** Search Tab ***********************************/

Tabs.Search = {
	tabOrder: 1020,
	tabLabel: 'Search',
	myDiv: null,
	MapAjax : new CMapAjax(),
	MAX_SHOW_WHILE_RUNNING : 500,
	PANEL_HEIGHT : 500,
	FilterShow : true,
	BlockList : [],
	Blocks : [],
	SearchList : [],
	Rankings : [],
	mapDat : [],
	dat : [],
	KMData : [],
	OldMists : [],
	opt : {},
	ModelCity: null,
	ModelCityId: 0,
	searchRunning : false,
	blocksTotal : 0,
	blocksSearched : 0,
	tilesFound : 0,
	firstX : 0,
	firstY : 0,
	lastX : 0,
	lastY : 0,
	LastSearch : {},
	QSMarching : {},
	ReqSent : {},
	mists : 0,
	scouted : 0,

	Options: {
		SearchType		: 0, // 0 - city, 1 - barb camp, 2 - wild, 3 - dark forest, 4 - merc camp, 5 - nomad camp, 6 - alliance HQ - anything greater than 1, treat like wild!
		SearchShape		: 0, // 0 - square, 1 - circle
		MinLevel		: 1,
		MaxLevel		: 10,
		WildType		: 1, // 0 - bog, 1 - grassland/lake, 2 - forest, 3 - hill, 4 - mountain, 5 - plain, 99 - all
		Unowned			: true,
		Misted			: true,
		OldMists		: true,
		NewMists		: true,
		Hostile			: true,
		Friendly		: true, // and own alliance
		Neutral			: true,
		Unallied		: true,
		MinMight		: '',
		MaxMight		: '',
		Rank			: '',
		RankType		: '',
		AllianceName	: '',
		PlayerName		: '',
		sortColNum		: 2,
		sortDir			: 1,
	},

// t.mapDat
// 0 - map[k].xCoord
// 1 - map[k].yCoord
// 2 - distance
// 3 - map[k].tileType
// 4 - map[k].tileLevel
// 5 - map[k].tileCityId
// 6 - uid
// 7 - map[k].cityName
// 8 - name
// 9 - might
// 10 - alliance
// 11 - aid
// 12 - Online
// 13 - misted
// 14 - map[k].isPrestige
// 15 - map[k].prestigeLevel
// 16 - map[k].prestigeType
// 17 - map[k].tileId
// 18 - map[k].tileProvinceId
// 19 - Defending
// 20 - map[k].premiumTile
// 21 - map[k].allianceHq.hqId
//
// t.dat = filtered subset of above

	init: function (div) {
		var t = Tabs.Search;
		t.myDiv = div;

		if (!Options.SearchOptions) {
			Options.SearchOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.SearchOptions.hasOwnProperty(y)) {
					Options.SearchOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('ptsearchClickSort', Tabs.Search.searchClickSort);
		uWExportFunction('searchquickmarch', Tabs.Search.searchquickmarch);
		uWExportFunction('btShowHQMembers', Tabs.Search.ShowHQMembers);

		var m = '<DIV class=divHeader align="center">'+tx('MAP SEARCH')+'</div>';
		m += '<TABLE width=100% class=xtab><TR style="height:25px;"><td colspan=3 align=right id=pbsavedsearch>&nbsp;</td></tr><tr><TD align=right width=20%>'+tx('Search Coords')+':&nbsp;</td><TD colspan=2>X:&nbsp;<INPUT id=pbSearchX type=text\> &nbsp;Y:&nbsp;<INPUT id=pbSearchY type=text\>';
		m += '&nbsp;&nbsp;'+tx("Radius")+':&nbsp;<INPUT id=pbSearchDist size=3 value=10 />';
		m += '&nbsp;&nbsp;<SPAN id=pbSearchCitySpan></span></td></tr>';
		m += '<TR><TD align=right>'+tx('Or Search')+':&nbsp;</td><TD><select id="pbSearchProvince"><option value=0>-- '+uW.g_js_strings.commonstr.province+' --</option>';
		for (var i in Provinces) {
			m += '<option value="'+i+'">'+uW.provincenames[i]+'</option>';
		}
		m += '</select>&nbsp;' + tx('Divide into')+':&nbsp;'+ htmlSelector ({1:'1', 4:'4', 9:'9', 16:'16', 25:'25', 36:'36', 49:'49', 64:'64'}, 1, 'id=pbProvinceSlices')+'&nbsp;'+tx('squares')+'.&nbsp;&nbsp;&nbsp;'+tx('Your Square')+':&nbsp;<select id="pbProvinceSlice"><option value=1 selected>1</option></select>&nbsp;'+tx('Detect new mists')+'<INPUT id=pbautoKM type=checkbox />';
		m += '&nbsp;<input style="display:none;" type=button class=btInput id=pbClearMistData value="'+tx('Reset saved mists')+'">';
		m += '</td>';
		m += '<td align=left width=30%><a id=pbSearchSubmit class="inlineButton btButton blue20"><span>'+tx('Start Search')+'</span></a></td></tr>';
		m += '</table>';

		m += '<hr><div id=pbSearchResults style="height:'+t.PANEL_HEIGHT+'px;">&nbsp;</div><div style="min-height:30px;" align=center id=pbSearchBottom>&nbsp;</div>';

		div.innerHTML = m;
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		t.ModelCity = new CdispCityPicker ('pbSearchCity', ById ('pbSearchCitySpan'), true, t.citySelNotify, null);
		t.ModelCity.bindToXYboxes(ById ('pbSearchX'), ById ('pbSearchY'));

		ById ('pbSearchProvince').addEventListener ('click', function() {
			if (this.value != 0) {
				ById ('pbSearchX').value = Provinces[this.value].x+75;
				ById ('pbSearchY').value = Provinces[this.value].y+75;
				ById ('pbSearchDist').value = '75';
				t.setSlice();
			}
		}, false);

		ById ('pbProvinceSlice').addEventListener ('change', function() {
			t.setSlice();
		}, false);

		ById ('pbautoKM').addEventListener ('change', function() {
			if (t.mapDat.length!=0) {
				t.setupFilterDisplay();
				if (t.opt.province != 0 && ById('pbautoKM').checked) {
					t.LookupMists(t.opt.province,t.dispMapTable);
				}
				else {
					t.KMData = [];
					t.dispMapTable();
				}
			}
		}, false);

		ById ('pbClearMistData').addEventListener ('click', function() {
			t.clearoldmists();
		}, false);

		jQuery("#pbProvinceSlices").change(function () {
			var numslices = ById('pbProvinceSlices').value;
			var yourslice = ById('pbProvinceSlice');
			jQuery("#pbProvinceSlice").empty();
			for (var i=1;i<=numslices;i++) {
				var slOption = document.createElement('option');
				slOption.text = i;
				slOption.value = i;
				yourslice.add(slOption);
			}
			jQuery("#pbProvinceSlice").val(1);
			t.setSlice();
		});

		ById ('pbSearchDist').addEventListener ('keydown', t.e_coordChange, false);
		ById ('pbSearchX').addEventListener ('keydown', t.e_coordChange, false);
		ById ('pbSearchY').addEventListener ('keydown', t.e_coordChange, false);
		ById ('pbSearchY').addEventListener ('change', t.e_coordChange, false);
		ById ('pbSearchY').addEventListener ('change', t.e_coordChange, false);
		ById ('pbSearchSubmit').addEventListener ('click', t.clickedSearch, false);

		setTimeout (function () {
			t.readlastsearch( function () {
				if (t.LastSearch.mapDat && t.LastSearch.mapDat != []) {
					t.displaylastsearch();
				}
			});
		}, 0);

//		window.addEventListener('unload', t.onUnload, false);
//		setTimeout (t.readoldmists, 0);
	},

	onUnload : function () {
		var t = Tabs.Search;
		var numRows = t.mapDat.length;
		if (numRows > 0){
			for (var i=0; i<numRows; i++){
				if (t.mapDat[i][13]) {
					if (t.OldMists.indexOf(t.mapDat[i][0]+'_'+t.mapDat[i][1]) == -1) {
						t.OldMists.push(t.mapDat[i][0]+'_'+t.mapDat[i][1]);
					}
				}
			}
		}
		t.saveoldmists();
	},

	searchClickSort : function (e) {
		var t = Tabs.Search;
		var newColNum = e.id.substr(9);
		ById('SearchCol' + Options.SearchOptions.sortColNum).className = 'buttonv2 std blue';
		e.className = 'buttonv2 std green';
		if (newColNum == Options.SearchOptions.sortColNum) { Options.SearchOptions.sortDir *= -1; }
		else { Options.SearchOptions.sortColNum = newColNum; }
		saveOptions();
		t.dispMapTable();
	},

	searchquickmarch : function (x,y) {
		QuickMarch.MapClick(x,y,Cities.byID[Tabs.Search.ModelCityId].idx);
	},

	e_coordChange : function(){
		ById ('pbSearchProvince').selectedIndex = 0;
	},

	setSlice : function () {
		var t = Tabs.Search;
		var prov = ById('pbSearchProvince');
        if (prov.value != 0) {
			var numslices = ById('pbProvinceSlices').value;
			if (numslices == 1) {
				ById('pbSearchX').value = Provinces[prov.value].x+75;
				ById('pbSearchY').value = Provinces[prov.value].y+75;
				ById('pbSearchDist').value = '75';
				return;
			}
			var yourslice = ById('pbProvinceSlice').value;
			var distance = Math.ceil(75/Math.sqrt(numslices));
			var originx = Provinces[prov.value].x;
			var originy = Provinces[prov.value].y;
			var limitx = Provinces[prov.value].x+150;
			var limity = Provinces[prov.value].y+150;
			var nextx = originx+distance;
			var nexty = originy+distance;
			for (var i=1;i<=numslices;i++) {
				if (i == yourslice) {
					ById('pbSearchX').value = nextx;
					ById('pbSearchY').value = nexty;
					ById('pbSearchDist').value = distance;
					return;
				}
				nextx = nextx+(distance*2);
				if (nextx > limitx) {
					nextx = originx+distance;
					nexty = nexty+(distance*2);
					if (nexty > limity) return; // ffs I dunno
				}
			}
		}
	},

	citySelNotify : function (city,x,y){
		var t = Tabs.Search;
		if (city) {
			t.ModelCityId = city.id;
		}
	},

	saveoldmists : function (){
		var t = Tabs.Search;
		var serverID = getServerId();
		setTimeout(function () { GM_setValue ('OldMists_'+serverID+'_'+uW.tvuid, JSON2.stringify(t.OldMists)); },0); // get around GM_SetValue uW error
	},

	readoldmists : function (notify) {
		var t = Tabs.Search;
		var serverID = getServerId();
		var l = JSON2.parse(GM_getValue ('OldMists_'+getServerId()+'_'+uW.tvuid, '[]'));
		if (matTypeof(l) == 'array') { t.OldMists = l; }
		if (notify) { notify(); }
	},

	clearoldmists : function () {
		var t = Tabs.Search;
		t.OldMists = [];
		t.saveoldmists();
	},

	savelastsearch : function (){
		var t = Tabs.Search;
		var serverID = getServerId();
		setTimeout(function () { GM_setValue ('LastSearch_'+serverID+'_'+uW.tvuid, JSON2.stringify(t.LastSearch)); },0); // get around GM_SetValue uW error
	},

	readlastsearch : function (notify) {
		var t = Tabs.Search;
		var serverID = getServerId();
 		s = GM_getValue ('LastSearch_'+serverID+'_'+uW.tvuid);
		if (s != null){
			opts = JSON2.parse (s);
			for (var k in opts)
				t.LastSearch[k] = opts[k];
		}
		if (notify) { notify(); }
	},

	clearlastsearch : function () {
		var t = Tabs.Search;
		ById('pbsavedsearch').innerHTML = "&nbsp;";
		t.LastSearch = {};
		t.savelastsearch();
	},

	showlastsearch : function () {
		var t = Tabs.Search;
		if (t.searchRunning){
			t.stopSearch (tx('Search Cancelled!'));
		}

		ById ('pbSearchX').value = t.LastSearch.opt.startX;
		ById ('pbSearchY').value = t.LastSearch.opt.startY;
		ById ('pbSearchDist').value = t.LastSearch.opt.maxDistance;
		ById('pbSearchProvince').value = t.LastSearch.opt.province;
		ById('pbProvinceSlice').value = t.LastSearch.opt.provinceSlice;
		ById('pbProvinceSlices').value = t.LastSearch.opt.provinceSlices;

		t.mapDat = t.LastSearch.mapDat.slice();
		t.opt.startX = parseInt(t.LastSearch.opt.startX);
		t.opt.startY = parseInt(t.LastSearch.opt.startY);
		t.opt.maxDistance = parseInt(t.LastSearch.opt.maxDistance);
		t.opt.province = ById('pbSearchProvince').value;
		t.opt.provinceSlice = ById('pbProvinceSlice').value;
		t.opt.provinceSlices = ById('pbProvinceSlices').value;
		t.setupResultsPanel(true);
		t.stopSearch('Previous Search');
	},

	displaylastsearch : function () {
		var t = Tabs.Search;
		n = tx("Previous Search")+' ('+uW.formatDate(uWCloneInto(new Date(t.LastSearch.time * 1000)), "NNN dd, HH:mm")+')&nbsp;<INPUT id=pbshowlastsearch class=btInput type=submit value="'+tx('Show')+'"/>&nbsp;<INPUT id=pbclearlastsearch class=btInput type=submit value="'+tx("Clear")+'"/>';
		ById('pbsavedsearch').innerHTML = n;
		ById('pbclearlastsearch').addEventListener('click', t.clearlastsearch, false);
		ById('pbshowlastsearch').addEventListener('click', t.showlastsearch, false);
	},

	clickedSearch : function (){
		var t = Tabs.Search;

		if (t.searchRunning){
			t.stopSearch (tx('Search Cancelled!'),true);
			return;
		}

		t.opt.startX = parseInt(ById('pbSearchX').value);
		t.opt.startY = parseInt(ById('pbSearchY').value);
		t.opt.maxDistance = parseInt(ById('pbSearchDist').value);
		t.opt.province = ById('pbSearchProvince').value;
		t.opt.provinceSlice = ById('pbProvinceSlice').value;
		t.opt.provinceSlices = ById('pbProvinceSlices').value;

		errMsg = '';

		if (isNaN (t.opt.startX) ||t.opt.startX<0 || t.opt.startX>749)
			errMsg = "X "+tx("co-ordinate must be between 0 and 749")+"<BR>";
		if (isNaN (t.opt.startY) ||t.opt.startY<0 || t.opt.startY>749)
			errMsg += "Y "+tx("co-ordinate must be between 0 and 749")+"<BR>";
		if (isNaN (t.opt.maxDistance) ||t.opt.maxDistance<1 || t.opt.maxDistance>75)
			errMsg += tx("Radius (distance) must be between")+" 1 "+tx("and")+" 75<BR>";
		if (errMsg != ''){
			ById('pbSearchResults').innerHTML = '<center><FONT COLOR=#800>'+tx("ERROR")+':</font><BR><BR>'+errMsg+'</center>';
			return;
		}

		t.searchRunning = true;
		ById('pbSearchSubmit').innerHTML = '<span>'+tx('Stop Search')+'</span>';

		t.setupResultsPanel(false);

		if (t.opt.province != 0 && ById('pbautoKM').checked) {
			t.LookupMists(t.opt.province);
		}

		// save any mists in current map array to old mists array, before clearing...

		var numRows = t.mapDat.length;
		if (numRows > 0){
			for (var i=0; i<numRows; i++){
				if (t.mapDat[i][13]) {
					if (t.OldMists.indexOf(t.mapDat[i][0]+'_'+t.mapDat[i][1]) == -1) {
						t.OldMists.push(t.mapDat[i][0]+'_'+t.mapDat[i][1]);
					}
				}
			}
		}
		t.saveoldmists();

		t.mapDat = [];
		t.firstX = t.opt.startX-t.opt.maxDistance;
		t.firstY = t.opt.startY-t.opt.maxDistance;
		if (t.firstX<0) { t.firstX+=750; }
		if (t.firstY<0) { t.firstY+=750; }

		t.lastX = t.opt.startX+t.opt.maxDistance;
		t.lastY = t.opt.startY+t.opt.maxDistance;
		if (t.lastX>=750) { t.lastX-=750; }
		if (t.lastY>=750) { t.lastY-=750; }

		t.BlockList = t.MapAjax.generateBlockList(t.firstX,t.firstY,t.opt.maxDistance);

		t.blocksTotal = t.BlockList.length;
		t.blocksSearched = 0;
		t.tilesFound = 0;

		var counter = t.BlockList.length;
		if (counter > MAX_BLOCKS) { counter = MAX_BLOCKS; }

		var curX = t.firstX;
		var curY = t.firstY;
		ById ('pbStatStatus').innerHTML = tx('Searching at ')+curX+','+curY;

		t.Blocks = [];
		for (var i=1;i<=counter;i++) {
			t.Blocks.push(t.BlockList.shift());
			t.blocksSearched++;
		}
		var blockString = t.Blocks.join("%2C");

		t.MapAjax.LookupMap (blockString, function(rslt) { t.eventGetPlayerOnline(blockString,rslt);});
	},

	setupResultsPanel : function (Previous) {
		var t = Tabs.Search;
		if (t.FilterShow) {
			var FilterDisp = '';
			var ResultWidth = GlobalOptions.btWinSize.x-155;
			var FilterArrow = WhiteLeftArrow;
		}
		else {
			var ResultWidth = GlobalOptions.btWinSize.x-25;
			var FilterDisp = 'none';
			var FilterArrow = WhiteRightArrow;
		}
		var HEIGHT1 = t.PANEL_HEIGHT-35;
		var HEIGHT2 = t.PANEL_HEIGHT-25;
		var HEIGHT3 = t.PANEL_HEIGHT-20;
		m = '<DIV class=divHeader><TABLE width=100% cellspacing=0><TR><TD class=xtab width=125><DIV id=pbStatSearched></div></td>';
		m += '<TD class=xtab align=center><SPAN style="white-space:normal" id=pbStatStatus></span></td>';
		m += '<TD class=xtab align=right width=125><DIV id=pbStatFound></div></td></tr></table></div>';
		m += '<TABLE class=xtab style="width:100%" cellpadding=0 cellspacing=0 align=left><TR valign=top>';
		m += '<TD id=pbSearchFilterContainer style="padding-right:5px;width:130px;height:'+HEIGHT1+'px;padding:5px;border:1px solid;display:'+FilterDisp+'"><DIV id=pbSearchFilters></div></td>';
		m += '<td id=pbSearchOpener valign=middle style="padding-right:5px;width:20px;background:none;border:none;height:'+HEIGHT2+'px;"><a><div class="btExpander buttonv2 blue" style="width:20px;height:'+HEIGHT2+'px;"><span style="display:inline-block;height:100%;vertical-align:middle;"></span><img id=pbSearchOpenerImage style="margin-left:-4px;vertical-align:middle;" height="10" src="'+FilterArrow+'"></div></a></td>';
		m += '<TD class=xtab style="padding-right:0px;"><DIV id=pbResultsPanel style="max-width:'+ResultWidth+'px;overflow-x:auto;height:'+HEIGHT3+'px; max-height:'+HEIGHT3+'px; overflow-y:scroll;">&nbsp;</div></td>';
		m += '</tr></table>';

		ById('pbSearchResults').innerHTML = m;
		ById('pbSearchOpener').addEventListener ('click', t.ToggleSearchFilters, false);

		/* paint filter panel */

	    m = '<table cellpadding=0 cellspacing=0 class=xtab style="padding-right:0px;" width=100%><tr><td colspan=2 style="padding-right:0px;" align=center><div class=divHeader>'+tx('Filters')+'</div>';
//		m += '<div align=center><b><font size=3>'+t.opt.startX+','+t.opt.startY+'</font></b><br>('+tx('Radius')+'&nbsp;'+t.opt.maxDistance+')</div>';
		m += '</td></tr>';
		m += '<tr><td colspan=2 align=center style="padding-top:5px;">'+tx('Search Type')+':</td></tr>';
		m += '<tr><td colspan=2 align=center>'+ htmlSelector ({0:tx("Cities"), 1:tx("Barb Camps"), 2:tx("Wilds"), 3:tx("Dark Forests"), 6:tx("Alliance HQ"), 4:tx("Mercenary Camps"), 5:tx("Nomad Camps"), 7:tx("Runic Megaliths")}, Options.SearchOptions.SearchType, 'id=pbSearchType class=btInput')+'</td></tr>';
		m += '<tr id=pbswild1><td colspan=2 align=center style="padding-top:5px;">'+tx('Wild Type')+':</td></tr>';
		m += '<tr id=pbswild2><td colspan=2 align=center>'+ htmlSelector ({0:tx("Bogs"),1:tx("Grassland/Lakes"),2:tx("Woods"),3:tx("Hills"),4:tx("Mountains"),5:tx("Plains"),99:tx("ALL")}, Options.SearchOptions.WildType, 'id=pbSearchWildType class=btInput')+'</td></tr>';
		m += '<tr id=pbslevel1><td colspan=2 align=center style="padding-top:5px;">'+tx('Tile Levels')+':</td></tr>';
		m += '<tr id=pbslevel2><td colspan=2 align=center><INPUT id=pbSearchMinLevel class=btInput size=2 value='+Options.SearchOptions.MinLevel+'>&nbsp;-&nbsp;<INPUT id=pbSearchMaxLevel class=btInput size=2 value='+Options.SearchOptions.MaxLevel+'></td></tr>';
		m += '<tr id=pbsplayerchecks><td colspan=2><table class=xtab align=center>';
		m += '<tr id=pbsunowned><td><INPUT id=pbSearchUnowned type=checkbox '+(Options.SearchOptions.Unowned?'CHECKED':'')+'/>'+tx('Unowned')+'</td></tr>';
		m += '<tr id=pbsmisted><td><INPUT id=pbSearchMisted type=checkbox '+(Options.SearchOptions.Misted?'CHECKED':'')+'/>'+tx('Misted')+'</td></tr>';
		m += '<tr id=pbsmisted1><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=pbSearchOldMists type=checkbox '+(Options.SearchOptions.OldMists?'CHECKED':'')+'/>'+tx('Old')+'</td></tr>';
		m += '<tr id=pbsmisted2><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<INPUT id=pbSearchNewMists type=checkbox '+(Options.SearchOptions.NewMists?'CHECKED':'')+'/>'+tx('New')+'</td></tr>';
		m += '<tr id=pbsfriendly><td><INPUT id=pbSearchFriendly type=checkbox '+(Options.SearchOptions.Friendly?'CHECKED':'')+'/>'+tx('Friendly')+'</td></tr>';
		m += '<tr id=pbshostile><td><INPUT id=pbSearchHostile type=checkbox '+(Options.SearchOptions.Hostile?'CHECKED':'')+'/>'+tx('Hostile')+'</td></tr>';
		m += '<tr id=pbsneutral><td><INPUT id=pbSearchNeutral type=checkbox '+(Options.SearchOptions.Neutral?'CHECKED':'')+'/>'+tx('Neutral')+'</td></tr>';
		m += '<tr id=pbsunallied><td><INPUT id=pbSearchUnallied type=checkbox '+(Options.SearchOptions.Unallied?'CHECKED':'')+'/>'+tx('Unallied')+'</td></tr>';
		m += '</table></td></tr>';
		m += '<tr id=pbsmight1><td colspan=2 align=center style="padding-top:5px;">'+tx('Might (Billion)')+':</td></tr>';
		m += '<tr id=pbsmight2><td colspan=2 align=center><INPUT id=pbSearchMinMight class=btInput size=3 value='+Options.SearchOptions.MinMight+'>&nbsp;-&nbsp;<INPUT id=pbSearchMaxMight class=btInput size=3 value='+Options.SearchOptions.MaxMight+'></td></tr>';
		m += '<tr id=pbsrank1><td colspan=2 align=center style="padding-top:5px;">'+tx('Alliance Rank')+':</td></tr>';
		m += '<tr id=pbsrank2><td colspan=2 align=center><INPUT id=pbSearchRank class=btInput size=3 value='+Options.SearchOptions.Rank+'>&nbsp;'+ htmlSelector ({0:tx("and Above"), 1:tx("and Below")}, Options.SearchOptions.RankType, 'id=pbSearchRankType class=btInput')+'</td></tr>';
		m += '<tr id=pbsaname1><td colspan=2 align=center style="padding-top:5px;">'+tx('Alliance Name')+':</td></tr>';
		m += '<tr id=pbsaname2><td colspan=2 align=center><INPUT id=pbSearchAllName class=btInput size=8 value='+Options.SearchOptions.AllianceName+'></td></tr>';
		m += '<tr id=pbspname1><td colspan=2 align=center style="padding-top:5px;">'+tx('Player Name')+':</td></tr>';
		m += '<tr id=pbspname2><td colspan=2 align=center><INPUT id=pbSearchPlayerName class=btInput size=8 value='+Options.SearchOptions.PlayerName+'></td></tr>';
		m += '<tr><td colspan=2 align=center style="padding-top:5px;">'+tx('Search Shape')+':</td></tr>';
		m += '<tr><td colspan=2 align=center>'+ htmlSelector ({0:tx("Square"), 1:tx("Circle")}, Options.SearchOptions.SearchShape, 'id=pbSearchShape class=btInput')+'</td></tr>';
		m += '</table>';
		ById('pbSearchFilters').innerHTML = m;

		m = '<TABLE class=xtab style="width:100%" cellpadding=0 cellspacing=0 align=left><TR valign=top><td style="padding-left:5px;padding-top:5px;padding-right:5px;width:155px;" align=left><div id=pbautoqsdiv>'+tx("Auto-QuickScout Mists")+'<INPUT type=checkbox id=pbAutoQS></div></td><td align=left id=pbSearchMessages>&nbsp;</td></tr></table>';
		ById('pbSearchBottom').innerHTML = m;
		ById('pbAutoQS').addEventListener ('change', function (){ t.dispMapTable (); }, false); // triggers autoQS

		t.setupFilterDisplay();

		ById('pbSearchType').addEventListener ('change', function (e){
			Options.SearchOptions.SearchType = e.target.value;
			saveOptions();
			t.setupFilterDisplay();
			t.dispMapTable();
		}, false);

		ChangeOption('SearchOptions','pbSearchWildType','WildType',t.dispMapTable);
		ChangeOption('SearchOptions','pbSearchShape','SearchShape',t.dispMapTable);

		ById('pbSearchMinLevel').addEventListener ('change', t.MinLevelChange, false);
		ById('pbSearchMinLevel').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.MinLevelChange);	}, false);

		ById('pbSearchMaxLevel').addEventListener ('change', t.MaxLevelChange, false);
		ById('pbSearchMaxLevel').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.MaxLevelChange);	}, false);

		ById('pbSearchMinMight').addEventListener ('change', t.MinMightChange, false);
		ById('pbSearchMinMight').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.MinMightChange);	}, false);

		ById('pbSearchMaxMight').addEventListener ('change', t.MaxMightChange, false);
		ById('pbSearchMaxMight').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.MaxMightChange);	}, false);

		ById('pbSearchRank').addEventListener ('change', t.SearchRankChange, false);
		ById('pbSearchRank').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.SearchRankChange); }, false);

		ById('pbSearchRankType').addEventListener ('change', function (e){
			Options.SearchOptions.RankType = e.target.value;
			saveOptions();
			t.AllianceRankings(Options.SearchOptions.Rank,Options.SearchOptions.RankType,function (e) {
				t.Rankings = e;
				t.dispMapTable();
			});
		}, false);

		ById('pbSearchAllName').addEventListener ('change', t.SearchAllNameChange, false);
		ById('pbSearchAllName').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.SearchAllNameChange); }, false);

		ById('pbSearchPlayerName').addEventListener ('change', t.SearchPlayerNameChange, false);
		ById('pbSearchPlayerName').addEventListener ('keyup', function (e){ StartKeyTimer(e.target, t.SearchPlayerNameChange); }, false);

		ToggleOption('SearchOptions','pbSearchUnowned','Unowned',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchMisted','Misted',function() { t.setupFilterDisplay();t.dispMapTable();});
		ToggleOption('SearchOptions','pbSearchOldMists','OldMists',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchNewMists','NewMists',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchFriendly','Friendly',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchHostile','Hostile',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchNeutral','Neutral',t.dispMapTable);
		ToggleOption('SearchOptions','pbSearchUnallied','Unallied',t.dispMapTable);

		if (parseIntNan(Options.SearchOptions.Rank)!=0) {
			t.AllianceRankings(Options.SearchOptions.Rank,Options.SearchOptions.RankType,function (e) {
				t.Rankings = e;
				if (!t.searchRunning) { t.dispMapTable(); }
			});
		}
	},

	MinLevelChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchMinLevel');
		if (isNaN(e.value)) { e.value = ''; }
		Options.SearchOptions.MinLevel = e.value;
		saveOptions();
		t.dispMapTable();
	},

	MaxLevelChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchMaxLevel');
		if (isNaN(e.value)) { e.value = ''; }
		Options.SearchOptions.MaxLevel = e.value;
		saveOptions();
		t.dispMapTable();
	},

	MinMightChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchMinMight');
		if (isNaN(e.value)) { e.value = ''; }
		Options.SearchOptions.MinMight = e.value;
		saveOptions();
		t.dispMapTable();
	},

	MaxMightChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchMaxMight');
		if (isNaN(e.value)) { e.value = ''; }
		Options.SearchOptions.MaxMight = e.value;
		saveOptions();
		t.dispMapTable();
	},

	SearchRankChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchRank');
		if (isNaN(e.value)) { e.value = ''; }
		if (e.value>50) { e.value = 50; }
		Options.SearchOptions.Rank = e.value;
		saveOptions();
		t.AllianceRankings(Options.SearchOptions.Rank,Options.SearchOptions.RankType,function (e) {
			t.Rankings = e;
			t.dispMapTable();
		});
	},

	SearchAllNameChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchAllName');
		Options.SearchOptions.AllianceName = e.value;
		saveOptions();
		t.dispMapTable();
	},

	SearchPlayerNameChange : function () {
		var t = Tabs.Search;
		if (KeyTimer) { clearTimeout(KeyTimer); }
		var e = ById('pbSearchPlayerName');
		Options.SearchOptions.PlayerName = e.value;
		saveOptions();
		t.dispMapTable();
	},

	setupFilterDisplay : function () {
		var t = Tabs.Search;

		var stype = Options.SearchOptions.SearchType;

		if (stype == 2) {
			jQuery('#pbswild1').removeClass('divHide');
			jQuery('#pbswild2').removeClass('divHide');
			jQuery('#pbsunowned').removeClass('divHide');
		}
		else {
			jQuery('#pbswild1').addClass('divHide');
			jQuery('#pbswild2').addClass('divHide');
			jQuery('#pbsunowned').addClass('divHide');
		}

		if (stype != 0 && stype != 6) {
			jQuery('#pbslevel1').removeClass('divHide');
			jQuery('#pbslevel2').removeClass('divHide');
		}
		else {
			jQuery('#pbslevel1').addClass('divHide');
			jQuery('#pbslevel2').addClass('divHide');
		}

		if (stype != 0) {
			if (ById('pbHighDefenders')) ById('pbHighDefenders').style.display = 'none';
		}
		else {
			if (ById('pbHighDefenders')) ById('pbHighDefenders').style.display = '';
		}

		if (stype == 0 || stype == 2 || stype==6) {
			jQuery('#pbsplayerchecks').removeClass('divHide');
			jQuery('#pbsrank1').removeClass('divHide');
			jQuery('#pbsrank2').removeClass('divHide');
			jQuery('#pbsaname1').removeClass('divHide');
			jQuery('#pbsaname2').removeClass('divHide');
			if (stype == 6) {
				jQuery('#pbsmight1').addClass('divHide');
				jQuery('#pbsmight2').addClass('divHide');
				jQuery('#pbspname1').addClass('divHide');
				jQuery('#pbspname2').addClass('divHide');
				jQuery('#pbautoqsdiv').addClass('divHide');
			} else {
				jQuery('#pbspname1').removeClass('divHide');
				jQuery('#pbspname2').removeClass('divHide');
				jQuery('#pbsmight1').removeClass('divHide');
				jQuery('#pbsmight2').removeClass('divHide');
				jQuery('#pbautoqsdiv').removeClass('divHide');
			}
		}
		else {
			jQuery('#pbsplayerchecks').addClass('divHide');
			jQuery('#pbsrank1').addClass('divHide');
			jQuery('#pbsrank2').addClass('divHide');
			jQuery('#pbsaname1').addClass('divHide');
			jQuery('#pbsaname2').addClass('divHide');
			jQuery('#pbsmight1').addClass('divHide');
			jQuery('#pbsmight2').addClass('divHide');
			jQuery('#pbspname1').addClass('divHide');
			jQuery('#pbspname2').addClass('divHide');
			jQuery('#pbautoqsdiv').addClass('divHide');
		}

		if ((stype == 0) && Options.SearchOptions.Misted && ById('pbautoKM').checked) {
			jQuery('#pbsmisted1').removeClass('divHide');
			jQuery('#pbsmisted2').removeClass('divHide');
		}
		else {
			jQuery('#pbsmisted1').addClass('divHide');
			jQuery('#pbsmisted2').addClass('divHide');
		}

		if (stype == 6) {
			jQuery('#pbsmisted').addClass('divHide');
			jQuery('#pbsunallied').addClass('divHide');
		}
		else {
			jQuery('#pbsmisted').removeClass('divHide');
			jQuery('#pbsunallied').removeClass('divHide');
		}

	},

	ToggleSearchFilters : function (){
		var t = Tabs.Search;
		t.FilterShow = !t.FilterShow;
		var div = ById('pbSearchFilterContainer');
		if (div.style.display == 'none'){
			div.style.display = '';
			var ResultWidth = GlobalOptions.btWinSize.x-155;
			ById('pbSearchOpenerImage').src = WhiteLeftArrow;
		} else {
			div.style.display = 'none';
			var ResultWidth = GlobalOptions.btWinSize.x-25;
			ById('pbSearchOpenerImage').src = WhiteRightArrow;
		}
		ById('pbResultsPanel').style.maxWidth = ResultWidth+'px';
	},

	AllianceRankings : function (rank, type, callback, page, prop) {
		var t = Tabs.Search;
		if(parseIntNan(rank)==0) return;
		var limit = rank-1;
		if (type==0) { // above, so include passed rank
			limit=rank;
		}
		if(matTypeof(page) == 'undefined') page = 1;
		if(matTypeof(prop) == 'undefined') prop = [];
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.pageNo = page;
		params.cityId = uW.currentcityid;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceGetOtherInfo.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				var oa = rslt.otherAlliances;
				for (var i=0;i<oa.length;i++) {
					if (oa[i].ranking <= limit)
						prop.push(oa[i].allianceId)
				}
				if(oa[Number(i-1)].ranking < limit) {
					page++;
					t.AllianceRankings(rank, type, callback, page, prop);
				} else callback(prop);
			},
		});
	},

	eventGetPlayerOnline : function (blockString, rslt){
		var t = Tabs.Search;
		if (!t.searchRunning) { return; }
		if (!rslt.ok) {
			if (rslt.BotCode && rslt.BotCode==999) { // map captcha
				t.stopSearch ('<span class=boldRed>'+tx('Map captcha detected - Aborting search :(')+'</span>',true);
				return;
			}
			setTimeout ( function() {t.MapAjax.LookupMap (blockString, function() { t.eventGetPlayerOnline(blockString,rslt);})}, MAP_DELAY); //we need to retry if bad ajax request.
			return;
		}

		map = rslt.data;
		t.SearchList = rslt;
		var uList = [];
		for(k in map){
			if(map[k].tileUserId != null) {
				uList.push(map[k].tileUserId);
			}
		}
		getOnline(uList, function (r) { t.mapCallback(r) });
	},

	mapCallback : function (uList){
		var t = Tabs.Search;

		var rslt = t.SearchList;
		map = rslt.data;
		var userInfo = rslt.userInfo;
		var alliance = rslt.allianceNames;

		for (var k in map){
			var xOK = false;
			var yOK = false;
			if (t.firstX<t.lastX) { xOK = (map[k].xCoord>=t.firstX && map[k].xCoord<=t.lastX); }
			else { xOK = (map[k].xCoord>=t.firstX || map[k].xCoord<=t.lastX); } // search over x boundary
			if (t.firstY<t.lastY) { yOK = (map[k].yCoord>=t.firstY && map[k].yCoord<=t.lastY); }
			else { yOK = (map[k].yCoord>=t.firstY || map[k].yCoord<=t.lastY); } // search over y boundary
			var pOK = true;
			if (t.opt.province != 0) {
				pOK = (map[k].tileProvinceId == t.opt.province.split("p")[1]);
			}

			if (xOK && yOK && pOK) {
				var name = '';
				var might = 0;
				var city = ''
				var alli = '';
				var aID = 0;
				var dist = distance (t.opt.startX, t.opt.startY, map[k].xCoord, map[k].yCoord);

				var u = map[k].tileUserId || 0;
				if (u!=0) {
					if (userInfo['u'+u]) {
						name = userInfo['u'+u].n;
						might = parseIntNan(userInfo['u'+u].m);
						city = map[k].cityName || '';
						if (alliance['a'+userInfo['u'+u].a]) {
							alli = alliance['a'+userInfo['u'+u].a];
							aID = userInfo['u'+u].a
						} else {
							alli = '---';
							aID = 0;
						}	
					}
					else {
						u=0;
						map[k].tileType=53; // assume misted!
					}
				}
				var misted = map[k].misted;
				if (map[k].tileType==53) { // misted city (or plain)
					misted = true;
				}
				if (map[k].tileType!=51) {
					if (map[k].tileType!=50 || map[k].premiumTile!=1) {
						city = tileTypes[map[k].tileType];
					}
				}
				else {
					if (u==0 && !misted) {
						city = tx('Barb Camp');
					}
				}

				var hqId = 0;
				if (map[k].allianceHq) {
					if (misted) { // fill in alliance info from HQ fields
						alli = map[k].allianceHq.allianceName;
						aID = map[k].allianceHq.allianceId;
					}
					city = map[k].allianceHq.hqName;
					hqId = map[k].allianceHq.hqId;
				}

				t.mapDat.push ([map[k].xCoord, map[k].yCoord, dist, map[k].tileType, parseIntNan(map[k].tileLevel), map[k].tileCityId, u, city, name, might, alli, aID, uList.data[u]?1:0, misted, map[k].isPrestige, map[k].prestigeLevel, map[k].prestigeType, map[k].tileId, map[k].tileProvinceId,false,map[k].premiumTile, hqId]);
				++t.tilesFound;
			}
		}

		ById('pbStatSearched').innerHTML = tx('Searched: ')+ Math.round((t.blocksSearched/t.blocksTotal)*100)+'%';
		t.dispMapTable();

		var counter = t.BlockList.length;
		if (counter==0) {
			t.stopSearch (tx('Completed!'),true);
			return;

		}
		if (counter > MAX_BLOCKS) { counter = MAX_BLOCKS; }

		var nextblock = t.BlockList[0];
		var curX = nextblock.split("_")[1];
		var curY = nextblock.split("_")[3];
		ById ('pbStatStatus').innerHTML = tx('Searching at ')+ curX +','+ curY;

		t.Blocks = [];
		for (var i=1;i<=counter;i++) {
			t.Blocks.push(t.BlockList.shift());
			t.blocksSearched++;
		}
		var blockString = t.Blocks.join("%2C");
		setTimeout (function(){t.MapAjax.LookupMap (blockString, function(rslt) { t.eventGetPlayerOnline(blockString,rslt);})}, MAP_DELAY);
	},

	LookupMists : function (prov,notify) {
		var t = Tabs.Search;
		t.KMData = [];

		// look up kocbyte mists page for province, and build array

		var URL = 'http://www.kocbyte.com/misted/'+getServerId()+'/'+t.opt.province.split("p")[1];
		try {
			GM_xmlhttpRequest({
				method: 'GET',
				url: URL,
				onload: function(xpr) {
					var rslt = null;
					try {
						rslt = xpr.responseText;
					} catch (e){
						logerr(e);
						if (notify) {notify();}
						return;
					}

					RegExp.prototype.execAll = function(string) {
						var match = null;
						var matches = new Array();
						while (match = this.exec(string)) {
							var matchArray = [];
							for (var i in match) {
								if (parseInt(i) == i) {
									matchArray.push(match[i]);
								}
							}
							matches.push(matchArray);
						}
						return matches;
					}
					var myregexp = /([1-9]*\,[1-9]*)/g;
					var match = myregexp.execAll(rslt);
					for (var m in match) {
						t.KMData.push(match[m][1].split(",")[0]+'_'+match[m][1].split(",")[1]);
					}
					if (notify) {notify();}
				},
				onerror: function() {
					if (notify) {notify();}
				}
			});
		} catch (e){ logerr(e);	}
	},

	dispMapTable : function (){
		var t = Tabs.Search;

		function sortFunc(a, b) {
			var t = Tabs.Search;
			if (typeof (a[Options.SearchOptions.sortColNum]) == 'number') {
				if (Options.SearchOptions.sortDir > 0)
					return a[Options.SearchOptions.sortColNum] - b[Options.SearchOptions.sortColNum];
				else
					return b[Options.SearchOptions.sortColNum] - a[Options.SearchOptions.sortColNum];
			} else if (typeof (a[Options.SearchOptions.sortColNum]) == 'boolean') {
				return 0;
			} else {
				if (Options.SearchOptions.sortDir > 0)
					return a[Options.SearchOptions.sortColNum].localeCompare(b[Options.SearchOptions.sortColNum]);
				else
					return b[Options.SearchOptions.sortColNum].localeCompare(a[Options.SearchOptions.sortColNum]);
			}
		}

		t.dat = [];

		for (var i=0; i<t.mapDat.length; i++){
			var TileOK = (Options.SearchOptions.SearchShape == 0 || t.mapDat[i][2] <= t.opt.maxDistance); // check distance on circle search

			if (TileOK) { // check type
				if (Options.SearchOptions.SearchType==0) { // city
					TileOK = ((t.mapDat[i][3]==51 && t.mapDat[i][5] && t.mapDat[i][5]!=0) || (t.mapDat[i][3]==53));
				}
				if (Options.SearchOptions.SearchType==1) { // barb camp
					TileOK = (t.mapDat[i][3]==51 && (!t.mapDat[i][5] || t.mapDat[i][5]==0));
				}
				if (Options.SearchOptions.SearchType==2) { // wilderness
					TileOK = (t.mapDat[i][3]<50 || (t.mapDat[i][3]==50 && t.mapDat[i][20]==0));
				}
				if (Options.SearchOptions.SearchType==3) { // dark forest
					TileOK = (t.mapDat[i][3]==54);
				}
				if (Options.SearchOptions.SearchType==4) { // mercenary camp
					TileOK = (t.mapDat[i][3]==55);
				}
				if (Options.SearchOptions.SearchType==5) { // nomad camp
					TileOK = (t.mapDat[i][3]==56);
				}
				if (Options.SearchOptions.SearchType==6) { // alliance HQ
					TileOK = (t.mapDat[i][3]==50 && t.mapDat[i][20]==1);
				}
				if (Options.SearchOptions.SearchType==7) { // runic megalith
					TileOK = (t.mapDat[i][3]==57);
				}
			}

			if (TileOK && Options.SearchOptions.SearchType!=0 && Options.SearchOptions.SearchType!=6) { // check level (not cities or HQ)
				var Level = parseIntNan(t.mapDat[i][4]);
				TileOK = ((Level==0) || Level>=parseIntNan(Options.SearchOptions.MinLevel) && (Level<=parseIntNan(Options.SearchOptions.MaxLevel) || parseIntNan(Options.SearchOptions.MaxLevel)==0));
			}

			if (TileOK && Options.SearchOptions.SearchType==2) {
				var WType = Math.floor(t.mapDat[i][3]/10);
				TileOK = (WType==Options.SearchOptions.WildType || Options.SearchOptions.WildType==99); // wild type

				if (TileOK) {
					if (parseIntNan(t.mapDat[i][5])==0 && !t.mapDat[i][13]) { // unowned wilds
						TileOK = (Options.SearchOptions.Unowned);
					}
				}
			}

			if (TileOK && (Options.SearchOptions.SearchType==2 || Options.SearchOptions.SearchType==0 || Options.SearchOptions.SearchType==6)) {
				if (t.mapDat[i][13] && Options.SearchOptions.SearchType!=6) {
					TileOK = (Options.SearchOptions.Misted); // misted

					if (TileOK && Options.SearchOptions.SearchType==0 && ById('pbautoKM').checked) {
						var newmist = true;
						if (newmist && t.KMData.length != 0) {
							newmist = (t.KMData.indexOf(t.mapDat[i][0]+'_'+t.mapDat[i][1]) == -1);
						}
						if (newmist) {
							newmist = (t.OldMists.indexOf(t.mapDat[i][0]+'_'+t.mapDat[i][1]) == -1);
						}
						if (newmist) { TileOK = (Options.SearchOptions.NewMists); }
						else { TileOK = (Options.SearchOptions.OldMists); }
					}
				}
				else {
					if ((parseIntNan(t.mapDat[i][5])!=0)) { // owned filters
						if (parseIntNan(t.mapDat[i][11])==0 && Options.SearchOptions.SearchType!=6) { // unallied
							TileOK = (Options.SearchOptions.Unallied);
						}
						else {
							var dip = getDiplomacy(parseIntNan(t.mapDat[i][11]));
							if (dip==uW.g_js_strings.commonstr.friendly || dip==uW.g_js_strings.commonstr.yours) { // friendly and yours
								TileOK = (Options.SearchOptions.Friendly);
							}
							else {
								if (dip==uW.g_js_strings.commonstr.hostile) { // hostile
									TileOK = (Options.SearchOptions.Hostile);
								}
								else {
									TileOK = (Options.SearchOptions.Neutral); // neutral
								}
							}

							if (TileOK) { // min or max alliance rank
								if (parseIntNan(Options.SearchOptions.Rank)!=0) {
									if (Options.SearchOptions.RankType==0) {
										TileOK = (t.Rankings.indexOf(parseIntNan(t.mapDat[i][11])) != -1);
									}
									else {
										TileOK = (t.Rankings.indexOf(parseIntNan(t.mapDat[i][11])) == -1);
									}
								}
							}

							if (TileOK) { // include alliance name
								if (Options.SearchOptions.AllianceName && Options.SearchOptions.AllianceName.trim() != '') {
									TileOK = (t.mapDat[i][10].toUpperCase().search(Options.SearchOptions.AllianceName.trim().toUpperCase()) >= 0);
								}
							}
						}

						if (TileOK && Options.SearchOptions.SearchType!=6) { // min/max player might
							var Might = parseIntNan(t.mapDat[i][9]);
							var MinMight = parseIntNan(Options.SearchOptions.MinMight)*1000000000;
							var MaxMight = parseIntNan(Options.SearchOptions.MaxMight)*1000000000;
							TileOK = (Might>=MinMight && (Might<=MaxMight || MaxMight==0));
						}

						if (TileOK && Options.SearchOptions.SearchType!=6) { // include player name
							if (Options.SearchOptions.PlayerName && Options.SearchOptions.PlayerName.trim() != '') {
								TileOK = (t.mapDat[i][8].toUpperCase().search(Options.SearchOptions.PlayerName.trim().toUpperCase()) >= 0);
							}
						}
					}
				}
			}

			if (TileOK) {
               t.dat.push(t.mapDat[i]);
			}
		}

		t.mists = 0;
		t.scouted = 0;

		ById('pbStatFound').innerHTML = tx('Found')+': '+t.dat.length;
		var m = '<center><br><br>'+tx('No tiles found matching search criteria')+'</center>';
		if (t.dat.length!=0) {
			t.dat.sort(sortFunc);

			var dis = '';
			if (t.searchRunning) { dis = 'disabled'; }

			var m = '<table align=center width=99% cellspacing=0 cellpadding=0>';
			m += '<TR><td width=30>&nbsp;</td><TD nowrap><A id=SearchCol4 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Lvl')+'&nbsp;</span></a></td>\
				<TD nowrap><a class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="padding-right:10px;vertical-align:middle;display:inline-block;width:100%;"><INPUT id=ToggleSearchScoutCheckbox type=checkbox '+dis+'></span></a></td>\
				<TD nowrap><A id=SearchCol0 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Co-ords')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=SearchCol2 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Distance')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=SearchCol8 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Player')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=SearchCol7 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('City')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=SearchCol9 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+tx('Might')+'&nbsp;</span></a></td>\
				<TD nowrap><A id=SearchCol10 onclick="ptsearchClickSort(this)" class="buttonv2 std blue" style="padding-left:0px;padding-right:0px;"><span style="display:inline-block;width:100%;">&nbsp;'+uW.g_js_strings.commonstr.alliance+'&nbsp;</span></a></td>\
				</tr>';

			var numRows = t.dat.length;
			if (numRows > t.MAX_SHOW_WHILE_RUNNING && t.searchRunning){
				numRows = t.MAX_SHOW_WHILE_RUNNING;
				ById('pbSearchMessages').innerHTML = '<FONT COLOR=#800>'+tx('NOTE: Table only shows ')+ t.MAX_SHOW_WHILE_RUNNING +' of '+ t.dat.length +tx(' results until search is completed')+'.</font>';
			}

			var qsdelay = 0;
			var r = 0;
			var RowId = "";

			for (var i=0; i<numRows; i++){
				RowId = 'search_'+t.dat[i][0].toString()+'_'+t.dat[i][1].toString();
				var status = '<img title="Offline" style="vertical-align:bottom" src="'+OFFLINE+'"/>';
				if (t.dat[i][12] == 1) { status = '<img title="Online" style="vertical-align:bottom" src="'+ONLINE+'"/>'; }

				var rowStyle = '';
				var cityname = '';
				var playername = '';
				var might = '';

				var HQ = (t.dat[i][3]==50 && t.dat[i][20]==1);

				if (t.dat[i][7]) { cityname = t.dat[i][7]; }
				if (t.dat[i][8]) { playername = t.dat[i][8]; }
				if (cityname == "" && HQ) {
					cityname = tx("Alliance HQ");
					if (trusted) cityname += ' '+strButton8(uW.g_js_strings.commonstr.members,'onclick="btShowHQMembers(this,'+t.dat[i][21]+')"');
				}
				if (playername == "" && HQ) playername = "???";
				if (parseIntNan(t.dat[i][9])!=0) { might = addCommas(t.dat[i][9]); }

				if (t.dat[i][13] && !HQ) {
					t.mists++;
					if (parseIntNan(t.dat[i][6])!=0 || playername != '') t.scouted++;
					var newmist = (Options.SearchOptions.SearchType==0); // cities only!
					if (newmist && t.KMData.length != 0) {
						newmist = (t.KMData.indexOf(t.dat[i][0]+'_'+t.dat[i][1]) == -1);
					}
					if (newmist) {
						newmist = (t.OldMists.indexOf(t.dat[i][0]+'_'+t.dat[i][1]) == -1);
					}
					if (newmist && ById('pbautoKM').checked) {
						rowStyle = 'style="color:#f00;"'; // highlighted
						mistedtext = tx("NEW MIST");
					}
					else {
						rowStyle = 'style="opacity:0.5;"'; // misted
						mistedtext = tx("MISTED");
					}
				}

				r=r+1;
				rowClass = 'evenRow';
				var rem = (r % 2);
				if (rem == 1) rowClass = 'oddRow';
				if (t.dat[i][19]) rowClass += ' highRow';

				m += '<TR id="'+RowId+'" class="'+rowClass+'" style="max-height:30px"><TD class=xtab><a id=l_'+t.dat[i][0]+'_t_'+t.dat[i][1]+' class=divLink onclick="';
				m += 'searchquickmarch('+t.dat[i][0]+', '+t.dat[i][1]+')';
				m += '">'+TileImage(t.dat[i][3],t.dat[i][4],t.dat[i][5],t.dat[i][16],t.dat[i][15],t.dat[i][20])+'</a></td>';
				m += '<td class=xtab align=center>'+((t.dat[i][4]!=0)?t.dat[i][4]:'??')+'</td>';
				m += '<TD class=xtab align=center style="padding-left:4px;padding-right:0px;"><INPUT id=pbSearchScout_'+t.dat[i][0]+'_'+t.dat[i][1]+' type=checkbox '+dis+'></td>';
				m += '<td class=xtab align=center><DIV onclick="btGotoMap('+ t.dat[i][0] +','+ t.dat[i][1] +')"><A>'+ t.dat[i][0] +','+ t.dat[i][1] +'</a></div></td>';
				m += '<td class=xtab align=right>'+t.dat[i][2]+'</td>';

				if (t.dat[i][13] && !HQ && parseIntNan(t.dat[i][6])==0) { // still misted
					if (playername == '') {
						m += '<TD '+rowStyle+' class=xtab nowrap colspan=4 id=pbsrch_'+t.dat[i][0]+'_'+t.dat[i][1]+'><center>*** '+mistedtext+' ***&nbsp;&nbsp;<SPAN onclick="quickscoutsearch('+ t.dat[i][0] +','+ t.dat[i][1] +','+t.ModelCityId+');return false;"><A>'+tx("QuickScout")+'</a></span></center></td>';
						if (ById('pbAutoQS')) {
							if (ById('pbAutoQS').checked) {
								if (!Tabs.Search.QSMarching[t.dat[i][0]+'_'+t.dat[i][1]] || Tabs.Search.QSMarching[t.dat[i][0]+'_'+t.dat[i][1]]==0) {
									Tabs.Search.QSMarching[t.dat[i][0]+'_'+t.dat[i][1]] = 1;
									setTimeout(uW.quickscoutsearch,(5000*qsdelay),t.dat[i][0],t.dat[i][1],t.ModelCityId,true);
									qsdelay = qsdelay + 1;
								}
							}
						}
					}
					else {
						m += '<TD '+rowStyle+' class=xtab nowrap colspan=4 id=pbsrch_'+t.dat[i][0]+'_'+t.dat[i][1]+'>'+playername+'</td>'; // messages from quickscout stored in playername
					}
				}
				else {
					m += '<TD '+rowStyle+' class=xtab nowrap>'+((parseIntNan(t.dat[i][6])!=0)?status+PlayerLink(t.dat[i][6],playername):playername)+'</td>';
					m += '<td '+rowStyle+' class=xtab>'+cityname+'</td>';
					m += '<td '+rowStyle+' class=xtab align=right>'+might+'</td>';
					m += '<td '+rowStyle+' class=xtab><span style='+DiplomacyColours(t.dat[i][11])+'>'+t.dat[i][10]+'</span></td>';
				}

				m += '</tr>';
			}
			m += '</table>';
		}

		ById('pbResultsPanel').innerHTML = m;
		if (t.dat.length!=0) {
			ById('SearchCol' + Options.SearchOptions.sortColNum).className = 'buttonv2 std green';
			ById('ToggleSearchScoutCheckbox').addEventListener('change', t.doSelectall, false);
		}
		t.updateMistProgress();
	},

	ShowHQMembers : function (elem,hqId) {
		var t = Tabs.Search;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.hqId = hqId;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/allianceHqMineOpen.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var helpText = '<DIV style="max-height:400px; height:400px; overflow-y:auto">';
					helpText += '<br>';
					for (var mem in rslt.collect_status) {
						helpText += MonitorLink(rslt.collect_status[mem].userId,rslt.collect_status[mem].displayName)+'<br>';
					}
					helpText += '</div><br>';

					var off = getOffset(elem);
					var pop = new CPopup ('BotHelp', off.left, off.top+20, 150, 400, true);
					pop.getMainDiv().innerHTML = helpText;
					pop.getTopDiv().innerHTML = '<CENTER><B>'+uW.g_js_strings.commonstr.members+'</b></center>';
					pop.show (true);
					ResetFrameSize('BotHelp',400,150);
				}
			},
		}, false);
	},

	updateMistProgress : function () {
		var t = Tabs.Search;
		if (!t.searchRunning) {
			if (t.mists!=0) {
	//			ById('pbStatSearched').innerHTML = tx('Scouted: ')+ Math.round((t.scouted/t.mists)*100)+'%';
				ById('pbStatSearched').innerHTML = tx('Mists Scouted: ')+ t.scouted+'/'+t.mists;
			}
			else {
				ById('pbStatSearched').innerHTML = "";
			}
		}
	},

	doSelectall: function () {
		var t = Tabs.Search;
		var coords = "";
		for (var k = 0; k < t.dat.length; k++) {
			coords = t.dat[k][0]+'_'+t.dat[k][1];
			if (ById('ToggleSearchScoutCheckbox').checked) ById('pbSearchScout_' + coords).checked = true;
			else ById('pbSearchScout_' + coords).checked = false;
		}
	},

	stopSearch : function (msg,savelast){
		var t = Tabs.Search;
		t.searchRunning = false;
		ById ('pbStatStatus').innerHTML = msg;
		ById ('pbSearchSubmit').innerHTML = '<span>'+tx('Start Search')+'</span>';

		if (savelast) {
			t.clearlastsearch();
			t.LastSearch.opt = t.opt;
			t.LastSearch.time = unixTime();
			t.LastSearch.mapDat = t.mapDat.slice();
			t.savelastsearch();
			t.displaylastsearch();
		}

		var m = '<DIV align=right style="max-width:'+Number(GlobalOptions.btWinSize.x-170)+'px;overflow-x:auto;">';
		m += strButton20(tx('Highlight Defenders'), 'id=pbHighDefenders')+'&nbsp;';
		m += strButton20(tx('Copy Co-ordinates'), 'id=pbCoordCopy')+'&nbsp;';
		if (Tabs.BulkScout) m += strButton20(tx('Add to Scout List'), 'id=pbScoutExport')+'&nbsp;';
		if (Tabs.BulkAttack) m += strButton20(tx('Add to Attack List'), 'id=pbBulkAttackExport')+'&nbsp;';
		if (Tabs.Attack) m += strButton20(tx('Add to Auto-Attack'), 'id=pbAttackExport')+'&nbsp;';
		m += '&nbsp;</div>&nbsp;';

		ById ('pbSearchMessages').innerHTML = m;
		if (ById('pbScoutExport')) ById('pbScoutExport').addEventListener('click', t.ExportScoutList, false);
		if (ById('pbBulkAttackExport')) ById('pbBulkAttackExport').addEventListener('click', t.ExportAttackList, false);
		if (ById('pbAttackExport')) ById('pbAttackExport').addEventListener('click', t.ExportAttack, false);
		ById('pbCoordCopy').addEventListener('click', t.CopyCoords, false);
		if (ById('pbHighDefenders')) ById('pbHighDefenders').addEventListener('click', t.HighlightDefenders, false);

		if (Options.SearchOptions.SearchType != 0) {
			if (ById('pbHighDefenders')) ById('pbHighDefenders').style.display = 'none';
		}

		t.dispMapTable();
	},

	ExportScoutList : function () {
		var t = Tabs.Search;

		var coordlist = "";
		var coords = "";
		for (var k = 0; k < t.dat.length; k++) {
			coords = t.dat[k][0]+'_'+t.dat[k][1];
			if (ById('pbSearchScout_' + coords).checked) {
				coordlist += t.dat[k][0].toString()+','+t.dat[k][1].toString()+' ';
				ById('pbSearchScout_' + coords).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkScout.ImportCoords(coordlist.split(" "));
		}
	},

	ExportAttackList : function () {
		var t = Tabs.Search;

		var coordlist = "";
		var coords = "";
		for (var k = 0; k < t.dat.length; k++) {
			coords = t.dat[k][0]+'_'+t.dat[k][1];
			if (ById('pbSearchScout_' + coords).checked) {
				coordlist += t.dat[k][0].toString()+','+t.dat[k][1].toString()+' ';
				ById('pbSearchScout_' + coords).checked = false;
			}
		}

		if (coordlist != "") {
			Tabs.BulkAttack.ImportCoords(coordlist.split(" "));
		}
	},

	ExportAttack : function () {
		var t = Tabs.Search;

		var sel = false;
		for (var k = 0; k < t.dat.length; k++) {
			coords = t.dat[k][0]+'_'+t.dat[k][1];
			if (ById('pbSearchScout_' + coords).checked) {
				sel = true;
				break;
			}
		}

		if (sel) {
			Tabs.Attack.NewRoute();
			ById('bttcAttack').click();
		}
	},

	CopyCoords : function () {
		var t = Tabs.Search;

		var coordlist = "";
		var coords = "";
		for (var k = 0; k < t.dat.length; k++) {
			coords = t.dat[k][0]+'_'+t.dat[k][1];
			if (ById('pbSearchScout_' + coords).checked) {
				coordlist += t.dat[k][0].toString()+','+t.dat[k][1].toString()+' ';
			}
		}

		if (coordlist != "") {
			window.prompt('Copy to clipboard: Ctrl+C', coordlist);
		}
	},

	HighlightDefenders : function () {
		var t = Tabs.Search;

		var delayer = 0;
		ById('pbHighDefenders').outerHTML = '<span id=pbHighDefendersProg>&nbsp;</span>';

		for (var k = 0; k < t.dat.length; k++) {
			if ((t.dat[k][3]==51 && t.dat[k][5] && t.dat[k][5]!=0) || (t.dat[k][3]==53)) {
				if (!t.ReqSent[t.dat[k][0]+'_'+t.dat[k][1]] || t.ReqSent[t.dat[k][0]+'_'+t.dat[k][1]]==0) {
					t.ReqSent[t.dat[k][0]+'_'+t.dat[k][1]]=1;
					setTimeout(getDefendStatus,(250*delayer),t.dat[k][0],t.dat[k][1],false,false,t.UpdateDefendStatus,k,t.dat.length,'pbHighDefendersProg');
					delayer = delayer + 1;
				}
			}
		}

		function ClearAtEnd () {
			if (ById('pbHighDefendersProg')) {
				ById('pbHighDefendersProg').outerHTML = strButton20(tx('Highlight Defenders'),'id=pbHighDefenders');
				ById('pbHighDefenders').addEventListener('click', t.HighlightDefenders, false);
			}
		};

		setTimeout (ClearAtEnd,(250*delayer));
	},

	UpdateDefendStatus : function (rslt,x,y,k) {
		var t = Tabs.Search;
		t.ReqSent[x+'_'+y]=0;
		var div = ById('search_'+x+'_'+y);
		var coords = t.dat[k][0]+'_'+t.dat[k][1];
		if (rslt.ok && rslt.ok=="true") {
			t.dat[k][19] = true;
			if (div) jQuery(div).addClass("highRow");
			if (ById('pbSearchScout_' + coords)) ById('pbSearchScout_' + coords).checked = true;
		}
		else {
			t.dat[k][19] = false;
			if (div) jQuery(div).removeClass("highRow");
			if (ById('pbSearchScout_' + coords)) ById('pbSearchScout_' + coords).checked = false;
		}
		var numRows = t.mapDat.length;
		for (var i=0; i<numRows; i++){
			if (t.mapDat[i][0] == x && t.mapDat[i][1] == y) {
				t.mapDat[i][19] = t.dat[k][19];
			}
		}
	},

	show: function (init) {
		var t = Tabs.Search;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
	},
};

/**************************** Spells Tab ****************************************/

Tabs.Spells = {
	tabLabel: 'Spells',
	tabOrder: 2100,
	tabColor : 'brown',
	myDiv: null,
	timer: null,
	LoopCounter: 0,
	intervalSecs  : 2,
	autodelay : 0,
	Squire:0,
	Knight:0,
	Guinevere:0,
	Morgana:0,
	Arthur:0,
	Merlin:0,
	Divine:0,
	Epic:0,
	Legendary:0,
	ItemList : [1, 2, 3, 4, 5, 6, 7, 8, 10],
	ItemTrans : ["SH","KH","GH","MH","AH","RH","DH","EH","LH"],
	Options: {
		Running: false,
		Enabled : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
		UseLH : false,
		UseEH : false,
		UseDH : false,
		UseRH : false,
		UseAH : false,
		UseMH : false,
		UseGH : false,
		UseKH : false,
		UseSH : false,
		UseOverride : false,
		OverrideItem : 0,
		OverrideHours : 0,
		OverrideMinutes : 1,
		Toggle : false,
	},

	init: function (div) {
		var t = Tabs.Spells;
        t.myDiv = div;

		if (!Options.SpellOptions) {
			Options.SpellOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.SpellOptions.hasOwnProperty(y)) {
					Options.SpellOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('speedupSpell', Tabs.Spells.speedupSpell);

		if (Options.SpellOptions.Toggle) AddSubTabLink('AutoSpell',t.toggleAutoSpellState, 'SpellToggleTab');
		SetToggleButtonState('Spell',Options.SpellOptions.Running,'Spell');

		var m = '<DIV class=divHeader align=center>'+tx('BATTLE SPELLS')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btSpellToggle type=checkbox '+ (Options.SpellOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoSpellState type=submit value="'+tx("AutoSpell")+' = '+ (Options.SpellOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>&nbsp;</td></tr></table>';

		m += '<br><DIV id=btSpellOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';

		m += '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td width=40>&nbsp;</td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btSpellCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}
		m += "<td>&nbsp;</td>"; // spacer
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Active')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btSpellAutoCity_'+i+'" type=checkbox '+(Options.SpellOptions.Enabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right><b>'+uW.g_js_strings.commonstr.faction+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btSpellFactionCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Battle Spell')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btSpellNameCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+uW.g_js_strings.commonstr.status+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:60px;"><span id="btSpellStatusCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr></table></div></div>';

		m += '<div class="divHeader" align="center">'+tx('USE AUTO-SPEEDUPS')+'</div>';

		m += '<table width=100% class=xtab><tr><td><div align=center>';

		var Boosts = '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'\n'+tx(HourGlassHint[i])+'" /></td><td>(<span id=pbspellUse'+t.ItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '<td width=70 rowspan=2 align=right><INPUT id=pbSpellHelp type=submit value="'+tx('HELP')+'!"></td>';
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbspell'+t.ItemTrans[i]+'" '+(Options.SpellOptions["Use"+t.ItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr></table></td></tr>';
        Boosts += '<tr><td><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td><input type=checkbox id=pbspellOV ' + (Options.SpellOptions.UseOverride ? "CHECKED" : "") + '>'+tx('Override above by always using')+' '+htmlSelector(HourGlassName,Options.SpellOptions.OverrideItem, 'id=pbspellOVItem') + ' '+tx('when more than')+' ';
		Boosts += '<INPUT style="width: 30px;text-align:right;" id="pbspellOVHours" type=text maxlength=4 value="'+Options.SpellOptions.OverrideHours+'">&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT style="width: 30px;text-align:right;" id="pbspellOVMinutes" type=text maxlength=4 value="'+Options.SpellOptions.OverrideMinutes+'">&nbsp;'+uW.g_js_strings.timestr.timemin+' '+tx('remaining')+'.</td></tr></table></div></td></tr>';

		m += Boosts+'</table></div><br>';

		div.innerHTML = m;

		for (var i = 1; i <= Cities.numCities; i++) {
			ById('btSpellAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.SpellOptions.Enabled[citynum] = e.target.checked;
				if (Options.SpellOptions.Enabled[citynum]) {
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
		}

		ToggleOption('SpellOptions','btSpellToggle','Toggle');

		ToggleOption('SpellOptions','pbspellSH','UseSH');
		ToggleOption('SpellOptions','pbspellKH','UseKH');
		ToggleOption('SpellOptions','pbspellGH','UseGH');
		ToggleOption('SpellOptions','pbspellMH','UseMH');
		ToggleOption('SpellOptions','pbspellAH','UseAH');
		ToggleOption('SpellOptions','pbspellRH','UseRH');
		ToggleOption('SpellOptions','pbspellDH','UseDH');
		ToggleOption('SpellOptions','pbspellEH','UseEH');
		ToggleOption('SpellOptions','pbspellLH','UseLH');
		ToggleOption('SpellOptions','pbspellOV','UseOverride');
		ChangeIntegerOption('SpellOptions','pbspellOVItem','OverrideItem');
		ChangeIntegerOption('SpellOptions','pbspellOVHours','OverrideHours');
		ChangeIntegerOption('SpellOptions','pbspellOVMinutes','OverrideMinutes');

		ById ('pbSpellHelp').addEventListener ('click', t.helpPop, false);

		ById('btAutoSpellState').addEventListener('click', function(){
			t.toggleAutoSpellState(this);
		}, false);

		// start autocraft loop timer to start in 15 seconds...

		if (Options.SpellOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, (15 * 1000));
		}
	},

	toggleAutoSpellState: function(obj){
		var t = Tabs.Spells;
		obj = ById('btAutoSpellState');
		if (Options.SpellOptions.Running == true) {
			Options.SpellOptions.Running = false;
			obj.value = tx("AutoSpell = OFF");
		}
		else {
			Options.SpellOptions.Running = true;
			obj.value = tx("AutoSpell = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Spell',Options.SpellOptions.Running,'Spell');
		t.PaintOverview();
	},

	show: function (init) {
		var t = Tabs.Spells;
		t.PaintOverview();
	},

	helpPop : function (){
		var t = Tabs.Spells;
		var helpText = '<br>'+tx("Using Speedups for Spells");
		helpText += '<p>'+tx('Speedups will be used in the following order if they are selected, and the required criteria is met')+' :-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+uW.g_js_strings.commonstr.item+'</b></td><TD><b>'+uW.g_js_strings.commonstr.time+'</b></td><TD><b>'+tx('Criteria')+'</b></td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i10.name+'</td><TD>4 days</td><TD>'+tx('More than 3 days and 12 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i8.name+'</td><TD>2.5 days</td><TD>'+tx('More than 48 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i7.name+'</td><TD>24 hrs</td><TD>'+tx('More than 23 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i6.name+'</td><TD>15 hrs</td><TD>'+tx('More than 14 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i5.name+'</td><TD>8 hrs</td><TD>'+tx('More than 7 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i4.name+'</td><TD>2.5 hrs</td><TD>'+tx('More than 2 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i3.name+'</td><TD>1 hr</td><TD>'+tx('More than 45 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i2.name+'</td><TD>15 mins</td><TD>'+tx('More than 5 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i1.name+'</td><TD>1 min</td><TD>'+tx('More than 30 seconds remaining')+'</td></tr>';
		helpText += '</table>';
		helpText += '<p>'+tx('If the override box is ticked, then the override rule specified will take priority')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 360, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Speedups")+'</b></center>';
		pop.show (true);
	},

	EverySecond : function () {
		var t = Tabs.Spells;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh overview display every 2 seconds
			if (tabManager.currentTab.name == 'Spells' && Options.btWinIsOpen){ t.PaintOverview(); }
		}
	},

	PaintOverview : function () {
		var t = Tabs.Spells;

		t.Squire = parseIntNan(Seed.items.i1);
		t.Knight = parseIntNan(Seed.items.i2);
		t.Guinevere = parseIntNan(Seed.items.i3);
		t.Morgana = parseIntNan(Seed.items.i4);
		t.Arthur = parseIntNan(Seed.items.i5);
		t.Merlin = parseIntNan(Seed.items.i6);
		t.Divine = parseIntNan(Seed.items.i7);
		t.Epic = parseIntNan(Seed.items.i8);
		t.Legendary = parseIntNan(Seed.items.i10);

		ById('pbspellUseSHLabel').innerHTML = t.Squire;
		ById('pbspellUseKHLabel').innerHTML = t.Knight;
		ById('pbspellUseGHLabel').innerHTML = t.Guinevere;
		ById('pbspellUseMHLabel').innerHTML = t.Morgana;
		ById('pbspellUseAHLabel').innerHTML = t.Arthur;
		ById('pbspellUseRHLabel').innerHTML = t.Merlin;
		ById('pbspellUseDHLabel').innerHTML = t.Divine;
		ById('pbspellUseEHLabel').innerHTML = t.Epic;
		ById('pbspellUseLHLabel').innerHTML = t.Legendary;

		var now = unixTime();
		var q;

		for (var i = 0; i < Cities.numCities; i++) {
			citynum = i+1;
			cityId = Cities.cities[i].id;

			var spells = getSpellData(cityId);
			var faction = spells.faction;

			var SpellName = 'none';
			var SpellActivity = 'n/a';
			if (spells.spellavailable) {
				SpellName = '<span class=boldMagenta>'+eval("uW.g_js_strings.spells.name_"+SpellTypes[faction])+'</span>';
				var spellstyle = 'color:#080;';
				SpellActivity = '<span style="'+spellstyle+'"><b>'+tx('Ready')+'!</b></span>';

				if (spells.cooldownactive) {
					spellstyle = 'color:#800;';
					SpellActivity = '<b><span id=CoolTime style="'+spellstyle+'">'+spells.cooldown+'</span></b>';

					var Speedups = '';
					Speedups += t.paintSpeedup(cityId, faction, 1, t.Squire, '1 min');
					Speedups += t.paintSpeedup(cityId, faction, 2, t.Knight, '15 mins');
					Speedups += t.paintSpeedup(cityId, faction, 3, t.Guinevere, '60 mins');
					Speedups += t.paintSpeedup(cityId, faction, 4, t.Morgana, '150 mins');
					Speedups += t.paintSpeedup(cityId, faction, 5, t.Arthur, '8 hours');
					Speedups += '</tr><tr>';
					Speedups += t.paintSpeedup(cityId, faction, 6, t.Merlin, '15 hours');
					if (Speedups != "") Speedups = "<table align=left cellspacing=0 cellpadding=0><tr>" + Speedups + "</tr></table>";
					SpellActivity = SpellActivity+'<div>'+Speedups+'</div>';
				}
			}

			var CityFaction = tx('Not ascended');
			var ascended = getAscensionValues(cityId);
			if (faction != 0) {
				CityFaction = getFactionName(faction) + '&nbsp('+ascended.prestigeLevel+')';
			}

			ById("btSpellFactionCity_"+citynum).innerHTML = CityFaction;
			ById("btSpellNameCity_"+citynum).innerHTML = SpellName;
			ById("btSpellStatusCity_"+citynum).innerHTML = SpellActivity;
		}
	},

	paintSpeedup : function (cityId, faction, item, count, hint) {
		var t = Tabs.Spells;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px"><a onClick="speedupSpell('+cityId+', '+item+', '+SpellTypes[faction]+')"><img height=18 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+tx(hint)+') ('+count+')"></a></td>';
		}
		return n;
	},

	doAutoLoop : function (idx) {
		var t = Tabs.Spells;
		clearTimeout(t.timer);
		if (!Options.SpellOptions.Running) return;

		var cityId = Cities.cities[idx-1].id;
		if (idx==1) { t.loopaction = false; } // reset loop action indicator for first city
		t.autodelay = 0; // no delay if no action taken!

		// check spell status and speedup if on cooldown

		var spells = getSpellData(cityId);
		var faction = spells.faction;
		if (spells.spellavailable && spells.cooldownactive) {
			t.autoSpeedup (cityId,SpellTypes[faction]);
		}

		if (idx == Cities.numCities) {
			if (!t.loopaction) { t.autodelay = t.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(1); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1); }, (t.autodelay * 1000));
		}
	},

    autoSpeedup: function (cityId,spell) {
		var t = Tabs.Spells;
		var now = unixTime();
		var item = 0;
		totTime = parseInt(Seed.cityData.city[cityId].spells[spell].endDate) - now;

		if (totTime > 0) {
			if (Options.SpellOptions.UseOverride && Options.SpellOptions.OverrideItem != 0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.SpellOptions.OverrideMinutes)*60)+(parseIntNan(Options.SpellOptions.OverrideHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && uW.ksoItems[Options.SpellOptions.OverrideItem].count > 0) { item = Options.SpellOptions.OverrideItem; }
			}
            if (item==0 && totTime >= HourGlassThreshold[8] && Options.SpellOptions.UseLH && uW.ksoItems[10].count > 0) { item = 10; }
            if (item==0 && totTime >= HourGlassThreshold[7] && Options.SpellOptions.UseEH && uW.ksoItems[8].count > 0) { item = 8; }
            if (item==0 && totTime >= HourGlassThreshold[6] && Options.SpellOptions.UseDH && uW.ksoItems[7].count > 0) { item = 7; }
            if (item==0 && totTime >= HourGlassThreshold[5] && Options.SpellOptions.UseRH && uW.ksoItems[6].count > 0) { item = 6; }
            if (item==0 && totTime >= HourGlassThreshold[4] && Options.SpellOptions.UseAH && uW.ksoItems[5].count > 0) { item = 5; }
            if (item==0 && totTime >= HourGlassThreshold[3] && Options.SpellOptions.UseMH && uW.ksoItems[4].count > 0) { item = 4; }
            if (item==0 && totTime >= HourGlassThreshold[2] && Options.SpellOptions.UseGH && uW.ksoItems[3].count > 0) { item = 3; }
            if (item==0 && totTime >= HourGlassThreshold[1] && Options.SpellOptions.UseKH && uW.ksoItems[2].count > 0) { item = 2; }
            if (item==0 && totTime >= HourGlassThreshold[0] && Options.SpellOptions.UseSH && uW.ksoItems[1].count > 0) { item = 1; }
        }

		if (item != 0) {
			t.autodelay = t.intervalSecs;
			t.loopaction = true;
			t.speedupSpell(cityId,item,spell);
		}
    },

	speedupSpell : function (cityId,item,spell) {
		var t = Tabs.Spells;

		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btSpellCity_'+citynum).css('color', 'magenta');
		var params = uW.Object.clone(uW.g_ajaxparams);
  		params.cid = cityId;
  		params.iid = item;
  		params.sid = spell;
  		params.apothecary = false;

  		new MyAjaxRequest(uW.g_ajaxpath + "ajax/speedupBattleSpellCooldown.php" + uW.g_ajaxsuffix, {
  			method: "post",
  			parameters: params,
  			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (rslt.endDate) {
						Seed.cityData.city[cityId].spells = {};
						Seed.cityData.city[cityId].spells[spell] = { endDate : rslt.endDate };
					}
					Seed.items["i"+item] = Number(parseInt(Seed.items["i"+item])-1);
					uW.ksoItems[item].subtract();
					if (cityId == uW.currentcityid) uW.update_queue();
					if (ById('QMSpell')) QuickMarch.BuildSpellSelect();
					actionLog(Cities.byID[cityId].name+': Spell cooldown speedup applied','SPELLS');
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Spell cooldown speedup failed ('+rslt.msg+')','SPELLS');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Spell cooldown speedup failed ('+rslt.error_code+')','SPELLS');
					}
				}
				jQuery('#btSpellCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
  			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Spell cooldown speedup failed (AJAX Error)','SPELLS');
				jQuery('#btSpellCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
  		},true);
	},
}

/*********************************** Transport Tab ***********************************/

Tabs.Transport = {
	tabOrder: 2030,
	tabLabel : 'Transport',
	tabColor : 'brown',
	myDiv : null,
	dcp0 : null,
	dcp1 : null,
	timer : null,
	autodelay : 0,
	loopaction : false,
	marchspeed : 0,
	LoopCounter : 0,
	EditRouteNumber : -1,
	EditMode : false,
	LoadSac : '',
	Options : {
		Running: false,
		Toggle : false,
		Routes : [],
		TransportInterval : 10,
		intervalSecs  : 5,
		MinWagons : 100,
		ReverseTransport : false,
		ReverseTransportPercent : 90,
		ThroneCheck: false,
		MarchSpeed: 0,
		Priority: "1,4,5,3,2", // food, ore, aether, stone, wood
	},
	NewRouteObject : {
		cityId: null,
		target_x: '',
		target_y: '',
		target_cityId: null,
		TroopType: 9,
		ship_Gold: false,
		ship_Food: false,
		ship_Wood: false,
		ship_Stone: false,
		ship_Ore: false,
		ship_Aether: false,
		keep_Gold: 0,
		keep_Food: 0,
		keep_Wood: 0,
		keep_Stone: 0,
		keep_Ore: 0,
		keep_Aether: 0,
		trade_Gold: 0,
		trade_Food: 0,
		trade_Wood: 0,
		trade_Stone: 0,
		trade_Ore: 0,
		trade_Aether: 0,
		Active: true,
		OverrideTime: false,
		Interval : 10,
		LastChecked : 0,
	},
	RouteObject : null,

	init : function (div) {
		var t = Tabs.Transport;
		t.myDiv = div;

		if (!Options.TransportOptions) {
			Options.TransportOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.TransportOptions.hasOwnProperty(y)) {
					Options.TransportOptions[y] = t.Options[y];
				}
			}
		}
		t.checkcitymoved();

		uWExportFunction ('pbtrDeleteRoute', Tabs.Transport.DeleteRoute);
		uWExportFunction ('pbtrEditRoute', Tabs.Transport.EditRoute);
		uWExportFunction ('pbtrSendRoute', Tabs.Transport.SendRoute);
		uWExportFunction ('pbtrToggleActive', Tabs.Transport.ToggleActive);

		if (Options.TransportOptions.Toggle) AddSubTabLink('Transport',t.toggleAutoTransportState, 'TransportToggleTab');
		SetToggleButtonState('Transport',Options.TransportOptions.Running,'Transport');

		var m = '<DIV class=divHeader align=center>'+tx('AUTOMATED TRANSPORT')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btTransportToggle type=checkbox '+ (Options.TransportOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoTransportState type=submit value="'+tx("Transport")+' = '+ (Options.TransportOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>'+tx('Current Transport Speed')+':&nbsp;<span id=bttrMarchCurrTR></span>&nbsp;&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td align=left><INPUT id=bttrMarchTR type=checkbox '+(Options.TransportOptions.ThroneCheck?'CHECKED':'')+'></td><td>'+tx('Only transport when march speed for transports is at least')+' <INPUT id=bttrMarchTRSpeed type=text size=3 maxlength=4 value="'+ Options.TransportOptions.MarchSpeed +'">&nbsp;%</td><td align=right>&nbsp;'+tx("Check routes every:")+'&nbsp;<INPUT id=pbtransportinterval type=text size=2 value="' + Options.TransportOptions.TransportInterval+'"\> '+tx("minutes")+'</td></tr>';
        m += '<tr><td>&nbsp;</td><td>'+tx("Do not march if less than")+' <INPUT id=pbminwagons type=text size=6 value="' + Options.TransportOptions.MinWagons+'"\> '+tx("troops are needed. (Avoids needless transports)")+'</td><td align=right>&nbsp;'+tx("March Interval:")+'&nbsp;<INPUT id=pbtmarchinterval type=text size=2 value="' + Options.TransportOptions.intervalSecs+'"\> '+tx("seconds")+'</td></tr>';
        m += '<tr><td><INPUT id=pbrevtrans type=checkbox '+(Options.TransportOptions.ReverseTransport?'CHECKED':'')+'></td><td>'+tx('Reverse transport if resource amount falls below')+' <INPUT id=pbrevtranspc type=text size=2 value="'+Options.TransportOptions.ReverseTransportPercent+'"\> % '+tx('of the Keep value')+'.</td><td align=right>&nbsp;'+tx("Transport Priority:")+'&nbsp;'+htmlSelector({"1,4,5,3,2": uW.g_js_strings.commonstr.food, "4,1,5,3,2": uW.g_js_strings.commonstr.ore}, Options.TransportOptions.Priority, 'id=pbtPriority')+'</td></tr></table>';
		m += '<div id=pbtrMessages align=center>&nbsp;</div>';
		m += '<div id=pbtrRouteDetail>&nbsp;</div><br>';

		div.innerHTML = m;

		ToggleOption('TransportOptions','btTransportToggle','Toggle');

		ById('btAutoTransportState').addEventListener('click', function(){
			t.toggleAutoTransportState(this);
		}, false);

        ById('pbtransportinterval').addEventListener('keyup', function () {
            if (isNaN(ById('pbtransportinterval').value)) { ById('pbtransportinterval').value = 60; }
            Options.TransportOptions.TransportInterval = ById('pbtransportinterval').value;
            saveOptions();
        }, false);
        ById('pbtmarchinterval').addEventListener('keyup', function () {
            if (parseIntNan(ById('pbtmarchinterval').value)<1) { ById('pbtmarchinterval').value = 5; }
            if (parseIntNan(ById('pbtmarchinterval').value)<2) { ById('pbtmarchinterval').value = 2; }
            Options.TransportOptions.intervalSecs = parseIntNan(ById('pbtmarchinterval').value);
            saveOptions();
        }, false);
		ById('pbtPriority').addEventListener('change', function() {
			Options.TransportOptions.Priority = ById('pbtPriority').value;
			saveOptions();
		}, false);
		ById('pbrevtrans').addEventListener('change', function(){
			Options.TransportOptions.ReverseTransport = ById('pbrevtrans').checked;
			saveOptions();
		}, false);
        ById('pbrevtranspc').addEventListener('keyup', function () {
            if (isNaN(ById('pbrevtranspc').value)) { ById('pbrevtranspc').value = 0; }
            Options.TransportOptions.ReverseTransportPercent = ById('pbrevtranspc').value;
            saveOptions();
        }, false);
        ById('pbminwagons').addEventListener('keyup', function () {
            if (isNaN(ById('pbminwagons').value)) { ById('pbminwagons').value = 100; }
            Options.TransportOptions.MinWagons = ById('pbminwagons').value;
            saveOptions();
        }, false)
		ById('bttrMarchTR').addEventListener ('change', function() {
			Options.TransportOptions.ThroneCheck = this.checked;
			saveOptions();
        }, false);
		ById('bttrMarchTRSpeed').addEventListener ('change', function() {
			Options.TransportOptions.MarchSpeed = parseIntNan(this.value);
			saveOptions();
        }, false);

		t.PaintRoutes();

		// start autotransport loop timer to start in 10 seconds...

		if (Options.TransportOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, (10 * 1000));
		}
	},

	toggleAutoTransportState: function(obj){
		var t = Tabs.Transport;
		obj = ById('btAutoTransportState');
		if (Options.TransportOptions.Running == true) {
			Options.TransportOptions.Running = false;
			obj.value = tx("Transport = OFF");
			clearTimeout(t.timer);
		}
		else {
			Options.TransportOptions.Running = true;
			obj.value = tx("Transport = ON");
			// clear the last checked field on all routes
			var n = Options.TransportOptions.Routes.length;
			while (n--) {
				Options.TransportOptions.Routes[n].LastChecked = 0;
			}
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Transport',Options.TransportOptions.Running,'Transport');
	},

	checkcitymoved: function () {
		var t = Tabs.Transport;
		for (var i = 0; i < Options.TransportOptions.Routes.length; i++) {
			if (parseIntNan(Options.TransportOptions.Routes[i].target_cityId) != 0 && Cities.byID[Options.TransportOptions.Routes[i].target_cityId]) {
				Options.TransportOptions.Routes[i].target_x = Cities.byID[Options.TransportOptions.Routes[i].target_cityId].x;
				Options.TransportOptions.Routes[i].target_y = Cities.byID[Options.TransportOptions.Routes[i].target_cityId].y;
			}
        }
		saveOptions();
	},

	ClearRoutes : function() {
		var t = Tabs.Transport;
		Options.TransportOptions.Routes = [];
		saveOptions();
		ById('pbtrMessages').innerHTML = tx("All transport routes deleted")+"!";
		t.PaintRoutes();
	},

	PaintRoutes : function () {
		var t = Tabs.Transport;

		t.EditMode = false;
		var z = '';
		var r = 0;

		var bclass = "blue14";
		var btext  = "Clear Routes";
		var Routes = false;

		var z= '<div class=divHeader align=center>'+tx('TRANSPORT ROUTES')+'</div><br>';
		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td width=90px>'+strButton20(tx('New Route'), 'id=pbtrNewRoute')+'</td>';
		z += '<td align=left id=pbtrbulkactions>&nbsp;</td>';
		z += '<td align=right>'+strButton20(tx('Delete ALL Routes'), 'id=pbtrClearRoutes')+'&nbsp;</td></tr></table>';
		z += '<div style="max-height:535px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px";overflow-x:auto" align="center"><TABLE id=pbtrRoutesTable cellSpacing=0 width=100% height=0%><tr><td class="xtabHD" style="width:100px"><b>'+tx('Source')+'</b></td><td style="width:100px" class="xtabHD"><b>'+tx('Destination')+'</b></td><td style="width:100px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.resources+'</b></td><td class="xtabHD" align="center" style="width:90px"><b>'+tx('Active')+'</b></td><td class="xtabHD" align="right" style="width: 115px"><span id=pbtrnumroutes>'+Options.TransportOptions.Routes.length+'</span> '+tx('Routes')+'</td></tr>';

		var FromList = {0:"-- "+tx('Select City')+" --"};
		var BulkAction = {0:"-- "+tx('Select Action')+" --",1:tx("Delete ALL Marches From"),2:tx("Delete ALL Marches To"),3:tx("Transfer ALL Marches From"),4:tx("Transfer ALL Marches To"),5:tx("Disable ALL Marches From"),6:tx("Disable ALL Marches To"),7:tx("Enable ALL Marches From"),8:tx("Enable ALL Marches To")};
		var CityList = {0:"-- "+tx('Select City')+" --"};
		for (g in Cities.byID) { CityList[Cities.byID[g].id] = Cities.byID[g].name; }

		var n = Options.TransportOptions.Routes.length;
		while (n--) {
			var a = Options.TransportOptions.Routes[n];
			var fid = -1;
			var fromname = '<span class=boldRed>'+tx('No City')+'!</span>';
			if (Cities.byID[a.cityId]) { fromname = Cities.byID[a.cityId].name; fid = a.cityId; }
			FromList[fid] = fromname;
			var toname = '<span class=boldRed>'+tx('No City')+'!</span>';
			if (a.target_cityId != 0) {
				var fid = -1;
				if (Cities.byID[a.target_cityId]) { toname = Cities.byID[a.target_cityId].name; fid = a.target_cityId; }
				FromList[fid] = toname;
			}
			else {
				toname = coordLink(a.target_x,a.target_y);
			}

			Routes = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:100px" class=xtab valign=top>'+fromname+'</td>';
			z += '<TD style="width:100px" class=xtab valign=top>'+toname+'</td>';
			z += '<TD style="width:100px" class=xtab valign=top>'+uW.unitcost['unt'+a.TroopType][0]+'</td>';

			var zz = '<table cellpadding=0 cellspacing=0 class=xtab>';
            if (a.ship_Food) {
				zz += '<TR><TD width=30px>'+ResourceImage(FoodImage,uW.g_js_strings.commonstr.food)+'</td>';
				if (parseIntNan(a.keep_Food)!=0 || parseIntNan(a.trade_Food)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Food)+'</td>'; }
				if (parseIntNan(a.trade_Food)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Food)+'</td>'; }
				zz += '</tr>';
			}
            if (a.ship_Wood) {
				zz += '<TR><TD width=30px>'+ResourceImage(WoodImage,uW.g_js_strings.commonstr.wood)+'</td>';
				if (parseIntNan(a.keep_Wood)!=0 || parseIntNan(a.trade_Wood)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Wood)+'</td>'; }
				if (parseIntNan(a.trade_Wood)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Wood)+'</td>'; }
				zz += '</tr>';
			}
            if (a.ship_Stone) {
				zz += '<TR><TD width=30px>'+ResourceImage(StoneImage,uW.g_js_strings.commonstr.stone)+'</td>';
				if (parseIntNan(a.keep_Stone)!=0 || parseIntNan(a.trade_Stone)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Stone)+'</td>'; }
				if (parseIntNan(a.trade_Stone)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Stone)+'</td>'; }
				zz += '</tr>';
			}
            if (a.ship_Ore) {
				zz += '<TR><TD width=30px>'+ResourceImage(OreImage,uW.g_js_strings.commonstr.ore)+'</td>';
				if (parseIntNan(a.keep_Ore)!=0 || parseIntNan(a.trade_Ore)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Ore)+'</td>'; }
				if (parseIntNan(a.trade_Ore)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Ore)+'</td>'; }
				zz += '</tr>';
			}
            if (a.ship_Aether) {
				zz += '<TR><TD width=30px>'+ResourceImage(AetherImage,uW.g_js_strings.commonstr.aetherstone)+'</td>';
				if (parseIntNan(a.keep_Aether)!=0 || parseIntNan(a.trade_Aether)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Aether)+'</td>'; }
				if (parseIntNan(a.trade_Aether)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Aether)+'</td>'; }
				zz += '</tr>';
			}
            if (a.ship_Gold) {
				zz += '<TR><TD width=30px>'+ResourceImage(GoldImage,uW.g_js_strings.commonstr.gold)+'</td>';
				if (parseIntNan(a.keep_Gold)!=0 || parseIntNan(a.trade_Gold)==0) { zz += '<TD width=175px>'+tx("Keep")+':&nbsp;'+addCommas(a.keep_Gold)+'</td>'; }
				if (parseIntNan(a.trade_Gold)!=0) { zz += '<TD width=175px>'+tx("Trade")+':&nbsp;'+addCommas(a.trade_Gold)+'</td>'; }
				zz += '</tr>';
			}
			zz += '</table><br>'

			z += '<TD class=xtabBRTop>'+zz+'</td>';
			z += '<TD style="width:90px" class=xtab align=center valign=top><INPUT id="pbtrRouteActive'+n+'" type=checkbox '+(a.Active?'CHECKED':'')+' onclick="pbtrToggleActive('+n+')" /><div id="pbtrRouteStatus'+n+'"><span><br><br></span><//div></td>';
			z += '<TD style="width:100px" class=xtab align=right valign=top><a id="pbtrRouteEdit'+n+'" class="inlineButton btButton brown8" onclick="pbtrEditRoute('+n+')"><span>Edit</span></a>&nbsp;<a id="pbtrRouteDelete'+n+'" class="inlineButton btButton brown8" onclick="pbtrDeleteRoute('+n+')"><span>Del</span></a></a></td>';
			z += '</tr>';
		}

		if (!Routes) {
			z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No transport routes')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		ById('pbtrRouteDetail').innerHTML = z;
		ById('pbtrbulkactions').innerHTML = tx("Bulk Action")+":&nbsp;"+htmlSelector(BulkAction,0,'class=btInput id=pbtrbulkaction')+'&nbsp;'+htmlSelector(FromList,0,'class=btInput id=pbtrbulkfrom')+'&nbsp;<span id=pbtrbulknew class=divHide>To&nbsp;'+htmlSelector(CityList,0,'class=btInput id=pbtrbulkto')+'</span>&nbsp;'+strButton8(tx('Go'),'id=pbtrbulkgo');

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('pbtrbulkgo').addEventListener('click', function(){t.DoBulkAction(ById('pbtrbulkaction').value,ById('pbtrbulkfrom').value,ById('pbtrbulkto').value);}, false);
		ById('pbtrbulkaction').addEventListener('change', function(e){
			if (e.target.value==3 || e.target.value==4) { jQuery('#pbtrbulknew').removeClass("divHide"); }
			else { jQuery('#pbtrbulknew').addClass("divHide"); }
		}, false);

		ById('pbtrClearRoutes').addEventListener ('click', function() {t.ClearRoutes();}, false);
		ById('pbtrNewRoute').addEventListener ('click', function() {t.NewRoute();}, false);
		t.updateRoutes();
	},

	DoBulkAction : function (Action,From,To) {
		var t = Tabs.Transport;
		ById('pbtrMessages').innerHTML = "&nbsp;";
		if (Action==0 || From==0) return;
		if ((Action==3 || Action==4) && To==0) return;
		for (var i=Number(Options.TransportOptions.Routes.length-1); i>-1 ;i--) {
			if (Action==1 || Action==3 || Action==5 || Action==7) {
				if ((Options.TransportOptions.Routes[i].cityId == From) || (From==-1 && !Cities.byID[Options.TransportOptions.Routes[i].cityId])) {
					if (Action==1) { Options.TransportOptions.Routes.splice(i,1); }
					else {
						if (Action==3) { Options.TransportOptions.Routes[i].cityId = To; }
						else {
							if (Action==5) { Options.TransportOptions.Routes[i].Active = false; }
							else {
								if (Action==7) { Options.TransportOptions.Routes[i].Active = true; }
							}
						}
					}
				}
			}
			if (Action==2 || Action==4 || Action==6 || Action==8) {
				if (parseIntNan(Options.TransportOptions.Routes[i].target_cityId) != 0) {
					if ((Options.TransportOptions.Routes[i].target_cityId == From) || (From==-1 && !Cities.byID[Options.TransportOptions.Routes[i].target_cityId])) {
						if (Action==2) { Options.TransportOptions.Routes.splice(i,1); }
						else {
							if (Action==4) {
								Options.TransportOptions.Routes[i].target_cityId = To;
								Options.TransportOptions.Routes[i].target_x = Cities.byID[To].x;
								Options.TransportOptions.Routes[i].target_y = Cities.byID[To].y;
							}
							else {
								if (Action==6) { Options.TransportOptions.Routes[i].Active = false; }
								else {
									if (Action==8) { Options.TransportOptions.Routes[i].Active = true; }
								}
							}
						}
					}
				}
			}
		}
		saveOptions();
		if (Action==1 || Action==2) { ById('pbtrMessages').innerHTML = "Transport routes deleted!"; }
		else {
			if (Action==3 || Action==4) { ById('pbtrMessages').innerHTML = "Transport routes relocated!"; }
		}
		t.PaintRoutes();
	},

	DeleteRoute : function (entry) {
		var t = Tabs.Transport;
		Options.TransportOptions.Routes.splice(entry,1);
		saveOptions();
		ById('pbtrMessages').innerHTML = "Transport route deleted!";
		t.PaintRoutes();
	},

	ToggleActive : function (entry) {
		var t = Tabs.Transport;
		Options.TransportOptions.Routes[entry].Active = !Options.TransportOptions.Routes[entry].Active;
		saveOptions();
		t.updateRoutes();
	},

	SendRoute : function (entry) {
		var t = Tabs.Transport;
		Options.TransportOptions.Routes[entry].LastChecked = 0;
		saveOptions();
		t.updateRoutes();
	},

	EditRoute : function (entry) {
		var t = Tabs.Transport;
		t.EditRouteNumber = entry;
		t.EditMode = true;
		ById('pbtrMessages').innerHTML = "&nbsp;";

		t.RouteObject = {};
		for (var y in Options.TransportOptions.Routes[t.EditRouteNumber]) {
			t.RouteObject[y] = Options.TransportOptions.Routes[t.EditRouteNumber][y];
		}
		if (!t.RouteObject.OverrideTime) {
			t.RouteObject.Interval = Options.TransportOptions.TransportInterval;
		}
		t.PaintNewRoutePanel();
	},

	NewRoute : function () {
		var t = Tabs.Transport;
		t.EditRouteNumber = -1;
		t.EditMode = true;
		ById('pbtrMessages').innerHTML = "&nbsp;";

		if (!t.RouteObject) {
			t.RouteObject = {};
			for (var y in t.NewRouteObject) {
				t.RouteObject[y] = t.NewRouteObject[y];
			}
			t.RouteObject.Interval = Options.TransportOptions.TransportInterval;
		}
		t.PaintNewRoutePanel();
	},

	show : function (){
		var t = Tabs.Transport;
		t.PaintOverview();
		if (t.EditMode) { t.updateResources(); }
		else { t.updateRoutes(); }
	},

	EverySecond : function () {
		var t = Tabs.Transport;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh transport march speed and overview display every 2 seconds
			t.marchspeed = Math.floor(equippedthronestats(67))+Math.floor(equippedthronestats(70)); // march speed is transport and general march speed added together
			if (tabManager.currentTab.name == 'Transport' && Options.btWinIsOpen){
				t.PaintOverview();

				if (t.EditMode) { // paint from and to city resources
					t.updateResources();
				}
				else { // paint time on each route?
					t.updateRoutes();
				}
			}
		}
	},

	PaintOverview : function () {
		var t = Tabs.Transport;

		if (Options.TransportOptions.ThroneCheck && (t.marchspeed < Number(Options.TransportOptions.MarchSpeed))) {
			ts = '<span class=boldRed><b>'+t.marchspeed+'%</b></span>';
		}
		else { ts = t.marchspeed+'%'; }
		ById("bttrMarchCurrTR").innerHTML = ts;
	},

	PaintNewRoutePanel : function () {
		var t = Tabs.Transport;
		var fromidx = null;
		var toidx = null;

		if (t.EditRouteNumber<0) {
			var z= '<div class=divHeader align=center>'+tx('NEW TRANSPORT ROUTE')+'</div><br>';
			fromidx = Cities.byID[uW.currentcityid].idx; // default new route from current city
		}
		else {
			var z= '<div class=divHeader align=center>'+tx('EDIT TRANSPORT ROUTE')+'</div><br>';
		}

		// remember last route details.... (or saved route details)

		if (Cities.byID[t.RouteObject.cityId]) {
			fromidx = Cities.byID[t.RouteObject.cityId].idx;
		}
		if (t.RouteObject.target_cityId != 0 && Cities.byID[t.RouteObject.target_cityId]) {
			toidx = Cities.byID[t.RouteObject.target_cityId].idx;
			t.RouteObject.target_x = Cities.byID[t.RouteObject.target_cityId].x;
			t.RouteObject.target_y = Cities.byID[t.RouteObject.target_cityId].y;
		}

		z += '<TABLE align=left class=xtab>';
		z += '<TR><TD align=right>&nbsp;'+tx("From City")+':&nbsp;</td><TD><span id=pbtfromcity></span></td></tr>';
		z += '<TR><TD align=right>&nbsp;'+tx("To City")+':&nbsp;</td><TD><span id=pbttocity></span></td>';
		z += '<TD>&nbsp;'+tx("or")+'&nbsp;&nbsp;&nbsp;X:&nbsp;<INPUT id=pbtcityX type=text size=3 value="'+t.RouteObject.target_x+'"\>&nbsp;Y:&nbsp;<INPUT id=pbtcityY type=text size=3 value="'+t.RouteObject.target_y+'"\>&nbsp;&nbsp;&nbsp;<a id=pbtFetchBookmarks>'+tx('Select Bookmark')+':</a></td><td><select id=pbtBookmarks class=btInput style="max-width:180px;"></select></td></tr>';
		z += '<TR><TD align=right>&nbsp;'+uW.g_js_strings.openCastle.trooptype+':&nbsp;</td><TD><SELECT id="pbttroops">';
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			z += '<option value='+i+'>'+uW.unitcost["unt"+i][0]+'</option>';
		}
		z += '</select></td><TD align=right>'+tx("Maximum March Size")+':&nbsp;</td><TD id=pbtmaxtroops>&nbsp;</td></tr>';
		z += '<TR><TD align=right>&nbsp;'+tx("Troop Count")+':&nbsp;</td><TD id=pbttotaltroops>&nbsp;</td><TD align=right>'+tx("Maximum Load")+':&nbsp;</td><TD id=pbtmaxload>&nbsp;</td></tr>';
		z += '<TR><TD align=right>&nbsp;</td><TD><INPUT id=pbtoverrideintervalchk type=checkbox '+(t.RouteObject.OverrideTime?'CHECKED':'')+'>&nbsp;'+tx('Override transport interval')+'</td><TD align=right>'+tx("Transport Interval")+':&nbsp;</td><TD><INPUT  id=pbtoverrideinterval type=text size=2 value="' + t.RouteObject.Interval+'" '+(t.RouteObject.OverrideTime?'':'disabled')+' \> '+tx("minutes")+'</td></tr>';
		z += '</table><br>';

		z += '<TABLE width=98% align=center class=xtab cellspacing=0><TR><th class=xtabHD align=center>'+tx('Resource')+'</th><th class=xtabHD align=right>'+tx('Source')+'</th><th class=xtabHD align=right>'+tx('Destination')+'</th><th class=xtabHD align=center>'+tx('Send')+'</th><th class=xtabHD align=left>'+tx('Keep')+'</th><th class=xtabHD align=left>'+tx('Trade')+'</th><th class=xtabHD align=left>&nbsp;</th></tr>';
		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+FoodImage+'" title="'+uW.g_js_strings.commonstr.food+'"></td>';
		z += '<TD id=pbtfromRec1 align=right width=110px></td>';
		z += '<TD id=pbttoRec1 align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipFood type=checkbox '+(t.RouteObject.ship_Food?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountFood type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Food+'" '+(t.RouteObject.ship_Food?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountFood type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Food+'" '+(t.RouteObject.ship_Food?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxFood type=submit value="Max" '+(t.RouteObject.ship_Food?'':'disabled')+' ></td></tr>';

		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+WoodImage+'" title="'+uW.g_js_strings.commonstr.wood+'"></td>';
		z += '<TD id=pbtfromRec2 align=right width=110px></td>';
		z += '<TD id=pbttoRec2 align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipWood type=checkbox '+(t.RouteObject.ship_Wood?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountWood type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Wood+'" '+(t.RouteObject.ship_Wood?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountWood type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Wood+'" '+(t.RouteObject.ship_Wood?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxWood type=submit value="Max" '+(t.RouteObject.ship_Wood?'':'disabled')+' ></td></tr>';

		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+StoneImage+'" title="'+uW.g_js_strings.commonstr.stone+'"></td>';
		z += '<TD id=pbtfromRec3 align=right width=110px></td>';
		z += '<TD id=pbttoRec3 align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipStone type=checkbox '+(t.RouteObject.ship_Stone?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountStone type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Stone+'" '+(t.RouteObject.ship_Stone?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountStone type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Stone+'" '+(t.RouteObject.ship_Stone?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxStone type=submit value="Max" '+(t.RouteObject.ship_Stone?'':'disabled')+' ></td></tr>';

		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+OreImage+'" title="'+uW.g_js_strings.commonstr.ore+'"></td>';
		z += '<TD id=pbtfromRec4 align=right width=110px></td>';
		z += '<TD id=pbttoRec4 align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipOre type=checkbox '+(t.RouteObject.ship_Ore?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountOre type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Ore+'" '+(t.RouteObject.ship_Ore?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountOre type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Ore+'" '+(t.RouteObject.ship_Ore?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxOre type=submit value="Max" '+(t.RouteObject.ship_Ore?'':'disabled')+' ></td></tr>';

		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+AetherImage+'" title="'+uW.g_js_strings.commonstr.aetherstone+'"></td>';
		z += '<TD id=pbtfromRec5 align=right width=110px></td>';
		z += '<TD id=pbttoRec5 align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipAether type=checkbox '+(t.RouteObject.ship_Aether?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountAether type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Aether+'" '+(t.RouteObject.ship_Aether?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountAether type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Aether+'" '+(t.RouteObject.ship_Aether?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxAether type=submit value="Max" '+(t.RouteObject.ship_Aether?'':'disabled')+' ></td></tr>';

		z += '<TR>';
		z += '<TD align=center width=5%><img src="'+GoldImage+'" title="'+uW.g_js_strings.commonstr.gold+'"></td>';
		z += '<TD id=pbtfromGold align=right width=110px></td>';
		z += '<TD id=pbttoGold align=right width=110px></td>';
		z += '<TD width=55px align=center><INPUT id=pbshipGold type=checkbox '+(t.RouteObject.ship_Gold?'CHECKED':'')+' \></td>';
		z += '<TD width=180px><INPUT id=pbtargetamountGold type=text size=11 maxlength=20 value="'+t.RouteObject.keep_Gold+'" '+(t.RouteObject.ship_Gold?'':'disabled')+' \></td>';
		z += '<TD width=100px><INPUT id=pbtradeamountGold type=text size=11 maxlength=20 value="'+t.RouteObject.trade_Gold+'" '+(t.RouteObject.ship_Gold?'':'disabled')+' \></td>';
		z += '<TD width=50px><INPUT id=pbMaxGold type=submit value="Max" '+(t.RouteObject.ship_Gold?'':'disabled')+' ></td></tr>';
		z += '</table><br>';

		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td>&nbsp;</td><td align=center>'+strButton20(tx('Save Route'), 'id=pbtrSaveRoute')+'&nbsp;';
		if (t.EditRouteNumber>=0) { z += strButton20(tx('Save a Copy'), 'id=pbtrCopyRoute')+'&nbsp;'; }
		z += strButton20(tx('Manual Transport'), 'id=pbtrManualTransport')+'&nbsp;'+strButton20(uW.g_js_strings.commonstr.cancel, 'id=pbtrCancelRoute')+'</td><td align=right>&nbsp;</td></tr></table></div>';

		ById('pbtrRouteDetail').innerHTML = z;

		ById('pbttroops').value = t.RouteObject.TroopType;
		t.dcp0 = new CdispCityPicker('pbttradefrom', ById('pbtfromcity'), true, t.updateResources, fromidx);
		t.dcp1 = new CdispCityPicker('pbttradeto', ById('pbttocity'), true, t.updateResources, toidx);
		t.dcp1.bindToXYboxes(ById('pbtcityX'), ById('pbtcityY'));

		ById('pbtFetchBookmarks').addEventListener('click', function () {
			FillBookmarkList('pbtBookmarks');
		},false);

		ById('pbtBookmarks').addEventListener('change', function () {
			if (this.value != '') {
				var val = this.value;
				var x = val.substr(0, val.lastIndexOf(','));
				var y = val.substr(val.lastIndexOf(',') + 1, val.length);
				ById('pbtcityX').value = x;
				ById('pbtcityY').value = y;
			}
		}, false);

		ById('pbttroops').addEventListener('change', function () {
			t.updateResources();
		}, false);

		ById('pbtoverrideintervalchk').addEventListener('click', function () {
			var disablerow = (!ById('pbtoverrideintervalchk').checked);
			ById('pbtoverrideinterval').disabled = disablerow;
			if (disablerow) {
				ById('pbtoverrideinterval').value = Options.TransportOptions.TransportInterval;
			}
		}, false);

		ById('pbtargetamountFood').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountFood').value)) ById('pbtargetamountFood').value = 0;
		}, false);
		ById('pbtargetamountWood').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountWood').value)) ById('pbtargetamountWood').value = 0;
		}, false);
		ById('pbtargetamountStone').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountStone').value)) ById('pbtargetamountStone').value = 0;
		}, false);
		ById('pbtargetamountOre').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountOre').value)) ById('pbtargetamountOre').value = 0;
		}, false);
		ById('pbtargetamountAether').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountAether').value)) ById('pbtargetamountAether').value = 0;
		}, false);
		ById('pbtargetamountGold').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtargetamountGold').value)) ById('pbtargetamountGold').value = 0;
		}, false);
		ById('pbtradeamountFood').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountFood').value)) ById('pbtradeamountFood').value = 0;
		}, false);
		ById('pbtradeamountWood').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountWood').value)) ById('pbtradeamountWood').value = 0;
		}, false);
		ById('pbtradeamountStone').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountStone').value)) ById('pbtradeamountStone').value = 0;
		}, false);
		ById('pbtradeamountOre').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountOre').value)) ById('pbtradeamountOre').value = 0;
		}, false);
		ById('pbtradeamountAether').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountAether').value)) ById('pbtradeamountAether').value = 0;
		}, false);
		ById('pbtradeamountGold').addEventListener('change', function () {
			if (isNaNCommas(ById('pbtradeamountGold').value)) ById('pbtradeamountGold').value = 0;
		}, false);

		ById('pbshipFood').addEventListener('click', function () {
			var disablerow = (!ById('pbshipFood').checked);
			ById('pbtargetamountFood').disabled = disablerow;
			ById('pbtradeamountFood').disabled = disablerow;
			ById('pbMaxFood').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountFood').value = 0;
				ById('pbtradeamountFood').value = 0;
			}
		}, false);
		ById('pbshipWood').addEventListener('click', function () {
			var disablerow = (!ById('pbshipWood').checked);
			ById('pbtargetamountWood').disabled = disablerow;
			ById('pbtradeamountWood').disabled = disablerow;
			ById('pbMaxWood').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountWood').value = 0;
				ById('pbtradeamountWood').value = 0;
			}
		}, false);
		ById('pbshipStone').addEventListener('click', function () {
			var disablerow = (!ById('pbshipStone').checked);
			ById('pbtargetamountStone').disabled = disablerow;
			ById('pbtradeamountStone').disabled = disablerow;
			ById('pbMaxStone').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountStone').value = 0;
				ById('pbtradeamountStone').value = 0;
			}
		}, false);
		ById('pbshipOre').addEventListener('click', function () {
			var disablerow = (!ById('pbshipOre').checked);
			ById('pbtargetamountOre').disabled = disablerow;
			ById('pbtradeamountOre').disabled = disablerow;
			ById('pbMaxOre').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountOre').value = 0;
				ById('pbtradeamountOre').value = 0;
			}
		}, false);
		ById('pbshipAether').addEventListener('click', function () {
			var disablerow = (!ById('pbshipAether').checked);
			ById('pbtargetamountAether').disabled = disablerow;
			ById('pbtradeamountAether').disabled = disablerow;
			ById('pbMaxAether').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountAether').value = 0;
				ById('pbtradeamountAether').value = 0;
			}
		}, false);
		ById('pbshipGold').addEventListener('click', function () {
			var disablerow = (!ById('pbshipGold').checked);
			ById('pbtargetamountGold').disabled = disablerow;
			ById('pbtradeamountGold').disabled = disablerow;
			ById('pbMaxGold').disabled = disablerow;
			if (disablerow) {
				ById('pbtargetamountGold').value = 0;
				ById('pbtradeamountGold').value = 0;
			}
		}, false);

		ById('pbMaxFood').addEventListener('click', function () {
			ById('pbtradeamountFood').value = t.CalcMaxResource('Food');
		}, false);
		ById('pbMaxWood').addEventListener('click', function () {
			ById('pbtradeamountWood').value = t.CalcMaxResource('Wood');
		}, false);
		ById('pbMaxStone').addEventListener('click', function () {
			ById('pbtradeamountStone').value = t.CalcMaxResource('Stone');
		}, false);
		ById('pbMaxOre').addEventListener('click', function () {
			ById('pbtradeamountOre').value = t.CalcMaxResource('Ore');
		}, false);
		ById('pbMaxAether').addEventListener('click', function () {
			ById('pbtradeamountAether').value = t.CalcMaxResource('Aether');
		}, false);
		ById('pbMaxGold').addEventListener('click', function () {
			ById('pbtradeamountGold').value = t.CalcMaxResource('Gold');
		}, false);

		ById('pbtrSaveRoute').addEventListener ('click', function() {t.SaveRoute(false);}, false);
		if (ById('pbtrCopyRoute')) { ById('pbtrCopyRoute').addEventListener ('click', function() {t.SaveRoute(true);}, false); }
		ById('pbtrCancelRoute').addEventListener ('click', function() {t.RouteObject = null; t.PaintRoutes();}, false);
		ById('pbtrManualTransport').addEventListener ('click', function() {t.ManualTransport();}, false);

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		t.updateResources();
	},

	SaveRoute : function (CopyRoute) {
		var t = Tabs.Transport;

		if (!t.validateScreenFields('save')) { return; }

		if (t.EditRouteNumber<0 || CopyRoute) {
			Options.TransportOptions.Routes.push(JSON2.parse(JSON2.stringify(t.RouteObject))); // create new object in array
			if (CopyRoute) { t.RouteObject = null; } // clear route object
		}
		else {
			t.RouteObject.LastChecked = 0;
			Options.TransportOptions.Routes[t.EditRouteNumber] = t.RouteObject;
			t.RouteObject = null; // clear route object
		}
		ById('pbtrMessages').innerHTML = "Transport route saved!";
		t.PaintRoutes();
	},

	validateScreenFields : function (action) {
		var t = Tabs.Transport;

		ById('pbtrMessages').innerHTML = "&nbsp;";

		if (!t.dcp0.city) {
			ById('pbtrMessages').innerHTML = "No source city selected";
			return false;
		}

		// copy screen fields to routeobject

		t.RouteObject.cityId = t.dcp0.city.id;
		var x = ById("pbtcityX").value;
		var y = ById("pbtcityY").value;
		if (x=="" || y=="" || isNaN(x) || isNaN(y) || x < 0 || x > 749 || y < 0 || y > 749) {
			ById('pbtrMessages').innerHTML = tx("Map co-ordinates must be between 0 and 749!");
			return false;
		}

		t.RouteObject.target_x = x;
		t.RouteObject.target_y = y;
		t.RouteObject.target_cityId = 0
		for (ii in Seed.cities) {
			if (Seed.cities[ii][2] == t.RouteObject.target_x && Seed.cities[ii][3] == t.RouteObject.target_y) { t.RouteObject.target_cityId = Seed.cities[ii][0]; }
		}
		t.RouteObject.TroopType = ById('pbttroops').value;
		t.RouteObject.ship_Gold = ById('pbshipGold').checked;
		t.RouteObject.ship_Food = ById('pbshipFood').checked;
		t.RouteObject.ship_Wood = ById('pbshipWood').checked;
		t.RouteObject.ship_Stone = ById('pbshipStone').checked;
		t.RouteObject.ship_Ore = ById('pbshipOre').checked;
		t.RouteObject.ship_Aether = ById('pbshipAether').checked;
		t.RouteObject.keep_Gold = ById('pbtargetamountGold').value;
		t.RouteObject.keep_Food = ById('pbtargetamountFood').value;
		t.RouteObject.keep_Wood = ById('pbtargetamountWood').value;
		t.RouteObject.keep_Stone = ById('pbtargetamountStone').value;
		t.RouteObject.keep_Ore = ById('pbtargetamountOre').value;
		t.RouteObject.keep_Aether = ById('pbtargetamountAether').value;
		t.RouteObject.trade_Gold = ById('pbtradeamountGold').value;
		t.RouteObject.trade_Food = ById('pbtradeamountFood').value;
		t.RouteObject.trade_Wood = ById('pbtradeamountWood').value;
		t.RouteObject.trade_Stone = ById('pbtradeamountStone').value;
		t.RouteObject.trade_Ore = ById('pbtradeamountOre').value;
		t.RouteObject.trade_Aether = ById('pbtradeamountAether').value;

		t.RouteObject.OverrideTime = ById('pbtoverrideintervalchk').checked;
		if (isNaN(ById('pbtoverrideinterval').value)) { t.RouteObject.Interval = 0; }
		else { t.RouteObject.Interval = ById('pbtoverrideinterval').value; }

		if (t.RouteObject.target_x=="" || t.RouteObject.target_y=="") {
			ById('pbtrMessages').innerHTML = tx("Destination coordinates invalid");
			return false;
		}
		if(t.dcp0.city.id==t.RouteObject.target_cityId){
			ById('pbtrMessages').innerHTML = tx("Cannot transport to the same city!");
			return false;
		}
		if (parseIntNan(t.RouteObject.TroopType)==0) {
			ById('pbtrMessages').innerHTML = tx("No troop type selected");
			return false;
		}
		if (!t.RouteObject.ship_Gold && !t.RouteObject.ship_Food && !t.RouteObject.ship_Wood && !t.RouteObject.ship_Stone && !t.RouteObject.ship_Ore && !t.RouteObject.ship_Aether) {
			ById('pbtrMessages').innerHTML = tx("You must transport something!");
			return false;
		}

		if (action=="send") {
			if (!t.RouteObject.trade_Gold && !t.RouteObject.trade_Food && !t.RouteObject.trade_Wood && !t.RouteObject.trade_Stone && !t.RouteObject.trade_Ore && !t.RouteObject.trade_Aether) {
				ById('pbtrMessages').innerHTML = tx("For manual transports you must enter the Trade values.");
				return false;
			}
		}

		// validation OK!
		return true;
	},

	updateResources : function () {
		var t = Tabs.Transport;
		if (!t.dcp0 || !t.dcp0.city) return;

		var ToCity = null;
		for (var i = 1; i <= 5; i++) {
			if (i==5) { ById('pbtfromRec'+i).innerHTML = addCommas(parseInt(Seed.resources["city" + t.dcp0.city.id]['rec' + i][0])); }
			else { ById('pbtfromRec'+i).innerHTML = addCommas(parseInt(Seed.resources["city" + t.dcp0.city.id]['rec' + i][0] / 3600)); }
		}
		ById('pbtfromGold').innerHTML = addCommas(parseInt(Seed.citystats["city" + t.dcp0.city.id]['gold'][0]));
		for (ii in Seed.cities) {
			if (Seed.cities[ii][2] == ById('pbtcityX').value && Seed.cities[ii][3] == ById('pbtcityY').value) { ToCity = Seed.cities[ii][0]; }
		}
        for (var i = 1; i <= 5; i++) {
			if (ToCity) {
				if (i==5) { ById('pbttoRec'+i).innerHTML = addCommas(parseInt(Seed.resources["city" + ToCity]['rec' + i][0])); }
				else { ById('pbttoRec'+i).innerHTML = addCommas(parseInt(Seed.resources["city" + ToCity]['rec' + i][0] / 3600)); }
			}
			else {
				ById('pbttoRec'+i).innerHTML = "----";
			}
		}
		if (ToCity) { ById('pbttoGold').innerHTML = addCommas(parseInt(Seed.citystats["city" + ToCity]['gold'][0])); }
		else { ById('pbttoGold').innerHTML = "----"; }

		// update troop and rally point information

		var Food = parseIntCommas(ById('pbtradeamountFood').value);
		var Wood = parseIntCommas(ById('pbtradeamountWood').value);
		var Stone = parseIntCommas(ById('pbtradeamountStone').value);
        var Ore = parseIntCommas(ById('pbtradeamountOre').value);
		var Gold = parseIntCommas(ById('pbtradeamountGold').value);
		var Aether = parseIntCommas(ById('pbtradeamountAether').value)*5;

		var unit = ById('pbttroops').value;
		var Troops = parseInt(Seed.units['city' + t.dcp0.city.id]["unt"+unit]);
        var LoadUnit = t.getLoadUnit(unit,t.dcp0.city.id);
		var MaxMarchSize = March.RallyPoint(t.dcp0.city.id).maxSize;
		if (MaxMarchSize < Troops) { var GlobalMaxLoad = MaxMarchSize * LoadUnit; }
		else { var GlobalMaxLoad = Troops * LoadUnit; }
		if (GlobalMaxLoad>0) GlobalMaxLoad = GlobalMaxLoad-1; // avoid max load problems

		var LoadSelected = Food+Wood+Stone+Ore+Gold+Aether;
		var TroopsNeeded = Math.ceil(LoadSelected/LoadUnit);

		var troopcolor = Options.Colors.PanelText;
        if (TroopsNeeded >= Troops || Troops==0) { troopcolor = '#f00'; }

		var marchcolor = Options.Colors.PanelText;
        if (TroopsNeeded >= MaxMarchSize) { marchcolor = '#f00'; }

		var loadcolor = Options.Colors.PanelText;
        if (GlobalMaxLoad < LoadSelected) { loadcolor = '#f00'; }

		ById('pbttotaltroops').innerHTML = '<FONT color='+troopcolor+'>'+addCommas(Troops)+'</font>';
		ById('pbtmaxtroops').innerHTML = '<FONT color='+marchcolor+'>'+addCommas(MaxMarchSize)+'</font>';
		ById('pbtmaxload').innerHTML = '<FONT color='+loadcolor+'>'+addCommas(GlobalMaxLoad)+'</font>'+t.LoadSac;
	},

	getLoadUnit : function (unit,cityId) {
		var t = Tabs.Transport;

		var featherweight = parseInt(Seed.tech.tch10) * 0.1;
		var loadEffectBoost = 0;
		if (Seed.playerEffects.loadExpire > uW.unixtime()) { loadEffectBoost = 0.25; };
		var loadBoostBase = (Math.floor(CM.ThroneController.effectBonus(6)) * 0.01) + loadEffectBoost;
		if (CM.unitFrontendType[unit] == "siege") { loadBoostBase += (CM.ThroneController.effectBonus(59) * 0.01) };
        if (CM.unitFrontendType[unit] == "horsed") { loadBoostBase += (CM.ThroneController.effectBonus(48) * 0.01); };
        var Load = parseInt(uW.unitstats["unt"+unit]['5']);

		t.LoadSac = "";
		if (Seed.queue_sacr["city"+cityId]) {
			for(var sacIndex = 0; sacIndex < Seed.queue_sacr["city"+cityId].length; sacIndex ++ ) {
				if(Seed.queue_sacr["city"+cityId][sacIndex]["unitType"] == unit) {
					Load *= Seed.queue_sacr["city"+cityId][sacIndex]["multiplier"][0];
					t.LoadSac = '<span style="color:#f00;">&nbsp;&nbsp;&nbsp;Ritual Boost '+Math.round((Seed.queue_sacr["city"+cityId][sacIndex]["multiplier"][0]-1)*100)+'%</span>';
				}
			}
		}

		if (loadBoostBase > Number(CM.thronestats.boosts.Load.Max)/100) {
			loadBoostBase = Number(CM.thronestats.boosts.Load.Max)/100;
		};
		loadBoostBase += featherweight; //Should be done after throne room max check to get max boost?
		loadBoostBase += 1;

		return Math.floor(loadBoostBase*Load);
	},

	CalcMaxResource : function (restype) {
		var t = Tabs.Transport;
		if (!t.dcp0 || !t.dcp0.city) return;

		var Food = (restype=="Food")?0:parseIntCommas(ById('pbtradeamountFood').value);
		var Wood = (restype=="Wood")?0:parseIntCommas(ById('pbtradeamountWood').value);
		var Stone = (restype=="Stone")?0:parseIntCommas(ById('pbtradeamountStone').value);
        var Ore = (restype=="Ore")?0:parseIntCommas(ById('pbtradeamountOre').value);
		var Gold = (restype=="Gold")?0:parseIntCommas(ById('pbtradeamountGold').value);
		var Aether = (restype=="Aether")?0:parseIntCommas(ById('pbtradeamountAether').value)*5;

		var unit = ById('pbttroops').value;
		var Troops = parseInt(Seed.units['city' + t.dcp0.city.id]["unt"+unit]);
        var LoadUnit = t.getLoadUnit(unit,t.dcp0.city.id);
		var MaxMarchSize = March.RallyPoint(t.dcp0.city.id).maxSize;
		if (MaxMarchSize < Troops) { var GlobalMaxLoad = MaxMarchSize * LoadUnit; }
		else { var GlobalMaxLoad = Troops * LoadUnit; }
		if (GlobalMaxLoad>0) GlobalMaxLoad = GlobalMaxLoad-1; // avoid max load problems

		var LoadSelected = Food+Wood+Stone+Ore+Gold+Aether;
		var Max = GlobalMaxLoad - LoadSelected;
		if (Max<0) Max = 0;
		if (restype=="Aether") Max = Math.floor(Max/5);
		// limit to source city values
		var citylimit = 0;
		if (restype=="Food") citylimit = parseIntNan(Seed.resources["city" + t.dcp0.city.id]['rec1'][0] / 3600);
		if (restype=="Wood") citylimit = parseIntNan(Seed.resources["city" + t.dcp0.city.id]['rec2'][0] / 3600);
		if (restype=="Stone") citylimit = parseIntNan(Seed.resources["city" + t.dcp0.city.id]['rec3'][0] / 3600);
		if (restype=="Ore") citylimit = parseIntNan(Seed.resources["city" + t.dcp0.city.id]['rec4'][0] / 3600);
		if (restype=="Gold") citylimit = parseIntNan(Seed.citystats["city" + t.dcp0.city.id]['gold'][0]);
		if (restype=="Aether") citylimit = parseIntNan(Seed.resources["city" + t.dcp0.city.id]['rec5'][0]);
		if (Max>citylimit) Max = citylimit;

		return Max;
	},

	updateRoutes : function () {
		var t = Tabs.Transport;

		if (!tabManager.currentTab || tabManager.currentTab.name != 'Transport' || !Options.btWinIsOpen) { return; }

		var n = Options.TransportOptions.Routes.length;
		while (n--) {
			var a = Options.TransportOptions.Routes[n];
			var elstat = ById('pbtrRouteStatus'+n);
			if (elstat) {
				elstat.innerHTML = '<span><br><br></span>';
				if (Options.TransportOptions.Running) {
					if (a.Active) {
						if (Options.TransportOptions.ThroneCheck && (t.marchspeed < Options.TransportOptions.MarchSpeed)) {
							elstat.innerHTML = '<span class=boldRed>March<br>Speed!<br></span>';
						}
						else {
							var now = unixTime();
							var interval = Options.TransportOptions.TransportInterval*60;
							if (a.OverrideTime) { interval = a.Interval*60; }
							var due = a.LastChecked+interval;
							if (due < now) {
								elstat.innerHTML = '<span class=boldGreen>'+tx('Checking')+'...<br><br></span>';
							}
							else {
								elstat.innerHTML = uW.timestr(due-now)+'<br><a id="pbtrRouteCheck'+n+'" onclick="pbtrSendRoute('+n+')"><span>'+tx('Check Now')+'</span></a>';
							}
						}
					}
				}
			}
		}
	},

	doAutoLoop : function (idx,rev) {
		var t = Tabs.Transport;
		clearTimeout(t.timer);
		if (!Options.TransportOptions.Running) return;

		if (idx>=Options.TransportOptions.Routes.length) { idx=0; } // safety, if route(s) have been deleted.
		if (idx==0 && !rev) { t.loopaction = false; } // reset loop march indicator for first march
		t.autodelay = 0; // no delay if no action taken...

		if (idx<Options.TransportOptions.Routes.length) {
			var a = Options.TransportOptions.Routes[idx];

			if (a.Active) {
				var now = unixTime();
				var interval = Options.TransportOptions.TransportInterval*60;
				if (a.OverrideTime) { interval = a.Interval*60; }
				var due = a.LastChecked+interval;
				if ((due < now) || rev) {
					// check if march is required...
					t.doTrades(idx,rev);
					if (!rev) {
						Options.TransportOptions.Routes[idx]["LastChecked"] = uW.unixtime();
						saveOptions();
						t.updateRoutes();
						if (Options.TransportOptions.ReverseTransport) {  // check for reverse transport on this route
							t.timer = setTimeout(function () { t.doAutoLoop(idx,true); }, (t.autodelay * 1000));
							return;
						}
					}
				}
			}
		}

		if (idx >= Options.TransportOptions.Routes.length-1) {
			if (!t.loopaction) { t.autodelay = Options.TransportOptions.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(0,false); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1,false); }, (t.autodelay * 1000));
		}
	},

	doTrades: function(idx,rev){
		var t = Tabs.Transport;
		var a = Options.TransportOptions.Routes[idx];

		if (Options.TransportOptions.ThroneCheck && (t.marchspeed < Options.TransportOptions.MarchSpeed)) { return; } // if not enough march speed

		if (!rev) {
			var sourcecityId = parseIntNan(a["cityId"]);
			var destcityId = a["target_cityId"];
			var xcoord = a["target_x"];
			var ycoord = a["target_y"];
		}
		else {
			if (a["rev_eta"] && parseInt(a["rev_eta"]) > uW.unixtime()) { return; } // only one reverse transport on each route at a time
			var sourcecityId = a["target_cityId"];
			var destcityId = parseIntNan(a["cityId"]);
			if(!Cities.byID[destcityId]) { return; } // no reverse transport city!
			var xcoord = Cities.byID[destcityId].x;
			var ycoord = Cities.byID[destcityId].y;
		}

		if (!Cities.byID[sourcecityId]) { return; } // no source city!

		var towerok = (!Options.TowerOptions || !Options.TowerOptions.SaveCityState[sourcecityId] || Options.TowerOptions.SaveCityState[sourcecityId].AllowMarches);
		if (!towerok) { return; } // source city under attack!

		var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[Cities.byID[sourcecityId].idx]);
		if (!ascensionok) { return; } // source city waiting to ascend!

		var targetname = xcoord+','+ycoord;
		if (destcityId && destcityId != 0) {
			if (!Cities.byID[destcityId]) return; // no destination city!
			targetname = Cities.byID[destcityId].name;
		}

		var ship_Food = a["ship_Food"];
		var ship_Wood = a["ship_Wood"];
		var ship_Stone = a["ship_Stone"];
		var ship_Ore = a["ship_Ore"];
		var ship_Aether = a["ship_Aether"];
		var ship_Gold = a["ship_Gold"];

		var trade_Food = parseIntNan(a["trade_Food"]);
		var trade_Wood = parseIntNan(a["trade_Wood"]);
		var trade_Stone = parseIntNan(a["trade_Stone"]);
		var trade_Ore = parseIntNan(a["trade_Ore"]);
		var trade_Aether = parseIntNan(a["trade_Aether"]);
		var trade_Gold = parseIntNan(a["trade_Gold"]);

		var TotalTrade = trade_Food+trade_Wood+trade_Stone+trade_Ore+(trade_Aether*5)+trade_Gold;

		var target_Food = parseIntNan(a["keep_Food"]);
		var target_Wood = parseIntNan(a["keep_Wood"]);
		var target_Stone = parseIntNan(a["keep_Stone"]);
		var target_Ore = parseIntNan(a["keep_Ore"]);
		var target_Aether = parseIntNan(a["keep_Aether"]);
		var target_Gold = parseIntNan(a["keep_Gold"]);

		var minfactor = parseIntNan(Options.TransportOptions.ReverseTransportPercent)/100;

		var min_Food = target_Food * minfactor;
		var min_Wood = target_Wood * minfactor;
		var min_Stone = target_Stone * minfactor;
		var min_Ore = target_Ore * minfactor;
		var min_Aether = target_Aether * minfactor;
		var min_Gold = target_Gold * minfactor;

		var citymax_Food = parseIntNan(Seed.resources["city"+sourcecityId]['rec1'][0] / 3600);
		var citymax_Wood = parseIntNan(Seed.resources["city"+sourcecityId]['rec2'][0] / 3600);
		var citymax_Stone = parseIntNan(Seed.resources["city"+sourcecityId]['rec3'][0] / 3600);
		var citymax_Ore = parseIntNan(Seed.resources["city"+sourcecityId]['rec4'][0] / 3600);
		var citymax_Aether = parseIntNan(Seed.resources["city"+sourcecityId]['rec5'][0]);
		var citymax_Gold = parseIntNan(Seed.citystats["city"+sourcecityId]['gold']);

		if (!rev) {
			var carry_Food = parseIntNan(citymax_Food - target_Food);
			var carry_Wood = parseIntNan(citymax_Wood - target_Wood);
			var carry_Stone = parseIntNan(citymax_Stone - target_Stone);
			var carry_Ore = parseIntNan(citymax_Ore - target_Ore);
			var carry_Aether = parseIntNan(citymax_Aether - target_Aether);
			var carry_Gold = 0;
		}
		else {
			var tgtcitymax_Food = parseIntNan(Seed.resources["city"+destcityId]['rec1'][0] / 3600);
			var tgtcitymax_Wood = parseIntNan(Seed.resources["city"+destcityId]['rec2'][0] / 3600);
			var tgtcitymax_Stone = parseIntNan(Seed.resources["city"+destcityId]['rec3'][0] / 3600);
			var tgtcitymax_Ore = parseIntNan(Seed.resources["city"+destcityId]['rec4'][0] / 3600);
			var tgtcitymax_Aether = parseIntNan(Seed.resources["city"+destcityId]['rec5'][0]);
			var tgtcitymax_Gold = parseIntNan(Seed.citystats["city"+destcityId]['gold']);

			var carry_Food = parseIntNan(min_Food - tgtcitymax_Food);
			var carry_Wood = parseIntNan(min_Wood - tgtcitymax_Wood);
			var carry_Stone = parseIntNan(min_Stone - tgtcitymax_Stone);
			var carry_Ore = parseIntNan(min_Ore - tgtcitymax_Ore);
			var carry_Aether = parseIntNan(min_Aether - tgtcitymax_Aether);
			var carry_Gold = 0;
		}

		if (carry_Food < 0 || !ship_Food) carry_Food = 0;
		if (carry_Wood < 0 || !ship_Wood) carry_Wood = 0;
		if (carry_Stone < 0 || !ship_Stone) carry_Stone = 0;
		if (carry_Ore < 0 || !ship_Ore) carry_Ore = 0;
		if (carry_Aether < 0 || !ship_Aether) carry_Aether = 0;

		if (!rev) {
			if (trade_Food > 0 && (carry_Food > trade_Food)) carry_Food = parseIntNan(trade_Food);
			if (trade_Wood > 0 && (carry_Wood > trade_Wood)) carry_Wood = parseIntNan(trade_Wood);
			if (trade_Stone > 0 && (carry_Stone > trade_Stone)) carry_Stone = parseIntNan(trade_Stone);
			if (trade_Ore > 0 && (carry_Ore > trade_Ore)) carry_Ore = parseIntNan(trade_Ore);
			if (trade_Aether > 0 && (carry_Aether > trade_Aether)) carry_Aether = parseIntNan(trade_Aether);
		}
		else { // reverse trans up to keep value (not min value)
			if (carry_Food > 0 && (target_Food > min_Food)) carry_Food = parseIntNan(target_Food - tgtcitymax_Food);
			if (carry_Wood > 0 && (target_Wood > min_Wood)) carry_Wood = parseIntNan(target_Wood - tgtcitymax_Wood);
			if (carry_Stone > 0 && (target_Stone > min_Stone)) carry_Stone = parseIntNan(target_Stone - tgtcitymax_Stone);
			if (carry_Ore > 0 && (target_Ore > min_Ore)) carry_Ore = parseIntNan(target_Ore - tgtcitymax_Ore);
			if (carry_Aether > 0 && (target_Aether > min_Aether)) carry_Aether = parseIntNan(target_Aether - tgtcitymax_Aether);

			// don't attempt to reverse transport more than you actually have available...
			if (carry_Food > citymax_Food) carry_Food = parseIntNan(citymax_Food);
			if (carry_Wood > citymax_Wood) carry_Wood = parseIntNan(citymax_Wood);
			if (carry_Stone > citymax_Stone) carry_Stone = parseIntNan(citymax_Stone);
			if (carry_Ore > citymax_Ore) carry_Ore = parseIntNan(citymax_Ore);
			if (carry_Aether > citymax_Aether) carry_Aether = parseIntNan(citymax_Aether);
		}
		carry_Aether *= 5; // Multiply by 5 to account for 5 times less carrying capacity

		var unit = 9;
		if (a['TroopType'] && a['TroopType']!=0) { unit = a['TroopType']; }
		var Troops = parseInt(Seed.units['city' + sourcecityId]["unt"+unit]);
		if(Troops < Options.TransportOptions.MinWagons) { // insufficient troops!
			actionLog(Cities.byID[sourcecityId].name+": Insufficient troops available for transport",'TRANSPORT');
			return;
		}

        var LoadUnit = t.getLoadUnit(unit,sourcecityId);
		var MaxMarchSize = March.RallyPoint(sourcecityId).maxSize;
		var maxload = MaxMarchSize * LoadUnit;
		if (Troops < MaxMarchSize) { maxload = Troops * LoadUnit; }
		if (maxload>0) maxload = maxload - 1; // avoid max load problems

		var slots = Number(March.getEmptySlots(sourcecityId));
		if (parseInt(slots) <=Number(Options.FreeRallySlots)) { // no free slots - don't bother server!
			if (GlobalOptions.ExtendedDebugMode) {actionLog(Cities.byID[sourcecityId].name+": No available rally slots",'TRANSPORT');}
			return;
		}

		// apportion resources if too many to carry at once...

		var shift_Food = parseIntNan(maxload / 9); // Total of 9 portions
		var shift_Wood = parseIntNan(maxload / 9);
		var shift_Stone = parseIntNan(maxload / 9);
		var shift_Ore = parseIntNan(maxload / 9);
		var shift_Aether = parseIntNan(maxload / 9 * 5); // Aetherstone takes 5 of 9 portions - This gives us extra capacity if there's no aether

		if ((maxload - carry_Food - carry_Wood - carry_Stone - carry_Ore - carry_Aether) < 0){
			var shift_spare=0;

			// Check: See if load/9 is to big for some resources...

            if (carry_Food < shift_Food) {
				shift_spare += (shift_Food - carry_Food);
				shift_Food = carry_Food;
			}
			if (carry_Wood < shift_Wood) {
				shift_spare += (shift_Wood - carry_Wood);
				shift_Wood = carry_Wood;
			}
			if (carry_Stone < shift_Stone) {
				shift_spare += (shift_Stone - carry_Stone);
				shift_Stone = carry_Stone;
			}
			if (carry_Ore < shift_Ore) {
				shift_spare += (shift_Ore - carry_Ore);
				shift_Ore = carry_Ore;
			}
			if (carry_Aether < shift_Aether) {
				shift_spare += (shift_Aether - carry_Aether);
				shift_Aether = carry_Aether;
			}

			while (shift_spare > 1) {
				var PriorityList = 	Options.TransportOptions.Priority.split(",");
				for (var p in PriorityList) {
					var res = PriorityList[p];
					if (res==1) { // food
						if (carry_Food < (shift_Food + shift_spare)){
							shift_Food = carry_Food;
							shift_spare = shift_spare - carry_Food;
						}
						else{
							shift_Food = (shift_Food + shift_spare);
							shift_spare = 0;
						}
					}
					if (res==2) { // wood
						if (carry_Wood < (shift_Wood + shift_spare)){
							shift_Wood = carry_Wood;
							shift_spare = shift_spare - carry_Wood;
						} else {
							shift_Wood = shift_Wood + shift_spare;
							shift_spare = 0;
						}
					}
					if (res==3) { // stone
						if (carry_Stone < (shift_Stone + shift_spare)){
							shift_Stone = carry_Stone;
							shift_spare = shift_spare - carry_Stone;
						} else {
							shift_Stone = shift_Stone + shift_spare;
							shift_spare = 0;
						}
					}
					if (res==4) { // ore
						if (carry_Ore < (shift_Ore + shift_spare)) {
							shift_Ore = carry_Ore;
							shift_spare = shift_spare - carry_Ore;
						} else {
							shift_Ore = shift_Ore + shift_spare;
							shift_spare = 0;
						}
					}
					if (res==5) { // aether
						if (carry_Aether < (shift_Aether + shift_spare)) {
							shift_Aether = carry_Aether;
							shift_spare = shift_spare - carry_Aether;
						} else {
							shift_Aether = shift_Aether + shift_spare;
							shift_spare = 0;
						}
					}
				}
			}
			carry_Food = shift_Food;
			carry_Wood = shift_Wood;
			carry_Stone = shift_Stone;
			carry_Ore = shift_Ore;
			carry_Aether = shift_Aether;
		}

		// ship gold if any spare capacity left

		var spaceleft = maxload - (carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Aether);
		if ((spaceleft > 0) && ship_Gold) {
			if (!rev) {
				if (spaceleft > (citymax_Gold - target_Gold)) {
					carry_Gold = (citymax_Gold - target_Gold);
					if (carry_Gold < 0) carry_Gold = 0;
				}
				else {
					carry_Gold = spaceleft;
				}
				if (trade_Gold > 0 && (carry_Gold > trade_Gold)) carry_Gold = parseInt(trade_Gold);
			}
			else {
				carry_Gold = (min_Gold - tgtcitymax_Gold);
				if (carry_Gold < 0) carry_Gold = 0;
				if (carry_Gold > 0) {
					if (spaceleft > (target_Gold - tgtcitymax_Gold)) {
						carry_Gold = (target_Gold - tgtcitymax_Gold);
						if (carry_Gold < 0) carry_Gold = 0;
					}
					else {
						carry_Gold = spaceleft;
					}
				}
				if (carry_Gold > citymax_Gold) carry_Gold = parseIntNan(citymax_Gold);
			}
		}
		var totalres = carry_Food + carry_Wood + carry_Stone + carry_Ore + carry_Aether + carry_Gold;
		var wagons_needed = Math.ceil((totalres) / LoadUnit);
		var IgnoreMinCheck = (!rev && (TotalTrade==totalres)); // don't check min troops if transporting the set amount of resources user has asked to be transported
        if (wagons_needed < Options.TransportOptions.MinWagons && !IgnoreMinCheck) {
            if (GlobalOptions.ExtendedDebugMode && !rev) { actionLog(Cities.byID[sourcecityId].name+": Small transport skipped : ("+wagons_needed+" for "+totalres+" load)",'TRANSPORT'); }
            return;
        }
        if (wagons_needed > MaxMarchSize) { // don't bother server with this either, we can trust my calculations I hope!!
            if (GlobalOptions.ExtendedDebugMode) { actionLog(Cities.byID[sourcecityId].name+": Maximum march size exceeded : ("+wagons_needed+"/"+MaxMarchSize+" for "+totalres+" load)",'TRANSPORT'); }
            return;
        }

		if (totalres > 0) { // final safety net
			t.autodelay = Options.TransportOptions.intervalSecs; // march is required, so delay subsequent loop
			t.loopaction = true;

			var params = uW.Object.clone(uW.g_ajaxparams);
			params.cid = sourcecityId;
			params.kid = 0;
			params.type = 1;
			params.xcoord = xcoord;
			params.ycoord = ycoord;
			params.r1 = carry_Food;
			params.r2 = carry_Wood;
			params.r3 = carry_Stone;
			params.r4 = carry_Ore;
			params.r5 = parseInt(carry_Aether/5);
			params.gold = carry_Gold;
			params["u"+unit] = wagons_needed;

			March.addMarch(params, function(rslt){
				if (rslt.ok) {
					if (!rev) {
						actionLog(Cities.byID[sourcecityId].name+": "+wagons_needed+" "+uW.unitcost["unt"+unit][0]+" transported goods to "+targetname,'TRANSPORT');
					}
					else {
						actionLog(Cities.byID[sourcecityId].name+": "+wagons_needed+" "+uW.unitcost["unt"+unit][0]+" reverse-transported goods back to "+targetname,'TRANSPORT');
						Options.TransportOptions.Routes[idx]["rev_eta"] = parseInt(rslt.eta);
						saveOptions();
					}
				}
				else {
					if (!rslt.msg) {rslt.msg = 'Error Code ('+rslt.error_code+')';}
					if (!rev) { actionLog(Cities.byID[sourcecityId].name+": Transport Error - "+rslt.msg,'TRANSPORT'); }
					else { actionLog(Cities.byID[sourcecityId].name+": Reverse Transport Error - "+rslt.msg,'TRANSPORT'); }
				}
			});
		}
	},

	ManualTransport : function () {
		var t = Tabs.Transport;

		if (!t.validateScreenFields('send')) { return; }

		ById('pbtrMessages').innerHTML = "Sending manual transport...";

		var a = t.RouteObject;

		var sourcecityId = parseIntNan(a["cityId"]);
		var xcoord = a["target_x"];
		var ycoord = a["target_y"];

		var carry_Food = parseIntNan(a["trade_Food"]);
		var carry_Wood = parseIntNan(a["trade_Wood"]);
		var carry_Stone = parseIntNan(a["trade_Stone"]);
		var carry_Ore = parseIntNan(a["trade_Ore"]);
		var carry_Aether = parseIntNan(a["trade_Aether"]);
		var carry_Gold = parseIntNan(a["trade_Gold"]);

		var totalres = carry_Food+carry_Wood+carry_Stone+carry_Ore+(carry_Aether*5)+carry_Gold;

		var unit = 9;
		if (a['TroopType'] && a['TroopType']!=0) { unit = a['TroopType']; }
		var Troops = parseInt(Seed.units['city' + sourcecityId]["unt"+unit]);
		if(Troops <= 0) { Troops=0; }
        var LoadUnit = t.getLoadUnit(unit,sourcecityId);
		var MaxMarchSize = March.RallyPoint(sourcecityId).maxSize;
		var maxload = MaxMarchSize * LoadUnit;
		if (Troops < MaxMarchSize) { maxload = Troops * LoadUnit; }
		if (maxload>0) maxload = maxload - 1; // avoid max load problems

		if (totalres > maxload) {
			ById('pbtrMessages').innerHTML = "Too much to carry!";
			return;
		}

		var slots = Number(March.getEmptySlots(sourcecityId));
		if (parseInt(slots) <=0) { // no free slots - don't bother server!
			ById('pbtrMessages').innerHTML = tx("No free rally point slots");
			return;
		}

		var wagons_needed = Math.ceil((totalres) / LoadUnit);
        if (wagons_needed > MaxMarchSize) { // don't bother server with this either, we can trust my calculations I hope!!
			ById('pbtrMessages').innerHTML = "Maximum march size exceeded : ("+wagons_needed+"/"+MaxMarchSize+" for "+totalres+" load)";
            return;
        }

		if (totalres > 0) { // final safety net
			var params = uW.Object.clone(uW.g_ajaxparams);
			params.cid = sourcecityId;
			params.kid = 0;
			params.type = 1;
			params.xcoord = xcoord;
			params.ycoord = ycoord;
			params.r1 = carry_Food;
			params.r2 = carry_Wood;
			params.r3 = carry_Stone;
			params.r4 = carry_Ore;
			params.r5 = carry_Aether;
			params.gold = carry_Gold;
			params["u"+unit] = wagons_needed;

			March.addMarch(params, function(rslt){
				if (rslt.ok) {
					ById('pbtrMessages').innerHTML = "Manual transport successful!";
				}
				else {
					if (!rslt.msg) {rslt.msg = 'Error Code ('+rslt.error_code+')';}
					ById('pbtrMessages').innerHTML = rslt.msg;
				}
			});
		}
	},
}


/*********************************** Reassign Tab ***********************************/

Tabs.Reassign = {
	tabOrder: 2040,
	tabLabel : 'Reassign',
	tabColor : 'brown',
	myDiv : null,
	dcp0 : null,
	dcp1 : null,
	timer : null,
	autodelay : 0,
	loopaction : false,
	more : false,
	marchspeed : 0,
	LoopCounter : 0,
	EditRouteNumber : -1,
	EditMode : false,
	Options : {
		Running: false,
		Toggle : false,
		Routes : [],
		ReassignInterval : 60,
		intervalSecs  : 5,
		ReverseReassign : false,
		ThroneCheck: false,
		MarchSpeed: 0,
		ReassignKnights: false,
	},
	NewRouteObject : {
		cityId: null,
		target_cityId: null,
		troops: {}, //id{send,keep}
		keep: {},
		Active: true,
		OverrideTime: false,
		Interval : 10,
		LastChecked : 0,
	},
	RouteObject : null,

	init : function (div) {
		var t = Tabs.Reassign;
		t.myDiv = div;

		if (!Options.ReassignOptions) {
			Options.ReassignOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.ReassignOptions.hasOwnProperty(y)) {
					Options.ReassignOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction ('pbreDeleteRoute', Tabs.Reassign.DeleteRoute);
		uWExportFunction ('pbreEditRoute', Tabs.Reassign.EditRoute);
		uWExportFunction ('pbreSendRoute', Tabs.Reassign.SendRoute);
		uWExportFunction ('pbreToggleActive', Tabs.Reassign.ToggleActive);

		if (Options.ReassignOptions.Toggle) AddSubTabLink('Reassign',t.toggleAutoReassignState, 'ReassignToggleTab');
		SetToggleButtonState('Reassign',Options.ReassignOptions.Running,'Reassign');

		var m = '<DIV class=divHeader align=center>'+tx('AUTOMATED TROOP REASSIGN')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btReassignToggle type=checkbox '+ (Options.ReassignOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoReassignState type=submit value="'+tx("Reassign")+' = '+ (Options.ReassignOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>'+tx('Current Reassign Speed')+':&nbsp;<span id=btreMarchCurrTR></span>&nbsp;&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td align=left><INPUT id=btreMarchTR type=checkbox '+(Options.ReassignOptions.ThroneCheck?'CHECKED':'')+'></td><td>'+tx('Only reassign when march speed for reassign is at least')+' <INPUT id=btreMarchTRSpeed type=text size=3 maxlength=4 value="'+ Options.ReassignOptions.MarchSpeed +'">&nbsp;%</td><td align=right>&nbsp;'+tx("Check routes every:")+'&nbsp;<INPUT id=pbreassigninterval type=text size=2 value="' + Options.ReassignOptions.ReassignInterval+'"\> '+tx("minutes")+'</td></tr>';
        m += '<tr><td><INPUT id=pbreassignknights type=checkbox '+(Options.ReassignOptions.ReassignKnights?'CHECKED':'')+'></td><td>'+tx('Reassign with Knights')+'</td><td align=right>&nbsp;'+tx("March Interval:")+'&nbsp;<INPUT id=pbrmarchinterval type=text size=2 value="' + Options.ReassignOptions.intervalSecs+'"\> '+tx("seconds")+'</td></tr>';
        m += '<tr><td><INPUT id=pbrevreassign type=checkbox '+(Options.ReassignOptions.ReverseReassign?'CHECKED':'')+'></td><td colspan=2>'+tx('Reverse reassign if troop numbers fall below keep value')+'</td></tr></table>';
		m += '<div id=pbreMessages align=center>&nbsp;</div>';
		m += '<div id=pbreRouteDetail>&nbsp;</div><br>';

		div.innerHTML = m;

		ToggleOption('ReassignOptions','btReassignToggle','Toggle');

		ById('btAutoReassignState').addEventListener('click', function(){
			t.toggleAutoReassignState(this);
		}, false);

        ById('pbreassigninterval').addEventListener('keyup', function () {
            if (isNaN(ById('pbreassigninterval').value)) { ById('pbreassigninterval').value = 60; }
            Options.ReassignOptions.ReassignInterval = ById('pbreassigninterval').value;
            saveOptions();
        }, false);
        ById('pbrmarchinterval').addEventListener('keyup', function () {
            if (parseIntNan(ById('pbrmarchinterval').value)<1) { ById('pbrmarchinterval').value = 5; }
            if (parseIntNan(ById('pbrmarchinterval').value)<2) { ById('pbrmarchinterval').value = 2; }
            Options.ReassignOptions.intervalSecs = parseIntNan(ById('pbrmarchinterval').value);
            saveOptions();
        }, false);
		ById('pbrevreassign').addEventListener('change', function(){
			Options.ReassignOptions.ReverseReassign = ById('pbrevreassign').checked;
			saveOptions();
		}, false);
		ById('pbreassignknights').addEventListener('change', function(){
			Options.ReassignOptions.ReassignKnights = ById('pbreassignknights').checked;
			saveOptions();
		}, false);
		ById('btreMarchTR').addEventListener ('change', function() {
			Options.ReassignOptions.ThroneCheck = this.checked;
			saveOptions();
        }, false);
		ById('btreMarchTRSpeed').addEventListener ('change', function() {
			Options.ReassignOptions.MarchSpeed = parseIntNan(this.value);
			saveOptions();
        }, false);

		t.PaintRoutes();

		// start autoreassign loop timer to start in 12 seconds...

		if (Options.ReassignOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, (12 * 1000));
		}
	},

	toggleAutoReassignState: function(obj){
		var t = Tabs.Reassign;
		obj = ById('btAutoReassignState');
		if (Options.ReassignOptions.Running == true) {
			Options.ReassignOptions.Running = false;
			obj.value = tx("Reassign = OFF");
			clearTimeout(t.timer);
		}
		else {
			Options.ReassignOptions.Running = true;
			obj.value = tx("Reassign = ON");
			// clear the last checked field on all routes
			var n = Options.ReassignOptions.Routes.length;
			while (n--) {
				Options.ReassignOptions.Routes[n].LastChecked = 0;
			}
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Reassign',Options.ReassignOptions.Running,'Reassign');
	},

	ClearRoutes : function() {
		var t = Tabs.Reassign;
		Options.ReassignOptions.Routes = [];
		saveOptions();
		ById('pbreMessages').innerHTML = "All reassign routes deleted!";
		t.PaintRoutes();
	},

	PaintRoutes : function () {
		var t = Tabs.Reassign;

		t.EditMode = false;
		var z = '';
		var r = 0;

		var bclass = "blue14";
		var btext  = "Clear Routes";
		var Routes = false;

		var z= '<div class=divHeader align=center>'+tx('REASSIGN ROUTES')+'</div><br>';
		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td width=90px>'+strButton20(tx('New Route'), 'id=pbreNewRoute')+'</td>';
		z += '<td align=left id=pbrebulkactions>&nbsp;</td>';
		z += '<td align=right>'+strButton20(tx('Delete ALL Routes'), 'id=pbreClearRoutes')+'&nbsp;</td></tr></table>';
		z += '<div style="max-height:535px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px";overflow-x:auto" align="center"><TABLE id=pbreRoutesTable cellSpacing=0 width=100% height=0%><tr><td class="xtabHD" style="width:100px"><b>'+tx('Source')+'</b></td><td style="width:100px" class="xtabHD"><b>'+tx('Destination')+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b><td class="xtabHD" align="center" style="width:90px"><b>'+tx('Active')+'</b></td><td class="xtabHD" align="right" style="width: 115px"><span id=pbrenumroutes>'+Options.ReassignOptions.Routes.length+'</span> '+tx('Routes')+'</td></tr>';

		var FromList = {0:"-- "+tx('Select City')+" --"};
		var BulkAction = {0:"-- "+tx('Select Action')+" --",1:tx("Delete ALL Marches From"),2:tx("Delete ALL Marches To"),3:tx("Transfer ALL Marches From"),4:tx("Transfer ALL Marches To"),5:tx("Disable ALL Marches From"),6:tx("Disable ALL Marches To"),7:tx("Enable ALL Marches From"),8:tx("Enable ALL Marches To")};
		var CityList = {0:"-- "+tx('Select City')+" --"};
		for (g in Cities.byID) { CityList[Cities.byID[g].id] = Cities.byID[g].name; }

		var n = Options.ReassignOptions.Routes.length;
		while (n--) {
			var a = Options.ReassignOptions.Routes[n];
			var fid = -1;
			var fromname = '<span class=boldRed>'+tx('No City')+'!</span>';
			if (Cities.byID[a.cityId]) { fromname = Cities.byID[a.cityId].name; fid = a.cityId; }
			FromList[fid] = fromname;
			var fid = -1;
			var toname = '<span class=boldRed>'+tx('No City')+'!</span>';
			if (Cities.byID[a.target_cityId]) { toname = Cities.byID[a.target_cityId].name; fid = a.target_cityId; }
			FromList[fid] = toname;

			Routes = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:100px" class=xtab valign=top>'+fromname+'</td>';
			z += '<TD style="width:100px" class=xtab valign=top>'+toname+'</td>';

			var zz = '<table cellpadding=0 cellspacing=0 class=xtab><tr>';

			// loop troops

			var c = 0;
			var LineBreak = 3;
			if (GlobalOptions.btWinSize.x == 750) {LineBreak = 2;}
			if (GlobalOptions.btWinSize.x == 1250) {LineBreak = 4;}
			for (var ui in uW.cm.UNIT_TYPES){
				var i = uW.cm.UNIT_TYPES[ui];
				if (a.troops[i]) {
					var nn = '<TD width=30px>'+TroopImage(i)+'</td>';
					nn += '<TD width=150px>'+tx("Keep")+':&nbsp;'+addCommas(parseIntNan(a.keep[i]))+'</td>';
					if (c%LineBreak==0) zz+= '</tr><tr>';
					zz += nn;
					c++;
				}
			}
			zz += '</tr></table><br>'

			z += '<TD class=xtabBRTop>'+zz+'</td>';
			z += '<TD style="width:90px" class=xtab align=center valign=top><INPUT id="pbreRouteActive'+n+'" type=checkbox '+(a.Active?'CHECKED':'')+' onclick="pbreToggleActive('+n+')" /><div id="pbreRouteStatus'+n+'"><span><br><br></span><//div></td>';
			z += '<TD style="width:100px" class=xtab align=right valign=top><a id="pbreRouteEdit'+n+'" class="inlineButton btButton brown8" onclick="pbreEditRoute('+n+')"><span>Edit</span></a>&nbsp;<a id="pbreRouteDelete'+n+'" class="inlineButton btButton brown8" onclick="pbreDeleteRoute('+n+')"><span>Del</span></a></a></td>';
			z += '</tr>';
		}

		if (!Routes) {
			z += '<tr><td colspan=5 class=xtab><div align="center"><br><br>'+tx('No reassign routes')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		ById('pbreRouteDetail').innerHTML = z;
		ById('pbrebulkactions').innerHTML = tx("Bulk Action")+":&nbsp;"+htmlSelector(BulkAction,0,'class=btInput id=pbrebulkaction')+'&nbsp;'+htmlSelector(FromList,0,'class=btInput id=pbrebulkfrom')+'&nbsp;<span id=pbrebulknew class=divHide>To&nbsp;'+htmlSelector(CityList,0,'class=btInput id=pbrebulkto')+'</span>&nbsp;'+strButton8(tx('Go'),'id=pbrebulkgo');

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('pbrebulkgo').addEventListener('click', function(){t.DoBulkAction(ById('pbrebulkaction').value,ById('pbrebulkfrom').value,ById('pbrebulkto').value);}, false);
		ById('pbrebulkaction').addEventListener('change', function(e){
			if (e.target.value==3 || e.target.value==4) { jQuery('#pbrebulknew').removeClass("divHide"); }
			else { jQuery('#pbrebulknew').addClass("divHide"); }
		}, false);

		ById('pbreClearRoutes').addEventListener ('click', function() {t.ClearRoutes();}, false);
		ById('pbreNewRoute').addEventListener ('click', function() {t.NewRoute();}, false);
		t.updateRoutes();
	},

	DoBulkAction : function (Action,From,To) {
		var t = Tabs.Reassign;
		ById('pbreMessages').innerHTML = "&nbsp;";
		if (Action==0 || From==0) return;
		if ((Action==3 || Action==4) && To==0) return;
		for (var i=Number(Options.ReassignOptions.Routes.length-1); i>-1 ;i--) {
			if (Action==1 || Action==3 || Action==5 || Action==7) {
				if ((Options.ReassignOptions.Routes[i].cityId == From) || (From==-1 && !Cities.byID[Options.ReassignOptions.Routes[i].cityId])) {
					if (Action==1) { Options.ReassignOptions.Routes.splice(i,1); }
					else {
						if (Action==3) { Options.ReassignOptions.Routes[i].cityId = To; }
						else {
							if (Action==5) { Options.ReassignOptions.Routes[i].Active = false; }
							else {
								if (Action==7) { Options.ReassignOptions.Routes[i].Active = true; }
							}
						}
					}
				}
			}
			if (Action==2 || Action==4 || Action==6 || Action==8) {
				if (parseIntNan(Options.ReassignOptions.Routes[i].target_cityId) != 0) {
					if ((Options.ReassignOptions.Routes[i].target_cityId == From) || (From==-1 && !Cities.byID[Options.ReassignOptions.Routes[i].target_cityId])) {
						if (Action==2) { Options.ReassignOptions.Routes.splice(i,1); }
						else {
							if (Action==4) {
								Options.ReassignOptions.Routes[i].target_cityId = To;
							}
							else {
								if (Action==6) { Options.ReassignOptions.Routes[i].Active = false; }
								else {
									if (Action==8) { Options.ReassignOptions.Routes[i].Active = true; }
								}
							}
						}
					}
				}
			}
		}
		saveOptions();
		if (Action==1 || Action==2) { ById('pbreMessages').innerHTML = "Reassign routes deleted!"; }
		else {
			if (Action==3 || Action==4) { ById('pbreMessages').innerHTML = "Reassign routes relocated!"; }
		}
		t.PaintRoutes();
	},

	DeleteRoute : function (entry) {
		var t = Tabs.Reassign;
		Options.ReassignOptions.Routes.splice(entry,1);
		saveOptions();
		ById('pbreMessages').innerHTML = "Reassign route deleted!";
		t.PaintRoutes();
	},

	ToggleActive : function (entry) {
		var t = Tabs.Reassign;
		Options.ReassignOptions.Routes[entry].Active = !Options.ReassignOptions.Routes[entry].Active;
		saveOptions();
		t.updateRoutes();
	},

	SendRoute : function (entry) {
		var t = Tabs.Reassign;
		Options.ReassignOptions.Routes[entry].LastChecked = 0;
		saveOptions();
		t.updateRoutes();
	},

	EditRoute : function (entry) {
		var t = Tabs.Reassign;
		t.EditRouteNumber = entry;
		t.EditMode = true;
		ById('pbreMessages').innerHTML = "&nbsp;";

		t.RouteObject = {};
		for (var y in Options.ReassignOptions.Routes[t.EditRouteNumber]) {
			t.RouteObject[y] = Options.ReassignOptions.Routes[t.EditRouteNumber][y];
		}
		if (!t.RouteObject.OverrideTime) {
			t.RouteObject.Interval = Options.ReassignOptions.ReassignInterval;
		}
		t.PaintNewRoutePanel();
	},

	NewRoute : function () {
		var t = Tabs.Reassign;
		t.EditRouteNumber = -1;
		t.EditMode = true;
		ById('pbreMessages').innerHTML = "&nbsp;";

		if (!t.RouteObject) {
			t.RouteObject = {};
			for (var y in t.NewRouteObject) {
				t.RouteObject[y] = t.NewRouteObject[y];
			}
			t.RouteObject.Interval = Options.ReassignOptions.ReassignInterval;
		}
		t.PaintNewRoutePanel();
	},

	show : function (){
		var t = Tabs.Reassign;
		t.PaintOverview();
		if (t.EditMode) { t.updateResources(); }
		else { t.updateRoutes(); }
	},

	EverySecond : function () {
		var t = Tabs.Reassign;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh reassign march speed and overview display every 2 seconds
			t.marchspeed = Math.floor(equippedthronestats(67))+Math.floor(equippedthronestats(71)); // march speed is reassign and general march speed added together
			if (tabManager.currentTab.name == 'Reassign' && Options.btWinIsOpen){
				t.PaintOverview();

				if (t.EditMode) { // paint from and to city resources
					t.updateResources();
				}
				else { // paint time on each route?
					t.updateRoutes();
				}
			}
		}
	},

	PaintOverview : function () {
		var t = Tabs.Reassign;

		if (Options.ReassignOptions.ThroneCheck && (t.marchspeed < Number(Options.ReassignOptions.MarchSpeed))) {
			ts = '<span class=boldRed><b>'+t.marchspeed+'%</b></span>';
		}
		else { ts = t.marchspeed+'%'; }
		ById("btreMarchCurrTR").innerHTML = ts;
	},

	PaintNewRoutePanel : function () {
		var t = Tabs.Reassign;
		var fromidx = null;
		var toidx = null;

		if (t.EditRouteNumber<0) {
			var z= '<div class=divHeader align=center>'+tx('NEW REASSIGN ROUTE')+'</div><br>';
			fromidx = Cities.byID[uW.currentcityid].idx; // default new route from current city
		}
		else {
			var z= '<div class=divHeader align=center>'+tx('EDIT REASSIGN ROUTE')+'</div><br>';
		}

		// remember last route details.... (or saved route details)

		if (Cities.byID[t.RouteObject.cityId]) {
			fromidx = Cities.byID[t.RouteObject.cityId].idx;
		}
		if (Cities.byID[t.RouteObject.target_cityId]) {
			toidx = Cities.byID[t.RouteObject.target_cityId].idx;
		}

		z += '<TABLE align=left class=xtab>';
		z += '<TR><TD align=right>&nbsp;'+tx("From City")+':&nbsp;</td><TD><span id=pbrfromcity></span></td></tr>';
		z += '<TR><TD align=right>&nbsp;'+tx("To City")+':&nbsp;</td><TD><span id=pbrtocity></span></td></tr>';

		z += '<TR><TD align=right>&nbsp;</td><TD><INPUT id=pbroverrideintervalchk type=checkbox '+(t.RouteObject.OverrideTime?'CHECKED':'')+'>&nbsp;'+tx('Override reassign interval')+'</td><TD align=right>'+tx("Reassign Interval")+':&nbsp;</td><TD><INPUT  id=pbroverrideinterval type=text size=2 value="' + t.RouteObject.Interval+'" '+(t.RouteObject.OverrideTime?'':'disabled')+' \> '+tx("minutes")+'</td></tr>';
		z += '<TR><TD align=right>&nbsp;</td><TD><INPUT id=pbrselectall type=checkbox>&nbsp;'+tx('Select/Unselect ALL')+'</td><TD align=right>&nbsp;</td><TD><INPUT id=pbrzeroise type=button value="'+tx("Zeroise values")+'"\>&nbsp;<INPUT id=pbrdefault type=button value="'+tx("Default city values")+'"\></td></tr>';
		z += '</table><br>';

		var c = 0;
		var LineBreak = 7;
		if (GlobalOptions.btWinSize.x == 750) {LineBreak = 5;}
		if (GlobalOptions.btWinSize.x == 1250) {LineBreak = 8;}
		z += '<table class=xtab cellpadding=4 cellspacing=0 align="center"><tr>';
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			var n = '<td><table class=xtab cellspacing=0 cellpadding=0><tr style="vertical-align:top;"><td rowspan=2 width="30px">'+TroopImageBig(i)+'</td><td>'+uW.unitnamedesctranslated['unt'+i][0]+'</td></tr>';
			n += '<tr><td><INPUT type=CHECKBOX id="chkRein'+i+'" '+(t.RouteObject.troops[i]?'CHECKED':'')+'></td></tr>';
			n += '<tr><td align=right>'+tx('Keep')+':</td><td><INPUT class=btInput id="pbReinKeep'+i+'" type=text size=11 maxlength=12 value="'+(t.RouteObject.keep[i]||0)+'" '+(t.RouteObject.troops[i]?'':'disabled')+' \></td></tr></table></td>';
			if (c%LineBreak==0) z+= '</tr><tr>';
			z+=n;
			c++;
		}
		z += '</table>'

		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td>&nbsp;</td><td align=center>'+strButton20(tx('Save Route'), 'id=pbreSaveRoute')+'&nbsp;';
		if (t.EditRouteNumber>=0) { z += strButton20(tx('Save a Copy'), 'id=pbreCopyRoute')+'&nbsp;'; }
		z += strButton20(uW.g_js_strings.commonstr.cancel, 'id=pbreCancelRoute')+'</td><td align=right>&nbsp;</td></tr></table></div>';

		ById('pbreRouteDetail').innerHTML = z;

		t.dcp0 = new CdispCityPicker('pbreassignfrom', ById('pbrfromcity'), true, t.updateResources, fromidx);
		t.dcp1 = new CdispCityPicker('pbreassignto', ById('pbrtocity'), true, t.updateResources, toidx);

		ById('pbroverrideintervalchk').addEventListener('click', function () {
			var disablerow = (!ById('pbroverrideintervalchk').checked);
			ById('pbroverrideinterval').disabled = disablerow;
			if (disablerow) {
				ById('pbroverrideinterval').value = Options.ReassignOptions.ReassignInterval;
			}
		}, false);
		ById('pbrzeroise').addEventListener('click', function() {
			for (var ui in uW.cm.UNIT_TYPES){
				var i = uW.cm.UNIT_TYPES[ui];
				ById('pbReinKeep'+i).value = 0;
			}
		}, false);
		ById('pbrdefault').addEventListener('click', function() {
			if (t.dcp0 && t.dcp0.city) {
				for (var ui in uW.cm.UNIT_TYPES){
					var i = uW.cm.UNIT_TYPES[ui];
					ById('pbReinKeep'+i).value = getCityTroops(i,t.dcp0.city.id,true);
				}
			}
		}, false);
		ById('pbrselectall').addEventListener('click', function() {
			for (var ui in uW.cm.UNIT_TYPES){
				var i = uW.cm.UNIT_TYPES[ui];
				ById('chkRein'+i).checked = ById('pbrselectall').checked;
				ById('pbReinKeep'+i).disabled = (!ById('pbrselectall').checked);
			}
		}, false);

		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			t.addListeners(i);
		}

		ById('pbreSaveRoute').addEventListener ('click', function() {t.SaveRoute(false);}, false);
		if (ById('pbreCopyRoute')) { ById('pbreCopyRoute').addEventListener ('click', function() {t.SaveRoute(true);}, false); }
		ById('pbreCancelRoute').addEventListener ('click', function() {t.RouteObject = null; t.PaintRoutes();}, false);

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
		t.updateResources();
	},

	addListeners : function(Troop) {
		var T1 = 'pbReinKeep'+Troop;
		var T2 = 'chkRein'+Troop;
		ById(T1).addEventListener('keyup', function(){ if (isNaN(ById(T1).value)) ById(T1).value=0; }, false);
		ById(T2).addEventListener('click', function(){ ById(T1).disabled = (!ById(T2).checked); },false);
	},

	SaveRoute : function (CopyRoute) {
		var t = Tabs.Reassign;

		if (!t.validateScreenFields('save')) { return; }

		if (t.EditRouteNumber<0 || CopyRoute) {
			Options.ReassignOptions.Routes.push(JSON2.parse(JSON2.stringify(t.RouteObject))); // create new object in array
			if (CopyRoute) { t.RouteObject = null; } // clear route object
		}
		else {
			t.RouteObject.LastChecked = 0;
			Options.ReassignOptions.Routes[t.EditRouteNumber] = t.RouteObject;
			t.RouteObject = null; // clear route object
		}
		ById('pbreMessages').innerHTML = tx("Reassign route saved")+"!";
		t.PaintRoutes();
	},

	validateScreenFields : function (action) {
		var t = Tabs.Reassign;

		if (!t.dcp0.city) {
			ById('pbreMessages').innerHTML = tx("No source city selected");
			return false;
		}
		if (!t.dcp1.city) {
			ById('pbreMessages').innerHTML = tx("No destination city selected");
			return false;
		}
		if(t.dcp0.city.id==t.dcp1.city.id){
			ById('pbreMessages').innerHTML = tx("Cannot reassign to the same city")+"!";
			return false;
		}

		// copy screen fields to routeobject

		t.RouteObject.cityId = t.dcp0.city.id;
		t.RouteObject.target_cityId = t.dcp1.city.id;

		t.RouteObject.troops = {};
		t.RouteObject.keep = {};

		var gottroops = false;
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			if (ById('chkRein'+i).checked) {
				gottroops = true;
				t.RouteObject.troops[i] = true;
				t.RouteObject.keep[i] = parseIntNan(ById('pbReinKeep'+i).value);
			}
		}

		if(!gottroops){
			ById('pbreMessages').innerHTML = tx("You must reassign something")+"!";
			return false;
		}

		t.RouteObject.OverrideTime = ById('pbroverrideintervalchk').checked;
		t.RouteObject.Interval = parseIntNan(ById('pbroverrideinterval').value);

		// validation OK!
		return true;
	},

	updateResources : function () {
		var t = Tabs.Reassign;
		if (!t.dcp0 || !t.dcp0.city) return;
		// at the moment nothing to do!
	},

	updateRoutes : function () {
		var t = Tabs.Reassign;

		if (!tabManager.currentTab || tabManager.currentTab.name != 'Reassign' || !Options.btWinIsOpen) { return; }

		var n = Options.ReassignOptions.Routes.length;
		while (n--) {
			var a = Options.ReassignOptions.Routes[n];
			var elstat = ById('pbreRouteStatus'+n);
			if (elstat) {
				elstat.innerHTML = '<span><br><br></span>';
				if (Options.ReassignOptions.Running) {
					if (a.Active) {
						if (Options.ReassignOptions.ThroneCheck && (t.marchspeed < Options.ReassignOptions.MarchSpeed)) {
							elstat.innerHTML = '<span class=boldRed>'+tx('March')+'<br>'+tx('Speed')+'!<br></span>';
						}
						else {
							var now = unixTime();
							var interval = Options.ReassignOptions.ReassignInterval*60;
							if (a.OverrideTime) { interval = a.Interval*60; }
							var due = a.LastChecked+interval;
							if (due < now) {
								elstat.innerHTML = '<span class=boldGreen>'+tx('Checking')+'...<br><br></span>';
							}
							else {
								elstat.innerHTML = uW.timestr(due-now)+'<br><a id="pbreRouteCheck'+n+'" onclick="pbreSendRoute('+n+')"><span>Check Now</span></a>';
							}
						}
					}
				}
			}
		}
	},

	doAutoLoop : function (idx,rev) {
		var t = Tabs.Reassign;
		clearTimeout(t.timer);
		if (!Options.ReassignOptions.Running) return;

		if (idx>=Options.ReassignOptions.Routes.length) { idx=0; } // safety, if route(s) have been deleted.
		if (idx==0 && !rev) { t.loopaction = false; } // reset loop march indicator for first march
		t.autodelay = 0; // no delay if no action taken...

		if (idx<Options.ReassignOptions.Routes.length) {
			var a = Options.ReassignOptions.Routes[idx];

			if (a.Active) {
				var now = unixTime();
				var interval = Options.ReassignOptions.ReassignInterval*60;
				if (a.OverrideTime) { interval = a.Interval*60; }
				var due = a.LastChecked+interval;
				if ((due < now) || rev) {
					// check if march is required...
					t.more = false;
					t.doReassigns(idx,rev);
					if (!rev) {
						if (!t.more) {
							Options.ReassignOptions.Routes[idx]["LastChecked"] = uW.unixtime();
							saveOptions();
							t.updateRoutes();
						}
						if (Options.ReassignOptions.ReverseReassign) {  // check for reverse reassign on this route
							t.timer = setTimeout(function () { t.doAutoLoop(idx,true); }, (t.autodelay * 1000));
							return;
						}
					}
				}
			}
		}

		if (idx >= Options.ReassignOptions.Routes.length-1) {
			if (!t.loopaction) { t.autodelay = Options.ReassignOptions.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(0,false); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1,false); }, (t.autodelay * 1000));
		}
	},

	doReassigns: function(idx,rev){
		var t = Tabs.Reassign;
		var a = Options.ReassignOptions.Routes[idx];

		if (Options.ReassignOptions.ThroneCheck && (t.marchspeed < Options.ReassignOptions.MarchSpeed)) { return; } // if not enough march speed

		if (!rev) {
			var sourcecityId = parseIntNan(a["cityId"]);
			var destcityId = a["target_cityId"];
		}
		else {
			if (a["rev_eta"] && parseInt(a["rev_eta"]) > uW.unixtime()) { return; } // only one reverse reassign on each route at a time
			var sourcecityId = a["target_cityId"];
			var destcityId = parseIntNan(a["cityId"]);
		}

		if (!Cities.byID[sourcecityId]) { return; } // no source city!
		if (!Cities.byID[destcityId]) { return; } // no destination city!

		var towerok = (!Options.TowerOptions || !Options.TowerOptions.SaveCityState[sourcecityId] || Options.TowerOptions.SaveCityState[sourcecityId].AllowMarches);
		if (!towerok) { return; } // source city under attack!

		var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[Cities.byID[sourcecityId].idx]);
		if (!ascensionok) { return; } // source city waiting to ascend!

		var targetname = Cities.byID[destcityId].name;
		var xcoord = Cities.byID[destcityId].x;
		var ycoord = Cities.byID[destcityId].y;

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = sourcecityId;
		params.kid = 0;
		if (Options.ReassignOptions.ReassignKnights && !rev) {
			var knt = getAvailableKnights(sourcecityId);
			if (knt[0]) {
				knt = knt.sort(function sort(a,b) {a = a['ID'];b = b['ID'];return a == b ? 0 : (a < b ? -1 : 1);}); // sort by reverse id
				params.kid = knt[0].ID;
			}
		}
		params.type = 5;
		params.xcoord = xcoord;
		params.ycoord = ycoord;
		params.r1 = 0;
		params.r2 = 0;
		params.r3 = 0;
		params.r4 = 0;
		params.r5 = 0;
		params.gold = 0;
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			params["u"+i] = 0;
		}

		var maxsend = March.getMaxSize(sourcecityId);
		var totalsend = 0;

		var slots = Number(March.getEmptySlots(sourcecityId));
		if (parseInt(slots) <=Number(Options.FreeRallySlots)) { // no free slots - don't bother server!
			if (GlobalOptions.ExtendedDebugMode) {actionLog(Cities.byID[sourcecityId].name+": No available rally slots",'REASSIGN');}
			return;
		}

		var troopidx = [];
		for (var ui in uW.cm.UNIT_TYPES){
			troopidx.push(uW.cm.UNIT_TYPES[ui]);
		}
		for (var j=troopidx.length-1; j>=0; j--) { // reverse order
			var i = troopidx[j];
			if (!Options.ReassignOptions.Routes[idx].troops[i]) { continue; }
			if (!Seed.cityData.city[destcityId].isPrestigeCity && ((i==13) || (i==14) || (i==15))) {continue; }
			var keepvalue = parseIntNan(Options.ReassignOptions.Routes[idx].keep[i]);
			var availtroops = parseIntNan(Seed.units['city'+sourcecityId]['unt'+i]);

			if (!rev) {
				var citytotal = getCityTroops(i,sourcecityId,true);

				if (citytotal > keepvalue) {
					var sendtroops = parseIntNan(citytotal - keepvalue);
					if (sendtroops > availtroops)  { sendtroops = availtroops; }
					if (sendtroops < 0) { sendtroops = 0; }
					params["u"+i] = sendtroops;
					totalsend += sendtroops;
				}
			}
			else {
				var citytotal = getCityTroops(i,destcityId,true);

				if (citytotal < keepvalue) {
					var sendtroops = parseIntNan(keepvalue - citytotal);
					if (sendtroops > availtroops)  { sendtroops = availtroops; }
					if (sendtroops < 0) { sendtroops = 0; }
					params["u"+i] = sendtroops;
					totalsend += sendtroops;
				}
			}

			if(totalsend > maxsend){
				totalsend -= sendtroops;
				params["u"+i] = parseInt(maxsend-totalsend);
				totalsend = maxsend;
				t.more = true;
				break;
			}
		}

		if (totalsend > 0) { // final safety net
			t.autodelay = Options.ReassignOptions.intervalSecs; // march is required, so delay subsequent loop
			t.loopaction = true;

			March.addMarch(params, function(rslt){
				if (rslt.ok) {
					if (!rev) {
						actionLog(Cities.byID[sourcecityId].name+": "+totalsend+" troops reassigned to "+targetname,'REASSIGN');
					}
					else {
						actionLog(Cities.byID[sourcecityId].name+": "+totalsend+" troops reverse-reassigned to "+targetname,'REASSIGN');
						Options.ReassignOptions.Routes[idx]["rev_eta"] = parseInt(rslt.eta);
						saveOptions();
					}
				}
				else {
					if (!rslt.msg) {rslt.msg = 'Error Code ('+rslt.error_code+')';}
					if (!rev) { actionLog(Cities.byID[sourcecityId].name+": Reassign Error - "+rslt.msg,'REASSIGN'); }
					else { actionLog(Cities.byID[sourcecityId].name+": Reverse Reassign Error - "+rslt.msg,'REASSIGN'); }
				}
			});
		}
	},
}

/*********************************** Attack Tab ***********************************/

Tabs.Attack = {
	tabOrder: 2050,
	tabLabel : 'Attack',
	tabColor : 'brown',
	myDiv : null,
	dcp0 : null,
	timer : null,
	autodelay : 0,
	loopaction : false,
	mercmode : 0,
	mercmatch : {},
	searchval : '',
	LoopCounter : 0,
	EditRouteNumber : -1,
	EditMode : false,
	CrestList  : [1101,1102,1103,1104,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115],
	AttackOrder : [], // for randomising attack order
	Options : {
		Running: false,
		Toggle : false,
		intervalSecs  : 5,
		Randomize : false,
		Routes : [],
		AttackReport : false,
		AttackReportInterval : 1,
		AttackReportEmail : false,
		LastAttackReport : 0,
		MercRunning : false,
		MercItem : '31228',
		MercTarget : '',
		Wave1Count : 0,
		Wave2Count : 0,
		FreeRallySlots : 2,
	},
	NewRouteObject : {
		cityId: null,
		target_x: '',
		target_y: '',
		isWild: false,
		ChampOnly: false,
		RoundOne: false,
		RoundOneTroops: {},
		LastRoundOne: 0,
		RoundTwo:true,
		RoundTwoTroops: {},
		LastRoundTwo: 0,
		Active: true,
	},
	RouteObject : null,

	init : function (div) {
		var t = Tabs.Attack;
		t.myDiv = div;

		if (!Options.AttackOptions) {
			Options.AttackOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.AttackOptions.hasOwnProperty(y)) {
					Options.AttackOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction ('pbatDeleteRoute', Tabs.Attack.DeleteRoute);
		uWExportFunction ('pbatEditRoute', Tabs.Attack.EditRoute);
		uWExportFunction ('pbatToggleActive', Tabs.Attack.ToggleActive);

		if (Options.AttackOptions.Toggle) AddSubTabLink('Attack',t.toggleAutoAttackState, 'AttackToggleTab');
		SetToggleButtonState('Attack',Options.AttackOptions.Running,'Attack');

		var m = '<DIV class=divHeader align=center>'+tx('AUTOMATED ATTACKS')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btAttackToggle type=checkbox '+ (Options.AttackOptions.Toggle?'CHECKED ':'') +'/>&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoAttackState type=submit value="'+tx("Attack")+' = '+ (Options.AttackOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td align=left><INPUT id=pbattackrandom type=checkbox '+ (Options.AttackOptions.Randomize?'CHECKED ':'') +'/></td><td>'+tx("Randomize attack order")+'</td><td align=right>&nbsp;'+tx("Attack Interval:")+'&nbsp;<INPUT id=pbattackinterval type=text size=2 value="' + Options.AttackOptions.intervalSecs+'"\> '+tx("seconds")+'</td></tr>';
		m += '<tr><td align=left><INPUT id=pbattackreport type=checkbox '+ (Options.AttackOptions.AttackReport?' CHECKED':'') +'\></td><td align=left>'+tx("Send attack report every")+'&nbsp;<INPUT id=pbattackreportinterval value='+ Options.AttackOptions.AttackReportInterval +' type=text size=3 \>&nbsp;'+tx('hours')+'&nbsp;&nbsp;&nbsp;'+strButton8(tx('Send Now'), 'id=pbattackreportsend')+'</td>';
		m += '<td align=right>'+tx("Keep")+' <INPUT id=btatfreerallyslots type=text size=2 maxlength=2 value="'+Options.AttackOptions.FreeRallySlots+'"\> '+tx("free rally point slots")+'</td></tr>';
		if (uW.koc2Mail) {
			m += '<tr id=pbattackreportemaildiv><td>&nbsp;</td><td><INPUT id=pbattackreportemail type=checkbox '+ (Options.AttackOptions.AttackReportEmail?' CHECKED':'') +'\>&nbsp;'+tx("CC to Email")+'</td></tr>';
		}
		m += '<tr><td colspan=3 align=left><b>'+tx('Mercenary Camp Prize Target')+'</b></td></tr>';
		m += '<tr><td colspan=3 align=left id=pbatmercdiv></td></tr>';
		m += '</table>';
		m += '<div id=pbatMessages align=center>&nbsp;</div>';
		m += '<div id=pbatRouteDetail>&nbsp;</div><br>';

		div.innerHTML = m;
		t.PaintMercDiv();

		ToggleOption('AttackOptions','btAttackToggle','Toggle');

		ById('btAutoAttackState').addEventListener('click', function(){
			t.toggleAutoAttackState(this);
		}, false);

        ById('pbattackinterval').addEventListener('keyup', function () {
            if (parseIntNan(ById('pbattackinterval').value)<1) { ById('pbattackinterval').value = 6; }
            if (parseIntNan(ById('pbattackinterval').value)<2) { ById('pbattackinterval').value = 2; }
            Options.AttackOptions.intervalSecs = parseIntNan(ById('pbattackinterval').value);
            saveOptions();
        }, false);

        ById('pbattackreportsend').addEventListener('click', function () {
            Options.AttackOptions.LastAttackReport = 0;
            saveOptions();
			t.sendAttackReport();
        }, false);
		ChangeIntegerOption('AttackOptions','pbattackreportinterval','AttackReportInterval',1,t.sendAttackReport);
		ChangeIntegerOption('AttackOptions','btatfreerallyslots','FreeRallySlots');

		ToggleOption('AttackOptions','pbattackrandom','Randomize');
		ToggleOption('AttackOptions','pbattackreport','AttackReport',t.sendAttackReport);
		if (uW.koc2Mail) {
			ToggleOption('AttackOptions','pbattackreportemail','AttackReportEmail');
		}

		t.PaintRoutes();
		t.sendAttackReport(); // check every refresh

		// start autoattack loop timer to start in 8 seconds...

		if (Options.AttackOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, (8 * 1000));
		}
	},

	PaintMercDiv : function () {
		var t = Tabs.Attack;
		var m = '<table class=xtab cellpadding=0 cellspacing=0 width=100%><tr><td>';
		if (t.mercmode == 0) {
			var itemname = '<span class=boldRed>'+tx('Unknown Item')+'!</span>';
			if (uW.itemlist["i"+Options.AttackOptions.MercItem]) {
				itemname = uW.itemlist["i"+Options.AttackOptions.MercItem].name;
			}
			m += '<a id=pbmercsearch title="'+tx('Click to search by item name')+'">'+tx('Chest ID')+':</a>&nbsp;<INPUT id=pbmercitem type=text size=5 maxlength=8 value="'+ Options.AttackOptions.MercItem +'">&nbsp;&nbsp;&nbsp;'+itemname+'</td>';
		}
		if (t.mercmode == 1) {
			m += tx('Chest Name')+':&nbsp;<INPUT id=pbmercsearchname type=text style="width:180px;" maxlength=20 value="'+t.searchval+'">&nbsp;'+strButton8('Search','id=pbmercsearchbutton')+'&nbsp;'+strButton8(uW.g_js_strings.commonstr.cancel,'id=pbmercsearchcancel')+'</td>';
		}
		if (t.mercmode == 2) {
			m += tx('Chest Name')+':&nbsp;'+htmlSelector(t.mercmatch,0, 'id=pbmercselectlist style="width:180px;"')+'&nbsp;'+strButton8(uW.g_js_strings.commonstr.cancel,'id=pbmercsearchcancel')+'</td>';
		}
		m += '<td align=right>'+uW.g_js_strings.commonstr.target+':&nbsp;<INPUT id=pbmerctarget type=text size=3 \>&nbsp;&nbsp;'+tx('Current')+':&nbsp;<span id=pbcurrmerc></span>&nbsp;&nbsp;<a title="'+tx('automatically use excess items')+'" id=pbautomercstate class="inlineButton btButton '+(Options.AttackOptions.MercRunning?'red14':'blue14')+'"><span id=pbautomerclabel style="width:30px;display:inline-block;text-align:center;">'+(Options.AttackOptions.MercRunning?tx('Off'):tx('Auto'))+'</span></a></td></tr></table>';
		ById('pbatmercdiv').innerHTML = m;
		t.UpdateMercTarget();

		ById('pbautomercstate').addEventListener('click', function(){
			t.toggleAutoMercState(this);
		}, false);

		ChangeIntegerOption('AttackOptions','pbmerctarget','MercTarget',0,t.UpdateMercTarget);

		if (t.mercmode == 0) {
			ById("pbmercitem").addEventListener('change', function(e){
				Options.AttackOptions.MercItem = parseIntNan(e.target.value);
				if (Options.AttackOptions.MercRunning) { t.toggleAutoMercState(); }
				saveOptions();
				t.UpdateMercTarget();
				t.PaintMercDiv();
			},false);
			ById("pbmercsearch").addEventListener('click', function(){
				t.mercmode = 1;
				t.PaintMercDiv();
			},false);
		}
		if (t.mercmode == 1) {
			ById("pbmercsearchcancel").addEventListener('click', function(){
				ById('pbatMessages').innerHTML = "&nbsp;";
				t.mercmode = 0;
				t.PaintMercDiv();
			},false);
			ById("pbmercsearchbutton").addEventListener('click', function(){
				t.mercmode = 0;
				t.searchval = ById('pbmercsearchname').value.toUpperCase();
				if (t.searchval.length <3) {
					ById('pbatMessages').innerHTML = uW.g_js_strings.getAllianceSearchResults.entryatleast3;
					return;
				}
				ById('pbatMessages').innerHTML = tx("Searching...");
				t.MercItemSearch(t.searchval);
			},false);
		}
		if (t.mercmode == 2) {
			ById("pbmercsearchcancel").addEventListener('click', function(){
				ById('pbatMessages').innerHTML = "&nbsp;";
				t.mercmode = 1;
				t.PaintMercDiv();
			},false);
			ById("pbmercselectlist").addEventListener('change', function(e){
				ById('pbatMessages').innerHTML = "&nbsp;";
				Options.AttackOptions.MercItem = e.target.value;
				if (Options.AttackOptions.MercRunning) { t.toggleAutoMercState(); }
				saveOptions();
				t.mercmode = 0;
				t.PaintMercDiv();
			},false);
		}
	},

	MercItemSearch : function (searchval) {
		var t = Tabs.Attack;
		t.mercmatch = {};
		t.mercmatch[0] = "-- "+tx('Select Item')+" --";
		for (var i in uW.itemlist) {
			var item = uW.itemlist[i];
			var id = i.split('i')[1];
			if (item.name.toUpperCase().indexOf(searchval) != -1) {
				t.mercmatch[id] = item.name+' ('+id+')';
			}
		}
		var nummatches = Object.keys(t.mercmatch).length;
		if (nummatches==1) {
			ById('pbatMessages').innerHTML = tx("No matching items found");
			return;
		}
		if (nummatches==2) {
			ById('pbatMessages').innerHTML = "&nbsp;";
			Options.AttackOptions.MercItem = Object.keys(t.mercmatch)[1];
			if (Options.AttackOptions.MercRunning) { t.toggleAutoMercState(); }
			saveOptions();
			t.mercmode = 0;
			t.PaintMercDiv();
		}
		else {
			ById('pbatMessages').innerHTML = tx("Please select an item");
			t.mercmode = 2;
			t.PaintMercDiv();
		}
	},

	UpdateMercTarget : function() {
		var t = Tabs.Attack;
		ById("pbcurrmerc").innerHTML = parseIntNan(Seed.items["i"+Options.AttackOptions.MercItem]);
		if (parseIntNan(Seed.items["i"+Options.AttackOptions.MercItem]) >= parseIntNan(Options.AttackOptions.MercTarget)) {
			jQuery('#pbcurrmerc').css('color', 'green');
		}
		else {
			jQuery('#pbcurrmerc').css('color', 'black');
		}
	},

	checkMercItemLimit : function () {
		var t = Tabs.Attack;
		if (!Options.AttackOptions.MercRunning) return;
		if (isNaN(Options.AttackOptions.MercItem) || Options.AttackOptions.MercItem == 0) return;
		if (isNaN(Options.AttackOptions.MercTarget) || Options.AttackOptions.MercTarget == 0) return;
		var item = uW.ksoItems[Options.AttackOptions.MercItem];
		if (item) {
			var useamount = parseIntNan(item.count - parseIntNan(Options.AttackOptions.MercTarget));
			if (useamount>0) { // automatically use items to bring amount down...
				if (!item.usable) { // can't use so log it!
					actionLog('Unable to use Mercenary Prize Chest Item','ATTACK');
				}
				else {
					actionLog('Attempting to use '+useamount+' '+item.name,'ATTACK');
					if (uW.itemlist['i'+Options.AttackOptions.MercItem] && uW.itemlist['i'+Options.AttackOptions.MercItem].subCategory==100) {
						t.useMysteryChest(Options.AttackOptions.MercItem,useamount);
					}
					else {
						ItemMultiUseController.UseItems(Options.AttackOptions.MercItem,useamount);
					}
				}
			}
		}
		var now = unixTime();
		Options.AttackOptions.LastMercChecked = now;
		saveOptions();
	},

	useMysteryChest : function (itemId,quantity) {
		var t = Tabs.Attack;

		function addItemsToSeed(items) {
			jQuery.each(items, function (key, value) {
				if (Seed.items["i" + key]) {
					Seed.items["i" + key] = (parseInt(Seed.items["i" + key]) + parseInt(value)).toString();
					uW.ksoItems[key].add(Number(value))
				} else {
					Seed.items["i" + key] = value.toString();
					uW.ksoItems[key].add(Number(value))
				}
			})
		}

		params = uW.Object.clone(uW.g_ajaxparams);
		params.chestId = itemId;
		params.cid = uW.currentcityid;
		params.quantity = quantity;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/useMysteryChest.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					CM.InventoryView.removeItemFromInventory(itemId, params.quantity);
					addItemsToSeed(rslt.items);
				}
			},
		},true);
	},

	toggleAutoAttackState: function(obj){
		var t = Tabs.Attack;
		obj = ById('btAutoAttackState');
		if (Options.AttackOptions.Running == true) {
			Options.AttackOptions.Running = false;
			obj.value = tx("Attack = OFF");
			clearTimeout(t.timer);
		}
		else {
			Options.AttackOptions.Running = true;
			obj.value = tx("Attack = ON");
			// clear the last round one field on all routes
			var n = Options.AttackOptions.Routes.length;
			while (n--) {
				Options.AttackOptions.Routes[n].LastRoundOne = 0;
			}
			t.timer = setTimeout(function () { t.doAutoLoop(0,false);}, 0);
			t.sendAttackReport(); // check
		}
		saveOptions();
		SetToggleButtonState('Attack',Options.AttackOptions.Running,'Attack');
	},

	toggleAutoMercState: function(obj){
		var t = Tabs.Attack;
		obj = ById('pbautomerclabel');
		if (Options.AttackOptions.MercRunning == true) {
			Options.AttackOptions.MercRunning = false;
			obj.innerHTML = tx("Auto");
			jQuery('#pbautomercstate').removeClass("red14");
			jQuery('#pbautomercstate').addClass("blue14");
		}
		else {
			Options.AttackOptions.MercRunning = true;
			obj.innerHTML = tx("Off");
			jQuery('#pbautomercstate').addClass("red14");
			jQuery('#pbautomercstate').removeClass("blue14");
			Options.AttackOptions.LastMercChecked = 0;
		}
		saveOptions();
	},

	ClearRoutes : function() {
		var t = Tabs.Attack;
		Options.AttackOptions.Routes = [];
		saveOptions();
		ById('pbatMessages').innerHTML = tx("All attack routes deleted!");
		t.PaintRoutes();
	},

	PaintRoutes : function () {
		var t = Tabs.Attack;

		t.EditMode = false;
		var z = '';
		var r = 0;

		var bclass = "blue14";
		var btext  = "Clear Routes";
		var Routes = false;

		var z= '<div class=divHeader align=center>'+tx('ATTACK ROUTES')+'</div><br>';
		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td width=90px>'+strButton20(tx('New Route'), 'id=pbatNewRoute')+'</td>';
		z += '<td align=left id=pbatbulkactions>&nbsp;</td>';
		z += '<td align=right>'+strButton20(tx('Delete ALL Routes'), 'id=pbatClearRoutes')+'&nbsp;</td></tr></table>';
		z += '<div style="max-height:535px;overflow-y:scroll;width:'+GlobalOptions.btWinSize.x+'px";overflow-x:auto" align="center"><TABLE id=pbatRoutesTable cellSpacing=0 width=100% height=0%><tr><td class="xtabHD" style="width:100px"><b>'+tx('City')+'</b></td><td style="width:100px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.target+'</b></td><td style="width:100px" class="xtabHD"><b>'+uW.g_js_strings.commonstr.options+'</b></td><td class="xtabHD"><b>'+uW.g_js_strings.commonstr.troops+'</b><td class="xtabHD" align="center" style="width:90px"><b>'+tx('Active')+'</b></td><td class="xtabHD" align="right" style="width: 115px"><span id=pbatnumroutes>'+Options.AttackOptions.Routes.length+'</span> '+tx('Routes')+'</td></tr>';

		var FromList = {0:"-- "+tx('Select City')+" --"};
		var BulkAction = {0:"-- "+tx('Select Action')+" --",1:tx("Delete ALL Attacks From"),2:tx("Transfer ALL Attacks From"),3:tx("Disable ALL Attacks From"),4:tx("Enable ALL Attacks From")};
		var CityList = {0:"-- "+tx('Select City')+" --"};
		for (g in Cities.byID) { CityList[Cities.byID[g].id] = Cities.byID[g].name; }

		var n = Options.AttackOptions.Routes.length;
		while (n--) {
			var a = Options.AttackOptions.Routes[n];
			var fromname = '<span class=boldRed>'+tx('No City')+'!</span>';
			var fid = -1;
			if (Cities.byID[a.cityId]) { fromname = Cities.byID[a.cityId].name; fid = a.cityId; }
			FromList[fid] = fromname;
			var toname = coordLink(a.target_x,a.target_y);

			Routes = true;
			r=r+1;
			rowClass = 'evenRow';
			var rem = (r % 2);
			if (rem == 1) rowClass = 'oddRow';

			z += '<tr class="'+rowClass+'">';
			z += '<TD style="width:100px" class=xtab valign=top>'+fromname+'</td>';
			z += '<TD style="width:100px" class=xtab valign=top>'+toname+'</td>';
			var RouteOpts = '';
			if (a.isWild) RouteOpts += tx('Is Wild')+'<BR>';
			if (a.ChampOnly) RouteOpts += tx('Champ Only');
			z += '<TD style="width:100px;" class=xtab valign=top>'+RouteOpts+'</td>';

			var zz = '<table cellpadding=0 cellspacing=0 class=xtab><tr valign=top>';

			var LineBreak = 4;
			if (GlobalOptions.btWinSize.x == 750) {LineBreak = 2;}
			if (GlobalOptions.btWinSize.x == 1250) {LineBreak = 5;}

			if (a.RoundOne) {
				zz += '<td width=60px style="padding-top:5px;"><b>'+tx('Wave')+' 1:&nbsp;</b></td><td><table cellpadding=0 cellspacing=1 class=xtab><tr>';
				var c = 0;
				for (var ui in uW.cm.UNIT_TYPES){
					var i = uW.cm.UNIT_TYPES[ui];
					if (a.RoundOneTroops[i]) {
						var nn = '<TD width=30px>'+TroopImage(i)+'</td>';
						nn += '<TD width=150px>'+addCommas(parseIntNan(a.RoundOneTroops[i]))+'</td>';
						if (c%LineBreak==0) zz+= '</tr><tr>';
						zz += nn;
						c++;
					}
				}
				zz += '</tr></table></td></tr><tr valign=top>';
			}

			if (a.RoundTwo) {
				zz += '<td width=60px style="padding-top:5px;"><b>'+tx('Wave')+' 2:&nbsp;</b></td><td><table cellpadding=0 cellspacing=1 class=xtab><tr>';
				var c = 0;
				for (var ui in uW.cm.UNIT_TYPES){
					var i = uW.cm.UNIT_TYPES[ui];
					if (a.RoundTwoTroops[i]) {
						var nn = '<TD width=30px>'+TroopImage(i)+'</td>';
						nn += '<TD width=150px>'+addCommas(parseIntNan(a.RoundTwoTroops[i]))+'</td>';
						if (c%LineBreak==0) zz+= '</tr><tr>';
						zz += nn;
						c++;
					}
				}
				zz += '</tr></table></td>';
			}
			zz += '</tr></table><br>'

			z += '<TD class=xtabBRTop>'+zz+'</td>';
			z += '<TD style="width:90px" class=xtab align=center valign=top><INPUT id="pbatRouteActive'+n+'" type=checkbox '+(a.Active?'CHECKED':'')+' onclick="pbatToggleActive('+n+')" /></td>';
			z += '<TD style="width:100px" class=xtab align=right valign=top><a id="pbatRouteEdit'+n+'" class="inlineButton btButton brown8" onclick="pbatEditRoute('+n+')"><span>Edit</span></a>&nbsp;<a id="pbatRouteDelete'+n+'" class="inlineButton btButton brown8" onclick="pbatDeleteRoute('+n+')"><span>Del</span></a></a></td>';
			z += '</tr>';
		}

		if (!Routes) {
			z += '<tr><td colspan=6 class=xtab><div align="center"><br><br>'+tx('No attack routes')+'</div></td></tr>';
		}

		z += '</table></div><br>';

		ById('pbatRouteDetail').innerHTML = z;
		ById('pbatbulkactions').innerHTML = tx("Bulk Action")+":&nbsp;"+htmlSelector(BulkAction,0,'class=btInput id=pbatbulkaction')+'&nbsp;'+htmlSelector(FromList,0,'class=btInput id=pbatbulkfrom')+'&nbsp;<span id=pbatbulknew class=divHide>To&nbsp;'+htmlSelector(CityList,0,'class=btInput id=pbatbulkto')+'</span>&nbsp;'+strButton8(tx('Go'),'id=pbatbulkgo');

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);

		ById('pbatbulkgo').addEventListener('click', function(){t.DoBulkAction(ById('pbatbulkaction').value,ById('pbatbulkfrom').value,ById('pbatbulkto').value);}, false);
		ById('pbatbulkaction').addEventListener('change', function(e){
			if (e.target.value==2) { jQuery('#pbatbulknew').removeClass("divHide"); }
			else { jQuery('#pbatbulknew').addClass("divHide"); }
		}, false);

		ById('pbatClearRoutes').addEventListener ('click', function() {t.ClearRoutes();}, false);
		ById('pbatNewRoute').addEventListener ('click', function() {t.NewRoute();}, false);
	},

	DoBulkAction : function (Action,From,To) {
		var t = Tabs.Attack;
		ById('pbatMessages').innerHTML = "&nbsp;";
		if (Action==0 || From==0) return;
		if (Action==2 && To==0) return;
		for(var i=Number(Options.AttackOptions.Routes.length-1); i>-1 ;i--) {
			if ((Options.AttackOptions.Routes[i].cityId == From) || (From==-1 && !Cities.byID[Options.AttackOptions.Routes[i].cityId])) {
				if (Action==1) { Options.AttackOptions.Routes.splice(i,1); }
				else {
					if (Action==2) { Options.AttackOptions.Routes[i].cityId = To; }
					else {
						if (Action==3) { Options.AttackOptions.Routes[i].Active = false; }
						else {
							if (Action==4) { Options.AttackOptions.Routes[i].Active = true; }
						}
					}
				}
			}
		}
		saveOptions();
		if (Action==1) { ById('pbatMessages').innerHTML = tx("Attack routes deleted")+"!"; }
		else {
			if (Action==2) { ById('pbatMessages').innerHTML = tx("Attack routes relocated")+"!"; }
		}
		t.PaintRoutes();
	},

	DeleteRoute : function (entry) {
		var t = Tabs.Attack;
		Options.AttackOptions.Routes.splice(entry,1);
		saveOptions();
		ById('pbatMessages').innerHTML = tx("Attack route deleted")+"!";
		t.PaintRoutes();
	},

	ToggleActive : function (entry) {
		var t = Tabs.Attack;
		Options.AttackOptions.Routes[entry].Active = !Options.AttackOptions.Routes[entry].Active;
		saveOptions();
	},

	EditRoute : function (entry) {
		var t = Tabs.Attack;
		t.EditRouteNumber = entry;
		t.EditMode = true;
		ById('pbatMessages').innerHTML = "&nbsp;";

		t.RouteObject = {};
		for (var y in Options.AttackOptions.Routes[t.EditRouteNumber]) {
			t.RouteObject[y] = Options.AttackOptions.Routes[t.EditRouteNumber][y];
		}
		t.PaintNewRoutePanel();
	},

	NewRoute : function (xcoord,ycoord) {
		var t = Tabs.Attack;
		t.EditRouteNumber = -1;
		t.EditMode = true;
		ById('pbatMessages').innerHTML = "&nbsp;";

		if (!t.RouteObject) {
			t.RouteObject = {};
			for (var y in t.NewRouteObject) {
				t.RouteObject[y] = t.NewRouteObject[y];
			}
		}
		if (xcoord && ycoord) {
			t.RouteObject.target_x = xcoord;
			t.RouteObject.target_y = ycoord;
		}
		else {
			if (ById('maparea_map').style.display != "none") {
				t.RouteObject.target_x = ById('mapXCoor').value;
				t.RouteObject.target_y = ById('mapYCoor').value;
			}
		}
		t.PaintNewRoutePanel();
	},

	show : function (){
		var t = Tabs.Attack;
		t.PaintOverview();
	},

	EverySecond : function () {
		var t = Tabs.Attack;
		var now = unixTime();

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh overview display every 2 seconds
			if (tabManager.currentTab.name == 'Attack' && Options.btWinIsOpen){
				t.PaintOverview();
			}
		}

		if (t.LoopCounter%3==0 && Options.AttackOptions.Running) { // check abandon wilds every 3 seconds
			setTimeout(t.checkAbandonWild,0);

			// Check Merc Item Limit
			if (Options.AttackOptions.MercRunning && (Options.AttackOptions.LastMercChecked+60) < now) { // check once a minute, but on a timer!
				t.checkMercItemLimit();
			}
		}

		if (t.LoopCounter%60==0) { // check attack report every minute
			t.sendAttackReport();
			t.LoopCounter = 0;
		}
	},

	PaintOverview : function () {
		var t = Tabs.Attack;
		// update merc items
		t.UpdateMercTarget();
	},

	PaintNewRoutePanel : function () {
		var t = Tabs.Attack;
		var fromidx = null;

		if (t.EditRouteNumber<0) {
			var z= '<div class=divHeader align=center>'+tx('NEW ATTACK ROUTE')+'</div><br>';
			fromidx = Cities.byID[uW.currentcityid].idx; // default new route from current city
		}
		else {
			var z= '<div class=divHeader align=center>'+tx('EDIT ATTACK ROUTE')+'</div><br>';
		}

		// remember last route details.... (or saved route details)

		if (Cities.byID[t.RouteObject.cityId]) {
			fromidx = Cities.byID[t.RouteObject.cityId].idx;
		}

		var MarchPresets = {0:"-- "+tx('Select Preset')+" --"};
		for (var PN in Options.QuickMarchOptions.MarchPresets) {
			MarchPresets[PN] = Options.QuickMarchOptions.MarchPresets[PN][0];
		}

		z += '<TABLE align=left class=xtab>';
		z += '<TR><TD align=right>'+tx("Attack From")+':&nbsp;</td><TD colspan=2><span id=pbatfromcity></span></td></tr>';
		z += '<tr><TD align=right>'+tx("Target Co-ords")+':&nbsp;</td><td colspan=2>X:&nbsp;<INPUT id=pbatX type=text size=3 value="'+t.RouteObject.target_x+'"\>&nbsp;Y:&nbsp;<INPUT id=pbatY type=text size=3 value="'+t.RouteObject.target_y+'"\>&nbsp;&nbsp;&nbsp;<a id=pbatFetchBookmarks>'+tx('Select Bookmark')+':</a>&nbsp;<select id=pbatBookmarks class=btInput style="max-width:180px;"></select></td></tr>';
		z += '<TR><TD colspan=2><INPUT id=pbatwild type=checkbox '+(t.RouteObject.isWild?'CHECKED':'')+'>&nbsp;'+tx('Target is a Wilderness')+'</td><td>('+tx('Auto-abandon wild and reduce wave 1 troops for subsequent attacks')+')</td></tr>';
		z += '<TR><TD colspan=2><INPUT id=pbatchamponly type=checkbox '+(t.RouteObject.ChampOnly?'CHECKED':'')+'>&nbsp;'+tx('Attack with Champion Only!')+'</td><td>('+tx('Champions are only sent on Wave 2')+')</td></tr>';
		z += '</table><br>';

		z += '<TABLE width=100% class=xtab><TR valign=top>';
		z += '<td style="padding-top:3px;"><INPUT type=checkbox id=pbatRound1 '+(t.RouteObject.RoundOne?'CHECKED':'')+'></td><TD style="padding-top:6px;"><b>'+tx('Wave 1')+'</b>&nbsp;('+tx('initial')+'):<br>';
		z += htmlSelector(MarchPresets, 0, 'id=pbatPreset1 class=btInput');
		z += '</td><td><table class=xtab cellspacing=0 cellpadding=0><tr>';

		var LineBreak = 6;
		if (GlobalOptions.btWinSize.x == 750) {LineBreak = 5;}
		if (GlobalOptions.btWinSize.x == 1250) {LineBreak = 8;}
		var c = 0;
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			zz = '<td width=30px style="padding-right:0px;">'+TroopImageBig(i)+'</td><TD><INPUT id=pbatR1_'+i+' type=text size=7 maxlength=7 value="'+(t.RouteObject.RoundOneTroops[i]||0)+'">&nbsp;&nbsp;</td>';
			if (c%LineBreak==0) z+= '</tr><tr>';
			z+=zz;
			c++;
		}

		z += '</tr></table></td></tr><tr><td>&nbsp;</td><td>&nbsp;</td></tr><TR valign=top>';
		z += '<TD style="padding-top:3px;"><INPUT type=checkbox id=pbatRound2 '+(t.RouteObject.RoundTwo?'CHECKED':'')+'><TD style="padding-top:6px;"><b>'+tx('Wave 2')+'</b>&nbsp;('+tx('recurring')+'):<br>';
		z += htmlSelector(MarchPresets, 0, 'id=pbatPreset2 class=btInput');
		z += '</td><td><table class=xtab cellspacing=0 cellpadding=0><tr>';

		var c = 0;
		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			zz = '<td width=30px style="padding-right:0px;">'+TroopImageBig(i)+'</td><TD><INPUT id=pbatR2_'+i+' type=text size=7 maxlength=7 value="'+(t.RouteObject.RoundTwoTroops[i]||0)+'">&nbsp;&nbsp;</td>';
			if (c%LineBreak==0) z+= '</tr><tr>';
			z+=zz;
			c++;
		}
		z += '</tr></table></td></tr></table>';

		z += '<div align="center"><TABLE cellSpacing=0 width=98% height=0% class=xtab><tr><td>&nbsp;</td><td align=center>'+strButton20(tx('Save Route'), 'id=pbatSaveRoute')+'&nbsp;';
		if (t.EditRouteNumber>=0) { z += strButton20(tx('Save a Copy'), 'id=pbatCopyRoute')+'&nbsp;'; }
		if (Tabs.Search && Tabs.Search.dat) {
			for (var k = 0; k < Tabs.Search.dat.length; k++) {
				coords = Tabs.Search.dat[k][0]+'_'+Tabs.Search.dat[k][1];
				elem = ById('pbSearchScout_' + coords);
				if (elem && elem.checked) {
					z += strButton20(tx('Bulk Add Co-ords from Search'), 'id=pbatImport')+'&nbsp;';
					break;
				}
			}
		}
		z += strButton20(uW.g_js_strings.commonstr.cancel, 'id=pbatCancelRoute')+'</td><td align=right>&nbsp;</td></tr></table></div>';

		ById('pbatRouteDetail').innerHTML = z;

		t.dcp0 = new CdispCityPicker('pbattackfrom', ById('pbatfromcity'), true, null, fromidx);

		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			t.addListeners(i);
		}

		ById('pbatRound1').addEventListener('click', function(){
			var checked = (!this.checked);
			t.checkDisableRound('1',checked);
		},false);
		ById('pbatRound2').addEventListener('click', function(){
			var checked = (!this.checked);
			t.checkDisableRound('2',checked);
		},false);

		t.checkDisableRound('1',!t.RouteObject.RoundOne);
		t.checkDisableRound('2',!t.RouteObject.RoundTwo);

		ById('pbatPreset1').addEventListener('change', function(e) {
			t.LoadPreset(e.target.value,1);
		}, false);
		ById('pbatPreset2').addEventListener('change', function(e) {
			t.LoadPreset(e.target.value,2);
		}, false);

		ById('pbatFetchBookmarks').addEventListener('click', function () {
			FillBookmarkList('pbatBookmarks');
		},false);

		ById('pbatBookmarks').addEventListener('change', function () {
			if (this.value != '') {
				var val = this.value;
				var x = val.substr(0, val.lastIndexOf(','));
				var y = val.substr(val.lastIndexOf(',') + 1, val.length);
				ById('pbatX').value = x;
				ById('pbatY').value = y;
			}
		}, false);

		ById('pbatSaveRoute').addEventListener ('click', function() {t.SaveRoute(false);}, false);
		if (ById('pbatCopyRoute')) { ById('pbatCopyRoute').addEventListener ('click', function() {t.SaveRoute(true);}, false); }
		if (ById('pbatImport')) { ById('pbatImport').addEventListener ('click', function() {t.ImportRoutes();}, false); }
		ById('pbatCancelRoute').addEventListener ('click', function() {t.RouteObject = null; t.PaintRoutes();}, false);

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	addListeners : function(Troop) {
		var t = Tabs.Attack;
		var T1 = 'pbatR1_'+Troop;
		var T2 = 'pbatR2_'+Troop;
		ById(T1).addEventListener('keyup', function(){ if (isNaN(ById(T1).value)) ById(T1).value=0; }, false);
		ById(T2).addEventListener('keyup', function(){ if (isNaN(ById(T2).value)) ById(T2).value=0; }, false);
	},

	LoadPreset : function(PN,r) {
		var t = Tabs.Attack;
		for (var ui in uW.cm.UNIT_TYPES) {
			var i = uW.cm.UNIT_TYPES[ui];
			var elem = ById('pbatR'+r+'_'+i);
			if (elem) {
				elem.value = 0;
				if (Options.QuickMarchOptions.MarchPresets[PN][i]) {
					elem.value = parseIntNan(Options.QuickMarchOptions.MarchPresets[PN][i]);
				}
			}
		}
	},

	checkDisableRound : function(r,disabled) {
		var t = Tabs.Attack;
      	for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			var elem = ById('pbatR'+r+'_'+i);
			if (elem) {
				elem.disabled = disabled;
				if (disabled) {	elem.value = 0; }
			}
		}
		var elem = ById('pbatPreset'+r);
		if (elem) {
			elem.disabled = disabled;
			if (disabled) {	elem.value = 0; }
		}
	},

	SaveRoute : function (CopyRoute) {
		var t = Tabs.Attack;

		if (!t.validateScreenFields('save')) { return; }

		if (t.EditRouteNumber<0 || CopyRoute) {
			Options.AttackOptions.Routes.push(JSON2.parse(JSON2.stringify(t.RouteObject))); // create new object in array
			if (CopyRoute) { t.RouteObject = null; } // clear route object
		}
		else {
			Options.AttackOptions.Routes[t.EditRouteNumber] = t.RouteObject;
			t.RouteObject = null; // clear route object
		}
		ById('pbatMessages').innerHTML = tx("Attack route saved!");
		t.PaintRoutes();
	},

	ImportRoutes : function () {
		var t = Tabs.Attack;

		if (!t.validateScreenFields('import')) { return; }

		if (Tabs.Search && Tabs.Search.dat) {
			for (var k = 0; k < Tabs.Search.dat.length; k++) {
				coords = Tabs.Search.dat[k][0]+'_'+Tabs.Search.dat[k][1];
				elem = ById('pbSearchScout_' + coords);
				if (elem && elem.checked) {
					t.RouteObject.target_x = Tabs.Search.dat[k][0];
					t.RouteObject.target_y = Tabs.Search.dat[k][1];
					Options.AttackOptions.Routes.push(JSON2.parse(JSON2.stringify(t.RouteObject))); // create new object in array
					elem.checked = false;
				}
			}
		}

		t.RouteObject = null; // clear route object
		ById('pbatMessages').innerHTML = tx("Routes imported from Search Results!");
		t.PaintRoutes();
	},

	validateScreenFields : function (action) {
		var t = Tabs.Attack;

		if (!t.dcp0.city) {
			ById('pbatMessages').innerHTML = tx("No source city selected");
			return false;
		}

		if (action=="save") {
			var x = ById("pbatX").value;
			var y = ById("pbatY").value;
			if (x=="" || y=="" || isNaN(x) || isNaN(y) || x < 0 || x > 749 || y < 0 || y > 749) {
				ById('pbatMessages').innerHTML = tx("Map co-ordinates must be between 0 and 749!");
				return false;
			}
		}

		// copy screen fields to routeobject

		t.RouteObject.cityId = t.dcp0.city.id;
		t.RouteObject.target_x = x;
		t.RouteObject.target_y = y;
		t.RouteObject.isWild = ById('pbatwild').checked;
		t.RouteObject.ChampOnly = ById('pbatchamponly').checked;
		t.RouteObject.RoundOne = ById('pbatRound1').checked;
		t.RouteObject.RoundTwo = ById('pbatRound2').checked;

		t.RouteObject.RoundOneTroops = {};
		t.RouteObject.RoundTwoTroops = {};

		var gotR1troops = false;
		var gotR2troops = false;

		for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			var troopval = parseIntNan(ById('pbatR1_'+i).value);
			if (troopval != 0) {
				gotR1troops = true;
				t.RouteObject.RoundOneTroops[i] = troopval;
			}
			var troopval = parseIntNan(ById('pbatR2_'+i).value);
			if (troopval != 0) {
				gotR2troops = true;
				t.RouteObject.RoundTwoTroops[i] = troopval;
			}
		}

		if(!gotR1troops && !gotR2troops){
			ById('pbatMessages').innerHTML = tx("You must select some attack troops!");
			return false;
		}
		if (!gotR1troops && ById('pbatRound1').checked){
			ById('pbatMessages').innerHTML = tx("No wave 1 troops selected!");
			return false;
		}
		if (!gotR2troops && ById('pbatRound2').checked){
			ById('pbatMessages').innerHTML = tx("No wave 2 troops selected!");
			return false;
		}

		// validation OK!
		return true;
	},

	sendAttackReport : function () {
		var t = Tabs.Attack;
		if (!Options.AttackOptions.AttackReport || !Options.AttackOptions.Running) { return; }

		var now = unixTime();

		if (now < (parseInt(Options.AttackOptions.LastAttackReport)+(Options.AttackOptions.AttackReportInterval*60*60)))
			return;

		var total = 0;
		var message = tx('Attack Report for')+' '+Options.AttackOptions.AttackReportInterval+' '+tx('hours of attacking (or since last report)')+' %0A';
		message += tx('Numbers of 1st wave sent')+': '+ Options.AttackOptions.Wave1Count +'%0A';
		message += tx('Numbers of 2nd wave sent')+': '+ Options.AttackOptions.Wave2Count +'%0A';
		message +='%0A';

		if (Options.ReportOptions.DeleteRptaa) {
			message += tx('Miscellaneous items')+': %0A';

			var Crests = {};
			for (var z in t.CrestList) { Crests[t.CrestList[z]] = 0; }

			for (var z in DeleteReports.ReportLog.ItemsFound) {
				if (!isNaN(Crests[z])) // if item is a crest or seal...
					Crests[z] = DeleteReports.ReportLog.ItemsFound[z];
				else {
					if (z=="T") {
						message += uW.g_js_strings.commonstr.found+' '+tx('Treasure Chest')+' x '+DeleteReports.ReportLog.ItemsFound[z]+'%0A';
					}
					else {
						message += uW.g_js_strings.commonstr.found+' '+uW.ksoItems[z].name+' x '+DeleteReports.ReportLog.ItemsFound[z]+'%0A';
					}
				}
			}
			message +='%0A';
			message += tx('Crest Stats')+': %0A';
			for (crest in Crests) {
				if (Crests[crest] > 0) {
					message += uW.itemlist['i'+crest]['name'] +' x '+ Crests[crest] +'%0A';
					total += (Crests[crest]);
				}
			}
			message += tx('Total Crests Found')+': '+ total +'%0A';

			message +='%0A';
			message += tx('Jewel Stats')+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.JewelItemsFound){
				itemcount += DeleteReports.ReportLog.JewelItemsFound[z];
				message += eval('uW.g_js_strings.jewel.quality_'+Number(z-1))+' Jewel x '+DeleteReports.ReportLog.JewelItemsFound[z]+'%0A';
			}
			message += tx('Total Jewels Found')+': '+itemcount+'%0A';

			message +='%0A';
			message += tx('Throne Stats')+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.ThroneItemsFound){
				itemcount += DeleteReports.ReportLog.ThroneItemsFound[z].amount;
				message += strQuality(DeleteReports.ReportLog.ThroneItemsFound[z].quality)+' '+DeleteReports.ReportLog.ThroneItemsFound[z].type+' x '+DeleteReports.ReportLog.ThroneItemsFound[z].amount+'%0A';
			}
			message += tx('Total Throne Room Items Found')+': '+itemcount+'%0A';

			message +='%0A';
			message += uW.g_js_strings.report_view.champion_stats+': %0A';
			var itemcount = 0;
			for (z in DeleteReports.ReportLog.ChampItemsFound){
				itemcount += DeleteReports.ReportLog.ChampItemsFound[z].amount;
				message += strQuality(DeleteReports.ReportLog.ChampItemsFound[z].quality)+' '+DeleteReports.ReportLog.ChampItemsFound[z].type+' x '+DeleteReports.ReportLog.ChampItemsFound[z].amount+'%0A';
			}
			message += tx('Total Champion Equipment Found')+': '+itemcount+'%0A';
		}
		else {
			message += tx('Found item details only available if the option "Delete auto-attack reports" is ticked')+'%0A';
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.emailTo = Seed.player['name'];
		params.subject = tx("Attack Overview");

		if (uW.koc2Mail && Options.AttackOptions.AttackReportEmail) {
			koc2Mail.customMail(params.emailTo,params.subject,message);
		}

		params.message = message;
		params.requestType = "COMPOSED_MAIL";

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/getEmail.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					DeleteLastMessage();
					Options.AttackOptions.Wave1Count = 0;
					Options.AttackOptions.Wave2Count = 0;
					saveOptions();
					if (Options.ReportOptions.DeleteRptaa) {
						DeleteReports.ReportLog.ItemsFound = {};
						DeleteReports.ReportLog.ThroneItemsFound = {};
						DeleteReports.ReportLog.ChampItemsFound = {};
						DeleteReports.ReportLog.JewelItemsFound = {};
						DeleteReports.saveLog();
					}
				}
			},
		});

		Options.AttackOptions.LastAttackReport = now;
		saveOptions();
	},

	doAutoLoop : function (idx,busted) {
		var t = Tabs.Attack;
		clearTimeout(t.timer);
		if (!Options.AttackOptions.Running) return;

		if (idx>=Options.AttackOptions.Routes.length) { idx=0; } // safety, if route(s) have been deleted.
		if (idx==0 && !busted) {
			t.loopaction = false; // reset loop action indicator for first city
			t.AttackOrder = [];
			for (var y in Options.AttackOptions.Routes) { t.AttackOrder.push(y); }
			if (Options.AttackOptions.Randomize) {
				t.AttackOrder = shuffle(t.AttackOrder);
			}
		}
		t.autodelay = 0; // no delay if no action taken!

		if (idx<Options.AttackOptions.Routes.length) {
			var a = Options.AttackOptions.Routes[t.AttackOrder[idx]];
			t.autodelay = 0; // no delay if no action taken...

			if (a.Active) {
				// do we need another round 1 yet?
				var now = unixTime();
				if (a.RoundTwo && a.RoundOne && !busted) {
					if (now > (parseIntNan(a.LastRoundOne) + 90)) {
						if (t.doAttack(idx,1,true)) { return; } // march call initiated, loop handled from there...
					}
				}
				if (a.RoundTwo) { t.doAttack(idx,2,false); }
				else { t.doAttack(idx,1,false); } // if only round 1 just keep sending round 1...
			}
		}
		t.checkNextRoute(idx);
	},

	checkNextRoute : function (idx) {
		var t = Tabs.Attack;
		if (idx >= Options.AttackOptions.Routes.length-1) {
			if (!t.loopaction) { t.autodelay = Options.AttackOptions.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(0,false); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1,false); }, (t.autodelay * 1000));
		}
	},

	doAttack: function(idx,r,buster){
		var t = Tabs.Attack;
		var a = Options.AttackOptions.Routes[t.AttackOrder[idx]];

		var champid = 0;
		for (y in Seed.champion.champions) {
			citychamp = Seed.champion.champions[y];
			if (citychamp.assignedCity == a.cityId) {
				var champstatus = citychamp.status;
				if (champstatus != "10") { champid = citychamp.championId; }
				break;
			}
		}

		if (!Cities.byID[a.cityId]) { return false; } // no attack city!
		var towerok = (!Options.TowerOptions || !Options.TowerOptions.SaveCityState[a.cityId] || Options.TowerOptions.SaveCityState[a.cityId].AllowMarches);
		if (!towerok) { return false; } // attack city under attack!

		var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[Cities.byID[a.cityId].idx]);
		if (!ascensionok) { return; } // attack city waiting to ascend!

		if (a.ChampOnly && (champid==0) && (r==2 || (r==1 && a.RoundTwo))) { return false; } // no champ or champ not ready!
		if (!t.checkCityTroops(r,idx)) { return false; } // insufficient troops for one or both waves!
		var slotsneeded = 1;
		if (r==1 && a.RoundTwo) slotsneeded = 2;
		var keepfree = Number(Options.AttackOptions.FreeRallySlots); // use highest of attack keep rally free or general keep rally free
		if (keepfree < Number(Options.FreeRallySlots)) { keepfree = Number(Options.FreeRallySlots); }
		var availslots = Number(March.getEmptySlots(a.cityId))-keepfree;
		if (availslots < slotsneeded) { return false; }

		var knt = getAvailableKnights(a.cityId);
		if (!knt[0]) { return false; } // no knight for this wave
		if (r==1 && a.RoundTwo && !knt[1]) { return false; } // no knight for wave 2!

		// from here, should be ok to attack..

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = a.cityId;
		params.kid = knt[0].ID; // will fail if no knights
		params.type = 4;
		params.xcoord = a.target_x;
		params.ycoord = a.target_y;

		if (a.ChampOnly && (r==2)) {
			params.champid = champid;
		}

		var totalsend = 0;
      	for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			if (r==1) { params["u"+i] = parseIntNan(a.RoundOneTroops[i]); }
			else { params["u"+i] = parseIntNan(a.RoundTwoTroops[i]); }
			totalsend += params["u"+i];
		}

		if (r==1) {
			var now = unixTime();
			if (now < (parseInt(a.LastRoundOne) + 500) && a.isWild) {
				for (var ui in uW.cm.UNIT_TYPES) {
					var i = uW.cm.UNIT_TYPES[ui];
					if (params["u"+i]!=0) {
						params["u"+i] = Math.ceil(params["u"+i]/10);
					}
				}
			}
		}

		if (totalsend == 0) { // final safety net
			return false;
		}
		else {
			t.autodelay = Options.AttackOptions.intervalSecs; // march is required, so delay subsequent loop
			t.loopaction = true;

			March.addMarch(params, function(rslt){
				if (rslt.ok) {
					var now = unixTime();
					if (r==1) {
						Options.AttackOptions.Wave1Count++;
						Options.AttackOptions.Routes[t.AttackOrder[idx]].LastRoundOne = now;
					}
					else {
						Options.AttackOptions.Wave2Count++;
					}
					saveOptions();
					if (buster) { // wave 1 success!.. reset loop on same route for wave 2...
						t.timer = setTimeout(function () { t.doAutoLoop(idx,true); }, (t.autodelay * 1000));
					}
				}
				else {
					if (rslt.error_code==206) { // cannot do this to yourself! You still own the wild....
//						if (a.isWild) {
							var tid = CalculateTileId(a.target_x, a.target_y);
							if (tid!=0) { AbandonWild (tid, a.target_x, a.target_y, a.cityId); }
//						}
					}
					else {
						if (!rslt.msg) {rslt.msg = 'Error Code ('+rslt.error_code+')';}
						if (GlobalOptions.ExtendedDebugMode) { actionLog(Cities.byID[a.cityId].name+": Attack Error - "+rslt.msg,'ATTACK'); }
					}
					if (buster) { // wave 1 failed.. reset loop and move on to next route
						t.checkNextRoute(idx);
					}
				}
			});
		}

		return true; // march was requested...
	},

	checkCityTroops : function (round,idx) {
		var t = Tabs.Attack;
		var a = Options.AttackOptions.Routes[t.AttackOrder[idx]];
		var result = true;
      	for (var ui in uW.cm.UNIT_TYPES){
			var i = uW.cm.UNIT_TYPES[ui];
			var needed = 0;
			for (var r=round;r<=2;r++) { // wave 1 checks both wave requirements
				if (r==1) { needed += parseIntNan(a.RoundOneTroops[i]); }
				else { needed += parseIntNan(a.RoundTwoTroops[i]); }
				result = (result && (parseIntNan(Seed.units['city'+a.cityId]['unt'+i]) >= needed));
				if (!result) {return result;}
			}
		}
		return result;
	},

	checkAbandonWild : function () {
		var t = Tabs.Attack;
		if (!Options.AttackOptions.Running) { return; }
		for (var m in Options.AttackOptions.Routes) {
			var a = Options.AttackOptions.Routes[m];
			if(a.isWild) {
				for (var c = 0; c < Cities.numCities; c++) {
					var city = Cities.cities[c];
					var cWilds = Seed.wilderness['city' + city.id];
					if (matTypeof(cWilds) == 'object') {
						for (var k in Seed.wilderness['city' + city.id]) {
							var w = Seed.wilderness['city' + city.id][k];
							if (w.xCoord==a.target_x && w.yCoord==a.target_y) {
								AbandonWild (w.tileId, w.xCoord, w.yCoord, city.id);
								return; // only abandon one per loop
							}
						}
					}
				}
			}
		};
	},

}

/**************************** Build Tab ****************************************/
Tabs.Build = {
	tabLabel: 'Build',
	tabOrder: 2060,
	tabColor : 'brown',
	tabDisabled: false,
	myDiv: null,
	timer: null,
	ModelCity: null,
	ModelCityId: 0,
	LoopCounter: 0,
	intervalSecs  : 5,
	autodelay : 0,
	citydelay: {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
	loopaction : false,
	limitingFactor: null,
	buildspeed : 0,
	cityval : 0,
	Subscriber : false,
	BuildMode : false,
	BuildDiv : null,
	BuildList : {},
    koc_buildslot: null,
	Squire:0,
	Knight:0,
	Guinevere:0,
	Morgana:0,
	Arthur:0,
	Merlin:0,
	Divine:0,
	Epic:0,
	Legendary:0,
	ItemList : [1, 2, 3, 4, 5, 6, 7, 8, 10],
	ItemTrans : ["SH","KH","GH","MH","AH","RH","DH","EH","LH"],
	SmartOrder : [12,7,8,14,16,20,19,0,9,15,17,18,21,11,6,10,23,25,27], // experiment!
	PresetTypes : {0:"Unascended City",1:"Druid City",2:"Fey City",3:"Briton City"},
	CityBuildings : [5,6,7,8,9,10,11,12,13,14,15,16,17,18,20,21],
	FieldBuildings : [1,2,3,4],
	DruidCityBuildings : [5,7,8,10,11,12,13,14,20],
	FeyCityBuildings : [5,7,8,10,11,12,13,14,20,21],
	BritonCityBuildings : [5,7,8,10,11,12,13,14,20,21],
	DruidFieldBuildings : [22,23],
	FeyFieldBuildings : [24,25],
	BritonFieldBuildings : [26,27],
	NextPresetNumber : 0,
	InitPresetNumber : 0,
	PresetNum : 0,
	PresetType : "",
	PresetName : "",
	Preset : {},
	FieldView : false,
	Options: {
		Running: false,
		ThroneCheck: false,
		BuildSpeed: 0,
		Enabled : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
		Toggle : false,
		maxbuildlevel : 9,
		help : false,
		bothqueues : false,
		EmptySlots : 5,
		BuildPriority : 1, // 0 - none, 1 - shortest time, 2 - position, 3 - building type, 4 - unique buildings
		KeepCompleted : false,
		UseLH : false,
		UseEH : false,
		UseDH : false,
		UseRH : false,
		UseAH : false,
		UseMH : false,
		UseGH : false,
		UseKH : false,
		UseSH : false,
		UseOverride : false,
		OverrideItem : 0,
		OverrideHours : 0,
		OverrideMinutes : 1,
		BuildPresetNames : {},
		BuildPresetTypes : {},
		BuildPresets : {},
		AscendRunning : false,
		AscendEnabled : {1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		AscendTime : 1,
		AscendFaction : 1, // 1 - druid, 2 - fey, 3 - briton
		AscendBlessings : {1:[0,0,0,0,0,0], 2:[0,0,0,0,0,0], 3:[0,0,0,0,0,0]}, // up to 6 minor blessings will be allowed eventually...
		AscendPresets : {1:0, 2:0, 3:0}, // which preset to queue after ascension
		AscendPresetLevel : 9, // building level to queue after ascension
		AscensionReady : {1:false,2:false,3:false,4:false,5:false,6:false,7:false,8:false},
		UseLesserCrystals : false,
		UseGreaterCrystals : false,
	},
	BuildQueue : {}, // cityId:{ pos0:{buildtype,maxlevel,status,ascendcomplete,errors}, },

	init: function (div) {
		var t = Tabs.Build;
        t.myDiv = div;

		if (!Options.BuildOptions) {
			Options.BuildOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.BuildOptions.hasOwnProperty(y)) {
					Options.BuildOptions[y] = t.Options[y];
				}
			}
		}

		// fix any broken build presets

		for (var y in Options.BuildOptions.BuildPresets) {
			if (!Options.BuildOptions.BuildPresets[y].pos0) { Options.BuildOptions.BuildPresets[y].pos0 = 'bdg0'; }
			if (!Options.BuildOptions.BuildPresets[y].pos1) { Options.BuildOptions.BuildPresets[y].pos1 = 'bdg19'; }
		}

		for (var b in uW.buildingcost) {
			var bid = Number(b.split('bdg')[1]);
			if (bid<30) {
				t.BuildList[bid] = uW.buildingcost[b][0];
			}
		}

		for (var c=1;c<=8;c++) {
			if (!Cities.cities[c-1]) {
				Options.BuildOptions.AscendEnabled[c] = false;
			}
			else {
				var ascended = getAscensionValues(Cities.cities[c-1].id);
				if (ascended.isPrestigeCity) {
					var MaxLevel = CM.PrestigeModel.getLevelCapSoft(ascended.prestigeType);
					if (parseIntNan(ascended.prestigeLevel)==MaxLevel) {
						Options.BuildOptions.AscendEnabled[c] = false;
					}
				}
			}
		}

		t.ReadBuildQueue();

        t.koc_buildslot = uW.buildslot; //save original koc function
		t.CreateBuildModeDiv();

		t.Subscriber = CM.QueueModel.hasFreeQueue();

		if (Options.BuildOptions.Toggle) AddSubTabLink('AutoBuild',t.toggleAutoBuildState, 'BuildToggleTab');
		SetToggleButtonState('Build',Options.BuildOptions.Running,'Build');

		uWExportFunction('speedupBuild', Tabs.Build.speedupBuild);
		uWExportFunction('btcancelConstruction', Tabs.Build.cancelConstruction);
		uWExportFunction('cancelBuild',Tabs.Build.cancelBuild);
		uWExportFunction('btBldCancelAll',Tabs.Build.cancelAll);
		uWExportFunction('btNewBldPreset', Tabs.Build.NewBldPreset);
		uWExportFunction('btSelectBldPreset', Tabs.Build.SelectBldPreset);
		uWExportFunction('btSetBldPreset', Tabs.Build.SetBldPreset);

		var m = '<DIV class=divHeader align=center>'+tx('AUTOMATIC BUILD FUNCTION')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btBuildToggle type=checkbox />&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoBuildState type=submit value="'+tx("AutoBuild")+' = '+ (Options.BuildOptions.Running?'ON':'OFF')+'">&nbsp;<INPUT id=btAutoAscendState type=submit value="'+tx("AutoAscend")+' = '+ (Options.BuildOptions.AscendRunning?'ON':'OFF')+'"></td></td><td width=30% align=right>'+tx('Current Construction Speed')+':&nbsp;<span id=btBuildCurrTR></span>&nbsp;&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td colspan=2 align=left><INPUT id=btBuildTR type=checkbox >&nbsp;'+tx('Only build when construction speed is at least')+' <INPUT id=btBuildTRSpeed type=text size=3 maxlength=4 >&nbsp;%</td>';
		m += '<td colspan=2 align=right>'+tx('Current Increased City Value')+':&nbsp;<span id=btCityValCurrTR></span>&nbsp;&nbsp;</td></tr>';
		m += '<tr><TD colspan=2 align=left><INPUT id=pbKeepCompleted type=checkbox \>&nbsp;'+tx("Keep completed buildings in queues of ascended cities")+'</td><td colspan=2 align=right>'+tx("Maximum Build Level") + ':&nbsp;'+htmlSelector({9:9, 10:10, 11:11, 12:12, 13:13}, Options.BuildOptions.maxbuildlevel, 'id=pbMaxBuildLevel')+'</TD></tr>';
		m += '<tr><TD colspan=2 align=left><INPUT id=pbHelpRequest type=checkbox \>&nbsp;'+tx("Ask for help")+'</td><TD colspan=2 align=right>'+tx("Build Priority")+':&nbsp;'+ htmlSelector({0:tx('None'),1:tx('Shortest time'),2:tx('Position'),3:tx('Building Type'),4:tx('Unique Buildings')},Options.BuildOptions.BuildPriority, 'id=pbBuildPriority')+'</td></tr>';
		m += '<tr><TD colspan=2 align=left class='+(!t.Subscriber?'divHide':'')+'>&nbsp;</td><TD colspan=2 align=right class='+(!t.Subscriber?'divHide':'')+'><INPUT id=pbbothqueues type=checkbox \>'+tx("Use both build queues")+'</td></tr>';
		m += '</table>';

		m += '<br><DIV id=btBuildOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';

		m += '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td width=100>&nbsp;</td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btBuildCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}
		m += "<td>&nbsp;</td>"; // spacer
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Auto-Build')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btBuildAutoCity_'+i+'" type=checkbox '+(Options.BuildOptions.Enabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right><b>'+uW.g_js_strings.commonstr.faction+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btBuildFactionCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Ascension')+'%&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btBuildAscensionPercentCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right><b>'+tx('Protection')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btBuildAscensionProtectionCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Auto-Ascend')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btBuildAutoAscendCity_'+i+'" type=checkbox '+(Options.BuildOptions.AscendEnabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right><b>'+tx('Queue Length')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btBuildQueueLengthCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Queue Time')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><span id="btBuildQueueTimeCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+tx('Activity')+'&nbsp;</b></td>';
		var actheight = 90;
		if (t.Subscriber) { actheight = 180; }
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:'+actheight+'px;"><span id="btBuildActiveCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr></table></div></div>';

		m += '<div class="divHeader" align="center">'+tx('USE AUTO-SPEEDUPS')+'</div>';

		m += '<table width=100% class=xtab><tr><td><div align=center>';

		var Boosts = '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'\n'+tx(HourGlassHint[i])+'" /></td><td>(<span id=pbbuildUse'+t.ItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '<td width=70 rowspan=2 align=right><INPUT id=pbBuildHelp type=submit value="'+tx('HELP')+'!"></td>';
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbbuild'+t.ItemTrans[i]+'" '+(Options.BuildOptions["Use"+t.ItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr></table></td></tr>';
        Boosts += '<tr><td><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td><input type=checkbox id=pbbuildOV >'+tx('Override above by always using')+' '+htmlSelector(HourGlassName,Options.BuildOptions.OverrideItem, 'id=pbbuildOVItem') + ' '+tx('when more than')+' ';
		Boosts += '<INPUT style="width: 30px;text-align:right;" id="pbbuildOVHours" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT style="width: 30px;text-align:right;" id="pbbuildOVMinutes" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timemin+' '+tx('remaining')+'.</td></tr></table></div></td></tr>';

		m += Boosts+'</table></div>';

		m += '<a id=btBldAscendLink class=divLink><div class="divHeader" align="left"><table cellpadding=0 cellspacing=0 width=100%><tr><td class=xtab><img id=btBldAscendArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('AUTO-ASCEND OPTIONS')+'</td><td class=xtab align=right>&nbsp;</td></tr></table></div></a>';
		m += '<div id=btBldAscend style="max-height:400px;overflow-y:scroll;" class=divHide>&nbsp;</div><hr>';

		m += '<br><DIV style="text-align:center; margin-bottom:5px;">'+uW.g_js_strings.commonstr.city+':&nbsp;<span id=pbbuildcity></span></div>';

		m += '<div class="divHeader" align="center">'+tx('ADD BUILDINGS')+'</div><br>';
		m += '<div><table cellpadding=0 cellspacing=0 class=xtab width=100%><tr><td><INPUT id=pbBuildMode class=btInput type=submit value="' + tx("Build Mode = OFF") + '"></td>';
		m += '<td>'+tx('Empty Slots')+':&nbsp;'+htmlSelector(t.BuildList,Options.BuildOptions.EmptySlots,'id=pbbuildempty')+'</td>';
		m += '<td align=right>'+tx('Queue ALL')+':&nbsp;'+htmlSelector({all:uW.g_js_strings.commonstr.buildings, barracks:uW.buildingcost.bdg13[0], cottages:uW.buildingcost.bdg5[0], farms:uW.buildingcost.bdg1[0], sawmills:uW.buildingcost.bdg2[0], quarries:uW.buildingcost.bdg3[0], mines:uW.buildingcost.bdg4[0], guardians:uW.g_js_strings.guardian.guardians, deftower:uW.g_js_strings.tower.towerName, redoubt:uW.g_js_strings.redoubt.redoubt, empty:tx("Empty Slots")},'all','id=pbquickadd')+'&nbsp;'+tx('to level')+'&nbsp;<select id=pbaddAllTo></select>&nbsp;<INPUT class=btInput id=doXbuildingToX type=submit value="'+tx('Add to Queue')+'">&nbsp;</td>';
		m += '</tr></table></div><br>';

		m += '<a id=btBldPresetLink class=divLink><div class="divHeader" align="left"><img id=btBldPresetArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('LAYOUT DESIGNER')+'</div></a>';
		m += '<div id=btBldPreset style="height:400px; max-height:400px; overflow-y:auto;" class=divHide>';
		m += '<br><TABLE align=center cellSpacing=0 width=98% height=0%><tr><td width=25% class=xtab style="height:20px;">';
		m +='<SELECT class="btSelector" style="width:190px;" id="btBuildPreset" onchange="btSelectBldPreset(this);">';
		m +='</select>&nbsp;<a id="btNewBldPreset" class="inlineButton btButton brown8" onclick="btNewBldPreset()"><span>'+tx('New')+'</span></a></td><td width=50% class=xtab align=center><span id=btBldPresetMessages>&nbsp;</span></td>';
		m +='<td width=25% align=right class=xtab style="padding-right:0px;"><a id="btAddBldPresetButton" class="inlineButton btButton blue14" onclick="btSetBldPreset()"><span style="width:85px;display:inline-block;text-align:center;" align="center">'+tx('Add to Queue')+'</span></a>&nbsp;'+tx('to level')+'&nbsp;<select id=btBldPresetAllTo></td></tr>';
		m += '<tr><td colspan=3 class=xtab><hr></td></tr></table><div id=btBldPresetDetails>&nbsp;</div>';
		m += '</div>';

		m += '<a id=btBldQueueLink class=divLink><div class="divHeader" align="left"><table cellpadding=0 cellspacing=0 width=100%><tr><td class=xtab><img id=btBldQueueArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('BUILDING QUEUE')+'</td><td class=xtab align=right id=btBldQueueStats>&nbsp;</td></tr></table></div></a>';
		m += '<div id=btBldQueue style="max-height:200px;overflow-y:scroll;">&nbsp;</div>';

		m += '</div><br>';

		div.innerHTML = m;
		t.PaintAscendOptions();
		t.clearBuildPresetDiv();
		t.LoadBuildPresets();
		t.MaxLevelChanged();
		OpenDiv["Building"] = "btBldQueue";

		t.ModelCity = new CdispCityPicker('pbbuild', ById('pbbuildcity'), true, t.clickCitySelect, null);

		ById('btBldAscendLink').addEventListener ('click', function () {ToggleMainDivDisplay("Building",100,GlobalOptions.btWinSize.x,"btBldAscend",true)}, false);
		ById('btBldQueueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Building",100,GlobalOptions.btWinSize.x,"btBldQueue",true)}, false);
		ById('btBldPresetLink').addEventListener ('click', function () {ToggleMainDivDisplay("Building",100,GlobalOptions.btWinSize.x,"btBldPreset",true)}, false);

		for (var i = 1; i <= Cities.numCities; i++) {
			ById('btBuildAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.BuildOptions.Enabled[citynum] = e.target.checked;
				if (Options.BuildOptions.Enabled[citynum]) {
					t.citydelay[citynum] = 0;
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
			ById('btBuildAutoAscendCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.BuildOptions.AscendEnabled[citynum] = e.target.checked;
				saveOptions();
			}, false);
		}

		ToggleOption('BuildOptions','btBuildToggle','Toggle');

		ById('pbBuildMode').addEventListener('click', function () {
			t.toggleStateMode();
		}, false);

		ById('btAutoBuildState').addEventListener('click', function(){
			t.toggleAutoBuildState(this);
		}, false);

		ById('btAutoAscendState').addEventListener('click', function(){
			t.toggleAutoAscendState(this);
		}, false);

		ToggleOption('BuildOptions','btBuildTR','ThroneCheck');
		ChangeIntegerOption('BuildOptions','btBuildTRSpeed','BuildSpeed');
		ChangeIntegerOption('BuildOptions','pbMaxBuildLevel','maxbuildlevel',0,t.MaxLevelChanged);

		ById('doXbuildingToX').addEventListener('click', function () {
			var cityId = t.ModelCityId;
			if (!cityId) return;
			var AddType = ById('pbquickadd').value;
			var toLevel = parseIntNan(ById('pbaddAllTo').value.substr(5));
			t.allBuildsTo(cityId,AddType,toLevel);
        }, false);

		ToggleOption('BuildOptions','pbHelpRequest','help');
		ToggleOption('BuildOptions','pbKeepCompleted','KeepCompleted',t.ValidateBuildQueue);
		ToggleOption('BuildOptions','pbbothqueues','bothqueues');
		ChangeOption('BuildOptions','pbbuildempty','EmptySlots');
		ChangeOption('BuildOptions','pbBuildPriority','BuildPriority',t.PaintCityInfo);

		ToggleOption('BuildOptions','pbbuildSH','UseSH');
		ToggleOption('BuildOptions','pbbuildKH','UseKH');
		ToggleOption('BuildOptions','pbbuildGH','UseGH');
		ToggleOption('BuildOptions','pbbuildMH','UseMH');
		ToggleOption('BuildOptions','pbbuildAH','UseAH');
		ToggleOption('BuildOptions','pbbuildRH','UseRH');
		ToggleOption('BuildOptions','pbbuildDH','UseDH');
		ToggleOption('BuildOptions','pbbuildEH','UseEH');
		ToggleOption('BuildOptions','pbbuildLH','UseLH');
		ToggleOption('BuildOptions','pbbuildOV','UseOverride');
		ChangeIntegerOption('BuildOptions','pbbuildOVItem','OverrideItem');
		ChangeIntegerOption('BuildOptions','pbbuildOVHours','OverrideHours');
		ChangeIntegerOption('BuildOptions','pbbuildOVMinutes','OverrideMinutes');

		ById('pbBuildHelp').addEventListener ('click', t.helpPop, false);

		// start autobuild loop timer to start in 6 seconds...

		if (Options.BuildOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, (6 * 1000));
		}

		// check auto ascend to clear the ascension ready flags if they are set incorrectly!

		t.checkAutoAscend();
	},

	helpPop : function (){
		var t = Tabs.Build;
		var helpText = '<br>'+tx("Using Speedups for Construction");
		helpText += '<p>'+tx('Speedups will be used in the following order if they are selected, and the required criteria is met')+' :-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+uW.g_js_strings.commonstr.item+'</b></td><TD><b>'+uW.g_js_strings.commonstr.time+'</b></td><TD><b>'+tx('Criteria')+'</b></td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i10.name+'</td><TD>4 days</td><TD>'+tx('More than 3 days and 12 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i8.name+'</td><TD>2.5 days</td><TD>'+tx('More than 48 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i7.name+'</td><TD>24 hrs</td><TD>'+tx('More than 23 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i6.name+'</td><TD>15 hrs</td><TD>'+tx('More than 14 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i5.name+'</td><TD>8 hrs</td><TD>'+tx('More than 7 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i4.name+'</td><TD>2.5 hrs</td><TD>'+tx('More than 2 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i3.name+'</td><TD>1 hr</td><TD>'+tx('More than 45 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i2.name+'</td><TD>15 mins</td><TD>'+tx('More than 5 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i1.name+'</td><TD>1 min</td><TD>'+tx('More than 30 seconds remaining')+'</td></tr>';
		helpText += '</table>';
		helpText += '<p>'+tx('If the override box is ticked, then the override rule specified will take priority')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 360, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Speedups")+'</b></center>';
		pop.show (true);
	},

	clearBuildPresetDiv : function() {
		var t = Tabs.Build;
		ById('btBldPresetDetails').innerHTML = '<br><br><br><br><br><br><br><br><br><center>'+tx('Please select an existing layout or create a new one above...')+'</center>';
	},


	toggleAutoBuildState: function(obj){
		var t = Tabs.Build;
		obj = ById('btAutoBuildState');
		if (Options.BuildOptions.Running == true) {
			Options.BuildOptions.Running = false;
			obj.value = tx("AutoBuild = OFF");
		}
		else {
			Options.BuildOptions.Running = true;
			obj.value = tx("AutoBuild = ON");
			t.timer = setTimeout(function () { t.doAutoLoop(1);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Build',Options.BuildOptions.Running,'Build');
		t.citydelay = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0};
		t.PaintOverview();
	},

	toggleAutoAscendState: function(obj){
		var t = Tabs.Build;
		if (Options.BuildOptions.AscendRunning == true) {
			Options.BuildOptions.AscendRunning = false;
			obj.value = tx("AutoAscend = OFF");
		}
		else {
			Options.BuildOptions.AscendRunning = true;
			obj.value = tx("AutoAscend = ON");
		}
		saveOptions();
		t.checkAutoAscend();
		t.PaintOverview();
	},

	MaxLevelChanged : function () {
		var t = Tabs.Build;
		var m = '';
		for (a = 1; a <= Options.BuildOptions.maxbuildlevel ; a++) {
			var sel = ''; if (a==Options.BuildOptions.maxbuildlevel) sel=' selected';
			m += '<OPTION value=toLvl'+a+sel+'>'+a+'</option>';
		}
		ById('pbaddAllTo').innerHTML = m;
		ById('btBldPresetAllTo').innerHTML = m;
		ById('pbbuildmodeto').innerHTML = m;
		t.ResetAscendAllTo();
	},

	ResetAscendAllTo : function () {
		var t = Tabs.Build;
		var m = '';
		if (Options.BuildOptions.AscendPresetLevel > Options.BuildOptions.maxbuildlevel) {
			Options.BuildOptions.AscendPresetLevel = Options.BuildOptions.maxbuildlevel;
			saveOptions();
		}
		for (a = 1; a <= Options.BuildOptions.maxbuildlevel ; a++) {
			var sel = ''; if (a==Options.BuildOptions.AscendPresetLevel) sel=' selected';
			m += '<OPTION value=toLvl'+a+sel+'>'+a+'</option>';
		}
		ById('btBldAscendAllTo').innerHTML = m;
	},

	SaveBuildQueue : function (){
		var t = Tabs.Build;
		var serverID = getServerId();
		setTimeout(function () { GM_setValue ('BuildQueue_'+serverID+'_'+uW.tvuid, JSON2.stringify(t.BuildQueue)); },0); // get around GM_SetValue uW error
	},

	ReadBuildQueue : function (notify) {
		var t = Tabs.Build;
		var serverID = getServerId();
 		s = GM_getValue ('BuildQueue_'+serverID+'_'+uW.tvuid);
		if (s != null){
			opts = JSON2.parse (s);
			for (var k in opts) {
				var validQ = false;
				var cid = 0;
				for (var i = 0; i < Cities.numCities; i++) {
					if (k==t.QueueKey(Cities.cities[i].id)) {
						validQ = true;
						cid = Cities.cities[i].id;
						break;
					}
				}
				if (validQ) {
					t.BuildQueue[k] = opts[k];
					t.ValidateBuildQueue(cid,false);
				}
			}
			t.SaveBuildQueue(); // cleanup
		}
		if (notify) { notify(); }
	},

	show: function (init) {
		var t = Tabs.Build;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
		t.PaintOverview();
	},

	QueueKey : function (cid) {
		var t = Tabs.Build;
		var QKey = cid;
		if (Seed.cityData.city[cid].isPrestigeCity) { QKey += 'A'; }
		return QKey;
	},

	EverySecond : function () {
		var t = Tabs.Build;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh build speed and overview display every 2 seconds
			t.buildspeed = Math.floor(equippedthronestats(78));
			t.cityval = Math.floor(equippedthronestats(109));
			if (tabManager.currentTab.name == 'Build' && Options.btWinIsOpen){
				t.PaintOverview();
				t.PaintCityInfo();
			}
		}

		if (t.LoopCounter >= 60) { // check for auto ascend every minute
			t.checkAutoAscend();
			t.LoopCounter = 0;
		}
	},

	toggleStateMode: function (obj) {
		var t = Tabs.Build;
		t.BuildMode = !t.BuildMode;
		obj = ById('pbBuildMode');
		if (t.BuildMode) {
			// start build mode state
			uW.buildslot = t.bot_buildslot; // overwrite original koc function
			obj.value = tx("Build Mode = ON");
			ById('pbbuildmodeempty').value = Options.BuildOptions.EmptySlots;
			t.BuildDiv.style.display = 'block';
			hideMe();
		}
		else {
			// stop build mode state
			uW.buildslot = t.koc_buildslot; // restore original koc function
			obj.value = tx("Build Mode = OFF");
			ById('pbbuildempty').value = Options.BuildOptions.EmptySlots;
			t.BuildDiv.style.display = 'none';
			showMe();
			ById('bttcBuild').click();
			t.PaintOverview();
			t.PaintCityInfo();
		}
	},

	clickCitySelect: function (city) {
		var t = Tabs.Build;
		t.ModelCityId = city.id;
		t.LastQueue = 'x';
		t.PaintCityInfo();
	},

	PaintOverview : function () {
		var t = Tabs.Build;
		var now = uW.unixtime();

		t.Squire = parseIntNan(Seed.items.i1);
		t.Knight = parseIntNan(Seed.items.i2);
		t.Guinevere = parseIntNan(Seed.items.i3);
		t.Morgana = parseIntNan(Seed.items.i4);
		t.Arthur = parseIntNan(Seed.items.i5);
		t.Merlin = parseIntNan(Seed.items.i6);
		t.Divine = parseIntNan(Seed.items.i7);
		t.Epic = parseIntNan(Seed.items.i8);
		t.Legendary = parseIntNan(Seed.items.i10);

		ById('pbbuildUseSHLabel').innerHTML = t.Squire;
		ById('pbbuildUseKHLabel').innerHTML = t.Knight;
		ById('pbbuildUseGHLabel').innerHTML = t.Guinevere;
		ById('pbbuildUseMHLabel').innerHTML = t.Morgana;
		ById('pbbuildUseAHLabel').innerHTML = t.Arthur;
		ById('pbbuildUseRHLabel').innerHTML = t.Merlin;
		ById('pbbuildUseDHLabel').innerHTML = t.Divine;
		ById('pbbuildUseEHLabel').innerHTML = t.Epic;
		ById('pbbuildUseLHLabel').innerHTML = t.Legendary;

		for (var i = 0; i < Cities.numCities; i++) {
			citynum = i+1;
			cityId = Cities.cities[i].id;

			var str = '';
			if (t.citydelay[citynum] > 0) { str = tx('Waiting')+'...'; }
			if (Options.BuildOptions && Options.BuildOptions.AscensionReady[citynum]) { str = tx('Ascension')+'...'; }

			var isBusy = false;
			var activeblds = [];
			var activetimes = [];
			var qcon = Seed.queue_con["city" + cityId];
			if (matTypeof(qcon) == 'array' && qcon.length > 0) {
				if (parseInt(qcon[0][4]) > now) {
					isBusy = true;
					activeblds.push(parseIntNan(qcon[0][7]));
					activetimes.push(parseIntNan(qcon[0][4]));
				}
			}
			if (isBusy) {
				var timeLeft = qcon[0][4] - now;
				str = '<table cellpadding=0 cellspacing=0 width=100% style="padding-right:0px;"><tr><td class=xtab align=center >';
				str += uW.buildingcost['bdg'+qcon[0][0]][0];
				if (qcon[0][1] == 0) {
					str += '<br>(Destroy)';
				} else {
					str += '<br>Lvl '+qcon[0][1];
				}
				str += '<br>'+timestr(timeLeft)+'</td></tr>';
				var Speedups = '';
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,1,t.Squire,'1 min');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,2,t.Knight,'15 mins');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,3,t.Guinevere,'60 mins');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,4,t.Morgana,'150 mins');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,5,t.Arthur,'8 hours');
				Speedups += '</tr><tr>';
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,6,t.Merlin,'15 hours');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,7,t.Divine,'24 hours');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,8,t.Epic,'60 hours');
				Speedups += t.paintSpeedup(cityId,qcon[0][2],0,10,t.Legendary,'96 hours');

				if (Speedups != "") Speedups = '<tr><td style="padding-right:0px;padding-bottom:2px;"><table align=left cellspacing=0 cellpadding=0><tr>' + Speedups + '</tr></table></td></tr>';
				str = str+Speedups+'<tr><td class=xtab><table align=center cellspacing=0 cellpadding=0><tr><td class=xtab style="padding-right:0px;"><a class="inlineButton button14" onClick="btcancelConstruction('+cityId+',0)"><span>'+tx("Cancel")+'</span></a></td></tr></table>';

				if (qcon.length > 1) {
					if (parseInt(qcon[1][4]) > now) {
						activeblds.push(parseIntNan(qcon[1][7]));
						activetimes.push(parseIntNan(qcon[1][4]));
						timeLeft = qcon[1][4] - now;
						str += '</td></tr><tr><td class=xtab align=center >';
						str += uW.buildingcost['bdg'+qcon[1][0]][0];
						if (qcon[1][1] == 0) {
							str += '<br>(Destroy)';
						} else {
							str += '<br>Lvl '+qcon[1][1];
						}
						str += '<br>'+timestr(timeLeft)+'</td></tr>';
						var Speedups = '';
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,1,t.Squire,'1 min');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,2,t.Knight,'15 mins');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,3,t.Guinevere,'60 mins');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,4,t.Morgana,'150 mins');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,5,t.Arthur,'8 hours');
						Speedups += '</tr><tr>';
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,6,t.Merlin,'15 hours');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,7,t.Divine,'24 hours');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,8,t.Epic,'60 hours');
						Speedups += t.paintSpeedup(cityId,qcon[0][2],1,10,t.Legendary,'96 hours');

						if (Speedups != "") Speedups = '<tr><td style="padding-right:0px;padding-bottom:2px;"><table align=left cellspacing=0 cellpadding=0><tr>' + Speedups + '</tr></table></td></tr>';
						str = str+Speedups+'<tr><td class=xtab><table align=center cellspacing=0 cellpadding=0><tr><td class=xtab style="padding-right:0px;"><a class="inlineButton button14" onClick="btcancelConstruction('+cityId+',1)"><span>'+tx("Cancel")+'</span></a></td></tr></table>';
					}
				}
				str += '</td></tr></table>';
            }

			var ascended = getAscensionValues(cityId);
			var faction = ascended.prestigeType;
			var CityFaction = tx('Not ascended');
			var CityValue = parseIntNan(Seed.cityData.city[cityId].cityValue);
			var cityPrestigeLevel = ascended.prestigeLevel;
			if (faction != 0) {
				CityFaction = getFactionName(faction) + '&nbsp('+cityPrestigeLevel+')';
			}
			var CityPercent = parseIntNan(CityValue*100/t.getAscensionRequirements('max',faction,(parseIntNan(cityPrestigeLevel)+1)));
			var CityMin = parseIntNan(t.getAscensionRequirements('min',faction,(parseIntNan(cityPrestigeLevel)+1)));
			if (parseIntNan(cityPrestigeLevel) >= CM.PrestigeModel.getLevelCapSoft(faction)) {
				CityPercent = 'max';
				ById('btBuildAutoAscendCity_'+citynum).disabled = true;
			}
			else {
				ById('btBuildAutoAscendCity_'+citynum).disabled = false;
				if (CityPercent >= 100) { CityPercent = '<span class=boldGreen>100%</span>'; }
				else {
					if (CityValue < CityMin) { CityPercent = '<span class=boldRed>'+CityPercent+'%</span>'; }
					else { CityPercent = CityPercent+'%'; }
				}
			}
			var prestigeexp = '&nbsp;';
			var cityExpTime = ascended.prestigeBuffExpire;
			if ((!isNaN(cityExpTime)) && (cityExpTime +(3600*24) >= unixTime())) {
				if (cityExpTime < unixTime()) {
					prestigeexp = '<span style="color:#f00"><b>&nbsp;'+tx('Expired!')+'</b></span>';
				}
				else {
					prestigeexp = '<span style="color:#080"><b>&nbsp;'+uW.timestr(cityExpTime-unixTime())+'</b></span>';
				}
			}

			ById("btBuildFactionCity_"+citynum).innerHTML = CityFaction;
			ById("btBuildAscensionPercentCity_"+citynum).innerHTML = CityPercent;
			ById("btBuildAscensionProtectionCity_"+citynum).innerHTML = prestigeexp;

			var Completed = true;
			var QEntries = false;
			var BQ = t.BuildQueue[t.QueueKey(cityId)];
			var QLen = 0;
			var QTime = 0;
			for (var b in BQ) {
				if (BQ[b].hasOwnProperty("buildtype")) {
					QEntries = true;
					var CurrLevel = 0;
					if (Seed.buildings['city'+cityId][b] && Seed.buildings['city'+cityId][b][0]==BQ[b].buildtype) {
						CurrLevel = parseIntNan(Seed.buildings['city'+cityId][b][1]);
					}
					var pos = Number(b.split("pos")[1]);
					var actindex = activeblds.indexOf(pos);
					var acttime = 0;
					var bbmax = BQ[b].maxlevel;
					if (actindex != -1) {
						acttime = activetimes[actindex]-now;
						bbmax--;
					}
					QTime += acttime;

					if (BQ[b].maxlevel==0) {
						Completed = false;
						QLen += 1;
						if (acttime==0) {
							QTime += t.getBuildTime(cityId, CurrLevel, BQ[b].buildtype, true);
						}
					}
					else {
						if (BQ[b].maxlevel>CurrLevel) {
							Completed = false;
							QLen += BQ[b].maxlevel-CurrLevel;
							for (var bb=CurrLevel;bb<bbmax;bb++) {
								QTime += t.getBuildTime(cityId, bb, BQ[b].buildtype, false);
							}
						}
					}
				}
			}

			if (!isBusy && QEntries && Completed) { str = uW.g_js_strings.commonstr.completedexc; }
			ById('btBuildActiveCity_'+citynum).innerHTML = str;

			ById("btBuildQueueLengthCity_"+citynum).innerHTML = QLen;
			ById("btBuildQueueTimeCity_"+citynum).innerHTML = timestr(QTime);
		}

		if (Options.BuildOptions.ThroneCheck && (t.buildspeed < Number(Options.BuildOptions.BuildSpeed))) {
			ts = '<span class=boldRed><b>'+t.buildspeed+'%</b></span>';
		}
		else { ts = t.buildspeed+'%'; }
		ById("btBuildCurrTR").innerHTML = ts;
		cv = t.cityval+'%';
		ById("btCityValCurrTR").innerHTML = cv;
	},

	paintSpeedup : function (cityId, qitem, i, item, count, hint) {
		var t = Tabs.Build;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px"><a onClick="speedupBuild('+cityId+','+item+','+qitem+','+i+')"><img height=18 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+hint+') ('+count+')"></a></td>';
		}
		return n;
	},

	cancelAll: function (cityId) {
		var t = Tabs.Build;
		delete t.BuildQueue[t.QueueKey(cityId)];
		t.SaveBuildQueue();
		t.PaintOverview();
		t.PaintCityInfo();
	},

	cancelBuild: function (cityId,pos) {
		var t = Tabs.Build;
		delete t.BuildQueue[t.QueueKey(cityId)][pos];
		t.SaveBuildQueue();
		t.PaintOverview();
		t.PaintCityInfo();
	},

	allBuildsTo : function (cityId,AddType,ToLevel) {
		var t = Tabs.Build;
		if (AddType != 'empty') {
			for (var b in Seed.buildings['city'+cityId]) {
				var building = Seed.buildings['city'+cityId][b];
				if (building) {
					if (parseInt(building[2]) < 300 || parseInt(building[2]) > 309) { // no dummy ascension buildings
						if (building && building[1] != 0) { // ALL doesn't include guardians or defensive tower!
							if ((building[0]==5 && AddType=="cottages") || (building[0]==1 && AddType=="farms") || (building[0]==2 && AddType=="sawmills") || (building[0]==3 && AddType=="quarries") || (building[0]==4 && AddType=="mines") || (building[0]==13 && AddType=="barracks") || (building[0]>=50 && building[0]<=53 && AddType=="guardians") || (building[0]==30 && AddType=="deftower") || (building[0]==31 && AddType=="redoubt") || (AddType=="all" && building[0]<30)) {
								t.addToBuildQueue(cityId,b,building[0],ToLevel,parseIntNan(building[1]));
							}
						}
					}
				}
				// automatically add walls even if level 0 when "all" chosen.
				if (AddType=="all" && (!Seed.buildings['city'+cityId]['pos1'] || Seed.buildings['city'+cityId]['pos1'][1]==0)) {
					t.addToBuildQueue(cityId,"pos1",19,ToLevel,0);
				}
			}
		}
		else {
			for (var b = 1;b<=32;b++) {
				if (!Seed.buildings['city'+cityId]['pos'+b]) {
					if (b==1) { var buildingType = 19; } // wall in position 1!
					else {
						var buildingType = Options.BuildOptions.EmptySlots;
					}
					t.addToBuildQueue(cityId,"pos"+b,buildingType,ToLevel,0);
				}
            }
		}
		t.citydelay[Cities.byID[cityId].idx+1] = 0;
		t.SaveBuildQueue();
		t.PaintOverview();
		t.PaintCityInfo();
	},

	addToBuildQueue : function (cityId,pos,buildtype,maxlevel,currlevel) {
		var t = Tabs.Build;
		var Result = false;
		if (uW.buildingmaxlvl[buildtype]<maxlevel) { maxlevel = uW.buildingmaxlvl[buildtype]; }
		if (!t.BuildQueue[t.QueueKey(cityId)]) { t.BuildQueue[t.QueueKey(cityId)] = {}; }
		if (currlevel < maxlevel || maxlevel==0) {
			t.BuildQueue[t.QueueKey(cityId)][pos] = {buildtype:buildtype,maxlevel:maxlevel,status:"",ascendcomplete:"",errors:0};
			// if castle, check and add wall SPECIAL CASE!!
			if (maxlevel != 0 && buildtype==0) {
				var wallLevel = 0;
				if (Seed.buildings["city" + cityId] && Seed.buildings["city" + cityId].pos1) {
					wallLevel = parseInt(Seed.buildings["city" + cityId].pos1[1]);
				}
				if (maxlevel>2 && wallLevel<maxlevel-2) {
					t.addToBuildQueue(cityId,"pos1",19,(maxlevel-2),wallLevel);
				}
			}
			t.SaveBuildQueue();
			Result = true;
		}
		return Result;
	},

	getBuildTime : function (cityId, buildingLevel, buildingType, destroy) {
		var t = Tabs.Build;
		var now = unixTime();
		var constructionBoost = uW.cm.ThroneController.getBoundedEffect(78);
		if (destroy) {
			var buildingMult = 1;
			if (buildingLevel>2) { buildingMult = Math.pow(2, buildingLevel-2); }
		}
		else {
			var buildingMult = Math.pow(2, buildingLevel);
		}
		var polValue = 0;
		var knt = Seed.knights["city" + cityId];
		if (knt) {
			knt = knt["knt" + Seed.leaders["city" + cityId].politicsKnightId];
			if (knt) {
				polValue = parseInt(knt.politics)
				if (!destroy) {
					var polBoost = parseInt(knt.politicsBoostExpireUnixtime);
					if (polBoost > now) {
						polValue = parseInt(polValue * 1.25);
					}
				}
			}
		}
		var buildingTime = uW.buildingcost["bdg" + buildingType][7] * buildingMult;
		if (parseInt(buildingType) == 30) {
			buildingTime = uW.cm.defensiveTower.costs[buildingLevel+1][6];
		}
		if (parseInt(buildingType) == 31) {
			buildingTime = uW.cm.defensiveTowerRedoubt.costs[buildingLevel+1][6];
		}
		if (parseInt(buildingType) < 6 && parseInt(buildingType) > 0 && buildingMult == 1) {
			buildingTime = 15;
		}
		if (destroy) {
			if (buildingTime % 1 > 0) { buildingTime = parseInt(buildingTime); }
		}
		else {
			buildingTime = parseInt(buildingTime / (1 + 0.005 * polValue + 0.1 * parseInt(Seed.tech.tch16)));
			if (constructionBoost > 0) buildingTime = Math.round(buildingTime / (1 + (constructionBoost / 100)));
		}
        return buildingTime;
	},

	PaintCityInfo : function () {
		var t = Tabs.Build;
		var cityId = t.ModelCityId;

		if (cityId==0) { return; }

		t.ValidateBuildQueue(cityId,true); // clear completed if required

		// paint the Queue...

		var SortedQ = t.sortBuildQueue(cityId);
		var now = unixTime();
		var BQ = t.BuildQueue[t.QueueKey(cityId)];
		var QLen = SortedQ.length;

		if (QLen==0) {
			t.LastQueue = 'x';
			m = '<br><div align=center style="opacity:0.3;">'+tx('No buildings queued')+'</div>';
			ById('btBldQueue').innerHTML = m;
		} else {
			var activeblds = [];
			var activetimes = [];
			var qcon = Seed.queue_con["city" + cityId];
			if (matTypeof(qcon) == 'array' && qcon.length > 0) {
				if (parseInt(qcon[0][4]) > now) { activeblds.push(parseIntNan(qcon[0][7])); activetimes.push(parseIntNan(qcon[0][4])); }
				if (qcon.length > 1) {
					if (parseInt(qcon[1][4]) > now) { activeblds.push(parseIntNan(qcon[1][7])); activetimes.push(parseIntNan(qcon[1][4])); }
				}
			}

			var qs = JSON2.stringify(SortedQ);
			if (qs == t.LastQueue) { // queue hasn't changed, just update the current level, time, and status text
				for (var QObj in SortedQ) {
					var b = SortedQ[QObj].b;
					if (b) {
						var CurrLevel = 0;
						var pos = Number(b.split("pos")[1]);
						var StatusText = BQ[b].status;
						var actindex = activeblds.indexOf(pos);
						var acttime = 0;
						var bbmax = BQ[b].maxlevel;
						if (actindex != -1) {
							if (BQ[b].maxlevel>0) { StatusText = tx('Building')+'...'; }
							else { StatusText = tx('Destroying')+'...'; }
							if (BQ[b].status != "") {
								BQ[b].status = "";
								t.SaveBuildQueue();
							}
							acttime = activetimes[actindex]-now;
							bbmax--;
						}
						var QTime = acttime;
						if (Seed.buildings["city"+cityId][b]) { CurrLevel = parseIntNan(Seed.buildings["city"+cityId][b][1]); }
						if ((actindex == -1) && BQ[b].ascendcomplete && BQ[b].ascendcomplete == Seed.cityData.city[cityId].prestigeInfo.prestigeLevel) { StatusText = 'Complete!'; }
						if (BQ[b].maxlevel==0) {
							if (acttime==0) {
								QTime += t.getBuildTime(cityId, CurrLevel, BQ[b].buildtype, true);
							}
						}
						else {
							for (var bb=CurrLevel;bb<bbmax;bb++) {
								QTime += t.getBuildTime(cityId, bb, BQ[b].buildtype, false);
							}
						}
						ById('pbbldcurr_'+b).innerHTML = CurrLevel;
						ById('pbbldtime_'+b).innerHTML = timestr(QTime, true);
						ById('pbbldstatus_'+b).innerHTML = StatusText;
					}
				}
			} else {
				t.LastQueue = qs;

				m = '<TABLE width=98% cellspacing=0 align=center class=xtab><tr><th width=30px class=xtabHD align=left>'+tx('Pos')+'</th><th class=xtabHD align=left>'+uW.g_js_strings.commonstr.type+'</th><th width=50px class=xtabHD align=center>'+tx('Max Level')+'</th><th width=50px class=xtabHD align=center>'+tx('Current')+'</th><th width=100px class=xtabHD align=right>'+tx('Remaining')+'</th><th class=xtabHD align=left>'+uW.g_js_strings.commonstr.status+'</th><th class=xtabHD align=right><a id=btBldCancelAllButton class="inlineButton btButton red14" onclick="btBldCancelAll('+cityId+')"><span>'+tx('Remove All')+'</span></a></th></tr>';
				var r = 0;

				for (var QObj in SortedQ) {
					var b = SortedQ[QObj].b;
					if (b) {
						rowClass = 'evenRow';
						var rem = (r % 2);
						if (rem == 1) rowClass = 'oddRow';
						var CurrLevel = 0;
						var pos = Number(b.split("pos")[1]);
						var StatusText = BQ[b].status;
						var actindex = activeblds.indexOf(pos);
						var acttime = 0;
						var bbmax = BQ[b].maxlevel;
						if (actindex != -1) {
							if (BQ[b].maxlevel>0) { StatusText = tx('Building')+'...'; }
							else { StatusText = tx('Destroying')+'...'; }
							if (BQ[b].status != "") {
								BQ[b].status = "";
								t.SaveBuildQueue();
							}
							acttime = activetimes[actindex]-now;
							bbmax--;
						}
						var QTime = acttime;
						if (Seed.buildings["city"+cityId][b]) { CurrLevel = parseIntNan(Seed.buildings["city"+cityId][b][1]); }
						if ((actindex == -1) && BQ[b].ascendcomplete && BQ[b].ascendcomplete == Seed.cityData.city[cityId].prestigeInfo.prestigeLevel) { StatusText = 'Complete!'; }

						m += '<TR class="'+rowClass+'"><TD align=left>'+pos+'</td><td align=left>'+uW.buildingcost['bdg'+BQ[b].buildtype][0]+'</td><td align=center>'+(BQ[b].maxlevel||"("+uW.g_js_strings.commonstr.decontruct+")")+'</td><td align=center id="pbbldcurr_'+b+'">'+(CurrLevel||"--")+'</td>';
						if (BQ[b].maxlevel==0) {
							if (acttime==0) {
								QTime += t.getBuildTime(cityId, CurrLevel, BQ[b].buildtype, true);
							}
						}
						else {
							for (var bb=CurrLevel;bb<bbmax;bb++) {
								QTime += t.getBuildTime(cityId, bb, BQ[b].buildtype, false);
							}
						}
						m += '<td align=right id="pbbldtime_'+b+'">'+timestr(QTime, true) + '</td>';
						m += '<td align=left id="pbbldstatus_'+b+'">'+StatusText+'</td><td align=right><A class="inlineButton btButton brown11" onclick="cancelBuild(' + cityId + ',\'' + b + '\')"><span>'+tx('Remove')+'</span></a></td></tr>';
						r++;
					}
				}
				m += '</table><div align=center id=btBldQueueMessage>&nbsp;</div>';
				ById('btBldQueue').innerHTML = m;
			}
		}
		ById('btBldQueueStats').innerHTML = QLen+ ' Buildings';
		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	getAscensionRequirements : function (type,faction,level) {
		var t = Tabs.Build;
		var fac = 'DRUID';
		switch (faction) {
			case "2": fac = 'FEY'; break;
			case "3": fac = 'BRITON'; break;
		}
		return CM.WorldSettings.getSettingAsObject("ASCENSION_REQS_"+fac)[level] ? parseIntNan(CM.WorldSettings.getSettingAsObject("ASCENSION_REQS_"+fac)[level][type]) : 9999999;
	},

	CreateBuildModeDiv : function () {
		var t = Tabs.Build;

		t.BuildDiv = document.createElement('div');
		t.BuildDiv.id = 'btBuildDiv';
		t.BuildDiv.style.position = 'absolute';
		t.BuildDiv.style.width = '750px';
		t.BuildDiv.style.top = '20px';
		t.BuildDiv.style.height = '25px';
		t.BuildDiv.style.paddingLeft = '10px';
		t.BuildDiv.style.paddingTop = '8px';
		t.BuildDiv.style.zIndex = '20002'; // keep above nearly everything else...
		t.BuildDiv.style.display = 'none';
		t.BuildDiv.style.opacity = '0.95';
		t.BuildDiv.style.backgroundColor = '#fde073';

		var m = '<table cellpadding=0 cellspacing=0 class=xtab width=100%><tr><td><b><span id=pbbmlabel>'+tx('BUILD MODE')+':</span></b>&nbsp;</td>';
		m += '<td>'+uW.g_js_strings.commonstr.type+':&nbsp;'+htmlSelector({build: tx('Next Level Only'), max: tx('Build to Level'), destroy: uW.g_js_strings.commonstr.decontruct, stomp: tx('Dragon Stomp')},'max','id=pbbuildmodetype')+'&nbsp;'+uW.g_js_strings.commonstr.level+'&nbsp;<select id=pbbuildmodeto></select></td>';
		m += '<td>'+tx('Empty Slots')+':&nbsp;'+htmlSelector(t.BuildList,Options.BuildOptions.EmptySlots,'id=pbbuildmodeempty')+'</td>';
		m += '<td align=right>'+strButton14(uW.g_js_strings.commonstr.close,'id=pbbuildmodeclose')+'</td></tr></table>';
		t.BuildDiv.innerHTML = m;

		ById('mod_maparea').appendChild(t.BuildDiv);

		ChangeOption('BuildOptions','pbbuildmodeempty','EmptySlots');
		ById('pbbuildmodeclose').addEventListener('click', t.toggleStateMode, false);
	},

	FlashBuildMode : function(color) {
		var t = Tabs.Build;
		jQuery('#pbbmlabel').css('color', color);
		setTimeout(function() { jQuery('#pbbmlabel').css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')'); },250);
	},

	bot_buildslot: function (c, a) {
		var t = Tabs.Build;
		var buildingMode = ById('pbbuildmodetype').value;
		var toLevel = ById('pbbuildmodeto').value.substr(5);
        var cityId = uW.currentcityid;
        var buildingPos = c.id.split("_")[1];
		if (!Seed.buildings['city' + cityId]["pos" + buildingPos]) {
			// new build!
			if (buildingMode != "stomp" && buildingMode != "destroy") {
				if (buildingPos==1) { var buildingType = 19; } // wall in position 1!
				else {
					var buildingType = parseIntNan(Options.BuildOptions.EmptySlots);
				}
				if (buildingMode == "build") {
					var buildingLevel = 0;
					if (t.BuildQueue[t.QueueKey(cityId)] && t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos] && t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].buildtype==buildingType) {
						if (t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].maxlevel > buildingLevel) { buildingLevel = t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].maxlevel; }
					}
					buildingLevel += 1;
				}
				else {
					if (buildingMode == "max") { var buildingLevel = parseIntNan(toLevel); }
				}
				var maxlevel = buildingLevel;
				if (uW.buildingmaxlvl[buildingType]<maxlevel) { maxlevel = uW.buildingmaxlvl[buildingType]; }

				if (t.addToBuildQueue(cityId,"pos"+buildingPos,buildingType,buildingLevel,0)) {
					t.FlashBuildMode('green');
					t.citydelay[Cities.byID[cityId].idx+1] = 0;
					return;
				}
			}
		}
		else {
			var buildingType = parseIntNan(Seed.buildings['city' + cityId]["pos" + buildingPos][0]);
			var buildingLevel = parseIntNan(Seed.buildings['city' + cityId]["pos" + buildingPos][1]);
			var buildingId = parseIntNan(Seed.buildings['city' + cityId]["pos" + buildingPos][3]);
			if (buildingMode != "stomp" && buildingMode != "destroy") {
				if (buildingLevel < Options.BuildOptions.maxbuildlevel) {
					var CurrLevel = buildingLevel;
					if (buildingMode == "build") {
						if (t.BuildQueue[t.QueueKey(cityId)] && t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos] && t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].buildtype==buildingType) {
							if (t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].maxlevel > buildingLevel) { buildingLevel = t.BuildQueue[t.QueueKey(cityId)]["pos"+buildingPos].maxlevel; }
						}
						buildingLevel += 1;
					}
					else {
						if (buildingMode == "max") { buildingLevel = parseIntNan(toLevel); }
					}
					var maxlevel = buildingLevel;
					if (uW.buildingmaxlvl[buildingType]<maxlevel) { maxlevel = uW.buildingmaxlvl[buildingType]; }
					if (t.addToBuildQueue(cityId,"pos"+buildingPos,buildingType,maxlevel,CurrLevel)) {
						t.FlashBuildMode('green');
						t.citydelay[Cities.byID[cityId].idx+1] = 0;
						return;
					}
				}
			}
			else {
				if (buildingMode == "stomp") {
					uW.destructBuildingConfirm(buildingId, buildingPos);
					t.FlashBuildMode('green');
					return;
				};
				if (buildingMode == "destroy") {
					if (t.addToBuildQueue(cityId,"pos"+buildingPos,buildingType,0,buildingLevel)) {
						t.FlashBuildMode('green');
						t.citydelay[Cities.byID[cityId].idx+1] = 0;
						return;
					}
				}
			}
		}
		t.FlashBuildMode('red'); // indicate error
	},

	bot_gethelp: function (f, cid, time, retry) {
		var t = Tabs.Build;
		if (retry>3) return;  //dont want to get stuck in a loop of failures
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.bid = f;
		params.ctrl = 'AskForHelp';
		params.action = 'getHelpData';
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/_dispatch.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok && rslt.data) {
					uW.handleHelpCallback(rslt.data);
					//only post build to FB if they take at least half an hour
					if (time > 1800) {
						var a = Seed.queue_con["city" + cid];
						var e = 0;
						var d = 0;
						for (var c = 0; c < a.length; c++) {
							if (parseInt(a[c][2]) == parseInt(f)) {
								e = parseInt(a[c][0]);
								d = parseInt(a[c][1]);
								break
							}
						}
						var b = new Array();
						b.push(["REPLACE_LeVeLbUiLdInG", d]);
						b.push(["REPLACE_BuIlDiNgNaMe", uW.buildingcost["bdg" + e][0]]);
						b.push(["REPLACE_LeVeLiD", d]);
						b.push(["REPLACE_AsSeTiD", f]);
						var g = function (h, i) {
							uW.continuation_95(h, i);
							if (!h) {
								var j = d > 1 ? uW.cm.SpeedUpType.upgrade : uW.cm.SpeedUpType.build;
								uW.cm.ClientSideCookieManager.setCookie(j, false)
							}
						};
						uW.common_postToProfile("95", b);
					}
				}
				else {
					if (rslt.errorMsg) { actionLog(Cities.byID[cid].name+': '+rslt.errorMsg,'BUILD'); }
					else { actionLog(Cities.byID[cid].name+': Build help request failure','BUILD'); }
				}
			},
			onFailure: function () {
				actionLog(Cities.byID[cid].name+': Build help request failure','BUILD');
				t.bot_gethelp(f, cid, time, retry+1);
				return;
			},
		},true);
	},

	sortBuildQueue : function (cityId) {
		var t = Tabs.Build;
		var Sorted = [];
		var BQ = t.BuildQueue[t.QueueKey(cityId)];
		if (BQ && BQ!={}) {
			BQ = JSON2.parse(JSON2.stringify(BQ)); // new object
			for (var b in BQ) {
				var BObj = BQ[b];
				if (BObj.hasOwnProperty("buildtype")) {
					var CurrLevel = 0;
					if (Seed.buildings["city"+cityId][b]) { CurrLevel = parseIntNan(Seed.buildings["city"+cityId][b][1]); }
					var QTime = 0;
					if (BQ[b].maxlevel==0) { QTime = t.getBuildTime(cityId, CurrLevel, BQ[b].buildtype, true); }
					else {
						if (CurrLevel>=BQ[b].maxlevel) { QTime=99999999; }
						else { QTime = t.getBuildTime(cityId, CurrLevel, BQ[b].buildtype, false); }
					}
					var SmartOrder = t.SmartOrder.indexOf(Number(BQ[b].buildtype));
					if (SmartOrder<0) { SmartOrder = 99999999; }
					BObj.QTime = QTime;
					BObj.b = b;
					BObj.pos = Number(b.split("pos")[1]);
					BObj.SmartOrder = SmartOrder;
					Sorted.push(BObj);
				}
			}
			// sort by next level time, then position...
			if (parseIntNan(Options.BuildOptions.BuildPriority)==1) {
				Sorted.sort(function(a, b){ var x = a.QTime - b.QTime; return (x==0) ? a.pos - b.pos : x; });
			}
			// sort by position...
			if (parseIntNan(Options.BuildOptions.BuildPriority)==2) {
				Sorted.sort(function(a, b){ return a.pos - b.pos; });
			}
			// sort by type, then position...
			if (parseIntNan(Options.BuildOptions.BuildPriority)==3) {
				Sorted.sort(function(a, b){ var x = Number(a.buildtype) - Number(b.buildtype); return (x==0) ? a.pos - b.pos : x; });
			}
			// sort by smartorder, then position...
			if (parseIntNan(Options.BuildOptions.BuildPriority)==4) {
				Sorted.sort(function(a, b){ var x = a.SmartOrder - b.SmartOrder; var y = Number(b.buildtype) - Number(a.buildtype); return (x==0) ? ((y==0) ? a.pos - b.pos : y) : x; });
			}
			return Sorted;
		}
		else {
			return Sorted;
		}
	},

	ValidateBuildQueue : function (cityId,save) {
		var t = Tabs.Build;
		var BQ = t.BuildQueue[t.QueueKey(cityId)];
		if (BQ && BQ!={}) {
			for (var b in BQ) {
				var BObj = BQ[b];
				if (BObj.hasOwnProperty("buildtype")) {
					if (BObj.ascendcomplete && BObj.ascendcomplete != Seed.cityData.city[cityId].prestigeInfo.prestigeLevel) { // new ascension level
						t.BuildQueue[t.QueueKey(cityId)][b].ascendcomplete = ""; // clear completed flag
						t.BuildQueue[t.QueueKey(cityId)][b].status = ""; // clear status flag
						if (save) t.SaveBuildQueue();
					}
					if (Seed.buildings["city"+cityId][b]) { // check building type and level
						var buildingType = parseIntNan(Seed.buildings['city' + cityId][b][0]);
						var buildingLevel = parseIntNan(Seed.buildings['city' + cityId][b][1]);
					}
					if (BObj.maxlevel > 0) {
						if (Seed.buildings["city"+cityId][b]) { // check building type and level
							var KeepCompleted = (Options.BuildOptions.KeepCompleted && Seed.cityData.city[cityId].isPrestigeCity);
							if (buildingType && BObj.buildtype!=buildingType || (BObj.maxlevel<=buildingLevel && !KeepCompleted)) {
								delete t.BuildQueue[t.QueueKey(cityId)][b];
								if (save) t.SaveBuildQueue();
							}
						}
					}
					else { // check if already destroyed
						if (!Seed.buildings["city"+cityId][b]) {
							delete t.BuildQueue[t.QueueKey(cityId)][b];
							if (save) t.SaveBuildQueue();
						}
						else {
							if (buildingType && BObj.buildtype!=buildingType) {
								delete t.BuildQueue[t.QueueKey(cityId)][b];
								if (save) t.SaveBuildQueue();
							}
						}
					}
				}
			}
		}
	},

	doAutoLoop : function (idx) {
		var t = Tabs.Build;
		clearTimeout(t.timer);
		if (!Options.BuildOptions.Running) return;

		var cityId = Cities.cities[idx-1].id;
		if (idx==1) { t.loopaction = false; } // reset loop action indicator for first city
		t.autodelay = 0; // no delay if no action taken!

		// first check if city is idle (or busy)

		var now = unixTime();
		var isBusy = false;
		var qcon = Seed.queue_con["city" + cityId];
		if (qcon.length > 0) {
			if (parseInt(qcon[0][4]) > now) {
				isBusy = true;
				// try second queue
				if (CM.QueueModel.hasFreeQueue() && Options.BuildOptions.bothqueues) {
					isBusy = false;
					if (qcon.length > 1) {
						if (parseInt(qcon[1][4]) > now) { isBusy = true; }
					}
					else { t.FixQueue(cityId,1); }
				}
			}
			else { t.FixQueue(cityId,0); }
		}

		if (isBusy) {
			// queue busy, try speedup!
			t.autoSpeedup (cityId,qcon[0]);
		}
		else { // we can build!
			t.ValidateBuildQueue(cityId,true);
			if (!Options.BuildOptions.ThroneCheck || (t.buildspeed >= Options.BuildOptions.BuildSpeed)) { // if no build speed restriction or enough building speed
				var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[idx]);
				if (Options.BuildOptions.Enabled[idx] && ascensionok) {
					if (t.citydelay[idx] > 0) { t.citydelay[idx]--; } // city being delayed due to error, reduce delay number and skip city
					else {
						var SortedQ = t.sortBuildQueue(cityId);
						if (SortedQ.length>0) {
							var activeblds = [];
							if (matTypeof(qcon) == 'array' && qcon.length > 0) {
								if (parseInt(qcon[0][4]) > now) { activeblds.push(parseIntNan(qcon[0][7])); }
								if (qcon.length > 1) {
									if (parseInt(qcon[1][4]) > now) { activeblds.push(parseIntNan(qcon[1][7])); }
								}
							}

							// select next building from sorted queue and check build requirements...

							var SomethingToBuild = false;
							for (var QObj in SortedQ) {
								var b = SortedQ[QObj].b;
								if (b) {
									if (activeblds.indexOf(parseIntNan(b.split("pos")[1])) == -1) { // check not already building
										var QEntry = t.BuildQueue[t.QueueKey(cityId)][b];
										if (QEntry.maxlevel>0) {
											if (!QEntry.ascendcomplete || QEntry.ascendcomplete != Seed.cityData.city[cityId].prestigeInfo.prestigeLevel) { // check building not already completed for this ascension level
												var NextLevel = 1;
												if (Seed.buildings['city'+cityId][b]) { NextLevel = parseIntNan(Seed.buildings['city'+cityId][b][1])+1; }
												if (NextLevel <= QEntry.maxlevel) {
													var CanBuild = t.CheckCanBuild(QEntry.buildtype, NextLevel, cityId, b.split("pos")[1]);
													if (!CanBuild) { // update queue entry
														var statustext = tx('Missing Requirement');
														if (t.limitingFactor) { statustext += ' ('+t.limitingFactor+')'; }
														t.BuildQueue[t.QueueKey(cityId)][b].status = statustext;
														t.SaveBuildQueue();
													}
													else {
														SomethingToBuild = true;
														t.autodelay = t.intervalSecs;
														t.loopaction = true;
														t.Build(cityId,b,QEntry.buildtype,NextLevel);
														break;
													}
												}
												else {
													t.BuildQueue[t.QueueKey(cityId)][b].status = "";
													t.BuildQueue[t.QueueKey(cityId)][b].ascendcomplete = Seed.cityData.city[cityId].prestigeInfo.prestigeLevel;
													t.SaveBuildQueue();
												}
											}
										}
										else {
											// cannot destroy embassy while part of alliance...
											if (QEntry.buildtype==8 && getMyAlliance()[0] != 0) {
												var statustext = 'Cannot destroy when part of Alliance!';
												t.BuildQueue[t.QueueKey(cityId)][b].status = statustext;
												t.SaveBuildQueue();
											}
											else { // cannot destroy spire when craft queue is full
												if (QEntry.buildtype==20 && Seed.queue_craft["city"+cityId].length > 0) {
													var statustext = 'Cannot destroy when crafting!';
													t.BuildQueue[t.QueueKey(cityId)][b].status = statustext;
													t.SaveBuildQueue();
												}
												else {
													var NextLevel = parseIntNan(Seed.buildings['city'+cityId][b][1]); // need this for destroy?
													SomethingToBuild = true;
													t.autodelay = t.intervalSecs;
													t.loopaction = true;
													t.Destroy(cityId,b,QEntry.buildtype,NextLevel);
													break;
												}
											}
										}
									}
								}
							}
							if (!SomethingToBuild) {
								// nothing we can build in this city, delay the city by 10 loops...
								t.citydelay[idx] = 10;
							}
						}
					}
				}
			}
		}

		if (idx == Cities.numCities) {
			if (!t.loopaction) { t.autodelay = t.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(1); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1); }, (t.autodelay * 1000));
		}
	},

    autoSpeedup: function (cityId,q) {
		var t = Tabs.Build;
		var now = unixTime();
		var item = 0;
		totTime = q[4] - now;

		if (totTime > 0) {
			if (Options.BuildOptions.UseOverride && Options.BuildOptions.OverrideItem != 0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.BuildOptions.OverrideMinutes)*60)+(parseIntNan(Options.BuildOptions.OverrideHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && uW.ksoItems[Options.BuildOptions.OverrideItem].count > 0) { item = Options.BuildOptions.OverrideItem; }
			}
            if (item==0 && totTime >= HourGlassThreshold[8] && Options.BuildOptions.UseLH && uW.ksoItems[10].count > 0) { item = 10; }
            if (item==0 && totTime >= HourGlassThreshold[7] && Options.BuildOptions.UseEH && uW.ksoItems[8].count > 0) { item = 8; }
            if (item==0 && totTime >= HourGlassThreshold[6] && Options.BuildOptions.UseDH && uW.ksoItems[7].count > 0) { item = 7; }
            if (item==0 && totTime >= HourGlassThreshold[5] && Options.BuildOptions.UseRH && uW.ksoItems[6].count > 0) { item = 6; }
            if (item==0 && totTime >= HourGlassThreshold[4] && Options.BuildOptions.UseAH && uW.ksoItems[5].count > 0) { item = 5; }
            if (item==0 && totTime >= HourGlassThreshold[3] && Options.BuildOptions.UseMH && uW.ksoItems[4].count > 0) { item = 4; }
            if (item==0 && totTime >= HourGlassThreshold[2] && Options.BuildOptions.UseGH && uW.ksoItems[3].count > 0) { item = 3; }
            if (item==0 && totTime >= HourGlassThreshold[1] && Options.BuildOptions.UseKH && uW.ksoItems[2].count > 0) { item = 2; }
            if (item==0 && totTime >= HourGlassThreshold[0] && Options.BuildOptions.UseSH && uW.ksoItems[1].count > 0) { item = 1; }
        }

		if (item != 0) {
			t.autodelay = t.intervalSecs;
			t.loopaction = true;
			t.speedupBuild(cityId,item,q[2],0,true);
		}
    },

	FixQueue : function (cityId,qpos) {
		var t = Tabs.Build;
		var qcon = Seed.queue_con["city" + cityId];
		if (qcon[qpos]) { // fix the seed...
			if (GlobalOptions.ExtendedDebugMode) { logit(Cities.byID[cityId].name+': Fixing seed.building array','BUILD'); }
			if (qcon[qpos][1] == 0) {
				delete Seed.buildings["city" + cityId]['pos'+qcon[qpos][7]];
			}
			else {
				Seed.buildings["city" + cityId]['pos'+qcon[qpos][7]] = [qcon[qpos][0],qcon[qpos][1],qcon[qpos][7],qcon[qpos][2]];
			};
			qcon.pop(); // remove expired build from queue
			uW.modal_build_show_state();
			if (cityId == uW.currentcityid) uW.update_bdg();
		}
	},

	CheckCanBuild : function (BuildId,Level,cityId,pos) {
		var t = Tabs.Build;

		t.limitingFactor = null;

		if (parseIntNan(Level)==0) return false;

		var Result = true;

		if (BuildId >= 50 && BuildId <= 53) {	return true; }

		// for field view in unascended, check slot unlocked by castle level

		var MaxFields = 109 + (3 * parseInt(Seed.buildings["city"+cityId]["pos0"][1]));
		if (pos>MaxFields) {
			t.limitingFactor = tx('Field still locked');
			Result = false;
			return Result;
		}

		// if building above 10, check castle level

		if (Level > 10 && (BuildId == 19 || BuildId == 12 || BuildId == 16 || BuildId == 15 || BuildId == 17 || BuildId == 11 || BuildId == 18 || BuildId == 8 || BuildId == 9 || BuildId == 1 || BuildId == 2 || BuildId == 3 || BuildId == 4 || BuildId == 13)) {
			var B = parseInt(Seed.buildings["city"+cityId]["pos0"][1]);
			if (B < Level) {
				t.limitingFactor = tx('Castle');
				Result = false;
				return Result;
			}
		}

		// check resources

		if (BuildId == 30) { // defensive tower different
			var unitFood = parseInt(uW.cm.defensiveTower.costs[Level][1]);
			var unitWood = parseInt(uW.cm.defensiveTower.costs[Level][2]);
			var unitStone = parseInt(uW.cm.defensiveTower.costs[Level][3]);
			var unitOre = parseInt(uW.cm.defensiveTower.costs[Level][4]);
		}
		else {
			if (BuildId == 31) { // redoubt tower difference
				var unitFood = parseInt(uW.cm.defensiveTowerRedoubt.costs[Level][1]);
				var unitWood = parseInt(uW.cm.defensiveTowerRedoubt.costs[Level][2]);
				var unitStone = parseInt(uW.cm.defensiveTowerRedoubt.costs[Level][3]);
				var unitOre = parseInt(uW.cm.defensiveTowerRedoubt.costs[Level][4]);
			}
			else {
				var BuildMult = Math.pow(2, Level-1);
				var unitFood = parseInt(uW.buildingcost['bdg'+BuildId][1])*BuildMult;
				var unitWood = parseInt(uW.buildingcost['bdg'+BuildId][2])*BuildMult;
				var unitStone = parseInt(uW.buildingcost['bdg'+BuildId][3])*BuildMult;
				var unitOre = parseInt(uW.buildingcost['bdg'+BuildId][4])*BuildMult;
			}
		}
		var food = parseIntNan(Seed.resources['city' + cityId].rec1[0] / 3600);
		var wood = parseIntNan(Seed.resources['city' + cityId].rec2[0] / 3600);
		var stone = parseIntNan(Seed.resources['city' + cityId].rec3[0] / 3600);
		var ore = parseIntNan(Seed.resources['city' + cityId].rec4[0] / 3600);

		if (food < unitFood) {
			t.limitingFactor = uW.resourceinfo['rec1'];
			Result = false;
		}
		if (wood < unitWood) {
			t.limitingFactor = uW.resourceinfo['rec2'];
			Result = false;
		}
		if (stone < unitStone) {
			t.limitingFactor = uW.resourceinfo['rec3'];
			Result = false;
		}
		if (ore < unitOre) {
			t.limitingFactor = uW.resourceinfo['rec4'];
			Result = false;
		}

		if (!Result) return Result; // break out if already failed

		// building requirements

		var Buildings = getCityBuildings(cityId);

		if (BuildId == 30) { // defensive tower different
			var fc = uW.cm.defensiveTower.buildReq[Level];
			if (matTypeof(fc[0]) == 'object'){
				for (var k in fc[0]){
					var b = Buildings[k];
					var req = fc[0][k];
					if (req<0) { req=Level+req; }
					if (b.maxLevel < req){
						t.limitingFactor = uW.buildingcost["bdg"+k.substr(1)][0];
						Result = false;
						break;
					}
				}
			}
			var fc = uW.cm.defensiveTower.itemsReq[Level];
			if (matTypeof(fc) == 'object'){
				for (var k in fc){
					var b = parseIntNan(Seed.items["i"+k]);
					var req = fc[k];
					if (b < req){
						t.limitingFactor = uW.itemlist["i"+k].name;
						Result = false;
						break;
					}
				}
			}
		}
		else {
			if (BuildId == 31) { // redoubt tower different
				var fc = uW.cm.defensiveTowerRedoubt.buildReq[Level];
				if (matTypeof(fc[0]) == 'object'){
					for (var k in fc[0]){
						var b = Buildings[k];
						var req = fc[0][k];
						if (req<0) { req=Level+req; }
						if (b.maxLevel < req){
							t.limitingFactor = uW.buildingcost["bdg"+k.substr(1)][0];
							Result = false;
							break;
						}
					}
				}
				var fc = uW.cm.defensiveTowerRedoubt.itemsReq[Level];
				if (matTypeof(fc) == 'object'){
					for (var k in fc){
						var b = parseIntNan(Seed.items["i"+k]);
						var req = fc[k];
						if (b < req){
							t.limitingFactor = uW.itemlist["i"+k].name;
							Result = false;
							break;
						}
					}
				}
			}
			else {
				var fc = uW.buildingcost['bdg'+BuildId];
				if (matTypeof(fc[8]) == 'object'){
					for (var k in fc[8]){
						var b = Buildings[k.substr(1)];
						var req = fc[8][k][1];
						if (req<0) { req=Level+req; }
						if (b.maxLevel < req){
							t.limitingFactor = uW.buildingcost["bdg"+k.substr(1)][0];
							Result = false;
							break;
						}
					}
				}
				if (matTypeof(fc[9]) == 'object'){
					for (var k in fc[9]){
						if (parseInt(Seed.tech['tch'+k.substr(1)]) < (fc[9][k][1])+Level){
							t.limitingFactor = uW.techcost["tch"+k.substr(1)][0];
							Result = false;
							break;
						}
					}
				}
			}
		}

		// item requirements

		if (Level > 9) {
			var h = "i401";
			if (BuildId == 0) {
				if (Level == 11) {
					h = "i402"
				} else {
					if (Level == 12) {
						h = "i404"
					} else {
						if (Level == 13) {
							h = "i409"
						}
					}
				}
			} else {
				if (Level > 11) {
					h = "i403"
				}
			}
			if (BuildId == 12 && Level == 13) {
				h = "i410"
			}
			if (BuildId == 19 && Level == 13) {
				h = "i408"
			}
			if (BuildId == 5 && Level == 12) {
				h = "i407"
			}

			var c = CM.BuildingRequirements.get(BuildId, (Level-1));
			h = c || h;
			var b = parseIntNan(Seed.items[h]);
			if (b<1) {
				t.limitingFactor = uW.itemlist[h].name;
				Result = false;
			}
		}
		return Result;
	},

	speedupBuild : function (cityId,item,bid,slot,noretry) {
		var t = Tabs.Build;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btBuildCity_'+citynum).css('color', 'magenta');

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.iid = item;
		params.bid = bid;
		params.apothecary = false;
  		new MyAjaxRequest(uW.g_ajaxpath + "ajax/speedupConstruction.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var reduced = CM.intelligentOrdering.getReduceTime(item);
					Seed.items["i" + item] = parseInt(Seed.items["i" + item]) - 1;
					uW.ksoItems[item].subtract();
					var qloc = 0;
					var timered = 0;
					var queue = Seed.queue_con["city" + cityId][slot];
					timered = SpeedupArray[parseInt(item) - 1];
					queue[3] = parseInt(queue[3]) - timered;
					queue[4] = parseInt(queue[4]) - timered
					if (cityId == uW.currentcityid) uW.update_queue();
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Construction speedup failed ('+rslt.msg+')','BUILD');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Construction speedup failed ('+rslt.error_code+')','BUILD');
					}
				}
				jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
  			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Construction speedup failed (AJAX Error)','BUILD');
				jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
  		},noretry);
	},

	Destroy : function(cityId,bpos,btype,lvl) {
		var t = Tabs.Build;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btBuildCity_'+citynum).css('color', 'red');
		var bid = parseIntNan(Seed.buildings["city" + cityId][bpos][3]);
		var additionalqueue = 0;
		var qcon = Seed.queue_con["city"+cityId];
		if (matTypeof(qcon) == 'array' && qcon.length > 0) {
			if (CM.QueueModel.hasFreeQueue() && Options.BuildOptions.bothqueues) { // double check!
				additionalqueue = 1;
			}
			else {
				t.citydelay[citynum] = 10; // delay 10 loops
				actionLog(Cities.byID[cityId].name+': Not authorised to use second build queue','BUILD');
				return;
			}
		}
		var time = t.getBuildTime(cityId, lvl, btype, true);

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.bid = bid;
		params.pos = bpos.split("pos")[1];
		params.lv = lvl-1;
		params.type = btype;
		params.pay_for_an_additional_queue=additionalqueue;
		params.permission=0;

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/destruct.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					if (rslt.timeNeeded) { time = rslt.timeNeeded; }
					actionLog(Cities.byID[cityId].name+': Deconstructing '+uW.buildingcost['bdg'+btype][0],'BUILD');
					Seed.queue_con["city"+cityId].push([btype, 0, parseInt(rslt.buildingId), uW.unixtime(), uW.unixtime()+time, 0, time, params.pos]);
					if (params.cid == uW.currentcityid) uW.update_bdg();
					delete t.BuildQueue[t.QueueKey(cityId)][bpos]; // remove destroy request from queue
					t.SaveBuildQueue();
				}
				else {
					t.HandleBuildError (rslt,cityId,bpos,btype,lvl);
				}
				t.PaintOverview();
				jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': AJAX Error','BUILD');
				jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			}
		},true);
	},

	Build : function(cityId,bpos,btype,lvl) {
		var t = Tabs.Build;
		var citynum = Cities.byID[cityId].idx+1;
		var bid = 0;
		var BuildOK = true;
		if (Seed.buildings["city" + cityId][bpos]) { bid = parseIntNan(Seed.buildings["city" + cityId][bpos][3]); }
		var additionalqueue = 0;
		var qcon = Seed.queue_con["city"+cityId];
		if (matTypeof(qcon) == 'array' && qcon.length > 0) {
			if (CM.QueueModel.hasFreeQueue() && Options.BuildOptions.bothqueues) { // double check!
				additionalqueue = 1;
			}
			else {
				t.citydelay[citynum] = 10; // delay 10 loops
				actionLog(Cities.byID[cityId].name+': Not authorised to use second build queue','BUILD');
				BuildOK = false;
			}
		}

		// double check building requirements?

		if (btype != 30 && btype != 31) { // not defensive tower...?
			var chk = uW.checkreq("bdg", btype, lvl); //check if all requirements are met
			for (var c = 0; c < chk[3].length; c++) {
				if (chk[3][c] == 0) {
					t.citydelay[citynum] = 10; // delay 10 loops
					actionLog(Cities.byID[cityId].name+': Final building check failed ('+btype+','+lvl+')','BUILD');
					BuildOK = false;
				}
			}
		}

		if (BuildOK) {
			jQuery('#btBuildCity_'+citynum).css('color', 'green');
			var time = t.getBuildTime(cityId, lvl-1, btype, false);

			var params = uW.Object.clone(uW.g_ajaxparams);
			params.cid = cityId;
			params.bid = "";
			if (bid!=0) params.bid = bid;
			params.pos = bpos.split("pos")[1];
			params.lv = lvl;
			params.type = btype;
			params.pay_for_an_additional_queue=additionalqueue;
			if (params.lv > 9) { params.permission = 1; }
			else { params.permission=0; }

			new MyAjaxRequest(uW.g_ajaxpath + "ajax/construct.php" + uW.g_ajaxsuffix, {
				method: "post",
				parameters: params,
				onSuccess: function (rslt) {
					if (rslt.ok) {
						if (rslt.timeNeeded) { time = rslt.timeNeeded; }
						actionLog(Cities.byID[cityId].name+': Building '+uW.buildingcost['bdg'+btype][0]+' Level '+lvl,'BUILD');
						Seed.queue_con["city"+cityId].push([btype, lvl, parseInt(rslt.buildingId), uW.unixtime(), uW.unixtime()+time, 0, time, params.pos]);
						if (btype == 30) { // defensive tower different
							jQuery.each(CM.defensiveTower.itemsReq[lvl], function (i, G) {
								CM.InventoryView.removeItemFromInventory(i, G)
							});
							var unitFood = parseInt(uW.cm.defensiveTower.costs[lvl][1]);
							var unitWood = parseInt(uW.cm.defensiveTower.costs[lvl][2]);
							var unitStone = parseInt(uW.cm.defensiveTower.costs[lvl][3]);
							var unitOre = parseInt(uW.cm.defensiveTower.costs[lvl][4]);
						}
						else {
							if (btype == 31) { // redoubt tower different
								jQuery.each(CM.defensiveTowerRedoubt.itemsReq[lvl], function (i, G) {
									CM.InventoryView.removeItemFromInventory(i, G)
								});
								var unitFood = parseInt(uW.cm.defensiveTowerRedoubt.costs[lvl][1]);
								var unitWood = parseInt(uW.cm.defensiveTowerRedoubt.costs[lvl][2]);
								var unitStone = parseInt(uW.cm.defensiveTowerRedoubt.costs[lvl][3]);
								var unitOre = parseInt(uW.cm.defensiveTowerRedoubt.costs[lvl][4]);
							}
							else {
								var BuildMult = Math.pow(2, lvl-1);
								var unitFood = parseInt(uW.buildingcost['bdg'+btype][1])*BuildMult;
								var unitWood = parseInt(uW.buildingcost['bdg'+btype][2])*BuildMult;
								var unitStone = parseInt(uW.buildingcost['bdg'+btype][3])*BuildMult;
								var unitOre = parseInt(uW.buildingcost['bdg'+btype][4])*BuildMult;
							}
						}
						Seed.resources["city"+cityId].rec1[0] -= unitFood;
						Seed.resources["city"+cityId].rec2[0] -= unitWood;
						Seed.resources["city"+cityId].rec3[0] -= unitStone;
						Seed.resources["city"+cityId].rec4[0] -= unitOre;

						if (lvl > 9) {
							var h = "i401";
							if (btype == 0) {
								if (lvl == 11) {
									h = "i402"
								} else {
									if (lvl == 12) {
										h = "i404"
									} else {
										if (lvl == 13) {
											h = "i409"
										}
									}
								}
							} else {
								if (lvl > 11) {
									h = "i403"
								}
							}
							if (btype == 12 && lvl == 13) {
								h = "i410"
							}
							if (btype == 19 && lvl == 13) {
								h = "i408"
							}
							if (btype == 5 && lvl == 12) {
								h = "i407"
							}

							var c = CM.BuildingRequirements.get(btype, (lvl-1));
							h = c || h;
							Seed.items[h] = parseInt(Seed.items[h]) - 1;
							uW.ksoItems[parseInt(h.substr(1))].subtract();
						}

						if (Options.BuildOptions.help && time > 59) t.bot_gethelp(params.bid, cityId, time, 1);
						uW.queue_changetab_building();
						uW.modal_build_show_state();
						if (params.cid == uW.currentcityid) uW.update_bdg();
						if (lvl==t.BuildQueue[t.QueueKey(cityId)][bpos].maxlevel) {
							t.BuildQueue[t.QueueKey(cityId)][bpos].ascendcomplete = Seed.cityData.city[cityId].prestigeInfo.prestigeLevel; // completed
						}
						t.BuildQueue[t.QueueKey(cityId)][bpos].errors = 0;
						t.SaveBuildQueue();
					}
					else {
						t.HandleBuildError (rslt,cityId,bpos,btype,lvl);
					}
					t.PaintOverview();
					jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				},
				onFailure: function () {
					actionLog(Cities.byID[cityId].name+': AJAX Error','BUILD');
					jQuery('#btBuildCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
				}
			},true);
		}
	},

	HandleBuildError : function (rslt,cityId,bpos,btype,lvl) {
		var t = Tabs.Build;
		var citynum = Cities.byID[cityId].idx+1;
		// fix Seed missing buildingId for next pass...
		if (rslt.buildingId && Seed.buildings["city" + cityId][bpos]) {
			Seed.buildings["city" + cityId][bpos][3] = parseInt(rslt.buildingId);
		}
		if (!rslt.msg) {rslt.msg = 'Error Code ('+rslt.error_code+')';}
		actionLog(Cities.byID[cityId].name+': Building Error - '+rslt.msg,'BUILD');
		var a = null;
		var g = Number(rslt.error_code);
		var g_server = uW.g_server;
		var SetError = false;
		switch (g) {
			case 0:
				a = "Unexpected Error.";
				break;
			case 2: // building in progress - update seed to fix
				uW.buildingcost["bdg666"] = ["Building...", 0, 0, 0, 0, 0, 0, 0, [], [], ""];
				Seed.queue_con["city" + cityId].push([666, 666, 666, uW.unixtime(), uW.unixtime() + 90, 0, 90, 999]);
				a = "Construction is already starting.";
				break;
			case 3: // Unknown issue when updating your game, please try again
				break;
			case 8:
				a = "Excess traffic.";
				uW.cm.GATracker("Error", a + " (" + g + ")", g_server);
				break;
			case 102: // Another building already exists on the same spot
				SetError = true;
				break;
			case 103: // building already at this level
				SetError = true;
				break;
			case 104: // building cannot be built here
				SetError = true;
				break;
			case 105: // building does not exist here
				SetError = true;
				break;
			case 106: // only one building of this type
				SetError = true;
				break;
			case 107: // only one field building of this type
				SetError = true;
				break;
			case 108: // all available queues in use - update seed to fix
				uW.buildingcost["bdg666"] = ["Building...", 0, 0, 0, 0, 0, 0, 0, [], [], ""];
				Seed.queue_con["city" + cityId].push([666, 666, 666, uW.unixtime(), uW.unixtime() + 90, 0, 90, 999]);
				a = "all available queues are in use.";
				break;
			default:
				a = "Something has gone wrong.";
				uW.cm.GATracker("Error", a + " (" + g + ")", g_server);
		};
		if (SetError) {
			if (!t.BuildQueue[t.QueueKey(cityId)][bpos].errors) { t.BuildQueue[t.QueueKey(cityId)][bpos].errors = 0; }
			t.BuildQueue[t.QueueKey(cityId)][bpos].errors++;
			if (t.BuildQueue[t.QueueKey(cityId)][bpos].errors >= 3) { // remove building from queue after 3 errors
				actionLog(Cities.byID[cityId].name+': Removing Building in Position '+bpos+' from Build Queue','BUILD');
				delete t.BuildQueue[t.QueueKey(cityId)][bpos];
			}
			t.SaveBuildQueue();
		}
		if(rslt.user_action) { // captcha wtf?
			actionLog(Cities.byID[cityId].name+': Build Captcha Detected - delaying...','BUILD');
			t.citydelay[citynum] = 10;
		}
	},

	LoadBuildPresets : function () {
		var t = Tabs.Build;
		ById('btBuildPreset').options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Layout')+" --"
		o.value = 0;
		ById("btBuildPreset").options.add(o);
		for (var y in Options.BuildOptions.BuildPresetNames) {
			var o = document.createElement("option");
			o.text = Options.BuildOptions.BuildPresetNames[y];
			o.value = y;
			ById("btBuildPreset").options.add(o);
		}
		t.NextPresetNumber = parseIntNan(y) + 1;
		if (t.InitPresetNumber != 0) {
			ById('btBuildPreset').value = t.InitPresetNumber;
			t.InitPresetNumber = 0;
		}
		for (var a=1;a<=3;a++) {
			t.LoadAscensionPresets('btAscendPreset_'+a,a);
		}
	},

	PaintBldPreset : function (PN,msg) {
		var t = Tabs.Build;
		t.FieldView = false;
		t.PresetType = Options.BuildOptions.BuildPresetTypes[PN]||parseIntNan(Seed.cityData.city[t.ModelCityId].prestigeInfo.prestigeType);
		t.PresetName = Options.BuildOptions.BuildPresetNames[PN]||"";
		if (PN!=0) { t.Preset = JSON2.parse(JSON2.stringify(Options.BuildOptions.BuildPresets[PN])); }
		else { t.Preset = {pos0:"bdg0",pos1:"bdg19"}; }
		t.PresetNum = PN;

		if (PN==0) { ById('btBldPresetMessages').innerHTML = tx('Layout Name')+':&nbsp;<INPUT class="btInput" id="btBldPresetName" size=20 style="width: 185px" type=text value="City Layout #'+t.NextPresetNumber+'"/>'; }
		else { ById('btBldPresetMessages').innerHTML = msg; }

		var m = '<table width=100% cellpadding=0 cellspacing=0 class=xtab><tr style="vertical-align:top;"><td id=btBldPresetData><div id=btBldPresetSlots>&nbsp</div></td>';
		m += '<td width=400px align=right><div id=btBldPresetImage>&nbsp;</div>';
		m += '<div align=center><br>'+tx('Layout Type')+':&nbsp;'+htmlSelector(t.PresetTypes,t.PresetType,'id=btBldPresetType')+'</div>';
		m += '<div align=center><input id=btBldPresetCity type=radio name=btcityfield '+(!t.FieldView?'CHECKED':'')+'>'+tx('City View')+'&nbsp;&nbsp;<input id=btBldPresetField type=radio name=btcityfield '+(t.FieldView?'CHECKED':'')+'>'+tx('Field View')+'</div>';
		m += '<br><div align=center>'+strButton8(tx('Copy Current'),'id=btBldPresetCopy')+'&nbsp;'+strButton8(tx('Delete Layout'),'id=btBldPresetDelete')+'&nbsp;'+strButton8(tx('Save Changes'),'id=btBldPresetSave')+'&nbsp;'+strButton8(uW.g_js_strings.commonstr.cancel,'id=btBldPresetCancel')+'</div></td></tr></table>';

		ById('btBldPresetDetails').innerHTML = m;
		t.setLayoutImage();
		t.displaySlots();

		if (PN==0) { jQuery('#btBldPresetDelete').addClass("disabled"); }
		else {
			jQuery('#btBldPresetCancel').addClass("disabled");
			jQuery('#btBldPresetSave').addClass("disabled");
		}

		ById('btBldPresetCity').addEventListener('change', function () {
			t.FieldView = !ById('btBldPresetCity').checked;
			t.setLayoutImage();
			t.displaySlots();
		}, false);
		ById('btBldPresetField').addEventListener('change', function () {
			t.FieldView = ById('btBldPresetField').checked;
			t.setLayoutImage();
			t.displaySlots();
		}, false);
		ById('btBldPresetType').addEventListener('change',function (e) {
			t.PresetType = e.target.value;
			jQuery('#btBldPresetSave').removeClass("disabled");
			t.ValidateLayout();
			t.setLayoutImage();
			t.displaySlots();
		} ,false);
		if (ById('btBldPresetName')) {
			ById('btBldPresetName').addEventListener('change',function (e) {
				jQuery('#btBldPresetSave').removeClass("disabled");
				jQuery('#btBldPresetCancel').removeClass("disabled");
			} ,false);
		}

		ById('btBldPresetCopy').addEventListener('click', t.CopyBldPreset,false);
		ById('btBldPresetSave').addEventListener('click', t.SaveBldPreset,false);
		ById('btBldPresetDelete').addEventListener('click', t.DeleteBldPreset,false);
		ById('btBldPresetCancel').addEventListener('click', t.CancelBldPreset,false);

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	setLayoutImage : function () {
		var t = Tabs.Build;
		var ImageFile = CITY_VIEW;
		if (!t.FieldView) {
			if (t.PresetType==1) { ImageFile = DRUID_CITY_VIEW; }
			if (t.PresetType==2) { ImageFile = FEY_CITY_VIEW; }
			if (t.PresetType==3) { ImageFile = BRITON_CITY_VIEW; }
		}
		else {
			ImageFile = FIELD_VIEW;
			if (t.PresetType==1) { ImageFile = DRUID_FIELD_VIEW; }
			if (t.PresetType==2) { ImageFile = FEY_FIELD_VIEW; }
			if (t.PresetType==3) { ImageFile = BRITON_FIELD_VIEW; }
		}
		ById('btBldPresetImage').innerHTML = '<img width=400px src="'+ImageFile+'">';
	},

	displaySlots : function() {
		var t = Tabs.Build;
		var min = 0;
		var max = 32;
		var rowcount = 11;
		if (GlobalOptions.btWinSize.x == 750) {rowcount = 17;}
		if (GlobalOptions.btWinSize.x == 1250) {rowcount = 9;}
		var m = '<table width=100% cellpadding=0 cellspacing=0><tr style="vertical-align:top;"><td style="padding-right:0px;">';
		var Blds = t.CityBuildings;
		if (!t.FieldView) {
			if (t.PresetType==1) { Blds = t.DruidCityBuildings; }
			if (t.PresetType==2) { Blds = t.FeyCityBuildings; }
			if (t.PresetType==3) { Blds = t.BritonCityBuildings; }
		}
		else {
			Blds = t.FieldBuildings;
			if (t.PresetType==1) { Blds = t.DruidFieldBuildings; }
			if (t.PresetType==2) { Blds = t.FeyFieldBuildings; }
			if (t.PresetType==3) { Blds = t.BritonFieldBuildings; }
			rowcount = 14;
			if (GlobalOptions.btWinSize.x == 750) {rowcount = 21;}
			if (GlobalOptions.btWinSize.x == 1250) {rowcount = 11;}
			if (t.PresetType==0) { min = 100; max = 145; }
			else { min = 101; max = 103; }
		}
		var BldSelect = {0:"-- Select Building --"};
		for (var k in Blds) {
			if (uW.buildingcost["bdg"+Blds[k]]) {
				BldSelect["bdg"+Blds[k]] = uW.buildingcost["bdg"+Blds[k]][0];
			}
		}
		var c = 0;
		m += '<table class=xtab>';
		for (var p = min; p<=max; p++) {
			if (t.FieldView && p > 139 && p != 142 && p != 145) { continue; }
			if (p==0) { m += '<tr><td align=right>'+p+':&nbsp;</td><td align=left style="padding-right:0px;">&nbsp;'+uW.buildingcost["bdg0"][0]+'</td></tr>'; }
			else {
				if (p==1) { m += '<tr><td align=right>'+p+':&nbsp;</td><td align=left style="padding-right:0px;">&nbsp;'+uW.buildingcost["bdg19"][0]+'</td></tr>'; }
				else {
					m += '<tr><td align=right>'+p+':&nbsp;</td><td align=left style="padding-right:0px;">'+htmlSelector(BldSelect,t.Preset["pos"+p]||0,'class="btInput btBldPresetSelector" id="btBldPresetpos'+p+'"')+'</td></tr>';
				}
			}
			c++;
			if (c%rowcount==0) { m += '</table></td><td><table class=xtab>'; }
		}
		m += '</table></td></tr></table>';
		ById('btBldPresetSlots').innerHTML = m;

		var nodes = document.getElementsByClassName('btBldPresetSelector');
		if(nodes.length > 0){
			for(var i=0; i<nodes.length; i++){
				nodes[i].addEventListener('change', function (e) {
					t.Preset[e.target.id.substring(11)] = e.target.value;
					if (t.Preset[e.target.id.substring(11)]==0) { delete t.Preset[e.target.id.substring(11)]; }
					jQuery('#btBldPresetSave').removeClass("disabled");
					jQuery('#btBldPresetCancel').removeClass("disabled");
				},false);
			}
		}

		ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
	},

	ValidateLayout : function () {
		var t = Tabs.Build;
		var Blds = t.CityBuildings;
		var Flds = t.FieldBuildings;
		var min = 100;
		var max = 145;
		if (t.PresetType==1) { Blds = t.DruidCityBuildings; Flds = t.DruidFieldBuildings; min=101; max=103; }
		if (t.PresetType==2) { Blds = t.FeyCityBuildings; Flds = t.FeyFieldBuildings; min=101; max=103; }
		if (t.PresetType==3) { Blds = t.BritonCityBuildings; Flds = t.BritonFieldBuildings; min=101; max=103; }
		for (var b in t.Preset) {
			var building = t.Preset[b];
			if (building) {
				var bid = parseInt(building.split("bdg")[1]);
				var pos = parseInt(b.split("pos")[1]);
				if (pos !=0 && pos != 1) {
					if (pos < 100) {
						if (Blds.indexOf(bid) == -1) { delete t.Preset[b]; }
					}
					else {
						if (Flds.indexOf(bid) == -1 || pos<min || pos>max) { delete t.Preset[b]; }
					}
				}
			}
		}
	},

	NewBldPreset : function () {
		var t = Tabs.Build;
		ById('btBuildPreset').value = 0;
		jQuery('#btNewBldPreset').addClass("disabled");
		t.PaintBldPreset(0,'');
	},

	DeleteBldPreset : function () {
		var t = Tabs.Build;
		if (!t.PresetNum) return;
		delete Options.BuildOptions.BuildPresetTypes[t.PresetNum];
		delete Options.BuildOptions.BuildPresetNames[t.PresetNum];
		delete Options.BuildOptions.BuildPresets[t.PresetNum];
		saveOptions();
		t.LoadBuildPresets();
		jQuery('#btNewBldPreset').removeClass("disabled");
		t.clearBuildPresetDiv();
		ById('btBldPresetMessages').innerHTML = tx('Layout Deleted')+'!';
	},

	CancelBldPreset : function () {
		var t = Tabs.Build;
		jQuery('#btNewBldPreset').removeClass("disabled");
		ById('btBldPresetMessages').innerHTML = '&nbsp;';
		if (!t.PresetNum) { t.clearBuildPresetDiv(); }
		else { t.PaintBldPreset(t.PresetNum,''); }
	},

	SaveBldPreset : function () {
		var t = Tabs.Build;

		// validate buildings?

		if (t.PresetNum==0) {
			t.PresetNum = t.NextPresetNumber;
			Options.BuildOptions.BuildPresetNames[t.PresetNum] = ById('btBldPresetName').value;
		}
		Options.BuildOptions.BuildPresetTypes[t.PresetNum] = ById('btBldPresetType').value;
		Options.BuildOptions.BuildPresets[t.PresetNum] = JSON2.parse(JSON2.stringify(t.Preset));
		saveOptions();
		jQuery('#btNewBldPreset').removeClass("disabled");
		t.InitPresetNumber = t.PresetNum;
		t.LoadBuildPresets();
		t.PaintBldPreset(t.PresetNum,tx('Layout Saved')+'!');
	},

	SelectBldPreset : function (sel) {
		var t = Tabs.Build;
		if (sel.value==0) { t.clearBuildPresetDiv(); }
		else { t.PaintBldPreset(sel.value,''); }
	},

	CopyBldPreset : function () {
		var t = Tabs.Build;
		t.Preset = {pos0:"bdg0",pos1:"bdg19"};
		t.PresetType = parseIntNan(Seed.cityData.city[t.ModelCityId].prestigeInfo.prestigeType);
		ById('btBldPresetType').value = t.PresetType;
		for (var b in Seed.buildings['city'+t.ModelCityId]) {
			var building = Seed.buildings['city'+t.ModelCityId][b];
			if (building) {
				if (parseInt(building[2]) < 300 || parseInt(building[2]) > 309) { // no dummy ascension buildings
					if (building && building[1] != 0) {
						if (building[0]<30 && building[0]>1) {
							t.Preset[b] = "bdg"+building[0];
						}
					}
				}
			}
		}
		jQuery('#btBldPresetSave').removeClass("disabled");
		jQuery('#btBldPresetCancel').removeClass("disabled");
		t.setLayoutImage();
		t.displaySlots();
	},

	SetBldPreset : function () {
		var t = Tabs.Build;
		var cityId = t.ModelCityId;
		var ToLevel = parseIntNan(ById('btBldPresetAllTo').value.substr(5));
		var PN = parseIntNan(ById('btBuildPreset').value);
		if (PN==0) return;
		ById('btBldPresetMessages').innerHTML = '&nbsp;';

		// validate correct type

		if (t.PresetType != parseIntNan(Seed.cityData.city[cityId].prestigeInfo.prestigeType)) {
			ById('btBldPresetMessages').innerHTML = 'Incorrect city type';
			return;
		}

		for (var b in t.Preset) {
			var building = t.Preset[b];
			if (building && building != 0) {
				var bid = parseInt(building.split("bdg")[1]);
				var pos = parseInt(b.split("pos")[1]);
				var CurrLevel=0;
				if (Seed.buildings['city'+cityId][b]) { CurrLevel = Seed.buildings['city'+cityId][b][1]; }
				if (CurrLevel==0 || Seed.buildings['city'+cityId][b][0]==bid) {
					t.addToBuildQueue(cityId,b,bid,ToLevel,CurrLevel);
				}
			}
		}
		t.SaveBuildQueue();
		t.PaintOverview();
		t.PaintCityInfo();
		ById('btBldQueueLink').click();
	},

	Ascend : function (cityId,faction,blessingId,notify) {
		var t = Tabs.Build;
		var ascended = getAscensionValues(cityId);
		var cityPrestigeType = ascended.prestigeType;
		var cityPrestigeLevel = ascended.prestigeLevel;
		var blessings = Seed.cityData.city[cityId].prestigeInfo.blessings;
		if (!blessings) { blessings = []; }

		var action = 1;

		if (ascended.isPrestigeCity) {
			action = 2;
			faction = cityPrestigeType;
		}

		var paymentType = 'gems';
		var crystalId = null;
		var cost = 0;
		var CanUseCrystal = false;
		var Lessers = Seed.items.i33000||0;
		var Greaters = Seed.items.i33001||0;
		if (cityPrestigeLevel<3) { // lessers ascend 1-3
			CanUseCrystal = (Options.BuildOptions.UseLesserCrystals && Lessers);
			if (CanUseCrystal) {
				paymentType = 'crystals';
				crystalId = '33000';
				cost = 1;
			}
		}
		else {
			if (cityPrestigeLevel<6 ) { // greaters ascend 4-6
				CanUseCrystal = (Options.BuildOptions.UseGreaterCrystals && Greaters);
				if (CanUseCrystal) {
					paymentType = 'crystals';
					crystalId = '33001';
					cost = 1;
				}
			}
		}
		var cityValue = parseIntNan(Seed.cityData.city[cityId].cityValue);
		var cityPercent = parseIntNan(cityValue*100/Tabs.Build.getAscensionRequirements('max',faction,(cityPrestigeLevel+1)));
		if (cityPercent < 100 && !CanUseCrystal) {
			actionLog(Cities.byID[cityId].name+': Not ready for ascension ('+cityPercent+'%)','ASCEND');
			return;
		}

		if (ascended.isPrestigeCity && cityPrestigeLevel != 3 && cityPrestigeLevel != 6 && cityPrestigeLevel != 9) { // minor
			var allowed = CM.BlessingSystemModel.getBlessingGroup().minor.blessing[faction];
			if (allowed.indexOf(blessingId) == -1) { // this blessing not allowed, choose the first allowed one...
				blessingId = allowed[0];
			}
			if (blessings.indexOf(blessingId) != -1) { // this blessing already used, find the first blessing in the allowed list that isn't used!
				for (var b in allowed) {
					blessingId = allowed[b];
					if (blessings.indexOf(blessingId) == -1) { break; }
				}
			}
			blessings.push(blessingId);
		}
		else { // major
			blessingId = CM.BlessingSystemModel.getBlessingGroup().major[cityPrestigeLevel+1][faction-1]; // force the applicable major blessing - 0 index array!!
			blessings.push(blessingId);
		}

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.action = action;
		params.cid = cityId;
		params.prestigeLevel = cityPrestigeLevel+1;
		params.prestigeType = faction;
		params.blessings = blessings.toString();
		params.paymentType = paymentType;
		if (paymentType=="crystals") {
			params.crystalId = crystalId;
		}
		params.cost = cost;
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/createPrestigeCity.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
//					var citynum = Cities.byID[cityId].idx+1;
//					uW.btShowCity(citynum); // have to show the city to get it to update properly, it seems...
					CM.BlessingSystemModel.updateTempFaction(cityId, faction);
					CM.BlessingSystemModel.levelUp(cityId, rslt.updateSeed);
//					uW.btShowCity(citynum); // refresh display
					actionLog(Cities.byID[cityId].name+': Successfully Ascended','ASCEND');
					if (notify) { notify(cityId,faction); } // action on successful ascend...
					// need to reload to get everything in order (the above stuff doesn't work)
					ReloadKOC();
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Failed to ascend ('+rslt.msg+')','ASCEND');
					}
					else {
						if (rslt.feedback) {
							actionLog(Cities.byID[cityId].name+': Failed to ascend ('+rslt.feedback+')','ASCEND');
						}
						else {
							actionLog(Cities.byID[cityId].name+': Failed to ascend ('+rslt.error_code+')','ASCEND');
						}
					}
					t.killCityActivity(cityId); // try and stop things that may be going on..
				}
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Failed to ascend (Ajax Error)','ASCEND');
			},
		},true); // noretry
	},

	checkAutoAscend : function () {
		var t = Tabs.Build;

		// loop through cities checking if any cities ready to ascend

		for (var i = 1; i <= Cities.numCities; i++) {
			var cityId = Cities.cities[i-1].id;
			if (Options.BuildOptions.AscendEnabled[i] && Options.BuildOptions.AscendRunning) {
				var ascended = getAscensionValues(cityId);
				var cityPrestigeType = ascended.prestigeType;
				var cityPrestigeLevel = ascended.prestigeLevel;
				var faction = parseIntNan(Options.BuildOptions.AscendFaction)||1;
				if (ascended.isPrestigeCity) { faction = cityPrestigeType; }
				var blessings = ascended.blessings;
				if (!blessings) { blessings = []; }
				var MaxLevel = CM.PrestigeModel.getLevelCapSoft(faction);
				if (ascended.isPrestigeCity) { faction = cityPrestigeType; }
				var cityValue = parseIntNan(Seed.cityData.city[cityId].cityValue);
				var cityPercent = parseIntNan(cityValue*100/Tabs.Build.getAscensionRequirements('max',faction,(cityPrestigeLevel+1)));
				var cityExpTime = Seed.cityData.city[cityId].prestigeInfo.prestigeBuffExpire;
				if (isNaN(cityExpTime)) { cityExpTime = 0; }
				else { cityExpTime = cityExpTime-unixTime(); }

				ascendok = false;
				canAscend = (cityPercent >= 100);
				if (!canAscend) {
					var Lessers = Seed.items.i33000||0;
					var Greaters = Seed.items.i33001||0;
					if (cityPrestigeLevel<3) {
						canAscend = (Options.BuildOptions.UseLesserCrystals && Lessers);
					}
					else {
						if (cityPrestigeLevel<6) {
							canAscend = (Options.BuildOptions.UseGreaterCrystals && Greaters);
						}
					}

				}
				if (!ascended.isPrestigeCity && canAscend) { ascendok = true; }
				if (ascended.isPrestigeCity && (cityPrestigeLevel < MaxLevel) && canAscend && (cityExpTime <= (Options.BuildOptions.AscendTime*60))) { ascendok = true; }

				if (ascendok) {
					// get next available minor blessing from preferred list -
					var blessingId = 0;
					for (var b in Options.BuildOptions.AscendBlessings[faction]) {
						blessingId = parseIntNan(Options.BuildOptions.AscendBlessings[faction][b]);
						if (blessingId!=0) {
							if (blessings.indexOf(blessingId) == -1) { break; }
						}
					}

					// do ascend!

					Options.BuildOptions.AscensionReady[i] = true; // suspend auto functions!
					saveOptions();

					citydormant = true; // TODO - check this!

					if (!citydormant) { // try and stop all the stuff going on before the next pass....
						t.killCityActivity(cityId);
					}

					if (citydormant) {
						t.Ascend(cityId,faction,blessingId,t.AscensionCallBack);
					}
				}
				else {
					if (Options.BuildOptions.AscensionReady[i]) {
						Options.BuildOptions.AscensionReady[i] = false;
						saveOptions();
					}
				}
			}
			else {
				if (Options.BuildOptions.AscensionReady[i]) {
					Options.BuildOptions.AscensionReady[i] = false;
					saveOptions();
				}
			}
		}
	},

	killCityActivity : function (cityId) {
		var t = Tabs.Build;

		// kill training queue
		Tabs.Train.cancelAll(cityId);

		// kill fortification queue
		Tabs.Fort.cancelAll(cityId);

		// kill currently reviving
		var q1 = Seed.queue_revive["city"+cityId];
		if (q1 != null && q1.length > 0) {
			Tabs.Revive.cancelRevive(cityId,1);
		}
		var q2 = Seed.queue_revive2["city"+cityId];
		if (q2 != null && q2.length > 0) {
			Tabs.Revive.cancelRevive(cityId,2);
		}

		// kill raids and attempt to bring all other marches home
		var now = unixTime();
		Options.RaidLastReset = now;
		saveOptions();
		ToggleCityRaids (cityId,'stopAll');
		var city_atkp = Seed.queue_atkp['city'+cityId]
		var count=0;
		for (var e in city_atkp){
			destinationUnixTime = city_atkp[e]['destinationUnixTime'];
			MarchId = city_atkp[e]['marchId'];
			MarchStatus = city_atkp[e]['marchStatus'];
			MarchType = city_atkp[e]['marchType'];
			botMarchStatus = city_atkp[e]['botMarchStatus'];
			if (MarchType == 9 && botMarchStatus == 3 && MarchStatus == 10) {
				count++;
				setTimeout(RaidManager.DoAllDelete, (count*1250), MarchId,Cities.byID[cityId].idx,count);
			}
			if (MarchType != 9 && MarchId && (MarchStatus==1 || MarchStatus==2)) {
				Dashboard.Recall(MarchId,false);
			}
		}

		// kill currently building
		var qcon = Seed.queue_con["city" + cityId];
		if (qcon.length > 0) {
			var bldSlotId = qcon[0][7];
			var currLevel = parseIntNan(qcon[0][1])-1;
			t.removeConstruction(cityId, bldSlotId, currLevel);
		}

		// cancel market trades - TODO

	},

	cancelConstruction : function (cityId,q) {
		var t = Tabs.Build;
		var qcon = Seed.queue_con["city" + cityId];
		if (qcon.length > 0) {
			var bldSlotId = qcon[q][7];
			var currLevel = parseIntNan(qcon[q][1])-1;
			t.removeConstruction(cityId, bldSlotId, currLevel);
		}
	},

	removeConstruction : function (cityId, bldSlotId, currLevel) {
		var t = Tabs.Build;
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.requestType = "CANCEL_CONSTRUCTION";
		params.cityId = cityId;
		params.buildingPosition = bldSlotId;
		params.buildingId = Seed.buildings["city" + cityId]["pos" + bldSlotId][3];
		new MyAjaxRequest(uW.g_ajaxpath + "ajax/cancelConstruction.php" + uW.g_ajaxsuffix, {
			method : "post",
			parameters : params,
			onSuccess : function (rslt) {
				if (rslt.ok) {
					var tgtlv = parseInt(Seed.queue_con["city" + cityId][0][1]);
					var city_queue = Seed.queue_con["city" + cityId];
					for (var x in city_queue) {
						if (parseInt(city_queue[x][2]) == parseInt(params.buildingId)) {
							city_queue.splice(x, 1)
						}
					}
					if (currLevel == 0) {
						delete Seed.buildings["city" + cityId]["pos" + bldSlotId];
						for (var b = 0; b < Seed.queue_con["city" + cityId].length; b++) {
							if (parseInt(Seed.queue_con["city" + cityId][b][7]) == parseInt(bldSlotId)) {
								Seed.queue_con["city" + cityId].splice(b, 1);
								break;
							}
						}
					}

					bldLvl = Seed.buildings["city" + cityId]["pos" + bldSlotId][1];
					bdgType = Seed.buildings["city" + cityId]["pos" + bldSlotId][0];
					if (bldLvl > 0 && tgtlv != 0) {
						if (parseInt(bdgType) == 30) {
							var costs = CM.TowerModel.getCosts().slice(0);
							Seed.resources["city" + cityId].rec1[0] += parseInt(costs[1] / 2) * 3600;
							Seed.resources["city" + cityId].rec2[0] += parseInt(costs[2] / 2) * 3600;
							Seed.resources["city" + cityId].rec3[0] += parseInt(costs[3] / 2) * 3600;
							Seed.resources["city" + cityId].rec4[0] += parseInt(costs[4] / 2) * 3600;
						} else {
							if (parseInt(bdgType) == 31) {
								var costs = CM.RedoubtModel.getCosts().slice(0);
								Seed.resources["city" + cityId].rec1[0] += parseInt(costs[1] / 2) * 3600;
								Seed.resources["city" + cityId].rec2[0] += parseInt(costs[2] / 2) * 3600;
								Seed.resources["city" + cityId].rec3[0] += parseInt(costs[3] / 2) * 3600;
								Seed.resources["city" + cityId].rec4[0] += parseInt(costs[4] / 2) * 3600;
							} else {
								mult = Math.pow(2, (bldLvl - 1));
								Seed.resources["city" + cityId].rec1[0] += parseInt(uW.buildingcost["bdg" + bdgType][1]) * mult * 3600;
								Seed.resources["city" + cityId].rec2[0] += parseInt(uW.buildingcost["bdg" + bdgType][2]) * mult * 3600;
								Seed.resources["city" + cityId].rec3[0] += parseInt(uW.buildingcost["bdg" + bdgType][3]) * mult * 3600;
								Seed.resources["city" + cityId].rec4[0] += parseInt(uW.buildingcost["bdg" + bdgType][4]) * mult * 3600;
								Seed.citystats["city" + cityId].gold[0] += parseInt(uW.buildingcost["bdg" + bdgType][5]) * mult;
							}
						}
						if (uW.currentcityid == cityId) uW.update_gold();
					}
					if (uW.currentcityid == cityId) uW.update_bdg()
				}
			},
		},true)
	},

	AscensionCallBack : function(cityId,faction) {
		var t = Tabs.Build;

		var citynum = Cities.byID[cityId].idx+1;
		Options.BuildOptions.AscensionReady[citynum] = false; // allow stuff to happen again!
		saveOptions();

		var ToLevel = parseIntNan(Options.BuildOptions.AscendPresetLevel);
		var PN = parseIntNan(Options.BuildOptions.AscendPresets[faction]);
		if (PN==0) return;
		if (!Options.BuildOptions.BuildPresets[PN]) return;

		var Preset = JSON2.parse(JSON2.stringify(Options.BuildOptions.BuildPresets[PN]));

		// clear existing building queue before applying new preset..
		delete t.BuildQueue[t.QueueKey(cityId)];
		for (var b in Preset) {
			var building = Preset[b];
			if (building && building != 0) {
				var bid = parseInt(building.split("bdg")[1]);
				var CurrLevel=0;
				t.addToBuildQueue(cityId,b,bid,ToLevel,CurrLevel);
			}
		}

		t.SaveBuildQueue();
		t.PaintOverview();
		t.PaintCityInfo();
	},

	PaintAscendOptions : function () {
		var t = Tabs.Build;

		var Lessers = Seed.items.i33000||0;
		var Greaters = Seed.items.i33001||0;

		var m = '<table width=100% class=xtab><tr><td colspan=2>&nbsp;'+tx("Automatically ascend when city value is 100% and remaining protection is less than")+'&nbsp;<INPUT id=pbascendinterval type=text size=2 value="' + Options.BuildOptions.AscendTime+'"\> '+tx("minutes")+'&nbsp;<INPUT id=pbResetAscend type=button class=btInput value="'+tx("Clear City States")+'"></td></tr>';
		m += '<tr><td width=100>&nbsp;'+tx("Automatically use Ascension Crystals when city value is not 100%")+'</td><td><input type=checkbox id=pbascendlesser '+(Options.BuildOptions.UseLesserCrystals?'CHECKED':'')+'>&nbsp;'+uW.itemlist['i33000'].name+' ('+Lessers+')</td></tr>';
		m += '<tr><td>&nbsp;</td><td><input type=checkbox id=pbascendgreater '+(Options.BuildOptions.UseGreaterCrystals?'CHECKED':'')+'>&nbsp;'+uW.itemlist['i33001'].name+' ('+Greaters+')</td></tr>';
		m += '<tr><td colspan=2>&nbsp;'+tx("Default faction for unascended cities")+':&nbsp;'+htmlSelector({1: uW.g_js_strings.commonstr.druid, 2: uW.g_js_strings.commonstr.fey, 3: uW.g_js_strings.commonstr.briton}, Options.BuildOptions.AscendFaction, 'id=btBldAscendFaction')+'</td></tr>';
		m += '<tr><td colspan=2>&nbsp;'+tx('Re-queue buildings to level')+'&nbsp;<select id=btBldAscendAllTo></select>&nbsp;'+tx('using preferred building layout selected below')+':-</td></tr>';
		m += '<tr><td colspan=2 align=center><table cellpadding=5 cellspacing=0><tr><th colspan=3 align=center><b>'+tx('Preferred Building Layouts')+'</b></th></tr><tr>';
		for (var a=1;a<=3;a++) {
			m += '<th class=xtabHD width=33% align=center><b>'+getFactionName(a)+'</b></th>'
		}
		m += '</tr><tr>';
		for (var a=1;a<=3;a++) {
			m += '<td align=center><SELECT class="'+a+'" style="width:190px;" id="btAscendPreset_'+a+'"></td>';
		}
		m += '</tr><tr><td colspan=3>&nbsp;</td></tr><tr><th colspan=3 align=center><b>'+tx('Preferred Minor Blessings')+'</b></th></tr><tr>';
		for (var a=1;a<=3;a++) {
			m += '<th class=xtabHD width=33% align=center><b>'+getFactionName(a)+'</b></th>'
		}
		m += '</tr><tr>';
		for (var a=1;a<=3;a++) {
			var blessings = CM.BlessingSystemModel.getBlessingGroup().minor.blessing[a];
			var blesslist = {0:"-- "+tx('Select Blessing')+" --"};
			for (var bb=0; bb<blessings.length; bb++) {
				blesslist[blessings[bb]] = uW.g_js_strings.blessingSystem['blessing_name_'+blessings[bb]];
			}
			m += '<td>';
			var MaxLevel = CM.PrestigeModel.getLevelCapSoft(a);
			var Maj = Math.ceil(MaxLevel/3);
			var Min = MaxLevel-Maj;
			for (var b=1;b<=Min;b++) {
				m += htmlSelector(blesslist, Options.BuildOptions.AscendBlessings[a][b], 'id=btAscendBlessing_'+a+'_'+b+' class="'+a+'_'+b+'"')+'<br>';
			}
			m += '</td>';
		}
		m += '</tr></table>';
		m += '</td></tr></table><br>';

		ById('btBldAscend').innerHTML = m;

		ToggleOption('BuildOptions','pbascendlesser','UseLesserCrystals');
		ToggleOption('BuildOptions','pbascendgreater','UseGreaterCrystals');

		ById('pbResetAscend').addEventListener ('click', t.resetCityStates, false);

		ById('pbascendinterval').addEventListener('change', function (e) {
			Options.BuildOptions.AscendTime = parseIntNan(this.value);
			if (Options.BuildOptions.AscendTime==0) {
				Options.BuildOptions.AscendTime = 1;
				this.value = Options.BuildOptions.AscendTime;
			}
 			saveOptions();
		}, false);

		ById('btBldAscendFaction').addEventListener('change', function (e) {
			Options.BuildOptions.AscendFaction = parseIntNan(this.value);
 			saveOptions();
		}, false);

		ById('btBldAscendAllTo').addEventListener('change', function (e) {
			Options.BuildOptions.AscendPresetLevel = parseIntNan(this.value.substr(5));
 			saveOptions();
		}, false);

		for (var a=1;a<=3;a++) {
			ById('btAscendPreset_'+a).addEventListener('change', function (e) {
				Options.BuildOptions.AscendPresets[e.target['className']] = this.value;
				saveOptions();
			}, false);

			var MaxLevel = CM.PrestigeModel.getLevelCapSoft(a);
			var Maj = Math.ceil(MaxLevel/3);
			var Min = MaxLevel-Maj;
			for (var b=1;b<=Min;b++) {
				ById('btAscendBlessing_'+a+'_'+b).addEventListener('change', function (e) {
					var elems = e.target['className'].split('_');
					Options.BuildOptions.AscendBlessings[elems[0]][elems[1]] = this.value;
					saveOptions();
				}, false);
			}
		}
	},

	resetCityStates : function () {
		var t = Tabs.Build;
		for (var i = 1; i <= Cities.numCities; i++) {
			Options.BuildOptions.AscensionReady[i] = false;
		}
		saveOptions();
	},

	LoadAscensionPresets : function (sel,faction) {
		var t = Tabs.Build;
		ById(sel).options.length = 0;
		var o = document.createElement("option");
		o.text = "-- "+tx('Select Layout')+" --"
		o.value = 0;
		ById(sel).options.add(o);
		for (var y in Options.BuildOptions.BuildPresetNames) {
			if (Options.BuildOptions.BuildPresetTypes[y]==faction) {
				var o = document.createElement("option");
				o.text = Options.BuildOptions.BuildPresetNames[y];
				o.value = y;
				ById(sel).options.add(o);
			}
		}
		if (Options.BuildOptions.AscendPresets[faction] != 0) {
			ById(sel).value = Options.BuildOptions.AscendPresets[faction];
		}
	},

}

/**************************** Revive Tab ****************************************/
Tabs.Revive = {
	tabLabel: 'Revive',
	tabOrder: 2070,
	tabColor : 'brown',
	myDiv: null,
	timer: null,
	LoopCounter: 0,
	intervalSecs  : 5,
	autodelay : 0,
	citydelay: {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0},
	loopaction : false,
	revivespeed : 0,
	revivecost : 0,
	totgold : 0,
	ModelCity: null,
	ModelCityId: 0,
	unitsarr : [],
	troopTotal: {},
	LastWounded : 'x',
	noApothecary : [],
	Squire:0,
	Knight:0,
	Guinevere:0,
	Morgana:0,
	Arthur:0,
	Merlin:0,
	Divine:0,
	Epic:0,
	Legendary:0,
	Spectral:0,
	Demonic:0,
	ItemList : [1, 2, 3, 4, 5, 6, 7, 8, 10],
	ItemTrans : ["SH","KH","GH","MH","AH","RH","DH","EH","LH"],
	ExtraItemList : [80, 81],
	ExtraItemTrans : ["PH","NH"],
	ExtraHourGlassThreshold : [2160000,4320000],
	CannotReviveUnit : [27],
	Options: {
		Running: false,
		ThroneCheck: false,
		ReviveSpeed: 0,
		MinGold : 5000,
		Enabled : {1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true},
		HealArray : {1:[],2:[],3:[],4:[],5:[],6:[],7:[],8:[]},
		BatchMin : 0,
		SelectBatchMax : true,
		BatchMax : 10000,
		UseLH : false,
		UseEH : false,
		UseDH : false,
		UseRH : false,
		UseAH : false,
		UseMH : false,
		UseGH : false,
		UseKH : false,
		UseSH : false,
		UseOverride : false,
		OverrideItem : 0,
		OverrideHours : 0,
		OverrideMinutes : 1,
		Toggle : false,
	},

	init: function (div) {
		var t = Tabs.Revive;
        t.myDiv = div;

		for (var ui in CM.UNIT_TYPES){
			i = CM.UNIT_TYPES[ui];
			if (t.CannotReviveUnit.indexOf(parseInt(i)) == -1) {
				t.unitsarr.push(i);
			}
		}

		if (!Options.ReviveOptions) {
			Options.ReviveOptions = t.Options;
		}
		else {
			for (var y in t.Options) {
				if (!Options.ReviveOptions.hasOwnProperty(y)) {
					Options.ReviveOptions[y] = t.Options[y];
				}
			}
		}

		uWExportFunction('speedupRevive', Tabs.Revive.speedupRevive);
		uWExportFunction('cancelRevive', Tabs.Revive.cancelRevive);
		uWExportFunction('btRevQueueDeleteAll', Tabs.Revive.deleteRevQueueAll);
		uWExportFunction('btRevQueueDelete', Tabs.Revive.deleteRevQueue);
		uWExportFunction('btRevQueueUp', Tabs.Revive.RevQueueUp);
		uWExportFunction('btRevQueueDn', Tabs.Revive.RevQueueDn);

		var ReviveHourGlassName = {};
		for (var h=0;h<HourGlasses.length;h++) { ReviveHourGlassName[HourGlasses[h]] = uW.itemlist['i'+HourGlasses[h]].name; }
		for (var h=0;h<t.ExtraItemList.length;h++) { ReviveHourGlassName[t.ExtraItemList[h]] = uW.itemlist['i'+t.ExtraItemList[h]].name; }
		
		for (var cid in Cities.byID){
			var x = Cities.byID[cid].idx+1;
			t.noApothecary[x] = (getCityBuilding(cid, 21).count>0)?false: true;
			if(t.noApothecary[x]) { t.noApothecary[x] = (getCityBuilding(cid, 23).count>0)?false: true; }
		}

		if (Options.ReviveOptions.Toggle) AddSubTabLink('AutoRevive',t.toggleAutoReviveState, 'ReviveToggleTab');
		SetToggleButtonState('Revive',Options.ReviveOptions.Running,'Revive');

		var m = '<DIV class=divHeader align=center>'+tx('AUTOMATED WOUNDED TROOP REVIVE')+'</div>';
		m += '<div align="center">';

        m += '<table width=100% class=xtab><tr><td width=30%><INPUT id=btReviveToggle type=checkbox />&nbsp;'+tx("Add toggle button to main screen header")+'</td><td colspan=2 align=center><INPUT id=btAutoReviveState type=submit value="'+tx("AutoRevive")+' = '+ (Options.ReviveOptions.Running?'ON':'OFF')+'"></td><td width=30% align=right>'+tx('Current Revive Speed')+':&nbsp;<span id=btReviveCurrTR></span>&nbsp;&nbsp;</td></tr></table>';
		m += '<table width=100% class=xtab><tr><td colspan=2 align=left><INPUT id=btReviveTR type=checkbox > '+tx('Only revive when revive speed is at least')+' <INPUT id=btReviveTRSpeed type=text size=3 maxlength=4 >&nbsp;%</td>';
		m += '<td colspan=2 align=right>'+tx('Current Revive Cost')+':&nbsp;<span id=btReviveCostTR></span>&nbsp;&nbsp;</td></td></tr>';
		m += '<tr><td colspan=2 align=left>&nbsp;</td><td colspan=2 align=right>'+tx('Minimum Gold')+':&nbsp;<input type=text  size=9 maxlength=10 id=btReviveMinGold>&nbsp;&nbsp;</td></tr>';
		m += '</table>';

		m += '<br><DIV id=btReviveOverviewDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">';

		m += '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td width=100>&nbsp;</td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btReviveCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
		}
		m += "<td>&nbsp;</td>"; // spacer
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right><b>'+tx('Active')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div class=xtabBorder align=center><INPUT class='+i+' id="btReviveAutoCity_'+i+'" type=checkbox '+(Options.ReviveOptions.Enabled[i]?'CHECKED':'')+'></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+tx('Facilities')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:40px;"><span id="btReviveApothecaryCity_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="oddRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+tx('Queue 1')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:80px;"><span id="btReviveActivityCity1_'+i+'">&nbsp;</span></div></td>';
		}
		m += '</tr><TR align=right class="evenRow"><TD colspan=2 align=right style="padding-top:2px;vertical-align:top;padding-left:0px;"><b>'+tx('Queue 2')+'&nbsp;</b></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder style="height:80px;"><span id="btReviveActivityCity2_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr><TR align=right class="oddRow"><TD style="padding-left: 0px;"><img height=18 src="'+GoldImage+'" title="'+uW.g_js_strings.commonstr.gold+'"></td><td><div id=btTotGold class="totalCell xtabBorder">&nbsp;</div></td>';
		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD><div align=center class=xtabBorder><span id="btReviveGoldCity_'+i+'">&nbsp;</span></div></td>';
		}

		m += '</tr></table></div></div>';

		m += '<div class="divHeader" align="center">'+tx('USE AUTO-SPEEDUPS')+'</div>';

		m += '<table width=100% class=xtab><tr><td><div align=center>';

		var ExtraHourGlassHint = ['Time: 30 Days\nConditions: 25d+', 'Time: 60 Days\nConditions: 50d+'];
		
		var Boosts = '<table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ItemList[i]].name+'\n'+tx(HourGlassHint[i])+'" /></td><td>(<span id=pbreviveUse'+t.ItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '<td width=70 rowspan=2 align=right><INPUT id=pbReviveHelp type=submit value="'+tx('HELP')+'!"></td>';
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbrevive'+t.ItemTrans[i]+'" '+(Options.ReviveOptions["Use"+t.ItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ExtraItemList.length; i++) {
			Boosts += '<td width=30 rowspan=2><img height=28 src="'+IMGURL+'items/70/'+t.ExtraItemList[i]+'.jpg" title="'+uW.itemlist["i"+t.ExtraItemList[i]].name+'\n'+tx(ExtraHourGlassHint[i])+'" /></td><td>(<span id=pbreviveUse'+t.ExtraItemTrans[i]+'Label>' + parseIntNan(uW.ksoItems[t.ExtraItemList[i]].count) + '</span>)</td>';
		}
		Boosts += '</tr><tr style="vertical-align:top;">';
		for (var i = 0; i < t.ExtraItemList.length; i++) {
			Boosts += '<td><input type=checkbox id="pbrevive'+t.ExtraItemTrans[i]+'" '+(Options.ReviveOptions["Use"+t.ExtraItemTrans[i]]?"CHECKED" : "")+'></td>';
		}
		Boosts += '</tr></table></td></tr>';
        Boosts += '<tr><td><div align=center><table width=95% class=xtab align=center cellpadding=0 cellspacing=0><tr><td><input type=checkbox id=pbreviveOV >'+tx('Override above by always using')+' '+htmlSelector(ReviveHourGlassName,Options.ReviveOptions.OverrideItem, 'id=pbreviveOVItem') + ' '+tx('when more than')+' ';
		Boosts += '<INPUT style="width: 30px;text-align:right;" id="pbreviveOVHours" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timehr+'&nbsp;<INPUT style="width: 30px;text-align:right;" id="pbreviveOVMinutes" type=text maxlength=4 >&nbsp;'+uW.g_js_strings.timestr.timemin+' '+tx('remaining')+'.</td></tr></table></div></td></tr>';

		m += Boosts+'</table></div>';

		m += '<a id=btReviveQueueLink class=divLink><div class="divHeader" align="left"><img id=btReviveQueueArrow height="10" src="'+RightArrow+'">&nbsp;'+tx('REVIVE TROOPS')+'</div></a>';
		m += '<div id=btReviveQueue style="height:210px; max-height:210px; overflow-y:auto;" class=divHide>';

		m += '<TABLE align=center cellpadding=0 cellspacing=0 class=xtab width=100% style="padding-right:0px;"><TR><TD valign=top width=49%>';
		m += '<br>';
		m += '<TABLE class=xtab><tr><td align=right>'+uW.g_js_strings.commonstr.city+':&nbsp;</td><td colspan=2><DIV style="text-align:center; margin-bottom:5px;"><span id=pbrevivecity></span></div></td></tr><tr><TD align=right>'+tx(uW.g_js_strings.openCastle.trooptype)+':&nbsp;</td><TD colspan=2>';
		m += '<SELECT id=btRevType><option value=0><CENTER>-- '+uW.g_js_strings.commonstr.select+' --</center></option>';
		for (var ui in uW.cm.UNIT_TYPES) {
			var u = uW.cm.UNIT_TYPES[ui];
			if (t.CannotReviveUnit.indexOf(parseInt(u)) == -1) {
				m += '<option value='+u+'>'+uW.unitcost["unt"+u][0]+'</option>';
			}
		}
		m += '</select>&nbsp;'+strButton8(tx('Add ALL Wounded'),'id=btRevAddAllWounded')+'</td></tr><tr><td align=right>'+tx('Total Wounded')+':&nbsp;</td><td colspan=2><span id=btRevWounded>&nbsp;</span></td></tr>';
		m += '<tr><td align=right><img style="vertical-align:middle;" height=18 src="'+GoldImage+'" title="'+uW.g_js_strings.commonstr.gold+'"><span style="vertical-align:middle;">&nbsp;'+tx('Total Cost')+':&nbsp;</span></td><td colspan=2><span id=btRevCost>&nbsp;</span></td></tr>';
		m += '<TR><td>&nbsp;</td><TD colspan=2><b>'+tx('Batch Size')+':-&nbsp;</b></td></tr><tr><td>&nbsp;</td><td align=left>'+tx('Min')+':&nbsp;<INPUT id=btRevBatchMin type=text size=6 maxlength=6 value="'+ Options.ReviveOptions.BatchMin+'"\></td>';
		m += '<td><INPUT type=checkbox id=btRevSelBatchMax '+(Options.ReviveOptions.SelectBatchMax?'CHECKED':'')+'>&nbsp;'+tx("Max")+':&nbsp;<INPUT id=btRevBatchMax type=text size=6 maxlength=6 value="'+ Options.ReviveOptions.BatchMax+'"\></td></tr>';

		m += '<tr><td>&nbsp;</td><td colspan=2><INPUT id=btRevButton type=button value="'+tx('Add to Queue')+'"\>&nbsp;<INPUT id=btRevNowButton type=button value="'+tx('Revive Now!')+'"\></td></tr></table>';
		m += '</TD><TD valign=top width=49% style="padding-right:0px;"><TABLE class=xtab width=100% style="padding-right:0px;"><tr><td align=center style="padding-right:0px;"><div style="padding-right:0px;color: rgba(0,0,0,0.5);"><b>'+tx('REVIVE QUEUE')+'</b></div></td></tr>';
		m += '<tr><td valign=top align=center id="btReviveCityQueue" style="padding-right:0px;">&nbsp;</td></tr>';
		m += '</table>';

		m += '</td></tr><tr><td colspan=2><div id=btRevMessages align=center>&nbsp;</div></td></tr></table></div>';

		m += '<a id=btReviveWoundedLink class=divLink><div class="divHeader" align="left"><img id=btReviveWoundedArrow height="10" src="'+DownArrow+'">&nbsp;'+tx('WOUNDED TROOPS')+'</div></a>';
		m += '<div id=btReviveWounded style="min-height:100px; max-height:400px; overflow-y:scroll;">';
		m += '<br><DIV id=btReviveWoundedDiv style="width:'+GlobalOptions.btWinSize.x+'px;overflow-x:auto;">&nbsp;</div></div><br>';

		div.innerHTML = m;

		ById('btReviveQueueLink').addEventListener ('click', function () {ToggleMainDivDisplay("Revive",100,GlobalOptions.btWinSize.x,"btReviveQueue",false)}, false);
		ById('btReviveWoundedLink').addEventListener ('click', function () {ToggleMainDivDisplay("Revive",100,GlobalOptions.btWinSize.x,"btReviveWounded",false)}, false);

		t.ModelCity = new CdispCityPicker('pbrevive', ById('pbrevivecity'), true, t.clickCitySelect, null);
		t.PaintWounded();

		for (var i = 1; i <= Cities.numCities; i++) {
			ById('btReviveAutoCity_'+i).addEventListener('click', function(e){
				var citynum = e.target['className'];
				Options.ReviveOptions.Enabled[citynum] = e.target.checked;
				if (Options.ReviveOptions.Enabled[citynum]) {
					t.citydelay[i] = 0;
					t.timer = setTimeout(function () { t.doAutoLoop(Number(citynum));}, 0);
				}
				saveOptions();
			}, false);
		}

		ToggleOption('ReviveOptions','btReviveToggle','Toggle');

		ToggleOption('ReviveOptions','pbreviveSH','UseSH');
		ToggleOption('ReviveOptions','pbreviveKH','UseKH');
		ToggleOption('ReviveOptions','pbreviveGH','UseGH');
		ToggleOption('ReviveOptions','pbreviveMH','UseMH');
		ToggleOption('ReviveOptions','pbreviveAH','UseAH');
		ToggleOption('ReviveOptions','pbreviveRH','UseRH');
		ToggleOption('ReviveOptions','pbreviveDH','UseDH');
		ToggleOption('ReviveOptions','pbreviveEH','UseEH');
		ToggleOption('ReviveOptions','pbreviveLH','UseLH');
		ToggleOption('ReviveOptions','pbreviveOV','UseOverride');
		ChangeIntegerOption('ReviveOptions','pbreviveOVItem','OverrideItem');
		ChangeIntegerOption('ReviveOptions','pbreviveOVHours','OverrideHours');
		ChangeIntegerOption('ReviveOptions','pbreviveOVMinutes','OverrideMinutes');

		ById('pbReviveHelp').addEventListener ('click', t.helpPop, false);

		ById('btAutoReviveState').addEventListener('click', function(){
			t.toggleAutoReviveState(this);
		}, false);

		ToggleOption('ReviveOptions','btReviveTR','ThroneCheck');
		ChangeIntegerOption('ReviveOptions','btReviveTRSpeed','ReviveSpeed');
		ChangeIntegerOption('ReviveOptions','btReviveMinGold','MinGold');

		ById('btRevType').addEventListener('change', t.PaintCityInfo, false);
		ById('btRevAddAllWounded').addEventListener('click', t.AddAllWounded, false);
		ById('btRevBatchMax').disabled=(!Options.ReviveOptions.SelectBatchMax);

		ChangeIntegerOption('ReviveOptions','btRevBatchMin','BatchMin');
		ChangeIntegerOption('ReviveOptions','btRevBatchMax','BatchMax');
		ById('btRevSelBatchMax').addEventListener('change', function(e){
			Options.ReviveOptions.SelectBatchMax = e.target.checked;
			ById('btRevBatchMax').disabled = (!e.target.checked);
			if (!e.target.checked) {
				Options.ReviveOptions.BatchMax = "";
				ById('btRevBatchMax').value = Options.ReviveOptions.BatchMax;
			}
			saveOptions();
		}, false);
		ById("btRevNowButton").addEventListener('click', function(){
			t.Revive_Now(t.ModelCity.city.idx,ById('btRevType').value,parseIntNan(Options.ReviveOptions.BatchMin),parseIntNan(Options.ReviveOptions.BatchMax),Options.ReviveOptions.SelectBatchMax);
		},false);
		ById("btRevButton").addEventListener('click', function(){
			t.Add_Revive(t.ModelCity.city.idx,ById('btRevType').value,parseIntNan(Options.ReviveOptions.BatchMin),parseIntNan(Options.ReviveOptions.BatchMax),Options.ReviveOptions.SelectBatchMax);
		},false);

		// start autorevive loop timer to start in 25 seconds...

		if (Options.ReviveOptions.Running) {
			t.timer = setTimeout(function () { t.doAutoLoop(1,false);}, (25 * 1000));
		}
	},

	toggleAutoReviveState: function(obj){
		var t = Tabs.Revive;
		obj = ById('btAutoReviveState');
		if (Options.ReviveOptions.Running == true) {
			Options.ReviveOptions.Running = false;
			obj.value = tx("AutoHeal = OFF");
		}
		else {
			Options.ReviveOptions.Running = true;
			obj.value = tx("AutoHeal = ON");
			t.citydelay = {1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0};
			t.timer = setTimeout(function () { t.doAutoLoop(1,false);}, 0);
		}
		saveOptions();
		SetToggleButtonState('Revive',Options.ReviveOptions.Running,'Revive');
		t.PaintOverview();
	},

	show: function (init) {
		var t = Tabs.Revive;
		if (t.ModelCityId==0) {
			if (init) {
				t.ModelCity.selectBut(Cities.byID[InitialCityId].idx);
			}
			else {
				t.ModelCity.selectBut(Cities.byID[uW.currentcityid].idx);
			}
		}
		t.PaintOverview();
		t.PaintCityInfo();
	},

	helpPop : function (){
		var t = Tabs.Revive;
		var helpText = '<br>'+tx("Using Speedups for Revive");
		helpText += '<p>'+tx('Speedups will be used in the following order if they are selected, and the required criteria is met')+' :-</p>';
		helpText += '<TABLE class=xtab><TR><TD><b>'+uW.g_js_strings.commonstr.item+'</b></td><TD><b>'+uW.g_js_strings.commonstr.time+'</b></td><TD><b>'+tx('Criteria')+'</b></td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i81.name+'</td><TD>60 days</td><TD>'+tx('More than 50 days remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i80.name+'</td><TD>30 days</td><TD>'+tx('More than 25 days remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i10.name+'</td><TD>4 days</td><TD>'+tx('More than 3 days and 12 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i8.name+'</td><TD>2.5 days</td><TD>'+tx('More than 48 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i7.name+'</td><TD>24 hrs</td><TD>'+tx('More than 23 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i6.name+'</td><TD>15 hrs</td><TD>'+tx('More than 14 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i5.name+'</td><TD>8 hrs</td><TD>'+tx('More than 7 hours 30 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i4.name+'</td><TD>2.5 hrs</td><TD>'+tx('More than 2 hours remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i3.name+'</td><TD>1 hr</td><TD>'+tx('More than 45 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i2.name+'</td><TD>15 mins</td><TD>'+tx('More than 5 minutes remaining')+'</td></tr>';
		helpText += '<TR><TD>'+uW.itemlist.i1.name+'</td><TD>1 min</td><TD>'+tx('More than 30 seconds remaining')+'</td></tr>';
		helpText += '</table>';
		helpText += '<p>'+tx('If the override box is ticked, then the override rule specified will take priority')+'.</p><br>';

		var pop = new CPopup ('BotHelp', 0, 0, 460, 400, true);
		pop.centerMe (mainPop.getMainDiv());
		pop.getMainDiv().innerHTML = helpText;
		pop.getTopDiv().innerHTML = '<CENTER><B>'+tx("PowerBot+ Help")+': '+tx("Speedups")+'</b></center>';
		pop.show (true);
	},

	EverySecond : function () {
		var t = Tabs.Revive;

		t.LoopCounter = t.LoopCounter + 1;

		if (t.LoopCounter%2==0) { // refresh revive speed and overview display every 2 seconds
			t.revivespeed = Math.floor(equippedthronestats(97));
			t.revivecost = Math.floor(equippedthronestats(98));
			if (tabManager.currentTab.name == 'Revive' && Options.btWinIsOpen){ t.PaintOverview(); }
		}

	},

	clickCitySelect: function (city) {
		var t = Tabs.Revive;
		t.ModelCityId = city.id;
		t.PaintCityInfo();
	},

	PaintOverview : function () {
		var t = Tabs.Revive;

		t.Squire = parseIntNan(Seed.items.i1);
		t.Knight = parseIntNan(Seed.items.i2);
		t.Guinevere = parseIntNan(Seed.items.i3);
		t.Morgana = parseIntNan(Seed.items.i4);
		t.Arthur = parseIntNan(Seed.items.i5);
		t.Merlin = parseIntNan(Seed.items.i6);
		t.Divine = parseIntNan(Seed.items.i7);
		t.Epic = parseIntNan(Seed.items.i8);
		t.Legendary = parseIntNan(Seed.items.i10);
		t.Spectral = parseIntNan(Seed.items.i80);
		t.Demonic = parseIntNan(Seed.items.i81);

		ById('pbreviveUseSHLabel').innerHTML = t.Squire;
		ById('pbreviveUseKHLabel').innerHTML = t.Knight;
		ById('pbreviveUseGHLabel').innerHTML = t.Guinevere;
		ById('pbreviveUseMHLabel').innerHTML = t.Morgana;
		ById('pbreviveUseAHLabel').innerHTML = t.Arthur;
		ById('pbreviveUseRHLabel').innerHTML = t.Merlin;
		ById('pbreviveUseDHLabel').innerHTML = t.Divine;
		ById('pbreviveUseEHLabel').innerHTML = t.Epic;
		ById('pbreviveUseLHLabel').innerHTML = t.Legendary;
		ById('pbreviveUsePHLabel').innerHTML = t.Spectral;
		ById('pbreviveUseNHLabel').innerHTML = t.Demonic;

		t.PaintWounded();

		t.totgold=0;
		var now = unixTime();
		var q;

		for (var i = 0; i < Cities.numCities; i++) {
			citynum = i+1;
			cityId = Cities.cities[i].id;
			var citygold = parseIntNan(Seed.citystats["city" + cityId]['gold'][0]);
			t.totgold = t.totgold+citygold;
			var span = '<span>';
			if (citygold < Options.ReviveOptions.MinGold) { span = '<span class=boldRed>'; }
			ById("btReviveGoldCity_"+citynum).innerHTML = span+addCommas(citygold)+'</span>';

			var blvl = [];
			for (bpos in Seed.buildings["city"+cityId]) {
                var btype = parseInt(Seed.buildings["city"+cityId][bpos][0]);
                if (btype == 21 || btype == 23) {
					var bname = uW.buildingcost['bdg' + Seed.buildings["city"+cityId][bpos][0]][0];
                    blvl.push('Lv.' + Seed.buildings["city"+cityId][bpos][1]);
				}
			}
			var str = '';
			if (blvl.join(', ')=='') { str = '<SPAN class=boldRed><B>'+tx('No')+'<br>'+uW.buildingcost.bdg21[0]+'</b></span>'; }
			else { str = bname + '<br />(' + blvl.join(', ') + ')'; }
			if (Seed.cityData.city[cityId].isPrestigeCity) {
				if (Seed.cityData.city[cityId].prestigeInfo.blessings.indexOf(106) != -1) {
					str += '<br>'+uW.g_js_strings.blessingSystem.blessing_name_106;
				}
			}
			ById('btReviveApothecaryCity_'+citynum).innerHTML = str;

			// paint currently reviving
			var q1 = Seed.queue_revive["city"+cityId];
			var u = '';
			if (q1 != null && q1.length > 0) {
				u = q1[0];
				str = '<table cellpadding=0 cellspacing=0 width=100% style="padding-right:0px;"><tr><td class=xtab align=center >'+addCommas(u[1])+'&nbsp;'+uW.unitcost["unt"+u[0]][0]+'<br />';
				if (parseInt(u[3]) > now) {
					str += '('+timestr(parseInt(u[3])-now)+')</td></tr>';
					var Speedups = '';
					Speedups += t.paintSpeedup(cityId,u[0],1,1,t.Squire,'1 min');
					Speedups += t.paintSpeedup(cityId,u[0],1,2,t.Knight,'15 mins');
					Speedups += t.paintSpeedup(cityId,u[0],1,3,t.Guinevere,'60 mins');
					Speedups += t.paintSpeedup(cityId,u[0],1,4,t.Morgana,'150 mins');
					Speedups += t.paintSpeedup(cityId,u[0],1,5,t.Arthur,'8 hours');
					Speedups += '</tr><tr>';
					Speedups += t.paintSpeedup(cityId,u[0],1,6,t.Merlin,'15 hours');
					Speedups += t.paintSpeedup(cityId,u[0],1,7,t.Divine,'24 hours');
					Speedups += t.paintSpeedup(cityId,u[0],1,8,t.Epic,'60 hours');
					Speedups += t.paintSpeedup(cityId,u[0],1,10,t.Legendary,'96 hours');
					Speedups += t.paintSpeedup(cityId,u[0],1,80,t.Spectral,'30 days');
					Speedups += t.paintSpeedup(cityId,u[0],1,81,t.Demonic,'60 days');

					if (Speedups != "") Speedups = '<tr><td style="padding-right:0px;padding-bottom:2px;"><table align=left cellspacing=0 cellpadding=0><tr>' + Speedups + '</tr></table></td></tr>';
					str = str+Speedups+'<tr><td class=xtab><table align=center cellspacing=0 cellpadding=0><tr><td class=xtab style="padding-right:0px;"><a class="inlineButton button14" onClick="cancelRevive('+cityId+',1)"><span>'+tx("Cancel")+'</span></a></td></tr></table>';
				} else {
                    str += '(done)';
					if (cityId != uW.currentcityid) {
						Seed.units["city"+cityId]["unt"+u[0]] = parseInt(Seed.units["city"+cityId]["unt"+u[0]]) + parseInt(u[1]);
						Seed.queue_revive["city"+cityId].splice(0,1);
					}
				}
				str += '</td></tr></table>';
            } else {
				if (t.citydelay[citynum] > 0) { str = '<SPAN class=boldRed><B>'+tx('Busy')+'!</b></span>'; }
				else {
					if (Options.BuildOptions && Options.BuildOptions.AscensionReady[citynum]) { str = '<SPAN>'+tx('Ascension')+'!</span>'; }
					else { str = ''; }
				}
            }
			ById('btReviveActivityCity1_'+citynum).innerHTML = str;

            // revive queue 2
			var q2 = Seed.queue_revive2["city"+cityId];
            var u = '';
            if (q2 != null && q2.length > 0) {
                u = q2[0];
				str = '<table cellpadding=0 cellspacing=0 width=100% style="padding-right:0px;"><tr><td class=xtab align=center >'+addCommas(u[1])+'&nbsp;'+uW.unitcost["unt"+u[0]][0]+'<br />';
                if (parseInt(u[3]) > now) {
					str += '(' + timestr(parseInt(u[3]) - now) + ')</td></tr>';
					var Speedups = '';
					Speedups += t.paintSpeedup(cityId,u[0],2,1,t.Squire,'1 min');
					Speedups += t.paintSpeedup(cityId,u[0],2,2,t.Knight,'15 mins');
					Speedups += t.paintSpeedup(cityId,u[0],2,3,t.Guinevere,'60 mins');
					Speedups += t.paintSpeedup(cityId,u[0],2,4,t.Morgana,'150 mins');
					Speedups += t.paintSpeedup(cityId,u[0],2,5,t.Arthur,'8 hours');
					Speedups += '</tr><tr>';
					Speedups += t.paintSpeedup(cityId,u[0],2,6,t.Merlin,'15 hours');
					Speedups += t.paintSpeedup(cityId,u[0],2,7,t.Divine,'24 hours');
					Speedups += t.paintSpeedup(cityId,u[0],2,8,t.Epic,'60 hours');
					Speedups += t.paintSpeedup(cityId,u[0],2,10,t.Legendary,'96 hours');
					Speedups += t.paintSpeedup(cityId,u[0],2,80,t.Spectral,'30 days');
					Speedups += t.paintSpeedup(cityId,u[0],2,81,t.Demonic,'60 days');

					if (Speedups != "") Speedups = '<tr><td style="padding-right:0px;padding-bottom:2px;"><table align=left cellspacing=0 cellpadding=0><tr>' + Speedups + '</tr></table></td></tr>';
					str = str+Speedups+'<tr><td class=xtab><table align=center cellspacing=0 cellpadding=0><tr><td class=xtab><a class="inlineButton button14" onClick="cancelRevive('+cityId+',2)"><span>'+tx("Cancel")+'</span></a></td></tr></table>';
				} else {
					str += '(done)';
					if (cityId != uW.currentcityid) {
						Seed.units["city"+cityId]["unt"+u[0]] = parseInt(Seed.units["city"+cityId]["unt"+u[0]]) + parseInt(u[1]);
						Seed.queue_revive2["city"+cityId].splice(0,1);
					}
				}
				str += '</td></tr></table>';
			} else {
				if (t.citydelay[citynum] > 0) { str = '<SPAN class=boldRed><B>'+tx('Busy')+'!</b></span>'; }
				else {
					if (Options.BuildOptions && Options.BuildOptions.AscensionReady[citynum]) { str = '<SPAN>'+tx('Ascension')+'!</span>'; }
					else { str = ''; }
				}
			}
			ById('btReviveActivityCity2_'+citynum).innerHTML = str;
		}
		ById('btTotGold').innerHTML = addCommas(t.totgold);

		if (Options.ReviveOptions.ThroneCheck && (t.revivespeed < Number(Options.ReviveOptions.ReviveSpeed))) {
			ts = '<span class=boldRed><b>'+t.revivespeed+'%</b></span>';
		}
		else { ts = t.revivespeed+'%'; }
		ById("btReviveCurrTR").innerHTML = ts;
		ById("btReviveCostTR").innerHTML = t.revivecost+'%';
	},

	paintSpeedup : function (cityId, qitem, i, item, count, hint) {
		var t = Tabs.Revive;
		var n = '';
		if (count>0) {
			n += '<td class=xtab style="padding-right:2px"><a onClick="speedupRevive('+cityId+','+item+','+qitem+','+i+')"><img height=18 style="opacity:0.8;vertical-align:text-top;" src="'+IMGURL+'items/70/'+item+'.jpg" title="'+uW.itemlist["i"+item].name+' ('+hint+') ('+count+')"></a></td>';
		}
		return n;
	},

	PaintCityInfo : function () {
		var t = Tabs.Revive;
		var cityId = t.ModelCityId;
		if (cityId) {
			var citynum = Cities.byID[cityId].idx+1;
			var unitId = ById('btRevType').value;
			ById('btRevWounded').innerHTML = '&nbsp;';
			ById('btRevCost').innerHTML = '&nbsp;';
			if (unitId!=0) {
				var unitWounded = parseIntNan(Seed.woundedUnits['city'+cityId]['unt'+unitId]);
				ById('btRevWounded').innerHTML = addCommas(unitWounded);
				ById('btRevCost').innerHTML = addCommas(t.getRevivalCost(unitId,unitWounded));
			}

			var bclass = "blue14";
			var btext  = tx("Clear");

			var m = '<DIV style="max-height:160px; height:160px; overflow-y:scroll"><table class=xtab cellpadding=0 cellspacing=0 width=100% style="padding-right:0px;"><tr>';
			m += '<TH class=xtabHD align=left>&nbsp;</th><TH class=xtabHD align=left>'+tx(uW.g_js_strings.openCastle.trooptype)+'</th><TH class=xtabHD align=right>'+tx('Min')+'</th><TH class=xtabHD align=right>'+tx('Max')+'</th><TH class=xtabHD align=right><a id=btClearLog onclick="btRevQueueDeleteAll(this,'+citynum+')" class="inlineButton btButton '+bclass+'"><span>'+btext+'</span></a></th></tr>';
			var rownum = 0;
			var gotqueue = false;
			for (var i=0; i<Options.ReviveOptions.HealArray[citynum].length; i++){
				gotqueue = true;
				if (rownum++ % 2)
					style = ' class="evenRow"';
				else
					style = ' class="oddRow"';
				var info = Options.ReviveOptions.HealArray[citynum][i];
				m += '<tr '+style+'><td align=left><a title="move up" onclick="btRevQueueUp(this,'+i+','+citynum+')"><img class=flip style="height:10px;width:13px;" src="'+DownArrow+'"><br><a title="move down" onclick="btRevQueueDn(this,'+i+','+citynum+')"><img style="height:10px;width:13px;" src="'+DownArrow+'"></td><td align=left>'+uW.unitcost['unt'+info.troop][0]+'</td>';
				var dispmax = "";
				if (info.max_sel) dispmax = addCommas(info.max);
				m += '<td align=right>'+addCommas(info.min)+'</td><td align=right>'+dispmax+'</td><td align=right>'+strButton8(uW.g_js_strings.commonstr.deletetx,'onclick="btRevQueueDelete(this,'+i+','+citynum+')"')+'</td></tr>';
			}
			if (!gotqueue) { m += '<tr><td colspan=5 align=center><br>'+tx('No wounded troops in revive queue')+'</td></tr>'; }
			m += '</table></div>';
			ById('btReviveCityQueue').innerHTML = m;
		}
	},

	deleteRevQueueAll : function(obj,citynum) {
		var t = Tabs.Revive;
		Options.ReviveOptions.HealArray[citynum] = [];
		saveOptions();
		ById('btRevMessages').innerHTML = tx("City Queue deleted!");
		t.PaintCityInfo();
	},

	deleteRevQueue : function(obj,index,citynum) {
		var t = Tabs.Revive;
		Options.ReviveOptions.HealArray[citynum].splice(index,1);
		saveOptions();
		ById('btRevMessages').innerHTML = tx("Queue entry deleted!");
		t.PaintCityInfo();
	},

	RevQueueUp : function(obj,index,citynum) {
		var t = Tabs.Revive;
		if (index>0) {
			Options.ReviveOptions.HealArray[citynum].splice(index-1, 0, Options.ReviveOptions.HealArray[citynum].splice(index, 1)[0]);
		}
		saveOptions();
		t.PaintCityInfo();
	},
	RevQueueDn : function(obj,index,citynum) {
		var t = Tabs.Revive;
		if (index<Options.ReviveOptions.HealArray[citynum].length-1) {
			Options.ReviveOptions.HealArray[citynum].splice(index+1, 0, Options.ReviveOptions.HealArray[citynum].splice(index, 1)[0]);
		}
		saveOptions();
		t.PaintCityInfo();
	},

	getRevivalCost : function(unitId,num) {
		var t = Tabs.Revive;
		var d = CM.WorldSettings.getSettingAsObject("APOTHECARY_COST");
		var i = d[unitId]?+(d[unitId]["Cost"])||2000:2000;
		var g = (100+CM.ThroneController.getBoundedEffect(98))/100;
		return Math.floor(i * g)*num;
	},

	getReviveTime : function (cid, uid, num) {
		var t = Tabs.Revive;
		var i = 0,
		q = getCityBuilding(cid, 23).count;
		try {
			i = CM.ThroneController.hasFactionBonus();
		} catch (m) {}

		var o = (100 + CM.ThroneController.getBoundedEffect(97)) / 100;
		var r = o * CM.WorldSettings.getSetting("APOTHECARY_TIME_FACTOR");
		var p = uW.unitcost["unt" + uid][7] * num / r;
		p = p >= 5 ? p : 5;
		if (q > 1) {
			p = p / 1.2
		}
		if (i.hazBonus && i.faction === "druid") {
			bonus = CM.ThroneController.effectBonus(96);
			p = p - (p * (bonus / 100))
		}
		p = Math.ceil(p - (p * CM.BlessingSystemModel.applyBlessing(CM.BlessingSystemModel.getBlessing().PICK_ME_UP, cid)));
		return p;
	},

	PaintWounded : function () {
		var t = Tabs.Revive;
		var rownum = 0;
		var irows = [];
		var	rows = [];
		var	acts = [];

		irows[0] = []; // wounded might

		function _row(name, row, noTotal, icon, act) {
			var t = Tabs.Revive;
			var tot = 0;
			if (!noTotal) {
				for (var i = 0; i < row.length; i++)
					tot += parseIntNan(row[i]);
				if (tot==0) { return ''; }
			}
			if (rownum++ % 2)
				style = ' class="evenRow"';
			else
				style = ' class="oddRow"';
			var m = [];
			m.push('<TR align=right');
			m.push(style);
			if (noTotal) {
				m.push('><TD colspan=2');
			}
			else {
				m.push('><TD');
			}
			m.push(' style="padding-left: 0px;"');
			m.push('>');
			if (icon) {
				m.push(icon);
			}
			else {
				m.push('<B>'+name+'&nbsp;</B>');
			}
			m.push('</td>');
			if (!noTotal) {
				m.push('<TD><div class="totalCell xtabBorder">');
				t.troopTotal[name] = tot;
				m.push(addCommas(tot));
				m.push('</div></td>');
			}
			for (var i = 0; i < row.length; i++) {
				m.push('<TD');
				m.push(style);
				m.push('><div class=xtabBorder>');
				if (act) { m.push('<span class="'+act[i]+'">'); }
				else { m.push('<span>'); }
				m.push(addCommas(row[i]));
				m.push('</span></div></td>');
			}
			m.push('</tr>');
			return m.join('');
		}

		var m = '<TABLE width=98% class=xtab cellpadding=1 cellspacing=0 align=center style="font-size:'+Options.OverviewOptions.OverviewFontSize+'px;"><TR valign=bottom><td width=20>&nbsp;</td><td align=right width=100><b>&nbsp;</b></td>';

		for (var i = 1; i <= Cities.numCities; i++) {
			m += '<TD style="font-size:11px;" align=center width=100><span id="btWoundedCity_'+i+'"><B>'+Cities.cities[i-1].name.substring(0, 12)+'</b></span></td>';
			irows[0][i-1] = 0;
		}

		m += "<td>&nbsp;</td></tr>"; // spacer

		for (var r = 1; r < t.unitsarr.length + 1; r++) {
			rows[r] = [];
			acts[r] = [];
			for (var i = 0; i < Cities.numCities; i++) {
				cityId = Cities.cities[i].id;
				rows[r][i] = 0;
				if (Seed.woundedUnits['city'+cityId] && Seed.woundedUnits['city'+cityId]['unt'+t.unitsarr[r-1]]) {
					rows[r][i] = parseIntNan(Seed.woundedUnits['city'+cityId]['unt'+t.unitsarr[r-1]]);
				}
				acts[r][i] = "";
				var q1 = Seed.queue_revive["city"+cityId];
				var u1 = 0;
				if (q1 != null && q1.length > 0) { u1 = q1[0][0]; }
				var q2 = Seed.queue_revive2["city"+cityId];
				var u2 = 0;
				if (q2 != null && q2.length > 0) { u2 = q2[0][0]; }
				if (t.unitsarr[r-1]==u1||t.unitsarr[r-1]==u2) { acts[r][i] = "boldGreen"; }
				irows[0][i] += parseIntNan(rows[r][i]) * uW.unitmight['unt'+t.unitsarr[r-1]];
			}
		}

		rownum = 0;
		for (var j = 1; j < t.unitsarr.length+1; j++) {
			m += _row(uW.unitcost['unt'+t.unitsarr[j-1]][0], rows[j], false, TroopImage(t.unitsarr[j-1]),acts[j]);
		}
		m += '<TR><TD colspan=2 align=right><b>'+tx('Wounded Might')+'&nbsp;</b></td></tr>';
		m += _row('', irows[0], false);

		m += '</table>';
		if (t.LastWounded!=m) {
			ById('btReviveWoundedDiv').innerHTML = m;
			ResetFrameSize('btMain',100,GlobalOptions.btWinSize.x);
			t.LastWounded = m;
		}
	},

	doAutoLoop : function (idx,addqueue) {
		var t = Tabs.Revive;
		clearTimeout(t.timer);
		if (!Options.ReviveOptions.Running) return;

		var cityId = Cities.cities[idx-1].id;
		if (idx==1) { t.loopaction = false; } // reset loop action indicator for first city
		t.autodelay = 0; // no delay if no action taken!

		if (Options.ReviveOptions.HealArray[idx] && !t.noApothecary[idx] && Options.ReviveOptions.Enabled[idx]) {
			if (t.citydelay[idx] > 0) { t.citydelay[idx]--; } // city being delayed due to error, reduce delay number and skip city
			else {
				// first check if city is idle (or busy)

				var now = unixTime();
				if (addqueue) { var qrev = Seed.queue_revive2["city" + cityId];	var slot=2;}
				else { var qrev = Seed.queue_revive["city" + cityId];  var slot=1; }
				if (qrev.length > 0 && parseInt(qrev[0][3]) > now) {
					// queue busy, try speedup!
					t.autoSpeedup (cityId,qrev[0],slot);
				}
				else {
					var ascensionok = (!Options.BuildOptions || !Options.BuildOptions.AscensionReady[idx]);
					if (ascensionok && (!Options.ReviveOptions.ThroneCheck || (t.revivespeed >= Options.ReviveOptions.ReviveSpeed))) { // if no revive speed restriction or enough revive speed
						var AvailGold = parseIntNan(Seed.citystats["city" + cityId].gold[0]) - parseIntNan(Options.ReviveOptions.MinGold);
						if (AvailGold > 0) {
							for (var i=0; i<Options.ReviveOptions.HealArray[idx].length; i++){
								var info = Options.ReviveOptions.HealArray[idx][i];
								var amt = 0;
								if (Seed.woundedUnits['city'+cityId]['unt'+info.troop] < info.min) continue;
								if (Seed.woundedUnits['city'+cityId]['unt'+info.troop] > info.max && info.max_sel){
									amt = info.max;
								} else {
									amt = Seed.woundedUnits['city'+cityId]['unt'+info.troop];
								}
								var unitGold = t.getRevivalCost(info.troop,1);
								var costGold = unitGold*amt;
								if (costGold>AvailGold) {
									amt = Math.floor(AvailGold/unitGold);
									if (amt < info.min || amt==0) continue;
								}
								// revive this!
								if (info.troop > 0 && amt > 0){
									t.autodelay = t.intervalSecs;
									t.loopaction = true;
									t.Revive(cityId,info.troop,amt);
									break;
								}
							}
						}
					}
				}
				if (!addqueue) {
					var twoqueues = false;
					if 	(Seed.cityData.city[cityId].isPrestigeCity) {
						twoqueues = (Seed.cityData.city[cityId].prestigeInfo.blessings.indexOf(106) != -1);
					}
					if (twoqueues) { // check additional queue
						t.timer = setTimeout(function () { t.doAutoLoop(idx,true); }, (t.autodelay * 1000));
						return;
					}
				}
			}
		}

		if (idx == Cities.numCities) {
			if (!t.loopaction) { t.autodelay = t.intervalSecs; } // if no action this loop, apply delay anyway...
			t.timer = setTimeout(function () { t.doAutoLoop(1,false); }, (t.autodelay * 1000));
		}
		else {
			t.timer = setTimeout(function () { t.doAutoLoop(idx+1,false); }, (t.autodelay * 1000));
		}
	},

    autoSpeedup: function (cityId,q,slot) {
		var t = Tabs.Revive;
		var now = unixTime();
		var item = 0;
		totTime = q[3] - now;

		if (totTime > 0) {
			if (Options.ReviveOptions.UseOverride && Options.ReviveOptions.OverrideItem != 0) {
				var THRESHOLD_SECONDS = (parseIntNan(Options.ReviveOptions.OverrideMinutes)*60)+(parseIntNan(Options.ReviveOptions.OverrideHours)*60*60);
				if (totTime >= THRESHOLD_SECONDS && uW.ksoItems[Options.ReviveOptions.OverrideItem].count > 0) { item = Options.ReviveOptions.OverrideItem; }
			}
            if (item==0 && totTime >= t.ExtraHourGlassThreshold[1] && Options.ReviveOptions.UseNH && uW.ksoItems[81].count > 0) { item = 81; }
            if (item==0 && totTime >= t.ExtraHourGlassThreshold[0] && Options.ReviveOptions.UsePH && uW.ksoItems[80].count > 0) { item = 80; }
            if (item==0 && totTime >= HourGlassThreshold[8] && Options.ReviveOptions.UseLH && uW.ksoItems[10].count > 0) { item = 10; }
            if (item==0 && totTime >= HourGlassThreshold[7] && Options.ReviveOptions.UseEH && uW.ksoItems[8].count > 0) { item = 8; }
            if (item==0 && totTime >= HourGlassThreshold[6] && Options.ReviveOptions.UseDH && uW.ksoItems[7].count > 0) { item = 7; }
            if (item==0 && totTime >= HourGlassThreshold[5] && Options.ReviveOptions.UseRH && uW.ksoItems[6].count > 0) { item = 6; }
            if (item==0 && totTime >= HourGlassThreshold[4] && Options.ReviveOptions.UseAH && uW.ksoItems[5].count > 0) { item = 5; }
            if (item==0 && totTime >= HourGlassThreshold[3] && Options.ReviveOptions.UseMH && uW.ksoItems[4].count > 0) { item = 4; }
            if (item==0 && totTime >= HourGlassThreshold[2] && Options.ReviveOptions.UseGH && uW.ksoItems[3].count > 0) { item = 3; }
            if (item==0 && totTime >= HourGlassThreshold[1] && Options.ReviveOptions.UseKH && uW.ksoItems[2].count > 0) { item = 2; }
            if (item==0 && totTime >= HourGlassThreshold[0] && Options.ReviveOptions.UseSH && uW.ksoItems[1].count > 0) { item = 1; }
        }

		if (item != 0) {
			t.autodelay = t.intervalSecs;
			t.loopaction = true;
			t.speedupRevive(cityId,item,q[0],slot,true);
		}
    },

	cancelRevive : function (cityId,slotNum) {
		var t = Tabs.Revive;
		var q;
		if (slotNum == 1) {	q = Seed.queue_revive['city'+cityId][0]; }
		if (slotNum == 2) {	q = Seed.queue_revive2['city'+cityId][0]; }
		if(q) {
			CM.last_building_opened = 23; // force apothecary view boolean
			uW.removeTraining(0, cityId, q[0], q[1], q[3], q[2], q[5], false, 'rev'+slotNum);
		}
	},

	speedupRevive : function (cityId,item,cid,slotNum,noretry) {
		var t = Tabs.Revive;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btReviveCity_'+citynum).css('color', 'magenta');

		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.iid = item;
		params.uid = cid;
		params.slotNum = slotNum;
		params.apothecary = true;
  		new MyAjaxRequest(uW.g_ajaxpath + "ajax/speedupTraining.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function (rslt) {
				if (rslt.ok) {
					var reduced = CM.intelligentOrdering.getReduceTime(item);
					Seed.items["i" + item] = parseInt(Seed.items["i" + item]) - 1;
					uW.ksoItems[item].subtract();
					var qloc = 0;
					var timered = 0;
					var queue = Seed.queue_unt;
					if (params.slotNum == 1) { queue = Seed.queue_revive; }
					if (params.slotNum == 2) { queue = Seed.queue_revive2; }
					queue["city" + cityId][0][3] = rslt.dateTraining;
					if (rslt.updateCityUnits) { uW.update_cityUnits(rslt.updateCityUnits); }
					if (rslt.updateWoundedCityUnits) { uW.update_woundedCityUnits(rslt.updateWoundedCityUnits); }
					timered = SpeedupArray[parseInt(item) - 1];
					if (Seed.player.usedSpeedup && Seed.player.usedSpeedup == 0) {
						Seed.player.usedSpeedup = 1;
					}
					if (cityId == uW.currentcityid) uW.update_queue();
				}
				else {
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Revive speedup failed ('+rslt.msg+')','REVIVE');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Revive speedup failed ('+rslt.error_code+')','REVIVE');
					}
				}
				jQuery('#btReviveCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
  			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Revive speedup failed (AJAX Error)','REVIVE');
				jQuery('#btReviveCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
  		},noretry);
	},

	Revive_Now: function(idx,troop,min,max,max_sel){
		var t = Tabs.Revive;
		ById('btRevMessages').innerHTML = "";
		var citynum=idx+1;
		if(t.noApothecary[citynum]) {
			ById('btRevMessages').innerHTML = tx("No Apothecary")+"!";
			return;
		}
		var cid = Cities.cities[idx].id;
		var amt = 0;
		var twoqueues = false;
		if (Seed.cityData.city[cid].isPrestigeCity) {
			twoqueues = (Seed.cityData.city[cid].prestigeInfo.blessings.indexOf(106) != -1);
		}
		if (Seed.queue_revive['city'+cid].length > 0 && (Seed.queue_revive2['city'+cid].length > 0 || !twoqueues)) {
			ById('btRevMessages').innerHTML = tx("Revive queue is full")+"!";
			return;
		}
		var AvailGold = parseIntNan(Seed.citystats["city" + cid].gold[0]) - parseIntNan(Options.ReviveOptions.MinGold);
		if (AvailGold < 0) {
			ById('btRevMessages').innerHTML = tx("Gold is below minimum threshold")+"!";
			return;
		}
		if (Seed.woundedUnits['city'+cid]['unt'+troop] < min) {
			ById('btRevMessages').innerHTML = tx("Wounded troops are below minimum threshold")+"!";
			return;
		}
		if (Seed.woundedUnits['city'+cid]['unt'+troop] == 0) {
			ById('btRevMessages').innerHTML = tx("No troops to revive")+"!";
			return;
		}
		if (Seed.woundedUnits['city'+cid]['unt'+troop] > max && max_sel){ var amt = parseIntNan(max); }
		else { var amt = parseIntNan(Seed.woundedUnits['city'+cid]['unt'+troop]); }
		// check gold!
		var unitGold = t.getRevivalCost(troop,1);
		var costGold = unitGold*amt;
		if (costGold>AvailGold) {
			amt = Math.floor(AvailGold/unitGold);
			if (amt < min || amt==0) {
				ById('btRevMessages').innerHTML = tx("Not enough gold above threshold to revive minimum troop threshold")+"!";
				return;
			}
		}
		if(cid > 0 && troop > 0 && amt > 0){
			t.Revive(cid,troop,amt);
		}
	},

	Add_Revive: function(idx,troop,min,max,max_sel){
		var t = Tabs.Revive;
		var citynum = idx+1;
		ById('btRevMessages').innerHTML = "";
		if(t.noApothecary[citynum]) {
			ById('btRevMessages').innerHTML = tx("No Apothecary")+"!";
			return;
		}
		if (troop==0 || (max_sel && max<1) || (max_sel && max<min)) {
			ById('btRevMessages').innerHTML = tx("Invalid parameters")+"!";
			return;
		}

		Options.ReviveOptions.HealArray[citynum].push({troop:troop,min:min,max:max,max_sel:max_sel});
        saveOptions();
		t.PaintCityInfo();
	},

	AddAllWounded : function () {
		var t = Tabs.Revive;
		var cityId = t.ModelCityId;
		var citynum = Cities.byID[cityId].idx+1;
		ById('btRevMessages').innerHTML = "";
		var min = parseIntNan(Options.ReviveOptions.BatchMin);
		var max = parseIntNan(Options.ReviveOptions.BatchMax);
		var max_sel = Options.ReviveOptions.SelectBatchMax;
		if(t.noApothecary[citynum]) {
			ById('btRevMessages').innerHTML = tx("No Apothecary")+"!";
			return;
		}
		if ((max_sel && max<1) || (max_sel && max<min)) {
			ById('btRevMessages').innerHTML = tx("Invalid parameters")+"!";
			return;
		}
		for (var w in Seed.woundedUnits['city'+cityId]) {
			var unitId = w.split("unt")[1];
			if (unitId && (t.CannotReviveUnit.indexOf(parseIntNan(unitId)) == -1) && parseIntNan(Seed.woundedUnits['city'+cityId][w])>0) {
				var gottroops = false;
				for (var e in Options.ReviveOptions.HealArray[citynum]) {
					if (Options.ReviveOptions.HealArray[citynum][e].troop==unitId) {
						gottroops = true;
						break;
					}
				}
				if (!gottroops) {
					t.Add_Revive(t.ModelCity.city.idx,unitId,min,max,max_sel);
				}
			}
		}
	},

	Revive : function(cityId,unitId,num){
		var t = Tabs.Revive;
		var citynum = Cities.byID[cityId].idx+1;
		jQuery('#btReviveCity_'+citynum).css('color', 'green');
		var params = uW.Object.clone(uW.g_ajaxparams);
		params.cid = cityId;
		params.type = unitId;
		params.quant = num;
		params.apothecary = true;
		var time = t.getReviveTime(cityId,unitId, num);

		new MyAjaxRequest(uW.g_ajaxpath + "ajax/train.php" + uW.g_ajaxsuffix, {
			method: "post",
			parameters: params,
			onSuccess: function(rslt) {
				if (rslt.ok) {
//					for (var i = 1; i < 5; i++) {
//						var resourceLost = parseInt(uW.unitcost["unt" + unitId][i]) * 3600 * parseInt(num);
//						if(rslt.gamble) resourceLost = resourceLost*rslt.gamble[i];
//						Seed.resources["city"+cityId]["rec"+i][0] = parseInt(Seed.resources["city"+cityId]["rec"+i][0])-resourceLost;
//					}
					if (!rslt.initTS) { rslt.initTS = uW.unixTime() - 1; }
					if (Seed.queue_revive["city" + cityId].length == 0) { RQ = Seed.queue_revive["city" + cityId] }
					else { RQ = Seed.queue_revive2["city" + cityId] }
					RQ.push([unitId, num, rslt.initTS, parseInt(rslt.initTS) + time, 0, time, null]);
					var cost = t.getRevivalCost(unitId, num);
					Seed.citystats["city" + cityId].gold[0] -= parseInt(cost);
					if (uW.currentcityid == cityId) unsafeWindow.update_gold();
					Seed.woundedUnits["city"+cityId]["unt"+unitId]=parseInt(Seed.woundedUnits["city"+cityId]["unt"+unitId])-num;
					t.PaintCityInfo();
				} else {
					if (rslt.error_code == 6) { // city already reviving? delay 10 loops
						t.citydelay[citynum] = 10;
					}
					if (rslt.msg) {
						actionLog(Cities.byID[cityId].name+': Revive failed ('+rslt.msg+')','REVIVE');
					}
					else {
						actionLog(Cities.byID[cityId].name+': Revive failed ('+rslt.error_code+')','REVIVE');
					}
				}
				jQuery('#btReviveCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
			onFailure: function () {
				actionLog(Cities.byID[cityId].name+': Revive failed (AJAX Error)','REVIVE');
				jQuery('#btReviveCity_'+citynum).css('color', 'rgb('+HEXtoRGB(Options.Colors.PanelText).r+','+HEXtoRGB(Options.Colors.PanelText).g+','+HEXtoRGB(Options.Colors.PanelText).b+')');
			},
  		},true);
	},
}

/***************************************************************************************/
/************************************ END OF TABS *************************************/
/***************************************************************************************/

if (document.URL.search(/main_src.php/i) != -1) {
	if (window.self.location != window.parent.location) { // Fix weird bug with koc game?
		PowerBotStartup();
	}
}