WoTStatScript - Clanpage

More info for World of Tanks clan page.

Від 01.07.2016. Дивіться остання версія.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        WoTStatScript - Clanpage
// @version     0.9.15.1.4
// @description More info for World of Tanks clan page.
// @author      Orrie
// @namespace   http://forum.worldoftanks.eu/index.php?/topic/263423-
// @icon        http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/img/icon.png
// @include     http://*.wargaming.net/clans/*/*
// @grant       GM_xmlhttpRequest
// @connect     www.wnefficiency.net
// @connect     api.worldoftanks.eu
// @connect     api.worldoftanks.ru
// @connect     api.worldoftanks.com
// @connect     api.worldoftanks.asia
// @connect     api.worldoftanks.kr
// @connect     eu.wargaming.net
// @require     https://greasyfork.org/scripts/18946-tablesort/code/Tablesort.js?version=120660
// @license     MIT License
// ==/UserScript==
(function() {
	// global vars
	var d = document, c = d.cookie;

	// get server info and webpage
	var wg = {host:d.location.host, href:d.location.href, clan:{}};
	wg.srv = wg.host.match(/(eu|ru|na|asia|kr)/)[0];
	wg.m = (/players/i.test(wg.href) || /players\/wot/i.test(wg.href)) && !/wowp/i.test(wg.href);
	wg.g = /globalmap/i.test(wg.href);

	// getting claninfo
	var emblemName = d.getElementsByClassName('page-header_emblem')[0],
	clanName = d.getElementsByClassName('clan_name')[0],
	sidebarName = d.getElementsByClassName('sidebar-clan_emblem')[0];
	wg.clan.id = wg.href.match(/\/(\d+)/)[1];
	wg.clan.name = (emblemName || clanName) ? ((clanName) ? clanName.firstElementChild.innerHTML.replace(/[\[\]]/g,"") : emblemName.alt) : sidebarName.alt;
	wg.p = new RegExp("\\["+wg.clan.name+"\\] \\|").test(d.title) && !/wowp/i.test(wg.href);

	// script variables
	var sc = {
		vers: ((GM_info) ? GM_info.script.version : ""),
		host: "http://greasyfork.org/en/scripts/12137-wotstatscript-clans",
		user: {
			wl: "http://forum.wotlabs.net/index.php?/user/1618-orrie/",
			wot: "http://worldoftanks.eu/community/accounts/505838943-Orrie/"
		},
		top: {
			eu: "http://forum.worldoftanks.eu/index.php?showtopic=263423",
			na: "http://forum.worldoftanks.com/index.php?showtopic=404652"
		},
		cred: { // translators
			cs: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/500744969/'>Crabtr33</a></td><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/508323506/'>Ragnarocek</a></td></tr><tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/508904714/'>jViks</a></td></tr>" ,
			de: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/504873051/'>ArtiOpa</a></td><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/501118529/'>Crakker</a></td></tr><tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/501072645/'>multimill</a></td><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/500373105/'>coolathlon</a></td></tr>",
			fr: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/506641783/'>SuperPommeDeTerre</a></td></tr>",
			pl: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/501801562/'>KeluMocy</a></td><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/504412736/'>pokapokami</a></td></tr>",
			es: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/512759883/'>Frodo45127</a></td></tr>",
			tr: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.eu/community/accounts/500400806/'>Ufuko</a></td></tr>",
			ru: "<tr><td><a class='b-orange-arrow' href='http://worldoftanks.ru/community/accounts/291063/'>Bananium</a></td><td>dimon222</td></tr>"
		},
		api: {
			ru: "98ca7c4fb108175b67d6505b9c3f3ebd",
			eu: "a7595640a90bf2d19065f3f2683b171c",
			na: "bf5dba0efd444d75147b6222dd903fd2",
			asia: "95f8713eccd322e52dbf521dbd28b19c",
			kr: "ffea0f1c3c5f770db09357d94fe6abfb"
		},
		srv: {
			wl: false,   // wotlabs
			nm: false,   // noobmeter
			vb: false,   // vbaddict
			ws: false,   // wotstats
			cs: false,   // wotcs
			wlf: false,  // wot-life
			ct: false,   // clan tools
			kttc: false, // kttc
			wots: false, // wots
			ch: false,   // clan history
			wr: false,   // wotreplays
			we: false    // wot event stats
		},
		wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json",
		loc: c.match(/wgccfe_language=(\w+)/)[1],
		locSup: ["en", "ru", "cs", "de", "fr", "pl", "es", "tr"],
		date: Date.now(),
		dateFormat: {ru: "ru-RU", eu: "en-GB", na: "en-US", asia: "en-AU", kr: "ko-KR"},
		web: {
			gecko: typeof InstallTrigger !== 'undefined',
			opera: !!window.opera || /opera|opr/i.test(navigator.userAgent),
			chrome: !!window.chrome && !!window.chrome.webstore,
			safari: /constructor/i.test(window.HTMLElement)
		}
	};

	// script functions
	var sf = {
		tableFetch: function () {
			// show animated loading gear
			loadGif.classList.remove("js-hidden");
			// find required info from table player rows
			for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) {
				var row = memObj.cls.rows[_rt];
				if (!row.classList.contains("tbl-rating_tr__card")) {
					var id = row.getAttribute('data-account_id'),
					name = row.getElementsByClassName('player_name')[0].innerHTML.match(/[\w\_]+/)[0],
					role = row.getElementsByClassName('tbl-rating_td__rank')[0].firstElementChild.classList.item(4).match(/i__(\w+)/)[1];
					if (!isNaN(id)) {
						memObj.ids.push(id);
						s.user[id] = {u:{name:name,id:id,role:role}, v:{frag:0,dmg:0,spot:0,def:0,win:0}, wn8:""};
					}
				}
			}
			s.clan = {name:wg.clan.name, wn8:0, win:0, mem: _rt_len};
			// request and retrieve statistics from API
			if (s.clan.mem > 0) {
				sf.request(sc.api.i+memObj.ids.join(','), sf.apiInfoHnd);
			}
		},
		apiInfoHnd: function (resp) { // processing information from player API
			var data = JSON.parse(resp).data;
			for (var a in data) {
				if (data.hasOwnProperty(a)) {
					var pData = data[a];
					if (pData !== null) {
						// store stats
						var pDataStats = pData.statistics.all;
						s.user[pData.account_id].u = {
							name: pData.nickname,
							id: pData.account_id,
							role: s.user[pData.account_id].u.role,
							cid: pData.clan_id,
							bat: pDataStats.battles,
							win: (pDataStats.wins/pDataStats.battles)*100,
							dmg: pDataStats.damage_dealt/pDataStats.battles,
							frag: pDataStats.frags/pDataStats.battles,
							spot: pDataStats.spotted/pDataStats.battles,
							def: pDataStats.dropped_capture_points/pDataStats.battles,
							wgr: pData.global_rating,
							lng: pData.client_language
						};
						s.clan.win += (!isNaN(s.user[pData.account_id].u.win)) ? s.user[pData.account_id].u.win : 0;
					}
				}
			}
			d.getElementById('js-wn8-status').textContent = "50%";
			sf.request(sc.api.v+memObj.ids.join(','), sf.apiVehHnd);
		},
		apiVehHnd: function (resp) { // processing information from vehicle API and calculate WN8
			var data = JSON.parse(resp).data;
			for (var p in data) {
				if (data.hasOwnProperty(p)) {
					var vData = data[p];
					if (vData !== null) {
						var rWin, rDmg, rFrag, rSpot, rDef, wn8 = 0, battles = 0;
						if (s.user[p].u.bat > 0) {
							for (var v in vData) {
								if (vData.hasOwnProperty(v)) {
									// go through each vehicle to get expected stats
									for (var _so=0, _so_len = statArr.length; _so<_so_len; _so++) {
										if (statArr[_so].IDNum == vData[v].tank_id) {
											var vehStat = statArr[_so],
											dataBattles = vData[v].statistics.battles;
											s.user[p].v.frag += vehStat.expFrag    * dataBattles;
											s.user[p].v.dmg  += vehStat.expDamage  * dataBattles;
											s.user[p].v.spot += vehStat.expSpot    * dataBattles;
											s.user[p].v.def  += vehStat.expDef     * dataBattles;
											s.user[p].v.win  += vehStat.expWinRate * dataBattles;
											battles += dataBattles;
											break;
										}
									}
								}
							}
							// start calculating wn8
							rWin  = Math.max(((s.user[p].u.win /(s.user[p].v.win /battles)-0.71)/(1-0.71)),0);
							rDmg  = Math.max(((s.user[p].u.dmg /(s.user[p].v.dmg /battles)-0.22)/(1-0.22)),0);
							rFrag = Math.max(Math.min(rDmg+0.2,((s.user[p].u.frag/(s.user[p].v.frag/battles)-0.12)/(1-0.12))),0);
							rSpot = Math.max(Math.min(rDmg+0.1,((s.user[p].u.spot/(s.user[p].v.spot/battles)-0.38)/(1-0.38))),0);
							rDef  = Math.max(Math.min(rDmg+0.1,((s.user[p].u.def /(s.user[p].v.def /battles)-0.10)/(1-0.10))),0);
							wn8 = 980*rDmg + 210*rDmg*rFrag + 155*rFrag*rSpot + 75*rDef*rFrag + 145*Math.min(1.8,rWin);
						}
						// store wn8 and add to clan total
						s.user[p].wn8 = wn8;
						s.clan.wn8 += wn8;
					}
				}
			}
			// calculate average wn8 / winrate and store everything in localStorage, then reload page
			s.clan.wn8 = s.clan.wn8/s.clan.mem;
			s.clan.win = s.clan.win/s.clan.mem;
			sf.storage("statScriptValues_"+wg.clan.id, s, "set", "string");
			sf.storage("statScriptDate_"+wg.clan.id, sc.date, "set");
			d.getElementById('js-wn8-status').textContent = "100%";
			location.reload();
		},
		apiBanHnd: function (resp) { // processing information from banned API
			var data;
			if (!memObj.bans.api) {
				data = JSON.parse(resp).data;
				memObj.bans.api = data;
				memObj.bans.f = true;
			}
			else {
				data = memObj.bans.api;
			}
			for (var a in data) {
				if (data.hasOwnProperty(a)) {
					var bData = data[a];
					var memClass = "js-tooltip-id_js-playerslist-account-name-tooltip-"+a,
					memCell = d.getElementsByClassName(memClass)[0].parentNode;
					if (bData.ban_time !== null) {
						var banTime = (bData.ban_time > 0) ? new Date(bData.ban_time*1000).toLocaleString(sc.dateFormat[wg.srv]) : loc[18];
						memCell.appendChild(sf.elem("p", "player_time", banTime));
					}
					else {
						memCell.appendChild(sf.elem("p", "player_time", loc[19]));
					}
				}
			}
		},
		format: function (input, type) { // input and output formatting
			var inputStr = input.toString();
			switch(type) {
				case (1): // input string into number
					return parseFloat(inputStr.replace(/[^\d]/g,""));
				case (2): // output number with locale symbol
					return inputStr.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1"+loc[0]);
				case (3): // input string into number - exclude dots
					return parseFloat(inputStr.replace(/[^\d\.]/g,""));
				default:
					console.error("Error filtering: ", input);
					return input;
			}
		},
		color: function (input, type, dec, sym) { // color formatting
			var color = colArr.dft[0],
			output = input.toFixed(dec);
			if (input >= 1000) {
				output = sf.format(input.toFixed(dec),2);
			}
			for (var c in colArr) {
				if (colArr.hasOwnProperty(c)) {
					if (input >= colArr[c][colArr.id[type]]) {
						color = colArr[c][0]; break;
					}
				}
			}
			if (loc[0] !== "," && dec !== 0) {
				output = output.replace(/\.(\d+)*$/g,",$1");
			}
			if (sym) {
				output += sym;
			}
			return "<font color='"+color+"'>"+output+"</font>";
		},
		elem: function (tag, name, html, type, src) { // element creation
			var element = d.createElement(tag);
			if (name) {
				element.className = name;
			}
			if (html) {
				if (/</.test(html)) {
					element.innerHTML = html;
				}
				else {
					element.textContent = html;
				}
			}
			if (type) {
				element.type = type;
			}
			if (src) {element.src = src;}
			return element;
		},
		settings: function (name, text, state, dftState, wlist) { // script menu handler
			var listItem = sf.elem("li", "b-settingItem "+name, ""),
			listItems = d.createDocumentFragment();
			if (name == "wnRefresh") {
				var refreshBtn = sf.elem("div", "b-settingParent", "<a>"+text+"</a>");
				listItem.classList.add("settingSeperator");
				refreshBtn.addEventListener('click', function() {localStorage.removeItem("wnExpValues"); location.reload();}, false);
				listItems.appendChild(refreshBtn);
			}
			else if (name == "cleanStorage") {
				var cleanBtn = sf.elem("div", "b-settingParent", "<a>"+text+"</a>");
				cleanBtn.addEventListener('click', function() {localStorage.clear(); location.reload();}, false);
				listItems.appendChild(cleanBtn);
			}
			else {
				var optCheckDiv = sf.elem("div", "b-checkbox", "<span class='b-checkbox_checker'></span>"),
				optLabel = sf.elem("label", "b-combobox-label", text),
				optCheck = sf.elem("input", "l-box", "", "checkbox");
				optLabel.htmlFor = name;
				optCheck.name = name;
				optCheck.id = name;
				if (state) {
					optCheckDiv.classList.add("b-checkbox__checked");
					optLabel.classList.add("b-combobox-label__checked");
				}
				optCheck.checked = (state !== undefined) ? state : dftState;
				optCheck.addEventListener('click', function() {
					sf.storage('statScript_' + this.name, this.checked, "set");
					d[this.name] = this.checked;
					this.parentNode.classList.toggle('b-checkbox__checked');
					this.parentNode.parentNode.classList.toggle('b-combobox-label__checked');
					return this.checked;
				}, false);
				d[optCheck.name] = optCheck.checked;
				optCheckDiv.insertBefore(optCheck, optCheckDiv.firstChild);
				optLabel.appendChild(optCheckDiv);
				listItems.appendChild(optLabel);
				if (name == "whitelist") {
					var optText = sf.elem("textarea", "l-textarea", "");
					optText.placeholder = "Add clanID seperated by comma without spaces: 500004502,500010805";
					if (wlist) {
						optText.value = wlist;
					}
					optText.addEventListener('input', function() {
						sf.storage('statScript_whitelist_list', optText.value.split(","), "set");
					}, false);
					listItems.appendChild(optText);
				}
			}
			listItem.appendChild(listItems);
			return listItem;
		},
		links: function (parent, links) { // links handler
			var uRows = d.createDocumentFragment();
			for (var _l=0, _l_len = links.length; _l<_l_len; ++_l) {
				if (links[_l] instanceof HTMLElement) {
					uRows.appendChild(links[_l]);
				}
				else {
					uRows.appendChild((links[_l][0] && links[_l][1]) ? sf.elem("li", "", links[_l][1]) : sf.elem("li", "statname", links[_l][0]));
				}
			}
			parent.appendChild(uRows);
		},
		storage: function (name, data, type, mode) { // localStorage handler
			var storage;
			switch(type) {
				case ("set"):
					if (mode == "string") {
						data = JSON.stringify(data);
					}
					storage = localStorage.setItem(name, data);
					break;
				case ("get"):
					storage = localStorage.getItem(name);
					if (mode == "parse") {
						storage = JSON.parse(storage);
					}
					break;
				default: break;
			}
			return storage;
		},
		wn: function (resp) { // wnefficiency handler
			sf.storage("wnExpValues", resp, "set");
			sf.storage("wnExpDate", sc.date, "set");
			sf.storage("wnExpVers", [sc.vers, JSON.parse(resp).header.version], "set", "string");
			location.reload();
		},
		request: function (url, handler) { // request handler
			GM_xmlhttpRequest({
				method: "GET",
				url: url,
				headers: {
					"Accept": "application/json"
				},
				onload: function(resp) {
					if (resp.status == 200) {
						handler(resp.responseText);
					}
					else {
						console.error("Error accessing", url, resp.readyState, resp.status, resp.statusText);
					}
				},
				onerror: function(resp) {
					console.error("Error accessing", url, resp.readyState, resp.status, resp.statusText);
				}
			});
		}
	};

	// api links without account id
	sc.api.i = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/info/?application_id="+sc.api[wg.srv]+"&account_id=";
	sc.api.v = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/tanks/?application_id="+sc.api[wg.srv]+"&account_id=";

	// fetch wnefficiency values - check if array exists in localStorage, otherwise fetch and reload page
	var wn = {
		values: sf.storage("wnExpValues", "", "get", "parse"),
		date: sf.storage("wnExpDate", "", "get", "parse")+12096e5 >= sc.date, // true if timestamp is less than 2 weeks old, refresh list if false.
		vers: sf.storage("wnExpVers", "", "get", "parse") || ""
	}, statArr = [];
	if (wn.vers[0]==sc.vers && wn.values && wn.date) {
		statArr = wn.values.data;
	}
	else {
		sf.request(sc.wn, sf.wn);
	}

	// fetch stored clanlist stats - check if array exists in localStorage, otherwise tag fetching to true
	var ss = {
		val: sf.storage("statScriptValues_"+wg.clan.id, "", "get", "parse"),
		date: sf.storage("statScriptDate_"+wg.clan.id, "", "get", "parse")+6048e5 >= sc.date // true if timestamp is less than 1 weeks old, refresh list if false.
	}, s = {clan:{},user:{}}, statFetch = false;
	if (ss.val && ss.date) {
		s = ss.val;
	}
	else {
		statFetch = true;
	}

	// inserting style into head
	var style = sf.elem("style", "wotstatscript", "", "text/css");
	d.head.appendChild(style);

	// colour scale array
	var colArr = {
		//      col        wr  bat    sr  hr  dmg  wgr   wn8   wn7   eff   nm
		sUni: [ "#5A3175", 65, 30000, 50, 80, 300, 9900, 2900, 2050, 2050, 2000 ], // 99.99% super unicum
		uni:  [ "#83579D", 60, 25000, 46, 75, 270, 9000, 2450, 1850, 1800, 1950 ], // 99.90% unicum
		gr8:  [ "#3972C6", 56, 21000, 42, 70, 240, 8500, 2000, 1550, 1500, 1750 ], // 99.00% great
		vGud: [ "#4099BF", 54, 17000, 38, 65, 210, 6500, 1600, 1350             ], // 95.00% very good
		good: [ "#4D7326", 52, 13000, 34, 60, 180, 5000, 1200, 1100, 1200, 1450 ], // 82.00% good
		aAvg: [ "#849B24", 50, 10000, 30, 55, 150, 4000,  900                   ], // 63.00% above average
		avg:  [ "#CCB800", 48,  7000, 25, 50, 120, 3000,  650,  900,  900, 1250 ], // 40.00% average
		bAvg: [ "#CC7A00", 47,  3000, 20, 45,  90, 2000,  450,  700,  600, 1150 ], // 20.00% below average
		bas:  [ "#CD3333", 46,  1000, 15, 40,  60, 1500,  300,  500             ], //  6.00% basic
		beg:  [ "#930D0D",  0,     0,  0,  0,   0,    0,    0,    0,    0,    0 ], //  0.00% beginner
		dft:  [ "#6B6B6B" ], // default
		id: { "col": 0, "wr": 1, "bat": 2, "sr": 3, "hr": 4, "dmg": 5, "wgr": 6, "wn8": 7, "wn7": 8, "eff": 9, "nm": 10 }  // type identifier
	};

	// localization
	// cz-czech   - Crabtr33 and Ragnarocek
	// de-german  - ArtiOpa, Crakker and multimill
	// fr-french  - SuperPommeDeTerre
	// pl-polish  - KeluMocy and pokapokami
	// es-spanish - Frodo45127
	// tr-turkish - Ufuko
	// ru-russian - dimon222
	var loc = [
		// thousands separator
		{ en: ",", ru: " ", cs: " ", de: ".", fr: " ", pl: " ", es:" ", tr: "."},
		// clan page
		{ en: "Clan Stats", ru: "Статистика клана", cs: "Stat. klanu", de: "Clanstatistiken", fr: "Statistiques du clan", pl: "Statystyki klanu", es: "Estadísticas del clan", tr: "Klan İstatistikleri"},
		{ en: "Replays:", ru: "Реплеи:", cs: "Záznamy:", de: "Replays", fr: "Replays:", pl: "Powtórki:", es: "Repeticiones:", tr: "Replayler"},
		// memberlist
		{ en: "Script Menu", ru: "Меню скрипта", cs: "Nastavení scriptu", de: "Script-Menü", fr: "Menu du script", pl: "Script Menu", es:"Script Menu", tr: "Script Menu"},
		{ en: "Load Stats Automatically", ru: "Load Stats Automatically", cs: "Nahrát stat. automaticky", de: "Load Stats Automatically", fr: "Charger les statistiques automatiquement", pl: "Load Stats Automatically", es:"Load Stats Automatically", tr: "Load Stats Automatically"},
		{ en: "Use Whitelist", ru: "Use Whitelist", cs: "Použi whitelist", de: "Use Whitelist", fr: "Utiliser la liste blanche", pl: "Use Whitelist", es:"Use Whitelist", tr: "Use Whitelist"},
		{ en: "Refresh WN8 Table", ru: "Обновить таблицу WN8", cs: "Obnov WN8 Tabulku", de: "WN8-Tabelle neu laden", fr: "Rafraîchir la table WN8", pl: "Refresh WN8 Table", es: "Refresh WN8 Table", tr: "Refresh WN8 Table"},
		{ en: "Clean Script Database", ru: "Clean Script Database", cs: "Vyčisti db scriptu", de: "Clean Script Database", fr: "Nettoyer la base de données du script", pl: "Clean Script Database", es: "Clean Script Database", tr: "Clean Script Database"},
		{ en: "Average Winrate", ru: "Average Winrate", cs: "Průměrný winrate", de: "Average Winrate", fr: "Ratio de victoire moyen", pl: "Average Winrate", es:"Average Winrate", tr: "Average Winrate"},
		{ en: "Average WN8", ru: "Average WN8", cs: "Průměrné WN8", de: "Average WN8", fr: "Average WN8", pl: "WN8 moyen", es:"Average WN8", tr: "Average WN8"},
		{ en: "Overall Average Winrate", ru: "Overall Average Winrate", cs: "Průměrný winrate", de: "Overall Average Winrate", fr: "Overall Average Winrate", pl: "Overall Average Winrate", es:"Overall Average Winrate", tr: "Overall Average Winrate"},
		{ en: "Overall Average WN8", ru: "Overall Average WN8", cs: "Overall Average WN8", de: "Overall Average WN8", fr: "Overall Average WN8", pl: "Overall Average WN8", es:"Overall Average WN8", tr: "Overall Average WN8"},
		{ en: "Fetch WN8 for Clan", ru: "Fetch WN8 for Clan", cs: "Obnov WN8 pre klan", de: "Fetch WN8 for Clan", fr: "Calculer le WN8 pour le clan", pl: "Fetch WN8 for Clan", es:"Fetch WN8 for Clan", tr: "Fetch WN8 for Clan"},
		{ en: "Fetching WN8 for Clan!", ru: "Fetching WN8 for Clan!", cs: "Obnovuju WN8 pro klan!", de: "Fetching WN8 for Clan!", fr: "Walcul du WN8 pour le clan !", pl: "Fetching WN8 for Clan!", es:"Fetching WN8 for Clan!", tr: "Fetching WN8 for Clan!"},
		{ en: "WN8 Fetched for Clan!", ru: "WN8 Fetched for Clan!", cs: "WN8 obnoveno pro klan!", de: "WN8 Fetched for Clan!", fr: "WN8 calculé pour le clan !", pl: "WN8 Fetched for Clan!", es:"WN8 Fetched for Clan!", tr: "WN8 Fetched for Clan!"},
		{ en: "Not Found", ru: "Not Found", cs: "Nenalezeno", de: "Not Found", fr: "Non trouvé", pl: "Not Found", es:"Not Found", tr: "Not Found"},
		{ en: "New Members:", ru: "New Members:", cs: "Noví členové:", de: "New Members:", fr: "Nouveaux membres :", pl: "New Members:", es:"New Members:", tr: "New Members:"},
		{ en: "Banned Members:", ru: "Banned Members:", cs: "Noví členové:", de: "Banned Members:", fr: "Membres bannis:", pl: "Banned Members:", es:"Banned Members:", tr: "Banned Members:"},
		{ en: "Currently Unavailable", ru: "Currently Unavailable", cs: "Currently Unavailable", de: "Currently Unavailable", fr: "Indisponible actuellement", pl: "Currently Unavailable", es:"Currently Unavailable", tr: "Currently Unavailable"},
		{ en: "Ban ended, but no login", ru: "Ban ended, but no login", cs: "Ban ended, but no login", de: "Ban ended, but no login", fr: "Ban terminé, mais aucune connexion", pl: "Ban ended, but no login", es:"Ban ended, but no login", tr: "Ban ended, but no login"},
		{ en: "Script Author:", ru: "Автор скрипта:", cs: "Autor skriptu:", de: "Script-Autor:", fr: "Auteur du script:", pl: "Script Author:", es:"Script Author:", tr: "Script Author:"},
		{ en: "Contributors", ru: "Contributors", cs: "Kontributoři", de: "Contributors", fr: "Contributeurs", pl: "Contributors", es:"Contributors", tr: "Contributors"},
		{ en: "Battle Schedule", ru: "Battle Schedule", cs: "Battle Schedule", de: "Battle Schedule", fr: "Battle Schedule", pl: "Battle Schedule", es:"Battle Schedule", tr: "Battle Schedule"},
		{ en: "Clan Wars Countdown:", ru: "Clan Wars Countdown:", cs: "Clan Wars Countdown:", de: "Clan Wars Countdown:", fr: "Clan Wars Countdown:", pl: "Clan Wars Countdown:", es:"Clan Wars Countdown:", tr: "Clan Wars Countdown:"},
		{ en: "Battle Count:", ru: "Battle Count:", cs: "Battle Count:", de: "Battle Count:", fr: "Battle Count:", pl: "Battle Count:", es:"Battle Count:", tr: "Battle Count:"},
		{ en: "Gold Income:", ru: "Gold Income:", cs: "Gold Income:", de: "Gold Income:", fr: "Gold Income:", pl: "Gold Income:", es:"Gold Income:", tr: "Gold Income:"},
		{ en: "Province", ru: "Провинция", cs: "Province", de: "Province", fr: "Province", pl: "Province", es:"Province", tr: "Province"},
		{ en: "Map", ru: "Игровая карта", cs: "Map", de: "Map", fr: "Map", pl: "Map", es:"Map", tr: "Map"},
		{ en: "Timezone", ru: "Timezone", cs: "Timezone", de: "Timezone", fr: "Timezone", pl: "Timezone", es:"Timezone", tr: "Timezone"},
		{ en: "Fame", ru: "Fame", cs: "Fame", de: "Fame", fr: "Fame", pl: "Fame", es:"Fame", tr: "Fame"},
		{ en: "Gold", ru: "Gold", cs: "Gold", de: "Gold", fr: "Gold", pl: "Gold", es:"Gold", tr: "Gold"},
		{ en: "Owner", ru: "Owner", cs: "Owner", de: "Owner", fr: "Owner", pl: "Owner", es:"Owner", tr: "Owner"},
		{ en: "ELO", ru: "ELO", cs: "ELO", de: "ELO", fr: "ELO", pl: "ELO", es:"ELO", tr: "ELO"},
		{ en: "Next Opponent", ru: "Next Opponent", cs: "Next Opponent", de: "Next Opponent", fr: "Next Opponent", pl: "Next Opponent", es:"Next Opponent", tr: "Next Opponent"},
		{ en: "Type", ru: "Type", cs: "Type", de: "Type", fr: "Type", pl: "Type", es:"Type", tr: "Type"},
		{ en: "Foes", ru: "Foes", cs: "Foes", de: "Foes", fr: "Foes", pl: "Foes", es:"Foes", tr: "Foes"},
		{ en: "Battles", ru: "Battles", cs: "Battles", de: "Battles", fr: "Battles", pl: "Battles", es:"Battles", tr: "Battles"},
		{ en: "Last Updated:", ru: "Last Updated:", cs: "Last Updated:", de: "Last Updated:", fr: "Last Updated:", pl: "Last Updated:", es:"Last Updated:", tr: "Last Updated:"},
		{ en: "Updating...", ru: "Updating...", cs: "Updating...", de: "Updating...", fr: "Updating...", pl: "Updating...", es:"Updating...", tr: "Updating..."},
		{ en: "See you next time.", ru: "See you next time.", cs: "See you next time.", de: "See you next time.", fr: "See you next time.", pl: "See you next time.", es:"See you next time.", tr: "See you next time."},
		{ en: "Not Started", ru: "Not Started", cs: "Not Started", de: "Not Started", fr: "Not Started", pl: "Not Started", es:"Not Started", tr: "Not Started"},
		{ en: "Ongoing", ru: "Ongoing", cs: "Ongoing", de: "Ongoing", fr: "Ongoing", pl: "Ongoing", es:"Ongoing", tr: "Ongoing"},
		{ en: "Planned", ru: "Planned", cs: "Planned", de: "Planned", fr: "Planned", pl: "Planned", es:"Planned", tr: "Planned"},
		{ en: "Defense", ru: "Defense", cs: "Defense", de: "Defense", fr: "Defense", pl: "Defense", es:"Defense", tr: "Defense"},
		{ en: "Owner", ru: "Owner", cs: "Owner", de: "Owner", fr: "Owner", pl: "Owner", es:"Owner", tr: "Owner"},
		{ en: "Attack", ru: "Attack", cs: "Attack", de: "Attack", fr: "Attack", pl: "Attack", es:"Attack", tr: "Attack"},
		{ en: "Free Round", ru: "Free Round", cs: "Free Round", de: "Free Round", fr: "Free Round", pl: "Free Round", es:"Free Round", tr: "Free Round"},
		{ en: "No Owner", ru: "No Owner", cs: "No Owner", de: "No Owner", fr: "No Owner", pl: "No Owner", es:"No Owner", tr: "No Owner"},
		{ en: "No Attacks", ru: "No Attacks", cs: "No Attacks", de: "No Attacks", fr: "No Attacks", pl: "No Attacks", es:"No Attacks", tr: "No Attacks"},
		{ en: "No Battles", ru: "No Battles", cs: "No Battles", de: "No Battles", fr: "No Battles", pl: "No Battles", es:"No Battles", tr: "No Battles"},
		{ en: "No Division", ru: "No Division", cs: "No Division", de: "No Division", fr: "No Division", pl: "No Division", es:"No Division", tr: "No Division"},
		{ en: "Division Data not Available!", ru: "Division Data not Available!", cs: "Division Data not Available!", de: "Division Data not Available!", fr: "Division Data not Available!", pl: "Division Data not Available!", es:"Division Data not Available!", tr: "Division Data not Available!"},
		{ en: "Clan ID Error", ru: "Clan ID Error", cs: "Clan ID Error", de: "Clan ID Error", fr: "Clan ID Error", pl: "Clan ID Error", es:"Clan ID Error", tr: "Clan ID Error"},
		{ en: "No Event Campaign", ru: "No Event Campaign", cs: "No Event Campaign", de: "No Event Campaign", fr: "No Event Campaign", pl: "No Event Campaign", es:"No Event Campaign", tr: "No Event Campaign"},
		{ en: "No Planned Battles", ru: "No Planned Battles", cs: "No Planned Battles", de: "No Planned Battles", fr: "No Planned Battles", pl: "No Planned Battles", es:"No Planned Battles", tr: "No Planned Battles"},
		{ en: "Hours", ru: "Hours", cs: "Hours", de: "Hours", fr: "Hours", pl: "Hours", es:"Hours", tr: "Hours"},
		{ en: "Mins", ru: "Mins", cs: "Mins", de: "Mins", fr: "Mins", pl: "Mins", es:"Mins", tr: "Mins"},
		{ en: "Secs", ru: "Secs", cs: "Secs", de: "Secs", fr: "Secs", pl: "Secs", es:"Secs", tr: "Secs"},
		{ en: "Event Only Schedule", ru: "Event Only Schedule", cs: "Event Only Schedule", de: "Event Only Schedule", fr: "Event Only Schedule", pl: "Event Only Schedule", es:"Event Only Schedule", tr: "Event Only Schedule"},
		{ en: "Currently Running", ru: "Currently Running", cs: "Currently Running", de: "Currently Running", fr: "Currently Running", pl: "Currently Running", es:"Currently Running", tr: "Currently Running"},
		{ en: "Concurrent Battles:", ru: "Concurrent Battles:", cs: "Concurrent Battles:", de: "Concurrent Battles:", fr: "Concurrent Battles:", pl: "Concurrent Battles:", es:"Concurrent Battles:", tr: "Concurrent Battles:"}
		// 60 localized strings
		// {en: "", ru: "", cs: "", de: "", fr: "", pl: "", es:"", tr: ""}
	];

	// region settings for external sites
	switch(wg.srv) {
		case ("eu"): // eu server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.wlf = sc.srv.ct = sc.srv.kttc = sc.srv.ch = sc.srv.wr = sc.srv.we = wg.srv;
			break;
		case ("ru"): // ru server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.ct = sc.srv.kttc = sc.srv.wots = sc.srv.ch = sc.srv.wr = wg.srv;
			break;
		case ("na"): // na server - american english
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.wlf = sc.srv.ct = sc.srv.kttc = sc.srv.ch = wg.srv; sc.srv.wr = "com";
			break;
		case ("asia"): // asia server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = "sea"; sc.srv.ct = sc.srv.kttc = sc.srv.ch = wg.srv; sc.srv.wr = "com";
			break;
		case ("kr"): // korean server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.cs = sc.srv.ct = sc.srv.ch = wg.srv; sc.srv.wr = "com";
			break;
		default: break;
	}

	// set script language to english if an unsupported language is detected
	var locMiss = 0;
	if (sc.locSup.indexOf(sc.loc) == -1) {
		sc.loc = "en";
	}

	// process localization
	for (var _l=0, l_len = loc.length; _l<l_len; _l++) {
		var langLoc = loc[_l][sc.loc];
		if (sc.loc !== "en" && langLoc == loc[_l].en && !loc[_l].i) {
			locMiss ++;
			console.info("Missing translation at line "+(_l+550)+" - en:\""+loc[_l].en+"\"", sc.loc+":\""+loc[_l][sc.loc]+"\"");
		}
		loc[_l] = langLoc;
	}

	// add language to body classname for language based styling
	d.body.classList.add("lang-"+sc.loc);

	// variables for dropbox, css and data uri
	var css = {
		u: {
			cIcons: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAACgCAMAAAAy5xwmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAK7UExURUxpcWV+bG+/jnacsI2z0I+z0JCzzqDAsqXAt6mwjrG/0rPAwr7BzL/D0sDBzdGli9Kyn////3qsYKWJZ1VTZS2Szlm3c1y7cmC5cWRoZWVrZ86LTdGOR9OKSS2RzS2Szi2Tzy+SzVm2c1m3c2C5cWVrZ4J/hc6LTc+NRtCNR9GbbCiU1F29eIGChdCOR9yGOh6R11e8c+KIOB6S2BSR3iGT2Uu+cVi8dPehhVBOlUqkxTyqwTYmS+rBihgYGEeyyUVUtciUVurTn5pNG/R0WTyqwdrhhaTM2Xcnqz+wyPT5+xkXFDFly/+BhRgXFUOxydurZv/0xykpKaBYHb7BzMXDy38axfvxhRsaGvhrBXAxlv+ChTNly77BzL7BzL/BzUCvyMXDy77BzMDF08PC0cXB0sXDy8jEy77BzMPB0M/i4L3D0cHBzrzG177BzL/Czb/CzS4oKP9rAEGvx/+Ghe3nzzCT0zJUoYfG5e7Eih8dHH8axf/nhUGxybzl9jFlyykpKXI1lMuXaWFoIv+Ahdj9hWKn1Nfp9PLs4RsZGv9sAaNdev+phT6txDJlzCopKaDqhf9/hb7BzGJgYWJiYduIPhyR1x+T2iGT2CKT2FS8cFa9dVe9dVi+dGZlZmZmZn8axduKQduKQ9yKQTyqwXAxltU5LiIgH+fIn77BzPVhCvrv1R+T2h+T2yGT2iKS1yKS2CKT2Fa9dVi+dGZkZmZmZtqJQ9qKQ9uJQ9uKQ9yKQdyLQeicAGJUZdfs+f9qACYmJh+T2iKT2Fa9dVi9dFi+dGZkZmZmZtuKQ9yLQb7BzH8axTJn0TyqwSEXFiQjIykoKDAiITgrKUUyMFBBN2tGQnAxlnen13h0a3lMR6LT66WZlbqRrr7BzL7Bzb/CzcDDrcTQ3OPSvuX2/Pb7/P758P9qAP/z2v///9BBknIAAADOdFJOUwAAAAAAAAAAAAAAAAAAAAAAAAEBBQoKCgoKCgoKCgsLCwsLCwsLCwsLCwsMDAwMDA0NDQ4PDw8PEBETFxgiLzE1OTk+QUROT1JVVVZXX2pvcXF2eHh5fX2AgIGBhoiJiYqMjY2NjY2Njo6Oj4+Tk5OUnJ+goaWqqqqqq6yztLS3ub29vsPExsbGysrQ0NHT1tfb4+Tk5OXl5eXl5eXl5eXl5eXl6Ojq6+3w8PH09PT09PT09PT09PT09PT09fb29vf4+Pj4+Pj4+Pj7/f7+oQ6AsQAABQ9JREFUSMe9lYlXG1UUh6/7vlTHfWnVKuK+m04niwKBNBC0qKQh1RG3WrUaAlVj0xgWZRAIdd9X0qlt3XcLJNZdCDNMJhGKUVuSlD/D+95MJkmPPfZ4PN4Db+793u/ed9/M4wHw72wpP5BIWIuxdWA4kXCAxWfEicRwDSyJ+GAJBcFEgl8KzOOyBW4hcQ3GDIkjDIzXIfAnhlHpk+XlUDf+GILhhB9guSzHMWP8TQR0gbgsRwDBOAU1RIAZOiDGReQIV9YrwzHwP5pXG0Mhr9dW7yVGwQQ1b0EVCg1SEAqxmh59CA3avCEU1QPQWW/9BFtPPU0wOFg/GCKKiZCeUjC9rq1g/912PNF0wehr9Rhh2kMFxfmo9p413xAwFHhshiCMIIodhnWBJw3pMKldpy2BD9CUTDRMvijWApqBWnJUMDFNihKffFvaEl2lTjsCUQOkaVY4XQRRXMKm9au3HmZ0QbSwOU+dsUF9+3SMevZ4N2Z72cli7END5lKA8ZAd7EVmMvfYe6Cnp5hm7zHZwdRTlDQ34ySzzm4U1dzmZmPRdVRs7kednczZ19Fypn4z/vabANq1ZKa9ARraW1rA1K2Xb2g3dVebNpiru/UGzN0N7Qy0EJHeYPeG6sKoWUs70TZsMBl7oB5j3vuR4VwBCzBun8X4k5QkJwJJdNF1uYAsBSwcZwlIopPUwhm3KyBGfK6AJFg4YAQp4BRHZ2fVuChLYgAsohSPy9Pq9LQsipLghoCEJivqrEqcAAdu8pSU6VGZAgYsApWoCp3AhRknZgrCaEQQ0CG9cW4s5XK7cGm9M5IUV+K4plu7QxiLG9XYgpMzbhOLS3A7LXu5U3xivMREH4hSicmyCPHSeHQ0UgYi4aeqNCDTjYjOFbE+CmRVJQ939eZ8jIJIV5dTkISqvrwO3Cs2r6jqamrL64BMxfpGRmI6wFro5UdG8hQIkg9rGRaDKh/NLYK+jRtjZSC2uSSBgny+HLTFyqxtn64Ydk+XLwLiWlne+Fdj9bNWYHl2QE9iB6w46eD9jiAlbNDh5x3A843+xiD5Swqiw/NgRYk1yDIMJqAAazT6g44g8H7Ah7+RJDt43sEGgyx5at+a5R28A394q/G5mQGGGWBLu7eSDvf1OuWESTzz2khNmJyclPSR2iQxfaQmUlcsAvQlY/xbmyoaRu4pmFIUZTapaCCAg5JMJrOzKuIpEAlNqqqaRZJUFJoOaiqVyiJJJhVAmQKpmZkZjFNqMglJQmcImE2lVDUJEQ2kUhgjUIHz6YoZQhFgH8o/vJva68rB+rEOzaldRmz1XK73Bg3smEfLzec69WvINkfA/CajwMMaeFQP12bnDdtSheCR+RLrJGuVArLs2pJ40/WkibHdTetzncuym6rmcjeSGnO5jrH53iezWzqyu+kyv84VMnK9TbTxJ3bt/HPnb7t2dKyu3afzseDIot307tMLykBr5pcysCpz+80FsGYNie856EAdtGYyK2/N3H3wZVdqYFXmtpWZ3+84/MLnX6RgVebeo4964L5jD7hq+3YCWjN3Hbr/YcdccMXxV7//EYIH/7jzkMuvOe7S594646z3CHjo/iMuevnVky756eeKRVsJuPi8/a797tvFlV9tq1hEFc8+c8rZn3y8uPKLbRULt36I4Mcfzj0HwfmfE/ABgs8+paDyy68rzqQ1iOJ7rIFFF35D+njj9VNPfO2Vk09/+53TTnjhpQV/AasrpIaeUd4CAAAAAElFTkSuQmCC",
			arrow: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAECAMAAAB1GNVPAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAPUExURf///////////0xpcf///17pIXYAAAAEdFJOU393iAAiK7rGAAAAH0lEQVQI1w3GwQEAMBBEQBf6rzn7YeipxA0bXoU4LB8EgABGoTqNxwAAAABJRU5ErkJggg=="
		},
		i: {
			loader: "/clans/static/2.2.8/images/processing/loader.gif",
			arrow: "http://static-ptl-eu.gcdn.co/static/wot/common/css/scss/content/links/img/orange_arrow.png"
		}
	};

	// style contents
	var styleClan = [
		// fix width for header with low resolution
		".search-form__place-header {width: 30%;}",
		".search-form__place-header.search-form__state-on {width: 410px;}",
		// loading text
		".processing_loader span {display: table; margin: 0 auto;}",
		// links menu rules
		".menu-clan_links {padding: 0;}",
		".menu-clan_links.cm-parent-link__opened {border: 1px solid #313335;}",
		".menu-clan_links .menu-top_link {cursor: pointer; padding: 0 8px 0 9px;}",
		".menu-clan_links .menu-top_link.cm-parent-link__opened {background: #0E0E0E; border-left: 1px solid #313335; border-right: 1px solid #313335; margin-left: -1px;}",
		".menu-clan_links .cm-arrow {background-image: url('"+css.u.arrow+"'); display: inline-block; margin-left: 5px; opacity: 0.5; vertical-align: middle; transition: opacity 0.2s ease 0s; height: 4px; width: 7px;}",
		".menu-clan_links .cm-parent-link__opened .cm-arrow {opacity: 1; transform: rotate(180deg);}",
		".menu-clan_links .clan-links {background: rgba(14, 14, 14, 0.99); border: 1px solid #313335; display: none; box-shadow: 0px 0px 25px rgba(0, 0, 0, 0.4); margin-left: -1px; padding: 14px 16px; position: absolute;}",
		".menu-clan_links .cm-sublist__opened {display: block;}",
		".menu-clan_links .clan-links td {padding: 0 10px;}",
		".sl-icon {background: url('"+css.u.cIcons+"') no-repeat; display: inline-block; margin: -2px 8px 0px 0px; vertical-align: middle; height: 16px; width: 16px;}",
		".sl-wl {background-position: 0px 0px;}",
		".sl-nm {background-position: 0px -16px;}",
		".sl-ct {background-position: 0px -32px;}",
		".sl-cs {background-position: 0px -48px;}",
		".sl-kttc {background-position: 0px -64px;}",
		".sl-wlife {background-position: 0px -80px;}",
		".sl-as {background-position: 0px -96px;}",
		".sl-wr {background-position: 0px -112px;}",
		".sl-vb {background-position: 0px -128px;}",
		".sl-we {background-position: 0px -144px;}",
		// rating profile rules
		".rating-profile {width: 70%; margin: 0px auto;}",
		// settings menu rules
		"#common_menu .menu-settings {color: #7C7E80; display: inline-block;}",
		"#common_menu .menu-settings .cm-user-menu-link {margin: 0 10px 0 0;}",
		"#common_menu .menu-settings .cm-user-menu-link_cutted-text {max-width: unset;}",
		"#common_menu .menu-settings .cm-user-menu {min-width: 200px; padding: 15px;}",
		"#common_menu .menu-settings .cm-parent-link:hover {cursor: pointer;}",
		"#common_menu .menu-settings .b-settingItem {margin: 6px 0px; text-align: center;}",
		"#common_menu .menu-settings label {display: table; line-height: normal; cursor: pointer; margin: 0 auto;}",
		"#common_menu .menu-settings .l-box {display: none;}",
		"#common_menu .menu-settings .b-checkbox {height: 16px; width: 16px; float: left; margin-right: 5px;}",
		"#common_menu .menu-settings .b-checkbox span {height: 16px; width: 16px;}",
		"#common_menu .menu-settings .b-combobox-label__checked {color: #DCDCDC;}",
		"#common_menu .menu-settings .b-settingItem .b-combobox-label:hover {color: #DCDCDC;}",
		"#common_menu .menu-settings .b-settingItem .b-combobox-label:hover .b-checkbox {background-position: 0px -34px; box-shadow: 0px 0px 10px 1px rgba(191, 166, 35, 0.15), 0px 0px 3px 1px rgba(191, 166, 35, 0.25);}",
		"#common_menu .menu-settings .b-settingItem .b-combobox-label:hover .b-checkbox.b-checkbox__checked {background-position: 0px -68px;}",
		"#common_menu .menu-settings textarea.l-textarea {background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 2px; color: #FFFFFF; line-height: normal; padding: 5px; min-height: 50px; margin: 5px 0 5px 0; min-width: 175px;}",
		"#common_menu .menu-settings textarea::-webkit-input-placeholder {color: #FFFFFF;}",
		"#common_menu .menu-settings textarea::-moz-placeholder {color: #FFFFFF;}",
		"#common_menu .menu-settings .b-settingParent {line-height: 26px;}",
		"#common_menu .menu-settings .b-settingParent a {cursor: pointer; color: #B1B2B3; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);}",
		"#common_menu .menu-settings .b-settingParent a:hover {color: #FFFFFF; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75); text-decoration: underline;}",
		"#common_menu .menu-settings .settingCredits {margin: 2px 0px;}",
		"#common_menu .menu-settings .settingCredits h1 {color: #B1B2B3;}",
		"#common_menu .menu-settings .settingCredits table {font-size: 12px; margin: 0 auto; width: unset;}",
		"#common_menu .menu-settings .settingCredits table td {padding: 0 5px;}",
		"#common_menu .menu-settings .settingCredits p {font-size: 12px; padding: 2px 0;}",
		"#common_menu .menu-settings .settingCredits .b-orange-arrow {background: url('"+css.i.arrow+"') 100% 0 no-repeat; color: #F25322; line-height: 14px; padding-right: 9px;}",
		"#common_menu .menu-settings .settingCredits .b-orange-arrow:hover {color: #FF7432;}",
		"#common_menu .menu-settings .settingCredits.settingSeperator {border-top: 1px dashed #212123; margin-top: 6px; padding-top: 12px;}",
		"#common_menu .menu-settings .settingCredits.settingSeperator.b-wnRefresh {margin-top: 11px; padding-top: 6px;}",
		"#common_menu .menu-settings .settingCredits.settingLinks a {margin: 0 5px;}",
		// memberpage rules
		".page-header {padding: 30px 0 30px 75px}",
		".page-header_meminfo {display: table; margin: 0px auto; position: absolute; top: 3px; right: 0px; left: 0px; text-align: center;}",
		".page-header_meminfo span {margin: 0 5px;}",
		".page-header_ban {color: #E5B12E;}",
		".page-header_mem {color: #E5B12E;}",
		".js-page-header-view .page-header_mem {margin-left: 25px;}",
		// button fetch rules
		".b-button-stats {border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 2px; position: absolute; right: 0; top: 9px;}",
		".b-button-stats a {background: rgba(255, 255, 255, 0.1); color: #FFFFFF; cursor: pointer; font-size: 17px; line-height: 45px; display: block; padding: 0px 15px; transition: all 0.2s ease 0s;}",
		".b-button-stats a:hover {background: rgba(229, 177, 46, 0.25);}",
		// rating players rules
		".rating-players {height: 200px;}",
		".rating-players tbody {width: 95%; display: table; margin: 0px auto;}",
		".rating-players_item__data {padding-top: 25px; width: 14%;}",
		".rating-players_item__average {padding-top: 10px; width: 16%;}",
		".rating-players_stats {font-size: 40px;}",
		// membertable rules
		".js-expander-link-view {display: table; position: absolute; top: 333px;}",
		"#js-playerslist-table {margin-top: 7px;}",
		".tbl-rating_th__wn a {cursor: pointer;}",
		".player_time {position: absolute; right: 0; top: 18px;}"
	];
	style.textContent = styleClan.join("");
	// end style

	// add animated loading icon for progress indication
	var layoutHolder = d.getElementsByClassName('layout_holder')[0],
	loadGif = sf.elem("div", "processing js-hidden", "<div class='processing_loader'><img src='"+css.i.loader+"' alt='Processing...'><span id='js-wn8-status'></span></div>");
	layoutHolder.appendChild(loadGif);

	// script link and settings
	var clanSet_div = sf.elem("div", "menu-settings menu-top_item", "<a class='cm-user-menu-link' href='#' onClick='return false;'><span class='cm-user-menu-link_cutted-text'>"+loc[3]+"</span><span class='cm-arrow'></span></span>"),
	clanSet_list = sf.elem("ul", "cm-user-menu", ""),
	clanSet_list_locItem = sf.elem("li", "b-settingItem settingCredits settingSeperator", ""),
	enableOnPageload = sf.storage("statScript_onPageload", "", "get", "parse"),
	enableWhitelist = sf.storage("statScript_whitelist", "", "get", "parse"),
	enableWhiteList_list = sf.storage("statScript_whitelist_list", "", "get"),
	enableEventOnly = sf.storage("statScript_eventOnly", "", "get", "parse"),
	whiteListArray = (enableWhiteList_list) ? enableWhiteList_list.split(",") : "",
	clanSet_list_items = [
		sf.settings("onPageload", loc[4], enableOnPageload, false),
		sf.settings("whitelist", loc[5], enableWhitelist, false, enableWhiteList_list),
		sf.settings("eventOnly", loc[58], enableEventOnly, false),
		sf.settings("wnRefresh", loc[6]+" [v"+wn.vers[1]+"]"),
		sf.settings("cleanStorage", loc[7]),
		sf.elem("li", "b-settingItem settingCredits settingSeperator", "<p>Version: "+sc.vers+"</p>"),
		sf.elem("li", "b-settingItem settingCredits", "<p>"+loc[20]+" <a class='b-orange-arrow' href='"+sc.user.wot+"'>Orrie</a></p>"+((sc.cred[sc.loc]) ? "<p>"+loc[21]+" ("+sc.loc.toUpperCase()+"):</p><table>"+sc.cred[sc.loc]+"</table>" : "")),
		sf.elem("li", "b-settingItem settingCredits settingLinks", "<p><a class='b-orange-arrow' href='"+sc.host+"'>Greasy Fork</a><a class='b-orange-arrow' href='"+((wg.srv == "na") ? sc.top.na : sc.top.eu)+"'>Support Thread</a></p>")
	];
	if (sc.locSup.indexOf(sc.loc) == -1) {
		clanSet_list_locItem.innerHTML = "<h1>Script Translation</h1><p>Unsupported language detected!</p><p>If you want to contribute with translation, please contact <a class='b-orange-arrow' href='"+sc.user.wl+"'>Orrie</a></p>";
		clanSet_list_items.push(clanSet_list_locItem);
	}
	else if (locMiss > 0) {
		clanSet_list_locItem.innerHTML = "<h1>Script Translation</h1><p>Currently "+locMiss+" out of "+_l+" strings not translated in your language!</p><p>If you want to contribute, open the browser console, translate the strings and send them to <a class='b-orange-arrow' href='"+sc.user.wl+"'>Orrie</a></p>";
		clanSet_list_items.push(clanSet_list_locItem);
	}
	sf.links(clanSet_list, clanSet_list_items);
	clanSet_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-user-menu-link__opened'); this.nextSibling.classList.toggle('cm-user-menu__opened');}, false);
	clanSet_div.appendChild(clanSet_list);
	// add script info and settings if user menu exists, else wait
	var navMenu = d.getElementById('common_menu'),
	navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
	if (navUser) {
		navUser.appendChild(clanSet_div);
	}
	else {
		var setLook = new MutationObserver(function() {
			navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
			navUser.appendChild(clanSet_div);
			setLook.disconnect();
		});
		setLook.observe(navMenu, {childList: true});
	}

	// clan statistic links
	var menu_class = d.getElementsByClassName('menu-top')[0],
	clanMenu_div = sf.elem("div", "menu-clan_links menu-top_item", "<span class='menu-top_link'>"+loc[1]+"<span class='cm-arrow'></span></span>"),
	clanMenu_list = sf.elem("ul", "clan-links cm-sublist", ""),
	clanMenu_list_items = [
		[sc.srv.wl, "<a target='_blank' href='http://wotlabs.net/"+sc.srv.wl+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wl'></span>WoTLabs</a>"],
		[sc.srv.nm, "<a target='_blank' href='http://noobmeter.com/clan/"+sc.srv.nm+"/"+wg.clan.name+"/"+wg.clan.id+"'><span class='sl-icon sl-nm'></span>Noobmeter</a>"],
		[sc.srv.vb, "<a target='_blank' href='http://vbaddict.net/clan/worldoftanks."+sc.srv.vb+"/"+wg.clan.id+"/clan-"+wg.clan.name.toLowerCase()+"'><span class='sl-icon sl-vb'></span>vBAddict</a>"],
		[sc.srv.ct, "<a target='_blank' href='http://clantools.us/servers/"+sc.srv.ct+"/clans?id="+wg.clan.id+"'><span class='sl-icon sl-ct'></span>Clan Tools</a>"],
		[sc.srv.cs, "<a target='_blank' href='http://wotcs.com/clan.php?wid="+wg.clan.id+"'><span class='sl-icon sl-cs'></span>WoT-CS</a>"],
		[sc.srv.kttc, "<a target='_blank' href='http://"+((wg.srv=="ru") ? "" : sc.srv.kttc+".")+"kttc.ru/clan/"+wg.clan.id+"/'><span class='sl-icon sl-kttc'></span>KTTC</a>"],
		[sc.srv.wlf, "<a target='_blank' href='http://en.wot-life.com/"+sc.srv.wlf+"/clan/"+wg.clan.name+"-"+wg.clan.id+"/'><span class='sl-icon sl-wlife'></span>WoT-Life</a>"],
		[sc.srv.we, "<a target='_blank' href='http://wotevent.guildity.com/clans/"+wg.clan.name+"/'><span class='sl-icon sl-we'></span>WoT Event Stats</a>"],
		[sc.srv.wr, "<a target='_blank' href='http://wotreplays."+sc.srv.wr+"/clan/"+wg.clan.name+"'><span class='sl-icon sl-wr'></span>WoTReplays</a>"]
	];
	sf.links(clanMenu_list, clanMenu_list_items);
	clanMenu_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-parent-link__opened'); this.nextSibling.classList.toggle('cm-sublist__opened');}, false);
	clanMenu_div.appendChild(clanMenu_list);
	menu_class.appendChild(clanMenu_div);

	// add clan total stats if they exist
	if (wg.p && s.clan) {
		var clanProfileValue = d.getElementsByClassName('rating-profile_item');
		if (s.clan.win) {
			clanProfileValue[1].innerHTML = "<i class='rating-profile_icon i i__rating-common i__wot-victories'></i><span class='rating-profile_value rating-players_stats js-format-number'>"+sf.color(s.clan.win,"wr",2,"%")+"</span><span class='rating-profile_key'>"+loc[8]+"</span>";
		}
		if (s.clan.wn8) {
			clanProfileValue[3].innerHTML = "<i class='rating-profile_icon i i__rating-common i__wot-experience'></i><span class='rating-profile_value rating-players_stats js-format-number'>"+sf.color(s.clan.wn8,"wn8",0)+"</span><span class='rating-profile_key'>"+loc[9]+"</span>";
		}
	}

	// check if on memberlist page
	if (wg.m) {
		// formula calculations and variables
		var memObj = {
			cls: d.getElementsByClassName('tbl-rating_body')[0],
			ids: [],
			bans: {ids:[],f:false}
		};

		// add manual stat fetching button
		var filter_class = d.getElementsByClassName('filter')[0],
		refreshBtn_div = sf.elem("div", "b-button-stats", "<a>"+loc[12]+"</a>");
		refreshBtn_div.addEventListener('click', function() {sf.tableFetch();}, false);
		filter_class.appendChild(refreshBtn_div);

		// prepare stat fetcher, store stats in localStorage and reload page
		var ratLook = new MutationObserver(function() {
			sf.tableFetch();
			ratLook.disconnect();
		});

		// fetch stats automatically if enabled or check whitelist for whitelisted clan
		if (statFetch && (enableOnPageload || (enableWhitelist && whiteListArray.indexOf(wg.clan.id) > -1))) {
			ratLook.observe(memObj.cls, {childList: true});
		}
		else {
			// no stats fetching, check if stats already exist and add if they do
			var clanPlayersValue = d.getElementsByClassName('rating-players')[0].rows[0],
			pageHeader = d.getElementsByClassName('page-header')[0],
			ratHeadStatus = false;
			// add clan total stats if they exist
			clanPlayersValue.cells[1].getElementsByClassName('rating-players_key')[0].textContent = loc[8];
			if (s.clan) {
				if (s.clan.win) {
					var clanWinCell = clanPlayersValue.insertCell(2);
					clanWinCell.className = "rating-players_item rating-players_item__data";
					clanWinCell.innerHTML = "<i class='rating-players_icon i i__rating-common i__wot-victories'></i><span class='rating-players_value rating-players_stats'>"+sf.color(s.clan.win,"wr",2,"%")+"</span><span class='rating-players_key'>"+loc[10]+"</span>";
				}
				if (s.clan.wn8) {
					var clanWn8Cell = clanPlayersValue.insertCell(4);
					clanWn8Cell.className = "rating-players_item rating-players_item__data";
					clanWn8Cell.innerHTML = "<i class='rating-players_icon i i__rating-common i__wot-experience'></i><span class='rating-players_value rating-players_stats'>"+sf.color(s.clan.wn8,"wn8",0)+"</span><span class='rating-players_key'>"+loc[11]+"</span>";
				}
			}
			// add container for member counters
			var memInfo_div = sf.elem("div", "page-header_meminfo", "");
			pageHeader.appendChild(memInfo_div);
			// wait for table to be filled before adding wn8
			var ratInsert = new MutationObserver(function(muto) {
				if (muto[0].previousSibling === null) {
					var newMem = 0, banMem = d.getElementsByClassName('tbl-rating_tr__state-banned').length;
					// add a counter for amount of banned people in clan
					if (banMem > 0) {
						var banMem_span = d.getElementsByClassName('page-header_ban')[0];
						if (!banMem_span) {
							banMem_span = sf.elem("span", "page-header_ban", loc[17]+" "+banMem);
							memInfo_div.appendChild(banMem_span);
						}
						else {
							banMem_span.textContent = loc[17]+" "+banMem;
						}
					}
					// table header for wn8
					if (ratHeadStatus === false && Object.keys(s.clan).length !== 0) {
						var headName = d.getElementsByClassName('tbl-rating_th__name')[0],
						wnHead = sf.elem("td", "tbl-rating_th tbl-rating_th__wn", "<a class='sorter sorter__game-wot js-table-sorter js-sort-wn'><i class='sorter_icon sorter_icon__media i i__table-params i__wot-aeb'></i><span class='sorter_key'>WN8</span><span class='sorter_arrow'></span></a>"),
						colGroup = d.getElementsByTagName('colgroup')[0],
						newCol = sf.elem("col");
						newCol.width = "1px";
						headName.parentNode.insertBefore(wnHead, headName.nextSibling);
						colGroup.insertBefore(newCol, colGroup.children[5]);
						ratHeadStatus = true;
					}
					// add wn8 for each member and colorize stats
					var userCheck = Object.keys(s.user).length !== 0;
					for (var _rt=0, _rt_len = memObj.cls.rows.length; _rt<_rt_len; _rt++) {
						var row = memObj.cls.rows[_rt];
						if (!row.classList.contains("tbl-rating_tr__card")) {
							var id = row.getAttribute('data-account_id'),
							memName = row.getElementsByClassName('tbl-rating_td__name')[0],
							memWGR = row.getElementsByClassName('tbl-rating_td__value')[0],
							memWins = row.getElementsByClassName('tbl-rating_td__value')[2];
							if (userCheck) {
								var wnRow = sf.elem("td", "tbl-rating_td tbl-rating_td__value js-format-number", "");
								memName.parentNode.insertBefore(wnRow, memName.nextSibling);
								if (s.user[id]) {
									wnRow.innerHTML = sf.color(s.user[id].wn8,"wn8",0);
								}
								else {
									wnRow.innerHTML = loc[15];
									newMem ++;
								}
							}
							if (memWGR.innerHTML !== "0" && memWGR.innerHTML !== "—") {
								memWGR.innerHTML = sf.color(sf.format(memWGR.innerHTML,1),"wgr",0);
							}
							if (memWins.innerHTML !== "0.00%" && memWins.innerHTML !== "—") {
								memWins.innerHTML = sf.color(sf.format(memWins.innerHTML.replace(/[,]/g,"."),3),"wr",2,"%");
							}
						}
					}
					// add a counter for new people in the clan, compared to store stats
					if (newMem > 0) {
						var newMem_span = d.getElementsByClassName('page-header_mem')[0];
						if (!newMem_span) {
							newMem_span = sf.elem("span", "page-header_mem", loc[16]+" "+newMem);
							memInfo_div.appendChild(newMem_span);
						}
						else {
							newMem_span.textContent = loc[16]+" "+newMem;
						}
					}
					// check for length on bans
					if (memObj.bans.f) {
						sf.apiBanHnd();
					}
					else {
						memObj.bans.cls = d.getElementsByClassName('js-banned');
						for (var _bm=0, _bm_len = memObj.bans.cls.length; _bm<_bm_len; _bm++) {
							var bannedId = memObj.bans.cls[_bm].dataset.account_id;
							memObj.bans.ids.push(bannedId);
						}
						if (memObj.bans.ids.length > 0) {
							sc.api.b = sc.api.i+memObj.bans.ids.join(',')+"&fields=ban_time";
							sf.request(sc.api.b , sf.apiBanHnd);
						}
					}
				}
			});
			ratInsert.observe(memObj.cls, {childList: true});
		}
	}
	else if (wg.g) {
		// global variables
		var date = new Date();

		// script variables
		var cw_sc = {
			cw: {
				status: enableEventOnly,
				event: false,
				fame: 400,
				tier: "--",
				bats: "--",
				batsConc: [],
				batsCheck: 0,
				elo: "--",
				gold: 0
			},
			clan: {
				id: wg.clan.id,
				tag: "--",
				emblem: "--"
			},
			time: {
				h: date.getHours(),
				m: date.getMinutes(),
				o: ((date.getTimezoneOffset() > 0) ? -Math.abs(date.getTimezoneOffset()) : Math.abs(date.getTimezoneOffset()))/60
			},
			table: {
				eu: [17, 18, 19, 20, 21, 22, 23],
				na: [1, 2, 3, 4, 5, 6, 7, 8],
				ru: [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
				c: "",
				s: []
			},
			debug: false
		};
		cw_sc.api = {
			clan: "https://"+wg.srv+".wargaming.net/globalmap/game_api/clan/"+cw_sc.clan.id+"/battles",
			divs: "https://"+wg.srv+".wargaming.net/globalmap/game_api/wot/clan_tactical_data",
			map: "https://"+wg.srv+".wargaming.net/globalmap/game_api/map_fill_info?aliases=",
			tourney: "https://"+wg.srv+".wargaming.net/globalmap/game_api/tournament_info?alias=",
			prov: "https://"+wg.srv+".wargaming.net/globalmap/game_api/province_info?alias=",
			event: "https://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/globalmap/events/?application_id="+sc.api[wg.srv]+"&limit=1",
			provs: "https://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/globalmap/clanprovinces/?application_id="+sc.api[wg.srv]+"&clan_id="+cw_sc.clan.id
		};
		cw_sc.time.r = ((cw_sc.time.m >= 15 && cw_sc.time.m <= 45) ? [cw_sc.time.h,"30"] : ((cw_sc.time.m <= 15) ? [cw_sc.time.h,"00"] : [(cw_sc.time.h+1),"00"]));
		cw_sc.time.t = cw_sc.time.r[0]+"_"+cw_sc.time.r[1];

		// images, streams and functions
		var cw_sf = {
			handlerEvent: function(data) { // event checker
				// check if active event exists
				var event = data.data[0];
				if (event.status == "ACTIVE" || !cw_sc.cw.status) {
					if (event.status == "ACTIVE") {
						cw_sc.cw.event = true;
					}
					cw_sf.request("mainData", cw_sc.api.clan, cw_sf.handlerMain);
				}
				else {
					// empty table
					table.lastElementChild.innerHTML = "";
					table.lastElementChild.appendChild(sf.elem("tr", "t-cwText", "<td colspan='10'>"+loc[39]+"</td>"));
					clearInterval(updateInterval);
				}
				// insert update timestamp
				d.getElementById('js-batttleUpdate').textContent = new Date().toLocaleTimeString("en-GB");
			},
			handlerMain: function(data) { // data handler
				var battleProvinces = [], battle,
				battleFragment = d.createDocumentFragment();
				// store data
				cw_sc.clan.tag = data.clan.tag;
				cw_sc.clan.emblem = data.clan.emblem_url;
				cw_sc.cw.bats = data.clan.appointed_battles_count;
				cw_sc.cw.elo = {
					6: data.clan.elo_rating_6,
					8: data.clan.elo_rating_8,
					10: data.clan.elo_rating_10
				};
				// go through battles and planned battles
				for (var _b=0, _b_len = data.battles.length; _b<_b_len; _b++) {
					battle = data.battles[_b];
					if (battleProvinces.indexOf(battle.province_id) == -1) {
						battleProvinces.push(battle.province_id);
						battleFragment.appendChild(sf.elem("tr", "battle "+battle.province_id, "<td><a class='link__external' target='_blank' href='https://"+wg.srv+".wargaming.net/globalmap/#province/"+battle.province_id+"'>"+battle.province_name+"</a></td><td>"+battle.arena_name+"</td><td></td><td></td><td></td><td></td><td id='"+battle.enemy.id+"'><a target='_blank' href='http://"+wg.srv+".wargaming.net/clans/"+battle.enemy.id+"/'>["+battle.enemy.tag+"] <img src='"+battle.enemy.emblem_url+"'></a></td><td>--</td><td>--</td><td class='t-border'>--</td>"+cw_sc.table.c));
					}
				}
				for (var _bp=0, _bp_len = data.planned_battles.length; _bp<_bp_len; _bp++) {
					battle = data.planned_battles[_bp];
					if (battleProvinces.indexOf(battle.province_id) == -1) {
						battleProvinces.push(battle.province_id);
						battleFragment.appendChild(sf.elem("tr", "battle "+battle.province_id, "<td><a class='link__external' target='_blank' href='https://"+wg.srv+".wargaming.net/globalmap/#province/"+battle.province_id+"'>"+battle.province_name+"</a></td><td>"+battle.arena_name+"</td><td></td><td>"+((cw_sc.cw.event) ? "" : battle.province_revenue)+"</td><td></td><td></td><td>"+loc[40]+"</td><td>--</td><td>--</td><td class='t-border'>--</td>"+cw_sc.table.c));
					}
				}
				if (cw_sc.cw.bats > 0 && table.rows[1] && table.rows[1].classList.contains("t-cwText")) {
					table.lastElementChild.innerHTML = ""; // empty table
				}
				table.lastElementChild.appendChild(battleFragment);
				// insert battle count
				d.getElementById('js-battles').textContent = cw_sc.cw.bats;
				// send request for detailed battle information
				cw_sf.request("batsData", cw_sc.api.map+battleProvinces.join("&aliases="), cw_sf.handlerBats);
			},
			handlerBats: function(data) { // battles handler
				for (var _bd=0, _bd_len = data.data.length; _bd<_bd_len; _bd++) {
					var battle = data.data[_bd],
					battleRow = d.getElementsByClassName(battle.alias)[0],
					enemyID = battleRow.children[6].id,
					battleType = ((battle.owner_clan_id == cw_sc.clan.id) ? loc[43] : ((battle.owner_clan_id == enemyID) ? loc[44] : loc[45])),
					primeTime = [cw_sf.time(parseFloat(battle.primetime.match(/\d+/g)[0])), battle.primetime.match(/\d+/g)[1], parseFloat(battle.primetime.match(/\d+/g)[0])];
					// modify cells cells
					battleRow.children[2].textContent = primeTime[0]+":"+primeTime[1];
					battleRow.children[2].dataset.sort = primeTime[2];
					battleRow.children[3].innerHTML = (cw_sc.cw.event) ? battle.display_fame_points : "<span class='gold'>"+battle.revenue+"</span>";
					battleRow.children[5].textContent = battle.owner_clan_rating;
					battleRow.children[7].textContent = battleType;
					// get correct battle count and schedule
					cw_sf.request("tourneyData", cw_sc.api.tourney+battle.alias+"&round=1", cw_sf.handlerTourney);
				}
				// send request for clan provinces
				cw_sf.request("provData", cw_sc.api.provs+"&round=1", cw_sf.handlerProv);
				// refresh table
				sortTable.refresh();
			},
			handlerTourney: function(data) { // tournament handler
				var battleRow = d.getElementsByClassName(data.province_id)[0],
				primeTime = [cw_sf.time(parseFloat(data.start_time.match(/\d+/g)[0])), data.start_time.match(/\d+/g)[1], parseFloat(data.start_time.match(/\d+/g)[0])],
				ownerClan = (data.owner) ? (data.owner.id == cw_sc.clan.id) || false : false,
				cellOwnerTime = false,
				provFame = cw_sc.cw.fame*((data.owner) ? (Math.floor(data.owner.occupy/24)+1) : 1),
				attackers = [data.pretenders, 0];
				cw_sc.cw.batsCheck ++;
				// check attackers
				if (data.is_superfinal) {
					attackers = 1;
				}
				else if (attackers[0]) {
					attackers = attackers[0].length;
				}
				else {
					for (var _bc=0, _bc_len = data.battles.length; _bc<_bc_len; _bc++) {
						attackers[1] += ((data.battles[_bc].is_fake) ? 1 : 2);
					}
					attackers = attackers[1];
				}
				// find how many battles
				var battles = (attackers !== 0) ? Math.ceil(Math.log2(attackers))+1 : 0;
				// modify cells
				battleRow.children[1].textContent = data.arena_name;
				battleRow.children[2].textContent = primeTime[0]+":"+primeTime[1];
				battleRow.children[3].innerHTML = (cw_sc.cw.event) ? provFame : "<span class='gold'>"+data.province_revenue+"</span>";
				battleRow.children[4].innerHTML = (data.owner) ? "<a target='_blank' href='http://"+wg.srv+".wargaming.net/clans/"+data.owner.id+"/'>["+data.owner.tag+"] <img src='"+data.owner.emblem_url+"'></a>" : loc[47];
				if (ownerClan) {
					cw_sc.cw.gold += data.province_revenue;
					d.getElementById('js-gold').textContent = sf.format(cw_sc.cw.gold,2); // insert gold count
					if (cw_sc.cw.tier !== "--") {
						battleRow.children[5].textContent = data.owner["elo_rating_"+cw_sc.cw.tier];
					}
				}
				// only continue if there are any attackers
				if (attackers) {
					var cellEmpty = {
						eu: {20:15, 19:13, 18:11, 17:9},
						na: {5:17, 4:15, 3:13, 2:11, 1:9},
						ru: {20:31, 19:29, 18:27, 17:25, 16:23, 15:21, 14:19, 13:17, 12:15, 11:13, 10:11, 9:9},
					},
					lastBattle = battles+cellEmpty[wg.srv][primeTime[2]];
					battleRow.children[8].textContent = attackers;
					battleRow.children[9].textContent = battles;
					for (var _e=10; _e<battleRow.childElementCount; _e++) {
						var cell = battleRow.children[_e];
						if (cell.classList.item(1) == "t-0_00") {
							cell.classList.add("t-24_00");
						}
						if (_e > cellEmpty[wg.srv][primeTime[2]] && _e <= lastBattle) {
							var timeClass = "."+cell.classList.item(1);
							if (cw_sc.table.s.indexOf(timeClass) == -1) {
								cw_sc.table.s.push(timeClass);
								if (_e == lastBattle) {
									cw_sc.table.s.push(timeClass+" + th", timeClass+" + td");
								}
							}
							if (ownerClan && _e !== lastBattle) {
								cell.className += " t-noFight";
							}
							else {
								cell.className += " t-fight";
								if (cw_sc.cw.batsConc[_e]) {
									cw_sc.cw.batsConc[_e] ++;
								}
								else {
									cw_sc.cw.batsConc[_e] = 1;
								}
							}
							if (_e == lastBattle) {
								if (ownerClan) {
									cell.className += " js-last";
								}
								if (!data.owner) {
									cell.className += " t-noOwner";
								}
								cell.innerHTML = "♖";
								cellOwnerTime = [parseFloat(cell.classList.item(1).match(/\d+/g)[0]), parseFloat(cell.classList.item(1).match(/\d+/g)[1])];
							}
							else {
								cell.innerHTML = "&#9876;";
							}
						}
					}
					if (cw_sc.cw.batsCheck == cw_sc.cw.bats) {
						d.getElementById('js-battlesConc').textContent = cw_sc.cw.batsConc.sort(function(a,b){return b-a;})[0];
						style.textContent += cw_sc.table.s.join(", ")+" {display: table-cell !important;}";
					}
					// check if battle is planned or not started and change state to ongoing
					if ((battleRow.children[7].innerHTML == loc[42] || battleRow.children[6].innerHTML == loc[40]) && new Date().getHours() >= primeTime[0]-1 && new Date().getHours() < cellOwnerTime[0]) {
						battleRow.children[6].textContent = loc[41];
						battleRow.children[7].textContent = loc[43];
					}
					// check if no opponent - free round
					var lastBattle = data.battles[data.battles.length-1];
					if (battleRow.children[6].innerHTML == loc[40] && lastBattle && lastBattle.is_fake && lastBattle.first_competitor.id == cw_sc.clan.id) {
						battleRow.children[6].textContent = loc[46];
						battleRow.children[6].classList.add("t-bold");
					}
				}
				else {
					battleRow.children[8].textContent = "ERROR";
					battleRow.children[8].classList.add("t-error");
				}
				// refresh table
				battleRow.children[2].dataset.sort = primeTime[2]+"."+((battleRow.children[7].innerHTML == loc[45]) ? 0+""+battles : 1+""+cellOwnerTime[0]+""+cellOwnerTime[1]);
				sortTable.refresh();
			},
			handlerProv: function(data) { // provinces handler
				var provs = data.data[cw_sc.clan.id],
				provFragment = d.createDocumentFragment();
				if (table.rows[1] && table.rows[1].classList.contains("t-cwText")) {
					table.lastElementChild.innerHTML = ""; // empty table
				}
				if (provs) {
					for (var _p=0, _p_len = provs.length; _p<_p_len; _p++) {
						var prov = provs[_p],
						battleRow = d.getElementsByClassName(prov.province_id)[0],
						primeTime = [cw_sf.time(parseFloat(prov.prime_time.match(/\d+/g)[0])), prov.prime_time.match(/\d+/g)[1], parseFloat(prov.prime_time.match(/\d+/g)[0])+3],
						provFame = 400*(Math.floor(prov.turns_owned/24)+1);
						if (!battleRow) {
							provFragment.appendChild(sf.elem("tr", "province "+prov.province_id, "<td><a class='link__external' target='_blank' href='https://"+wg.srv+".wargaming.net/globalmap/#province/"+prov.province_id+"'>"+prov.province_name+"</a></td><td>"+prov.arena_name+"</td><td data-sort='"+primeTime[2]+"'>"+primeTime[0]+":"+primeTime[1]+"</td><td>"+((cw_sc.cw.event) ? provFame : "<span class='gold'>"+prov.daily_revenue+"</span>")+"</td><td><a target='_blank' href='http://"+wg.srv+".wargaming.net/clans/"+cw_sc.clan.id+"/'>["+cw_sc.clan.tag+"] <img src='"+cw_sc.clan.emblem+"'></a></td><td>"+cw_sc.cw.elo[prov.max_vehicle_level]+"</td><td>"+loc[48]+"</td><td>"+loc[43]+"</td><td data-sort='99'>--</td><td class='t-border' data-sort='99'>--</td>"+cw_sc.table.c));
							cw_sc.cw.gold += prov.daily_revenue;
							cw_sc.cw.tier = prov.max_vehicle_level;
						}
					}
					// insert gold count
					d.getElementById('js-gold').textContent = sf.format(cw_sc.cw.gold,2);
					// send request for divisions
					cw_sf.request("divsData", cw_sc.api.divs, cw_sf.handlerDivs);
				}
				else if (cw_sc.cw.bats === 0) {
					provFragment.appendChild(sf.elem("tr", "t-cwText", "<td colspan='10'>"+loc[49]+"</td>"));
				}
				table.lastElementChild.appendChild(provFragment);
				// refresh table
				sortTable.refresh();
			},
			handlerDivs: function(data) { // divisions handler
				if (data.data[0].division.clan_id == cw_sc.clan.id) {
					for (var _p=0, _p_len = data.data.length; _p<_p_len; _p++) {
						var div = data.data[_p],
						battleRow = d.getElementsByClassName(div.alias)[0];
						if (!div.division && battleRow.classList.contains('province')) {
							var defBattle = battleRow.getElementsByClassName("js-last")[0];
							battleRow.children[6].textContent = loc[50];
							battleRow.children[6].classList.add("t-bold");
							if (defBattle) {
								defBattle.classList.remove("t-fight");
								defBattle.classList.add("t-noFight");
							}
						}
						else {
							// sometimes future defenses wont show up in planned battles
							if (div.attackers.length > 0 && battleRow.classList.contains('province')) {
								table.lastElementChild.appendChild(sf.elem("tr", "planned "+div.alias, "<td><a class='link__external' target='_blank' href='https://"+wg.srv+".wargaming.net/globalmap/#province/"+div.alias+"'>"+div.name+"</a></td><td></td><td></td><td>"+battleRow.children[3].innerHTML+"</td><td></td><td></td><td></td><td>"+loc[42]+"</td>"));
								battleRow.parentNode.removeChild(battleRow);
								cw_sf.request("tourneyData", cw_sc.api.tourney+div.alias+"&round=1", cw_sf.handlerTourney);
								// refresh table
								sortTable.refresh();
							}
						}
					}
				}
				else {
					d.getElementById('js-error').textContent = " • "+loc[51];
				}
			},
			handlerError: function(name, data) { // error handler
				if (cw_sc.debug) {console.info("errorData", name, data);}
				switch(name) {
					case ("mainData"):
						table.lastElementChild.appendChild(sf.elem("tr", "t-cwText", "<td colspan='10'>"+loc[52]+"</td>"));
						break;
					case ("divsData"):
						d.getElementById('js-error').textContent = " • "+loc[51];
						break;
					default: break;
				}
			},
			time: function (hour, min, type) { // time converter
				var time = hour+cw_sc.time.o;
				if (time >= 24) {
					time -= 24;
				}
				else if (time < 0) {
					time += 24;
				}
				if (type == "s") {
					time = "t-"+time+"_"+min+((time === 0 && min == "00") ? " t-24_00" : "");
				}
				return time;
			},
			timer: function () { // timestamp handler
				var dateNow = new Date(),
				time = {
					h: cw_sf.time(cw_sc.table[wg.srv][0]-1)-dateNow.getHours(),
					m: 60-dateNow.getMinutes()-1,
					s: 60-dateNow.getSeconds()-1
				};
				var timeSpan = d.getElementById('js-timePrime');
				if (!cw_sc.cw.event && cw_sc.cw.status) {
					timeSpan.textContent = loc[53];
					timeSpan.classList.add("t-bold");
					clearInterval(timeInterval);
				}
				else if (time.h >= 0 && (time.s > 0 || time.m > 0)) {
					timeSpan.textContent = ((time.h > 0) ? time.h+" "+loc[55]+", " : "")+((time.m > 0) ? time.m+" "+loc[56]+", " : "")+time.s+" "+loc[57];
				}
				else if (time.h < 0) {
					if (cw_sc.cw.bats == "--") {
						if (cw_sc.cw.bats === 0) {
							timeSpan.textContent = loc[54];
							timeSpan.classList.add("t-bold");
							clearInterval(timeInterval);
						}
					}
					else {
						timeSpan.classList.add("h-shadow");
						timeSpan.textContent = loc[59];
						clearInterval(timeInterval);
					}
				}
			},
			updater: function () { // updater handler
				var newTime = ((cw_sc.time.m >= 15 && cw_sc.time.m <= 45) ? [cw_sc.time.h,"30"] : ((cw_sc.time.m <= 15) ? [cw_sc.time.h,"00"] : [(cw_sc.time.h+1),"00"]));
				if (cw_sc.time.r[0] !== newTime[0] || cw_sc.time.r[1] !== newTime[1]) {
					cw_sf.request("mainData", cw_sc.api.clan, cw_sf.handlerMain);
				}
			},
			request: function (name, api, handler) { // request handler
				// GreaseMonkey xmlhttpRequest
				GM_xmlhttpRequest({
					method: "GET",
					url: api,
					headers: {
						Accept: "application/json"
					},
					onload: function(resp) {
						var data = JSON.parse(resp.responseText);	
						if (resp.status == 200) {
							if (cw_sc.debug) {console.info(name, data);}
							handler(data);
						}
						else {
							cw_sf.handlerError(name, resp);
						}
					},
					onerror: function(resp) {
						console.error("Error accessing Wargaming API", name, api, resp);
					}
				});
			}
		};

		// inserting style into head
		var cw_style = sf.elem("style", "wotstatscript", "", "text/css"),
		styleText = [
			"h3 {text-align: center;}",
			".b-battlesHide {display: inline;}",
			".b-battlesHide img {margin-right: 3px; vertical-align: sub;}",
			".b-battles {font-size: 12px; margin: 0px 0 60px; width: 100%;}",
			".b-battles .h-battles {font-size: 15px; position: relative;}",
			".b-battles .h-battles .h-battles-info {border-bottom: 1px solid #000; box-shadow: inset 0 -1px rgba(255,255,255,.05); text-align: center; padding: 10px 0;}",
			".b-battles .h-battles .h-battles-info img {max-height: 16px; vertical-align: bottom;}",
			".b-battles .h-battles .h-battles-info .h-shadow {font-weight: bold; text-shadow: 0px 0px 1px rgba(27,27,28, 1), 0px 0px 2px rgba(27,27,28, 1);}",
			".b-battles .h-battles .h-battles-infotable {margin: 21px 10px; min-width: 150px; position: absolute; top: 0px;}",
			".b-battles .h-battles .h-battles-infotable td {padding: 0 2px;}",
			".b-battles .h-battles .h-battles-infotable td.gold {padding-right: 16px;}",
			".b-battles .b-battles-holder {background-color: rgba(0, 0, 0, 0.75);}",
			".b-battles .b-battles-holder .t-battles {border-spacing: 0; box-shadow: inset -1px 0 rgba(255,255,255,.05); text-align: center; width: 100%;}",
			".b-battles .b-battles-holder .t-battles thead tr {}",
			".b-battles .b-battles-holder .t-battles tbody tr:nth-child(even) td {background-color: rgba(80, 60, 60, 0.1);}",
			".b-battles .b-battles-holder .t-battles tbody tr:nth-child(odd) td {background-color: rgba(123, 123, 123, 0.1);}",
			".b-battles .b-battles-holder .t-battles tbody tr:hover {background-color: rgba(100, 100, 100, 0.20);}",
			".b-battles .b-battles-holder .t-battles thead tr th.t-"+cw_sc.time.t+", .b-battles .b-battles-holder .t-battles tbody tr td.t-"+cw_sc.time.t+" {background-color: rgba(254,252,223, 0.15); border-left: 1px solid #808080; border-right: 1px solid #808080;}",
			".b-battles .b-battles-holder .t-battles thead tr th.t-"+cw_sc.time.t+" + th, .b-battles .b-battles-holder .t-battles tbody tr td.t-"+cw_sc.time.t+" + td {background-color: rgba(224,223,218, 0.1); border-right: 1px solid #808080;}",
			".b-battles .b-battles-holder .t-battles tr .t-border {border-right: 2px solid rgba(194, 173, 173, 0.1);}",
			".b-battles .b-battles-holder .t-battles tr th {line-height: 35px; border-top: 1px solid rgba(255,255,255,.1); border-bottom: 1px solid #000; box-shadow: inset 1px -1px rgba(255,255,255,.05); position: relative;}",
			".b-battles .b-battles-holder .t-battles tr th .sorter_arrow {background: url(http://eu.wargaming.net/clans/static/2.4.2/images/sorter/sorter-wot.png) no-repeat 50% 0;  margin-top: -3px; width: 100%; left: 0;}",
			".b-battles .b-battles-holder .t-battles tr th:hover {color: #FFFFFF;}",
			".b-battles .b-battles-holder .t-battles tr th:hover .sorter_arrow {opacity: 1;}",
			".b-battles .b-battles-holder .t-battles tr th.sort-up .sorter_arrow {background-position-y: -10px; margin-top: -5px; opacity: 1;}",
			".b-battles .b-battles-holder .t-battles tr th.sort-down .sorter_arrow {background-position-y: -5px; opacity: 1;}",
			".b-battles .b-battles-holder .t-battles tr td {line-height: 25px; border-top: 1px solid rgba(255,255,255,.1); border-bottom: 1px solid #000; box-shadow: inset 1px -1px rgba(255,255,255,.05); padding: 0 2px;}",
			".b-battles .b-battles-holder .t-battles tr td:first-of-type {max-width: 100px; overflow: hidden; padding: 0 5px; text-overflow: ellipsis; white-space: nowrap;}",
			".b-battles .b-battles-holder .t-battles tr td.t-title {font-weight: bold;}",
			".b-battles .b-battles-holder .t-battles tr td.t-good {color: #4D7326;}",
			".b-battles .b-battles-holder .t-battles tr td.t-bad {color: #930D0D;}",
			".b-battles .b-battles-holder .t-battles tr td.t-plan {color: #FFE400;}",
			".b-battles .b-battles-holder .t-battles tr td.t-fight {color: #4D7326; font-size: 15px; font-weight: bold;}",
			".b-battles .b-battles-holder .t-battles tr td.t-noFight {color: #808080; font-size: 14px;}",
			".b-battles .b-battles-holder .t-battles tr td.t-fight.t-noOwner {color: #808080;}",
			".b-battles .b-battles-holder .t-battles tr td.t-error {color: #CD2911;}",
			".b-battles .b-battles-holder .t-battles tr.t-cwText td {font-size: 26px; line-height: 54px;}",
			".b-battles .b-battles-holder .t-battles img {height: 16px; margin-bottom: 5px; vertical-align: bottom;}",
			".b-battles .f-battles {border-top: 1px solid #000; box-shadow: inset 0 1px rgba(255,255,255,.05); font-size: 15px; padding: 10px 0; text-align: center;}",
			".b-battles .f-battles img {max-height: 16px; vertical-align: bottom;}",
			".b-battles .t-bold {font-weight: bold;}",
			".t-time {display: none;}",
			".b-display-none {display: none;}",
			".b-display-block {display: block}"
		];
		cw_style.textContent = styleText.join("");
		d.head.appendChild(cw_style);

		// prepare static html and table reference for further use
		var widgets = d.getElementsByClassName("widgets")[0],
		battlesPanel = sf.elem("div", "b-battles", "<div class='h-battles'><h3>"+loc[22]+"</h3><div class='h-battles-info'>"+loc[23]+" <span id='js-timePrime'>--</span></div><table class='h-battles-infotable'><tr><td>"+loc[24]+"</td><td id='js-battles'>0</td><td>"+loc[60]+"</td><td id='js-battlesConc'>0</td></tr><tr><td>"+loc[25]+"</td><td class='gold' id='js-gold'>0</td></tr></table></div><div class='b-battles-holder'><table class='t-battles sortable'><thead><tr><th>"+loc[26]+"<span class='sorter_arrow'></span></th><th>"+loc[27]+"<span class='sorter_arrow'></span></th><th id='js-sort' class='sort-default' data-sort-order='desc'>"+loc[28]+"<span class='sorter_arrow'></span></th><th>"+((cw_sc.cw.event) ? loc[29] : loc[30])+"<span class='sorter_arrow'></span></th><th>"+loc[31]+"<span class='sorter_arrow'></span></th><th>"+loc[32]+"<span class='sorter_arrow'></span></th><th>"+loc[33]+"<span class='sorter_arrow'></span></th><th>"+loc[34]+"<span class='sorter_arrow'></span></th><th>"+loc[35]+"<span class='sorter_arrow'></span></th><th class='t-border'>"+loc[36]+"<span class='sorter_arrow'></span></th></tr></thead><tbody></tbody></table></div><div class='f-battles'>"+loc[37]+" <span id='js-batttleUpdate'>--</span> [UTC"+((cw_sc.time.o >= 0) ? "+" : "")+cw_sc.time.o+"]<span id='js-error'></span></div>"),
		table = battlesPanel.children[1].firstElementChild,
		widgetsLook = new MutationObserver(function() {
			widgets.insertBefore(battlesPanel, widgets.children[1]);
			widgetsLook.disconnect();
		});
		//widgets.insertBefore(battlesPanel, widgets.children[2]);
		widgetsLook.observe(widgets, {childList: true});

		// time cells for header and body rows
		var timeCells = cw_sc.table[wg.srv],
		timeFragment = d.createDocumentFragment();
		for (var _tc=0, _tc_len = timeCells.length; _tc<_tc_len; _tc++) {
			var t = timeCells[_tc],
			times = [cw_sf.time(t,"00","s"), cw_sf.time(t)+":00", cw_sf.time(t,"30","s"), cw_sf.time(t)+":30"];
			timeFragment.appendChild(sf.elem("th", "t-time "+times[0], times[1]+"<span class='sorter_arrow'></span>"));
			cw_sc.table.c += "<td class='t-time "+times[0]+"'></td>";
			if (_tc !== _tc_len-1) {
				timeFragment.appendChild(sf.elem("th", "t-time "+times[2], times[3]+"<span class='sorter_arrow'></span>"));
				cw_sc.table.c += "<td class='t-time "+times[2]+"'></td>";
			}
		}
		table.firstElementChild.firstElementChild.appendChild(timeFragment);

		// add intervals for time and round updater
		var timeInterval = setInterval(cw_sf.timer,1000), // 1 second
		updateInterval = setInterval(cw_sf.updater,120000); // 2 minutes

		// activate tablesort function
		var sortTable = false;
		if (Tablesort) {
			// Numeric sort
			Tablesort.extend('number', function(item) {
				return item.match(/^-?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
			}, function(a, b) {
				a = parseFloat(a);
				b = parseFloat(b);

				a = isNaN(a) ? 0 : a;
				b = isNaN(b) ? 0 : b;
				return a - b;
			});
			sortTable = new Tablesort(table);
		}
		else {
			window.alert("Error activating tablesort, please refresh - if this shit continues, poke Orrie");
		}

		// insert update status
		table.lastElementChild.appendChild(sf.elem("tr", "t-cwText", "<td colspan='10'>"+loc[38]+"</td>"));

		// send request to wargaming api to see if an event is running
		cw_sf.request("eventData", cw_sc.api.event, cw_sf.handlerEvent);
	}
}(window));