Chess.com Favicon Alerts

Add number of games waiting to favicon

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

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

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

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

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

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

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

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

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

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

// ==UserScript==
// @name           Chess.com Favicon Alerts
// @description    Add number of games waiting to favicon
// @version        0.8
// @author         Jim Farrand
// @author         Peter Wooley (Original GMail Favicon script)
// @license        MIT
// @namespace      http://xyxyx.org/
// @include        https://www.chess.com/*
// @include        http://www.chess.com/*
// @grant          GM_getValue
// @grant          GM_setValue
// @grant          GM_registerMenuCommand
// ==/UserScript==

if(typeof GM_getValue === "undefined") {
    function GM_getValue(name, fallback) {
        return fallback;
    }
}

var titleNotificationConfigKey = 'titleNotificationEnabled';
var debuggingConfigKey = 'debuggingEnabled';
var autoReloadConfigKey = 'autoReloadEnabled';
var lastCountKey = 'lastCount';
var lastCountUpdateTimeKey = 'lastCountUpdateTime';
var lastCountChangeTimeKey = 'lastCountChangeTime';
var flashIconForNewKey = 'flashIconEnabled';

// Register GM Commands and Methods
if(typeof GM_registerMenuCommand !== "undefined") {
    var setTitleNotification = function(state) {
        console.log("Setting title notifications: " + state);
        GM_setValue(titleNotificationConfigKey, state);
    };

    var setDebugging = function(state) {
        console.log("Setting debugging: " + state);
        GM_setValue(debuggingConfigKey, state);
    };


    var setAutoReload = function(state) {
        console.log("Setting auto-reload: " + state);
        GM_setValue(autoReloadConfigKey, state);
    }
    
    var setFlashIcon = function(state) {
        console.log("Setting flash icon: " + state);
        GM_setValue(flashIconForNewKey, state);
    }

    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Title Notifications On", 
        function() { setTitleNotification(true) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Title Notifications Off", 
        function() { setTitleNotification(false) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Debugging On", 
        function() { setDebugging(true) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Debugging Off", 
        function() { setDebugging(false) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Auto Reload On", 
        function() { setAutoReload(true) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Auto Reload Off", 
        function() { setAutoReload(false) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Flash Icon After Change On", 
        function() { setFlashIcon(true) });
    GM_registerMenuCommand( "Chess.com Favicon Alerts > Set Flash Icon After Change Off", 
        function() { setFlashIcon(false) });
}

if(!window.frameElement) {
    new ChessDotComFavIconAlerts();
}

function ChessDotComFavIconAlerts() {
    var self = this;

    // PRIVATE VARIABLES AND METHODS

    // The URL attached to the little hand icon, with the link containing the number of games
    var gotoReadyGameURL = "http://www.chess.com/echess/goto_ready_game";

    // Min time to wait after suspected suspend before refreshing
    var reloadRandomizationMin  = 20 * 1000;
    
    // Random time to wait after suspected suspend before refreshing, in addition to reloadAfterSuspendMinimum
    var reloadRandomizationMax  = 40 * 1000;

    var searchElement;
    var iconCanvas;

    var isDebugging = function() {
        return false || GM_getValue(debuggingConfigKey, false);
    }

    var getLastCount = function() {
        return GM_getValue(lastCountKey);
    }

    var getLastCountUpdateTime = function() {
       return GM_getValue(lastCountUpdateTimeKey);
    }

	var getLastCountChangeTime = function() {
       return GM_getValue(lastCountChangeTimeKey);
    }
	
    var setLastCount = function(value) {
        GM_setValue(lastCountKey, value);
    }

    var setLastCountUpdateTime = function(value) {
        GM_setValue(lastCountUpdateTimeKey, value);
    }

	
    var setLastCountChangeTime = function(value) {
        GM_setValue(lastCountChangeTimeKey, value);
    }

	
    var isAutoReloadEnabled = function() {
       return false || GM_getValue(autoReloadConfigKey, false);
    }

    var isFlashIconEnabled = function() {
       return false || GM_getValue(flashIconForNewKey, false);
    }

	var isTitleUpdatedEnabled = function() {
		return false || GM_getValue(titleNotificationConfigKey, false);
	}
	
    var head = window.document.getElementsByTagName('head')[0];
 
    // Element that contains the count
    var findSearchElement = function() {
        var searchElement = document.getElementById("topright");;
        if (isDebugging()) { console.log("findSearchElement: " + searchElement); }
        return searchElement;
    }


    var setIcon = function(icon) {
        var links = head.getElementsByTagName("link");
        for (var i = 0; i < links.length; i++) {
            if ((links[i].rel == "shortcut icon" || links[i].rel=="icon") && links[i].href != icon) {
                head.removeChild(links[i]);
            } else if(links[i].href == icon) {
                return;
            }
        }

        var newIcon = document.createElement("link");
        newIcon.type = "image/png";
        newIcon.rel = "shortcut icon";
        newIcon.href = icon;

        head.appendChild(newIcon);

        setTimeout(function() {
            if (isDebugging()) { console.log("Timeout function"); }

            var shim = document.createElement('iframe');
            shim.width = shim.height = 0;
            document.body.appendChild(shim);
            shim.src = "icon";
            document.body.removeChild(shim);

            if (isDebugging()) { console.log("Timeout function done"); }
        }, 1000);
    }

    var getIconCanvas = function() {
        if(!iconCanvas) {
            iconCanvas = document.createElement('canvas');
            iconCanvas.height = iconCanvas.width = 16;

            var ctx = iconCanvas.getContext('2d');

            for (var y = 0; y < iconCanvas.width; y++) {
                for (var x = 0; x < iconCanvas.height; x++) {
                    if (self.pixelMaps.icons.unread[y][x]) {
                        ctx.fillStyle = self.pixelMaps.icons.unread[y][x];
                        ctx.fillRect(x, y, 1, 1);
                    }
                }
            }
        }

        return iconCanvas;
    }

    var showCount = function() {
        // We could decide here whether to show the count or the other icon
        return true;
    }

    // TODO: This could be made abstract so that that this class can be more easily reused
    var getCount = function() {
        // Return the number of things
        if(searchElement) {
            var center;
            var topRightChildren = searchElement.childNodes;
            for (var i = 0; i < topRightChildren.length; i++) {
                var topRightChild = topRightChildren.item(i);
                if (topRightChild.tagName == "LI" && topRightChild.hasAttribute("class") && topRightChild.getAttribute("class") == "center") {
                    var centerChildren = topRightChild.childNodes;
                    for (var i = 0; i < centerChildren.length; i++) {
                        var centerChild = centerChildren.item(i);
                        if (centerChild.tagName == "A" && centerChild.hasAttribute("href") && centerChild.getAttribute("href") == gotoReadyGameURL) {
                            var result = centerChild.textContent;
                            if (isDebugging()) { console.log("getCount: " + result); }
                            return result;
                        }
                    }
                }
            }
            if (isDebugging()) { console.log("getCount: 0"); }
            return 0;
        }
    }
	
    this.construct = function() {		
        if (isDebugging()) { console.log("Creating ChessDotComFavIconAlerts"); }

        // PUBLIC  VARIABLES AND METHODS

        this.backgroundFillColour   = "#ff0000";
        this.backgroundBorderColour = "#990000";
        this.digitColour = "#ffffff";
        
        // How long must have passed without user input in this window before we reload the page?
        this.inactivityTimeout = 15 * 60  * 1000; // 15 minutes
        
        // How old must the data be before we reload the page?
		this.dataTimeout = 3 * 60  * 1000; // 3 minutes
		// Note that we might have received data from another tab/window, which is why there are seperate data/inactivity timeouts
        
        // How long to flash the icon for after it changes
        this.flashPeriod = 15 * 1000;
		
        // TODO: More things could be private
        this.icons = {
            // TODO: These are the same, and incorrectly named.
            read:   'data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAARCwAAEQsAAAAAAAAAAAAA////AP///wD///8AO4ZcPDuKYMw7i2HsN3xR8jZ2S/83d0z/N3dM9zd3TN83d0ytN3dMIP///wD///8A////AP///wD///8A////AD+SaP4+k2r/PpNq/zqEWv84d03/OHhN/zZ3S/83d0z/N3dM/zd3TO////8A////AP///wD///8A////AP///wA7iV7hPpNq/z6Tav8+jWT/N3hM/zh4Tf83d0z/N3dM/zh3Tf42dkvL////AP///wD///8A////AP///wD///8AO4heuj6Tav8+k2r/PpJq/zmAVv83d0z/N3dM/zh3Tf83d0z/NnZLm////wD///8A////AP///wD///8A////ADuGXCo7jGLhPpNq/z6Tav87hVv/OHdN/zd3TP84d037N3dMqjd3TBX///8A////AP///wD///8A////AP///wAAAAAAAAAAADuGXFw9kGf7PIlg/zh4Tf82dkvfNnZLGwAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAPYphzjyOZP83d0z/N3dMjwAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAADuIX6I/kmj/N3dL/zZ3S2UAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAA8h1+AP5Rq/zh5T/82d0tLAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAO4ddZT6Tav83fFH/NnZLOQAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAPYphzjyPZvg+k2r/PI5k/zd5Ttk4d02PAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAADuIX9o9kGf8PpNq/z2NZP84eE7kN3dMnQAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hlxFPpNq/z+Uav8+k2r/On9U/jZ3SyUAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAO4leij6Sav8+k2r/PpNq/zuHXv82d0tSAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAADuGXEFyr5L/wNzO/0mZc/87h13/N3dMIwAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAP4tifF2ee/9Vn3v+OYJYZQAAAAAAAAAAAAAAAP///wD///8A////AOAHAADgBwAA4AcAAOAHAADgBwAA+B8AAPw/AAD8PwAA/D8AAPw/AAD4HwAA+B8AAPgfAAD4HwAA+B8AAPw/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAARCwAAEQsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hVsCO4ddaDuGXKk5f1W+N3dN0jd3Teo3d03+N3dN/zd3Tf83d03+N3dN6jd3TdI3d02sN3dNejd3TTs3d00BAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA7hVsKPIlftj2QZvw+k2n/PpNp/z6Taf88iF7/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3TeE3d013N3dNBf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AD2MYuY+k2n/PpNp/z6Taf8+k2n/PpNp/z6SaP83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d02v////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8APpJo/z6Taf8+k2n/PpNp/z6Taf8+k2n/PY9l/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3TfT///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA7iF6WPpJo/z6Taf8+k2n/PpNp/z6Taf89kWf/OH5U/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d032N3dNW////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAA7hlxVPpJo/z6Taf8+k2n/PpNp/z6Taf8+kmj/OHpQ/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN9jd3TS0AAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAD2MYuY+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf87hVv/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dNpwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAPI5k9D6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/z2MYv83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03LAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAA7h12BPpJo/z6Taf8+k2n/PpNp/z6Taf8+k2n/PZBm/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN9Dd3TU4AAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hlwwPIpgwj2QZvw+k2n/PpNp/z6Taf8+k2n/N3hO/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN4zd3TYI3d00ZAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAO4VbCDuIXpM+kmj+PpNp/z6Taf84fVP/N3dN/zd3Tf83d03/N3dN8Dd3TVo3d00DAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7U+k2n/PpNp/zmBV/83d03/N3dN/zd3Tf83d012AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ZcSz6Taf8+k2n/OoVb/zd3Tf83d03/N3dN/zd3TSkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7hVsCPpJo/z6Taf88iV//N3dN/zd3Tf83d031N3dNAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9j2X3PpNp/zyNY/83d03/N3dN/zd3TdIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2MYuY+k2n/PZFn/zd3Tf83d03/N3dNrwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPIth1D6Taf8+k2n/N3lP/zd3Tf83d02WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8imDFPpNp/z6Taf84fFL/N3dN/zd3TYUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7I+k2n/PpNp/zl/Vf83d03/N3dNcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPIhenT6Taf8+k2n/OoJY/zd3Tf83d01gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAA7hVslPIhenDyKYM08jmTxPpNp/z6Taf88jWP/OYFX/zd3TcQ3d02ON3dNYDd3TRMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAADyOZPM+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf8+k2n/OX9V/zd3Tf83d03/N3dNxgAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAPIlfuj6SaP4+k2n/PpNp/z6Taf8+k2n/PpNp/zyNY/84elD/N3dN/zd3TfI3d016AAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAO4VbBjyJX7o+k2n/PpNp/z6Taf8+kmj/OYBW/zd3Tf83d015N3dNAwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAA7hVslPZFn/j6Taf8+k2n/PpNp/z6Taf8+k2n/OH5U/zd3Te83d00TAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX6s+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf88jmT/N3dN/zd3TW0AAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAPIth2T6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf83e1H/N3dNmwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAA9i2HcPpNp/z6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/zh+VP83d02fAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7E+k2n/rdG//7TVxP9OnHX/PpNp/z6Taf8+k2n/OH1T/zd3TXIAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ZcLj6SaP6Twqv///////D28/9nqoj/PpNp/z6SaP84eU/0N3dNFwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4hekEaXbv/I4NT/+/38/5TDqv8+k2n/PIpg/jd3TVcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ddbTyNY+8+kmj/PpJo/zyNY+45gFZSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP8AAP/8AAA//AAAP/wAAD/8AAA//gAAf/4AAH/+AAB//gAAf/8AAP//wAP///AP///wD///8A////gf///4H///+B////gf///4H///+B///8AD///AA///wAP//+AH///gB///4Af//+AH///gB///4Af//+AH///wD///+B//',
            unread: 'data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAARCwAAEQsAAAAAAAAAAAAA////AP///wD///8AO4ZcPDuKYMw7i2HsN3xR8jZ2S/83d0z/N3dM9zd3TN83d0ytN3dMIP///wD///8A////AP///wD///8A////AD+SaP4+k2r/PpNq/zqEWv84d03/OHhN/zZ3S/83d0z/N3dM/zd3TO////8A////AP///wD///8A////AP///wA7iV7hPpNq/z6Tav8+jWT/N3hM/zh4Tf83d0z/N3dM/zh3Tf42dkvL////AP///wD///8A////AP///wD///8AO4heuj6Tav8+k2r/PpJq/zmAVv83d0z/N3dM/zh3Tf83d0z/NnZLm////wD///8A////AP///wD///8A////ADuGXCo7jGLhPpNq/z6Tav87hVv/OHdN/zd3TP84d037N3dMqjd3TBX///8A////AP///wD///8A////AP///wAAAAAAAAAAADuGXFw9kGf7PIlg/zh4Tf82dkvfNnZLGwAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAPYphzjyOZP83d0z/N3dMjwAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAADuIX6I/kmj/N3dL/zZ3S2UAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAA8h1+AP5Rq/zh5T/82d0tLAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAO4ddZT6Tav83fFH/NnZLOQAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAPYphzjyPZvg+k2r/PI5k/zd5Ttk4d02PAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAADuIX9o9kGf8PpNq/z2NZP84eE7kN3dMnQAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hlxFPpNq/z+Uav8+k2r/On9U/jZ3SyUAAAAAAAAAAP///wD///8A////AP///wD///8A////AAAAAAAAAAAAO4leij6Sav8+k2r/PpNq/zuHXv82d0tSAAAAAAAAAAD///8A////AP///wD///8A////AP///wAAAAAAAAAAADuGXEFyr5L/wNzO/0mZc/87h13/N3dMIwAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAP4tifF2ee/9Vn3v+OYJYZQAAAAAAAAAAAAAAAP///wD///8A////AOAHAADgBwAA4AcAAOAHAADgBwAA+B8AAPw/AAD8PwAA/D8AAPw/AAD4HwAA+B8AAPgfAAD4HwAA+B8AAPw/AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAARCwAAEQsAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hVsCO4ddaDuGXKk5f1W+N3dN0jd3Teo3d03+N3dN/zd3Tf83d03+N3dN6jd3TdI3d02sN3dNejd3TTs3d00BAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA7hVsKPIlftj2QZvw+k2n/PpNp/z6Taf88iF7/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3TeE3d013N3dNBf///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AD2MYuY+k2n/PpNp/z6Taf8+k2n/PpNp/z6SaP83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d02v////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8APpJo/z6Taf8+k2n/PpNp/z6Taf8+k2n/PY9l/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3TfT///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wA7iF6WPpJo/z6Taf8+k2n/PpNp/z6Taf89kWf/OH5U/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d032N3dNW////wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAA7hlxVPpJo/z6Taf8+k2n/PpNp/z6Taf8+kmj/OHpQ/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN9jd3TS0AAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAD2MYuY+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf87hVv/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dNpwAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAPI5k9D6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/z2MYv83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03LAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAA7h12BPpJo/z6Taf8+k2n/PpNp/z6Taf8+k2n/PZBm/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN9Dd3TU4AAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAA7hlwwPIpgwj2QZvw+k2n/PpNp/z6Taf8+k2n/N3hO/zd3Tf83d03/N3dN/zd3Tf83d03/N3dN4zd3TYI3d00ZAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAO4VbCDuIXpM+kmj+PpNp/z6Taf84fVP/N3dN/zd3Tf83d03/N3dN8Dd3TVo3d00DAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7U+k2n/PpNp/zmBV/83d03/N3dN/zd3Tf83d012AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ZcSz6Taf8+k2n/OoVb/zd3Tf83d03/N3dN/zd3TSkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7hVsCPpJo/z6Taf88iV//N3dN/zd3Tf83d031N3dNAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9j2X3PpNp/zyNY/83d03/N3dN/zd3TdIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2MYuY+k2n/PZFn/zd3Tf83d03/N3dNrwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPIth1D6Taf8+k2n/N3lP/zd3Tf83d02WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8imDFPpNp/z6Taf84fFL/N3dN/zd3TYUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7I+k2n/PpNp/zl/Vf83d03/N3dNcwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPIhenT6Taf8+k2n/OoJY/zd3Tf83d01gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAA7hVslPIhenDyKYM08jmTxPpNp/z6Taf88jWP/OYFX/zd3TcQ3d02ON3dNYDd3TRMAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAADyOZPM+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf8+k2n/OX9V/zd3Tf83d03/N3dNxgAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAPIlfuj6SaP4+k2n/PpNp/z6Taf8+k2n/PpNp/zyNY/84elD/N3dN/zd3TfI3d016AAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAO4VbBjyJX7o+k2n/PpNp/z6Taf8+kmj/OYBW/zd3Tf83d015N3dNAwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAA7hVslPZFn/j6Taf8+k2n/PpNp/z6Taf8+k2n/OH5U/zd3Te83d00TAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX6s+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf88jmT/N3dN/zd3TW0AAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAPIth2T6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/z6Taf83e1H/N3dNmwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAA9i2HcPpNp/z6Taf8+k2n/PpNp/z6Taf8+k2n/PpNp/zh+VP83d02fAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAADyJX7E+k2n/rdG//7TVxP9OnHX/PpNp/z6Taf8+k2n/OH1T/zd3TXIAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ZcLj6SaP6Twqv///////D28/9nqoj/PpNp/z6SaP84eU/0N3dNFwAAAAAAAAAAAAAAAAAAAAAAAAAA////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4hekEaXbv/I4NT/+/38/5TDqv8+k2n/PIpg/jd3TVcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO4ddbTyNY+8+kmj/PpJo/zyNY+45gFZSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wD///8A////AP///wD///8A////AP8AAP/8AAA//AAAP/wAAD/8AAA//gAAf/4AAH/+AAB//gAAf/8AAP//wAP///AP///wD///8A////gf///4H///+B////gf///4H///+B///8AD///AA///wAP//+AH///gB///4Af//+AH///gB///4Af//+AH///wD///+B//',
        };

        this.pixelMaps = {
            icons: {
                // TODO: Transparency
                'unread':
[["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#afc59b","#aac193","#6d9645","#c6d4bc","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#e1e8dc","#7ea159","#eef3e9","#67923a","#407119","#f5f8f7","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#b4c8a4","#59882a","#5c8a2e","#69933d","#507d29","#c7d4c1","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#f1f4f0","#598729","#69933e","#6c963e","#406f23","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#bcceac","#6a9342","#68933c","#608b39","#5b8149","#c1cfb9","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#7b9f5b","#5f8b35","#68933c","#638e39","#5b8247","#84a176","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#dce5d7","#5f8d2e","#3c6a23","#f6f8f5","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#c2d2b5","#618e30","#3b6924","#d8e1d3","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#b8cba7","#608d31","#3b6826","#c2d1bb","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#a9c192","#5d8932","#3f6c2a","#a2b897","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#fefeff","#608c35","#5e8939","#477232","#567e41","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#f7f9f7","#7da05c","#548324","#69943c","#5b853a","#4b7536","#497332","#38671f","#819f72","#ffffff","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#b0c59e","#5a882a","#69933d","#6c963e","#557f39","#4b7536","#4d7737","#4c7636","#36651d","#beceb7","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#bcceae","#5f8c31","#69933e","#66903d","#4a7436","#4c7636","#4d7737","#4c7636","#416e2a","#cdd8c7","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#40750c","#618d33","#68933b","#588238","#4b7536","#4c7636","#4b7535","#487331","#406d28","#2d5f14","#ffffff","#ffffff","#ffffff"],["#ffffff","#ffffff","#ffffff","#f3f6f2","#a8bf90","#799e58","#5b8346","#4b7535","#4c7636","#587f43","#759564","#a8bc9d","#ffffff","#ffffff","#ffffff","#ffffff"]]
                },
                numbers: [
                    [
                            [0,1,1,0],
                            [1,0,0,1],
                            [1,0,0,1],
                            [1,0,0,1],
                            [0,1,1,0]
                    ],
                    [
                            [0,1,0],
                            [1,1,0],
                            [0,1,0],
                            [0,1,0],
                            [1,1,1]
                    ],
                    [
                            [1,1,1,0],
                            [0,0,0,1],
                            [0,1,1,0],
                            [1,0,0,0],
                            [1,1,1,1]
                    ],
                    [
                            [1,1,1,0],
                            [0,0,0,1],
                            [0,1,1,0],
                            [0,0,0,1],
                            [1,1,1,0]
                    ],
                    [
                            [0,0,1,0],
                            [0,1,1,0],
                            [1,0,1,0],
                            [1,1,1,1],
                            [0,0,1,0]
                    ],
                    [
                            [1,1,1,1],
                            [1,0,0,0],
                            [1,1,1,0],
                            [0,0,0,1],
                            [1,1,1,0]
                    ],
                    [
                            [0,1,1,0],
                            [1,0,0,0],
                            [1,1,1,0],
                            [1,0,0,1],
                            [0,1,1,0]
                    ],
                    [
                            [1,1,1,1],
                            [0,0,0,1],
                            [0,0,1,0],
                            [0,1,0,0],
                            [0,1,0,0]
                    ],
                    [
                            [0,1,1,0],
                            [1,0,0,1],
                            [0,1,1,0],
                            [1,0,0,1],
                            [0,1,1,0]
                    ],
                    [
                            [0,1,1,0],
                            [1,0,0,1],
                            [0,1,1,1],
                            [0,0,0,1],
                            [0,1,1,0]
                    ],
            ]
        };

        this.timer = setInterval(this.poll, 100);
        this.poll();

        return true;
    }

    // This breaks unless the parameter is a string
    this.drawNumberedIcon = function(number) {
        if (! (number instanceof String) ) {
            number = number.toString();
        }
        
        if(!self.textedCanvas) {
                self.textedCanvas = [];
        }

        if(!self.textedCanvas[number]) {
			if (isDebugging()) { console.log("drawNumberedIcon(" + number + ")"); }
            var iconCanvas = getIconCanvas();
            var textedCanvas = document.createElement('canvas');
            textedCanvas.height = textedCanvas.width = iconCanvas.width;
            var ctx = textedCanvas.getContext('2d');
            ctx.drawImage(iconCanvas, 0, 0);

            ctx.fillStyle = this.backgroundFillColour;
            ctx.strokeStyle = this.backgroundBorderColour;
            ctx.strokeWidth = 1;

            var count = number.length;
            var bgHeight = self.pixelMaps.numbers[0].length;
            var bgWidth = 0;
            var padding = count > 2 ? 0 : 1;

            for(var index = 0; index < count; index++) {
                bgWidth += self.pixelMaps.numbers[number[index]][0].length;
                if(index < count-1) {
                    bgWidth += padding;
                }
            }
            bgWidth = bgWidth > textedCanvas.width-4 ? textedCanvas.width-4 : bgWidth;

            ctx.fillRect(textedCanvas.width-bgWidth-4,2,bgWidth+4,bgHeight+4);

            var digit;
            var digitsWidth = bgWidth;
            for(var index = 0; index < count; index++) {
                digit = number[index];
                if (self.pixelMaps.numbers[digit]) {
                    var map = self.pixelMaps.numbers[digit];
                    var height = map.length;
                    var width = map[0].length;

                    ctx.fillStyle = this.digitColour;

                    for (var y = 0; y < height; y++) {
                        for (var x = 0; x < width; x++) {
                            if(map[y][x]) {
                                ctx.fillRect(14- digitsWidth + x, y+4, 1, 1);
                            }
                        }
                    }

                    digitsWidth -= width + padding;
                }
            }

            ctx.strokeRect(textedCanvas.width-bgWidth-3.5,2.5,bgWidth+3,bgHeight+3);

            self.textedCanvas[number] = textedCanvas;

            if (isDebugging()) { console.log("drawNumberedIcon: Done making icon"); }
        }

        return self.textedCanvas[number];
    }

    var resetTimer = function(init) {
        var time = new Date().getTime();
        self.lastActivity = time;
    }

    this.poll = function() {

    
		var lastCount = getLastCount();
		var time = new Date().getTime();
		var count;
		
		if (self.foundCountAlready) {
			count = lastCount;
			
			if (isAutoReloadEnabled()) {	
				// TODO: Maybe we shouldn't do this on explorer, analysis board, and a few other places
				
                var lastCountUpdateTime = getLastCountUpdateTime();				

                var refreshTime = lastCountUpdateTime + self.dataTimeout;
				
                if (self.lastActivity) {
                    var inactivityRefreshTime = self.lastActivity + self.inactivityTimeout;
                    if (inactivityRefreshTime > refreshTime) {
                        refreshTime = inactivityRefreshTime;
                    }
                }
                
                if (self.noReloadBefore) {
                    if (self.noReloadBefore > refreshTime) {
                        refreshTime = self.noReloadBefore;
                    } else {
						// Some activity happened since this was set, so clear it and pick a new one next time
						self.noReloadBefore = undefined;
					}
                }
			     
                var time = new Date().getTime();
                if (isDebugging()) {
                    var d = new Date(refreshTime);
                    var formattedTime = d.getUTCHours() + ":" + (d.getUTCMinutes() < 10 ? "0" : "") + d.getUTCMinutes();
					if (self.noReloadBefore) {
						formattedTime += ":" + (d.getUTCSeconds() < 10 ? "0" : "") + d.getUTCSeconds()
					} else {
						formattedTime += " (ish)";
					}
                    if (!self.lastDebugTime || self.lastDebugTime != formattedTime) {
						self.lastDebugTime = formattedTime;
						console.log("poll: Will reload page at " + formattedTime);
                    }
                }
			
                if (time > refreshTime) {
                    if (isDebugging()) { console.log("poll: Page reload timeout passed after " + ((self.pageLoadTime - time)/1000) + "sec"); }
				
				    if ( self.noReloadBefore ) {
						// We already did a random period, and passed it, so we can reload now
						self.noReloadBefore = undefined; // Probably unneeded, we'll lose this after the reload
                        location.reload();
				    } else {
				        // If we massively overshot the refresh time, it's possible that this machine was suspended
				        // (which is why we didn't get woken up)
				        // That can be a problem - often the CPU becomes active several seconds before the network, and so if we
				        // immediately reload, we will get an error

						// Also, we don't want tabs all piling up and reloading at the same moment
						
				        // We therefore wait some extra random time before refreshing
				        self.noReloadBefore = time + reloadRandomizationMin + Math.ceil((reloadRandomizationMax-reloadRandomizationMin)*Math.random());
				    }
				

                }
            }
		} else {
			searchElement = findSearchElement();
			
			if(!searchElement) {
				if (isDebugging()) { console.log("poll: Search element not found, using last value"); }
				count = lastCount;
			} else {
				if (isDebugging()) { console.log("poll: Found search element"); }
				var lastCountUpdateTime = getLastCountUpdateTime();	
				if (lastCountUpdateTime && lastCountUpdateTime > time) {
					if (isDebugging()) { console.log("poll: Stored count more recent"); }
					// Some other page got a more up to date value
					count = lastCount;
				} else {
					count = getCount();
					if (count !== lastCount) {
						if (isDebugging()) { console.log("Count updated to: " + count); }
						setLastCount(count);
						setLastCountChangeTime(time);
					}
					
					setLastCountUpdateTime(time);
				}
				
				self.foundCountAlready = true;
			}
		}
	
		var displayCountIcon;
		if (count == 0 || !showCount()) {
			displayCountIcon = false;
		} else {
			var lastCountChangeTime = getLastCountChangeTime();
			if (isFlashIconEnabled() && (time - lastCountChangeTime) < self.flashPeriod && (!self.lastActivity || self.lastActivity < lastCountTime)) {
				displayCountIcon = (0 == (Math.floor(time / 1000) % 2)); 
			} else {
				displayCountIcon = true;
			}
		}
				
		if(displayCountIcon) {
			setIcon(self.drawNumberedIcon(count).toDataURL('image/png'));
		} else {
			setIcon(self.icons.read);
		}
		
		if (isTitleUpdatedEnabled()) {
			if (count === 0) {
				document.title = self.pageTitle;
			} else {
				document.title = "(" + count + ") " + self.pageTitle;
			}
		}
    }


    this.toString = function() { return '[object ChessDotComFavIconAlerts]'; } 
		
	this.pageLoadTime = new Date().getTime();
	this.pageTitle = document.title;
	
    window.addEventListener('mousemove', resetTimer);
    window.addEventListener('click', resetTimer);
	window.addEventListener('onkeypress', resetTimer);
	
	if (isDebugging()) { console.log("Done creating ChessDotComFavIconAlerts"); } ;
	
    return this.construct();
}