Cheggit - Tag Desirability Management

By Signe Last update Sep 30, 2011 — Installed 11,986 times.

There are 27 previous versions of this script.

Add Syntax Highlighting (this will take a few seconds, probably freezing your browser while it works)

// ==UserScript==
// @name           Cheggit Tag Desirability Management
// @namespace      http://www.cothlamadh.net/greasemonkey
// @description    Highlights tags that you would like to be notified of, colors tags that you want to be warned of, and completely removes torrents containing tags that you've marked undesirable.
// @include        http://cheggit.net/users.php?userid=*
// @include        http://cheggit.net/browsetorrents.php*
// @include        http://cheggit.net/torrents.php?torrentid=*
// @include        http://cheggit.net/tags.php*
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js
// @require        http://userscripts.org/scripts/source/52251.user.js
// @version        1.1.20110929
// ==/UserScript==

if (typeof autoUpdate != 'undefined') {
    autoUpdate(38136, "1.1.20110929");
}

/**
 * VERSION HISTORY
 *
 * 1.1.20110929
 *			Move the location of the Favorites box so that it's better represented on user and torrent pages
 * 1.1.20110926
 *			Updates to adapt to site layout changes
 * 1.1.20110713
 *      Reverting to jQuery 1.3 due to unknown jQuery error in 1.6
 * 1.1.20110706
 *      Upgrade jQuery to 1.6 for performance gains
 * 1.1.20110416
 *      Hide flagged torrents, consolidate separate addClass/removeClass calls into single lines
 * 1.1.20110414
 *      Fix the sidebar.  The ID of the box that was being replaced changed during a site update
 * 1.1.20101222
 *      Add 'show hidden' functionality, which can be useful when browsing category pages, or when you want to see what you're missing.
 * 1.1.20100627.1
 *      Convert the sidebar user links into userbrowse instead of tags searches
 * 1.1.20100627
 *      Handling for null tags
 * 1.1.20100619
 *      Further fixes for Chrome.  Stupid browser.
 * 1.1.20100618
 *      Override GM_getValue if the defaultValue test fails (Chrome)
 *      Fix selector for torrent title in good_user case
 * 1.1.20100610
 *      Modify selectors to assist with performance
 * 1.1.20100609.1
 *      Correct over-bolding of good_users tag text
 * 1.1.20100609
 *      Significant rewrite to remove old crufty code
 *      Add Favorite User support
 * 1.1.20100514
 *      Add Opera Support
 * 1.1.20100212
 *      Modify the jQuery include to use 1.3.x - 1.4 breaks the script for some reason
 * 1.1.20100105
 *      Fix function name
 * 1.1.20100104.3:
 *      Modify Chrome support:  Chrome users *MUST* download this script from http://www.cothlamadh.net/greasemonkey/38136.user.js
 * 1.1.20100104.2:
 *      Fix support for user profile pages
 * 1.1.20100104.1:
 *      Add JQuery
 *      Add Chrome Support
 * 1.1.20100104:
 *      Add AutoUpdate Script
 * 1.0.20091228:
 *      Add some statistics about how many tags are in use, and how much preference space they take up
 * 1.0.20091227:
 *      Make the favorites list in the sidebar collapsable, defaulting to collapsed.
 *      Add highlighting to the tags page.
 * 1.0.20090619:
 *      Slightly different behavior for Warn tags
 *      If a torrent has a Warn tag, and no Good tags, then it's hidden just as if it were a Bad tag.
 *      If it has a Warn and a Good, it's displayed normally with the tags highlighted.
 */

/**
 * Include JQuery dynamically (Opera Support)
 */
if (typeof $ != 'function') {
    // create script
    var newscript = document.createElement('script');
    newscript.setAttribute('type', 'text/javascript');
    newscript.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js');
    document.getElementsByTagName('head')[0].appendChild(newscript);
}


/**
 * Make sure that the GM_* functions work correctly
 * if they don't (Chrome) unset them so that we define them ourselves.
 */
if (typeof GM_getValue == 'function' && GM_getValue('foobarxyz', '123abc') != '123abc') {
    delete GM_getValue;
    delete GM_setValue;
}

/**
 *  Add GM_* function aliases if they're not already present
 */
if (typeof GM_addStyle != 'function') {
    GM_addStyle = function(css) {
        var style = document.createElement('style');
        style.textContent = css;
        document.getElementsByTagName('head')[0].appendChild(style);
    }
}

// Chrome was returning an undefined value instead of the passed default, hence the override if the default value test fails
if ((typeof GM_getValue != 'function' || GM_getValue('donotdefine', '123abc') != '123abc') && typeof localStorage.getItem == 'function') {
    GM_getValue = function(name, defaultValue) {
        var value = localStorage.getItem(name);
        if (value == 'false') {
            return false;
        }
        return (value || defaultValue);
    }
}

if (typeof GM_setValue != 'function' && typeof localStorage.setItem == 'function') {
    GM_setValue = function(name, value) {
        localStorage.setItem(name, value);
    }
}

if (typeof GM_log != 'function' && typeof console.log == 'function') {
    function GM_log(message) {
        console.log(message);
    }
}

Array.prototype.unique = function() {
    var a = [];
    var l = this.length;
    for (var i = 0; i < l; i++) {
        for (var j = i + 1; j < l; j++) {
            // If this[i] is found later in the array
            if (this[i] === this[j]) {
                j = ++i;
            }
        }
        a.push(this[i]);
    }
    return a;
};

Array.prototype.nonempty = function() {
    var a = [];
    var l = this.length;
    for (var i = 0; i < l; i++) {
        if (this[i].length != 0) {
            a.push(this[i]);
        }
    }
    return a;
}

function tdmDebug(str) {
    if (debug) {
        GM_log(str);
    }
}

function saveList(name, list) {
    var i = 0;
    GM_setValue(name, list.nonempty().unique().sort().join(" "));
}

function addListEntry(name, list, tags) {
    var tmp = tags.split(" ");
    for(var i = 0; i < tmp.length; i++) {
        var tag = tmp[i];
        if (tag.length > 0) {
            if (list.indexOf(tag) < 0) {
                list.push(tag);
                saveList(name, list);
            }
        }
    }
}

function removeListEntry(name, list, tag) {
    var idx = list.indexOf(tag);
    if (list.indexOf(tag) >= 0) {
        list.splice(idx, 1);
        saveList(name, list);
    }
}

function isEntry(list, entry) {
    return list.indexOf(entry) >= 0;
}

function createImage(img_data) {
    var img_element = document.createElement('img');
    img_element.setAttribute("src", img_data);
    img_element.setAttribute("style", "padding-right: 6px;");
    img_element.setAttribute("class", "cheggitTagHighlight");
    return img_element;
}

function getList(type, style) {
    if (type == 'good') {
        if (style == 'tags') {
            list = good_tags;
        } else if (style == 'users') {
            list = good_users;
        }
    } else if (type == 'warn') {
        if (style == 'tags') {
            list = warn_tags;
        } else if (style == 'users') {
            list = warn_users;
        }
    } else if (type == 'bad') {
        if (style == 'tags') {
            list = bad_tags;
        } else if (style == 'users') {
            list = bad_users;
        }
    }
    return list;
}

function addImage(type, style, tag, link) {
    var list = getList(type, style);

    var i_new;

    if (style == 'tags') {
        var classType = 'tag';
    } else if (style == 'users') {
        var classType = "user";
    }

    if (type == 'good') {
        i_new = createImage(img_green_minus);
    } else if (type == 'warn') {
        i_new = createImage(img_yellow_minus);
    } else if (type == 'bad') {
        i_new = createImage(img_red_minus);
    }
    $(i_new).bind('click', removeImageEvent(type, style, tag, link));

    $(link).siblings().remove('img');

    $(link).before(i_new);
    $(link).attr("class", classType + " " + type + "tdm");
}

function resetImages(style, tag, link) {

    var types = ['good', 'warn', 'bad'];
    // Get the class name from the style (trim the plural s)
    var classType = style.substr(0, style.length - 1);

    // Remove the existing image links
    $(link).siblings().remove('img');

    for (var i = 0; i < types.length; i++) {
        var type = types[i];
        var list = getList(type, style);

        var i_new;
        if (type == 'good') {
            i_new = createImage(img_green_plus);
        } else if (type == 'warn') {
            i_new = createImage(img_yellow_plus);
        } else if (type == 'bad') {
            i_new = createImage(img_red_plus);
        }

        $(i_new).bind('click', addImageEvent(type, style, tag, link));
        $(link).before(i_new);
    }
}

function addImageEvent(type, style, tag, link, img) {
    var list = getList(type, style);

    return function(e) {
        addListEntry(type + '_' + style, list, tag);
        addImage(type, style, tag, link);
    }
}

function removeImageEvent(type, style, tag, link, img) {
    var list = getList(type, style);

    return function(e) {
        $(link).attr('class', '');
        removeListEntry(type + '_' + style, list, tag);
        resetImages(style, tag, link);
    }
}

function addFavoritesBox() {
    var favoritesTdm = document.createElement('div');
    $(favoritesTdm).attr('id', 'favoritesTdm');
    $(favoritesTdm).addClass('menubox');
    $('#categoryFilterBox').before(favoritesTdm);

    $(favoritesTdm).html('<p class="title">Favorite Tags <small>[<a href="#" id="hidefavs">show</a>] [<a href="#" id="hidestats">stats</a>] [<a href="#" id="showhidden">show hidden</a>]</p>');

    /**
     * Generate some useful statistics about how many tags are in use, and how much space they take up
     */
    GM_addStyle('#favoritesStats td { padding: 3px; border: 1px solid; }');
    var favoritesStats = document.createElement('table');
    $(favoritesStats).attr('id', 'favoritesStats');
    $(favoritesStats).css({'display':'none','width':'auto','clear':'both','float':'none'});
    $(favoritesStats).html(
        "<tr><td>Good Tags:</td><td>" + good_tags.length + " tags</td><td>" + good_tags.join(' ').length + " bytes</td></tr>" +
        "<tr><td>Warn Tags:</td><td>" + warn_tags.length + " tags</td><td>" + warn_tags.join(' ').length + " bytes</td></tr>" +
        "<tr><td>Bad Tags:</td><td>" + bad_tags.length + " tags</td><td>" + bad_tags.join(' ').length + " bytes</td></tr>" +
        "<tr><td>Good Users:</td><td>" + good_users.length + " users</td><td>" + good_users.join(' ').length + " bytes</td></tr>" +
        "<tr><td>Warn Users:</td><td>" + warn_users.length + " users</td><td>" + warn_users.join(' ').length + " bytes</td></tr>" +
        "<tr><td>Bad Users:</td><td>" + bad_users.length + " users</td><td>" + bad_users.join(' ').length + " bytes</td></tr>"
    );
    $(favoritesTdm).append(favoritesStats);

    /**
     * Build the list of good/warn/bad users and insert it into the doc
     */
    var favoritesUsers = document.createElement('ul');
    $(favoritesUsers).attr('id', 'favoritesUsers');
    $(favoritesUsers).css('display', 'none');

    var newtext = ''
    newtext += "<li><b>Users:</b></li>";
    for (var i = 0; i < good_users.length; i++) {
        newtext += '<li><a class="tag goodtdm" href="/browseusers.php?username=' + good_users[i] +'">' + good_users[i] + '</a></li>';
    }
    for (var i = 0; i < warn_users.length; i++) {
        newtext += '<li><a class="tag warntdm" href="/browseusers.php?username=' + warn_users[i] +'">' + warn_users[i] + '</a></li>';
    }
    for (var i = 0; i < bad_users.length; i++) {
        newtext += '<li><a class="tag badtdm" href="/browseusers.php?username=' + bad_users[i] +'">' + bad_users[i] + '</a></li>';
    }
    newtext += "<li>&nbsp;</li>"; // Spacer
    $(favoritesUsers).html(newtext);
    $(favoritesTdm).append(favoritesUsers);

    /**
     * Build the list of good/warn/bad tags and insert it into the doc
     */
    var favoritesTags = document.createElement('ul');
    $(favoritesTags).attr('id', 'favoritesTags');
    $(favoritesTags).css('display', 'none');

    var newtext = ''
    newtext += "<li><b>Tags:</b></li>";
    for (var i = 0; i < good_tags.length; i++) {
        newtext += '<li><a class="tag goodtdm" href="browsetorrents.php?filter=' + good_tags[i] +'">' + good_tags[i] + '</a></li>';
    }
    for (var i = 0; i < warn_tags.length; i++) {
        newtext += '<li><a class="tag warntdm" href="browsetorrents.php?filter=' + warn_tags[i] +'">' + warn_tags[i] + '</a></li>';
    }
    for (var i = 0; i < bad_tags.length; i++) {
        newtext += '<li><a class="tag badtdm" href="browsetorrents.php?filter=' + bad_tags[i] +'">' + bad_tags[i] + '</a></li>';
    }
    $(favoritesTags).html(newtext);
    $(favoritesTdm).append(favoritesTags);

    /* Attach the show/hide functionality of the stats */
    $('#hidestats').bind('click', function(e) {
        $(favoritesStats).toggle('fast');
        e.preventDefault();
        return false;
    });

    /* Attach the show/hide functionality of the list */
    $('#hidefavs').bind('click', function(e) {
        $(favoritesUsers).toggle('fast', function() {
            if ($('#hidefavs').text() == 'hide') {
                $('#hidefavs').text('show');
            } else {
                $('#hidefavs').text('hide');
            }
        });
        $(favoritesTags).toggle('fast');
        e.preventDefault();
        return false;
    });
    
    /* Attach the show/hide hidden functionality of the list */
    $('#showhidden').bind('click', function(e) {
        if ($(this).text() == 'show hidden') {
            $('tr.warncell').removeClass('warncell').addClass('warncellshow');
            $('tr.badcell').removeClass('badcell').addClass('badcellshow');
            $(this).text('re-hide');
        } else {
            $('tr.warncellshow').addClass('warncell').removeClass('warncellshow');
            $('tr.badcellshow').addClass('badcell').removeClass('badcellshow');
            $(this).text('show hidden');
        }
        e.preventDefault();
        return false;
    });


}

function colorize() {

    if (typeof $ == 'undefined') {
        window.setTimeout(colorize, 200);
        return;
    }

    addFavoritesBox();

    /* Process the side-column user entries only on the main browse page */
    if (document.URL.indexOf('/browsetorrents.php') != -1) {
        var links = $('#favoritesUsers a');
        for (var i=0; i < links.length; i++) {
            var link = links[i];
            if (!link.firstChild) {
                continue;
            }

            var user = $(link).text();
            if (isEntry(good_users, user)) {
                addImage('good', 'users', user, link);
            }
            else if (isEntry(warn_users, user)) {
                addImage('warn', 'users', user, link);
            }
            else if (isEntry(bad_users, user)) {
                addImage('bad', 'users', user, link);
            } else {
                resetImages('users', user, link);
            }
            continue;
        }
    }

    /* Determine which page we are on so we can work with the correct side-colum tags list */
    var links = [];
    if (document.URL.indexOf('/torrents.php') != -1) {
        links = $('#tags a');
    } else if (document.URL.indexOf('/browsetorrents.php') != -1) {
        links = $('#favoritesTags a');
    }

    /* Process the side-column tag entries */
    for (var i=0; i < links.length; i++) {
        var link = links[i];
        if (!link.firstChild) {
            continue;
        }
        var tag = link.firstChild.nodeValue;
        if (isEntry(good_tags, tag)) {
            addImage('good', 'tags', tag, link);
        }
        else if (isEntry(warn_tags, tag)) {
            addImage('warn', 'tags', tag, link);
        }
        else if (isEntry(bad_tags, tag)) {
            addImage('bad', 'tags', tag, link);
        } else {
            resetImages('tags', tag, link);
        }
        continue;
    }

    /* Determine which page we are on so we can work with the correct username placement */
    var links = [];
    if (document.URL.indexOf('/torrents.php') != -1) {
        links = $('li:contains("Uploader") a[href*=users.php]');
    } else if (document.URL.indexOf('/users.php') != -1) {
        links = $('#userinfo p.title');
    }

    for (var i=0; i < links.length; i++) {
        var link = links[i];
        var user = $(link).text();
        if (isEntry(good_users, user)) {
            addImage('good', 'users', user, link);
        }
        else if (isEntry(warn_users, user)) {
            addImage('warn', 'users', user, link);
        }
        else if (isEntry(bad_users, user)) {
            addImage('bad', 'users', user, link);
        }
        else {
            resetImages('users', user, link)
        }
    }

    /* On the browse torrents and user pages, process tags in the main column */
    if (document.URL.indexOf('/browsetorrents.php') != -1 || document.URL.indexOf('/users.php') != -1) {
        var links = $('#torrentList a.tag');
        for (var i=0; i < links.length; i++) {
            var link = links[i];
            if (!link.firstChild) {
                continue;
            }
            var tagname = link.firstChild.nodeValue;
            if (isEntry(good_tags, tagname)) {
                $(link).addClass('goodtdm taglist');
                $(link.parentNode.parentNode.childNodes[1].firstChild).css('fontWeight', "bold");
                if (!$(link.parentNode.parentNode.parentNode).hasClass('badcell')) {
                    $(link.parentNode.parentNode.parentNode).removeClass("warncell").addClass("goodcell");
                }
            }
            else if (isEntry(warn_tags, tagname)) {
                $(link).addClass('warntdm taglist');
                if (!$(link.parentNode.parentNode.parentNode).hasClass('badcell') && !$(link.parentNode.parentNode.parentNode).hasClass('goodcell')) {
                    $(link.parentNode.parentNode.parentNode).addClass("warncell");
                }
            }
            else if (isEntry(bad_tags, tagname)) {
                $(link).addClass('badtdm taglist');
                $(link.parentNode.parentNode.parentNode).removeClass("goodcell").removeClass("warncell").addClass("badcell");
            }
        }
        
        /* Categorize 'flagged' torrents as bad */
        $('.hilite3').removeClass("goodcell").removeClass("warncell").addClass("badcell");

        var links = $('#torrentList tr td:last-child a[href^=users.php]');
        for (var i=0; i < links.length; i++) {
            var link = links[i];
            if (!link.firstChild) {
                continue;
            }
            var tagname = link.firstChild.nodeValue;
            if (isEntry(good_users, tagname)) {
                $(link).addClass('goodtdm taglist');
                $(link.parentNode.parentNode.childNodes[1].childNodes[1].firstChild).css('fontWeight', "bold");
                if (!$(link.parentNode.parentNode).hasClass('badcell')) {
                    $(link.parentNode.parentNode).removeClass("warncell").addClass("goodcell");
                }
            }
            else if (isEntry(warn_users, tagname)) {
                $(link).addClass('warntdm taglist');
                if (!$(link.parentNode.parentNode).hasClass('badcell') && !$(link.parentNode.parentNode).hasClass('goodcell')) {
                    $(link.parentNode.parentNode).addClass("warncell");
                }
            }
            else if (isEntry(bad_users, tagname)) {
                $(link).addClass('badtdm taglist');
                $(link.parentNode.parentNode).removeClass("goodcell").removeClass("warncell").addClass("badcell");
            }
        }
    }

    /* On the tags page, color tags in the main column */
    if (document.URL.indexOf('/tags.php') != -1) {
        var links = $('.cloud.tag');
        for (var i=0; i < links.length; i++) {
            var tagname = links[i].firstChild.nodeValue;
            if (isEntry(good_tags, tagname)) {
                links[i].style.color = 'green';
            }
            else if (isEntry(warn_tags, tagname)) {
                links[i].style.color = 'orange';
            }
            else if (isEntry(bad_tags, tagname)) {
                links[i].style.color = 'red';
            }
        }
    }
}

var img_green_plus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAABGdBTUEAAK/INwWK6QAAABl0'+
'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABASURBVHjaYmDACxhBxAIckgkM'+
'TMjc//H/gQhZhImBMFjA8B8DQGwkoJsF6sKFjBC74Wyi7GZB8SWSPqIAQIABANSOHUBsegfT'+
'AAAAAElFTkSuQmCC';

var img_green_minus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAABGdBTUEAAK/INwWK6QAAABl0'+
'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAwSURBVHjaYmDACxhBxAIckgkM'+
'TPh1E5BmgVD/4/+j27qQkWjdELUk201AmgAACDAAasYEt53mHC8AAAAASUVORK5CYII=';

var img_yellow_plus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAGXRFWHRTb2Z0d2FyZQBBZG9i'+
'ZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRF////zMwAAAAANJ5ySAAAACJJREFUeNpiYIIDBiZGK'+
'IAwGRgwmQxggM7ErhZhGBwABBgAGVoAdb8Fi4oAAAAASUVORK5CYII=';

var img_yellow_minus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZ'+
'SBJbWFnZVJlYWR5ccllPAAAAAlQTFRF////zMwAAAAANJ5ySAAAABxJREFUeNpiYIIDBiZGKM'+
'DNZAADdCYhbXAAEGAAGxIAfXROui0AAAAASUVORK5CYII=';

var img_red_plus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAABGdBTUEAAK/INwWK6QAAABl0'+
'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAA+SURBVHjaYmLAC1iA+AwOORMG'+
'BiZkvvH//0CELMLEQBAADf+PAc4Qo5sFQp1lZITYDWczkKAb2QwSAECAAQDmzx2dT/4q7wAA'+
'AABJRU5ErkJggg==';

var img_red_minus='data:image/png;base64,'+
'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAABGdBTUEAAK/INwWK6QAAABl0'+
'RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAySURBVHjaYmDACxiB+AwOORMG'+
'Bib8uglIs0Ao4///0STOMjISrRuilmS7CUgTAAABBgCBigTjAsuh4QAAAABJRU5ErkJggg==';

var good_tags = GM_getValue("good_tags", "").split(' ').nonempty();
var warn_tags = GM_getValue("warn_tags", "").split(' ').nonempty();
var bad_tags = GM_getValue("bad_tags", "").split(' ').nonempty();
var good_users = GM_getValue("good_users", "").split(' ').nonempty();
var warn_users = GM_getValue("warn_users", "").split(' ').nonempty();
var bad_users = GM_getValue("bad_users", "").split(' ').nonempty();

var tdmStyle = '';

tdmStyle += 'a.taglist { font-weight: bold !important; }\n';
tdmStyle += 'td.tabletext span a:visited { color: #666666; font-weight: inherit; }\n';
tdmStyle += 'td.tabletext span a.tag:visited { color: inherit; }\n';

tdmStyle += 'a.goodtdm { color: green !important; }\n';
tdmStyle += 'a.warntdm { color: orange !important; font-size:100%; }\n';
tdmStyle += 'a.badtdm { color: red !important; font-size:100%; }\n';

tdmStyle += 'tr.goodcell { display: table-row !important; visibility: visible !important; }\n';
tdmStyle += 'tr.warncell { display: none; visibility: hidden; }\n';
tdmStyle += 'tr.badcell { display: none !important; visibility: hidden !important; }\n';

tdmStyle += 'tr.warncellshow { display: table-row; visibility: inherit; }\n';
tdmStyle += 'tr.warncellshow td { background-color: lightyellow; }\n';

tdmStyle += 'tr.badcellshow { display: table-row; visibility: inherit; }\n';
tdmStyle += 'tr.badcellshow td { background-color: pink; }\n';

/* Fix for the new layout - return the column width to 100% */
tdmStyle += '#frame { width: 100%; }\n';

GM_addStyle(tdmStyle);


// ENABLES tdmDebug FUNCTION FOR CONSOLE LOGGING
var debug = false;

// This helps prevent duplicate calls due to things like the Firebug panel's onload event
if (document.body.innerHTML.length > 1024) {
    var start = new Date().getTime();
    colorize();
    var finish = new Date().getTime();
    tdmDebug('total: ' + (finish - start) + 'ms');
}