WoTStatScript - ForumsExtendedStat

Adds stats and links for posts on official World of Tanks forums

Od 10.03.2016.. Pogledajte najnovija verzija.

// ==UserScript==
// @name        WoTStatScript - ForumsExtendedStat
// @version     0.9.14.0.1
// @description Adds stats and links for posts on official World of Tanks forums
// @author      Orrie
// @contributor seriych
// @namespace   http://forum.worldoftanks.eu/index.php?/topic/263423-
// @icon        http://dl.dropboxusercontent.com/u/12497046/wot/projects/statscript/img/icon.png
// @include     /^http:\/\/forum\.worldoftanks\.(eu|com|ru|asia|kr)\/\S+(\/topic\/|\?showtopic=)/
// @include     /^http:\/\/forum\.worldoftanks\.(eu|com|ru|asia|kr)\/index\.php\?app=members&module=messaging&section=view&do=showConversation&topicID=\d+/
// @include     /^http:\/\/forum\.worldoftanks\.(eu|com|ru|asia|kr)\/index\.php\?\/forum/\S+/
// @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
// @license     MIT License
// ==/UserScript==
(function() {
	// global vars
	var d = document;

	// get server info and webpage
	var wg = {host:d.location.host, href:d.location.href, clan:{}};
		wg.srv = wg.host.match(/\.(eu|ru|com|asia|kr)/)[1].replace(/com/,"na");
		wg.topic = /(\/topic\/|\?showtopic=|messaging\&)/.test(wg.href);
		wg.forum = /\/forum\//.test(wg.href);
		wg.login = !!d.getElementsByClassName('js-cm-login-link')[0];

	// server, API and cluster settings
	var sc = {
		vers: "0.9.14.0.1",
		host: "http://greasyfork.org/scripts/660-wotstatscript-forumsextendedstat",
		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"
		},
		srv: {
			s: "en",
			wl: false, // wotlabs
			nm: false, // noobmeter
			vb: false, // vbaddict
			ws: false, // wotstats
			wr: false, // wotreplays
			ct: false, // clan-tools
			wlf: false // wot-life
		},
		api: {
			ru: "98ca7c4fb108175b67d6505b9c3f3ebd",
			eu: "a7595640a90bf2d19065f3f2683b171c",
			na: "bf5dba0efd444d75147b6222dd903fd2",
			asia: "95f8713eccd322e52dbf521dbd28b19c",
			kr: "ffea0f1c3c5f770db09357d94fe6abfb"
		},
		sym: ",",
		wn: "http://www.wnefficiency.net/exp/expected_tank_values_latest.json",
		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 threadlink
		sc.link = "<div class='b-scriptlink'><a target='_blank' href="+sc.host+">Script</a> v"+sc.vers+" - <a target='_blank' href="+((wg.srv == "na") ? sc.top.na : sc.top.eu)+">Thread</a></div>";
		
	// script functions
	var sf = {
		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[pData.account_id].u = {
							name: pData.nickname,
							id: pData.account_id,
							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,
							ban: pData.ban_time
						};
					}
					else {
						// store stats
						s[parseFloat(a)].u = {
							bat: 0
						};
					}
				}
			}
			sf.request(sc.api.v, 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;
						if (s[p].u.bat > 0) {
							for (var v in vData) {
								if (vData.hasOwnProperty(v)) {
									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[p].v.frag += vehStat.expFrag    * dataBattles;
											s[p].v.dmg  += vehStat.expDamage  * dataBattles;
											s[p].v.spot += vehStat.expSpot    * dataBattles;
											s[p].v.def  += vehStat.expDef     * dataBattles;
											s[p].v.win  += vehStat.expWinRate * dataBattles;
											break;
										}
									}
								}
							}
							rWin  = Math.max(((s[p].u.win /(s[p].v.win /s[p].u.bat)-0.71)/(1-0.71)),0);
							rDmg  = Math.max(((s[p].u.dmg /(s[p].v.dmg /s[p].u.bat)-0.22)/(1-0.22)),0);
							rFrag = Math.max(Math.min(rDmg+0.2,((s[p].u.frag/(s[p].v.frag/s[p].u.bat)-0.12)/(1-0.12))),0);
							rSpot = Math.max(Math.min(rDmg+0.1,((s[p].u.spot/(s[p].v.spot/s[p].u.bat)-0.38)/(1-0.38))),0);
							rDef  = Math.max(Math.min(rDmg+0.1,((s[p].u.def /(s[p].v.def /s[p].u.bat)-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
						s[p].wn8 = sf.color(wn8,"wn8",0);
					}
				}
			}
			sf.statInsert();
		},
		statInsert: function () { // insert stats and links to every post
			for (var y in s) {
				if (s.hasOwnProperty(y)) {
					var iPost = postObj.ids.indexOf(y), flag;
					if (iPost >- 1 && s[y].u.id) {
						if (wg.topic) {
							var userStats = [
								"<td>"+loc[1]+"</td><td>"+sf.color((s[y].u.bat > 0) ? s[y].u.win : 0,"wr",2,"%")+"</td>",
								"<td>"+loc[2]+"</td><td>"+sf.color(s[y].u.bat,"bat",0,"")+"</td>",
								"<td>"+loc[3]+"</td><td>"+sf.color(s[y].u.wgr,"pr",0,"")+"</td>",
								"<td>"+loc[4]+"</td><td>"+s[y].wn8+"</td>"
							],
							userLinks = [
								[
									["<a target='_blank' href='http://worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/community/accounts/"+s[y].u.id+"-"+s[y].u.name+"/'>Player Profile</a>"],
									[sc.srv.wl, "<a target='_blank' href='http://wotlabs.net/"+sc.srv.wl+"/player/"+s[y].u.name+"'>WoTLabs</a>"]
								],
								[
									[sc.srv.vb, "<a target='_blank' href='http://www.vbaddict.net/player/"+s[y].u.name.toLowerCase()+"-"+sc.srv.vb+"'>vBAddict</a>"],
									[sc.srv.nm, "<a target='_blank' href='http://noobmeter.com/player/"+sc.srv.nm+"/"+s[y].u.name+"'>Noobmeter</a>"]
								],
								[
									[sc.srv.ws, "<a target='_blank' href='http://wotstats.org/stats/"+sc.srv.ws+"/"+s[y].u.name+"/'>WoTstats</a>"],
									[sc.srv.ct, "<a target='_blank' href='http://clantools.us/servers/"+sc.srv.ct+"/players?id="+s[y].u.id+"'>Clan Tools</a>"]
								],
								[
									[sc.srv.wr, "<a target='_blank' href='http://wotreplays."+sc.srv.wr+"/player/"+s[y].u.name+"'>WoTReplays</a>"],
									(wg.srv=="ru") ? [sc.srv.wr, "<a target='_blank' href='http://wots.com.ua/user/stats/"+s[y].u.name+"'>WoTS.com.ua</a>"] : [sc.srv.wlf, "<a target='_blank' href='http://en.wot-life.com/"+sc.srv.wlf+"/player/"+s[y].u.name+"/'>WoT-Life</a>"]
								]
							];
							for (var _i=0, _i_len = postObj.num[iPost].length; _i<_i_len; _i++) {
								var groupTitle = postObj.post[postObj.num[iPost][_i]].getElementsByClassName("group_title")[0],
								basicInfo = postObj.post[postObj.num[iPost][_i]].getElementsByClassName("basic_info")[0],
								infoClass = postObj.post[postObj.num[iPost][_i]].getElementsByClassName("author_info")[0],
								statTable = sf.elem("table", "t-table-stats", ""),
								urlDiv = sf.elem("div", "b-table-links", ""),
								urlTable = sf.elem("table", "t-table-links", "<tbody></tbody>");
								flag = sf.elem("img", "i-xvm-lang", "", "", "https://bytebucket.org/seriych/worldoftanksforumextendedstat.user.js/raw/tip/data/img/lang/"+s[y].u.lng+".png");
								for (var _sr=0, _sr_len = userStats.length; _sr<_sr_len; ++_sr) {
									statTable.appendChild(sf.elem("tr", "", userStats[_sr]));
								}
								for (var _l=0, _l_len = userLinks.length; _l<_l_len; ++_l) {
									var uRow = sf.elem("tr", "", "");
									for (var _lr=0, _lr_len = userLinks[_l].length; _lr<_lr_len; ++_lr) {
										uRow.appendChild((userLinks[_l][_lr][0] && userLinks[_l][_lr][1]) ? sf.elem("td", "", userLinks[_l][_lr][1]) : sf.elem("td", "", userLinks[_l][_lr][0]));
									}
									urlTable.firstElementChild.appendChild(uRow);
								}
								if (wg.srv !== "ru") {
									groupTitle.appendChild(flag);
								}
								flag.title = s[y].u.lng.toUpperCase()+" "+loc[0];
								flag.addEventListener('error', function(){this.src=uri.q_mark;});
								if (s[y].u.ban) {
									var memTitle = postObj.post[postObj.num[iPost][_i]].getElementsByClassName("member_title")[0];
									memTitle.textContent = "Banned: "+ new Date(s[y].u.ban*1000).toLocaleString(sc.dateFormat[wg.srv]);
									memTitle.classList.add("member_banned");
								}
								basicInfo.insertBefore(statTable, basicInfo.lastElementChild);
								urlDiv.appendChild(urlTable);
								infoClass.appendChild(urlDiv);
							}
						}
						else if (wg.forum) {
							for (var _r=0, _r_len = postObj.num[iPost].length; _r<_r_len; _r++) {
								var statCell, id_url = postObj.span[postObj.num[iPost][_r]].getElementsByClassName("url")[0],
								threadRow = postObj.span[postObj.num[iPost][_r]].parentNode.parentNode,
								threadRowClsList = threadRow.classList;
								if (threadRowClsList.contains("announcement")) {
									statCell = threadRow.insertCell(1);
								}
								else if (threadRowClsList.contains("__topic")) {
									statCell = threadRow.insertCell(3);
								}
								statCell.className = "col_f_stats";
								if (!id_url || s[y].u.bat === 0) {
									statCell.appendChild(sf.elem("span", "s-no-stats", loc[6]));
								}
								else {
									var statsRow = [
										"<td>"+loc[1]+"</td><td>"+sf.color((s[y].u.bat > 0) ? s[y].u.win : 0,"wr",2,"%")+"</td><td>"+loc[2]+"</td><td>"+sf.color(s[y].u.bat,"bat",0,"")+"</td>",
										"<td>"+loc[3]+"</td><td>"+sf.color(s[y].u.wgr,"pr",0,"")+"</td><td>"+loc[4]+"</td><td>"+s[y].wn8+"</td>",
									],
									rowTable = sf.elem("table", "t-row-stats", "");
									flag = sf.elem("img", "i-xvm-lang", "", "", "https://bytebucket.org/seriych/worldoftanksforumextendedstat.user.js/raw/tip/data/img/lang/"+s[y].u.lng+".png");
									for (var _rr=0, _rr_len = statsRow.length; _rr<_rr_len; ++_rr) {
										rowTable.appendChild(sf.elem("tr", "", statsRow[_rr]));
									}
									if (wg.srv !== "ru") {
										statCell.appendChild(flag);
									}
									flag.title = s[y].u.lng.toUpperCase()+" "+loc[0];
									flag.addEventListener('error', function(){this.src=uri.q_mark;});
									statCell.appendChild(rowTable);
								}
							}
						}
					}
				}
			}
		},
		color: function (input, type, dec, sym) { // color formatting
			var color = colArr.dft[0],
			output = input.toFixed(dec);
			if (sym) {
				output += sym;
			}
			if (input >= 1000) {
				output = input.toFixed(dec).toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1"+sc.sym);
			}
			for (var c in colArr) {
				if (colArr.hasOwnProperty(c)) {
					if (input >= colArr[c][colArr.id[type]]) {
						color = colArr[c][0]; break;
					}
				}
			}
			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;
		},
		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: { // wnefficiency handler
			hnd: function (resp) {
				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();
			},
			error: function (error) {
				console.error("Error accessing WNEfficiency.net", error);
			}
		},
		request: function (url, handler, error) { // request handler
			GM_xmlhttpRequest({
				method: "GET",
				url: url,
				headers: {
					"Accept": "text/xml"
				},
				onload: function(resp) {
					if (resp.readyState == 4 && resp.status == 200 && resp.statusText == "OK") {
						handler(resp.responseText);
					}
					else {
						error(resp.responseText);
					}
				},
				onerror: function(resp) {
					error(resp.responseText);
				}
			});
		}
	};

	// 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.wr = sc.srv.ct = sc.srv.wlf = wg.srv;
			break;
		case ("ru"): // ru server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.wr = sc.srv.ct = sc.srv.wlf = wg.srv;
			sc.srv.s = "ru";
			sc.sym = " ";
			break;
		case ("com"): // na server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = sc.srv.ct = "na"; sc.srv.wr = "com";
			break;
		case ("asia"): // asia server
			sc.srv.wl = sc.srv.nm = sc.srv.vb = sc.srv.ws = "sea"; sc.srv.ct = 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.ct = sc.srv.ch = wg.srv; sc.srv.wr = "com";
			break;
		default: break;
	}

	// data uri
	var uri = {
		icon_arrow:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAAJCAMAAAAhKrH/AAAAV1BMVEUAAAD///+TKCf9AQmTLiX9AQmTMir9AQmTLif9AQmTMSz9AQmTMir9AQmTMyn9AQmTMirvGgKTMirsIAGTMirwGQOTMiqTMirsIAGaNDGgNzfqJwDrJABtE0DNAAAAGnRSTlMAABERIiIzM0REVVVmZnd3iIqZmrvDzN3g7thzQuwAAACHSURBVHja5dVLDsIwDEXRCySlP0IMoXXs7H+dDBASA1bQ3B0cPclm2Fe2wrfTQeO3qwqqAKWek80HxfO/l1/EBRgtU2tf+KkJ7TO9hdVSV3jU42f6ZClY6Qt/d4n+BGol29jTwQN1pE2QbA610BVefImuwL7xsNAXXhVpEYY8kNfO/rwsyA3ekEsOT2YDLE8AAAAASUVORK5CYII=",
		q_mark: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAANCAYAAACgu+4kAAAAh0lEQVQoz2OwsbGxtre3jwTiBBJxJEgvA4jBQCYA6wWZhkVOFIjLgPgOEH8A4llArIDFgARcBsgCsRkQywGxLhC3AXEtKQYgA5DN6UCcRo4BEkCcDcSVQMxLqgHcQJwPxNVAzIMjEPEaIAXEJUCcgScWiAoDBnINEAbieiCuobkBlKVESvMCADnAReqxtj3zAAAAAElFTkSuQmCC"
	};

	// 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.hnd, sf.wn.error);
	}

	// style contents
	var style = sf.elem("style", "wotstatscript", "", "text/css"),
		styleText = [
			// script header rules
			"#common_menu .cm-menu__user > *:not(.cm-notifications):not(.js-cm-user-menu-dropdown):not(.js-cm-dropdown-for-mobile-only):not(.cm-user-unauthorized) {display: inline-block}",
			"#common_menu .cm-parent-link:hover {cursor: inherit; color: #707273 !important;}",
			"#common_menu .b-scriptlink a {color: #E5B12E;}",
			"#common_menu .b-scriptlink a:hover {color: #FFBE4C; text-shadow: 0px 0px 7px rgba(255, 126, 0, 0.7);}",
			"#common_menu .cm-get-gold-link {margin: 0 12px;}",
			"#common_menu .cm-menu__user .cm-parent-link {font-size: 13px; padding: 0 8px 0 10px;}",
			// settings menu rules
			"#common_menu .menu-settings {text-align: left;}",
			"#common_menu .menu-settings .cm-user-menu-link {margin: 0;}",
			"#common_menu .menu-settings .cm-user-menu {padding: 15px; right: unset;}",
			"#common_menu .menu-settings .cm-parent-link:hover {cursor: pointer;}",
			"#common_menu .menu-settings label {display: table; line-height: normal; cursor: pointer;}",
			"#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 .settingItem .b-combobox-label:hover {color: #DCDCDC;}",
			"#common_menu .menu-settings .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 .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-settingLink {line-height: 26px;}",
			"#common_menu .menu-settings .b-settingLink a {cursor: pointer; color: #B1B2B3; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.5);}",
			"#common_menu .menu-settings .b-settingLink a:hover {color: #FFFFFF; text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.75);}",
			"#common_menu .menu-settings .settingCredits {border-top: 1px dashed #212123; margin-top: 6px; padding-top: 12px;}",
			"#common_menu .menu-settings .settingCredits p {font-size: 12px;}",
			"#common_menu .menu-settings .settingCredits .b-orange-arrow {color: #F25322; line-height: 14px; padding-right: 9px;}",
			"#common_menu .menu-settings .settingCredits .b-orange-arrow:hover {color: #FF7432;}",
			// forum rules
			".topic_list {table-layout: auto}",
			".col_f_stats {width: 200px;}",
			".col_f_preview {width: 10px !important;}",
			".col_f_views {width: auto;}",
			".col_f_post {width: auto;}",
			".col_f_stats .i-xvm-lang {margin: 6px 0 0 0;}",
			".t-row-stats {float: right; table-layout: fixed; width: 175px;}",
			".realm_ru .t-row-stats {width: 200px;}",
			"table.ipb_table .t-row-stats td {border-bottom: 0; font-size: 11px; padding: 0;}",
			"#announcements .t-row-stats td {border-bottom: 0;}",
			".s-no-stats {color: #A03737; display: table; font-size: 14px; margin: 0 auto;}",
			// thread rules
			".author_info {min-height: 310px; padding: 0 10px 10px 14px;}",
			".user_details > br {display: none;}",
			".author_info .member_title.member_banned {color: #CD3333;}",
			".basic_info {margin: 0 0 4px;}",
			".post_count.margin-bottom {margin: 0 0 5px;}",
			".battles_count {display: none;}",
			".i-xvm-lang {vertical-align: text-top;}",
			".t-table-stats {margin: 5px 0; width: auto;}",
			".t-table-stats td {padding: 0 5px 0 0; line-height: 16px;}",
			".t-table-stats td:last-of-type {font-weight: bold;}",
			".b-table-links {height: 25px; margin: 5px 0px 0px;}",
			".t-table-links {background: #EDEDED; border: 1px solid #d5d5d5; border-radius: 3px; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1), 0 0 3px 3px rgba(255, 255, 255, 0.2); display: inline-block; overflow: hidden; padding: 3px 3px 0; position: absolute; text-overflow: ellipsis; white-space: nowrap; height: "+((sc.web.chrome) ? "20px" : "25px")+"; width: 90px; z-index: 1;}",
			".t-table-links:hover {border-color: #7D7D7D; height: auto; width: auto;}",
			".t-table-links tbody {display: table; width: 180px;}",
			".t-table-links td {padding: 0 0 2px; font-weight: bold;}",
			".t-table-links td a { background: url("+uri.icon_arrow+") no-repeat scroll 0 2px rgba(0, 0, 0, 0); padding: 0 0 0 10px; vertical-align: middle;}",
			".t-table-links td a:hover {background: url("+uri.icon_arrow+") no-repeat scroll -244px 2px rgba(0, 0, 0, 0);}",
			".t-table-links tr:last-of-type td {}",
			// korean realm widths
			".realm_kr .t-table-links {width: 108px;}",
			".realm_kr .t-table-links:hover {width: 215px;}",
			".realm_kr .t-table-links tbody {width: 215px;}"
		];
		style.textContent = styleText.join("");
		d.head.appendChild(style);
	// end style

	// colour scale array
	var colArr = {
		//      col        wr  bat    wn8   wn7   eff   nm    pr
		sUni: [ "#5A3175", 65, 30000, 2900, 2050, 2050, 2000       ], // 99.99% super unicum
		uni:  [ "#83579D", 60, 25000, 2450, 1850, 1800, 1950, 9930 ], // 99.90% unicum
		gr8:  [ "#3972C6", 56, 21000, 2000, 1550, 1500, 1750, 8525 ], // 99.00% great
		vGud: [ "#4099BF", 54, 17000, 1600, 1350                   ], // 95.00% very good
		good: [ "#4D7326", 52, 13000, 1200, 1100, 1200, 1450, 6340 ], // 82.00% good
		aAvg: [ "#849B24", 50, 10000,  900                         ], // 63.00% above average
		avg:  [ "#CCB800", 48,  7000,  650,  900,  900, 1250, 4185 ], // 40.00% average
		bAvg: [ "#CC7A00", 47,  3000,  450,  700,  600, 1150, 2020 ], // 20.00% below average
		bas:  [ "#CD3333", 46,  1000,  300,  500                   ], //  6.00% basic
		beg:  [ "#930D0D",  0,     0,    0,    0,    0,    0, 0    ], //  0.00% beginner
		dft:  [ "#6B6B6B" ], // default
		id: { "col": 0, "wr": 1, "bat": 2, "wn8": 3, "wn7": 4, "eff": 5, "nm": 6, "pr": 7 }  // type identifier
	};

	// localization
	var loc = [
		{ en: "Client", ru: "Клиент"},
		{ en: "Winrate:", ru: "Винрейт:"},
		{ en: "Battles:", ru: "Боев:"},
		{ en: "Rating:", ru: "Рейтинг:"},
		{ en: "WN8:", ru: "WN8:"},
		{ en: "Please Login for Stats", ru: "Please Login for Stats"},
		{ en: "No Stats Found", ru: "No Stats Found"},
		{ en: "Script Menu", ru: "Script Menu"},
		{ en: "Refresh WN8 Table", ru: "Refresh WN8 Table"},
		{ en: "Script Author:", ru: "Script Author:"}
		//{ en: "f00_en", ru: "f00_ru"},
	];
	// process localization
	for (var _l=0, l_len = loc.length; _l<l_len; _l++) {
		loc[_l] = loc[_l][sc.srv.s];
	}

	// script link
	var userLink_div = sf.elem("div", "cm-parent-link", sc.link),
	userSet_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[7]+"</span><span class='cm-arrow'></span></span>"),
	userSet_list = sf.elem("ul", "cm-user-menu", "<li class='settingItem'><div class='b-settingLink'><a>"+loc[8]+" [v"+wn.vers[1]+"]</a></div></li><li class='b-settingItem settingCredits'><p>"+loc[9]+" <a class='b-orange-arrow' href='"+sc.user.wot+"'>Orrie</a></p></li>"),
	navMenu = d.getElementById('common_menu'),
	navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
	userSet_div.firstElementChild.addEventListener('click', function() {this.classList.toggle('cm-user-menu-link__opened'); this.nextSibling.classList.toggle('cm-user-menu__opened');}, false);
	userSet_list.firstElementChild.firstElementChild.addEventListener('click', function() {localStorage.removeItem("wnExpValues"); location.reload();}, false);
	userSet_div.appendChild(userSet_list);
	if (navUser) {
		navUser.insertBefore(userLink_div, navUser.firstChild);
		navUser.insertBefore(userSet_div, navUser.firstChild);
	}
	else {
		var navLook = new MutationObserver(function() {
			var navUser = navMenu.getElementsByClassName('cm-menu__user')[0];
			navUser.insertBefore(userLink_div, navUser.firstChild);
			navUser.insertBefore(userSet_div, navUser.firstChild);
			navLook.disconnect();
		});
		navLook.observe(navMenu, {childList: true});
	}

	// formula calculations and variables
	// create global post variable
	var postObj = {
		post: d.querySelectorAll(".post_wrap, .post_wrap__wg"),
		span: d.querySelectorAll("span.desc.lighter.blend_links"),
		cls: [],
		ids: [],
		num: []
	},
	s = {};
	switch(true) {
		case (wg.topic):
			postObj.cls = postObj.post; break;
		case (wg.forum):
			postObj.cls = postObj.span; break;
		default: break;
	}

	// fetch userids and store all posts into one obj for later use
	if (wg.topic || (wg.forum && wg.login === false)) {
		for (var _t=0, _t_len = postObj.cls.length; _t<_t_len; _t++) {
			var id;
			switch(true) {
				case (wg.topic):
					id = postObj.post[_t].getElementsByClassName("ipsUserPhotoLink")[0].getAttribute('href').match(/\-(\d+)\//)[1]; break;
				case (wg.forum):
					var id_url = postObj.span[_t].getElementsByClassName("url")[0];
					if (id_url) {
						id = id_url.getAttribute('href').match(/\-(\d+)\//)[1];
					}
					break;
				default: break;
			}
			if (!isNaN(id)) {
				var users = postObj.ids.length,
				index = postObj.ids.indexOf(id);
				s[id] = {u:{},v:{frag:0,dmg:0,spot:0,def:0,win:0},wn8:""};
				if (index>-1) {
					postObj.num[index][postObj.num[index].length] = _t;
				}
				else {
					postObj.ids[users] = id;
					postObj.num[users] = [_t];
				}
			}
		}
	}
	else {
		navUser.insertBefore(sf.elem("div", "cm-parent-link b-login-msg", "<div>"+loc[5]+"</div>"), navUser.firstChild);
	}

	// request and retrieve statistics from API
	if (postObj.ids.length > 0) {
		sc.api.i = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/info/?application_id="+sc.api[wg.srv]+"&account_id="+postObj.ids.join(',');
		sc.api.v = "http://api.worldoftanks."+((wg.srv == "na") ? "com" : wg.srv)+"/wot/account/tanks/?application_id="+sc.api[wg.srv]+"&account_id="+postObj.ids.join(',');
		sf.request(sc.api.i, sf.apiInfoHnd);
	}
	else {
		console.error("No post IDs found or not logged in");
	}
}(window));