RBR Czech - Class Addendum

Adds omitted class links on rbr.onlineracing.cz

目前为 2016-07-29 提交的版本。查看 最新版本

// ==UserScript==
// @name			RBR Czech - Class Addendum
// @namespace 		RBRCzechScripts
// @author			Łukasz Demolin "Maggot"
// @version 		0.7.2
// @date         2016-07-29
// @icon         https://dl.dropboxusercontent.com/u/10106549/e-rajdy/richard_burns_rally.ico
// @description		Adds omitted class links on rbr.onlineracing.cz
// @description		Also adds missing tracks on the "Ranks" and "Record" pages everywhere. Added dropdown-menu with stage select on stagerec/stagerank pages.
// @description		Unfortunately, the times and car names are not displayed (major hurdle).
// @require     https://code.jquery.com/jquery-3.0.0.js
// @include		http://rbr.onlineracing.cz/index.php?act=tourmntres*
// @include		http://rbr.onlineracing.cz/index.php?act=urec*
// @include		http://rbr.onlineracing.cz/index.php?act=urank*
// @include		http://rbr.onlineracing.cz/index.php?act=stagerec*
// @include		http://rbr.onlineracing.cz/index.php?act=stagerank*
// @include		http://rbr.onlineracing.cz/index.php?act=tstats*
// @grant       GM_getValue
// @grant       GM_setValue

// ==/UserScript==

// Populating a handy faux-dictionary with classes and their correct ids (to avoid messing up and hardcoding).
var classesDict = {
    "WRC legacy": 1,
    "N4" : 3,
    "S2000" : 13,
    "S1600" : 2,
    "A8" : 4,
    "A7" : 5,
    "A6" : 6,
    "A5" : 7,
    "N3" : 8,
    "H" : 11,
    "GT" : 14,
    "RC1" : 101,
    "RC2" : 102,
    "RGT" : 103,
    "RC3" : 104,
    "RC4" : 105,
    "RC5" : 106,
    "WRC" : 111,
    "H/B" : 107,
    "H/A" : 108,
    "H/4" : 109,
    "H/2" : 110
};

// A dictionary of sorts to assign all the countries correctly (sorts the duplicates like CZ/Czech Republic and mistakes like Sweeden). Preparing for CSS classes (avoiding spaces -> using the international 2-digit codes).
var countriesDict = { "Finland" : "FI",
    "Great Britain" : "GB",
	"Rally School" : "GB",
	"Rally school" : "GB",
    "Australia" : "AU",
    "France" : "FR",
    "Japan" : "JP",
    "USA": "US",
	"CZ" : "CZ",
	"Czech Republic" : "CZ",
	"Netherlands" : "NL",
	"Germany" : "DE",
	"Ireland" : "IE",
	"Slovakia" : "SK",
	"Lithuania" : "LT",
	"Poland" : "PL",
	"Spain" : "ES",
	"Montekland" : "Montek",
	"Sweeden" : "SE",
	"Sweden" : "SE",
	"Argentina" : "AR",
	"Estonia" : "EE",
	"Italy" : "IT",
	"Slovenia" : "SI",
	"Switzerland" : "CH",
	"Swiss" : "CH",
	"Ukraine" : "UA"
};

// An array of helpful data related to sorting and subtitling the stages and countries.
var countriesSortOrder = [["FI", "Finland", "http://rbr.onlineracing.cz/images/flgs/FI.gif"],
                          ["SE", "Sweden", "http://rbr.onlineracing.cz/images/flgs/SE.gif"],
                          ["GB", "Great Britain", "http://rbr.onlineracing.cz/images/flgs/GB.gif"],
                          ["IE", "Ireland", "http://rbr.onlineracing.cz/images/flgs/IE.gif"],
                          ["AU", "Australia", "http://rbr.onlineracing.cz/images/flgs/AU.gif"],
                          ["FR", "France", "http://rbr.onlineracing.cz/images/flgs/FR.gif"],
                          ["JP", "Japan", "http://rbr.onlineracing.cz/images/flgs/JP.gif"],
                          ["US", "USA", "http://rbr.onlineracing.cz/images/flgs/US.gif"],
                          ["CZ", "Czech Republic", "http://rbr.onlineracing.cz/images/flgs/CZ.gif"],
                          ["SK", "Slovakia", "http://rbr.onlineracing.cz/images/flgs/SK.gif"],
                          ["PL", "Poland", "http://rbr.onlineracing.cz/images/flgs/PL.gif"],
                          ["DE", "Germany", "http://rbr.onlineracing.cz/images/flgs/DE.gif"],
                          ["NL", "Netherlands", "http://rbr.onlineracing.cz/images/flgs/NL.gif"],
                          ["LT", "Lithuania", "http://rbr.onlineracing.cz/images/flgs/LT.gif"],
                          ["EE", "Estonia", "http://rbr.onlineracing.cz/images/flgs/EE.gif"],
                          ["SI", "Slovenia", "http://rbr.onlineracing.cz/images/flgs/SI.gif"],
                          ["UA", "Ukraine", "http://rbr.onlineracing.cz/images/flgs/UA.gif"],
                          ["ES", "Spain", "http://rbr.onlineracing.cz/images/flgs/ES.gif"],
                          ["IT", "Italy", "http://rbr.onlineracing.cz/images/flgs/IT.gif"],
                          ["CH", "Switzerland", "http://rbr.onlineracing.cz/images/flgs/CH.gif"],
                          ["AR", "Argentina", "http://rbr.onlineracing.cz/images/flgs/AR.gif"],
                          ["Montek", "Montekland", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAQCAIAAACHs/j/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAD5klEQVR4Xl2TbUxbVRjHn+ee+35v29s3oGtBbZnRDChjsNE007llwsYSNbwMo0OIMca4qYnJwhKDxrlojPEDw5e4+AKZ7wlxWczitwW3IQw3MIw5ySoQMyhvZW1vL+297fUDrBn8vpxzPvx/ef455wBsAKtrilxuAZESRdLdU3Dht5DNxtsUYegqd2XoOYuF9Xjl/nMFbe1FG4PrkI1HtFjJ13322TnH3Kza3GIeOMSXBlyipL7QkSos4FU1c/KUGg6Xnflci0RWAIBhaIHndN1Yz2+wAYgSe/oTW/Nh75XfNV9JxF9qULnyXM5LEQVQgBwCNZRJux/ffZMX1Oqd1KMPmz2nycREbINFkIQ9e+1VVXaPR3mm0T0ySheXkOMncHCYSqySlIGqAaoBqkGv6iEtE44ucamMMjW9u6pKvn8mem3RVO32JPNlb+H27SV6OjowkEjE+Rvj4cV5hWFvNTaNhR/TAQHAyOIgIFptoCYaX3n50rVrybxrMyUPypf/YFMGdLxEAQAgIIXByqDdLnW9g9FlUPW1GSFl4PlfrbW7lPJypazc6vdbZVmC/FUgoiSJDENoWt67V+3/GW+Mm2ACmBCdi+q6bhjURx+YUxGMzlFbPCDJ5kOB9JH24NNP2ZAk/xoz5uc10zQBABxO57Otrh9+LF2K12m6K2VAfBU/7obCIgQAROh6m8wuEYeT1B2oa2s/sueJUFMLGf+b6j3r83gVAOpevXtwHKc4LC2HrSOjnGrAcgJ/6ieRGez7jvSeZZMZHL6+nkHAgD/Asqwkwp9j3OWr7lePbgkEFJ5nIV82m83ShCp+oHR/nd3pnCcMrCwjL+DO2lx8BRYWcFWjBi6ad++CCRCLxXK5bFMzlgWL7/y3NZ0Gmo0vLbLptAkAwDD0jmrnL+f8k1Oh29NcNEbW+r77HhNdppIZuLMIyQz88y998hTldAMiNBzCuAbdn9lEUV4vCABrT0YQBYtMmwB6xpQtpLtHqT84bSIsLeCH71MuF+Xx5hCQ41Bx5HZUZ6OzlMtFG1m/2209/ubkV2eSGV2/X7oOw5Bjxx7R0qFYgool2ZReoWYckRlqcJhEZlDVUTO4lSSd0l0Tt2RfsSMUdrzVZdlVa0fc/LsAALZts42MFXae8FZUukeuBzVDTKX3a/rzWqZVyzy5qgc13fdNn9jUvPX8hcrmVjsiIqIgCCzLbnbxPH+wwe0rlgmhfT7rwnJbLEkdfcN6c7ImZbAjo8y335dphrOz00YhJYpcRaXN7rBttuQhhORn3rdPmV2oqm+wCBL/6Rf1KcPS8aJYUCRfvFTz2uvOfESSpPx+jf8Bk4d9ASiTkI4AAAAASUVORK5CYII="],
                          ["ROW", "Rest of the World", "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/2wBDAQMDAwQDBAgEBAgQCwkLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBD/wAARCAAIABADASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEE/8QAIRAAAQMCBwEAAAAAAAAAAAAAEQABEgITBBQhIiMxYQX/xAAUAQEAAAAAAAAAAAAAAAAAAAAH/8QAFxEBAAMAAAAAAAAAAAAAAAAAABEiQf/aAAwDAQACEQMRAD8A04FmzvO1ZL2yIXDtnLSB78U+gzZx7DVk8gELh3QjpA9eIiWpsPsf/9k="]];

// An array or array with data of all the stages available on the site.
var stagesDict = [[10,"Kaihuavaara","Finland","Snow","6.1 km","Yes","Open"],
                  [11,"Mustaselka","Finland","Snow","7.9 km","Yes","Open"],
                  [12,"Sikakama","Finland","Snow","10.2 km","Yes","Open"],
                  [13,"Autiovaara","Finland","Snow","6.1 km","Yes","Open"],
                  [14,"Kaihuavaara II","Finland","Snow","6.1 km","Yes","Open"],
                  [15,"Mustaselka II","Finland","Snow","7.7 km","Yes","Open"],
                  [16,"Sikakama II","Finland","Snow","10.2 km","Yes","Open"],
                  [17,"Autiovaara II","Finland","Snow","6.1 km","Yes","Open"],
                  [20,"Harwood Forest","Great Britain","Gravel","6.1 km","Yes","Open"],
                  [21,"Falstone","Great Britain","Gravel","6.6 km","Yes","Open"],
                  [22,"Chirdonhead","Great Britain","Gravel","7 km","Yes","Open"],
                  [23,"Shepherds Shield","Great Britain","Gravel","4.8 km","Yes","Open"],
                  [24,"Harwood Forest II","Great Britain","Gravel","5.9 km","Yes","Open"],
                  [25,"Chirdonhead II","Great Britain","Gravel","6.9 km","Yes","Open"],
                  [26,"Falstone II","Great Britain","Gravel","6.6 km","Yes","Open"],
                  [27,"Shepherds Shield II","Great Britain","Gravel","4.9 km","Yes","Open"],
                  [30,"Greenhills II","Australia","Gravel","6 km","Yes","Open"],
                  [31,"New Bobs","Australia","Gravel","10.1 km","Yes","Open"],
                  [32,"Greenhills","Australia","Gravel","6 km","Yes","Open"],
                  [33,"Mineshaft","Australia","Gravel","8.2 km","Yes","Open"],
                  [34,"East-West","Australia","Gravel","9.5 km","Yes","Open"],
                  [35,"New Bobs II","Australia","Gravel","10 km","Yes","Open"],
                  [36,"East-West II","Australia","Gravel","9.6 km","Yes","Open"],
                  [37,"Mineshaft II","Australia","Gravel","8.2 km","Yes","Open"],
                  [41,"Cote D'Arbroz","France","Tarmac","4.5 km","Yes","Open"],
                  [42,"Joux Verte","France","Tarmac","7.9 km","Yes","Open"],
                  [43,"Bisanne","France","Tarmac","5.6 km","Yes","Open"],
                  [44,"Joux Plane","France","Tarmac","11.1 km","Yes","Open"],
                  [45,"Joux Verte II","France","Tarmac","7.8 km","Yes","Open"],
                  [46,"Cote D'Arbroz II","France","Tarmac","4.3 km","Yes","Open"],
                  [47,"Bisanne II","France","Tarmac","5.6 km","Yes","Open"],
                  [48,"Joux Plane II","France","Tarmac","11.1 km","Yes","Open"],
                  [50,"Sipirkakim II","Japan","Gravel","8.7 km","Yes","Open"],
                  [51,"Noiker","Japan","Gravel","13.8 km","Yes","Open"],
                  [52,"Sipirkakim","Japan","Gravel","8.7 km","Yes","Open"],
                  [53,"Pirka Menoko","Japan","Gravel","6.7 km","Yes","Open"],
                  [54,"Tanner","Japan","Gravel","3.9 km","Yes","Open"],
                  [55,"Noiker II","Japan","Gravel","13.7 km","Yes","Open"],
                  [56,"Tanner II","Japan","Gravel","4 km","Yes","Open"],
                  [57,"Pirka Menoko II","Japan","Gravel","6.7 km","Yes","Open"],
                  [60,"Frazier Wells II","USA","Gravel","5 km","Yes","Open"],
                  [61,"Fraizer Wells","USA","Gravel","5 km","Yes","Open"],
                  [62,"Prospect Ridge","USA","Gravel","7.8 km","Yes","Open"],
                  [63,"Diamond Creek","USA","Gravel","7.1 km","Yes","Open"],
                  [64,"Hualapai Nation","USA","Gravel","8.6 km","Yes","Open"],
                  [65,"Prospect Ridge II","USA","Gravel","7.9 km","Yes","Open"],
                  [66,"Diamond Creek II","USA","Gravel","6.8 km","Yes","Open"],
                  [67,"Hualapai Nation II","USA","Gravel","8.6 km","Yes","Open"],
                  [70,"Prospect Ridge II A","USA","Gravel","7.6 km","Yes","Open"],
                  [71,"Rally School Stage","Rally school","Gravel","2.2 km","Yes","Open"],
                  [90,"Rally School Stage II","Rally school","Gravel","2.3 km","Yes","Open"],
                  [94,"Stryckovy okruh","CZ","Tarmac","9.2 km","Yes","Open"],
                  [95,"Sumburk 2007","CZ","Tarmac","12.4 km","No","Open"],
                  [96,"Sosnova","CZ","Tarmac","7.1 km","No","Open"],
                  [105,"Sosnova 2010","CZ","Tarmac","4.2 km","No","Restricted"],
                  [106,"Stryckovy - Zadni Porici","CZ","Tarmac","6.9 km","Yes","Open"],
                  [107,"PTD Rallysprint","Netherlands","Gravel","5.1 km","Yes","Open"],
                  [108,"Osli - Stryckovy","CZ","Tarmac","10.6 km","Yes","Open"],
                  [125,"Bergheim v1.1","Germany","Tarmac","8 km","Yes","Open"],
                  [131,"Lyon - Gerland","France","Tarmac","0.7 km","Yes","Restricted"],
                  [132,"Gestel","Netherlands","Tarmac","7.2 km","Yes","Open"],
                  [139,"RSI slalom Shonen","Ireland","Tarmac","1 km","Yes","Open"],
                  [140,"RSI slalom gegeWRC","Ireland","Tarmac","1.8 km","Yes","Open"],
                  [141,"Mlynky","Slovakia","Tarmac","7.1 km","Yes","Open"],
                  [142,"Mlynky Snow","Slovakia","Snow","7.1 km","Yes","Open"],
                  [143,"Peklo","Slovakia","Tarmac","8.5 km","Yes","Open"],
                  [144,"Peklo Snow","Slovakia","Snow","8.5 km","Yes","Open"],
                  [145,"Versme","Lithuania","Gravel","3.2 km","Yes","Open"],
                  [146,"Peklo II","Slovakia","Tarmac","8.5 km","Yes","Open"],
                  [147,"Peklo II Snow","Slovakia","Snow","8.5 km","Yes","Open"],
                  [148,"ROC 2008","Great Britain","Tarmac","2 km","Yes","Open"],
                  [149,"Sieversdorf V1.1","Germany","Tarmac","8 km","Yes","Open"],
                  [152,"RP 2009 Shakedown","Poland","Gravel","4.4 km","Yes","Open"],
                  [153,"RP 2009 Shakedown Reversed","Poland","Gravel","4.4 km","Yes","Open"],
                  [154,"Bruchsal-Unteroewisheim","Germany","Tarmac","8.9 km","Yes","Open"],
                  [155,"Humalamaki 1.0","Finland","Gravel","4.4 km","Yes","Open"],
                  [156,"Mlynky II","Slovakia","Tarmac","7.1 km","Yes","Open"],
                  [157,"Grand Canaria ROC 2000","Spain","Gravel","3.8 km","Yes","Open"],
                  [158,"Sweet Lamb","Great Britain","Gravel","5.1 km","Yes","Open"],
                  [159,"Sweet Lamb II","Great Britain","Gravel","5.1 km","Yes","Open"],
                  [471,"Aragona","Italy","Tarmac","6.4 km","Yes","Restricted"],
                  [472,"Muxarello","Italy","Tarmac","15.4 km","Yes","Restricted"],
                  [479,"Shomaru Pass","Japan","Tarmac","5.8 km","Yes","Open"],
                  [480,"Shomaru Pass II","Japan","Tarmac","5.8 km","Yes","Open"],
                  [481,"Karlstad","Sweeden","Snow","1.9 km","Yes","Open"],
                  [482,"Karlstad II","Sweeden","Snow","1.9 km","Yes","Open"],
                  [484,"Humalamaki Reversed","Finland","Gravel","4.4 km","Yes","Open"],
                  [488,"Jirkovicky","Montekland","Gravel","3.5 km","No","Restricted"],
                  [489,"Jirkovicky II","Montekland","Gravel","3.5 km","No","Restricted"],
                  [490,"Sourkov","Montekland","Gravel","6.2 km","No","Restricted"],
                  [491,"Lernovec","Montekland","Gravel","5 km","No","Restricted"],
                  [492,"Uzkotin","Montekland","Gravel","7.8 km","No","Restricted"],
                  [493,"Hroudovany","Montekland","Gravel","7.1 km","No","Restricted"],
                  [494,"Snekovice","Montekland","Gravel","8.6 km","No","Restricted"],
                  [495,"Lernovec II","Montekland","Gravel","5 km","No","Restricted"],
                  [496,"Uzkotin II","Montekland","Gravel","7.6 km","No","Restricted"],
                  [497,"Hroudovany II","Montekland","Gravel","7.1 km","No","Restricted"],
                  [498,"Snekovice II","Montekland","Gravel","8.6 km","No","Restricted"],
                  [499,"Sourkov 2","Montekland","Gravel","6.2 km","No","Restricted"],
                  [516,"Hradek 1","CZ","Tarmac","5.8 km","No","Open"],
                  [517,"Hradek 2","CZ","Tarmac","5.8 km","No","Open"],
                  [518,"Liptakov 1","CZ","Tarmac","6 km","No","Open"],
                  [519,"Liptakov 2","CZ","Tarmac","6 km","No","Open"],
                  [522,"Rally School Czech","Czech Republic","Tarmac","3.2 km","Yes","Open"],
                  [524,"Rally School Czech II","Czech Republic","Tarmac","3.1 km","Yes","Open"],
                  [528,"Kuadonvaara","Finland","Snow","5.7 km","Yes","Open"],
                  [533,"Karowa 2009","Poland","Tarmac","1.6 km","Yes","Open"],
                  [534,"Haugenau 2012","France","Tarmac","5.7 km","Yes","Open"],
                  [544,"Fernet Branca","Argentina","Gravel","6 km","Yes","Open"],
                  [545,"Junior Wheels I","Australia","Gravel","5.6 km","Yes","Open"],
                  [546,"Junior Wheels II","Australia","Gravel","5.6 km","Yes","Open"],
                  [550,"Foron","France","Tarmac","9.2 km","Yes","Open"],
                  [551,"Foron II","France","Tarmac","9.2 km","Yes","Open"],
                  [552,"Foron Snow","France","Snow","9.1 km","Yes","Open"],
                  [553,"Foron Snow II","France","Snow","9.1 km","Yes","Open"],
                  [555,"Maton I","France","Tarmac","3.5 km","Yes","Open"],
                  [556,"Maton II","France","Tarmac","3.5 km","Yes","Open"],
                  [557,"Red Bull HC","Italy","Gravel","14 km","Yes","Open"],
                  [558,"Maton snow","France","Snow","3.5 km","Yes","Open"],
                  [559,"Maton snow II","France","Snow","3.5 km","Yes","Open"],
                  [560,"Loch Ard","Great Britain","Gravel","8.3 km","Yes","Open"],
                  [561,"Loch Ard II","Great Britain","Gravel","8.3 km","Yes","Open"],
                  [565,"Undva Reversed","Estonia","Gravel","10 km","Yes","Open"],
                  [566,"Undva","Estonia","Gravel","10 km","Yes","Open"],
                  [570,"Peyregrosse - Mandagout","France","Tarmac","12.8 km","Yes","Open"],
                  [571,"Peyregrosse - Mandagout NIGHT","France","Tarmac","12.8 km","Yes","Open"],
                  [572,"Castrezzato","Italy","Tarmac","8.1 km","Yes","Open"],
                  [573,"SS Daniel Bonara","Italy","Tarmac","5.5 km","Yes","Open"],
                  [574,"Sorica","Slovenia","Tarmac","15.5 km","Yes","Open"],
                  [582,"Barum rally 2009 Semetin","CZ","Tarmac","11.7 km","Yes","Open"],
                  [583,"Barum rally 2010 Semetin","CZ","Tarmac","11.7 km","Yes","Open"],
                  [585,"SWISS II","Switzerland","Gravel","5.6 km","Yes","Open"],
                  [586,"SWISS I","Switzerland","Tarmac","5.6 km","Yes","Open"],
                  [587,"Swiss IV","Swiss","Gravel","8.2 km","Yes","Open"],
                  [589,"Swiss III","Swiss","Tarmac","8.2 km","Yes","Open"],
                  [590,"Blanare","France","Snow","7.6 km","Yes","Open"],
                  [591,"Blanare II","France","Snow","6.6 km","Yes","Open"],
                  [592,"Slovakia Ring 2014","Slovakia","Tarmac","11 km","Yes","Open"],
                  [593,"Slovakia Ring 2014 II","Slovakia","Tarmac","11 km","Yes","Open"],
                  [595,"Sardian","USA","Tarmac","5.1 km","Yes","Open"],
                  [596,"Sardian Night","USA","Tarmac","5.1 km","Yes","Open"],
                  [597,"Mlynky Snow II","Slovakia","Snow","7.1 km","Yes","Open"],
                  [598,"Pikes Peak 2008","USA","Tarmac","19.9 km","Yes","Open"],
                  [599,"Northumbria","Great Britain","Gravel","9 km","Yes","Open"],
                  [601,"Northumbria Tarmac","Great Britain","Tarmac","9 km","Yes","Open"],
                  [700,"Passo Valle","Italy","Tarmac","5.8 km","Yes","Open"],
                  [711,"Akagi Mountain","Japan","Tarmac","3.5 km","Yes","Open"],
                  [712,"Akagi Mountain II","Japan","Tarmac","3.5 km","Yes","Open"],
                  [777,"Pian del Colle","Italy","Tarmac","8.3 km","Yes","Open"],
                  [778,"Pian del Colle Reversed","Italy","Tarmac","8.4 km","Yes","Open"],
                  [779,"Pian del Colle Snow","Italy","Snow","8.3 km","Yes","Open"],
                  [780,"Pian del Colle Snow Reversed","Italy","Snow","8.4 km","Yes","Open"],
                  [800,"Ai-Petri","Ukraine","Tarmac","17.3 km","Yes","Open"],
                  [801,"Uchan-Su","Ukraine","Tarmac","10.8 km","Yes","Open"],
                  [802,"Ai-Petri Winter","Ukraine","Snow","17.3 km","Yes","Open"],
                  [803,"Uchan-Su Winter","Ukraine","Snow","10.8 km","Yes","Open"],
                  [810,"Livadija","Ukraine","Tarmac","5.5 km","Yes","Open"],
                  [811,"Livadija II","Ukraine","Tarmac","5.5 km","Yes","Open"],
                  [830,"Azov","Ukraine","Gravel","19.1 km","Yes","Open"],
                  [831,"Azov II","Ukraine","Gravel","19.2 km","Yes","Open"],
                  [886,"Zaraso Salos Trekas - 5 laps","Lithuania","Gravel","5 km","Yes","Open"],
                  [887,"Zaraso Salos Trekas - 2 laps","Lithuania","Gravel","2 km","Yes","Open"],
                  [888,"Shakedown Rally del Salento 2014","Italy","Tarmac","3.8 km","Yes","Open"],
                  [911,"Torre Vecchia","Italy","Tarmac","9.8 km","Yes","Open"],
                  [969,"Tavia","Italy","Gravel","3.8 km","Yes","Open"],
                  [979,"Berica","Italy","Gravel","14.8 km","Yes","Open"],
                  [980,"Rally Wisla Shakedown","Poland","Tarmac","2.5 km","Yes","Open"],
                  [981,"Hyppyjulma gravel","Finland","Gravel","6.1 km","Yes","Open"],
                  [982,"Hyppyjulma gravel II","Finland","Gravel","6.1 km","Yes","Open"],
                  [983,"Hyppyjulma tarmac","Finland","Tarmac","6.1 km","Yes","Open"],
                  [984,"Hyppyjulma tarmac II","Finland","Tarmac","6.1 km","Yes","Open"],
                  [985,"Kolmenjarvet gravel","Finland","Gravel","6.1 km","Yes","Open"],
                  [986,"Kolmenjarvet gravel II","Finland","Gravel","6.1 km","Yes","Open"],
                  [987,"Kolmenjarvet tarmac","Finland","Tarmac","6.1 km","Yes","Open"],
                  [988,"Kolmenjarvet tarmac II","Finland","Tarmac","6.1 km","Yes","Open"],
                  [993,"Kormoran Shakedown","Poland","Gravel","5.2 km","Yes","Open"],
                  [994,"Kormoran I","Poland","Gravel","10.3 km","No","Open"],
                  [995,"Kormoran II","Poland","Gravel","12 km","No","Open"],
                  [1012,"Puy du Lac","France","Tarmac","5 km","Yes","Open"],
                  [1024,"GB Sprint Extreme","Great Britain","Gravel","6.7 km","Yes","Open"],
                  [1025,"FSO Zeran - Warsaw","Poland","Tarmac","7.1 km","Yes","Open"],
                  [1033,"Track Test","Test","Tarmac","1.6 km","Yes","Restricted"],
                  [1141,"Snow Cote D'Arbroz","France","Snow","4.5 km","Yes","Open"],
                  [1142,"Snow Joux Verte","France","Snow","7.9 km","Yes","Open"],
                  [1143,"Snow Bisanne","France","Snow","5.6 km","Yes","Open"],
                  [1144,"Snow Joux Plane","France","Snow","11.1 km","Yes","Open"],
                  [1145,"Snow Joux Verte II","France","Snow","7.9 km","Yes","Open"],
                  [1146,"Snow Cote D'Arbroz II","France","Snow","4.5 km","Yes","Open"],
                  [1147,"Snow Bisanne II","France","Snow","5.6 km","Yes","Open"],
                  [1148,"Snow Joux Plane II","France","Snow","11.1 km","Yes","Open"],
                  [1899,"Courcelles Val'd Esnoms","France","Tarmac","9.9 km","Yes","Open"],
                  [1900,"Vieux Moulin-Perrancey","France","Gravel","20.5 km","Yes","Open"]];

// A couple of helpful vars to make traversing the stage data easier.
var stageID = 0, stageName = 1, stageCountry = 2, stageSurface = 3, stageDistance = 4, stageIsShakedownable = 5, stageIsRestricted = 6;

// Parsing the URL looking for a certain parameter (returning a string with value, or empty string if no value found).
function parseurl( name ){
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( document.URL );
  if( results === null )
    return "";
  else{/*
      if (name == "stageid"){
          return results[0]; // results "stageid=13"
      }
      else {
          return results[1];
      }*/
      return results[1];
  }
}

// Creating a base link to display in each row of the table. Link's contents depend on the type of site we're on.
function makeLinkBase(){
	var doLinkow = [];
	if (whereAmI == "urec" || whereAmI == "urank") { doLinkow[0] = whereAmI.replace("u", "stage"); }
	else { if (whereAmI == "tstats") { switch (parseurl("type")) { case "1": doLinkow[0] = "stagerec"; break; case "3": doLinkow[0] = "stagerank"; break; default: doLinkow[0] = "stagerec"; break; }}}
	doLinkow[1] = parseurl("classid");
	doLinkow[2] = parseurl("state");
	if (doLinkow[1] === "") { doLinkow[1] = 1; }

	return doLinkow;
}

// Finding the results table, non-jquery method (legacy).
function findResultsTable(){
	var tables = document.getElementsByTagName("table");
	for (var i = 0; i < tables.length; i++) {
		if (tables[i].width == '70%'){
			return tables[i].children[0];
		}
	}
	return null;
}

// Adding a head to the results table (it's missing by default)
function addHeadAndBody(){
    console.log("Searching for the head...");
    var thead = $("thead", resultsTable);
    /*console.log(thead);*/
    if (thead.length === 0){ // To avoid adding a second thead
        console.log("No head, wrapping.");
        $("<thead></thead>").prependTo(resultsTable);
        $("tr:first", resultsTable).appendTo($("thead", resultsTable));
    }
}

// Function finding and returning results table (records/ranks) via jQuery selector.
// The only unique attribute of that table is it's hard-coded width of 70% (no special classes and/or ids.
function findResultsTableJQ(){
    return $('table[width="70%"]');
}

// Function finding the correct ID of s
function findStage(name){
    for (var i = 0, len = stagesDict.length; i < len; i++)
    {
        if (stagesDict[i][stageName] === name)
        {
            return stagesDict[i]; // Return as soon as the object is found with the matching name
        }
    }
    return 0; // If the loop does not find a matching name - return 0
}

// Function changing the contents of the stages table (Country converted to the 2digit country codes according to the dictionary
function convertStageCountries(){
    console.log("Processing stage countries (dict)...");
    var currCountry = 0;
    var targetCountry = 0;
    $.each((stagesDict), function (key, value){
        // console.log("Processing " + value);
        currCountry = value[stageCountry];
        if (currCountry !== undefined){
            targetCountry = countriesDict[currCountry];
            if (targetCountry !== undefined && targetCountry !== 0){
                value[stageCountry] = targetCountry;
            } else {currCountry = "ROW";}
        }
        else {}
        // console.log("Results: " + value + " // Country: " + currCountry + "->" + targetCountry);
    });
    console.log("Stage countries processed!");
}

// Function sorting the stagesDict alphabetically (due to automatization reasons will not be done by hand)
// NOT USED due to performance issues. Insead all list are sorted during adding to table/selector.
function sortStagesDict(){
    stagesDict.sort(function (a, b) {

            var A = a[stageName].toUpperCase();
            var B = b[stageName].toUpperCase();
            console.log(A + " i " + B);

            if(A < B) {console.log("-1"); return -1;}
            if(A > B) {console.log("1"); return 1;}
            return 0;
        });
    $.each((stagesDict), function (key, value){ console.log(key + "//" + value);});
}

// Apllying correct classes (country codes) to all rows of the table + removing empty rows (containing blank names).
function classifyStages(){
    var currStage = 0;
    var stageData = 0;
    $.each($("tr[class=row2], tr[class=row3]",resultsTable), function (key, value) {
        currStage = $("td:first-of-type", this).text(); // Picking the name of the stage
        if (currStage === ""){ // Checking wheter or not the name is blank to avoid unnecessary processing.
            $(this).remove();
            console.warn("Removing empty line at row " + key);
        }else {
            stageData = findStage(currStage); // Finding the data for the stage (in stagesDict)
            // console.log("Processing stage: " + currStage + " // results: [" + stageData + "]");
            if(stageData !== 0){ // Processing further only if some data is found.
                if (stageData[stageCountry] !== undefined){ // Checking if the country from stageData exists, if not -> apply ROW class)
                    $(this).addClass(stageData[stageCountry]);
                    // console.log("%cProcessing succesful, added class: " + countriesDict[stageData[stageCountry]], 'background: #B2FFB2; color: #233323');
                    $("td:first", this).append("<br/> (" + stageData[stageSurface] + ", " + stageData[stageDistance] + ")");
                }else{ // No country data found - apllying the default class (ROW)
                    console.warn("No country entry for: " + stageData[stageCountry]);
                    $(this).addClass("ROW");
                }
            }else { // No stage data found - applying the default class (ROW)
                console.warn("No stage data for: " + currStage);
                $(this).addClass("ROW");
            }
        }
    });
}

function clearBlanks(){
	var linkiWewn = tabelkaRekordy.getElementsByTagName("a");
	for (var i = linkiWewn.length-1; i >= 0; i--){ if (linkiWewn[i].innerHTML === "") { tabelkaRekordy.removeChild(linkiWewn[i].parentNode.parentNode); } }
}

// Function creatin a row for the stage in the stages table. Takes innerHTML for each column.
function createStage( nazwaos , stageid , base , rowstyl , column2 , column3 , column4 , column5 ) {
	var rowTemp = document.createElement("tr");
	var komTemp = document.createElement("td");
	rowTemp.setAttribute("class", rowstyl);
	komTemp.innerHTML = '<a href="http://rbr.onlineracing.cz/index.php?act=' + base[0] + '&stageid=' + stageid + '&classid=' + base[1] + '&state=' + base[2] + '">' + nazwaos + '</a>';
	rowTemp.appendChild(komTemp);
	var tdcount;
	var tempTD;
	if (whereAmI == "urec" || whereAmI == "urank") {tdcount = 5; } else {tdcount = 4;}
	for(var i = 1; i<tdcount; i++) {
		tempTD = document.createElement("td");
		tempTD.innerHTML = "";
		if (i == 1 && typeof column2 != "undefined") { tempTD.innerHTML = column2; }
		if (i == 2 && typeof column3 != "undefined") { tempTD.innerHTML = column3; }
		if (i == 3 && typeof column4 != "undefined") { tempTD.innerHTML = column4; }
		if (i == 4 && typeof column5 != "undefined") { tempTD.innerHTML = column5; }
		rowTemp.appendChild(tempTD);
	}
	return rowTemp;
}

// Function creating a "subtitle", coloured breaker in the stages list descripting the country/region.
function createSub ( subtitle , country, flag ) {
	var rowSub = document.createElement("tr");
    rowSub.setAttribute("class", country + " header");
    //Adding an option to collapse rows until next country
    $(rowSub).click(function(){
        if ($(this).next().hasClass("hidden")){
            $(this).nextUntil('tr.header').removeClass("hidden");
            countriesHidden[country] = "false";
            // $(this).nextUntil('tr.header').toggle();
        } else {
            $(this).nextUntil('tr.header').addClass("hidden");
            countriesHidden[country] = "true";
            // console.log(countriesHidden);
        }
        GM_setValue("countriesHiddenSaved", JSON.stringify(countriesHidden));
        console.log(JSON.stringify(countriesHidden));
    });
	var thSub = document.createElement("th");
	thSub.setAttribute("colspan", "5");
	thSub.setAttribute("style", 'background-color: #840000 /*#49433a darkkhaki*/; background-image: none !important; color: white; font-weight: normal;');
	thSub.innerHTML = subtitle;
	if (flag !== undefined) {
		var flagIcon = document.createElement("IMG");
		flagIcon.src = flag;
		flagIcon.setAttribute("style", "float: left; margin-left: 3px; border: 1px solid black;");
		flagIcon.setAttribute("alt", subtitle);
		flagIcon.setAttribute("title", subtitle);
        var flagIcon2 = $(flagIcon).clone();
        flagIcon.style="float: right; margin-right: 3px; border: 1px solid black;";
		thSub.appendChild(flagIcon);
		$(thSub).append(flagIcon2);
	}
    // Appending contents to the row
	rowSub.appendChild(thSub);

	return rowSub;
}

// A simple function adding a missing GT class to filter list in results of events using legacy physics.
function addGTLink(){
	var links = document.getElementsByTagName("a");

	for (var i = 0; i < links.length; i++) {
		var isLastClass = links[i].href.indexOf("&class=11");

		if (isLastClass > -1 && links[i].text == "H"){
			var gt		= document.createElement("a");
			gt.href		= links[i].href.replace("&class=11","&class=14");
			gt.innerHTML = "GT";
			gt.style.position = "relative";
			gt.style.left = "-5px";
			gt.style.top = "0px";
            // Appending the creating link to the end of the listed classes.
            links[i].parentNode.appendChild(gt);
		}
	}
}

// Function adding the newer classes to the selector. Uses JQUERY!
function appendClasses(){
    //Finding the selector with id classid
    var classBox = $("#classid");
    // Clearing the default options
	$("option", classBox).remove();
    // Populating the box with the new layout.
    classBox.append($('<option>', {value: 0,text: "Select class", disabled: true}));
    classBox.append($('<option>', {value: 0,text: "-- NGP --", disabled: true}));
    classBox.append($('<option>', {value: classesDict["RC1"],text: "RC1"}));
    classBox.append($('<option>', {value: classesDict["RC2"],text: "RC2"}));
    classBox.append($('<option>', {value: classesDict["RGT"],text: "RGT"}));
    classBox.append($('<option>', {value: classesDict["RC3"],text: "RC3"}));
    classBox.append($('<option>', {value: classesDict["RC4"],text: "RC4"}));
    classBox.append($('<option>', {value: classesDict["RC5"],text: "RC5"}));
    classBox.append($('<option>', {value: classesDict["WRC"],text: "WRC"}));
    classBox.append($('<option>', {value: classesDict["H/B"],text: "H/B"}));
    classBox.append($('<option>', {value: classesDict["H/A"],text: "H/A"}));
    classBox.append($('<option>', {value: classesDict["H/4"],text: "H/4"}));
    classBox.append($('<option>', {value: classesDict["H/2"],text: "H/2"}));
    classBox.append($('<option>', {value: 0,text: "-- Legacy --", disabled: true}));
    classBox.append($('<option>', {value: classesDict["WRC legacy"],text: "WRC legacy"}));
    classBox.append($('<option>', {value: classesDict["N4"],text: "N4"}));
    classBox.append($('<option>', {value: classesDict["S2000"],text: "S2000"}));
    classBox.append($('<option>', {value: classesDict["S1600"],text: "S1600"}));
    classBox.append($('<option>', {value: classesDict["A8"],text: "A8"}));
    classBox.append($('<option>', {value: classesDict["A7"],text: "A7"}));
    classBox.append($('<option>', {value: classesDict["A6"],text: "A6"}));
    classBox.append($('<option>', {value: classesDict["A5"],text: "A5"}));
    classBox.append($('<option>', {value: classesDict["A7"],text: "A7"}));
    classBox.append($('<option>', {value: classesDict["N3"],text: "N3"}));
    classBox.append($('<option>', {value: classesDict["H"],text: "H"}));
    classBox.append($('<option>', {value: classesDict["GT"],text: "GT"}));

    // Checking what class should be set as currently selected in the selectbox.
	var currClass = parseurl("classid");
    // If current url without a specified class - revert to the default, WRC legacy.
    // Not very efficient, as it does not break after finding a correct match (iterates through the entire list every time.
    if (currClass === "") { classBox.val(classesDict["WRC legacy"]); }
    else {
        for(var classKey in classesDict){
            if (classesDict[classKey] == currClass) {
                classBox.val(classesDict[classKey]);
            }
        }
    }
}

function addMissingRanks(){
	tabelkaRekordy.insertBefore(createStage("Sikakama II", "16", linkBase, "row3"), tabelkaRekordy.children[7]);
	tabelkaRekordy.insertBefore(createStage("Autiovaara II", "17", linkBase, "row2"), tabelkaRekordy.children[8]);
	tabelkaRekordy.insertBefore(createStage("Falstone II", "26", linkBase, "row3"), tabelkaRekordy.children[15]);
	tabelkaRekordy.insertBefore(createStage("Shepherds Shield II", "27", linkBase, "row2"), tabelkaRekordy.children[16]);
	tabelkaRekordy.insertBefore(createStage("Greenhills II", "30", linkBase, "row2"), tabelkaRekordy.children[17]);
	tabelkaRekordy.insertBefore(createStage("Mineshaft II", "37", linkBase, "row3"), tabelkaRekordy.children[24]);
	tabelkaRekordy.insertBefore(createStage("Bisanne II", "47", linkBase, "row3"), tabelkaRekordy.children[31]);
	tabelkaRekordy.insertBefore(createStage("Joux Plane II", "48", linkBase, "row2"), tabelkaRekordy.children[32]);
	tabelkaRekordy.insertBefore(createStage("Sipirkakim II", "50", linkBase, "row2"), tabelkaRekordy.children[33]);
	tabelkaRekordy.insertBefore(createStage("Pirka Menoko II", "57", linkBase, "row3"), tabelkaRekordy.children[40]);
	tabelkaRekordy.insertBefore(createStage("Frazier Wells II", "60", linkBase, "row2"), tabelkaRekordy.children[41]);
	tabelkaRekordy.insertBefore(createStage("Hualapai Nation II", "67", linkBase, "row3"), tabelkaRekordy.children[48]);
	tabelkaRekordy.appendChild(createStage("Stryckovy - Zadni Porici", "106", linkBase, "row2"));
	tabelkaRekordy.appendChild(createStage("PTD Rallysprint", "107", linkBase, "row3"));
	tabelkaRekordy.appendChild(createStage("Osli - Stryckovy", "108", linkBase, "row2"));
	tabelkaRekordy.appendChild(createStage("Hradek 1", "516", linkBase, "row3"));
	tabelkaRekordy.appendChild(createStage("Hradek 2", "517", linkBase, "row2"));
	tabelkaRekordy.appendChild(createStage("Liptakov 1", "518", linkBase, "row3"));
	tabelkaRekordy.appendChild(createStage("Liptakov 2", "519", linkBase, "row2"));
}

// Function adding new rows with Montekland stages (they are ommited from the "Records" page by default). Uses JQUERY
function addMontekland(){ // records are ignored now -- Separate function, because it has to be added both to the records and ranks.
    console.log("Adding Montekland...");
    resultsTable.append(createStage("Sourkov", "490", linkBase, "row2"));
	resultsTable.append(createStage("Lernovec", "491", linkBase, "row3"));
	resultsTable.append(createStage("Uzkotin", "492", linkBase, "row2"));
	resultsTable.append(createStage("Hroudovany", "493", linkBase, "row3"));
	resultsTable.append(createStage("Snekovice", "494", linkBase, "row2"));
	resultsTable.append(createStage("Lernovec II", "495", linkBase, "row3"));
	resultsTable.append(createStage("Uzkotin II", "496", linkBase, "row2"));
	resultsTable.append(createStage("Hroudovany II", "497", linkBase, "row3"));
	resultsTable.append(createStage("Snekovice II", "498", linkBase, "row2"));
	resultsTable.append(createStage("Sourkov 2", "499", linkBase, "row3"));
    console.log("... Montekland added!");
}

// Function sorting the stages according to the country code
function sortStagesByCountry(){
    console.log("Starting sorting...");
    var currentSelection = 0;
    for (var i = 0; i < countriesSortOrder.length; i++) {
        console.log("Moving " + countriesSortOrder[i][1] + "...");
        currentSelection = $("."+countriesSortOrder[i][0], resultsTable);
        currentSelection.sort(function (a, b) {

            var A = $(a).find('td').eq(0).text().toUpperCase();
            /*console.log($(a).find('td').eq(0).text().toUpperCase());*/
            var B = $(b).find('td').eq(0).text().toUpperCase();

            if(A < B) {return -1;}
            if(A > B) {return 1;}
            return 0;
        });
        resultsTable.append(currentSelection);
    }
    console.log("Sorting finished!");
}

// Inserting the colorfull "subtitles" with country names and flags in front of the stages.
// Using the rbr-czech flags to minimize overhead where possible :)
function addSubtitles(){
    console.log("Adding subtitles...");
    var newSub = 0;
    for (var i = 0; i < countriesSortOrder.length; i++) {
        console.log("Subbing " + countriesSortOrder[i][1] + "...");
        newSub = createSub(countriesSortOrder[i][1], countriesSortOrder[i][0],  countriesSortOrder[i][2]);
        $(newSub).insertBefore($("."+countriesSortOrder[i][0]+":first", resultsTable));
    }
    console.log("Subtitles added!");
}

// Applying correct classes to all the rows (row2/row3) to "paint" them the correct colour after sorting.
function reClassifyRows(){
    console.log("Repainting the rows...");
    $.each($(".row2, .row3", resultsTable), function (key, value) {
        $(this).removeClass("row2");
        $(this).removeClass("row3");
        $(this).addClass("row"+ (2+key%2));
    });
    console.log("Repainting finished!");
}

// Checking and hiding the rows according to the saved data. Done at the begining of the pageload + on demand (via a button).
function reHideStageRows(){
    console.log("Hiding the hidden rows...");
    var stagesRowsOnly = $(".row2, .row3", resultsTable); // Selecting only the inside rows with stages.
    var currentCountry = 0;
    var currentCountryName = 0;
     $.each(stagesRowsOnly, function (key, value) { // First un-hiding all the rows (resetting the field).
        $(this).removeClass("hidden");
     });
    for (var i = 0; i < countriesSortOrder.length; i++) { // Iterating through all the countries to check if they should be hidden or not.
        currentCountry = countriesSortOrder[i][0];
        currentCountryName = countriesSortOrder[i][1];
        // console.log("Current country: " + currentCountry + ". Hidden: "+ countriesHidden[currentCountry]);
        if(countriesHidden[currentCountry] === "true") { // If the country is marked as hidden - we hide it.
            $.each(stagesRowsOnly.filter("." + currentCountry), function (key, value){ // Filter the stage rows by current country
                $(this).addClass("hidden"); // Hide all rows with country class.
            });
        }
    }
    console.log("Hiding finished!");
}

// Creating a drop-down menu with full list of stages available.
function createStageDropdown(){
	var newSelect = document.createElement("select");
	newSelect.setAttribute("id", "stageid");
	newSelect.setAttribute("name", "stageid");
	newSelect.setAttribute("style", "width: 200px;");
	newSelect.setAttribute("onChange", "document.getElementById('records').submit()");
    var newSelectJQ = $(newSelect); // Just to easily use jQuery
    newSelectJQ.append($('<option>', {value: 0, text: "Choose another stage", disabled: true}));
    var currentCountry = 0;
    var currentCountryName = 0;
    var currentSelection = 0;
    for (var i = 0; i < countriesSortOrder.length; i++) {
        currentCountry = countriesSortOrder[i][0];
        currentCountryName = countriesSortOrder[i][1];
        console.log("Selector country: " + currentCountryName);
        currentSelection = $.grep(stagesDict, function( n ) {
            return ( n[stageCountry] ==  currentCountry);
        });
        if(currentSelection.length !== 0){
            newSelectJQ.append($('<option>', {value: 0, text: currentCountryName, disabled: true}));
            console.log("Found " + currentSelection.length + " stages [" + currentCountry + "]. Sorting and adding!");
        } else {
            console.log("No entries found for [" + currentCountry + "], skipping!");
        }
        currentSelection.sort(function (a, b) {
            var A = a[stageName].toUpperCase();
            var B = b[stageName].toUpperCase();
            if(A < B) {return -1;}
            if(A > B) {return 1;}
            return 0;
        });
        $.each($(currentSelection), function (key, value) {
            newSelectJQ.append($('<option>', {value: value[stageID],text: value[stageName]}));
        });
    }
    var currStage = parseurl("stageid");
    console.log("Current stage ID: " + currStage);
    // If current url without a specified track - revert to the default, "Select stage".
    // Not very efficient, as it does not break after finding a correct match (iterates through the entire list every time.
    if (currStage === "") { newSelectJQ.val(0); }
    else {
        for(var stageKey in stagesDict){
            if (stagesDict[stageKey][stageID] == currStage) {
                console.log(stagesDict[stageKey]);
                newSelectJQ.val(stagesDict[stageKey][stageID]);
            }
        }
    }
	//newSelect.selectedIndex = 0;
    console.log("Selector completed, returning!");
    var stateSelector = $("#state");
    console.log(stateSelector);
    console.log(newSelectJQ);
    $("input[name=stageid]", "#records").remove();
    $(newSelectJQ).insertBefore(stateSelector);
	//return newSelect;
}

function addStyling(){
    var css = document.createElement('style');
    css.type = 'text/css';

    // var styles = 'tr.FI>td:first-of-type { background-color: yellow }';
    // styles += ' tr.CZ>td:first-of-type { text-align: right; }';

    var styles = "tr.hidden { display: none }" +
        "#btnTopHolder {display: block; width: 300px; /*background-color: white;*/ min-height: 10px; overflow: hidden; margin-top: -10px;}" +
        ".btnTop { padding: 10px 5px; display:block; border: 2px solid #840000; color: white;; float: left; width: calc(50% - 18px); margin: 0 2px; border-radius: 4px;}" +
        ".btnTop:active, tr.header:active { transition: all 100ms ease; transform: scale(.95); opacity: .75;}" +
        ".btnTop:hover { transition: all 60ms ease; opacity: .85; background-color:#840000}" +
        " tr.header:hover { transition: all 120ms ease; opacity: .85;}" +
        " .row2:hover, .row3:hover { transition: all 120ms ease; opacity: .85;}" +
        "";


    if (css.styleSheet) css.styleSheet.cssText = styles;
    else css.appendChild(document.createTextNode(styles));

    document.getElementsByTagName("head")[0].appendChild(css); // Apppending the style to the head.
}

function addHiderButtons(){
    $("<div id=\"btnTopHolder\"/>").insertBefore(resultsTable);
    $("<br/>").insertBefore(resultsTable);
    // Creating a div that will serve as a button.
    var btnHideAll = document.createElement("div");
    btnHideAll.setAttribute("id", "btnHideAllStages"); // Unique ID for the button.
    btnHideAll.setAttribute("class", "btnTop"); // Styleable class.
    btnHideAll.setAttribute("title", "Click to collapse all countries"); // Hover text.
    btnHideAll.innerHTML = "Collapse all"; // Button text.
    var currentCountry = 0;
    // var currentCountryName = 0; // Temp vars to iterate easier.
    $(btnHideAll).click(function(){
        console.log("Collapsing all countries!");
        for (var i = 0; i < countriesSortOrder.length; i++) { // Iterating through every possible country.
            currentCountry = countriesSortOrder[i][0];
            // currentCountryName = countriesSortOrder[i][1]; // Not used ATM
            countriesHidden[currentCountry]="true"; // Changing the object parameter for each country.
        }
        GM_setValue("countriesHiddenSaved", JSON.stringify(countriesHidden)); // Saving the current state to JSON string.
        reHideStageRows(); // Basically adding the "hidden" class to all the rows.
    });
    var btnShowAll = document.createElement("div");
    btnShowAll.setAttribute("id", "btnHideAllStages"); // Unique ID for the button.
    btnShowAll.setAttribute("class", "btnTop"); // Styleable class.
    btnShowAll.setAttribute("title", "Click to expand all countries"); // Hover text.
    btnShowAll.innerHTML = "Expand all"; // Button text.
    $(btnShowAll).click(function(){ // Quick function cleaning the hide/expand data.
        console.log("Expanding all countries!");
        countriesHidden ={}; // Empty the object.
        // console.log(countriesHidden);
        GM_setValue("countriesHiddenSaved", "{}"); // Empty the saved value (replace with empty JSON string).
        reHideStageRows(); // Remove "hidden" class from all the rows.
    });
    // Inserting the buttons in front of the table, inside the holder-container..
    $("#btnTopHolder").prepend(btnHideAll);
    $("#btnTopHolder").prepend(btnShowAll);
}

// ************************************ END OF FUNCTIONS ************************************
// Processing the document itself
addStyling(); // Adding special styling

// Checking for car class selector (drop-down). Appears on records and ranks sites.
// If exists: appending the additional car classes.
if (document.getElementById("classid")) { appendClasses(); }

// Checking the type of handled site we are on (act=).
var whereAmI = parseurl("act");

// If we are NOT on the tournament results page: proceed with finding the results table, preparing the linkbase etc.
if (whereAmI.indexOf("tourmntres") == -1) {
    var resultsTable = findResultsTableJQ();
    addHeadAndBody();
    convertStageCountries();
    var countriesHidden = JSON.parse(GM_getValue("countriesHiddenSaved", "{}"));
    console.log(typeof(countriesHidden));
    console.log(countriesHidden);
    var linkBase = makeLinkBase();
} else { addGTLink(); } // If on a page with records -> add the missing GT link

switch(whereAmI) {
	case "urank":
	case "tstats":
		if (parseurl("type") !="1"){
			addMissingRanks();
		}
	case "urec":
         // Find the correct table - globally.
		addMontekland(); // Add Montek first, because it has to be classified etc.
        classifyStages(); // Classify all the rows with country codes
        sortStagesByCountry();
        addSubtitles();
		reClassifyRows();
        reHideStageRows();
        addHiderButtons();
		break;
	case "stagerec":
	case "stagerank":
        createStageDropdown();
		document.getElementById("state").parentNode.insertBefore(document.createElement("br"), document.getElementById("state"));
		document.getElementById("state").parentNode.insertBefore(document.createElement("br"), document.getElementById("state"));
		break;
	default:
		break;
}