GC-Vote

displays average votes and lets users vote for the quality of caches on geocaching.com

// ==UserScript==
// @name           GC-Vote
// @namespace      http://dosensuche.de
// @include        http*://www.geocaching.com/seek/cache_details.aspx?*
// @include        http*://www.geocaching.com/geocache/GC*
// @include        http*://www.geocaching.com/my/*
// @include        http*://www.geocaching.com/map*
// @include        http*://www.geocaching.com/profile/*
// @include        http*://www.geocaching.com/seek/nearest.aspx*
// @include        http*://www.geocaching.com/seek/gmnearest.aspx*
// @include        http*://www.geocaching.com/seek/log.aspx?*
// @include        http*://www.geocaching.com/seek/cdpf.aspx?*
// @include        http*://www.geocaching.com/bookmarks/view.aspx?*
// @include        http*://www.geocaching.com/bookmarks/bulk.aspx?*
// @include        http://*gcvote.de/*
// @include        http://*gcvote.com/*
// @include        http://*dosensuche.de/GCVote/*
// @include        https://dl.dropbox.com/*
// @include        https://ssl.webpack.de/gcvote.com/*
// @grant   GM_getValue
// @grant   GM_setValue
// @grant   GM_log
// @grant   GM_xmlhttpRequest
// @grant   GM_addStyle
// @grant   unsafeWindow
// @version 3.3
// @description    displays average votes and lets users vote for the quality of caches on geocaching.com
// ==/UserScript==
//
// Author: guido.wegener@gmx.de
// Version 3.3
var version = "3.3";
 
var voteServerBase = "https://ssl.webpack.de/gcvote.com"; // connection to server
var GETVOTES = voteServerBase + "/getVotes.php";
var SETVOTE = voteServerBase + "/setVote.php";
var LISTVOTES = voteServerBase + "/listUserVotes.php";
var CHANGEPASSWORD = voteServerBase + "/changePassword.php";
var iconSetUrl = "https://dl.dropbox.com/s/ttvxvywl493dljq/gcVoteIconData.json";
 
var LOGGING;
var HALFSTARS;
 
var mapdivRange = (typeof(opera) == "undefined" ? 2 : 3);
 
var logInLink;
var userName;
var unescapedUserName;
var loggedIn;
var securityState;
var translations;
var batchesWaiting = 0;
var currentBatch = 0;
var reqCachesIds;
var GCVoteAdvertisementDefault;
var browserType = "unknown";
var languageHelper;
 
var pageControl;
var iconStorage;
 
var loaderImg = 'data:image/gif;base64,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';
var errorImg = 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAASCAYAAAC9+TVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAhtJREFUeNqUlN1KG0EUx8/ZUBMQdIvQmIuC25i2bL5GUCsqaC57Jb3offcRfJQ+QecNCr3ybktVED9INBGhUpVSkijFbr2Jjd1Mz0yyZjOJth04O7tn/ud35uPsAHTakWWb0uAfmq4z5KNipc0WoCtNvt8HoHFGutNDK/0m8OFBMiODXARg0iEAStQVcl8qng4gLetozY7WIR3HYjIjncthcQCaCoGKGiCkLRgtgFUf0CODwGi6jHp3dzKrAqhX3+Q3wzoyTok+ohRtp7IqC2hZqJUo0yqJ3g8Y47PHZUftSeDZSuWY0EBDtO1mFOH7tYCW6EZTEJ87PnBC3922+TTPBLZBUSEgQYs1SNEkZ1UYtEwKEMAXPu874TjUT2D9eZ5FhHDjTd80oJv+FyJcDg/x+XLR0WMM3fEsZ8JEagSaEYQGdO3BWAwm7VF28Xqpr456ZnKxssho/mo5vxs+XJ5cgfAFxB5GYfTxcHCmJdqgwqMPG14f5PzlHAMkAOJtpptrHxo/b2AkHutNLYQCxde2vFtIvTCjZqAXEgE5Kd5SQN/xq4Ik0Li742F9YaqzBNQAwMc/7alNrC9Ns0EgQikQ1qbzcnBZn0Fip9RzCrUXjIE/AGTgK6xlqbR9qg3R/gHpvHjisOwM+oNrGarsltK2QRFwEpUyV+/VZNo8s+ziV8t+97e7pPokzU4t+8e30FVw50XzP5fSHwEGAKsF0Kl9SrDyAAAAAElFTkSuQmCC';
var gcVoteImg = 'data:image/png;base64,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';
var imgToggleOn = 'data:image/png;base64,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';
var imgToggleOff = 'data:image/png;base64,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';
var imgHighlight = 'data:image/png;base64,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';
     
//tableSorter images  * Copyright (c) 2007 Christian Bach * Licence: MIT (http://www.opensource.org/licenses/mit-license.php)
var tableSorterDown = 'data:image/png;base64,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%3D%3D';
var tableSorterUp = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAkdJREFUeNqkk89LYlEUx89yApmFC4MW1UJ3JS6CEA0jyFHjVeID8xEaPHsYUygMg23aBi2iP6BtUCCY1jDBgD9CXwr5gwra95d8ZtELTGs2c+B7F+d87+dezj1XAPlfvS5D0XmpcXiXJHnjQil/JXnj4vAuSeelNmL+EHLcyhApOdCqK+i9HdKPP9B7O2jVFSIlB8etDP+EHJk6q9dOjKc8iX6GaGcT5T5OtLNJop/BeMiz+svJkanzIeT2+Ypw2Y7xtI/a3SLYVlgwF/E2fSyYiwTbCmp3C6O3T7hs5/b5imGI7aCqotUUEv0MwbbCfGMWd30GAHd9hvnGLMH2a12rKRxUVUTENghxxsuT6L3vrHc0/GYAd32awfCbAfxmgPWOhn5nEC9PIiLOQYgnVBwj/fgT5V7B2/TwUXibPpT7OOnmHqHiGCLieQdRixPWTWL4zTnc9WlclSlclSnc9Wn85hx+M0C0FUOvbqMWJ0Yh2dKy1ZPUu568ab7hJdhYImGm0H4rZEvLoxAROQlf2jEecqjdDYLtJRYa1us0FgnWllC7GxiVHOFLOyJyMgxxikg+Wwi/zsljjkQ/RbQRQ7lRiLZiJPopjEqO1ZKTbCGMiOSHG2sTkZCInO6eh4gUHWh/wuhtnXRzD726jXYVIVJwsHseQkROLb9teGKdFv1aRGr6mY+1i3G+Fb6wdjGOfuZDRGpWPW/5R8beJiJ+y3D6BhvQtZXPWz7bZx/QZp0QsswnA8pbeecb4NNfPATzDOjd5kHI3wEAqGsEYNCAlrQAAAAASUVORK5CYII%3D';
var tableSorterBoth = 'data:image/png;base64,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%3D%3D';
//tableSorter images end
 
function getSelectedLanguage() {
    var languageText = document.getElementsByClassName("selected-language")[0].getElementsByTagName("a")[0].firstChild.nodeValue;
    log("Selected language: " + languageText.substring(0, languageText.length - 1));
    return languageText.substring(0, languageText.length - 1);
}
 
function extractUserNameFromTitle(title, shortenedName) {
    var namePrefix = shortenedName.slice(0, shortenedName.length - 1),
        nameStart = title.lastIndexOf(namePrefix),
        nameEnd,
        extractedName;
    switch (getSelectedLanguage()) {
        case "Eesti":
            nameEnd = title.length - 9;
            break;
        default:
            nameEnd = title.length;
            break;
    }
    extractedName = title.substring(nameStart, nameEnd);
    log("Name prefix: " + namePrefix);
    log("Extracted Name: " + extractedName);
    return extractedName;
}
 
function isUserNameShortened(userName) {
    var isShortened = "…" === userName.charAt(userName.length - 1);
    log("Username '" + userName + "' shortened: " + isShortened);
    return isShortened;
}
 
function findUserName() {
	var container = (document.getElementsByClassName("li-user-info")[0] || document.getElementsByClassName("li-user")[0] || null);
	if(container !== null){
		userName = container.children[0].textContent;
		unescapedUserName = userName;
		if (userName) {
			userName = encodeURIComponent(userName);
		}
		log("userName=" + userName + "  escaped:" + encodeURIComponent(userName));
	}
	else{
		log("no userName found");
	}
}
 
function main() {
    init();
    iconStorage = new iconStore();
    GCVoteAdvertisementDefault = "\n" + tl("(Rated %%% stars with [url=http://www.gcvote.com]GCVote[/url])");
    // This string is just a default and is only used for the first install.
    // "%%%" will be replaced by your selected vote and the resulting string is written to the log.
 
    if (document.getElementsByTagName("body")[0].getAttribute("GCVoteMarker")) {
        log("multiple instances running (" + document.getElementsByTagName("body")[0].getAttribute("GCVoteMarker") + ")");
    }
    else {
        document.getElementsByTagName("body")[0].setAttribute("GCVoteMarker", version);
        log("marking instance (" + document.getElementsByTagName("body")[0].getAttribute("GCVoteMarker") + ")");
        if (document.URL.search("gcvote.de") >= 0 || document.URL.search("gcvote.com") >= 0 || document.URL.search("dosensuche.de") >= 0) {
            displayVersionInfo();
        }
        else {
            if (!document.getElementById("ctl00_SiteContent_lblSubmitErrorInfo")) {
                findUserName();

                if (userName && document.URL.search("www\.geocaching\.com\/my\/") >= 0) {
                    insertGCVoteMenu();
                }
                if (document.URL == "http://www.geocaching.com/my/owned.aspx" || document.URL == "http://www.geocaching.com/seek/nearest.aspx?u=" + userName) {
                    userName = null;
                }

                if (document.URL.search("cache_details\.aspx") >= 0) {
                    pageType = "details";
                    initDetailsPage();
                }
                else if (document.URL.search("geocache\/GC") >= 0) {
                    pageType = "cachePageNew";
                    initNewCachePage();
                }
                else if (document.URL.search("cdpf\.aspx") >= 0) {
                    pageType = "print";
                    initPrintPage();
                }
                else if (document.URL.search("logs\.aspx") >= 0) {
                    pageType = "loglist";
                    initLongListPage();
                }
                else if (document.URL.search("owned\.aspx") >= 0) {
                    pageType = "loglist";
                    initListPage();
                }
                else if (document.URL.search("www.geocaching.com\/map") >= 0) {
                    pageType = "newMap";
                    if (browserType == "Chrome" || browserType == "FireFox") {
						if (browserType === "FireFox") {
							var valuesToFetch = ["logging", "halfstars", "iconStoreActiveIcon", "iconStoreIcons", "enableIcons", "enablePopup", "enableTable", "enableTableSort", "enableLocalCaching", "enableCacheGeneration", "enableAutomaticCacheGeneration", "enableGcPersoFix", "enableSaveVisibility",  "language", "cachedVoteData", "cachedCacheData"];
							for(i=0;i<valuesToFetch.length;i++){
								getValue(valuesToFetch[i]);
							}
						}

						var scriptString = "";
						scriptString += "var localStorageCache = JSON.parse(decodeURIComponent('"+encodeURIComponent(JSON.stringify(localStorageCache))+"'));\n";
						scriptString += "var LOGGING = '" + LOGGING + "'; \n" + log.toString();	
						scriptString += getValue.toString();
                        scriptString += setValue.toString();
						scriptString += iconStore.toString().replace("function", "function iconStore") + "\n var iconSetUrl = '" + iconSetUrl + "';\nvar iconStorage = new iconStore();\n";						
                        scriptString += "var loaderImg = '" + loaderImg + "';\n" + "var errorImg = '" + errorImg + "';\n" + "var gcVoteImg = '" + gcVoteImg + "';\n" + "var imgToggleOn = '" + imgToggleOn + "';\n" + "var imgToggleOff = '" + imgToggleOff + "';\n" + "var imgHighlight = '" + imgHighlight + "';\n" + "var tableSorterDown = '" + tableSorterDown + "';\n" + "var tableSorterUp = '" + tableSorterUp + "';\n" + "var tableSorterBoth = '" + tableSorterBoth + "';\n";
                        scriptString += "var translations = " + JSON.stringify(translations) + ";\n" + tl + "function getLanguage() {return '" + getLanguage() + "';}";
                        scriptString += (function(style){
							var sheet = document.createElement('style');
							sheet.innerHTML = style;
							document.body.appendChild(sheet);
						}).toString().replace("function", "function GM_addStyle");
                        scriptString += xmlhttpRequest.toString();     
                        scriptString += 'function requestVotesForWaypoints(waypoints){ window.postMessage({ type: "FROM_PAGE_GCVoteRequestVotes", text: JSON.stringify(waypoints) }, "*"); }';
                        scriptString += getThreshold.toString();
                        scriptString += avg2suffix.toString();

                        window.addEventListener("message", function (event) {
                            if (event.source != window) {
                                return;
                            }

                            if (event.data.type && (event.data.type == "FROM_PAGE_GCVoteRequestVotes")) {
                                var data = JSON.parse(event.data.text);
                                requestVotesForWaypoints(data);
                            }
                        }, false);

                        scriptString += "("+(function (newMapHandler, data) {
                            window["pageControl"] = new newMapHandler(data);
                            window.addEventListener("message", function (event) {
                                if (event.source != window) {
                                    return;
                                }

                                if (event.data.type && (event.data.type == "FROM_Ext_GCVoteDataRecived")) {
                                    var data = JSON.parse(event.data.text);
                                    window["pageControl"].newVoteData(data.waypoint, data.voteStars, data.voteCnt, data.cacheId, data.voteAvg, data.totalVoteCount, data.voteUser, data.sortedVotes, data.rawVotes);
                                }
                            }, false);
                        }).toString() + ")(" + newMapHandler + "," + JSON.stringify({
                            enableIcons: (getValue("enableIcons", true)),
                            enablePopup: (getValue("enablePopup", true)),
                            enableTable: (getValue("enableTable", true)),
                            enableTableSort: (getValue("enableTableSort", true)),
                            enableLocalCaching: (getValue("enableLocalCaching", true)),
                            enableCacheGeneration: (getValue("enableCacheGeneration", true)),
                            enableAutomaticCacheGeneration: (getValue("enableAutomaticCacheGeneration", true)),
                            enableGcPersoFix: (getValue("enableGcPersoFix", false)),
                            enableSaveVisibility: (getValue("enableSaveVisibility", false))
                        }) + ")";
						//console.log(scriptString);
						injectPageScript(scriptString);
                    }
                    else {
                        pageControl = new newMapHandler({
                            enableIcons: (getValue("enableIcons", true)),
                            enablePopup: (getValue("enablePopup", true)),
                            enableTable: (getValue("enableTable", true)),
                            enableTableSort: (getValue("enableTableSort", true)),
                            enableLocalCaching: (getValue("enableLocalCaching", true)),
                            enableCacheGeneration: (getValue("enableCacheGeneration", true)),
                            enableAutomaticCacheGeneration: (getValue("enableAutomaticCacheGeneration", true)),
                            enableGcPersoFix: (getValue("enableGcPersoFix", false)),
                            enableSaveVisibility: (getValue("enableSaveVisibility", false))
                        });
                    }
                }
                else if (document.URL.search("nearest\.aspx") >= 0) {
                    pageType = "nearestlist";
                    initListPage();
                }
                else if (document.URL.search("\/my\/$") >= 0 || document.URL.search("\/my\/#") >= 0 || document.URL.search("\/my\/[dD]efault\.aspx") >= 0) {
                    pageType = "overviewlist1";
                    initLongListPage();
                }
                else if (document.URL.search("\/my\/geocaches\.aspx") >= 0) {
                    pageType = "overviewlist2";
                    initListPage();
                }
                else if (document.URL.search("\/log\.aspx") >= 0) {
                    pageType = "logedit";
                    initLogEditPage();
                }
                else if (document.URL.search("\/bookmarks\/view\.aspx") >= 0 || document.URL.search("\/bookmarks\/bulk\.aspx") >= 0) {
                    pageType = "bookmarks";
                    initListPage();
                }
                else if (document.URL.search("\/my\/favorites\.aspx") >= 0) {
                    pageType = "favorites";
                    initLongListPage();
                }
                else if (document.URL.search("\/my\/watchlist\.aspx") >= 0) {
                    pageType = "watchlist";
                    userName = null;
                    initLongListPage();
                }
                else if (document.URL.search("\/profile\/") >= 0 && document.getElementById("ctl00_ContentBody_ProfilePanel1_repFavoritedCaches_ctl01_row")) {
                    pageType = "profile";
                    userName = null;
                    initLongListPage();
                }
            }
        }
    }
}
 
function init() {
	LOGGING = getLogging();
	HALFSTARS = getHalfstars();
//For Opera Support
    if(typeof(opera) != "undefined") {
        browserType = "Opera";
        myWindow = window;
    }
    else if(typeof(chrome) != "undefined"){
        browserType = "Chrome";    
        myWindow = window;
         
        //Helperfunctions to inject functions into site context
        injectPageScript = function(scriptContent){
            var script = document.createElement("script");
            script.setAttribute("type", "text/javascript");
            script.innerHTML = scriptContent;
            var pageHead = document.getElementsByTagName("head")[0];
            pageHead.appendChild(script);
        }
 
        injectPageScriptFunction = function(funct, functCall){
            injectPageScript("("+funct.toString()+")"+functCall+";");   
        }
         
        if (typeof(GM_addStyle) == "undefined" || (typeof(chrome) !== "undefined" && (GM_addStyle.toString && GM_addStyle.toString().indexOf("not supported") != -1))) {
            GM_addStyle = function(style){
                var sheet = document.createElement('style');
                sheet.innerHTML = style;
                document.body.appendChild(sheet);
            }
        }
     
        if(typeof(GM_xmlhttpRequest) == "undefined" || (typeof(chrome) !== "undefined" && (GM_xmlhttpRequest.toString && GM_xmlhttpRequest.toString().indexOf("not supported") != -1))) {
            GM_xmlhttpRequest = function(requestData){
                var httpReq = new window.XMLHttpRequest();
                httpReq.onreadystatechange = function(data) {
                    if (httpReq.readyState == 4) {
                        if (httpReq.status == 200){
                            if(requestData.onload){
                                requestData.onload(httpReq);
                            }
                        }
                        else
                        {
                            if(requestData.onerror){
                                requestData.onerror(httpReq);
                            }
                        }
                    }               
                }
                 
                httpReq.open(requestData.method, requestData.url);
 
                if (requestData.headers) {
                    for (var header in requestData.headers) {
                        if(header == "User-Agent" || header == "Origin" ||header == "Cookie" ||header == "Cookie2" ||header == "Referer"){
                            continue;
                        }
                        httpReq.setRequestHeader(header, requestData.headers[header]);
                    }
                }
                 
                httpReq.send(typeof requestData.data == 'undefined' ? null : requestData.data);             
            }
        }
    }
    else if(typeof(safari) != "undefined"){
        browserType = "Safari";
        //required?
        var div = document.createElement("div");
        div.setAttribute("onclick", "return window;");
        myWindow = div.onclick();
    }
    else{
        browserType = "FireFox";
         
        if (typeof(GM_addStyle) == "undefined" || (typeof(chrome) !== "undefined" &&(GM_addStyle.toString && GM_addStyle.toString().indexOf("not supported") != -1))) {
            window.GM_addStyle=unsafeWindow.GM_addStyle= GM_addStyle = function(style){
                var sheet = document.createElement('style');
                sheet.innerHTML = style;
                document.body.appendChild(sheet);
            };
        }
 
	exportFunction( function(style){
                var sheet = document.createElement('style');
                sheet.innerHTML = style;
                document.body.appendChild(sheet);
            }, unsafeWindow, {defineAs: "GM_addStyle"});
	             
        //Helperfunctions to inject functions into site context
        injectPageScript = function(scriptContent){
            var script = document.createElement("script");
            script.setAttribute("type", "text/javascript");
            script.innerHTML = scriptContent;
            var pageHead = document.getElementsByTagName("head")[0];
            pageHead.appendChild(script);
        }
 
        injectPageScriptFunction = function(funct, functCall){
            injectPageScript("("+funct.toString()+")"+functCall+";");   
        }
         
         
        myWindow = unsafeWindow;
    }  
     
    //Dectect language
    setLanguage();
     
    translations = [
        "(Rated %%% stars with [url=http://www.gcvote.com]GCVote[/url])", ["(%%% Sterne bei [url=http://www.gcvote.com]GCVote[/url])", "J'ai donné %%% à cette cache grâce à [url=http://www.gcvote.com]GCVote[/url]", "(Votei %%% estrelas com o [url=http://www.gcvote.com]GCVote[/url])", "(Uděleno %%% hvězdiček prostřednictvím [url=http://www.gcvote.com]GCVote[/url])", "(Ocenione na %%% gwiazdek w [url=http://www.gcvote.com]GCVote[/url])", "(Gewaardeerd met %%% Sterren via [url=http://www.gcvote.com]GCVote[/url]", "(Valorado %%% estrellas con [url=http://www.gcvote.com]GCVote[/url])", "(vurderet %%% stjerner med url=http://gcvote.comGCVote/url)"],
        "Unable to get votes from server! Errorcode ", ["Fehler bei der Server-Abfrage: ", "Impossible de récupérer les cotes sur le serveur! Code d'erreur :", "Impossível obter votos do servidor! Errorcode", "Chyba při získávání hodnocení ze serveru! ErrorCode:", "Nie można pobrac głosów z serwera! Błąd", "Kon geen verbinding maken met de GCVote server! Errorcode", "¡Imposible recibir votos del servidor! Errorcode", "Ikke i stand til at hente vurderinger fra server! Fejlkode:"],
        "Your Account is password protected and you supplied no or the wrong password. If you did not register a password, please inform me: guido.wegener@gmx.de", ["Dein Account ist mit einem Passwort geschützt und Du hast kein oder ein falsches Passwort angegeben.", "Ce compte est protégé par mot de passe", "A tua conta está protegida com password e não a introduziste ou está errada. Se não registaste uma password, por favor contacta-me: guido.wegener@gmx.de", "Nevyplněné, nebo chybné heslo. V případě potíží mne kontaktujte: guido.wegener@gmx.de", "Twoje konto jest chronione hasłem, kórego nie wprowadziłeś lub podałeś błędne. Jeśli nie zarejestrowałeś hasła, skontaktuj się ze mną: guido.wegener@gmx.de", "Uw account is beschermd met een wachtwoord of u hebt  geen of een verkeerd wachtwoord ingevoerd. Als u nog geen wachtwoord heeft aangevraagd, neem dan contact op met guido.wegener@gmx.de", "Your Account is password protected and you supplied no or the wrong password. If you did not register a password, please inform me: guido.wegener@gmx.de", "Din konto er beskyttet med kodeord og du har intet angivet eller angivet et forkert kodeord. Hvis du ikke har registreret et kodeord, så venligst kontakt mig: guido.wegener@gmx.de"],
        "Unable to send vote to server! Errorcode", ["Fehler beim Speichern der Bewertung: ", "Impossible d'envoyer votre cote sur le serveur! Code d'erreur :", "Impossível enviar o voto para o servidor! Errorcode", "Chyba při ukládání hodnocení na server! ErrorCode:", "Nie można wysłać głosów do serwera! Błąd", "Kan geen verbinding maken met de GCVote server! Errorcode", "¡Imposible enviar voto al servidor! Errorcode", "Ikke muligt at sende vurdering til server! Fejlkode"],
        "Average (mean) ", ["Durchschnitt (Mittel) ", "Moyenne ", "Média", "Průměr (střední)", "Średnia", "Gemiddelde (standaard)", "Media", "Gennemsnit (middel)"],
        " your vote: ", [" Deine Bewertung: ", " votre cote: ", " o teu voto:", "mé hodnocení", " twój głos:", "Uw stem:", " tu voto:", "din vurdering:"],
        "neutral / not rated yet", ["unbewertet", "aucune cote", "sem voto", "nehodnoceno", "bez głosu", "Geen stem", "Sin votos", "neutral / ikke vurderet endnu"],
        "1: poor", ["1: schlecht", "1: perte de temps", "1: péssima", "1: nevyhovující odpad", "1: bardzo słaba", "Slecht", "Muy malo", "1: Meget dårlig"],
        "1.5: fairly poor", ["1,5: lohnt nicht", "1,5: sans intérêt", "1.5: má", "1.5: bezcenná", "1.5: słaba", "Matig", "Malo", "1,5: Dårlig"],
        "2: below average", ["2: schwach", "2: sous la moyenne", "2: fraca", "2: dík za bod", "2: raczej słaba", "Onvoldoende", "Poco interesante", "2: Under middel"],
        "2.5: not so bad", ["2,5: ok", "2,5: pas si mal", "2.5: razoável", "2.5: OK", "2.5: może być", "Net geen voldoende", "Algo peor de a lo normal", "2,5: Lidt under middel"],
        "3: average", ["3: durchschnittlich", "3: moyenne", "3: normal", "3: stojí za návštěvu", "3: średnia", "Voldoende", "Normal", "3: Middel"],
        "3.5: not bad at all", ["3,5: besser", "3,5: pas mal du tout", "3.5: melhor", "3.5: lepší průměr", "3.5: prawie dobra", "Ruim voldoende", "Algo mejor de lo normal", "3,5: Lidt over middel"],
        "4: better than average", ["4: gut", "4: plus plaisante que la moyenne", "4: boa", "4: velmi dobrá", "4: dobra", "Goed", "Interesante", "4: Over middel"],
        "4.5: very good", ["4,5: fast perfekt", "4,5: vraiment intéressante", "4.5: quase perfeita", "4.5: skvělá", "4.5: bardzo dobra", "Zeer goed", "Muy bueno", "4,5: God"],
        "5: awesome", ["5: großartig", "5: à faire absolument", "5: excelente", "5: zlatý fond", "5: świetna", "Uitstekend", "Inmejorable", "5: Meget god"],
        "Insert GCVote Info", ["GCVote-Info-Text einfügen", "Ajouter signature GCVote", "Inserir informação GCVote", "Vložit notifikaci GCVote", "Wstaw Gcvote Info", "Voer GCVote informatie in", "Insertar info GCVote", "Indsæt GCVote information"],
        "Distribution of votes:", ["Verteilung der Bewertungen:", "Distribution des cotes", "Distribuição dos votos:", "Rozdělení hodnocení :", "Przydział głosów", "Verdeling van de stemmen", "Distribución de votos:", "Fordeling af vurderinger:"],
        "Couldn't find entry tag for inserting GCVote configuration window. Maybe the geocaching.com website has been changed. Please have a look on http://gcvote.com and check for possibly released GCVote updates.", ["Unerwartetes HTML gefunden. Probiere mal aus, die Seite neu zu laden oder schau auf http://gcvote.com nach, ob es schon eine neue Version gibt.", "Couldn't find entry tag for inserting GCVote configuration window. Maybe the geocaching.com website has been changed. Please have a look on http://gcvote.com and check for possibly released GCVote updates.", "Não foi possível encontrar a tag onde seria inserida a janela de configuração do GCVote. Talvez o site geocaching.com tenha mudado. Por favor vai a http://gcvote.com e verifica se há updates disponíveis.", "Nelze zobrazit okno nastavení GCVote. Možná že došlo ke změně  internetových stránek geocaching.com. Prosím zkontrolujte aktualizaci na http://gcvote.com.", "Nie można znaleźć znacznika wejściowego do wstawienia okna konfiguracyjnego GCVote. Być może strona geocaching.com uległa zmianie. Proszę zajrzeć na on http://gcvote.com i sprawdzić aktualizacje GCVote.", "Kan geen verbinding maken met het GCVote configuratiescherm. Misschien is de geocaching.com website veranderd. Ga naar http://gvote.com om te controleren of er een update van GCVote is.", "No es posible encontrar la etiqueta de ventana de configuración de GCVote. Puede que haya habido cambios en www.geocaching.com. Visita http://www.gcvote.com y comprueba posibles actualizaciones de GCVote.", "Kunne ikke finde GCVote konfigurations vindue. Muligvis er der sket ændringer på geocaching.com. Check http://gcvote.com for mulige opdateringer"],
        "hide config", ["Menü verstecken", "cacher config", "esconder configuração", "skrýt nastavení", "ukryj config", "Verberg configuratiescherm", "Ocultar configuración", "skjul konfiguration"],
        "show config", ["Menü einblenden", "voir config", "mostrar configuração", "zobrazit nastavení", "pokaż config", "Laat configuratiescherm zien", "Mostrar configuración", "vis konfiguration"],
        "GCVote Configuration", ["GCVote Konfiguration", "Configuration GCVote", "Configuração GCVote", "Nastavení GCVote", "Konfiguracja GCVote", "GCVote configuratiescherm", "Configuración GCVote", "GCVote konfiguration"],
        "Update GCVote", ["Update GCVote", "Mettre à jour GCVote", "Actualizar GCVote", "Aktualizace GCVote", "Aktualizacja GCVote", "Update GCVote", "Actualizar GCVote", "Opdater GCVote"],
        "Homepage", ["Homepage", "Site web GCVote", "Homepage", "Homepage GCVote", "Strona domowa", "Startpagina", "Homepage", "Hjemmeside"],
        "List my votes", ["meine Bewertungen", "Voir toutes mes cotes", "Listar os meus votos", "Seznam mých hodnocení", "Lista moich głosów", "Toon mijn stemmen", "Listar mis votos", "Vis mine stemmer"],
        "Change password", ["Passwort ändern", "Changer mot de passe", "Mudar password", "Změna hesla", "Zmień hasło", "Wijzig wachtwoord", "Cambiar password", "Skift kodeord"],
        "Password:", ["Passwort:", "Mot de passe", "Password:", "Heslo :", "Hasło:", "Wachtwoord:", "Password:", "Kodeord:"],
        "passwords must be registered via GC.com-mail to BonnerGuido", ["Passwörter müssen per GC.com-Mail an BonnerGuido registriert werden", "Les mots de passe doivent être enregistrés auprèes de l'utilisateur BonnerGuido via le site geocaching.com", "as passwords têm de ser registadas através do envio de um mail via GC.com ao BonnerGuido", "heslo musí být registrováno prostřednictvím e-mailu kačeru BonnerGuido z gc.com", "hasło musi być zarejestrowane przez GC.com-mail do BonnerGuido", "Wachtwoorden moet geregistreerd worden dooor een mailtje te sturen via het profiel van BonnerGuido", "Las passwords se registran vía GC.com a BonnerGuido", "kodeord skal registreres via geocaching.com-mail (profil) til BonnerGuido"],
        "Template:", ["Mustertext", "Signature", "Frase:", "Šablona :", "Szablon:", "Template:", "Plantilla:", "Skabelon:"],
        "GCVote info string to insert into logs", ["GCVote-Informationstext, der bei Logs eingefügt werden soll", "Texte à ajouter dans un log seulement lorsque vous appuyer sur le bouton prévu à cet effet", "texto de informação GCVote para inserir nos logs", "vloží do logu tuto informaci o hodnocení keše prostřednictvím GCVote", "Tekst informacyjny do wstawiania w logach", "GCVote informatieregel om bij je log toe te voegen", "Texto GCVote para incluir en los logs", "GCVote info tekst der skal indsættes i logs"],
        "Minimum vote count:", ["Minimum Stimmenanzahl:", "Compte minimum de cotes:", "Contagem mínima de votos:", "Minimální počet hlasů:", "Minimalna liczba głosów", "Minimaal aantal stemmen", "Mínimo de votos", "Minimum antal vurderinger:"],
        "display stars only for caches with more than X votes", ["nur Sterne anzeigen, wenn mehr als X Bewertungen vorhanden sind", "montrer les cotes seulement pour les caches qui ont plus de X cotes", "mostrar estrelas apenas para caches com mais de X votos", "zobrazit jen keše s minimálním počtem hlasů vyšším, než x", "wyświetl gwiazdki tylko dla skrytek z więcej niż X głosów", "Laat het aantal sterren alleen zien bij caches met meer dan X stemmen", "Muestra las estrellas sólo para los cachés con más de X votos", "vis kun stjerner for cacher med mere end X vurderinger"],
        "Average calculation:", ["Durchschnitts-Berechnung:", "Méthode du calcul moyen:", "Cálculo da média:", "Způsob průměrování :", "Obliczanie średniej:", "Gemiddelde berekening", "Cálculo medio:", "Beregning af gennemsnit:"],
        "how the number of displayed stars should be calculated", ["Berechnungsmethode für die Sterne", "la façon dont la moyenne est calculée", "método de cálculo do número de estrelas mostradas", "způsob průměrování pro výpočet zobrazených hvězdiček", "jak liczba wyświetlanych gwiazdek powinna być obliczana", "Hoe het aantal weergegeven sterren moet worden berekend", "Cómo se calculan las estrellas mostradas", "hvordan antallet af viste stjerner skal udregnes"],
        "Mean", ["Durchschnitt", "Moyenne", "Média", "Aritm. Průměr", "Średnia", "Gemiddelde", "Media", "Middel"],
        "arithmetic mean of all votes for the cache", ["arithmetisches Mittel der Bewertungen", "calcul de la moyenne selon toutes les cotes", "média aritmética de todos os votos da cache", "aritmetický průměr všech udělených hodnocení", "średnia arytmetyczna wszystkich głosów dla skrytki", "Berekend gemiddelde van alle stemmen voor de cache", "Media aritmética de todos los votos del caché", "middel gennemsnit af alle vurderinger for en cache"],
        "Median", ["Median", "Médiane", "Mediana", "Střední hodnota", "Mediana", "Mediaan ", "Mediana", "Median"],
        "median ignores unusual votes", ["Der Median ignoriert ungewöhnliche Bewertungen", "valeur médiane ignore les cotes exagérées", "a mediana ignora votos díspares", "pro výpočet střední hodnoty nebudou započítána krajní hodnocení", "mediana pomija skrajne głosy", "Mediaan negeert uitschietters ", "La mediana desestima los votos inusuales", "median ignorerer usædvanlige vurderinger"],
        "save changes", ["Änderungen speichern", "Enregistrer", "guardar alterações", "Uložit nastavení", "zapisz zmiany", "Veranderingen opslaan", "Guardar cambios", "Gem ændringer"],
        "Language:", ["Sprache:", "Langage:", "Idioma:", "Jazyk :", "Język:", "Taal:", "Idioma:", "Sprog:"],
        "language for GCVote", ["Sprache in GCVote", "Langue d'affichage de ce module", "o idioma para o GCVote", "jazyk ve kterém bude GCVote zobrazen", "język GCVote", "Taal voor GCVote", "Idioma GCVote", "sprog for GCVote"],
        "English", ["Englisch", "Anglais", "Inglês", "anglicky", "angielski", "Engels", "Inglés", "Engelsk"],
        "German", ["Deutsch", "Allemand", "Alemão", "německy", "niemiecki", "Duits", "Alemán", "Tysk"],
        "enable logging", ["Fehler-Log", "aide au déboguage", "activar registos", "povolit protokolování", "zezwól na logowanie", "Activeer foutenrapportage", "Habilitar logging", "aktiver logning"],
        "write debugging information to the error console", ["zusätzliche Meldungen in die Fehler-Konsole schreiben", "écrit l'information de déboguage à la console", "escrever informação de debugging para a consola de erro", "zaznamenává hlášení do chybové konzole", "zapisz informacje debugowania w wierszu poleceń błędów", "Schrijf debugging informatie naar de server", "Guardar información de depurado en la consola de error", "skriv debug information til en fejlkonsol"],
        "sorted sidebar", ["Karte sortieren", "tri selon les cotes", "ordenar barra lateral", "řazení", "uporządkowanie", "Gesorteerde zijbalk", "Barra ordenada", "sorteret sideliste"],
        "sort caches on the map page according to their ratings", ["Caches in der Liste auf der Karte nach Bewertung sortieren", "à droite de la carte, affiche les caches triées selon leur cote", "ordenar as caches na página do mapa de acordo com as suas classificações", "seřadí keše na stránce mapy podle jejich ohodnocení", "kolejność skrytek na stronie z mapą w zależności od ich oceny", "Sorteer caches op de kaart op waardering", "Ordenar cachés en el mapa según su valoración", "sorter cacher på kort-siden efter deres vurdering"],
        "half stars", ["halbe Sterne", "demie-étoile", "meias estrelas", "půlhvězdy", "pół gwiazdek", "Halve sterren", "Medias estrellas", "halve stjerner"],
        "enable ratings 1.5, 2.5, 3.5 and 4.5", ["auch halbe Sternchen vergeben", "permet de donner des cotes et demi", "permitir classificações de 1.5, 2.5, 3.5 e 4.5", "povolí hodnocení půlhvězdami, tedy 1.5, 2.5, 3.5 a 4.5", "zezwól na oceny 1.5, 2.5, 3.5 i 4.5", "Maak waarderen met 1,5 2,5 3,5 en 4,5 mogelijk", "Habilitar 1.5, 2.5, 3.5 y 4.5", "benyt vurderinger 1½, 2½, 3½ og 4½"],
        "?", ["?", "?", "?", "?", "?", "?", "?", "?"],
        " out of 5", [" von 5", " sur 5", " de 5", " z 5", " z 5", ".. Van 5", "  sobre 5", " ud af 5"],
        "password active", ["Passwort aktiviert", "mot de passe actif", "password activa", "heslo je aktivované", "hasło aktywne", "Wachtwoord actief", "Password activa", "kodeord aktivt"],
        "Help", ["Hilfe", "Aide", "Ajuda", "Nápověda", "Pomoc", "Help", "Ayuda", "Hjælp"],
        "Quality", ["Qualität", "Appréciation", "Qualidade", "Hodnocení", "Jakość", "Kwaliteit", "Calidad", "Kvalitet"],
        "French", ["Französisch", "Français", "Francês", "francouzsky", "francuski", "Frans", "Francés", "Fransk"],
        "compact layout", ["kompaktes Layout", "format compact", "layout compacto", "kompaktní zobrazení", "wygląd prosty", "Compacte opmaak", "Formato compacto", "kompakt layout"],
        "improve GCVote's layout for small screens", ["kompakteres Layout für kleine Bildschirme", "Format compact pour les petits écrans", "melhora o layout do GCVote para ecrans pequenos", "kompaktní zobrazení pro monitoty s nízkým rozlišením obrazovky", "dostosuj układ GCVote do małych ekarnów", "Verbetert de opmaak van GCVote voor kleine beeldschermen", "Optimizar formato GCVote para pantallas pequeñas", "optimer GCVotes layout på små skærme"],
        "Portuguese", ["Portugiesisch", "Portugais ", "Português", "portugalsky", "portugalski", "Portugees", "Portugués", "Portugisisk"],
        "Czech", ["Tschechisch", "Tchèque", "Tcheco", "Česky", "czeski", "Tsjechisch", "Checo", "Tjekkisk"],
        "Polish", ["Polnisch", "Polonais", "Polonês", "Polština", "polski", "Pools", "Polaco", "Polsk"],
        "Dutch", ["Niederländisch", "Néerlandais", "Holandês", "Nizozemština", "niderlandzki", "Nederlandse", "Holandés", "Hollandsk"],
        "show GCVote", ["GCVote aktiv", "show GCVote", "show GCVote", "show GCVote", "show GCVote", "show GCVote", "Mostrar GCVote", "vis GCVote"],
        "automatically load and update GCVote-stars on map", ["automatisch GCVote-Sterne nachladen und anzeigen", "automatically load and update GCVote-stars on map", "automatically load and update GCVote-stars on map", "automatically load and update GCVote-stars on map", "automatically load and update GCVote-stars on map", "automatically load and update GCVote-stars on map", "Actualizar automáticamente estrellas GCVote en el mapa", "hent og opdater GCVote-stjerner på kortet automatisk"],
        "Total votes:", ["Anzahl Stimmen:", "Nombre de cotes :", "Total votes:", "Total votes:", "Total votes:", "Total votes:", "Votos totales:", "Totale antal stemmer:"],
        "hide on long lists", ["auf langen Listen ausblenden", "désactive longue liste", "hide on long lists", "hide on long lists", "hide on long lists", "hide on long lists", "Ocultar en listas largas", "skjul på lange lister"],
        "Do not display star on pages that may contain many caches. Improves speed on slow computers.", ["Sterne auf Seiten mit vielen Caches nicht nachladen, um nicht so zu bremsen.", "désactive les cotes sur les pages qui affichent une longue liste de caches", "Do not display star on pages that may contain many caches. Improves speed on slow computers.", "Do not display star on pages that may contain many caches. Improves speed on slow computers.", "Do not display star on pages that may contain many caches. Improves speed on slow computers.", "Do not display star on pages that may contain many caches. Improves speed on slow computers.", "No mostrar estrellas en páginas que contengan muchos cachés. Mejora la velocidad en ordenadores lentos.", "Vis ikke stjerner på sider der kan have mange cacher. Øger hastigheden på langsomme computere"],
        "load GCVote", ["GCVote nachladen", "load GCVote", "load GCVote", "load GCVote", "load GCVote", "load GCVote", "Cargar GCVote", "hent GCVote"],
        "bar-graph statistics", ["Balken-Statistik", "stats graphiques", "bar-graph statistics", "bar-graph statistics", "bar-graph statistics", "bar-graph statistics", "Gráfico de estadísticas", "Søjlediagrammer"],
        "display histogram as fancy bars", ["Histogramme der Bewertungen als Balken-Diagramme anzeigen", "Tableau 'Distribution des votes' affiché graphiquement plutôt qu'en texte", "display histogram as fancy bars", "display histogram as fancy bars", "display histogram as fancy bars", "display histogram as fancy bars", "Mostrar estadísticas en barras", "vis vurderingsfordeling som søjlediagram"],
        "no+votes", ["keine+Bewertungen", "Aucune+cote", "no+votes", "no+votes", "no+votes", "no+votes", "No+votos", "ingen+stemmer"],
        "Spanish", ["Spanisch", "Espagnole", "Spanish", "Spanish", "Spanish", "Spanish", "Español", "Spanish"],
        "get GCVote ratings", ["GCVote-Sterne laden", "obtenir cotes GCVote", "get GCVote ratings", "get GCVote ratings", "get GCVote ratings", "get GCVote ratings", "get GCVote ratings", "hent GCVote vurdering"],
        "Average rating:", ["Durchschnitt:", "Moyenne des cotes : ", "Average rating:", "Average rating:", "Average rating:", "Average rating:", "Average rating:", "Gennemsnitlig vurdering:"],
        "Error while sending vote: ", ["Fehler beim Senden der Bewertung: ", "Erreur lors de l'envoi de la cote : ", "Error while sending vote: ", "Error while sending vote: ", "Error while sending vote: ", "Error while sending vote: ", "Error while sending vote: ", "Fejl ved afsendelse af vurdering:"],
        "Danish", ["Dänisch", "Danois", "Danish", "Danish", "Danish", "Danish", "Danish", "Danish"],
    "GCVote only supports the Leaflet-Map (you are using the Google-Map)", ["GCVote unterstützt nur die Leaflet-Map (du verwendest gerade die Google-Map)", "", "", "", "", ""],
    "Temporary enables/disables GCVote on the map", ["Aktiviert/Deaktiviert temporär GCVote auf der Karte", "", "", "", "", ""],
    "Temporary enables/disables only GCVote stars on the map and it's cache table", ["Aktiviert/Deaktiviert temporär GCVote-Sterne und die Cachetabelle", "", "", "", "", ""],
    "Generate Caches", ["Generiere Caches", "", "", "", "", ""],
    "Name", ["Name", "", "", "", "", ""],
    "Cache List (with votes)", ["Cache-Liste (mit Bewertungen)", "", "", "", "", ""],
    "Cache List", ["Cache-Liste", "", "", "", "", ""],
    "An other script wants access to GCVote.\nAllow?", ["Ein anderes Skript möchte auf GCVote zugreifen.\nZulassen?", "", "", "", "", ""],
    "Enable stars", ["Aktiviere Sterne ", "Afficher les étoiles", "", "", "", ""],
    "Add stars on cache icons.", ["Füge den Cachesymbolen Sterne hinzu.", "", "", "", "", ""],
    "Enable stars in popups", ["Aktiviere Sterne in Popups", "  Afficher les étoiles (popups)", "", "", "", ""],
    "Add stars in the cache popups.", ["Füge in den Cache-Pop-ups Sterne hinzu.", "", "", "", "", ""],
    "Enable the cache table (with stars)", ["Aktiviere die Cachetabelle (mit Sternen)", "Affiche un tableau des caches (avec étoiles)", "", "", "", ""],
    "Adds a table with all visible caches to the left panel.", ["Füge dem linken Panel eine Cachetabelle mit allen sichtbaren Cachen hinzu.", "", "", "", "", ""],
    "Enable sorting of the table", ["Aktiviere das Sortieren der Tabelle", "Ajoute fonction de tri au tableau", "", "", "", ""],
    "Enables sorting on the cache table.", ["Ermöglicht das sortieren der Tabelle.", "", "", "", "", ""],
    "Enable caching", ["Aktiviere Caching", "Active la mise en cache locale", "", "", "", ""],
    "Enables the local caching -> Known information where not downloaded again.", ["Aktiviert das lokale zwischenspeichern -> Vorhandene Informationen werden nicht erneut heruntergeladen.", "", "", "", "", ""],
    "Enable cache generation", ["Aktiviere das Generieren von Cachen", "Enable cache generation", "", "", "", ""],
    "Allows the manual generation of caches, using cached informations.", ["Erlaubt das (manuelle) Generieren von Cachen aus zwischengespeicherten Informationen.", "", "", "", "", ""],
    "Enable automatic cache generation", ["Aktiviert das automatische Generieren", "Enable automatic cache generation", "", "", "", ""],
    "Enables the automatic generation of caches -> Cached stars appear automatically.", ["Aktiviert das automatische Generieren von Cachen -> Sterne tauchen automatisch auf.", "", "", "", "", ""],
    "Allow pairing with GcPersoFix", ["Erlaube das Paaren mit GCPersoFix", "Allow pairing with GcPersoFix", "", "", "", ""],
    "Allows the cooperation with GCPersonalisationFix to hide found/hidden caches. (Geocaching.com Premium Members)", ["Erlaube die Zusammenarbeit mit GCPersonalisationFix um gefundene/eigene Caches auszublenden (Geocaching.com Premium Milglieder)", "", "", "", "", ""],
    "Save the state of the filters", ["Speichere den Zustand der Filter", "Sauvegarder l'état des filtres", "", "", "", ""],
    "If enabled filters (number of stars) are saved and will be restored on future sessions.", ["Wenn aktiviert, werden die Filter (Anzahl der Sterne) gespeichert und in späteren sitzungen wiederhergestellt.", "", "", "", "", ""],
    "Map options", ["Karten Optionen", "", "", "", "", ""],
    "Delete local caches", ["Lösche lokale Caches", "", "", "", "", ""],
    "This will delete all local cached data.\n\nDo you want to continue?", ["Dies löscht alle lokalgespeicherten Daten.\n\nMöchten Sie fortfahren?", "", "", "", "", ""],
    "Local caches had been deleted on user request. \nReload all map pages without using them!", ["Alle Caches wurden wie gewünscht gelöscht.\nLaden sie alle Fenster mit der Karte neu, ohne diese zu verwenden!", "", "", "", "", ""],
        "", ["", "", "", "", "", ""],
    ];
// en  de fr pt cs pl nl es dk
    return;
}
 
function displayMessage(message) {
    // display message on page or as alert
    log("displayMessage " + message);
    var messageBox = document.getElementById("GCVoteMessage");
    if (!messageBox) {
        var cont;
        if (document.getElementById("CacheName")) {
            cont = document.getElementById("CacheName").parentNode.parentNode.parentNode;
        }
        else {
            if (document.getElementById("ctl00_ContentBody_SearchResultText")) {
                cont = document.getElementById("ctl00_ContentBody_SearchResultText").parentNode.parentNode;
            }
            else {
                if (document.getElementById("__VIEWSTATE")) {
                    cont = document.getElementById("__VIEWSTATE").parentNode.parentNode;
                }
                else {
                    if (document.getElementById("ctl00_Breadcrumbs")) {
                        cont = document.getElementById("ctl00_Breadcrumbs").parentNode.parentNode;
                    }
                }
            }
        }
        messageBox = document.createElement("div");
        messageBox.id = ("GCVoteMessage");
        setStyle(messageBox, "border-width:6px;border-style:solid;border-color:#c02020;background-color:white;padding-bottom:8px");
        messageBox.innerHTML = "<b>GCVote</b>";
        if (!cont || !cont.firstChild) {
            log("Unknown XML on page named " + document.title);
            if (document.title.substr(0, 10) == "Geocaching")
                {
                    alert("GCVote: Please update at http://gcvote.com");
                }
        }
        cont.insertBefore(messageBox, cont.firstChild);
        document.GCVote_PreviousMessage = "";
    }
    if (document.GCVote_PreviousMessage != message) {
        messageBox.innerHTML += "<p>" + message + "</p>";
        window.scrollTo(0, 0);
        document.GCVote_PreviousMessage = message;
    }
}
 
function setVote(cacheId, vote) {
    // highlight user's vote
    log("setVote " + cacheId + " -> " + vote);
    for (var i = 0; i <= 5; i += HALFSTARS ? 0.5 : 1) {
        var voteLinks = document.getElementsByName("GCVoteLink" + cacheId + "=" + i);
        for (var j = 0; j < voteLinks.length; j++) {
            var voteLink = voteLinks[j];
            var style;
            if (vote == i) {
                if (vote == 0) {
                    style = "background-color:#30e030;font-weight:normal";
                }
                else {
                    style = "background-color:orange;font-weight:normal";
                }
            }
            else {
                style = "font-weight:normal";
            }
            if (voteLink != null) {
                setStyle(voteLink, style);
            }
        }
    }
}
 
function initDetailsPage() {
    // on load of detail pages
    log("initDetails " + pageType);
    var guidurl = document.getElementById("ctl00_hlSignOut");
    if (!guidurl) {
        guidurl = document.getElementById("aspnetForm");
    }
//  var loginurl=document.getElementById("ctl00_LoginUrl");
//  if(!loginurl && document.getElementById("hd")) {loginurl=document.getElementById("hd").childNodes[3];log("emergency loginurl=",loginurl);}
    var ref = guidurl.getAttribute("href");
    var regexp = /%3fguid%3d([^%]*)/;
    regexp.exec(ref);
    cacheId = RegExp.$1;
    if (!cacheId) {
        ref = document.getElementById("ctl00_ContentBody_lnkPrintFriendly5Logs").getAttribute("href");
        regexp = /\?guid=(.*)/;
        regexp.exec(ref);
        cacheId = RegExp.$1;
    }
    var wp = document.getElementById("ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode").firstChild.data.replace(/\s/g, "");
    log("wp=" + wp);
//  var ownerLink=document.getElementById("yui-g").getElementsByTagName("table")[0].getElementsByTagName("table")[0].getElementsByTagName("a")[0].getAttribute("href");
    var ownerLink = document.getElementById("cacheDetails").getElementsByTagName("span")[0].getElementsByTagName("a")[0];
    var regexp = /guid=([^&]*)/;
    regexp.exec(ownerLink);
    var owner = RegExp.$1;
    requestVoteO(cacheId, wp, owner);
}
 
function initNewCachePage() {
    // on load of (new) detail cache page
    log("initNewCache " + pageType);
    var guidurl = document.getElementById("hlViewWhoFavorited");
    if (!guidurl) {
        guidurl = document.getElementById("ctl00_ContentBody_lnkPrintFriendly");
    }
 
    var ref = guidurl.getAttribute("href");
    var regexp = /\?guid=(.*)/;
    regexp.exec(ref);
    cacheId = RegExp.$1;
    if (!cacheId) {
        ref = document.getElementById("ctl00_ContentBody_uxTravelBugList_uxViewAllTrackableItems").getAttribute("href");
        regexp = /\?guid=(.*)/;
        regexp.exec(ref);
        cacheId = RegExp.$1;
    }
    var wp = document.getElementById("ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode").firstChild.data.replace(/\s/g, "");
    log("wp=" + wp);
 
    var ownerLink = document.getElementById("ctl00_ContentBody_mcd1").getElementsByTagName("a")[0];
    var regexp = /guid=([^&]*)/;
    regexp.exec(ownerLink);
    var owner = RegExp.$1;
    requestVoteO(cacheId, wp, owner);
}
 
 
function initPrintPage() {
    // on load of printer friendly pages
    log("initPrintPage " + pageType);
    var ref = document.getElementById("Form1").getAttribute("action");
    var regexp = /guid=([^%]*)/;
    regexp.exec(ref);
    cacheId = RegExp.$1;
    log("ref=" + ref + "   id=" + cacheId);
    requestVote(cacheId);
}
 
function initLogEditPage() {
    // on load of "edit log"  pages
    log("initEdit " + pageType);
    //var href = document.getElementById("ctl00_ContentBody_LogBookPanel1_WaypointLink");
    var container = document.getElementById("ctl00_ContentBody_LogBookPanel1_EditLogPanel");
    if(!container) {
    container = document.getElementById("ctl00_ContentBody_LogBookPanel1_lbLogText");
    }
    var candiates = container.getElementsByTagName("a");
    var ref = "";
    for(canIndex in candiates){
        if(candiates[canIndex].getAttribute("href").indexOf("cache_details") != -1){
            ref = candiates[canIndex].getAttribute("href");
            break;
        }
    }
     
    var regexp = /\?guid=([^%]*)/;
    regexp.exec(ref);
    cacheId = RegExp.$1;
    log("cacheid found: " + cacheId);
    requestVote(cacheId);
}
 
function myUpdateSideBarList() {
    log("updatesidebar");
    myWindow.GCVoteOriginalUpdateSideBarList();
    var cb = document.getElementById("autoupdatemapinput");
    log("udsb " + cb.checked);
    if (cb.checked) {
        simClick();
    }
}
 
function updateSideBarListListener() {
    log("updatesidebarlistener");
    if (!document.getElementById("GCVoteWaitMap")) {
        var t = document.getElementById("chkShowNumbers").parentNode;
        var imgWait = document.createElement("img");
        imgWait.setAttribute("width", "14px");
        imgWait.setAttribute("height", "14px");
        imgWait.src = "https://www.geocaching.com/images/loading.gif";
        imgWait.id = "GCVoteWaitMap";
        t.appendChild(imgWait);
    }
    var waypoints = new Array();
    var sidebar = document.getElementById('cacheListBody');
    var lis = sidebar.getElementsByTagName("a");
    for (var i = 0, l = lis.length; i < l; i++) {
        var li = lis[i];
        var link = li.getAttribute("href");
        var regexp = /wp=(\w*)/;
        regexp.exec(link);
        waypoint = RegExp.$1;
        waypoints[i] = waypoint;
        log("found waypoint " + waypoint);
        var span = document.createElement("span");
        span.id = "td" + waypoint;
        var target = li.parentNode.nextSibling.nextSibling;
        target.appendChild(span);
    }
    requestVotesForWaypoints(waypoints);
}
 
function simClick() {
    var input = document.getElementById("hiddenTriggerInput");
    var event = document.createEvent("MouseEvents");
    event.initEvent("click", true, false);
    input.dispatchEvent(event);
}
 
function handleMapUpdateChange() {
    var cb = document.getElementById("autoupdatemapinput");
    setAutoUpdateMap(cb.checked);
    log("handleMapUpdateChange to " + getAutoUpdateMap() + " type " + typeof(getAutoUpdateMap()));
    if (getAutoUpdateMap()) {
        simClick();
    }
}
 
function initGMListPage() {
    log("initMap " + pageType);
    if (typeof(myWindow) == "undefined") {
        if (typeof(chrome) == "undefined" && typeof(safari) === "undefined") {
            return;
        } else {
            var input = document.createElement("input");
            addEvent(input, "click", function () {
                setTimeout(function () {
                    updateSideBarListListener();
                }, 0)
            });
            input.setAttribute("type", "button");
            input.setAttribute("value", tl("get GCVote ratings"));
            var t = document.getElementById("chkShowNumbers").parentNode;
            t.appendChild(document.createElement("br"));
            t.appendChild(input);
            return;
        }
    }
    if (typeof(chrome) == "undefined") {
        log("insert update box");
        var input = document.createElement("input");
        addEvent(input, "click", function () {
            setTimeout(handleMapUpdateChange, 0)
        });
        input.setAttribute("type", "checkbox");
        input.id = "autoupdatemapinput";
        if (getAutoUpdateMap()) {
            input.checked = "checked";
        }
        var t = document.getElementById("chkShowNumbers").parentNode;
        t.appendChild(document.createElement("br"));
        t.appendChild(input);
        t.appendChild(getTooltipSpan("show GCVote", "automatically load and update GCVote-stars on map"));
        t.appendChild(document.createElement("br"));
    }
    myWindow.GCVoteOriginalUpdateSideBarList = myWindow.updateSideBarList;
    myWindow.updateSideBarList = myUpdateSideBarList;
    var input = document.createElement("input");
    input.id = "hiddenTriggerInput";
    addEvent(input, "click", function () {
        setTimeout(function () {
            updateSideBarListListener();
        }, 0)
    });
    input.setAttribute("type", "hidden");
    document.getElementById("aspnetForm").appendChild(input);
//  document.getElementById("aspnetForm").appendChild(document.createElement('script')).innerHTML=
//      "GCVoteOriginalUpdateSideBarList=updateSideBarList;updateSideBarList=function() {GCVoteOriginalUpdateSideBarList();simClick();};";
//  document.body.appendChild(document.createElement('script')).innerHTML=simClick.toString();
}
 
function initLongListPage() {
    if (getDisableOnLongLists()) {
//      var count=document.getElementById("Content").parentNode.nextSibling;
        var count = document.getElementsByTagName("h2")[0].nextSibling.nextSibling;
        var buttonLoad = document.createElement("input");
        buttonLoad.setAttribute("type", "button");
        buttonLoad.setAttribute("value", tl("load GCVote"));
        addEvent(buttonLoad, "click", initListPage);
        buttonLoad.id = "load_GCVotes";
//      count.parentNode.insertBefore(buttonLoad,count);
        if (!count) {
            count = document.getElementsByTagName("h3")[0].nextSibling.nextSibling;
        }
        count.insertBefore(buttonLoad, count.firstChild);
        log("long list button inserted");
    }
    else {
        initListPage();
    }
}
 
 
function initListPage() {
    // on load of pages containing lists of caches
    log("initList " + pageType);
    var anchors = document.getElementsByTagName('a');
    var reg = /cache_details\.aspx\?guid=([^&]*)/;
    var regWaypointOnly = /\/geocache\/(GC\w{2,6})_/;
    var regTrack = /track\/details\.aspx\?guid=/;
    var cacheIds = new Array();
    var cacheDone = new Object();
    var ignoreNextLink = false;
 
    if (pageType == "profile" && !document.getElementById("ctl00_ContentBody_ProfilePanel1_repFavoritedCaches_ctl01_row")) {
        return;
    }
    if (document.getElementById("load_GCVotes")) {
        document.getElementById("load_GCVotes").parentNode.removeChild(document.getElementById("load_GCVotes"));
    }
    // create table header entry "QUALITY"
    {
        if (pageType == "bookmarks" || pageType == "favorites" || pageType == "watchlist" || pageType == "profile") {
            var qualityHeader = document.createElement("th");
            qualityHeader.appendChild(document.createTextNode(tl("Quality")));
            document.getElementsByTagName("th")[0].parentNode.appendChild(qualityHeader);
        }
        else if (pageType == "nearestlist") {
            var headers = document.getElementsByTagName("th");
            var tableHeaderRow = headers[0].parentNode;
            var qualityHeader = document.createElement("th");
            qualityHeader.setAttribute("scope", "col");
            qualityHeader.appendChild(document.createTextNode(tl("Quality")));
            tableHeaderRow.appendChild(qualityHeader);
        }
        else if (pageType == "loglist") {
            var headers = document.getElementsByTagName("th");
            // logs.aspx has no table headers!
            if (headers.length != 0) {
                var tableHeaderRow = headers[0].parentNode;
                var qualityHeader = document.createElement("th");
                qualityHeader.setAttribute("scope", "col");
                qualityHeader.appendChild(document.createTextNode(tl("Quality")));
                tableHeaderRow.appendChild(qualityHeader);
            }
        }
    }
 
    for (var i = 0; i < anchors.length; i++) { // check all links
        var a = anchors[i];
        if (ignoreNextLink) {
            ignoreNextLink = false;
            continue;
        }
    if(pageType == "nearestlist" && a.getAttribute("class") && a.getAttribute("class").match(/^lnk/) && regWaypointOnly.exec(a.href)) {
            var cacheId = RegExp.$1;
        log("potential waypoint "+a.href);
            if ((a.getElementsByTagName("img")[0])) {
//              log("Ignore Image "+a.getElementsByTagName("img")[0]);
                continue; // ignore one of the links per row
            }
            var target = document.createElement("td"); // create container for control
            cacheDone[cacheId] = 1;
            cacheIds.push(cacheId);
            log("found waypoint " + cacheId);
            target.setAttribute("name", "td" + cacheId);
            setStyle(target, "text-align:left");
            var tr = a.parentNode.parentNode;
            if (tr.tagName != "TR") {
                tr = tr.parentNode;
            }
            tr.appendChild(target);
    }
        else if(reg.exec(a.href)&&a.getAttribute("class")!="ImageLink"
                        && !(pageType=="profile" && a.getAttribute("class") && a.getAttribute("class").match(/^lnk/))
                        && a.getAttribute("target")!="_self") { // ignore links inserted by GC Tour
            var cacheId = RegExp.$1;
            if (pageType == "overviewlist1" && (a.parentNode.tagName == "LI")) {
                continue; // cache is part of list of unpublished caches
            }
            if ((pageType == "bookmarks" || pageType == "nearestlist" || pageType == "favorites" || pageType == "overviewlist1" || pageType == "loglist") && (a.getElementsByTagName("img")[0])) {
//              log("Ignore Image "+a.getElementsByTagName("img")[0]);
                continue; // ignore one of the links per row
            }
            if (pageType == "favorites" && a.getElementsByTagName("span")[0]) {
//              log("Ignore Span "+a.getElementsByTagName("span")[0]);
                continue; // ignore one of the links per row
            }
            var target = document.createElement("td"); // create container for control
            cacheDone[cacheId] = 1;
            cacheIds.push(cacheId);
            log("found cache " + cacheId);
            target.setAttribute("name", "td" + cacheId);
            setStyle(target, "text-align:left");
            if (pageType == "overviewlist1")
                {
                    a.parentNode.parentNode.appendChild(target);
                }
            if (pageType == "loglist" || pageType == "nearestlist" || pageType == "profile") {
                var tr = a.parentNode.parentNode;
                if (tr.tagName != "TR") {
                    tr = tr.parentNode;
                }
                tr.appendChild(target);
            }
            if (pageType == "watchlist") {
                var tr = a.parentNode.parentNode;
                if (tr.tagName != "TR") {
                    tr = tr.parentNode;
                }
                tr.appendChild(target);
            }
            if (pageType == "bookmarks" || pageType == "favorites") {
                if (pageType == "bookmarks") {
                    target.setAttribute("rowspan", 2);
                }
                a.parentNode.parentNode.appendChild(target);
            }
            if (pageType == "overviewlist2" && a.parentNode.parentNode.tagName == "TR") {
                a.parentNode.parentNode.replaceChild(target, a.parentNode.parentNode.getElementsByTagName("td")[2]);
            }
        }
        else if (regTrack.exec(a.href)) {
            ignoreNextLink = true;
        }
    }
    if(pageType=='nearestlist') {
        requestVotesForWaypoints(cacheIds);
    }
    else {
        requestVotes(cacheIds);
    }
}
 
function parseXML(xmlString) {
    // callback for XML containing the requested votes
    log("parseXML: " + xmlString);
    xmlDoc = getXmlDoc(xmlString);
    var messages = xmlDoc.getElementsByTagName("message");
    for (var i = 0; i < messages.length; i++) {
        var message = messages[i].firstChild.nodeValue;
        displayMessage(message);
    }
    var rootNodes = xmlDoc.getElementsByTagName("votes");
    if (rootNodes) {
        var rootNode = rootNodes[0];
        var currentVersion = rootNode.getAttribute("currentVersion");
        if (currentVersion != version) {
            var upd = document.getElementById("GC-Vote-update");
 
            // changed by Odilbert for better style
            if (upd) {
                setStyle(upd, "padding:5px; background-color:#ffe0c8");
                showConfig();
            }
        }
        securityState = rootNode.getAttribute("securityState");
        loggedIn = rootNode.getAttribute("loggedIn") == "true";
        log("cv=" + currentVersion + " ss=" + securityState + " li=" + loggedIn);
        if (securityState == "locked") {
            var pwd = document.getElementById("GCVotePasswordActive");
 
            // changed by Odilbert for better style
            if (pwd) {
                setStyle(pwd, "vertical-align:middle");
            }
        }
        if (securityState == "locked" && !loggedIn) {
            showConfig();
        }
    }
    var votes = xmlDoc.getElementsByTagName("vote");
    var mapdivs = new Array();
    var displayStarsAboveIcon = false;
    if (pageType == "gmnearestlist") {
        var divs = document.getElementsByTagName("DIV");
        var mapdiv;
        for (var i = 0; i < divs.length; i++) {
//          if(divs[i].className=="LabeledMarker_markerLabel") {mapdiv=divs[i];break;}
            if (divs[i].className == "LabeledMarker_markerLabel" || divs[i].className == "LD_markerLabel_1") {
                log("numbersonmap=" + divs[i].style["visibility"]);
                if (divs[i].className == "LD_markerLabel_1" || divs[i].style["visibility"] != "hidden") {
                    displayStarsAboveIcon = true;
                }
                mapdiv = divs[i];
                break;
            }
        }
        if (mapdiv) {
            var divs = mapdiv.parentNode.childNodes;
            var re = /\((\w+)\)\s*$/;
            for (var i = 0; i < divs.length - 1; i += mapdivRange) {
                if (divs[i].getElementsByTagName("span").length > 0) {
                    divs[i].removeChild(divs[i].getElementsByTagName("span")[0]);
                }
                re.exec(divs[i + mapdivRange - 1].title);
                var wp = RegExp.$1;
                mapdivs[wp] = divs[i];
            }
        }
    }
    var totalVoteCount = 0;
    var nonzeroCacheCount = 0;
    var voteSum = 0;
    for (var i = 0; i < votes.length; i++) {
        var vote = votes[i];
        //var userName = vote.getAttribute("userName");
        var cacheId = vote.getAttribute("cacheId");
        var voteAvg = vote.getAttribute("voteAvg");
        var voteStars = vote.getAttribute(getStarAttributeName());
        var voteCnt = vote.getAttribute("voteCnt");
        totalVoteCount += Number(voteCnt);
        if (voteCnt > 0) {
            nonzeroCacheCount++;
            voteSum += parseFloat(voteStars);
        }
        var voteUser = vote.getAttribute("voteUser");
        var waypoint = vote.getAttribute("waypoint");
        var vote1 = vote.getAttribute("vote1");
        var vote2 = vote.getAttribute("vote2");
        var vote3 = vote.getAttribute("vote3");
        var vote4 = vote.getAttribute("vote4");
        var vote5 = vote.getAttribute("vote5");
        var rawVotes = vote.getAttribute("rawVotes");
        var span;
        if (pageType == "gmnearestlist") {
            if (waypoint && Number(voteCnt) >= getThreshold()) {
                var td = document.getElementById("td" + waypoint);
                if (td.getElementsByTagName("span").length > 0) {
                    td.removeChild(td.getElementsByTagName("span")[0]);
                }
                span = getSmallVoteSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, false, false);
                td.appendChild(span);
                td.parentNode.parentNode.setAttribute("GCVote_stars", voteStars);
                if (!mapdivs || !mapdivs[waypoint]) {
                    continue;
                }
                mapdivs[waypoint].appendChild(getSmallVoteSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, true, displayStarsAboveIcon));
            }
            continue;
        }
        else {
            if (getStatType() == 'classic') {
                rawVotes = null;
            }
            else {
                if (rawVotes == null) {
                    rawVotes = "";
                }
            }
            span = getNewSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, vote1, vote2, vote3, vote4, vote5, rawVotes);
        }
        var replace = false; // replace existing control or generate new one
//      if(document.getElementById("GCVoteLink"+cacheId+"=1") && document.getElementById("GCVoteLink"+cacheId+"=1").firstChild) {replace=true;}
        if (document.getElementsByName("VoteControl" + cacheId).length > 0) {
            replace = true;
        }
        if (pageType == "details") {
            var sizediv = document.getElementById("ctl00_ContentBody_uxLegendScale").parentNode.nextSibling.nextSibling;
            var container = document.createElement("span");
            var parent = sizediv.getElementsByTagName("span")[0];
            container.id = "GCVote_container";
            container.appendChild(span);
            if (replace) {
                log("replace");
                parent.replaceChild(container, document.getElementById("GCVote_container"));
            }
            else {
                parent.appendChild(container);
            }
            /*          var table=document.getElementById("yui-g").getElementsByTagName("table")[0].getElementsByTagName("tr")[0].getElementsByTagName("td")[0].getElementsByTagName("table")[1];
             var td=document.createElement("td");
             td.appendChild(span);
             var row=table.getElementsByTagName("tr")[0];
             log("pre-row");
             if(replace) {log("replace");row.replaceChild(td,row.getElementsByTagName("td")[2]);}
             else row.appendChild(td);
             log("post-row");*/
//          var hidden=document.getElementById("ctl00_ContentBody_DateHidden");
//          if(!hidden) hidden=document.getElementById("ctl00_ContentBody_Difficulty");
//          if(replace) {log("replace");hidden.parentNode.replaceChild(span,hidden.parentNode.getElementsByTagName("div")[0]);}
//          else hidden.parentNode.appendChild(span);
//          if(replace) {log("replace");hidden.parentNode.replaceChild(span,hidden.parentNode.getElementsByTagName("div")[0]);}
//          else hidden.parentNode.insertBefore(span,hidden.parentNode.getElementsByTagName("br")[0]);
        }
        else if (pageType == "cachePageNew") {
            var parent = document.getElementsByClassName("minorCacheDetails")[1];
            var container = document.createElement("span");
            container.id = "GCVote_container";
            container.appendChild(span);
            if (replace) {
                log("replace");
                parent.replaceChild(container, document.getElementById("GCVote_container"));
            }
            else {
                parent.appendChild(container);
            }
        }
        else if (pageType == "newMap") { //New Map
            //pageControl.newVoteData(waypoint, voteStars, voteCnt);
            if(browserType == "Chrome" || browserType == "FireFox"){
                window.postMessage({ type: "FROM_Ext_GCVoteDataRecived", text: JSON.stringify({"waypoint":waypoint, "voteStars":voteStars, "voteCnt":voteCnt, "voteAvg":voteAvg, "totalVoteCount":totalVoteCount, "voteUser":voteUser, "sortedVotes":[vote1,vote2,vote3,vote3,vote4,vote5], "rawVotes":rawVotes}) }, "*");
            }
            else{
                pageControl.newVoteData(waypoint, voteStars, voteCnt, cacheId, voteAvg, totalVoteCount,voteUser, [vote1,vote2,vote3,vote3,vote4,vote5], rawVotes);
            }
        }
        else if (pageType == "logedit") {
            var oldtr = document.getElementById("GCVote-logedit");
            if (oldtr) {
                oldtr.parentNode.removeChild(oldtr);
            }
            var displayInsert = true;
            var comment = document.getElementById("ctl00_ContentBody_LogBookPanel1_uxLogInfo");
            var newdiv = document.createElement("div");
            setStyle(newdiv, "margin-top:2em;margin-bottom:1em");
            if (comment) {
                comment.parentNode.appendChild(newdiv);
            }
            else {
                var logdate = document.getElementById("ctl00_ContentBody_LogBookPanel1_LogDate");
                if (logdate) {
                    logdate.parentNode.appendChild(newdiv);
                }
            }
            fillLogEditTR(newdiv, span, voteUser, displayInsert);
        }
        else if (pageType == "print") {
            var bd = document.getElementById("Content").getElementsByTagName("p")[7];
            setStyle(span, "display:inline;float:right");
            setStyle(span.firstChild, "display:inline");
            span.insertBefore(document.createTextNode("GCVote: "), span.firstChild);
            bd.appendChild(span);
        }
        else if (pageType == "nearestlist") {
            var tds = document.getElementsByName("td" + waypoint);
            log("found " + tds.length + " tds for nearestlist");
        userName=null; // kludge to disable voting since search results lack cacheIds
            for (var j = 0; j < tds.length; j++) {
                var td = tds[j];
                if (!td) {
                    log("parseXML could not find td" + waypoint);
                    continue;
                }
                span = getNewSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, vote1, vote2, vote3, vote4, vote5, rawVotes);
                if (replace) {
                    td.replaceChild(span, td.lastChild);
                }
                else {
                    td.appendChild(span);
                }
            }
        }
        else {
            var tds = document.getElementsByName("td" + cacheId);
            log("found " + tds.length + " tds");
            for (var j = 0; j < tds.length; j++) {
                var td = tds[j];
                if (!td) {
                    log("parseXML could not find td" + cacheId);
                    continue;
                }
                span = getNewSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, vote1, vote2, vote3, vote4, vote5, rawVotes);
                if (replace) {
                    td.replaceChild(span, td.lastChild);
                }
                else {
                    td.appendChild(span);
                }
            }
        }
        setVote(cacheId, voteUser);
    }
 
    if (document.URL == "http://www.geocaching.com/my/owned.aspx") { // add totals
        var tbody = document.getElementById("ctl00_ContentBody_lbHeading").parentNode.parentNode.getElementsByTagName("tbody")[0];
        var tr = document.createElement("tr");
        for (var i = 0; i < 3; i++) {
            var td = document.createElement("td");
            tr.appendChild(td);
        }
        var td = document.createElement("td");
        td.appendChild(document.createTextNode(tl("Total votes:") + " " + totalVoteCount));
        if (nonzeroCacheCount > 0) {
            td.appendChild(document.createElement("br"));
            log("voteSum=" + voteSum + "  nonzeroCacheCount=" + nonzeroCacheCount);
            td.appendChild(document.createTextNode(tl("Average rating:") + " " + Math.round(voteSum / nonzeroCacheCount * 10) / 10));
        }
        tr.appendChild(td);
        tbody.appendChild(tr);
    }
 /*   if (pageType == "gmnearestlist" && SORTSIDEBAR) {
        var cacheList = document.getElementById("cacheListBody");
        var list = cacheList.getElementsByTagName("TR");
        var arr = new Array();
        log("Sidebar length: " + list.length);
        for (var i = 0; list.length; i++) {
            arr[i] = list[0];
            cacheList.removeChild(list[0]);
        }
        arr.sort(function (a, b) {
            return b.getAttribute("GCVote_stars") - a.getAttribute("GCVote_stars");
        });
        for (var i = 0; i < arr.length; i++) {
            cacheList.appendChild(arr[i]);
        }
        log("sorted");
    }*/
    if (document.getElementById("GCVoteWaitMap")) {
        var e = document.getElementById("GCVoteWaitMap");
        e.parentNode.removeChild(e);
    }
    if (batchesWaiting == currentBatch) {
        batchesWaiting = 0;
        currentBatch = 0;
        reqCacheIds = 0;
    }
    else {
        currentBatch++;
        if (batchesWaiting - currentBatch < 0) {
            return;
        }
        window.setTimeout(requestVoteBatch, 2000);
//      requestVoteBatch(null,null);
    }
}
 
function requestVote(cacheId) {
    // request vote for a single cache
    requestVoteO(cacheId, null, null);
}
 
function requestVoteO(cacheId, waypoint, owner) {
    // request vote for a single cache
    log("requestVote " + cacheId);
    var cacheIds = new Array(cacheId);
    requestVotesO(cacheIds, waypoint, owner);
}
 
function requestVotes(cacheIds) {
    // request votes for a number of caches
    requestVotesO(cacheIds, null, null);
}
 
function requestVotesO(cacheIds, waypoint, owner) {
    // request votes for a number of caches
    log("requestVotes");
    batchesWaiting = Math.ceil(cacheIds.length / 100) - 1;
    currentBatch = 0;
    reqCacheIds = cacheIds;
    requestVoteBatch(waypoint, owner);
}
 
function requestVoteBatch() {
    requestVoteBatch(null, null);
}
 
function requestVoteBatch(waypoint, owner) {
    // request a single batch of votes
    log("requestVoteBatch " + currentBatch + "/" + batchesWaiting);
    var cacheIds;
    if (batchesWaiting - currentBatch == 0) {
        cacheIds = reqCacheIds.slice(currentBatch * 100);
    }
    else {
        cacheIds = reqCacheIds.slice(currentBatch * 100, (currentBatch + 1) * 100);
    }
    var user = userName;
    if (!user) {
        user = "uglyDUMMYusernamesolution";
    }
    var dataString = "version=" + version + "&userName=" + user + "&cacheIds=" + cacheIds + "&password=" + encodeURIComponent(getPassword());
    if (waypoint) {
        dataString += "&waypoint=" + waypoint;
//      log(waypoint);
    }
    if (owner) {
        dataString += "&owner=" + owner;
//      log(owner);
    }
    xmlhttpRequest({
        method:'POST',
        headers:{'Content-type':'application/x-www-form-urlencoded; charset=UTF-8'},
        data:dataString,
        url:GETVOTES,
        onload:function (responseDetails) {
            parseXML(responseDetails.responseText);
        },
        onerror:function (responseDetails) {
            alert(tl("Unable to get votes from server! Errorcode ") + responseDetails.status);
        }
    });
}
 
function requestVotesForWaypoints(waypoints) {
    // request votes for a number of caches identified by waypoints
    log("requestVotesForWaypoints");
    var user = userName;
    if (!user) {
        user = "uglyDUMMYusernamesolution";
    }
    xmlhttpRequest({
        method:'POST',
        headers:{'Content-type':'application/x-www-form-urlencoded; charset=UTF-8'},
        data:"version=" + version + "&userName=" + user + "&waypoints=" + waypoints + "&password=" + encodeURIComponent(getPassword()),
        url:GETVOTES,
        onload:function (responseDetails) {
            parseXML(responseDetails.responseText);
        },
        onerror:function (responseDetails) {
            alert(tl("Unable to get votes from server! Errorcode ") + responseDetails.status);
        }
    });
}
 
function sendVote(cacheId, voteUser) {
    // send vote for cache with unknown waypoint to server
    log("sendVote " + cacheId + " -> " + voteUser);
    sendVoteWaypoint(cacheId, null, voteUser);
}
 
function sendVoteWaypoint(cacheId, waypoint, voteUser) {
    // send the user's new vote including waypoint to server
    log("sendVoteWaypoint " + cacheId + " (" + waypoint + ") -> " + voteUser);
    var seturl = SETVOTE + "?cacheId=" + cacheId + "&userName=" + userName + "&voteUser=" + voteUser + "&password=" + encodeURIComponent(getPassword());
    if (waypoint) {
        seturl += "&waypoint=" + waypoint;
    }
    log(seturl);
    xmlhttpRequest({
        method:'GET',
        url:seturl,
        onload:function (responseDetails) {
            if (responseDetails.responseText == "OK") {
                voteLink = document.getElementById("GCVoteLink" + cacheId + "=" + voteUser)
                setStyle(voteLink, "background-color:orange;font-weight:bolder;color:black"); // highlight confirmed vote
                requestVote(cacheId); // request reload of displayed score
            }
            else if (responseDetails.responseText.indexOf("wrong password") >= 0) {
                log(responseDetails.responseText);
                displayMessage(tl("Your Account is password protected and you supplied no or the wrong password. "
                    + "If you did not register a password, please inform me: guido.wegener@gmx.de"));
                window.location = voteServerBase + "/passwordwrong.php";
                return;
            }
            else {
                displayMessage(tl("Error while sending vote: ") + responseDetails.status + "; '" + responseDetails.responseText + "'");
            }
        },
        onerror:function (responseDetails) {
            alert(tl("Unable to send vote to server! Errorcode ") + responseDetails.status);
        }
    });
}
 
function GCVote_voteClick() {
    // user clicked a link to change his vote
    log("voteClick");
    if (securityState != "locked") {
        log("voteClick wrong");
        window.location = voteServerBase + "/passworderror.php";
        return;
    }
    log("voteClick ok");
    var reg = /#([^=]*)=([0-9\.]*)/;
    reg.exec(this);  // "this" contains the clicked URL
    var cacheId = RegExp.$1;
    var voted = RegExp.$2;
    setVote(cacheId, voted); // display user's choice
    var imgWaits = document.getElementsByName("GCVoteWait" + cacheId);
    for (var i = 0; i < imgWaits.length; i++) {
        setStyle(imgWaits[i], "position:relative;top:3px");
    }
    sendVote(cacheId, voted); // send new vote to server
}
 
function avg2suffix(avg, voteCnt) {
//  log("avg2suffix "+avg+", "+voteCnt+" - "+Math.abs(Number(voteCnt))+" - "+getThreshold());
    if (Math.abs(Number(voteCnt)) < getThreshold()) {
        return "0";
    }
    var avg2 = Math.round(avg * 2) / 2;
    var favg2 = Math.floor(avg2);
    var s = favg2;
    if (avg2 - favg2 > .25) {
        s += "_5";
    }
    return s;
}
 
function getSmallVoteSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, onMap, aboveIcon) {
    log("getsmallvote");
    var span = document.createElement("span");
    var em = document.createElement("em");
    em.setAttribute("style", "font-size:xx-small;color:" + colorCodeForVoteCount(voteCnt)); //#909090")
    em.appendChild(document.createTextNode(" (" + voteCnt + ")"));
    var img = document.createElement("img");
    var opacity = Math.min(0.4 + Math.abs(Number(voteCnt)) / 6, 1);
    if (onMap) {
        img.setAttribute("width", "34px");
        img.setAttribute("height", "8px");
        setStyle(img, "opacity:" + opacity + ";position:relative;left:-7px;top:" + (aboveIcon ? "-37" : "-7") + "px");
    }
    else {
        img.setAttribute("width", "36px");
        img.setAttribute("height", "9px");
    }
    var s = avg2suffix(voteStars, voteCnt);
    var voteAvg1 = new Number(voteAvg);
    img.src =  iconStorage.getStar(s);
    span.appendChild(img);
    if (Number(voteCnt) >= getThreshold() && !onMap) {
        span.appendChild(em);
    }
    return span;
}
 
function colorCodeForVoteCount(voteCnt) {
    var voteColor = Math.log(Math.abs(voteCnt)) / Math.log(50);
    if (voteColor > 1) {
        voteColor = 1;
    }
    if (voteColor < 0) {
        voteColor = 0;
    }
    voteColor = Math.floor(voteColor * 180);
    voteColor = voteColor.toString(16);
    while (voteColor.length < 2) {
        voteColor = "0" + voteColor;
    }
//  log("voteCnt="+voteCnt+"  voteColor="+voteColor);
    return "#00" + voteColor + "00";
}
 
function getNewSpan(cacheId, voteStars, voteAvg, voteCnt, voteUser, vote1, vote2, vote3, vote4, vote5, rawVotes) {
    // generate HTML node containing average and user's vote
//  log("getspan cacheid="+cacheId+" userName="+userName);
    function getVoteLink(cacheId, vote, text) {
        // generate single link for a user's vote
        var voteLink = document.createElement("a");
        addEvent(voteLink, "click", GCVote_voteClick);
        voteLink.setAttribute("href", "#" + cacheId + "=" + vote);
        setStyle(voteLink, "text-decoration:none!important");
        voteLink.id = "GCVoteLink" + cacheId + "=" + vote;
        voteLink.setAttribute("name", "GCVoteLink" + cacheId + "=" + vote);
        voteLink.title = text;
        var voteText = (vote == 0 ? "?" : Math.floor(vote));
        if (Math.floor(vote) < vote) {
            var halfVote = document.createElement("span");
            setStyle(halfVote, "color:grey;font-size:1.4ex");
            halfVote.appendChild(voteLink);
            voteLink.appendChild(document.createTextNode("\u00bd"));
            return halfVote;
        }
        voteLink.appendChild(document.createTextNode(voteText));
        return voteLink;
    }
 
    var div = document.createElement("div");
    setStyle(div, "z-index:200");
    div.setAttribute("name", "VoteControl" + cacheId);
    if (pageType == "details" || pageType == "cachePageNew") {
        setStyle(div, "float:right");
    }
    if (pageType == "loglist") {
        setStyle(div, "float:left");
    }
    if (pageType == "nearestlist") {
        setStyle(div, "float:left");
    }
    var span = document.createElement("div");
    setStyle(span, "white-space:nowrap;font-size:small;padding:0px;margin:0px;line-height:80%;");
//  if(voteUser>0) {span.setAttribute("style","white-space:nowrap");}
//  else {span.setAttribute("style","white-space:nowrap;background-color:#FFF0FF");}
 
    // skip "Quality:"-string for all tables containing a table header
    if (pageType != "profile" && pageType != "nearestlist" && pageType != "bookmarks" && pageType != "loglist" && (!getCompactCurrentPage())) {
        var bold = document.createElement("b");
        bold.appendChild(document.createTextNode(" " + tl("Quality") + ": "));
        span.appendChild(bold);
    }
 
    var img = document.createElement("img");
    var s = avg2suffix(voteStars, voteCnt);
    var voteAvg1 = new Number(voteAvg);
    img.src = iconStorage.getStar(s);
    var tooltip = tl("Average (mean) ") + voteAvg1.toFixed(1) + tl(" out of 5");
    img.setAttribute("alt", tooltip);
    img.setAttribute("title", tooltip);
    img.setAttribute("align", "absmiddle");
    // set image id
    img.id = "gcvoteStars" + cacheId;
    // add onclick event listener
    addEvent(img, "click", toggleGCVoteDetails(cacheId, span));
    // modify img's cursor
    img.style.cursor = 'pointer';
    span.appendChild(img);
    if (rawVotes != null) {
        createGCVoteBarDetails(span, cacheId, voteCnt, rawVotes);
    }
    else {
        createGCVoteDetails(span, cacheId, voteCnt, vote1, vote2, vote3, vote4, vote5);
    }
    span.appendChild(img);
    var small = document.createElement("small");
    var em = document.createElement("em");
    setStyle(em, "color:" + colorCodeForVoteCount(voteCnt) + ";font-weight:normal;font-size:1.15em");
    em.appendChild(document.createTextNode(" (" + translateVoteCount(voteCnt) + ")"));
    small.appendChild(em);
    span.appendChild(small);
    if (userName) {
        var span2 = document.createElement("div");
        var fontfactor = "1.1";
        if (pageType == "details" || pageType == "cachePageNew") {
            fontfactor = "1.3";
        }
        setStyle(span2, "white-space:nowrap;font-size:" + fontfactor + "em");
        var small2 = document.createElement("small");
        if (!getCompactCurrentPage()) {
            var em2 = document.createElement("em");
            em2.appendChild(document.createTextNode(tl(" your vote: ")));
            small2.appendChild(em2);
        }
        span2.appendChild(small2);
        span2.appendChild(getVoteLink(cacheId, 0, tl("neutral / not rated yet")));
        span2.appendChild(getVoteLink(cacheId, 1, tl("1: poor")));
        if (HALFSTARS) {
            span2.appendChild(getVoteLink(cacheId, 1.5, tl("1.5: fairly poor")));
        }
        span2.appendChild(getVoteLink(cacheId, 2, tl("2: below average")));
        if (HALFSTARS) {
            span2.appendChild(getVoteLink(cacheId, 2.5, tl("2.5: not so bad")));
        }
        span2.appendChild(getVoteLink(cacheId, 3, tl("3: average")));
        if (HALFSTARS) {
            span2.appendChild(getVoteLink(cacheId, 3.5, tl("3.5: not bad at all")));
        }
        span2.appendChild(getVoteLink(cacheId, 4, tl("4: better than average")));
        if (HALFSTARS) {
            span2.appendChild(getVoteLink(cacheId, 4.5, tl("4.5: very good")));
        }
        span2.appendChild(getVoteLink(cacheId, 5, tl("5: awesome")));
        var imgWait = document.createElement("img");
        imgWait.setAttribute("width", "14px");
        imgWait.setAttribute("height", "14px");
        imgWait.src = "https://www.geocaching.com/images/loading.gif";
        setStyle(imgWait, "display:none");
        imgWait.id = "GCVoteWait" + cacheId;
        imgWait.setAttribute("name", "GCVoteWait" + cacheId);
        span2.appendChild(imgWait);
    }
    div.appendChild(span);
    if (userName) {
        div.appendChild(span2);
    }
    return div;
}
 
function fillLogEditTR(tr, span, voteUser, displayInsert) {
    log("filltr " + displayInsert);
    var td = document.createElement("span");
    td.appendChild(span);
    tr.appendChild(td);
 
    var td2 = document.createElement("span");
    var displayInsert = true;
    if (!document.getElementById("ctl00_ContentBody_LogBookPanel1_uxLogInfo")) {
        displayInsert = false;
    }
    if (displayInsert) {
        var button = document.createElement("input");
        button.setAttribute("type", "button");
        button.setAttribute("value", tl("Insert GCVote Info"));
        addEvent(button, "click", function (event) {
            log("Insert GCVote Info " + voteUser);
            var template = getAdvertisementTemplate();
            //      var string = template.replace("%%%",voteUser);
            var vu = voteUser;
            if (Math.round(voteUser) == vu) {
                vu = Math.round(voteUser);
            }
            var string = template.toString().replace("%%%", vu);
            var logbox = document.getElementById("ctl00_ContentBody_LogBookPanel1_uxLogInfo");
            log(logbox.toString());
            if (vu != 0) {
                logbox.value = logbox.value.substring(0, logbox.selectionStart) + string + logbox.value.substring(logbox.selectionEnd, logbox.value.length);
            }
//          if(vu!=0) {logbox.value=logbox.value + string;}
        });
        td2.appendChild(button);
    }
    td2.appendChild(document.createElement("br"));
    tr.appendChild(td2);
    tr.id = "GCVote-logedit";
}
 
function toggleGCVoteDetails(cacheId, parent) {
    return function () {
        log("toggleGCVoteDetails " + cacheId);
 
        var detailsDiv = parent.getElementsByTagName("table")[0];
        var p = parent.getElementsByTagName("img")[0];
 
        if (!detailsDiv) {
            log("detailsDiv is 0");
            return false;
        }
        if (!p) {
            log("parent is 0");
            return false;
        }
 
        if (detailsDiv.style.visibility != "visible") {
            detailsDiv.style.position = "absolute";
            detailsDiv.style.top = "13px";
            parent.style.position = 'relative';
            detailsDiv.style.left = (parent.offsetWidth - detailsDiv.offsetWidth) + "px";
            detailsDiv.style.visibility = "visible";
        }
        else {
            detailsDiv.style.visibility = "hidden";
        }
 
        return false;
    }
}
 
function createGCVoteDetailsRow(table, vote, votecount) {
    var row = document.createElement("tr");
    table.appendChild(row);
 
    var td1 = document.createElement("td");
    row.appendChild(td1);
 
    var img = document.createElement("img");
    img.src =  iconStorage.getStar( vote );
    td1.appendChild(img);
 
    var td2 = document.createElement("td");
    if (votecount != 0) {
        td2.style.fontWeight = "bold";
    }
    td2.appendChild(document.createTextNode(translateVoteCount(votecount)));
    row.appendChild(td2);
}
 
// Modifications by Flopp <flopp-gc@online.de>
// * Extract "half-stars" from "rawVotes"
// * Display "half-stars" in histrograms (google charts api)
 
function extractVotes(s, v) {
    var r = new RegExp("\\(" + v + ":([0-9]+)\\)");
    var m = r.exec(s);
    if (m) {
        return parseInt(m[1]);
    } else {
        return 0;
    }
}
 
function createGCVoteBarDetails(parent, cacheId, votes, rawVotes) {
    var table = document.createElement('table');
    setStyle(table, "z-index:200");
    table.id = "gcvoteDetails" + cacheId;
    table.style.position = "absolute";
    table.style.visibility = "hidden";
    table.style.backgroundColor = "#eff4f9";
    table.style.border = "solid 1px #c0cee3";
    table.style.width = "auto";
    addEvent(table, "click", toggleGCVoteDetails(cacheId, parent));
    parent.appendChild(table);
 
    var row1 = document.createElement('tr');
    table.appendChild(row1);
 
    var header = document.createElement("td");
    header.style.fontWeight = "bold";
    header.appendChild(document.createTextNode(tl("Distribution of votes:")));
    row1.appendChild(header);
 
 
    var v10 = extractVotes(rawVotes, "1.0");
    var v15 = extractVotes(rawVotes, "1.5");
    var v20 = extractVotes(rawVotes, "2.0");
    var v25 = extractVotes(rawVotes, "2.5");
    var v30 = extractVotes(rawVotes, "3.0");
    var v35 = extractVotes(rawVotes, "3.5");
    var v40 = extractVotes(rawVotes, "4.0");
    var v45 = extractVotes(rawVotes, "4.5");
    var v50 = extractVotes(rawVotes, "5.0");
 
    var maxv = 0;
    if (v10 > maxv) {
        maxv = v10;
    }
    if (v15 > maxv) {
        maxv = v15;
    }
    if (v20 > maxv) {
        maxv = v20;
    }
    if (v25 > maxv) {
        maxv = v25;
    }
    if (v30 > maxv) {
        maxv = v30;
    }
    if (v35 > maxv) {
        maxv = v35;
    }
    if (v40 > maxv) {
        maxv = v40;
    }
    if (v45 > maxv) {
        maxv = v45;
    }
    if (v50 > maxv) {
        maxv = v50;
    }
 
    if (maxv > 0) {
        scale = maxv + maxv / 2;
        u = 'https://chart.googleapis.com/chart?cht=bvg&chs=175x75&chm=N,000000,0,-1,10,,h&chds=0,' + scale + '&chd=t:' + v10 + ',' + v15 + ',' + v20 + ',' + v25 + ',' + v30 + ',' + v35 + ',' + v40 + ',' + v45 + ',' + v50 + '&chco=ef6a2f&chbh=14,1,5&chxt=x&chxl=0:|1|1.5|2|2.5|3|3.5|4|4.5|5';
    }
    else {
        u = "https://chart.googleapis.com/chart?chst=d_bubble_icon_text_big&chld=star||" + tl("no+votes") + "||000000";
    }
 
    var img = document.createElement("img");
    img.src = u;
 
    var row2 = document.createElement("tr");
    table.appendChild(row2);
 
    var imgcontainer = document.createElement("td");
    imgcontainer.style.textAlign = "center";
    imgcontainer.appendChild(img);
 
    row2.appendChild(imgcontainer);
}
 
function createGCVoteDetails(parent, cacheId, votes, vote1, vote2, vote3, vote4, vote5) {
    var div = document.createElement('div');
    setStyle(div, "z-index:200");
    div.id = "gcvoteDetails" + cacheId;
    div.style.position = "absolute";
    div.style.visibility = "hidden";
    div.style.backgroundColor = "#eff4f9";
    div.style.border = "solid 1px #c0cee3";
    addEvent(div, "click", toggleGCVoteDetails(cacheId, parent));
    parent.appendChild(div);
 
    var header = document.createElement("div");
    header.style.fontWeight = "bold";
    header.style.fontStyle = "small";
    header.appendChild(document.createTextNode(tl("Distribution of votes:")));
    div.appendChild(header);
 
    var table = document.createElement("table");
 
    div.appendChild(table);
 
    createGCVoteDetailsRow(table, "1", vote1);
    createGCVoteDetailsRow(table, "2", vote2);
    createGCVoteDetailsRow(table, "3", vote3);
    createGCVoteDetailsRow(table, "4", vote4);
    createGCVoteDetailsRow(table, "5", vote5);
}
 
// code for log(), setValue(), getValue() is an edited version of code released by James Campos
// @copyright      2009, James Campos
// @license        cc-by-3.0; http://creativecommons.org/licenses/by/3.0/
 
function log(str) {
    if (LOGGING) {
        if (typeof(GM_log) == "undefined") {
            if (console && console.log) {
                console.log(str);
            }
        }
        else {
            GM_log(str);
        }
    }
}
 
function setValue(key, val) {
    if (typeof(chrome) !== "undefined") {
        val = (typeof val)[0] + val;
	}
	
	localStorageCache[key] = val;
	var data = {};
	data[key] = val;
	window.postMessage("GCV_Storage_" + JSON.stringify(data), "*"); 
}
 
function getValue(key, defaultValue) {	
	var value = localStorageCache[key];	
	
    if (typeof(GM_getValue) == "undefined" || (typeof(chrome) !== "undefined" &&(GM_getValue.toString && GM_getValue.toString().indexOf("not supported") != -1))) {
        if (typeof(value) === "undefined")
		{
			return defaultValue;
		}
		
		if(typeof(chrome) !== "undefined"){			
			var type = value[0];
			value = value.substring(1);
			switch (type) {
				case 'b':
					return value == 'true';
				case 'n':
					return Number(value);
				default:
					return value;
			}
		}
		else{
			if (value == "false") {
				return false;
			}
			else if (value == "true") {
				return true;
			}
			else {
				return value;
			}
		}
    }
    else {
		if (typeof(value) === "undefined")
		{
			value = localStorageCache[key] = GM_getValue(key, defaultValue);
		}
		
        if (value == "false") {
            return false;
        }
        else if (value == "true") {
            return true;
        }
        else {
            return value;
        } 
    }
}
 
window.addEventListener("message", function(e){
	if(e.data && typeof(e.data) === "string" && e.data.indexOf("GCV_Storage_") === 0){
		var data = JSON.parse(e.data.replace("GCV_Storage_", ""));
		
		for(key in data){
			localStorageCache[key] = data[key];
			if (!(typeof(GM_setValue) == "undefined" || (typeof(chrome) !== "undefined" &&(GM_setValue.toString && GM_setValue.toString().indexOf("not supported") != -1)))) {
				GM_setValue(key, data[key]);
			}
		}
		
		if (typeof(GM_setValue) == "undefined" || (typeof(chrome) !== "undefined" &&(GM_setValue.toString && GM_setValue.toString().indexOf("not supported") != -1))) {
			chrome.runtime.sendMessage({"setValue": data}, function(){});
		}	
	}
});	
 
function xmlhttpRequest(request) {
    if (typeof(GM_xmlhttpRequest) == "undefined") {
        if (typeof(chrome) != "undefined" && chrome.extension) {
            log("calling extension");
            chrome.extension.sendRequest(request, function (response) {
                if (response.status == 200) {
                    log("response ok, calling " + request.onload + " for " + response);
                    request.onload(response);
                } else {
                    request.onerror(response);
                }
            });
        } else if (typeof(safari) !== "undefined") {
            safariSendRequest(request);
        }
    }
    else {
        GM_xmlhttpRequest(request);
    }
}
 
function displayVersionInfo() {
    log("versionInfo");
    var vit = document.getElementById("VersionInfoText");
    log("vit=" + vit);
    var vin = document.getElementById("VersionInfoNumber");
    log("vin=" + vin);
    if (!vit || !vin) {
        return;
    }
    var currentversion = document.getElementById("currentversion").firstChild.data;
    log("versioninfo found: -" + currentversion + "-  installed: -" + version + "-");
    vin.appendChild(document.createTextNode(version));
    setStyle(vit, "");
    if (currentversion == version) {
        setStyle(document.getElementById("updatelink"), "display:none");
    }
    if (typeof(Pro_log) != "undefined") {
        document.getElementById("updatelink").getElementsByTagName("a")[0].href = "gcvote.ieuser.js";
    }
}
 
function getTooltipSpan(text, tooltip) {
    var span = document.createElement("span");
    span.appendChild(document.createTextNode(tl(text)));
    span.setAttribute("title", tl(tooltip));
    return span;
}
 
function getAdvertisementTemplate() {
    var str = getValue("advertisementTemplate");
    if (!str) {
        log("no ad text in GM, using " + GCVoteAdvertisementDefault);
        setValue("advertisementTemplate", GCVoteAdvertisementDefault);
        str = GCVoteAdvertisementDefault;
    }
    return str;
}
 
function getStarAttributeName() {
    var str = getValue("starAttributeName");
    if (!str) {
        setValue("starAttributeName", "voteAvg");
        str = "voteAvg";
    }
    return str;
}
 
function getStatType() {
    var str = getValue("statType");
    if (!str) {
        setValue("statType", "bars");
        str = "bars";
    }
    return str;
}
 
function getPassword() {
    var str = getValue("password[" + userName + "]");
    if (!str) {
        setValue("password[" + userName + "]", "");
        str = "";
    }
    return str;
}
 
function getThreshold() {
    var threshold = getValue("threshold");
    if (!threshold) {
        setValue("threshold", 1);
        threshold = 1;
    }
    return Number(threshold);
}
 
function getHalfstars() {
    var halfstars = getValue("halfstars");
    if (typeof(halfstars) == 'undefined') {
        setValue("halfstars", false);
        halfstars = false;
    }
    return Boolean(halfstars);
}
 
function getLogging() {
    var logging = getValue("logging");
    if (typeof(logging) == 'undefined') {
        setValue("logging", false);
        logging = false;
    }
    return Boolean(logging);
}
 
function getCompact() {
    var compact = getValue("compact");
    if (typeof(compact) == 'undefined') {
        setValue("compact", false);
        compact = false;
    }
    return Boolean(compact);
}
 
function getLanguage() {
    return languageHelper;
}
 
function setLanguage(delayedCall) {
    if (browserType == "FireFox" && !delayedCall) {
        var language = getValue("language","");
        if (language != "") {
            languageHelper = language;
        }
        else{
            //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation
            setTimeout(function () {
                setLanguage(true);
            }, 0);
        }      
    }
    else {
        var language = getValue("language");
        if (typeof(language) == 'undefined') {
        if (typeof(window.navigator.language) != 'undefined') {
            language = (window.navigator.language) ? window.navigator.language
: window.navigator.userLanguage;
            if (typeof(language) == 'undefined') {
                language = "en";
            }
        } else {
            language = "en";
        }
            log("detected language " + language);
            language = language.substr(0, 2);
            setValue("language", language);
        }
        languageHelper = language;
    }
}
 
function getAutoUpdateMap() {
    var update = getValue("autoupdatemap");
    if (typeof(update) == 'undefined') {
        setAutoUpdateMap(true);
        update = true;
    }
    return Boolean(update);
}
 
function setAutoUpdateMap(flag) {
    setValue("autoupdatemap", Boolean(flag));
}
 
function getDisableOnLongLists() {
    var update = getValue("DisableOnLongLists");
    if (typeof(update) == 'undefined') {
        setAutoUpdateMap(false);
        update = false;
    }
    return Boolean(update);
}
 
function setDisableOnLongLists(flag) {
    setValue("DisableOnLongLists", Boolean(flag));
}
 
function getCompactCurrentPage() {
    if (!getCompact()) {
        return false;
    }
    switch (pageType) {
        case "details":
            return true;
        case "loglist":
            return true;
        case "gmnearestlist":
            return true;
        case "nearestlist":
            return true;
        case "overviewlist1":
            return true;
        case "overviewlist2":
            return true;
        case "logedit":
            return false;
        case "bookmarks":
            return true;
        case "watchlist":
            return true;
        case "profile":
            return true;
        case "favorites":
            return true;
        case "print":
            return true;
        default:
            return false;
    }
}
 
function saveConfig(Event) {
    var newPwd = document.getElementById("GC-Vote-Password").value;
    var oldPwd = getPassword();
    var reload = false;
    if (newPwd != oldPwd) {
        reload = true;
    }
    setValue("password[" + userName + "]", newPwd);
    setValue("advertisementTemplate", document.getElementById("GC-Vote-Template").value);
    setValue("threshold", document.getElementById("GC-Vote-threshold").value);
    if (document.getElementById("GC-Vote-Stars-Average").checked) {
        setValue("starAttributeName", "voteAvg");
        log("avg");
    }
    else if (document.getElementById("GC-Vote-Stars-Median").checked) {
        setValue("starAttributeName", "voteMedian");
        log("med");
    }
    var options = document.getElementById("GC-Vote-language").options;
    for (i = 0; i < options.length; i++) {
        if (options[i].selected) {
            setValue("language", options[i].value);
            log("language=" + options[i].value);
        }
    }
    log("logging=" + document.getElementById("GC-Vote-logging").checked);
    log("halfstars=" + document.getElementById("GC-Vote-half").checked);
    setValue("logging", document.getElementById("GC-Vote-logging").checked);
    setValue("halfstars", document.getElementById("GC-Vote-half").checked);
    setValue("compact", document.getElementById("GC-Vote-compact").checked);
    setValue("DisableOnLongLists", document.getElementById("GC-Vote-longList").checked);
  
    var mapOptions = ["enableIcons", "enablePopup", "enableTable", "enableTableSort", "enableLocalCaching", "enableCacheGeneration", "enableAutomaticCacheGeneration", "enableGcPersoFix", "enableSaveVisibility"];
 
    for(var i=0; i<mapOptions.length;i++)
    {
    setValue(mapOptions[i], document.getElementById("GC-Vote-"+mapOptions[i]).checked);
    if(mapOptions[i] == "enableGcPersoFix" && !mapOptions[i].checked){
        setValue("apiKey_"+"GCPersonalisationFix", "");
        setValue("authKey_"+"GCPersonalisationFix", "");       
    }
    }
 
    setValue("iconStoreActiveIcon",document.getElementById("GC-Vote-StarDesign").selectedIndex);
     
    if (document.getElementById("GC-Vote-StatType-Bars").checked) {
        setValue("statType", "bars");
    }
    else {
        setValue("statType", "classic");
    }
    if (reload || true) {
        window.location.reload();
    }
}
 
function showConfig() {
    if (!document.getElementById("GCVote-Config")) {
        return;
    }
    setStyle(document.getElementById("GCVote-Config"), "");
    setStyle(document.getElementById("show GCVote-Config"), "display:none");
    setStyle(document.getElementById("hide GCVote-Config"), "");
    setStyle(document.getElementById("GC-Vote-Div-Dummy"), "display:none");
}
 
function hideConfig() {
    if (!document.getElementById("GCVote-Config")) {
        return;
    }
    setStyle(document.getElementById("GCVote-Config"), "display:none");
    setStyle(document.getElementById("show GCVote-Config"), "");
    setStyle(document.getElementById("hide GCVote-Config"), "display:none");
    setStyle(document.getElementById("GC-Vote-Div-Dummy"), "");
}
 
function insertGCVoteMenu() {
    log("insertGCVoteMenu");
    var sidebar = document.getElementById("ctl00_ContentBody_WidgetMiniProfile1_LoggedInPanel");
    if (!sidebar) {
        if (document.URL == "http://www.geocaching.com/my/"
            && !document.getElementById("ctl00_ContentBody_WidgetMiniProfile1_LoggedOutPanel")) {
            // Added by Odilbert for better error handling
            displayMessage(tl("Couldn't find entry tag for inserting GCVote configuration window. Maybe the geocaching.com website has been changed. " +
                "Please have a look on http://gcvote.com and check for possibly released GCVote updates."));
        }
 
        return;
    }
    var header = document.createElement("h3");
    header.setAttribute("class", "widget-header");
    var imgMinus = document.createElement("img");
    imgMinus.setAttribute("src", "https://www.geocaching.com/images/minus.gif");
    imgMinus.setAttribute("alt", tl("hide config"));
    var linkMinus = document.createElement("a");
    addEvent(linkMinus, "click", hideConfig);
    linkMinus.id = "hide GCVote-Config"
    setStyle(linkMinus, "display:none");
    linkMinus.appendChild(imgMinus);
    header.appendChild(linkMinus);
    var imgPlus = document.createElement("img");
    imgPlus.setAttribute("src", "https://www.geocaching.com/images/plus.gif");
    imgPlus.setAttribute("alt", tl("show config"));
    var linkPlus = document.createElement("a");
    addEvent(linkPlus, "click", showConfig);
    linkPlus.id = "show GCVote-Config"
    linkPlus.appendChild(imgPlus);
    header.appendChild(linkPlus);
    header.appendChild(document.createTextNode(" " + tl("GCVote Configuration") + " (v " + version + ")"));
    var divDummy = document.createElement("div");
    divDummy.appendChild(document.createTextNode("\u00A0"));
    divDummy.id = "GC-Vote-Div-Dummy";
    var div = document.createElement("div");
    setStyle(div, "display:none");
    div.id = "GCVote-Config";
    var p1 = document.createElement("p");
    p1.id = "GC-Vote-update";
    setStyle(p1, "display:none");
    var updateLink = document.createElement("a");
    updateLink.setAttribute("href", voteServerBase);
    updateLink.appendChild(document.createTextNode(tl("Update GCVote")));
    p1.appendChild(updateLink);
    div.appendChild(p1);
    var p2 = document.createElement("p");
    setStyle(p2, "margin:0px;padding:0px;font-size:0.95em");
 
    var linkHome = document.createElement("a");
    linkHome.setAttribute("href", "http://www.gcvote.de");
    linkHome.appendChild(document.createTextNode(tl("Homepage")));
    var linkHelp = document.createElement("a");
    linkHelp.setAttribute("href", voteServerBase + "/help.html");
    setStyle(linkHelp, "position:relative;right:3px;float:right;font-size:larger;font-weight:bold");
    linkHelp.appendChild(getTooltipSpan("?", "Help"));
    p2.appendChild(linkHelp);
    p2.appendChild(linkHome);
    p2.appendChild(document.createElement("br"));
    var linkListVotes = document.createElement("a");
    addEvent(linkListVotes, "click", listVotes);
    linkListVotes.setAttribute("href", "#");
//  linkListVotes.setAttribute("style","cursor:pointer");
    linkListVotes.appendChild(document.createTextNode(tl("List my votes")));
    p2.appendChild(linkListVotes);
    p2.appendChild(document.createElement("br"));
    var linkChangePassword = document.createElement("a");
    addEvent(linkChangePassword, "click", changePassword);
    linkChangePassword.setAttribute("href", "#");
    linkChangePassword.appendChild(document.createTextNode(tl("Change password")));
    p2.appendChild(linkChangePassword);
    p2.appendChild(document.createElement("br"));
    var linkDeleteCache = document.createElement("a");
    addEvent(linkDeleteCache, "click", deleteCaches);
    linkDeleteCache.setAttribute("href", "#");
    linkDeleteCache.appendChild(document.createTextNode(tl("Delete local caches")));
    p2.appendChild(linkDeleteCache);
    p2.appendChild(document.createElement("br"));   
 
    var textBoxesTable = document.createElement("table");
    textBoxesTable.id = "GCVoteTextBoxesTable";
    textBoxesTable.setAttribute("cellpadding", "0");
    textBoxesTable.setAttribute("cellspacing", "0");
    textBoxesTable.setAttribute("cellborder", "0");
    setStyle(textBoxesTable, "margin-top:1px");
 
    var passwordRow = document.createElement("tr");
 
    var spanPwd = document.createElement("span");
    spanPwd.id = "GCVotePasswordSpan";
    spanPwd.appendChild(getTooltipSpan("Password:", "passwords must be registered via GC.com-mail to BonnerGuido"));
 
    var inputPassword = document.createElement("input");
    inputPassword.setAttribute("type", "password");
    setStyle(inputPassword, "margin:1px 0px 1px 3px;font-size:x-small");
    inputPassword.id = "GC-Vote-Password";
    inputPassword.value = getPassword();
 
    var imgPadlock = document.createElement("img");
    imgPadlock.id = "GCVotePasswordActive";
    setStyle(imgPadlock, "display:none");
    imgPadlock.setAttribute("src", voteServerBase + "/padlock.gif");
    imgPadlock.setAttribute("alt", tl("password active"));
 
    var newtd = document.createElement("td");
    newtd.appendChild(spanPwd);
    setStyle(newtd, "padding:0px;border:0px");
    passwordRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(inputPassword);
    setStyle(newtd, "padding:0px;border:0px");
    passwordRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(imgPadlock);
    setStyle(newtd, "padding:0px;border:0px");
    passwordRow.appendChild(newtd);
 
    var templateRow = document.createElement("tr");
 
    var inputTemplate = document.createElement("input");
    inputTemplate.setAttribute("type", "text");
    setStyle(inputTemplate, "margin:1px 0px 1px 3px;font-size:x-small");
    inputTemplate.id = "GC-Vote-Template";
    inputTemplate.value = getAdvertisementTemplate();
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("Template:", "GCVote info string to insert into logs"));
    setStyle(newtd, "padding:0px;border:0px");
    templateRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(inputTemplate);
    setStyle(newtd, "padding:0px;border:0px");
    templateRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(document.createTextNode(" "));
    setStyle(newtd, "padding:0px;border:0px");
    templateRow.appendChild(newtd);
 
    var textBoxesTBody = document.createElement("tbody");
    textBoxesTable.appendChild(textBoxesTBody);
 
    textBoxesTBody.appendChild(passwordRow);
    textBoxesTBody.appendChild(templateRow);
 
    var averageTable = document.createElement("table");
    var averageTableBody = document.createElement("tbody");
    averageTable.appendChild(averageTableBody);
    averageTable.setAttribute("class", "Table WordWrap");
    averageTableBody.id = "GCVoteAverageTable";
    averageTableBody.setAttribute("cellpadding", "0");
    averageTableBody.setAttribute("cellspacing", "0");
    averageTableBody.setAttribute("cellborder", "0");
 
    var voteCountRow = document.createElement("tr");
 
    var inputThreshold = document.createElement("input");
    inputThreshold.setAttribute("type", "text");
    setStyle(inputThreshold, "margin:1px 0px 1px 3px");
    inputThreshold.setAttribute("size", "2");
    inputThreshold.id = "GC-Vote-threshold";
    inputThreshold.value = getThreshold();
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("Minimum vote count:", "display stars only for caches with more than X votes"));
    setStyle(newtd, "padding:0px;border:0px");
    voteCountRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.setAttribute("colspan", "2");
    newtd.appendChild(inputThreshold);
    setStyle(newtd, "padding:0px;border:0px");
    voteCountRow.appendChild(newtd);
 
    var meanRow = document.createElement("tr");
 
    var inputStarsAvg = document.createElement("input");
    inputStarsAvg.setAttribute("type", "radio");
    inputStarsAvg.setAttribute("name", "GC-Vote-Stars");
    inputStarsAvg.id = "GC-Vote-Stars-Average";
    inputStarsAvg.value = "voteAvg";
 
    newtd = document.createElement("td");
    setStyle(newtd, "padding-top:3px;vertical-align:top");
    newtd.setAttribute("rowspan", "2");
    newtd.appendChild(getTooltipSpan("Average calculation:", "how the number of displayed stars should be calculated"));
    setStyle(newtd, "padding:0px;border:0px");
    meanRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(inputStarsAvg);
    setStyle(newtd, "padding:0px;border:0px");
    meanRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    setStyle(newtd, "padding-top:3px");
    newtd.appendChild(getTooltipSpan("Mean", "arithmetic mean of all votes for the cache"));
    setStyle(newtd, "padding:0px;border:0px");
    meanRow.appendChild(newtd);
 
    var medianRow = document.createElement("tr");
 
    var inputStarsMedian = document.createElement("input");
    inputStarsMedian.setAttribute("type", "radio");
    inputStarsMedian.setAttribute("name", "GC-Vote-Stars");
    inputStarsMedian.id = "GC-Vote-Stars-Median";
    inputStarsMedian.value = "voteMedian";
 
//  newtd = document.createElement("td");
//  newtd.appendChild(document.createTextNode(" "));
//  medianRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(inputStarsMedian);
    setStyle(newtd, "padding:0px;border:0px");
    medianRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    setStyle(newtd, "padding-top:3px");
    newtd.appendChild(getTooltipSpan("Median", "median ignores unusual votes"));
    setStyle(newtd, "padding:0px;border:0px");
    medianRow.appendChild(newtd);
 
    var checkTable = document.createElement("table");
    var checkTableBody = document.createElement("tbody");
    checkTable.appendChild(checkTableBody);
    checkTableBody.id = "GCVoteCheckTable";
    checkTable.setAttribute("class", "Table WordWrap");
    checkTableBody.setAttribute("cellpadding", "0");
    checkTableBody.setAttribute("cellspacing", "0");
    checkTableBody.setAttribute("cellborder", "0");
    checkTableBody.setAttribute("style", "padding:0px;margin:0px");
 
    var selectTable = document.createElement("table");
    var selectTableBody = document.createElement("tbody");
    selectTable.appendChild(selectTableBody);
    selectTableBody.id = "GCVoteSelectTable";
    selectTable.setAttribute("class", "Table WordWrap");
    selectTableBody.setAttribute("cellpadding", "0");
    selectTableBody.setAttribute("cellspacing", "0");
    selectTableBody.setAttribute("cellborder", "0");
 
    var languageRow = document.createElement("tr");
 
    var inputLanguage = document.createElement("select");
    inputLanguage.id = "GC-Vote-language";
 
    function addLanguage(control, code, label) {
        var option = document.createElement("option");
        option.setAttribute("value", code);
        option.appendChild(document.createTextNode(tl(label)));
        if (getLanguage() == code) {
            option.setAttribute("selected", "selected");
        }
        control.appendChild(option);
    }
 
    addLanguage(inputLanguage, "en", "English");
    addLanguage(inputLanguage, "de", "German");
    addLanguage(inputLanguage, "fr", "French");
    addLanguage(inputLanguage, "nl", "Dutch");
    addLanguage(inputLanguage, "cs", "Czech");
    addLanguage(inputLanguage, "pt", "Portuguese");
    addLanguage(inputLanguage, "pl", "Polish");
    addLanguage(inputLanguage, "es", "Spanish");
    addLanguage(inputLanguage, "dk", "Danish");
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("Language:", "language for GCVote"));
    setStyle(newtd, "padding:0px;border:0px");
    languageRow.appendChild(newtd);
 
    newtd = document.createElement("td");
//  newtd.setAttribute("colspan", "2");
    newtd.appendChild(inputLanguage);
    setStyle(newtd, "padding:0px;border:0px");
    languageRow.appendChild(newtd);
 
    var starDesignRow = document.createElement("tr");
 
    var inputStarDesign = document.createElement("select");
    inputStarDesign.id = "GC-Vote-StarDesign";
     
    var iconCount = 0;
    var sampleIcon = iconStorage.getStarPreview(iconCount);
    while(sampleIcon != "")
    {
    var option = document.createElement("option");
        option.setAttribute("value", iconCount);
        option.appendChild(document.createTextNode(iconCount));
        if (iconCount == iconStorage.getActiveIconsNumer()) {
            option.setAttribute("selected", "selected");
        }
        inputStarDesign.appendChild(option);
    iconCount++;
    sampleIcon = iconStorage.getStarPreview(iconCount);
    }
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("Star-Design:", "The style of the stars."));
    setStyle(newtd, "padding:0px;border:0px");
    starDesignRow.appendChild(newtd);
     
    newtd = document.createElement("td");
    newtd.appendChild(inputStarDesign);
    setStyle(newtd, "padding:0px;border:0px");
    newtd.innerHTML += "<a id='starDesignReload' title='Reload Icons from Server'>x<a/><br/> <img id='starDesignPreview' src='"+  iconStorage.getStarPreview(iconStorage.getActiveIconsNumer())+"' style='width:61px; height:13px;'/>";
    starDesignRow.appendChild(newtd);  
     
    var loggingRow = document.createElement("tr");
 
    var inputLogging = document.createElement("input");
    inputLogging.setAttribute("type", "checkbox");
//  setStyle(inputLogging,"margin:1px 0px 1px 3px");
//  inputLogging.setAttribute("size","2");
    inputLogging.id = "GC-Vote-logging";
 
    newtd = document.createElement("td");
//  newtd.setAttribute("colspan", "2");
    newtd.appendChild(inputLogging);
    setStyle(newtd, "width:20px;text-align:right;padding:0px;border:0px");
    loggingRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("enable logging", "write debugging information to the error console"));
    setStyle(newtd, "padding:0px;border:0px");
    loggingRow.appendChild(newtd);
 
    var longListRow = document.createElement("tr");
 
    var inputlongList = document.createElement("input");
    inputlongList.setAttribute("type", "checkbox");
    inputlongList.id = "GC-Vote-longList";
 
    newtd = document.createElement("td");
    newtd.appendChild(inputlongList);
    setStyle(newtd, "width:20px;text-align:right;padding:0px;border:0px");
    longListRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("hide on long lists", "Do not display star on pages that may contain many caches. Improves speed on slow computers."));
    setStyle(newtd, "padding:0px;border:0px");
    longListRow.appendChild(newtd);
 
    var halfstarsRow = document.createElement("tr");
 
    var inputHalfstars = document.createElement("input");
    inputHalfstars.setAttribute("type", "checkbox");
    inputHalfstars.id = "GC-Vote-half";
 
    newtd = document.createElement("td");
    newtd.appendChild(inputHalfstars);
    setStyle(newtd, "width:20px;text-align:right;padding:0px;border:0px");
    halfstarsRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("half stars", "enable ratings 1.5, 2.5, 3.5 and 4.5"));
    setStyle(newtd, "padding:0px;border:0px");
    halfstarsRow.appendChild(newtd);
 
    var compactRow = document.createElement("tr");
 
    var inputCompact = document.createElement("input");
    inputCompact.setAttribute("type", "checkbox");
    inputCompact.id = "GC-Vote-compact";
 
    newtd = document.createElement("td");
    newtd.appendChild(inputCompact);
    setStyle(newtd, "width:20px;text-align:right;padding:0px;border:0px");
    compactRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("compact layout", "improve GCVote's layout for small screens"));
    setStyle(newtd, "padding:0px;border:0px");
    compactRow.appendChild(newtd);
 
    var statRow = document.createElement("tr");
 
    var inputStat = document.createElement("input");
    inputStat.setAttribute("type", "checkbox");
    inputStat.id = "GC-Vote-StatType-Bars";
 
    newtd = document.createElement("td");
    newtd.appendChild(inputStat);
    setStyle(newtd, "width:20px;text-align:right;padding:0px;border:0px");
    statRow.appendChild(newtd);
 
    newtd = document.createElement("td");
    newtd.appendChild(getTooltipSpan("bar-graph statistics", "display histogram as fancy bars"));
    setStyle(newtd, "padding:0px;border:0px");
    statRow.appendChild(newtd);
 
 
    var mapTable = document.createElement("table");
    var mapTableBody = document.createElement("tbody");
    mapTable.innerHTML = '<colgroup><col style="width:20px;"/><col/></colgroup>';
    mapTable.appendChild(mapTableBody);
    mapTableBody.id = "GCVoteMapTable";
    mapTable.setAttribute("class", "Table WordWrap");
    mapTableBody.setAttribute("cellpadding", "0");
    mapTableBody.setAttribute("cellspacing", "0");
    mapTableBody.setAttribute("cellborder", "0");
    mapTableBody.setAttribute("style", "padding:0px;margin:0px"); 
     
    var mapTableRow;
    mapTableRow=document.createElement("tr");
    mapTableRow.innerHTML = '<th colspan="2">'+tl('Map options')+'</th>';
    mapTableBody.appendChild(mapTableRow);
     
    var mapOptions = {"enableIcons":["enableTable", "enableTableSort", "enableCacheGeneration", "enableAutomaticCacheGeneration","enableGcPersoFix", "enableSaveVisibility"],
        "enablePopup":[],
        "enableTable":["enableTableSort"],
            "enableTableSort":[],
        "enableLocalCaching":["enableCacheGeneration", "enableAutomaticCacheGeneration"],
        "enableCacheGeneration":["enableAutomaticCacheGeneration"],
        "enableAutomaticCacheGeneration":[],
        "enableGcPersoFix":[],
            "enableSaveVisibility":[]};
         
   var mapOptionsDisplayNames = {"enableIcons":["Enable stars", "Add stars on cache icons."],
        "enablePopup":["Enable stars in popups", "Add stars in the cache popups."],
        "enableTable":["Enable the cache table (with stars)", "Adds a table with all visible caches to the left panel."],
            "enableTableSort":["Enable sorting of the table", "Enables sorting on the cache table."],
        "enableLocalCaching":["Enable caching", "Enables the local caching -> Known information where not downloaded again."],
        "enableCacheGeneration":["Enable cache generation", "Allows the manual generation of caches, using cached informations."],
        "enableAutomaticCacheGeneration":["Enable automatic cache generation", "Enables the automatic generation of caches -> Cached stars appear automatically."],
        "enableGcPersoFix":["Allow pairing with GcPersoFix", "Allows the cooperation with GCPersonalisationFix to hide found/hidden caches. (Geocaching.com Premium Members)"],
            "enableSaveVisibility":["Save the state of the filters", "If enabled filters (number of stars) are saved and will be restored on future sessions."]};
         
    var mapTableCb;   
    var mapTableCbs = new Array();
     
    var checkDependencies = function(element){        
        var mainElment = mapOptions[(element.id).replace("GC-Vote-","")];  
        var currElement;       
        for(var j=0; j<mainElment.length; j++)
        {
            currElement = document.getElementById("GC-Vote-" + mainElment[j]);
            if(currElement){                       
                if(element.checked)
                {
                    currElement.disabled = false;  
                }
                else{
                    currElement.disabled = true;   
                    currElement.checked = false;   
                }
            }
             
        }
    }
     
    for(mapOptionsName in mapOptions){
    mapTableRow=document.createElement("tr");
    mapTableRow.innerHTML = '<td style="width:20px;text-align:right;padding:0px;border:0px">    <input type="checkbox" id="GC-Vote-' + mapOptionsName + '">  </td>  <td style="padding:0px;border:0px"> '+getTooltipSpan(tl(mapOptionsDisplayNames[mapOptionsName][0]),tl(mapOptionsDisplayNames[mapOptionsName][1])).outerHTML+'</td>';
    mapTableCb=mapTableRow.getElementsByTagName("input")[0];       
     
    if(mapOptionsName == "enableGcPersoFix" || mapOptionsName == "enableSaveVisibility" ){
        //Default off
        mapTableCb.checked = (getValue(mapOptionsName , false));
    }
    else{
        mapTableCb.checked = (getValue(mapOptionsName , true));
    }
     
    mapTableCb.addEventListener("click", function() {checkDependencies(this);});
     
    mapTableBody.appendChild(mapTableRow);
    mapTableCbs.push(mapTableCb);
    }
     
    averageTableBody.appendChild(voteCountRow);
    averageTableBody.appendChild(meanRow);
    averageTableBody.appendChild(medianRow);
    selectTableBody.appendChild(languageRow);
    selectTableBody.appendChild(starDesignRow);
    checkTableBody.appendChild(halfstarsRow);
    checkTableBody.appendChild(compactRow);
    checkTableBody.appendChild(longListRow);
    checkTableBody.appendChild(statRow);
    checkTableBody.appendChild(loggingRow);
 
    p2.appendChild(textBoxesTable);
    p2.appendChild(averageTable);
    p2.appendChild(selectTable);
    p2.appendChild(checkTable);
    p2.appendChild(mapTable);
 
    var buttonSave = document.createElement("input");
    buttonSave.setAttribute("type", "button");
    buttonSave.setAttribute("value", tl("save changes"));
    setStyle(buttonSave, "margin-top:5px");
 
    addEvent(buttonSave, "click", saveConfig);
    p2.appendChild(buttonSave);
    div.appendChild(p2);
    sidebar.appendChild(header);
    sidebar.appendChild(div);
    sidebar.appendChild(divDummy);
    if ("voteAvg" == getStarAttributeName()) {
        inputStarsAvg.checked = "checked";
    }
    if ("voteMedian" == getStarAttributeName()) {
        inputStarsMedian.checked = "checked";
    }
    if (HALFSTARS) {
        inputHalfstars.setAttribute("checked", "checked");
    }
    if (getDisableOnLongLists()) {
        inputlongList.setAttribute("checked", "checked");
    }
    if (getCompact()) {
        inputCompact.setAttribute("checked", "checked");
    }
    if (getStatType() == 'bars') {
        inputStat.setAttribute("checked", "checked");
    }
    if (LOGGING) {
        inputLogging.setAttribute("checked", "checked");
    }
     
    for(var j=0;j<mapTableCbs.length;j++){
         checkDependencies(mapTableCbs[j]);
     }
      
      document.getElementById("GC-Vote-StarDesign").onchange = function(){
        document.getElementById("starDesignPreview").src = iconStorage.getStarPreview(document.getElementById("GC-Vote-StarDesign").selectedIndex);
    }
     
    document.getElementById("starDesignReload").onclick = function(){
        if (confirm(tl("This will delete all local icon data.\n\nDo you want to continue?"))) {
        setValue("iconStoreActiveIcon", 0);
        setValue("iconStoreIcons", "[ ]");
        document.getElementById('GC-Vote-StarDesign').innerHTML = '<option value="0" selected="selected">0</option>';
        document.getElementById("starDesignPreview").src = iconStorage.getStarPreview(0);
        iconStorage = new iconStore();
        alert(tl("Local icons have been deleted on user request. \nThey will be reoladed from Server."));
        }
    }
      
    log("insertGCVoteMenu done");
}
 
function listVotes() {
// faking a POST-form to hide password while redirecting
    var myForm = document.createElement("form");
    setStyle(myForm, "display:none");
    myForm.method = "GET";
    myForm.action = LISTVOTES;
    i1 = document.createElement("input");
    i1.setAttribute("name", "userName");
    i1.setAttribute("value", unescapedUserName);
    myForm.appendChild(i1);
    i2 = document.createElement("input");
    i2.setAttribute("name", "password");
    i2.setAttribute("value", getPassword());
    myForm.appendChild(i2);
    document.body.appendChild(myForm);
    myForm.submit();
    document.body.removeChild(myForm);
}
 
function changePassword() {
// faking a POST-form to hide password while redirecting
    var myForm = document.createElement("form");
    setStyle(myForm, "display:none");
    myForm.method = "POST";
    myForm.action = CHANGEPASSWORD;
    i1 = document.createElement("input");
    i1.setAttribute("name", "userName");
    i1.setAttribute("value", unescapedUserName);
    myForm.appendChild(i1);
    i2 = document.createElement("input");
    i2.setAttribute("name", "oldPassword");
    i2.setAttribute("value", getPassword());
    myForm.appendChild(i2);
    document.body.appendChild(myForm);
    myForm.submit();
    document.body.removeChild(myForm);
}
 
 
function deleteCaches() {
    if (confirm(tl("This will delete all local cached data.\n\nDo you want to continue?"))) {
        setValue("cachedVoteData", "{ }"); 
    setValue("cachedCacheData", "{ }");
    alert(tl("Local caches had been deleted on user request. \nReload all map pages without using them!"));
    }
}
 
// IE-Mod (by qByter): Added funtion to provide alternative to addEventListener for Internet Explorer
function addEvent(obj, type, fn) {
    if (obj.addEventListener)
        {
            obj.addEventListener(type, fn, false);
        }
    else {
        if (obj.attachEvent) {
            obj.attachEvent('on' + type, function () {
                return fn.apply(obj, new Array(window.event));
            });
        }
    }
}
 
function getXmlDoc(xmlString) {
    if (typeof(window.DOMParser) == 'undefined') {
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlString);
    }
    else {
        var parser = new window.DOMParser();
        xmlDoc = parser.parseFromString(xmlString, "text/xml");
    }
    return xmlDoc;
}
 
function setStyle(obj, style) {
//  obj.setAttribute("style",style);
    obj.style.cssText = style;
}
 
function translateVoteCount(count) {
    if (getCompactCurrentPage()) {
        return count;
    }
    if (getLanguage() == "de") {
        return count + " Stimme" + (count == 1 ? "" : "n");
    }
    if (getLanguage() == "pt") {
        return count + " voto" + (count == 1 ? "" : "s");
    }
    if (getLanguage() == "fr") {
        return count + " cote" + (count > 1 ? "s" : "");
    }
    if (getLanguage() == "cs") {
        return count + " " + (count == 0 ? "hlasů" : (count == 1 ? "hlas" : "hlasy"));
    }
    if (getLanguage() == "pl") {
        return count + " " + (count == 0 ? "głosów" : (count == 1 ? "głos" : "głosy"));
    }
    if (getLanguage() == "nl") {
        return count + " " + (count == 0 ? "stemmen" : (count == 1 ? "stem" : "stemmen"));
    }
    if (getLanguage() == "es") {
        return count + " voto" + (count == 1 ? "" : "s");
    }
    if (getLanguage() == "dk") {
        return count + " vurdering" + (count == 1 ? "" : "er");
    }
    return count + " vote" + (count == 1 ? "" : "s");
}
 
function tl(str) {
    var index = -1;
    switch (getLanguage()) {
        case "de":
            index = 0;
            break;
        case "fr":
            index = 1;
            break;
        case "pt":
            index = 2;
            break;
        case "cs":
            index = 3;
            break;
        case "pl":
            index = 4;
            break;
        case "nl":
            index = 5;
            break;
        case "es":
            index = 6;
            break;
        case "dk":
            index = 7;
            break;
    }
    if (index < 0) {
        return str;
    }
    var p = -1;
    if (translations.indexOf) {
        p = translations.indexOf(str);
    }
    else {
        for (var i = 0; i < translations.length; i += 2) {
            if (translations[i] == str) {
                p = i;
                break;
            }
        }
    }
    if (p < 0) {
        log("missing translation for '" + str + "'.");
        return str;
    }
    var trans = translations[p + 1];
    if(trans[index])
        {
            return trans[index];
        }
    else {
        return str;
    }
}
 
//Iconstore by Skywalker90
var iconStore = function(){
    var icons;
    var activeIcons = 0;
     
    var init = function(){ 
        activeIcons = getValue("iconStoreActiveIcon", 0);
        icons=JSON.parse(getValue("iconStoreIcons", "[ ]"));
        if(! icons[activeIcons] || ! icons[activeIcons]["stars"]){
            activeIcons = 0;
            icons[activeIcons] =  {"stars":{}};
            for(i=0;  i<= 5; i += 0.5){
                icons[activeIcons]["stars"][ i.toString().replace('.', '_')]='https://www.geocaching.com/images/stars/stars' + i.toString().replace('.', '_') + '.gif';
            }
             
            xmlhttpRequest({
                method:'GET',
                url:iconSetUrl,
                onload:function (responseDetails) {
                    log("received iconData");
                    icons = JSON.parse(responseDetails.responseText);  
                    setValue("iconStoreIcons", JSON.stringify(icons));
                     
                    var inputStarDesign = document.getElementById("GC-Vote-StarDesign");
                    if(inputStarDesign){
                        inputStarDesign.innerHTML = "";
                        var iconCount = 0;
                        var sampleIcon = iconStorage.getStarPreview(iconCount);
                        while(sampleIcon != "")
                        {
                        var option = document.createElement("option");
                        option.setAttribute("value", iconCount);
                        option.appendChild(document.createTextNode(iconCount));
                        if (iconCount == iconStorage.getActiveIconsNumer()) {
                            option.setAttribute("selected", "selected");
                        }
                        inputStarDesign.appendChild(option);
                        iconCount++;
                        sampleIcon = iconStorage.getStarPreview(iconCount);
                        }
                }
                }
            });
             
            log("icon loaded.");
        }
    }
     
    this.changeIcons =  function(iconPackNumber){
        if(iconPackNumber < icons.length){
            activeIcons = iconPackNumber;
        }      
    }
         
    this.getStar =  function(starName){
        return icons[activeIcons]["stars"][starName];
    }
     
    this.getActiveIconsNumer = function(){
        return activeIcons;
    }
     
    this.getStarPreview = function(iconPackNr){
        if(! icons[iconPackNr] || ! icons[iconPackNr]["stars"] || !icons[iconPackNr]["stars"]["2_5"]){
            return "";
        }
        else{
            return icons[iconPackNr]["stars"]["2_5"];
        }
    }
     
    //Constructor iconStore
    init();
}
 
//NEW MAP CODE by Skywalker90
var newMapHandler = function (options) {
    //Temporary enables/disables GCVote on the new map
    var gcVoteNewMapGlobalOn = true;
    //Temporary enables/disables only GCVote icons on the new map and it's cache table
    var gcVoteNewMapIconsOn = true;
     
     
    var mapIconControl;
    var mapPopupControl;
    var mapTableControl;
    var mapPositionControl;
    var mapCacheGeneratorControl;
    var localCacheControl;
     
    var GcPersoFixControl;
 
    var cacheExtractor;   
     
    var cacheData;
    var cacheDataSession = new Object();
    var voteData;
     
    var localVoteLifeTime = 48; //Lifetime of a vote information in the local cache in hours
    var localCacheLifeTime = 720; //Lifetime of a vote information in the local cache in hours
    var garbageCollectionFrequency = 168; //Frequency of the garbageCollection for the locally cached informations in hours
     
    //The GCVote icon with the settings on the map
    var gcVoteLayersControl;  
    if(!myWindow){
        var myWindow = window;
        if(typeof unsafeWindow != "undefined"){
            myWindow = unsafeWindow;
        }
    }
     
    var browserType = "unknown";
    if(typeof(opera) != "undefined") {
        browserType = "Opera";     
    }
    else if(typeof(chrome) != "undefined"){
        browserType = "Chrome";
    }
    else if(typeof(safari) != "undefined"){
        browserType = "Safari";
    }
    else{
        browserType = "FireFox";   
    }
     
    
    var L = myWindow.L;
    var map;
     
    //Init default options
    var option ={
        enableIcons: true,
        enablePopup: true,
        enableTable: true, //Requires enableIcons
        enableTableSort: true, //Requires enableTable
        enableLocalCaching: true,
        enableCacheGeneration: true, //Requires enableLocalCaching AND enableIcons should be true
        enableAutomaticCacheGeneration: true, //Requires enableCacheGeneration
        enableGcPersoFix: false,
        enableSaveVisibility: false
    };
     
    var init = function () {
        //Check if googleMap is activated
        if(typeof L != "object" && document.getElementsByClassName("leaflet-container").length == 0 && typeof google == "object" &&  typeof google.maps == "object"){
            log("GoogleMaps detected... Abort!");
            setTimeout(function () {
                if(! getValue("gcVoteWasGoogleAlertShown", false))
                {
                    if(myWindow.$ && myWindow.$.fancybox){
                        myWindow.$.fancybox({
                            width: 780,
                            height: 362,
                            autoScale: false,
                            padding: 0,
                            margin: 0,
                            href: "http://img196.imageshack.us/img196/8825/gcmapleaflet.png",
                            scrolling: 'no',
                            title:tl("GCVote only supports the Leaflet-Map (you are using the Google-Map)"),
                            type: "image"
                        });
                     
                        setValue("gcVoteWasGoogleAlertShown", true);
                    }
                }
            },750);        
        }
        else
        {      
            //Set options
            if(options){
                for(optionName in options)
                {
                    option[optionName] = options[optionName];
                }
                 
                //Check requirements
                if(option.enableTable){
                    option.enableIcons = true;
                }  
                if(option.enableTableSort){
                    option.enableTable = true;
                    option.enableIcons = true;
                }
                if(option.enableAutomaticCacheGeneration)
                {
                    option.enableCacheGeneration = true;
                }
                if(option.enableCacheGeneration && !option.enableIcons){
                    option.enableCacheGeneration = false;
                    option.enableAutomaticCacheGeneration = false;
                }
                if(option.enableCacheGeneration){
                    option.enableLocalCaching = true;
                }
                if(option.enableGcPersoFix){
                    option.enableIcons = true;
                }
                if(option.enableSaveVisibility){
                    option.enableIcons = true;
                }
                 
                gcVoteNewMapIconsOn = option.enableIcons;
                 
            }
             
            if(option.enableLocalCaching){
                localCacheControl = new localCacheHandler();
            }
            else{
                voteData=new Object();     
                cacheData=new Object();
            }
             
            initNewMap();
        }
    }
 
    var initNewMap = function () { 
        //Is the map loaded?
        if (! myWindow.MapSettings || !myWindow.MapSettings.Map || !myWindow.L || !myWindow.MapSettings.Map._loaded ) {
            //Workaround to get informed when the map is loaded: raise an event every time something on the map canvas changes
            setTimeout(waitForMap,5);
        }
        else {
            map = myWindow.MapSettings.Map;
             
            mapPositionControl = new mapPositionHandler();
             
            if(option.enablePopup){
                mapPopupControl = new mapPopupHandler();   
            }              
            if(option.enableIcons){
                mapIconControl = new mapIconLoader();
                 
                map.addEventListener("layeradd", function(e){                      
                        if(myWindow.MapSettings.MapLayers.Geocache && e.layer._leaflet_id == myWindow.MapSettings.MapLayers.Geocache._leaflet_id){
                            reInit();
                        }
                        else if(mapTableControl){
                            mapTableControl.updateTable();
                             
                            if (browserType == "FireFox") {
                                //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation        
                                setTimeout(function () {
                                    mapIconControl.saveLayerVisibility();
                                }, 0);             
                            }
                            else {
                                mapIconControl.saveLayerVisibility();
                            }  
                        }
                    });
                     
                    map.addEventListener("layerremove", function(e){
                        if(mapTableControl){
                            mapTableControl.updateTable();
                             
                            if (browserType == "FireFox") {
                                //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation        
                                setTimeout(function () {
                                    mapIconControl.saveLayerVisibility();
                                }, 0);             
                            }
                            else {
                                mapIconControl.saveLayerVisibility();
                            }  
                        }
                    });
                 
            }
            if(option.enableTable){
                mapTableControl = new mapTable(mapIconControl, mapPositionControl, option.enableTableSort);
            }
            if(option.enableCacheGeneration){
                mapCacheGeneratorControl = new mapCacheGenerator(mapPositionControl);  
                 
                if(option.enableAutomaticCacheGeneration){
                    setTimeout(mapCacheGeneratorControl.generateCaches,10);
                }
            }
             
            initGCVoteMapContol();
             
            if(option.enableGcPersoFix){
                GcPersoFixControl = new gcPersonalisationFixConnector(map, option, mapCacheGeneratorControl, mapIconControl);              
            }
             
            log("GCVote newMap code loaded");          
        }
    }
 
    //Handles the DOMAttrModified event of the mapCanvas (wait for map to load)
    var waitForMap = function (e) {
        if (myWindow.MapSettings.Map && myWindow.L && myWindow.MapSettings.Map._loaded) {
            //retry - init map
            initNewMap();
        }
        else{
          setTimeout(waitForMap,5);
        }
    }
 
    var initGCVoteMapContol = function() {
        if (gcVoteLayersControl == null) {
            var ConLayer = L.Control.Layers.extend({
            sort:function () {
                var nodes = this._overlaysList.childNodes;
                var sortedArray = new Array();
 
                var nodeRanks = new Array();
                var nodeText = "";
 
                for (var i = 0; i < nodes.length; i++) {
 
                if (nodes[i].childNodes[1].nodeName == "SPAN") {
                    nodeText = nodes[i].childNodes[1].textContent.trim();
                }
                else {
                    nodeText = nodes[i].childNodes[1].title;
                }
                nodeRanks.push(nodeText + "#" + i);
                }
 
                nodeRanks = nodeRanks.sort();
 
                for (i = 0; i < nodeRanks.length; i++) {
                nodeText = nodeRanks[i].split('#');
                sortedArray.push(nodes[nodeText[1]]);
                }
 
                this._overlaysList.innerHTML = "";
 
                for (i = 0; i < sortedArray.length; i++) {
                this._overlaysList.appendChild(sortedArray[i]);
                }
 
            },
            iconize:function () {
                var nodes = this._overlaysList.childNodes;
                var img;
                 
                for (var i = 0; i < nodes.length; i++) {
                var nodeText = "";             
 
                if (nodes[i].childNodes[1].nodeName == "SPAN") {
                    nodeText = nodes[i].childNodes[1].textContent.trim();
                    img = document.createElement("img");
                    img.title = nodeText;
                    img.alt = "Vote: " + nodeText;     
                    img.src = iconStorage.getStar(nodeText.replace('.', '_'));
                    nodes[i].replaceChild(img, nodes[i].childNodes[1]);
                }
 
                }
            },
            addControls:function(){
                //Add GCVote icon
                this._layersLink.style.backgroundImage = 'url("' + gcVoteImg + '")';
                 
                this._controlList = document.createElement('div');
                this._controlList.className = 'leaflet-control-layers-base';
                this._form.insertBefore(this._controlList,this._overlaysList);             
                 
                this._controlSeparator = document.createElement('div');
                this._controlSeparator.className = 'leaflet-control-layers-separator';
                this._form.insertBefore(this._controlSeparator,this._overlaysList);            
                 
                var toggleGlobalElement, toggleIconTableElement, buttonTableElement;
                 
                 
                //Global-Toggle
                toggleGlobalElement = document.createElement('label');
                toggleGlobalElement.style.fontWeight = "bold"; 
                toggleGlobalElement.style.fontSize = "135%";   
                toggleGlobalElement.style.verticalAlign = "middle";                
                     
                var name = document.createTextNode("Global ");
                var control = document.createElement("img");
                control.src = imgToggleOn;
                control.alt = "on";
                control.style.verticalAlign = "middle";            
                control.title = tl("Temporary enables/disables GCVote on the map");
                control.onclick = function(){
                    if(control.alt == "on"){
                        control.alt = "off";
                        gcVoteNewMapGlobalOn = false;
                        if(mapIconControl){
                            mapIconControl.setTempIconVisibility(false);
                        }
                         
                        if(mapTableControl){
                            mapTableControl.setTempIconVisibility(false);                          
                        }
                         
                        if(toggleIconTableElement){
                            toggleIconTableElement.style.display = 'none';
                        }
                         
                        //Also deactivate manual cache generation button
                        if(buttonTableElement)
                        {
                            buttonTableElement.style.display = 'none';
                        }
                         
                        control.src = imgToggleOff;
                    }
                    else{
                        control.alt = "on";
                        gcVoteNewMapGlobalOn = true;
                         
                        if(mapIconControl){
                            mapIconControl.setTempIconVisibility(true);
                        }
                         
                        if(mapTableControl){       
                            mapTableControl.setTempIconVisibility(true);
                        }
                         
                        if(toggleIconTableElement){
                            //Also activate the Stars/Table toggle
                            gcVoteNewMapIconsOn = true;    
                            toggleIconTableElement.style.display = '';                             
                            toggleIconTableElement.children[0].src = imgToggleOn;
                            toggleIconTableElement.children[0].alt = "on";
                        }
                         
                        //Also activate manual cache generation button
                        if(buttonTableElement)
                        {
                            buttonTableElement.style.display = '';
                        }
                         
                        control.src = imgToggleOn;
                         
                    }
                    gcVoteLayersControl.sort();
                    gcVoteLayersControl.iconize();
                }
                 
                toggleGlobalElement.appendChild(name);
                toggleGlobalElement.appendChild(control);                  
                this._controlList.appendChild(toggleGlobalElement);
                 
                if(option.enableIcons){
                    //Stars/Table-Toggle
                    toggleIconTableElement = document.createElement('label');          
                    toggleIconTableElement.style.fontWeight = "bold";  
                    toggleIconTableElement.style.fontSize = "135%";
                    toggleIconTableElement.style.verticalAlign = "middle";     
                     
                    var name2 = document.createTextNode("Stars/Table ");
                    var control2 = document.createElement("img");
                    control2.src = imgToggleOn;
                    control2.alt = "on";
                    control2.style.verticalAlign = "middle";
                    control2.style.textAlign = "right";
                    control2.title = tl("Temporary enables/disables only GCVote stars on the map and it's cache table");
                    control2.onclick = function(){
                        if(control2.alt == "on"){
                            control2.alt = "off";
                            gcVoteNewMapIconsOn = false;
                             
                            if(mapIconControl){
                                mapIconControl.setTempIconVisibility(false);
                            }
                             
                            if(mapTableControl){
                                mapTableControl.setTempIconVisibility(false);
                            }
                             
                            //Also deactivate manual cache generation button
                            if(buttonTableElement)
                            {
                                buttonTableElement.style.display = 'none';
                            }
                             
                            control2.src = imgToggleOff;
                        }
                        else{
                            control2.alt = "on";
                            gcVoteNewMapIconsOn = true;
                             
                            if(mapIconControl){
                                mapIconControl.setTempIconVisibility(true);
                            }
                            if(mapTableControl){
                                mapTableControl.setTempIconVisibility(true);
                            }
                             
                            //Also activate manual cache generation button
                            if(buttonTableElement)
                            {
                                buttonTableElement.style.display = '';
                            }
                             
                            control2.src = imgToggleOn;
                        }
                        gcVoteLayersControl.sort();
                        gcVoteLayersControl.iconize();
                    }
                     
                    toggleIconTableElement.appendChild(name2);
                    toggleIconTableElement.appendChild(control2);                  
                    this._controlList.appendChild(toggleIconTableElement);
                }
                 
                //Manual cache generation button
                if(option.enableCacheGeneration && !option.enableAutomaticCacheGeneration){
                    buttonTableElement = document.createElement('label');
                    buttonTableElement.style.verticalAlign = "middle";     
                     
                    var btnGenerate = document.createElement("input");
                    btnGenerate.setAttribute("type", "button");
                    btnGenerate.setAttribute("value", tl("Generate Caches"));
                    btnGenerate.addEventListener("click", mapCacheGeneratorControl.generateCaches);
                    btnGenerate.id = "btn_Generate";
                     
                    buttonTableElement.appendChild(btnGenerate);                   
                    this._controlList.appendChild(buttonTableElement);
                }
                 
                this._controlSeparator.style.display = '';
            }          
            });
 
            gcVoteLayersControl = new ConLayer();
            map.addControl(gcVoteLayersControl);
            gcVoteLayersControl.addControls();
        }
    }
     
    var getVotes = function(waypoints) {
        var waypointsForRequest = new Array(); 
        var now = new Date(Date.now());
         
        if(typeof waypoints != "object"){
            waypoints= [waypoints];
        }
         
        //Loop throw all waypoints
        for(var j=0;j<waypoints.length;j++)
        {
            //Are cached vote informations for this cache available?
            if(voteData[waypoints[j]] && voteData[waypoints[j]].vote != -1)
            {
                //Informations available -> use local voteCache
                voteEntry=voteData[waypoints[j]];
                voteEntryDate = new Date(voteEntry.date);
                 
                //Are these informations valid or expired?
                if((now.getTime() - voteEntryDate.getTime())/3600000 <= localVoteLifeTime)
                {
                    //Valid -> Use cached informations      
                    handleVoteData(waypoints[j]);                  
                }
                else
                {
                    //Expired -> Reserve this cache for online request
                    waypointsForRequest.push(waypoints[j]);                
                }          
            }
            else
            {
                //No infos -> Reserve this cache for online request
                waypointsForRequest.push(waypoints[j]);            
            }
        }      
 
        log("Used cache vote informations for: "+ (waypoints.length-waypointsForRequest.length) +" caches. Online request for "+waypointsForRequest.length+" caches started.");
         
         
        if(waypointsForRequest.length > 0)
        {
            //Do online request
            requestVotesForWaypoints(waypointsForRequest);
        }  
     
    }
     
    this.newVoteData = function(waypoint, voteStars, voteCnt, cacheId, voteAvg, totalVoteCount,voteUser,votes, rawVotes){
        if(gcVoteNewMapGlobalOn)
        {
            //Display only caches with more than threshold votes
            if(voteCnt >= getThreshold()){
                //Update cached informations
                updateVoteDataWithNewVoteData(waypoint, voteStars, voteCnt, cacheId, voteAvg, totalVoteCount,voteUser,votes, rawVotes);
                 
                //Use the voteData
                handleVoteData(waypoint);
            }
        }      
    }
     
    var handleVoteData = function(waypoint) {      
        if (!cacheDataSession[waypoint]) {
            cacheDataSession[waypoint] = new Object();             
        }
         
        if(mapPopupControl){
            //Fill in vote informations for popup      
            mapPopupControl.populatePopupStars(waypoint);
        }
         
        if(gcVoteNewMapIconsOn)
        {
            //Notify mapIconControl
            mapIconControl.newCacheVoteData(waypoint);
        }
    }
     
    var updateVoteDataWithNewVoteData= function(waypoint, voteStars, voteCnt, cacheId, voteAvg, totalVoteCount,voteUser,votes, rawVotes) {
        voteData[waypoint]={
            "vote": parseFloat(voteStars),
            "voteCnt": parseInt(voteCnt),
            "cacheId": cacheId,
            "voteAvg": parseFloat(voteAvg),
            "totalVoteCount": parseInt(totalVoteCount),
            "votes": votes,
            "rawVotes": rawVotes,
            "date": (new Date(Date.now())).toString() };       
         
        if(localCacheControl){
            localCacheControl.saveLocalCachesDelayed("voteData");
        }
    }   
     
    var removeCache=function(wpId, retryCount){
        if(mapIconControl){
            if(cacheDataSession[wpId] && cacheDataSession[wpId]["marker"]){
                mapIconControl.removeIcon(wpId);           
                if(mapTableControl){
                    if(cacheDataSession[wpId]["tableRow"]){
                        mapTableControl.updateTable();
                    }
                    else if(retryCount<5){
                        setTimeout(function(){ removeCache(wpId, retryCount+1);}, 50);
                    }
                }
            }
            else if(retryCount<5){
                setTimeout(function(){ removeCache(wpId, retryCount+1);}, 50);
            }
        }
         
    }
     
    var reInit = function(){
		var layerState = {};
		for(layerKey in gcVoteLayersControl._layers){
			var name = gcVoteLayersControl._layers[layerKey].name;
			if(mapIconControl.isSuffixLayerVisible(name.replace(".","_"))){
				layerState[name] = true;
			}	
		}
		
        mapIconControl.removeAllIcons();
        cacheDataSession = new Object();
        if(mapTableControl){
            mapTableControl.removeAllCachesFromTable();
        }
        //Generate new caches
        if(option.enableAutomaticCacheGeneration && option.enableCacheGeneration){         
            setTimeout(function(){
				mapCacheGeneratorControl.generateCaches();
							
				for(layerKey in gcVoteLayersControl._layers){
					if(layerState[gcVoteLayersControl._layers[layerKey].name]){
						var data = gcVoteLayersControl._layers[layerKey];
						gcVoteLayersControl._map.addLayer(data.layer, !data.overlay);
					}                                        
				}
				
				gcVoteLayersControl.sort();
				gcVoteLayersControl.iconize();
			},10);        
        }
    }
    //Classes
    var mapPopupHandler = function(){  
        var init = function () {
            myWindow.$.views.registerHelpers({
                getStarsSrcForPopup:function (wpId) {
                    if(!gcVoteNewMapGlobalOn){
                    log("Insert errorImg for " + wpId + " because GCVote istempoary disabled on user request.");
                    return errorImg;
                    }              
                    setTimeout(function () {                      
                        getVotes(wpId);
                        setTimeout(function () { checkTimeoutLoaderImg(wpId); }, 5000);
                    }, 3);
                    log("Insert placeholder for " + wpId + " in its popup.");
                    return loaderImg;                
                }
            });
 
            var tmpl = document.getElementById("cacheDetailsTemplate");
            var textContent = tmpl.textContent;       
            textContent = textContent.replace('<dt>Favorite Points:</dt> ', '<dt>GCVote/FP:</dt> ');
            textContent = textContent.replace('<dd><img src="/images/icons/16/favorites.png" />', '<dd> <img title="Loading..." id="gcVotePopupStars_{{=gc}}" src="{{=$ctx.getStarsSrcForPopup( gc ) }}" /> / <img src="/images/icons/16/favorites.png" />');
            tmpl.textContent = textContent;
        }
 
        this.populatePopupStars = function (wpId) {
            var imgStarElement = document.getElementById("gcVotePopupStars_" + wpId);
            if (imgStarElement != null) {
            log("Insert stars for " + wpId + " in its popup using the online informations.");
            imgStarElement.src =  iconStorage.getStar(avg2suffix(voteData[wpId].vote, voteData[wpId].voteCnt));
            imgStarElement.title = "";
            }          
        }
 
        var checkTimeoutLoaderImg = function (wpId) {
            var imgStarElement = document.getElementById("gcVotePopupStars_" + wpId);
 
            if (imgStarElement != null && imgStarElement.title.indexOf("Loading...") != -1) {          
                log("No online result arrived - Insert error image.");
                imgStarElement.src = errorImg;
            }
        }
 
        //Constructor
        init();
    }
 
    var mapCacheExtractor = function () {
        var subscribers = new Array();
        var lastIdString = "";
        var onMoveHelper = {};
 
        var tile2LatLng = function (x, y, z) {
            var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
            return {"lat":(180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))), "lng":(x / Math.pow(2, z) * 360 - 180)};
        }
 
        var tileOff2LatLng = function (tileX, tileY, offsetX, offsetY, zoom) {
            return tile2LatLng(tileX + (offsetX * 4 / 256), tileY + (offsetY * 4 / 256), zoom);
        }
 
        //~ var injectCacheInfoListener = function () {
           //~ if(browserType == "Chrome"){              
                //~ //var port = chrome.runtime.connect();
                 
                //~ window.addEventListener("message", function(event) {
                     //~ if (event.source != window){
                        //~ return;
                     //~ }
                      
                    //~ if (event.data.type && (event.data.type == "FROM_PAGE_GCVote")) {
                      //~ var data = JSON.parse(event.data.text);
                      //~ cacheInfoListener(data.data,  {"x":data.x, "y":data.y, "z":data.z});
                    //~ }
                //~ }, false);
                
               //~ injectPageScriptFunction(injectCacheInfoListenerHelperChrome,"()");
                //~ }
                
           //~ else{
               //~ injectCacheInfoListenerHelper();
           //~ }
        //~ }
         
        var injectCacheInfoListener2 = function () {
            if(browserType == "Chrome" || browserType == "FireFox"){    
                //Helperfunctions to inject functions into site context
                function injectPageScript(scriptContent){
                    var script = document.createElement("script");
                    script.setAttribute("type", "text/javascript");
                    script.innerHTML = scriptContent;
                    var pageHead = document.getElementsByTagName("head")[0];
                    pageHead.appendChild(script);
                }
 
                function injectPageScriptFunction(funct, functCall){
                    injectPageScript("("+funct.toString()+")"+functCall+";");   
                }
                 
                window.addEventListener("message", function(event) {
                     if (event.source != window){
                        return;
                     }
                      
                    if (event.data.type && (event.data.type == "FROM_PAGE_GCVote")) {
                      var data = JSON.parse(event.data.text);
                      cacheInfoListener(data.data,  {"x":data.x, "y":data.y, "z":data.z});
                    }
                }, false);
                 
                injectPageScriptFunction(injectCacheInfoListener2Chrome,"()");
            }
            else           
            {
                myWindow.MapSettings.Map.on('mousemove', function(e) {
                    var point = myWindow.MapSettings.Map.project(e.latlng);
                    var z = myWindow.MapSettings.Map.getZoom();               
                    var max = myWindow.MapSettings.Map.options.crs.scale(z) / myWindow.MapSettings.MapLayers.Geocache.options.tileSize;
                    var x = (Math.floor(point.x / myWindow.MapSettings.MapLayers.Geocache.options.tileSize) + max) % max;
                    var y = (Math.floor(point.y / myWindow.MapSettings.MapLayers.Geocache.options.tileSize) + max) % max;
                    var key = z + "_" + x + "_" + y;
                     
                    if(onMoveHelper[key]){
                        return;
                    }
                     
                    var data = myWindow.MapSettings.MapLayers.UTFGrid._cache[key];
                     
                    if(typeof data == "object"){
                        cacheInfoListener(data,  {"x":x, "y":y, "z":z});
                        onMoveHelper[key] = true;
                    }
                });
            }
        }
         
        var injectCacheInfoListener2Chrome = function () {
            window["onMoveHelper"] = {};
            window.MapSettings.Map.on('mousemove', function(e) {
                var point = window.MapSettings.Map.project(e.latlng);
                var z = window.MapSettings.Map.getZoom();               
                var max = window.MapSettings.Map.options.crs.scale(z) / window.MapSettings.MapLayers.Geocache.options.tileSize;
                var x = (Math.floor(point.x / window.MapSettings.MapLayers.Geocache.options.tileSize) + max) % max;
                var y = (Math.floor(point.y / window.MapSettings.MapLayers.Geocache.options.tileSize) + max) % max;
                var key = z + "_" + x + "_" + y;
                 
                if(window["onMoveHelper"][key]){
                    return;
                }
                 
                var data = window.MapSettings.MapLayers.UTFGrid._cache[key];
                 
                if(typeof data == "object"){
                    window.postMessage({ type: "FROM_PAGE_GCVote", text: JSON.stringify({"data":data, "x":x, "y":y, "z":z}) }, "*");
                    window["onMoveHelper"][key] = true;
                }
            });
        }
         
        //~ var injectCacheInfoListenerHelper = function () {
             
            //~ L.UtfGrid.prototype._loadTileP = function(z, x, y) {              
                //~ var head = window.$("head")[0];
                //~ var key = z + "_" + x + "_" + y;
                //~ var _this = this;
                //~ var url = L.Util.template(this._url, L.Util.extend({s: L.TileLayer.prototype._getSubdomain.call(this, {x: x,y: y}),z: z,x: x,y: y,cb: this._windowKey + "." + "lu_" + key}, this.options));
                //~ var script = document.createElement("script");
                //~ script.setAttribute("type", "text/javascript");
                //~ script.setAttribute("src", url+"#"+Math.random().toString(36).substring(7));
                //~ /*if(!window["gcvoteDataHelper"][key]){
                    //~ window.$('script[src*="'+url+'"]').remove();
                    //~ delete window[this._windowKey]["lu_" + key];
                //~ }
                //~ window["gcvoteDataHelper"][key] = true;*/
                //~ window[this._windowKey]["lu_" + key] = function(data) {                   
                    //~ _this._cache[key] = data;                 
                    //~ setTimeout(function(){
                        //~ cacheInfoListener(data,  {"x":x, "y":y, "z":z});
                        //~ //window["gcvoteDataHelper"][key] = false;
                    //~ },1);                    
                    
                    //~ delete window[this._windowKey]["lu_" + key];                     
                    //~ head.removeChild(script);                  
                //~ };             
                 
                //~ head.appendChild(script);
            //~ }
             
            //~ //window["gcvoteDataHelper"] = {};
            //~ window.$('script[src^="map.info"]').remove();
            //~ window.MapSettings.MapLayers.ResetGeocacheLayer();
        //~ }
         
          //~ var injectCacheInfoListenerHelperChrome = function () {           
               
            //~ L.UtfGrid.prototype._loadTileP = function(zoom, x, y) {
                //~ //alert(zoom +" "+ x+ " "+ y);
                //~ var head = window.$("head")[0];
                //~ var key = z + "_" + x + "_" + y;
                //~ var _this = this;
                //~ var url = L.Util.template(this._url, L.Util.extend({s: L.TileLayer.prototype._getSubdomain.call(this, {x: x,y: y}),z: z,x: x,y: y,cb: this._windowKey + "." + "lu_" + key}, this.options));
                //~ var script = document.createElement("script");
                //~ script.setAttribute("type", "text/javascript");
                //~ script.setAttribute("src", url);
                //~ /*if(!window["gcvoteDataHelper"][key]){
                    //~ window.$('script[src*="'+url+'"]').remove();
                    //~ delete window[wk][functionName];
                //~ }
                //~ window["gcvoteDataHelper"][key] = true;*/
                //~ window[wk][functionName] = function(data) {                   
                    //~ self._cache[key] = data;
                    //~ window.postMessage({ type: "FROM_PAGE_GCVote", text: JSON.stringify({"data":data, "x":x, "y":y, "z":zoom}) }, "*");                       
                    //~ //window["gcvoteDataHelper"][key] = false;
                     
                    //~ delete window[wk][functionName];
                    //~ head.removeChild(script);
                //~ };             
                 
                //~ head.appendChild(script);
            //~ }
             
            //~ //window["gcvoteDataHelper"] = {};
            //~ window.$('script[src^="map.info"]').remove();
            //~ window.MapSettings.MapLayers.ResetGeocacheLayer();
        //~ }
         
        var cacheInfoListener = function (resultData, coord) {
            if (resultData == null || !gcVoteNewMapGlobalOn) {
            return;
            }
 
            var data = resultData.data;
            var workArray = new Object();
            var workId;
            var workXY;
            var workDataSet;
            var i;
            var result = new Array();
            var idString = "";
            //var tileCoords = url.match(/[0-9]+(?=(&[a-z]=|$))/g);
            var changed = false;
 
            if (coord.z < 12) {
                return;
            }
 
            for (dataSetName in data) {
            workDataSet = data[dataSetName];
            workId = workDataSet[0].i;
            if (!workArray[workId]) {
                workArray[workId] = new Object();
                workArray[workId].id = workId;
                workArray[workId].name = workDataSet[0].n;
                workArray[workId].x = new Array();
                workArray[workId].y = new Array();
            }
 
            workXY = dataSetName.replace("(", "").replace(")", "").split(", ");
 
            workArray[workId].x.push(parseInt(workXY[0]));
            workArray[workId].y.push(parseInt(workXY[1]));
            }
 
            for (dataSetName in workArray) {
            workXY = [0, 0];
            workDataSet = workArray[dataSetName];
            for (i = 0; i < workDataSet.x.length; i++) {
                workXY[0] += workDataSet.x[i];
                workXY[1] += workDataSet.y[i];
            }
 
            workId = workDataSet.id;
            idString = idString + ';' + workId;
            accuracy = parseInt(coord.z);
            result.push(workId);
             
            if (!cacheData[workId] || cacheData[workId]["accuracy"] < accuracy) {   
                cacheData[workId] = new Object();              
                cacheData[workId]["wpId"] = workId;
                cacheData[workId]["name"] = workDataSet.name;
                cacheData[workId]["latlng"] = tileOff2LatLng(parseInt(coord.x), parseInt(coord.y),
                    parseFloat(workXY[0] / workDataSet.x.length),
                    parseFloat(workXY[1] / workDataSet.y.length),
                    parseInt(coord.z));
                cacheData[workId]["accuracy"] = accuracy;  
                 
                changed= true;             
            }
             
            if (!cacheDataSession[workId]) {
                cacheDataSession[workId] = new Object();               
            }
            }
 
            if(changed && localCacheControl)
            {          
                localCacheControl.saveLocalCaches("cacheData");
            }
             
            if (changed || idString != lastIdString) {
            lastIdString = idString;
 
            //Notify subscribers
            for (i = 0; i < subscribers.length; i++) {
                subscribers[i](result);
            }
            }
        }
 
        this.subscribe = function (callback) {         
            subscribers.push(callback);
        }
 
        //Constructor
        injectCacheInfoListener2();
    }
 
 
    var mapIconLoader = function () {          
        var markerLayerGroup = new Object();       
        var iconsTemplates = new Object();     
        var onIconAddSubscribers = new Array();
         
        //Constructor
        var init = function () {
            log("mapIconLoader initialisation started");         
            cacheExtractor = cacheExtractor||new mapCacheExtractor();
            if (browserType == "FireFox") {
            //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation
            cacheExtractor.subscribe(function (cachesInfo) {
                setTimeout(function () {
                newCacheInfo(cachesInfo);
                }, 0);
            });
            }
            else {
            cacheExtractor.subscribe(newCacheInfo);
            }
 
            log("mapIconLoader initialised");
        }
         
        var newCacheInfo = function (caches) {
            log("newCacheInfo: " + caches.length);        
            var cacheSession;
            var cachesToPopulate = new Array();
            var wpId;
             
            for (var i=0;i<caches.length;i++) {
            wpId = caches[i];          
            cacheSession = cacheDataSession[wpId];
 
            if (!cacheDataSession[wpId]["marker"]) {   
                cachesToPopulate.push(wpId);
            }          
            else if(cacheData[wpId]["accuracy"] > cacheDataSession[wpId]["currentAccuracy"]){
                moveIcon(cacheDataSession[wpId]["marker"], cacheData[wpId]["latlng"]);
            }
             
            }
             
            var length = cachesToPopulate.length;
            if (length > 0) {
            log("Request for " + length + " caches.");
            getVotes(cachesToPopulate);
            //newRequestControl.requestVotesWp(cachesToPopulate, false, function(obj){alert(obj)});
            }
        }
 
        var moveIcon = function(marker, latlng) {
            marker.setLatLng(new L.LatLng(latlng.lat, latlng.lng));
        }
         
        var injectIcon = function (lat, lng, icon, suffix) {
            var marker = new L.Marker(new L.LatLng(lat, lng), {
            icon:icon,
            clickable:false,
            draggable:false});
 
            if (!markerLayerGroup[suffix]) {
            markerLayerGroup[suffix] = new L.LayerGroup();
             
            markerLayerGroup[suffix].addLayer(marker);
             
            if(!option.enableSaveVisibility || getValue("gcVoteLayerVisibility_"+suffix, true) ){
                map.addLayer(markerLayerGroup[suffix]);
            }
             
            gcVoteLayersControl.addOverlay(markerLayerGroup[suffix], suffix.toString().replace('_', '.'));
            gcVoteLayersControl.sort();
            gcVoteLayersControl.iconize();
            }
            else {
            markerLayerGroup[suffix].addLayer(marker);
            }
             
            return {"marker":marker,
                "layerControl": markerLayerGroup[suffix]};
        }
 
        this.saveLayerVisibility = function(){
            if(option.enableSaveVisibility){
                for(var suffix in markerLayerGroup){
                    setValue("gcVoteLayerVisibility_"+suffix, markerLayerGroup[suffix]._map != null);
                }      
            }          
        }
         
        var getIcon = function (voteStars, voteCnt) {
            var suffix = avg2suffix(voteStars, voteCnt);
 
            if (!iconsTemplates[suffix]) {
            iconsTemplates[suffix] = new L.Icon({
                iconUrl: iconStorage.getStar(suffix),
                shadowUrl:"",
                iconSize:new L.Point(41, 9),
                iconAnchor:new L.Point(20, -12)
            });
            }
 
            return {"icon":iconsTemplates[suffix],
            "suffix":suffix};
        }
 
        this.isSuffixLayerVisible = function(suffix){
            return (markerLayerGroup[suffix] && markerLayerGroup[suffix]._map);
        }
         
        this.newCacheVoteData = function (waypoint) {
            var voteStars = voteData[waypoint].vote;
            var voteCnt = voteData[waypoint].voteCnt;
            log("newCacheVoteData received: " + waypoint + ":" + voteStars + "|" + voteCnt);
 
            if(voteStars >=0 && voteCnt >=0)
            {
                //Notify onIconAddSubscribers
                for (i = 0; i < onIconAddSubscribers.length; i++) {
                    onIconAddSubscribers[i](waypoint);
                }
 
                var iconData = getIcon(voteStars, voteCnt);
                var markerData = injectIcon(cacheData[waypoint].latlng.lat, cacheData[waypoint].latlng.lng, iconData.icon, iconData.suffix);   
                cacheDataSession[waypoint]["marker"] =  markerData.marker;
                cacheDataSession[waypoint]["layerControl"] =    markerData.layerControl;
                cacheDataSession[waypoint]["iconSuffix"] = iconData.suffix;
                cacheDataSession[waypoint]["currentAccuracy"] = cacheData[waypoint]["accuracy"];
            }
        }
         
        this.removeIcon = function(wpId){
            data = cacheDataSession[wpId];
            layer = data["marker"];
                 
            if (layer) {               
                data["layerControl"].removeLayer(layer);
                map.removeLayer(layer);            
            }
             
            data["marker"] = null;
            data["layerControl"] = null;
        }
         
        this.onIconAdd = function (callback) {
            onIconAddSubscribers.push(callback);
        }
         
        this.setTempIconVisibility = function(visible){        
            var checkBoxes = gcVoteLayersControl._overlaysList.getElementsByTagName('input');  
            var cb;
            var data;
            var layerId;
             
            for (var i = 0; i < checkBoxes.length; i++) {   
                cb = checkBoxes[i];
                if(browserType == "Chrome"){                   
                    //Hack for Chrome
                    var outerDiv = document.createElement("div");
                    outerDiv.style.visibility = "hidden";
                    outerDiv.style.height= "0px";
                    outerDiv.style.width= "0px";
                    document.getElementsByClassName("leaflet-control-layers")[0].appendChild(outerDiv);
                    outerDiv.addEventListener("DOMSubtreeModified",function() {                      
                            (function(_cb, _visible) {                         
                            layerId = _cb.layerId;
                            data = gcVoteLayersControl._layers[layerId];
 
                            if (_visible) {
                                gcVoteLayersControl._map.addLayer(data.layer, !data.overlay);
                            } else {
                                gcVoteLayersControl._map.removeLayer(data.layer);
                            }
                             
                            _cb.checked = _visible;
                            _cb.disabled = !_visible;  
                        })(cb, visible);
                    })
                     
                    var innerDiv = document.createElement("div");
                    innerDiv.style.visibility = "hidden";
                    innerDiv.style.height= "0px";
                    innerDiv.style.width= "0px";
                    outerDiv.appendChild(innerDiv);
                }
                else{
                    if(browserType == "FireFox" && typeof cb.wrappedJSObject != "undefined"){
                        //Hack to bypass the XPCNativeWrapper -> we have to access a custom property !
                        layerId = cb.wrappedJSObject.layerId;
                    }              
                    else{
                        layerId = cb.layerId;
                    }
                     
                    data = gcVoteLayersControl._layers[layerId];
 
                    if (visible) {
                        gcVoteLayersControl._map.addLayer(data.layer, !data.overlay);
                    } else {
                        gcVoteLayersControl._map.removeLayer(data.layer);
                    }
                     
                    cb.checked = visible;
                    cb.disabled = !visible;    
                }                  
                gcVoteLayersControl.sort();
            }
        }
         
        this.removeAllIcons = function(){
            for(var suffix in markerLayerGroup){
                map.removeLayer(markerLayerGroup[suffix]);
                gcVoteLayersControl.removeLayer(markerLayerGroup[suffix]);
            }
            markerLayerGroup = new Object();
        }
 
        init();
    }
 
    var mapTable = function (mapIconControl, mapPosControl, enableSort) {
        var activeTimeOutId; //Used to prevent blocking the map on mapmoves
        var activeTimeOutIdNewCacheData; //Used to prevent blocking the map on new cache data
        var table;
        var tableBody;
        var tab;
        var tabs;  
        var highlight;
        var onTableChangedSubscribers = new Array();
        var $ = myWindow.$ || null;                 
 
        var init = function(){
            $ = myWindow.$;        
             
            //insert table in the left bar
            insertTable();
             
            //Subscribe the onIconAdd event from mapIconControl
            mapIconControl.onIconAdd(newCacheData);
            //Subscribe the onMapMoved event from mapPosControl
            mapPosControl.onMapMoved(mapMoved);
             
            //Init highlight map icon
            //LatLng is Berlin, could be anywhere
            highlight = new L.Marker(new L.LatLng(52.523405,13.4114), {
            icon: new L.Icon({
                iconUrl:imgHighlight,
                shadowUrl:"",
                iconSize:new L.Point(35, 35),
                iconAnchor:new L.Point(17, 17) }),
            clickable:false,
            draggable:false});         
        }
         
        var insertTable = function () {        
            table = document.createElement("table");           
            table.id="cacheTable";
             
            var tableRowHead = document.createElement("tr");
            //tableRowHead.style = rowStyle + rowBackground[1];
            tableRowHead.innerHTML = '<th id="thName"><b>'+tl('Name')+'</b></th>' +
            '<th id="thCode"><b>GC Code</b></th>' +
            '<th id="thVote"><b>Vote</b></th>';
             
            var tableHead = document.createElement("THEAD");
            tableHead.appendChild(tableRowHead);
            table.appendChild(tableHead);
             
            tableBody = document.createElement("tbody");
            table.appendChild(tableBody);
             
            tabs = document.getElementById("searchtabs").firstElementChild;
            tab = document.createElement("li");
            tab.id = "clistlink_button";
            tab.className = "ui-block-b";
            tab.innerHTML = '<a href="#clist" title="'+tl('Cache List (with votes)')+'" id="clistButton" data-role="button" data-theme="a" class="ui-btn ui-btn-up-a">' +
            '<span class="ui-btn-inner">' +
            '<span class="ui-btn-text">' +
            tl('Cache List') +
            '</span>' +
            '</span>' +
            '</a>';
             
            tabs.insertBefore(tab, tabs.children[1]);
          
            tabs = document.getElementById("searchtabs").firstElementChild;
            tabs.children[0].style.width = "33%";
            tabs.children[1].style.width = "33%";
            tabs.children[2].style.width = "33%";
 
            var scroller = document.getElementById("scroller");
 
            var tabContent = document.createElement("div");
            tabContent.id = "clist";
            tabContent.style.display = "none";
            tabContent.appendChild(table);
         
            scroller.appendChild(tabContent);
             
            GM_addStyle("#cacheTable {width:330px;}"+
                    "#thName {width:212px;}"+
                    "#thCode {width:65px;}"+
                    "#thVote {width:61px;}");
             
            if(enableSort){
                //table style          
                GM_addStyle("table.tablesorter tbody tr.normal-row td { background: #E5E5E5; } " +
                        "table.tablesorter tbody tr.alt-row td { background: #FFFFFF; } "+
                        "th.tablesorter-header { background-color: #C7C7C7; background-image: url("+tableSorterBoth+");  background-repeat: no-repeat; background-position: center right; height: auto; cursor: pointer;}"+
                        "th.tablesorter-headerSortUp, th.headerSortUp, th.tablesorter-headerAsc {background-color: #A8A8A8; background-image: url("+tableSorterDown+"); background-repeat: no-repeat; background-position: center right;}"+
                        "th.headerSortDown, th.tablesorter-headerSortDown, th.tablesorter-headerDesc { background-color: #A8A8A8; background-image: url("+tableSorterUp+");  background-repeat: no-repeat; background-position: center right;}");
                 
                //load tablesorter jquery plugin
                tableSorterLoad($);
                initSorters();         
                 
                $(table).tablesorter({
                    headers: {
                        2: {
                            sorter:'vote'
                        }
                    },
                    textExtraction: {
                        2: function(node, table, cellIndex){ return node.children[0].src; }
                    },
                    widgets: ["zebra"],    
                    widgetOptions : {
                        zebra : [ "normal-row", "alt-row" ]
                    }
                });    
           }           
        }
 
        var insertRow = function (name, wpId, vote, voteCnt) {
            if (!cacheDataSession[wpId]["tableRow"]) {
            var tableRow = document.createElement("tr");
            tableRow.onmouseover = function() { showHighlight(wpId); };
            tableRow.onmouseout = hideHighlight;
 
            //tableRow.style = rowStyle + rowBackground[1];
            tableRow.innerHTML = '<td>' + name + '</td>' +
                '<td><a target="_blank" href="/seek/cache_details.aspx?wp='+ wpId +'">' + wpId + '</a></td>' +
                '<td>' + getIconString(vote, voteCnt) + '</td>';           
             
            tableBody.appendChild(tableRow);
 
            cacheDataSession[wpId]["tableRow"] = tableRow;
             
            display = cacheDataSession[wpId].marker && mapPosControl.isCoordOnScreen(cacheData[wpId].latlng.lat, cacheData[wpId].latlng.lng) && mapIconControl.isSuffixLayerVisible(cacheDataSession[wpId].iconSuffix);
            cacheDataSession[wpId]["tableRow"].style.display = display?'':'none';
            }         
        }
 
        var newCacheData = function (wpId) {       
            if(gcVoteNewMapGlobalOn && gcVoteNewMapIconsOn && cacheData[wpId])
            {
                insertRow(cacheData[wpId].name, wpId,  voteData[wpId].vote,  voteData[wpId].voteCnt);
                newCacheUpdateSorter();
            }
        }
 
        var getIconString = function (voteStars, voteCnt) {
            return '<img src="' +  iconStorage.getStar(avg2suffix(voteStars, voteCnt) ) + '" title="' + voteStars.toFixed(2) + '" />';
        }
         
        this.setTempIconVisibility = function(visible){
            var styleTabString =  (visible?"33%": "50%");
                 
            tabs.children[0].style.width = styleTabString;
            tabs.children[1].style.width  = styleTabString;
            tabs.children[2].style.width  = styleTabString;
             
            tab.style.display = (visible?'': 'none');
            table.style.display = (visible?'': 'none');
             
        }
         
        var mapMoved = function(currBounds, currentZoom)
        {
            //Only react when the map was not moved in the last time (prevent blocking of the map)
            clearTimeout(activeTimeOutId);                 
            activeTimeOutId = setTimeout(function() {handleMapMoved(currBounds, currentZoom);}, 500);
        }
         
        var newCacheUpdateSorter = function(){
            if(enableSort){
                //(prevent blocking of the map)
                clearTimeout(activeTimeOutIdNewCacheData);                 
                activeTimeOutIdNewCacheData = setTimeout(updateSorter, 50);
            }
        }
         
        var handleMapMoved = function(currBounds, currentZoom){        
            if(gcVoteNewMapGlobalOn && gcVoteNewMapIconsOn){
                var display;               
                 
                for(waypoint in cacheDataSession)
                {
                    if(cacheDataSession[waypoint]["tableRow"])
                    {                      
                        display = cacheDataSession[waypoint].marker && mapPosControl.isCoordOnScreen(cacheData[waypoint].latlng.lat, cacheData[waypoint].latlng.lng) && mapIconControl.isSuffixLayerVisible(cacheDataSession[waypoint].iconSuffix);
                        cacheDataSession[waypoint]["tableRow"].style.display = display?'':'none';                      
                    }
                }
                 
                if(enableSort){
                    updateSorter();
                }
            }
        }
         
        this.updateTable = function(){
            //use the map moved function
            mapMoved(mapPosControl.getCurrentBounds(),mapPosControl.getCurrentZoom());
        }
         
        var showHighlight = function(wpId) {           
            highlight.setLatLng(new L.LatLng(cacheData[wpId].latlng.lat,cacheData[wpId].latlng.lng));
            if(!highlight._map){
                map.addLayer(highlight);
            }
        }
         
        var hideHighlight = function() {
            if(highlight._map){
                map.removeLayer(highlight);
            }
        }
         
        this.removeAllCachesFromTable = function(){
            tableBody.innerHTML = "";
            if(enableSort){
                    updateSorter();
            }
        }
         
        if(enableSort){
            var initSorters = function(){
                $.tablesorter.addParser({
                    // set a unique id
                    id: 'vote',
                    is: function(s) {
                        // return false so this parser is not auto detected                    
                        return false;
                    },             
                    format: function(s,table,cell) {   
                        //return $.tablesorter.formatFloat((/[0-9]_*[0-9]*(?=\.gif)/.exec(s))[0].replace('_','.'));    
                        return $.tablesorter.formatFloat(cell.firstChild.title.replace('_','.'));
                    },
                    // set type, either numeric or text
                    type: 'numeric'
                });   
            }
             
            var updateSorter = function(){         
                $(table).trigger("update");        
            }      
         
            /*!
            * TableSorter 2.8.2 min - Client-side table sorting with ease!
            * Copyright (c) 2007 Christian Bach
            */
            var tableSorterLoad = function(g){g.extend({tablesorter:new function(){function d(c){"undefined"!==typeof console&&"undefined"!==typeof console.log?console.log(c):alert(c)}function w(c,b){d(c+" ("+((new Date).getTime()-b.getTime())+"ms)")}function r(c,b,a){if(!b){
                return "";
            }var e=c.config,d=e.textExtraction,j="",j="simple"===d?e.supportsTextContent?b.textContent:g(b).text():"function"===typeof d?d(b,c,a):"object"===typeof d&&d.hasOwnProperty(a)?d[a](b,c,a):e.supportsTextContent?b.textContent:g(b).text();return g.trim(j)} function l(c){var b=c.config,a=b.$tbodies=b.$table.children("tbody:not(."+b.cssInfoBlock+")"),e,t,j,h,k,p,m="";if(0===a.length){
                return b.debug ? d("*Empty table!* Not building a parser cache") : "";
            }a=a[0].rows;if(a[0]){e=[];t=a[0].cells.length;for(j=0;j<t;j++){h=b.$headers.filter(":not([colspan])");h=h.add(b.$headers.filter('[colspan="1"]')).filter('[data-column="'+j+'"]:last');k=b.headers[j];p=f.getParserById(f.getData(h,k,"sorter"));b.empties[j]=f.getData(h,k,"empty")||b.emptyTo||(b.emptyToBottom?"bottom": "top");b.strings[j]=f.getData(h,k,"string")||b.stringTo||"max";if(!p){
                a:{
                    h = c;
                    k = a;
                    p = -1;
                    for (var g = j, n = void 0, w = f.parsers.length, F = !1, C = "", n = !0; "" === C && n;){
                        p++, k[p] ? (F = k[p].cells[g], C = r(h, F, g), h.config.debug && d("Checking if value was empty on row " + p + ", column: " + g + ': "' + C + '"')) : n = !1;
                    }
                    for (; 0 <= --w;){
                        if ((n = f.parsers[w]) && "text" !== n.id && n.is && n.is(C, h, F)) {
                            p = n;
                            break a
                        }
                    }
                    p = f.getParserById("text")
                }
            }b.debug&&(m+="column:"+j+"; parser:"+p.id+"; string:"+b.strings[j]+"; empty: "+b.empties[j]+"\n");e.push(p)}}b.debug&& d(m);b.parsers=e}function s(c){var b=c.tBodies,a=c.config,e,t,j=a.parsers,h,k,p,m,q,n,G,l=[];a.cache={};if(!j){
                return a.debug ? d("*Empty table!* Not building a cache") : "";
            }a.debug&&(G=new Date);a.showProcessing&&f.isProcessing(c,!0);for(m=0;m<b.length;m++){
                if (a.cache[m] = {row: [], normalized: []}, !g(b[m]).hasClass(a.cssInfoBlock)) {
                    e = b[m] && b[m].rows.length || 0;
                    t = b[m].rows[0] && b[m].rows[0].cells.length || 0;
                    for (k = 0; k < e; ++k){
                        if (q = g(b[m].rows[k]), n = [], q.hasClass(a.cssChildRow)){
                            a.cache[m].row[a.cache[m].row.length - 1] = a.cache[m].row[a.cache[m].row.length - 1].add(q);
                        } else {
                            a.cache[m].row.push(q);
                            for (p = 0; p < t; ++p) {
                                if (h = r(c, q[0].cells[p], p), h = j[p].format(h, c, q[0].cells[p], p), n.push(h), "numeric" === (j[p].type || "").toLowerCase()){
                                    l[p] = Math.max(Math.abs(h), l[p] || 0);
                                }
                            }
                            n.push(a.cache[m].normalized.length);
                            a.cache[m].normalized.push(n)
                        }
                    }
                    a.cache[m].colMax = l
                }
            }a.showProcessing&&f.isProcessing(c);a.debug&&w("Building cache for "+e+" rows",G)}function v(c,b){var a=c.config,e=c.tBodies,d=[],j=a.cache,h,k,p,m,q,n,l,r,C,s,v;if(j[0]){a.debug&& (v=new Date);for(r=0;r<e.length;r++){
                if (h = g(e[r]), h.length && !h.hasClass(a.cssInfoBlock)) {
                    q = f.processTbody(c, h, !0);
                    h = j[r].row;
                    k = j[r].normalized;
                    m = (p = k.length) ? k[0].length - 1 : 0;
                    for (n = 0; n < p; n++){
                        if (s = k[n][m], d.push(h[s]), !a.appender || !a.removeRows) {
                            C = h[s].length;
                            for (l = 0; l < C; l++) {
                                q.append(h[s][l])
                            }
                        }
                    }
                    f.processTbody(c, q, !1)
                }
            }a.appender&&a.appender(c,d);a.debug&&w("Rebuilt table",v);b||f.applyWidget(c);g(c).trigger("sortEnd",c)}}function z(c){var b=[],a={},e=0,t=g(c).find("thead:eq(0), tfoot").children("tr"),j, h,k,p,m,q,n,l,r,s;for(j=0;j<t.length;j++){m=t[j].cells;for(h=0;h<m.length;h++){p=m[h];q=p.parentNode.rowIndex;n=q+"-"+p.cellIndex;l=p.rowSpan||1;r=p.colSpan||1;"undefined"===typeof b[q]&&(b[q]=[]);for(k=0;k<b[q].length+1;k++){
                if ("undefined" === typeof b[q][k]) {
                    s = k;
                    break
                }
            }a[n]=s;e=Math.max(s,e);g(p).attr({"data-column":s});for(k=q;k<q+l;k++){"undefined"===typeof b[k]&&(b[k]=[]);n=b[k];for(p=s;p<s+r;p++){
                n[p] = "x"
            }}}}c.config.columns=e;var v,u,z,B,A,y,D,x=c.config;x.headerList=[];x.headerContent=[];x.debug&& (D=new Date);B=x.cssIcon?'<i class="'+x.cssIcon+'"></i>':"";x.$headers=g(c).find(x.selectorHeaders).each(function(c){u=g(this);v=x.headers[c];x.headerContent[c]=this.innerHTML;A=x.headerTemplate.replace(/\{content\}/g,this.innerHTML).replace(/\{icon\}/g,B);x.onRenderTemplate&&(z=x.onRenderTemplate.apply(u,[c,A]))&&"string"===typeof z&&(A=z);this.innerHTML='<div class="tablesorter-header-inner">'+A+"</div>";x.onRenderHeader&&x.onRenderHeader.apply(u,[c]);this.column=a[this.parentNode.rowIndex+"-"+ this.cellIndex];var b=f.getData(u,v,"sortInitialOrder")||x.sortInitialOrder;this.order=/^d/i.test(b)||1===b?[1,0,2]:[0,1,2];this.count=-1;this.lockedOrder=!1;y=f.getData(u,v,"lockedOrder")||!1;"undefined"!==typeof y&&!1!==y&&(this.order=this.lockedOrder=/^d/i.test(y)||1===y?[1,1,1]:[0,0,0]);u.addClass(x.cssHeader);x.headerList[c]=this;u.parent().addClass(x.cssHeaderRow)});E(c);x.debug&&(w("Built headers:",D),d(x.$headers))}function A(c,b,a){var e=g(c);e.find(c.config.selectorRemove).remove();l(c); s(c);D(e,b,a)}function E(c){var b,a=c.config;a.$headers.each(function(c,d){b="false"===f.getData(d,a.headers[c],"sorter");d.sortDisabled=b;g(d)[b?"addClass":"removeClass"]("sorter-false")})}function y(c){var b,a,e,d=c.config,j=d.sortList,h=[d.cssAsc,d.cssDesc],k=g(c).find("tfoot tr").children().removeClass(h.join(" "));d.$headers.removeClass(h.join(" "));e=j.length;for(b=0;b<e;b++){
                if (2 !== j[b][1] && (c = d.$headers.not(".sorter-false").filter('[data-column="' + j[b][0] + '"]' + (1 === e ? ":last" : "")), c.length)){
                    for (a = 0; a < c.length; a++){
                        c[a].sortDisabled || (c.eq(a).addClass(h[j[b][1]]), k.length && k.filter('[data-column="' + j[b][0] + '"]').eq(a).addClass(h[j[b][1]]))
                    }
                }
            }}function B(c){var b=0,a=c.config,e=a.sortList,d=e.length,j=c.tBodies.length,h,k,f,m,q,n,l,r,s;if(!a.serverSideSorting&&a.cache[0]){a.debug&&(h=new Date);for(f=0;f<j;f++){
                q = a.cache[f].colMax, s = (n = a.cache[f].normalized) && n[0] ? n[0].length - 1 : 0, n.sort(function (j, h) {
                    for (k = 0; k < d; k++) {
                        m = e[k][0];
                        r = e[k][1];
                        l = /n/i.test(a.parsers && a.parsers[m] ? a.parsers[m].type || "" : "") ? "Numeric" : "Text";
                        l += 0 === r ? "" : "Desc";
                        /Numeric/.test(l) && a.strings[m] && (b = "boolean" === typeof a.string[a.strings[m]] ? (0 === r ? 1 : -1) * (a.string[a.strings[m]] ? -1 : 1) : a.strings[m] ? a.string[a.strings[m]] || 0 : 0);
                        var f = g.tablesorter["sort" + l](c, j[m], h[m], m, q[m], b);
                        if (f){
                            return f
                        }
                    }
                    return j[s] - h[s]
                });
            }a.debug&&w("Sorting on "+e.toString()+" and dir "+r+" time",h)}}function H(c,b){c.trigger("updateComplete");"function"===typeof b&&b(c[0])}function D(c,b,a){!1!==b&&!c[0].isProcessing?c.trigger("sorton",[c[0].config.sortList, function(){H(c,a)}]):H(c,a)}function I(c){var b=c.config,a=g(c),e,d;b.$headers.find("*")[g.fn.addBack?"addBack":"andSelf"]().filter(b.selectorSort).unbind("mousedown.tablesorter mouseup.tablesorter").bind("mousedown.tablesorter mouseup.tablesorter",function(a,e){var k=(this.tagName.match("TH|TD")?g(this):g(this).parents("th, td").filter(":last"))[0];if(1!==(a.which||a.button)){
                return !1;
            }if("mousedown"===a.type){
                return d = (new Date).getTime(), "INPUT" === a.target.tagName ? "" : !b.cancelSelection;
            }if(!0!==e&& 250<(new Date).getTime()-d){
                return !1;
            }b.delayInit&&!b.cache&&s(c);if(!k.sortDisabled){var p,m,q,n=c.config,l=!a[n.sortMultiSortKey],r=g(c);r.trigger("sortStart",c);k.count=a[n.sortResetKey]?2:(k.count+1)%(n.sortReset?3:2);n.sortRestart&&(m=k,n.$headers.each(function(){if(this!==m&&(l||!g(this).is("."+n.cssDesc+",."+n.cssAsc))){
                this.count = -1
            }}));m=k.column;if(l){n.sortList=[];if(null!==n.sortForce){p=n.sortForce;for(q=0;q<p.length;q++){
                p[q][0] !== m && n.sortList.push(p[q])
            }}p=k.order[k.count];if(2>p&&(n.sortList.push([m, p]),1<k.colSpan)){
                for (q = 1; q < k.colSpan; q++){
                    n.sortList.push([m + q, p])
                }
            }}else if(n.sortAppend&&1<n.sortList.length&&f.isValueInArray(n.sortAppend[0][0],n.sortList)&&n.sortList.pop(),f.isValueInArray(m,n.sortList)){
                for (q = 0; q < n.sortList.length; q++){
                    k = n.sortList[q], p = n.headerList[k[0]], k[0] === m && (k[1] = p.order[p.count], 2 === k[1] && (n.sortList.splice(q, 1), p.count = -1));
                }
            }else {
                if (p = k.order[k.count], 2 > p && (n.sortList.push([m, p]), 1 < k.colSpan)){
                    for (q = 1; q < k.colSpan; q++){
                        n.sortList.push([m + q, p]);
                    }
                }
            }if(null!==n.sortAppend){p=n.sortAppend; for(q=0;q<p.length;q++){
                p[q][0] !== m && n.sortList.push(p[q])
            }}r.trigger("sortBegin",c);setTimeout(function(){y(c);B(c);v(c)},1)}});b.cancelSelection&&b.$headers.each(function(){this.onselectstart=function(){return!1}});a.unbind("sortReset update updateRows updateCell updateAll addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave ".split(" ").join(".tablesorter ")).bind("sortReset.tablesorter",function(a){a.stopPropagation();b.sortList=[];y(c);B(c);v(c)}).bind("updateAll.tablesorter", function(a,b,e){a.stopPropagation();f.restoreHeaders(c);z(c);I(c);A(c,b,e)}).bind("update.tablesorter updateRows.tablesorter",function(a,b,e){a.stopPropagation();E(c);A(c,b,e)}).bind("updateCell.tablesorter",function(e,d,f,p){e.stopPropagation();a.find(b.selectorRemove).remove();var m,q,n;m=a.find("tbody");e=m.index(g(d).parents("tbody").filter(":last"));var t=g(d).parents("tr").filter(":last");d=g(d)[0];m.length&&0<=e&&(q=m.eq(e).find("tr").index(t),n=d.cellIndex,m=b.cache[e].normalized[q].length- 1,b.cache[e].row[c.config.cache[e].normalized[q][m]]=t,b.cache[e].normalized[q][n]=b.parsers[n].format(r(c,d,n),c,d,n),D(a,f,p))}).bind("addRows.tablesorter",function(d,h,f,g){d.stopPropagation();var m=h.filter("tr").length,t=[],n=h[0].cells.length,w=a.find("tbody").index(h.closest("tbody"));b.parsers||l(c);for(d=0;d<m;d++){for(e=0;e<n;e++){
                t[e] = b.parsers[e].format(r(c, h[d].cells[e], e), c, h[d].cells[e], e);
            }t.push(b.cache[w].row.length);b.cache[w].row.push([h[d]]);b.cache[w].normalized.push(t);t=[]}D(a, f,g)}).bind("sorton.tablesorter",function(b,e,d,f){b.stopPropagation();a.trigger("sortStart",this);var m,t,n,l=c.config;b=e||l.sortList;l.sortList=[];g.each(b,function(a,c){m=[parseInt(c[0],10),parseInt(c[1],10)];if(n=l.headerList[m[0]]){
                l.sortList.push(m), t = g.inArray(m[1], n.order), n.count = 0 <= t ? t : m[1] % (l.sortReset ? 3 : 2)
            }});y(c);B(c);v(c,f);"function"===typeof d&&d(c)}).bind("appendCache.tablesorter",function(a,b,e){a.stopPropagation();v(c,e);"function"===typeof b&&b(c)}).bind("applyWidgetId.tablesorter", function(a,e){a.stopPropagation();f.getWidgetById(e).format(c,b,b.widgetOptions)}).bind("applyWidgets.tablesorter",function(a,b){a.stopPropagation();f.applyWidget(c,b)}).bind("refreshWidgets.tablesorter",function(a,b,e){a.stopPropagation();f.refreshWidgets(c,b,e)}).bind("destroy.tablesorter",function(a,b,e){a.stopPropagation();f.destroy(c,b,e)})}var f=this;f.version="2.8.2";f.parsers=[];f.widgets=[];f.defaults={theme:"default",widthFixed:!1,showProcessing:!1,headerTemplate:"{content}",onRenderTemplate:null, onRenderHeader:null,cancelSelection:!0,dateFormat:"mmddyyyy",sortMultiSortKey:"shiftKey",sortResetKey:"ctrlKey",usNumberFormat:!0,delayInit:!1,serverSideSorting:!1,headers:{},ignoreCase:!0,sortForce:null,sortList:[],sortAppend:null,sortInitialOrder:"asc",sortLocaleCompare:!1,sortReset:!1,sortRestart:!1,emptyTo:"bottom",stringTo:"max",textExtraction:"simple",textSorter:null,widgets:[],widgetOptions:{zebra:["even","odd"]},initWidgets:!0,initialized:null,tableClass:"tablesorter",cssAsc:"tablesorter-headerAsc", cssChildRow:"tablesorter-childRow",cssDesc:"tablesorter-headerDesc",cssHeader:"tablesorter-header",cssHeaderRow:"tablesorter-headerRow",cssIcon:"tablesorter-icon",cssInfoBlock:"tablesorter-infoOnly",cssProcessing:"tablesorter-processing",selectorHeaders:"> thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me",debug:!1,headerList:[],empties:{},strings:{},parsers:[]};f.benchmark=w;f.construct=function(c){return this.each(function(){if(!this.tHead||0===this.tBodies.length||!0===this.hasInitialized){
                return this.config && this.config.debug ? d("stopping initialization! No thead, tbody or tablesorter has already been initialized") : "";
            }var b=g(this),a=this,e,t="",j=g.metadata;a.hasInitialized=!1;a.isProcessing=!0;a.config={};e=g.extend(!0,a.config,f.defaults,c);g.data(a,"tablesorter",e);e.debug&&g.data(a,"startoveralltimer",new Date);e.supportsTextContent="x"===g("<span>x</span>")[0].textContent;e.supportsDataObject=1.4<=parseFloat(g.fn.jquery);e.string={max:1,min:-1,"max+":1,"max-":-1,zero:0,none:0,"null":0,top:!0,bottom:!1}; /tablesorter\-/.test(b.attr("class"))||(t=""!==e.theme?" tablesorter-"+e.theme:"");e.$table=b.addClass(e.tableClass+t);e.$tbodies=b.children("tbody:not(."+e.cssInfoBlock+")");z(a);if(a.config.widthFixed&&0===g(a).find("colgroup").length){var h=g("<colgroup>"),k=g(a).width();g(a.tBodies[0]).find("tr:first").children("td").each(function(){h.append(g("<col>").css("width",parseInt(1E3*(g(this).width()/k),10)/10+"%"))});g(a).prepend(h)}l(a);e.delayInit||s(a);I(a);e.supportsDataObject&&"undefined"!==typeof b.data().sortlist? e.sortList=b.data().sortlist:j&&(b.metadata()&&b.metadata().sortlist)&&(e.sortList=b.metadata().sortlist);f.applyWidget(a,!0);0<e.sortList.length?b.trigger("sorton",[e.sortList,{},!e.initWidgets]):e.initWidgets&&f.applyWidget(a);e.showProcessing&&b.unbind("sortBegin.tablesorter sortEnd.tablesorter").bind("sortBegin.tablesorter sortEnd.tablesorter",function(b){f.isProcessing(a,"sortBegin"===b.type)});a.hasInitialized=!0;a.isProcessing=!1;e.debug&&f.benchmark("Overall initialization time",g.data(a, "startoveralltimer"));b.trigger("tablesorter-initialized",a);"function"===typeof e.initialized&&e.initialized(a)})};f.isProcessing=function(c,b,a){c=g(c);var e=c[0].config;c=a||c.find("."+e.cssHeader);b?(0<e.sortList.length&&(c=c.filter(function(){return this.sortDisabled?!1:f.isValueInArray(parseFloat(g(this).attr("data-column")),e.sortList)})),c.addClass(e.cssProcessing)):c.removeClass(e.cssProcessing)};f.processTbody=function(c,b,a){if(a){
                return c.isProcessing = !0, b.before('<span class="tablesorter-savemyplace"/>'), a = g.fn.detach ? b.detach() : b.remove();
            }a=g(c).find("span.tablesorter-savemyplace");b.insertAfter(a);a.remove();c.isProcessing=!1};f.clearTableBody=function(c){g(c)[0].config.$tbodies.empty()};f.restoreHeaders=function(c){var b=c.config;b.$headers.each(function(a){g(this).find(".tablesorter-header-inner").length&&g(this).html(b.headerContent[a])})};f.destroy=function(c,b,a){c=g(c)[0];if(c.hasInitialized){f.refreshWidgets(c,!0,!0);var e=g(c),d=c.config,j=e.find("thead:first"),h=j.find("tr."+d.cssHeaderRow).removeClass(d.cssHeaderRow), k=e.find("tfoot:first > tr").children("th, td");j.find("tr").not(h).remove();e.removeData("tablesorter").unbind("sortReset update updateAll updateRows updateCell addRows sorton appendCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave sortBegin sortEnd ".split(" ").join(".tablesorter "));d.$headers.add(k).removeClass(d.cssHeader+" "+d.cssAsc+" "+d.cssDesc).removeAttr("data-column");h.find(d.selectorSort).unbind("mousedown.tablesorter mouseup.tablesorter");f.restoreHeaders(c); !1!==b&&e.removeClass(d.tableClass+" tablesorter-"+d.theme);c.hasInitialized=!1;"function"===typeof a&&a(c)}};f.regex=[/(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi,/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,/^0x[0-9a-f]+$/i];f.sortText=function(c,b,a,e){if(b===a){
                return 0;
            }var d=c.config,j=d.string[d.empties[e]||d.emptyTo],h=f.regex;if(""===b&&0!==j){
                return "boolean" === typeof j ? j ? -1 : 1 : -j || -1;
            }if(""=== a&&0!==j){
                return "boolean" === typeof j ? j ? 1 : -1 : j || 1;
            }if("function"===typeof d.textSorter){
                return d.textSorter(b, a, c, e);
            }c=b.replace(h[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");e=a.replace(h[0],"\\0$1\\0").replace(/\\0$/,"").replace(/^\\0/,"").split("\\0");b=parseInt(b.match(h[2]),16)||1!==c.length&&b.match(h[1])&&Date.parse(b);if(a=parseInt(a.match(h[2]),16)||b&&a.match(h[1])&&Date.parse(a)||null){if(b<a){
                return -1;
            }if(b>a){
                return 1
            }}d=Math.max(c.length,e.length);for(b=0;b<d;b++){a=isNaN(c[b])? c[b]||0:parseFloat(c[b])||0;h=isNaN(e[b])?e[b]||0:parseFloat(e[b])||0;if(isNaN(a)!==isNaN(h)){
                return isNaN(a) ? 1 : -1;
            }typeof a!==typeof h&&(a+="",h+="");if(a<h){
                return -1;
            }if(a>h){
                return 1
            }}return 0};f.sortTextDesc=function(c,b,a,e){if(b===a){
                return 0;
            }var d=c.config,j=d.string[d.empties[e]||d.emptyTo];return""===b&&0!==j?"boolean"===typeof j?j?-1:1:j||1:""===a&&0!==j?"boolean"===typeof j?j?1:-1:-j||-1:"function"===typeof d.textSorter?d.textSorter(a,b,c,e):f.sortText(c,a,b)};f.getTextValue=function(c,b,a){if(b){var e= c?c.length:0,d=b+a;for(b=0;b<e;b++){
                d += c.charCodeAt(b);
            }return a*d}return 0};f.sortNumeric=function(c,b,a,e,d,j){if(b===a){
                return 0;
            }c=c.config;e=c.string[c.empties[e]||c.emptyTo];if(""===b&&0!==e){
                return "boolean" === typeof e ? e ? -1 : 1 : -e || -1;
            }if(""===a&&0!==e){
                return "boolean" === typeof e ? e ? 1 : -1 : e || 1;
            }isNaN(b)&&(b=f.getTextValue(b,d,j));isNaN(a)&&(a=f.getTextValue(a,d,j));return b-a};f.sortNumericDesc=function(c,b,a,d,g,j){if(b===a){
                return 0;
            }c=c.config;d=c.string[c.empties[d]||c.emptyTo];if(""===b&&0!==d){
                return "boolean" === typeof d ? d ? -1 : 1 : d || 1;
            }if(""===a&&0!==d){
                return "boolean" === typeof d ? d ? 1 : -1 : -d || -1;
            }isNaN(b)&&(b=f.getTextValue(b,g,j));isNaN(a)&&(a=f.getTextValue(a,g,j));return a-b};f.characterEquivalents={a:"\u00e1\u00e0\u00e2\u00e3\u00e4\u0105\u00e5",A:"\u00c1\u00c0\u00c2\u00c3\u00c4\u0104\u00c5",c:"\u00e7\u0107\u010d",C:"\u00c7\u0106\u010c",e:"\u00e9\u00e8\u00ea\u00eb\u011b\u0119",E:"\u00c9\u00c8\u00ca\u00cb\u011a\u0118",i:"\u00ed\u00ec\u0130\u00ee\u00ef\u0131",I:"\u00cd\u00cc\u0130\u00ce\u00cf",o:"\u00f3\u00f2\u00f4\u00f5\u00f6", O:"\u00d3\u00d2\u00d4\u00d5\u00d6",ss:"\u00df",SS:"\u1e9e",u:"\u00fa\u00f9\u00fb\u00fc\u016f",U:"\u00da\u00d9\u00db\u00dc\u016e"};f.replaceAccents=function(c){var b,a="[",d=f.characterEquivalents;if(!f.characterRegex){f.characterRegexArray={};for(b in d){
                "string" === typeof b && (a += d[b], f.characterRegexArray[b] = RegExp("[" + d[b] + "]", "g"));
            }f.characterRegex=RegExp(a+"]")}if(f.characterRegex.test(c)){
                for (b in d){
                    "string" === typeof b && (c = c.replace(f.characterRegexArray[b], b));
                }
            }return c};f.isValueInArray=function(c, b){var a,d=b.length;for(a=0;a<d;a++){
                if (b[a][0] === c){
                    return !0;
                }
            }return!1};f.addParser=function(c){var b,a=f.parsers.length,d=!0;for(b=0;b<a;b++){
                f.parsers[b].id.toLowerCase() === c.id.toLowerCase() && (d = !1);
            }d&&f.parsers.push(c)};f.getParserById=function(c){var b,a=f.parsers.length;for(b=0;b<a;b++){
                if (f.parsers[b].id.toLowerCase() === c.toString().toLowerCase()){
                    return f.parsers[b];
                }
            }return!1};f.addWidget=function(c){f.widgets.push(c)};f.getWidgetById=function(c){var b,a,d=f.widgets.length;for(b=0;b<d;b++){
                if ((a = f.widgets[b]) && a.hasOwnProperty("id") && a.id.toLowerCase() === c.toLowerCase()){
                    return a
                }
            }};f.applyWidget=function(c,b){c=g(c)[0];var a=c.config,d=a.widgetOptions,l=a.widgets.sort().reverse(),j,h,k,p=l.length;h=g.inArray("zebra",a.widgets);0<=h&&(a.widgets.splice(h,1),a.widgets.push("zebra"));a.debug&&(j=new Date);for(h=0;h<p;h++){
                if (k = f.getWidgetById(l[h])){
                    b ? (k.hasOwnProperty("options") && g.extend(!0, k.options, d), k.hasOwnProperty("init") && k.init(c, k, a, d)) : !b && k.hasOwnProperty("format") && k.format(c, a, d, !1);
                }
            } a.debug&&w("Completed "+(!0===b?"initializing":"applying")+" widgets",j)};f.refreshWidgets=function(c,b,a){c=g(c)[0];var e,l=c.config,j=l.widgets,h=f.widgets,k=h.length;for(e=0;e<k;e++){
                if (h[e] && h[e].id && (b || 0 > g.inArray(h[e].id, j))){
                    l.debug && d("Refeshing widgets: Removing " + h[e].id), h[e].hasOwnProperty("remove") && h[e].remove(c, l, l.widgetOptions);
                }
            }!0!==a&&f.applyWidget(c,b)};f.getData=function(c,b,a){var d="";c=g(c);var f,j;if(!c.length){
                return "";
            }f=g.metadata?c.metadata():!1;j=" "+(c.attr("class")||""); "undefined"!==typeof c.data(a)||"undefined"!==typeof c.data(a.toLowerCase())?d+=c.data(a)||c.data(a.toLowerCase()):f&&"undefined"!==typeof f[a]?d+=f[a]:b&&"undefined"!==typeof b[a]?d+=b[a]:" "!==j&&j.match(" "+a+"-")&&(d=j.match(RegExp("\\s"+a+"-([\\w-]+)"))[1]||"");return g.trim(d)};f.formatFloat=function(c,b){if("string"!==typeof c||""===c){
                return c;
            }var a;c=(b&&b.config?!1!==b.config.usNumberFormat:"undefined"!==typeof b?b:1)?c.replace(/,/g,""):c.replace(/[\s|\.]/g,"").replace(/,/g,".");/^\s*\([.\d]+\)/.test(c)&& (c=c.replace(/^\s*\(/,"-").replace(/\)/,""));a=parseFloat(c);return isNaN(a)?g.trim(c):a};f.isDigit=function(c){return isNaN(c)?/^[\-+(]?\d+[)]?$/.test(c.toString().replace(/[,.'"\s]/g,"")):!0}}});var l=g.tablesorter;g.fn.extend({tablesorter:l.construct});l.addParser({id:"text",is:function(){return!0},format:function(d,w){var r=w.config;d&&(d=g.trim(r.ignoreCase?d.toLocaleLowerCase():d),d=r.sortLocaleCompare?l.replaceAccents(d):d);return d},type:"text"});l.addParser({id:"digit",is:function(d){return l.isDigit(d)}, format:function(d,g){return d?l.formatFloat(d.replace(/[^\w,. \-()]/g,""),g):d},type:"numeric"});l.addParser({id:"currency",is:function(d){return/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/.test((d||"").replace(/[,. ]/g,""))},format:function(d,g){return d?l.formatFloat(d.replace(/[^\w,. \-()]/g,""),g):d},type:"numeric"});l.addParser({id:"ipAddress",is:function(d){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(d)},format:function(d,g){var r,u=d?d.split("."): "",s="",v=u.length;for(r=0;r<v;r++){
                s += ("00" + u[r]).slice(-3);
            }return d?l.formatFloat(s,g):d},type:"numeric"});l.addParser({id:"url",is:function(d){return/^(https?|ftp|file):\/\//.test(d)},format:function(d){return d?g.trim(d.replace(/(https?|ftp|file):\/\//,"")):d},type:"text"});l.addParser({id:"isoDate",is:function(d){return/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/.test(d)},format:function(d,g){return d?l.formatFloat(""!==d?(new Date(d.replace(/-/g,"/"))).getTime()||"":"",g):d},type:"numeric"});l.addParser({id:"percent", is:function(d){return/(\d\s?%|%\s?\d)/.test(d)},format:function(d,g){return d?l.formatFloat(d.replace(/%/g,""),g):d},type:"numeric"});l.addParser({id:"usLongDate",is:function(d){return/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i.test(d)||/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i.test(d)},format:function(d,g){return d?l.formatFloat((new Date(d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||"",g):d},type:"numeric"});l.addParser({id:"shortDate",is:function(d){return/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/.test((d|| "").replace(/\s+/g," ").replace(/[\-.,]/g,"/"))},format:function(d,g,r,u){if(d){r=g.config;var s=r.headerList[u],v=s.shortDateFormat;"undefined"===typeof v&&(v=s.shortDateFormat=l.getData(s,r.headers[u],"dateFormat")||r.dateFormat);d=d.replace(/\s+/g," ").replace(/[\-.,]/g,"/");"mmddyyyy"===v?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2"):"ddmmyyyy"===v?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1"):"yyyymmdd"===v&&(d=d.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$1/$2/$3"))}return d?l.formatFloat((new Date(d)).getTime()||"",g):d},type:"numeric"});l.addParser({id:"time",is:function(d){return/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(d)},format:function(d,g){return d?l.formatFloat((new Date("2000/01/01 "+d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||"",g):d},type:"numeric"});l.addParser({id:"metadata",is:function(){return!1},format:function(d,l,r){d=l.config;d=!d.parserMetadataName?"sortValue":d.parserMetadataName;return g(r).metadata()[d]}, type:"numeric"});l.addWidget({id:"zebra",format:function(d,w,r){var u,s,v,z,A,E,y=RegExp(w.cssChildRow,"i"),B=w.$tbodies;w.debug&&(A=new Date);for(d=0;d<B.length;d++){
                u = B.eq(d), E = u.children("tr").length, 1 < E && (v = 0, u = u.children("tr:visible"), u.each(function () {
                    s = g(this);
                    y.test(this.className) || v++;
                    z = 0 === v % 2;
                    s.removeClass(r.zebra[z ? 1 : 0]).addClass(r.zebra[z ? 0 : 1])
                }));
            }w.debug&&l.benchmark("Applying Zebra widget",A)},remove:function(d,l,r){var u;l=l.$tbodies;var s=(r.zebra||["even","odd"]).join(" ");for(r= 0;r<l.length;r++){
                u = g.tablesorter.processTbody(d, l.eq(r), !0), u.children().removeClass(s), g.tablesorter.processTbody(d, u, !1)
            }}})};
 
            //tablesorter end
        }
        //Constructor
        init();
    }
 
    var mapPositionHandler = function(){
        var currentBounds;
        var currentZoom;
        var onMapMovedSubscribers = new Array();
         
        var init = function(){     
            currentBounds = map.getBounds();   
            currentZoom = map.getZoom();           
            map.addEventListener("moveend",mapMovedHandler);
        }
         
        //Is called when the view of the map changed
        var mapMovedHandler = function()
        {
            currentBounds =map.getBounds();
            currentZoom = map.getZoom();
             
            //Notify subscribers
            for (i = 0; i < onMapMovedSubscribers.length; i++) {
                onMapMovedSubscribers[i](currentBounds, currentZoom);
            }
             
        }
         
        this.getCurrentBounds = function() {
            return currentBounds;
        }
         
        this.getCurrentZoom = function(){
            return currentZoom;
        }
         
        this.isCoordOnScreen = function (lat, lng) {
            return currentBounds.contains(new L.LatLng(lat, lng));
        }
         
        this.onMapMoved = function(callback) {
            onMapMovedSubscribers.push(callback);
        }      
         
        //Constructor
        init();
    }
     
    var mapCacheGenerator = function(mapPosControl){
        var lastBounds;
        var lastZoom;
         
         
        var init = function(){     
            lastBounds = mapPosControl.getCurrentBounds();     
            lastZoom = mapPosControl.getCurrentZoom(); 
             
            if(option.enableAutomaticCacheGeneration){
                mapPosControl.onMapMoved(mapMoved);
            }
        }
         
        var mapMoved = function(currBounds, currentZoom)
        {
            if(currentZoom < lastZoom || !currBounds.equals(lastBounds))
            {
                if (browserType == "FireFox") {
                    //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation        
                    setTimeout(function () {
                        tryGenerateCaches(currBounds, currentZoom);
                    }, 0);             
                }
                else {
                    tryGenerateCaches(currBounds, currentZoom);
                }  
            }
        }  
         
        this.generateCaches = function ()
        {
            var currBounds = mapPosControl.getCurrentBounds(); 
            var currentZoom = mapPosControl.getCurrentZoom();  
            tryGenerateCaches(currBounds, currentZoom);
        }
         
        var tryGenerateCaches = function(currBounds, currentZoom){
            var waypointsToInsert = new Array();
             
            if(gcVoteNewMapGlobalOn && gcVoteNewMapIconsOn && currentZoom > 12 ){               
                for(wpId in cacheData)
                {                  
                    if(mapPosControl.isCoordOnScreen(cacheData[wpId].latlng.lat, cacheData[wpId].latlng.lng) && !cacheDataSession[wpId])
                    {
                        //We have data, but they are not used in this session
                        waypointsToInsert.push(wpId);
                        //handleVoteData(wpId);
                    }
                }
            }
             
            var length = waypointsToInsert.length;
            if(length > 0)
            {
                log("Local information for " + length + " found for this map region.");
                getVotes(waypointsToInsert);
            }
             
            lastBounds = currBounds;
            lastZoom = currentZoom;
        }
         
        //Constructor
        init();
         
    }
     
    var localCacheHandler = function(){
        var activeTimeOutId = new Object();
        var init = function(){ 
            voteData=JSON.parse(getValue("cachedVoteData", "{ }"));
            log("cached voteData loaded.");
            cacheData=JSON.parse(getValue("cachedCacheData", "{ }"));
            log("cached cacheData loaded.");
             
            var now = new Date();          
            var lastTime;
             
            //Get the time of the last GC
            var lastGarbageCollectionString = getValue("lastGC", "");
            if (lastGarbageCollectionString == "") {
                lastTime = new Date();
                setValue("lastGC", (lastTime.toString()));
            }
            else {
                lastTime = new Date(lastGarbageCollectionString);
            }
 
            //Do the garbageCollection if the it is necessary (garbageCollectionFrequency)
            if ((now.getTime() - lastTime.getTime() ) / 3600000 > garbageCollectionFrequency) {
                //Run the garbageCollection delayed
                myWindow.setTimeout(doGarbageCollection, 500);
            }
        }
         
        //Cleans up the local caches - remove expired elements and set the timestamp for the last GC to now
        var doGarbageCollection = function()
        {
            log("GarbageCollection started");
            var now = new Date();
            var lastUpdate;
            var itemsToKeep = new Object();
 
            for (waypoint in voteData) {
                lastUpdate = new Date(voteData[waypoint].date);
 
                if ((now.getTime() - lastUpdate.getTime()) / 3600000 <= localVoteLifeTime) {
                    itemsToKeep[waypoint] = voteData[waypoint];
                }
            }
 
            voteData = itemsToKeep;
             
            itemsToKeep = new Object();
 
            for (waypoint in cacheData) {
                lastUpdate = new Date(cacheData[waypoint].date);
 
                if ((now.getTime() - lastUpdate.getTime()) / 3600000 <= localCacheLifeTime) {
                    itemsToKeep[waypoint] = cacheData[waypoint];
                }
            }
 
            cacheData = itemsToKeep;
             
            //Save local caches
            localSaveLocalCaches("voteData");
            localSaveLocalCaches("cacheData");
            setValue("lastGC", (now.toString()));
 
            log("GarbageCollection finished. Next run in " + garbageCollectionFrequency + " hours.");
        }
         
        var localSaveLocalCaches = function(name){
            if (browserType == "FireFox") {
                //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation        
                setTimeout(function () {
                    saveLocalCachesNow(name);
                }, 0);
            }          
            else {
                saveLocalCachesNow(name);
            }      
        }
         
        this.saveLocalCachesDelayed = function(name)
        {
            clearTimeout(activeTimeOutId[name]);       
            var functionWorkaround = this.saveLocalCaches;
            activeTimeOutId[name] = setTimeout(function() {functionWorkaround(name);}, 500);
        }
         
        this.saveLocalCaches = function(name){ 
            localSaveLocalCaches(name);
        }
         
        var saveLocalCachesNow = function(name){   
            if(name=="voteData") {
                setValue("cachedVoteData", JSON.stringify(voteData));
                log("cached voteData saved.");
            }
            else if(name=="cacheData") {
                setValue("cachedCacheData", JSON.stringify(cacheData));
                log("cached cacheData saved.");
            }
        }
         
        this.clearAllLocalCaches = function(){
            voteData = new Object();
            cacheData = new Object();
            localSaveLocalCaches("voteData");
            localSaveLocalCaches("cacheData");
        }
         
        //Constructor
        init();
    }  
     
    var gcPersonalisationFixConnector = function(){
        var gcPersoFixCon = null;
        var gcPersoFixInternal = null;
         
        var init = function(){ 
            if (browserType == "FireFox") {
                //Hack for FF-Problem: http://wiki.greasespot.net/Greasemonkey_access_violation        
                setTimeout(function () {
                    gcPersoFixInternal = new apiObject("GCPersonalisationFix", handleRemoveCache, initStep2);
                }, 0);
            }          
            else {
                gcPersoFixInternal = new apiObject("GCPersonalisationFix", handleRemoveCache, initStep2);
            }          
        }
         
        var initStep2 = function(){
            if(gcPersoFixInternal.isConnected()){
                gcPersoFixCon = gcPersoFixInternal;
                 
                if(mapIconControl){
                    mapIconControl.onIconAdd(onIconAddHandler);
                }
                 
                reInit();
            }      
        }
         
        var onIconAddHandler = function(wpId){
            gcPersoFixCon.checkVisibility(wpId);
        }
         
        this.checkVisibility = function(wpId){
            if(gcPersoFixCon != null){             
                return gcPersoFixCon.checkVisibility(wpId);
            }
        }
         
        var handleRemoveCache = function(wpId){
            removeCache(wpId, 0);
        }
         
        this.loaded = function(){
            return gcPersoFixCon != null;
        }
         
        this.removeConnection = function(){
            gcPersoFixCon = null;
            setValue("apiKey_"+"GCPersonalisationFix", "");
            setValue("authKey_"+"GCPersonalisationFix", "");
        }
         
        //An object for API access -> used for comunication with GCPersonalisationFix
        var apiObject= function (name, handleRemoveCache, initStep2) { 
            this.name= name;
            var apiKey = getValue("apiKey_"+name, "");
            var authKey = getValue("authKey_"+name, "");
            var isCacheVisiblePort = null;
             
            var init = function(){
                window.addEventListener('message', handleConnect, false);
                if(apiKey != "" && authKey != ""){
                    window.postMessage(JSON.stringify({"apiKey": apiKey, "service": "isCacheVisible"}),'http://www.geocaching.com');
                }
                else if(apiKey == "" && authKey == ""){
                    //Try to register              
                    window.postMessage(JSON.stringify({"apiKey": "", "authKey": "", "service":"register"}),'http://www.geocaching.com');
                }
            }
             
            var handleConnect = function(event){
                if(event.origin == 'http://www.geocaching.com'){           
                    var data = JSON.parse(event.data);
                     
                    if(data.service.indexOf("Answer") != -1){
                        if(isCacheVisiblePort == null && data.service && data.service == "isCacheVisibleAnswer" && event.ports && event.ports.length == 1 && data.authKey && data.authKey == authKey){
                            event.ports[0].addEventListener('message', handleIsCacheVisibleMessage, false);
                            isCacheVisiblePort = event.ports[0];
                            event.ports[0].start();
                             
                            initStep2();
                        }
                        else if(browserType == "FireFox" && isCacheVisiblePort == null && data.service && data.service == "isCacheVisibleAnswer" && data.authKey && data.authKey == authKey){
                            isCacheVisiblePort = new Object(); //dummy
                            initStep2();                           
                        }
                        else if(browserType == "FireFox" && data.service == "isCacheVisibleDataAnswer"){
                            handleIsCacheVisibleMessage(event);
                        }
                        else if(data.service && data.service == "registerAnswer" && data.apiKey && data.apiKey != "" && data.authKey && data.authKey != ""){
                            if(confirm(tl("An other script wants access to GCVote.\nAllow?"))){
                                apiKey = data.apiKey;
                                authKey = data.authKey
                                setValue("apiKey_"+name, apiKey);          
                                setValue("authKey_"+name, authKey);
                                 
                                window.postMessage(JSON.stringify({"apiKey": apiKey, "service": "isCacheVisible"}),'http://www.geocaching.com');                       
                            }
                        }
                    }
                }
            }
             
            this.checkVisibility = function(wpId){
                if(isCacheVisiblePort && browserType != "FireFox"){
                    isCacheVisiblePort.postMessage(JSON.stringify({"apiKey": apiKey, "wpId":wpId}));
                }
                else if(browserType == "FireFox"){
                    window.postMessage(JSON.stringify({"service":"isCacheVisibleData", "apiKey": apiKey, "wpId":wpId}), 'http://www.geocaching.com');                      
                }
            }
             
            var handleIsCacheVisibleMessage = function(event){
                var data = JSON.parse(event.data);
                if(!data.isVisible){
                    handleRemoveCache(data.wpId);      
                }              
            }
             
            this.isConnected=function() {
                return isCacheVisiblePort != null;
            }
             
            this.removeConnection = function(){
                isCacheVisiblePort = null;
                var apiKey = "";
                setValue("apiKey_"+name, apiKey);
                var authKey = "";
                setValue("authKey_"+name, authKey);
            }
             
            //Constructor
            init();
        }
         
        //Constructor  
        init();
    }
     
    //Constructor newMapHandler
    init();
};
 
     
 
 
 
//START
 
log("start");
 
if (typeof(opera) !== "undefined"){
    window.addEventListener('DOMContentLoaded', main, true);
}
else if(typeof(chrome) !== "undefined"){
	var localStorageCache = {};
	
	chrome.runtime.sendMessage({"getAllValues": ""}, function(data){
		if(typeof(data) !== "undefined"){
			localStorageCache = data;
		}
		
		main();
	});	
}
else {
	localStorageCache = {};
    main();
}