THPsupplemental

For those users that enjoy odd hats and questionable writing. Adds a few reasonable features to the THP site.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

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

(I already have a user script manager, let me install it!)

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.

ستحتاج إلى تثبيت إضافة مثل Stylus لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتتمكن من تثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

ستحتاج إلى تثبيت إضافة لإدارة أنماط المستخدم لتثبيت هذا النمط.

(لدي بالفعل مثبت أنماط للمستخدم، دعني أقم بتثبيته!)

// ==UserScript==
// @name         THPsupplemental
// @namespace    https://greasyfork.org/en/scripts/13233-thpsupplemental
// @version      0.9
// @description  For those users that enjoy odd hats and questionable writing. Adds a few reasonable features to the THP site.
// @author       kntei
// @include      http://www.touhou-project.com/*
// @run-at       document-end
// @grant        GM_listValues
// @grant        GM_deleteValue
// @grant        GM_getValue
// @grant        GM_setValue
// @icon         data:image/png;base64,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
// ==/UserScript==

//GLOBAL VARIABLES
var thps = {
    posts: [],
    threads: [],
    intervals: [],
    maxReplies: 3,
    timeThreshold: 1000 * 60 * 60 * 24 * 7, // 7 days
    refreshRSS: 1000 * 60 * 30, // 30 mins
    storyDomains: ["th", "eientei", "forest", "border", "shrine", "sdm", "youkai", "underground", "others", "shorts"],
    allBoards: [ "gensokyo", "i", "at", "th", "eientei", "forest", "border", "shrine", "sdm", "youkai", "underground", "others", "shorts", "blue" ],
    allFullBoards: [ "General Discussion", "Drawing", "18+ Touhou", "General", "Eientei & Lunar Capital", "Forest of Magic & Flower Fields", "Hakurei Border & Afterlife", "Hakurei Shrine, Human Village & Myouren Temple", "Scarlet Devil Mansion & Misty Lake", "Youkai Mountain & Heaven", "Underground & Makai", "Others", "Short Stories", "not a color we know" ]
};

//FUNCTIONS ON GLOBAL VARIABLES

function clearIntervals()
{
    for( var i = 0; i < thps.intervals.length; i++ )
        clearInterval(thps.intervals[i]);
}

function hasLocalPost( id, board )
{
    for( var i = 0; i < thps.posts.length; i++ )
        if( thps.posts[i].postID == id && thps.posts[i].boardStr == board )
            return true;
    return false;
}

function threadIndex( id )
{
    for( var i = 0; i < thps.threads.length; i++ )
        if( thps.threads[i].topicID == id )
            return i;
    return -1;
}

function updateThreads()
{
    thps.threads = [];
    for( var i = 0; i < thps.posts.length; i++ )
    {
        var index = threadIndex(thps.posts[i].topicID);
        if( index === -1 )
        {
            var newthread = new Thread();
            newthread.topicID = thps.posts[i].topicID;
            newthread.latestDate = thps.posts[i].date;
            if( thps.posts[i].topicID != thps.posts[i].postID )
                newthread.numChild = newthread.numChild + 1;
            thps.threads.push( newthread );
        }
        else
        {
            if( thps.threads[index].latestDate.stringToMilli() < thps.posts[i].date.stringToMilli() )
                thps.threads[index].latestDate = thps.posts[i].date;
            if( thps.posts[i].topicID != thps.posts[i].postID )
                thps.threads[index].numChild = thps.threads[index].numChild + 1;
        }
    }
}

function printThreads()
{
    for( var i = 0; i < thps.threads.length; i++ )
    {
        console.log('---');
        console.log( "ID " + thps.threads[i].topicID);
        console.log( "Date " + thps.threads[i].latestDate);
        console.log( "Child " + thps.threads[i].numChild);
    }
}

function sortPostArrayByDate()
{
    thps.posts.sort(
        function( a, b )
        {
            return a.date.stringToMilli() - b.date.stringToMilli();
        }
    );
}

function sortPostArrayByPostNum()
{
    updateThreads();
    thps.posts.sort(
        function( a, b )
        {
            if( thps.threads[threadIndex(a.topicID)].latestDate.stringToMilli() < thps.threads[threadIndex(b.topicID)].latestDate.stringToMilli() )
                return 1;
            if( thps.threads[threadIndex(a.topicID)].latestDate.stringToMilli() > thps.threads[threadIndex(b.topicID)].latestDate.stringToMilli() )
                return -1;
            else if( Number(a.topicID) >  Number(b.topicID) )
                return 1;
            else if( Number(a.topicID) <  Number(b.topicID) )
                return -1;
            else if( Number(a.postID) >  Number(b.postID) )
                return 1;
            else if( Number(a.postID) <  Number(b.postID) )
                return -1;
            else
                return 0;
        }
    );
}

// TIME CONVERSIONS
String.prototype.stringToMilli = function()
{
    var replaced = this.replace(/[^\w\s]/gi, ' ');
    var parsed = replaced.split(" ");

    var d = new Date( parsed[0], Number(parsed[1])-1, parsed[2], parsed[4], parsed[5], 0, 0);

    return d.valueOf();
};

Number.prototype.milliToString = function()
{

    var d = new Date( this );
    var string = "";
    var dayWeek = ["Sun", "Mon", "Tue", "Wen", "Thu", "Fri", "Sat"];

    string += d.getFullYear();
    string += '/';
    string += numPad(d.getMonth()+1, 2);
    string += '/';
    string += numPad(d.getDate(), 2);
    string += '(';
    string += dayWeek[d.getDay()];
    string += ')';
    string += numPad(d.getHours(), 2);
    string += ':';
    string += numPad(d.getMinutes(), 2);

    return string;
};

// XMLHttpRequest CLASS

function RequestThread()
{
    this.client = new XMLHttpRequest();
}

function AJAXLike( url, success, failure )
{
    var client = new XMLHttpRequest();
    var handler = function()
    {
        if (this.readyState === 4)
        {
            if (this.status === 200) //COMPLETE
                success(client);//FUNCTION
            else //ERROR
                failure();
        }
    };
    client.onreadystatechange = handler;
    client.open( "GET", url );
    client.send();
}

RequestThread.prototype.requestHTML = function( url, func, board )
{
    var handler = function()
    {
        if (this.readyState === 4)
        {
            if (this.status === 200) //COMPLETE
            {
                var doc = document.implementation.createHTMLDocument("");
                doc.body.innerHTML = this.response;
                func( doc, board );//FUNCTION
            }
            else //ERROR
                console.log( "ERROR on page " + url );
        }
    };
    this.client.onreadystatechange = handler;
    this.client.open( "GET", url );
    this.client.send();
};

function Thread(){
    this.topicID = "";
    this.latestDate = "";
    this.numChild = 0;
}

// POST CLASS

function Post() {
    this.boardStr = "";
    this.imgNumber = "";
    this.imgType = "";
    this.imgDetails = "";
    this.threadName = "";
    this.posterName = "";
    this.posterTrip = "";
    this.date = "";
    this.topicID = "";
    this.postID = "";
    this.text = "";
}

Post.prototype.isBlank = function()
{
    if( this.text === "" )
        return true;
    return false;
};

Post.prototype.isChild = function()
{
    if( Number(this.topicID) === Number(this.postID) )
        return false;
    return true;
};

Post.prototype.clear = function()
{
    this.boardStr = "";
    this.imgNumber = "";
    this.imgType = "";
    this.imgDetails = "";
    this.threadName = "";
    this.posterName = "";
    this.posterTrip = "";
    this.date = "";
    this.topicID = "";
    this.postID = "";
    this.text = "";
};

Post.prototype.fromSinglePost = function( doc, board )
{
    this.boardStr = board;
    var searchspan = doc.getElementsByTagName( "span" );
    for( var i = 0; i < searchspan.length; i++ )
    {
        if( searchspan[i].className == "filesize" )
        {
            var file = searchspan[i].childNodes;

            var a = file[1].textContent.split(".");
            this.imgNumber = a[0];
            this.imgType = a[1];

            var b = file[2].textContent;
            b.removeWhiteSpace();
            b = b.popFront();
            b = b.popBack();
            this.imgDetails = b;
        }
        if( searchspan[i].className == "filetitle" )
            this.threadName = searchspan[i].innerHTML;
        if( searchspan[i].className == "postername" )
            this.posterName = searchspan[i].innerHTML;
        if( searchspan[i].className == "postertrip" )
            this.posterTrip = searchspan[i].innerHTML;
        if( searchspan[i].className == "reflink" )
        {
            var ref = searchspan[i].innerHTML;
            var breakdown = ref.split('"');
            breakdown = breakdown[1].split(/[.\/#]/g);
            this.topicID = breakdown[breakdown.length-3];
            this.postID = breakdown[breakdown.length-1];
        }
    }

    var searchblock = doc.getElementsByTagName( "blockquote" );
    if( searchblock[0] !== undefined )
        this.text = searchblock[0].innerHTML;

    var searchlabel = doc.getElementsByTagName( "label" );
    if( searchlabel[0] !== undefined )
    {
        var lab = searchlabel[0].childNodes;
        this.date = lab[lab.length-1].textContent.replace(/\s/g, "");
    }
};

function createBreakString( arr )
{
    var s = "";
    var sLength = 0;
    for( var i = 0; i < arr.length; i++ )
    {
        s += "!" + (arr[i].length + sLength);
        sLength += arr[i].length;
    }
    return s;
}

function createDataString( arr )
{
    var s = "";
    for( var i = 0; i < arr.length; i++ )
        s += arr[i];
    return s;
}

Post.prototype.savePost = function()
{
    //breaksSTRING id + board + breaks, "!2!135!18469849!651651"
    //dataSTRING id + board + data, "al;sidjf;aloskjd;falksjdf;lasjkd"

    //GM_deleteValue( id + board + "breaks" );
    //GM_deleteValue( id + board + "data" );

    var id = this.postID;
    var board = this.boardStr;

    var brks = "0" + createBreakString([this.boardStr, this.imgNumber, this.imgType, this.imgDetails, this.threadName, this.posterName, this.posterTrip, this.date, this.topicID, this.postID, this.text]);
    var data =        createDataString([this.boardStr, this.imgNumber, this.imgType, this.imgDetails, this.threadName, this.posterName, this.posterTrip, this.date, this.topicID, this.postID, this.text]);

    //console.log( brks );
    //console.log( data );

    var savB = brks; 
    //var savB = totalencode(brks);
    GM_setValue( id + '!' + board + '!' + "breaks", savB );

    var savD = data;
    //var savD = totalencode(data);
    GM_setValue( id + '!' + board + '!' + "data", savD );
};

function parsePostData( pos, breaks, data )
{
    var string = "";
    var arrBreaks = breaks.split("!");
    string += data.substring(Number(arrBreaks[pos]),Number(arrBreaks[pos+1]));
    return string;
}

Post.prototype.loadPost = function( id, board )
{
    var loadB = GM_getValue( id + '!' + board + '!' + "breaks" );
    var loadD = GM_getValue( id + '!' + board + '!' + "data" );

    //var brks = totaldecode(loadB);
    var brks = loadB;
    //var data = totaldecode(loadD);
    var data = loadD;

    this.boardStr = parsePostData( 0, brks, data );
    this.imgNumber = parsePostData( 1, brks, data );
    this.imgType = parsePostData( 2, brks, data );
    this.imgDetails = parsePostData( 3, brks, data );
    this.threadName = parsePostData( 4, brks, data );
    this.posterName = parsePostData( 5, brks, data );
    this.posterTrip = parsePostData( 6, brks, data );
    this.date = parsePostData( 7, brks, data );
    this.topicID = parsePostData( 8, brks, data );
    this.postID = parsePostData( 9, brks, data );
    this.text = parsePostData( 10, brks, data );
};

function makeOpeningPost( oldhtml )
{
    var html = '';
    html += '<table>';
    html += '<tbody>';
    html += '<tr>';
    html += '<td>';

    html += oldhtml;

    html += '</span>';

    html += '</td>';
    html += '</tr>';
    html += '</tbody>';
    html += '</table>';

    return html;
}

function makeChildPost( oldhtml )
{
    var html = '';
    html += '<table>';
    html += '<tbody>';
    html += '<tr>';
    html += '<td class="reply" style=\'padding:0px 7.5px 0px 7.5px\'">';

    html += oldhtml;

    html += '</span>';

    html += '</td>';
    html += '</tr>';
    html += '</tbody>';
    html += '</table>';

    return html;
}

//////////////////////////////////////////////
// BORROWED SOME KUSABA CODE TO WORK IN FRAMES
//////////////////////////////////////////////
function addPreview(e) {
    var c;
    var d = "srcElement";
    var f = "href";
    this[f] ? c = this : c = e[d];
    ainfo = c.className.split('|');
    var g = getCurrentFrameDoc().createElement('div');
    g.setAttribute("id", "preview" + c.className);
    g.setAttribute('class', 'reflinkpreview');
    g.setAttribute('className', 'reflinkpreview');
    if (e.pageX) {
        g.style.left = '' + (e.pageX + 50) + 'px';
    } else {
        g.style.left = (e.clientX + 50);
    }
    var h = getCurrentFrameDoc().createTextNode('');
    g.appendChild(h);
    var i = c.parentNode;
    var j = i.insertBefore(g, c);
    AJAXLike('http://www.touhou-project.com/read.php?b=' + ainfo[1] + '&t=' + ainfo[2] + '&p=' + ainfo[3] + '&single',
             function(a) {
                 var b = a.responseText || _("something went wrong (blank response)");
                 j.innerHTML = b;
             },
             function() {
                 var response = _("something went wrong (blank response)");
                 newelement.innerHTML = response;
             }
            );
}

function delPreview(e) {
    var a;
    var b = "srcElement";
    var c = "href";
    this[c] ? a = this : a = e[b];
    var d = getCurrentFrameDoc().getElementById("preview" + a.className);
    if (d) {
        d.parentNode.removeChild(d);
    }
}

function parsePreview() {
    var a = getCurrentFrameDoc().getElementsByTagName('a');
    var b;
    var c;
    for (var i = 0; i < a.length; i++) {
        b = a[i];
        if (b.className) {
            if (b.className.substr(0, 4) == "ref|") {
                if (b.addEventListener) {
                    b.addEventListener("mouseover", addPreview, false);
                    b.addEventListener("mouseout", delPreview, false);
                } else if (b.attachEvent) {
                    b.attachEvent("onmouseover", addPreview);
                    b.attachEvent("onmouseout", delPreview);
                }
            }
        }
    }
}

// TEXT SHORTENER

function getCurrentFrameDoc()
{
    if( window.top.frames[1] !== undefined )
        return window.top.frames[1].document;
    else
        return document;
}

function setStyles( style )
{
    var styles = getCurrentFrameDoc().getElementsByTagName('link');
    for( var i = 0; i < styles.length; i++ )
        if( styles[i].type == "text/css" )
            if( styles[i].title == style )
                styles[i].disabled = false;
}

function deleteStyles()
{
    var styles = getCurrentFrameDoc().getElementsByTagName('link');
    for( var i = 0; i < styles.length; i++ )
        if( styles[i].type == "text/css" )
            styles[i].parentNode.removeChild(styles[i]);
}

function disableStyles()
{
    var styles = getCurrentFrameDoc().getElementsByTagName('link');
    for( var i = 0; i < styles.length; i++ )
        if( styles[i].type == "text/css" )
            styles[i].disabled = true;
}

function addStyles()
{
    var head = getCurrentFrameDoc().getElementsByTagName('head')[0];
    
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/img_global.css';
    head.appendChild(link);
    
    link = document.createElement('link');
    link.rel = 'alternate stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/burichan.css';
    link.title = 'Burichan';
    link.disabled = 'true';
    head.appendChild(link);
    
    link = document.createElement('link');
    link.rel = 'alternate stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/futaba.css';
    link.title = 'Futaba';
    link.disabled = 'true';
    head.appendChild(link);
    
    link = document.createElement('link');
    link.rel = 'alternate stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/photon.css';
    link.title = 'Photon';
    link.disabled = 'true';
    head.appendChild(link);
    
    link = document.createElement('link');
    link.rel = 'alternate stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/chernobyl.css';
    link.title = 'Chernobyl';
    link.disabled = 'true';
    head.appendChild(link);
    
    link = document.createElement('link');
    link.rel = 'alternate stylesheet';
    link.type = 'text/css';
    link.href = 'http://www.touhou-project.com/css/darkish.css';
    link.title = 'Darkish';
    link.disabled = 'true';
    head.appendChild(link);
}

function cookieStyle()
{
    var style = cookieValue(' kustyle');
    deleteStyles();
    addStyles();
    if( style !== '' )
        setStyles( style );
    else
        setStyles( "Photon" );
}

function cookieValue(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for( var i = 0; i < ca.length; i++ )
    {
        var s = ca[i].split('=');
        if( cname == s[0] )
            return s[1];
    }
    return "";
}

function toggle_visibility(id)
{
    var arr = id.split('!');
    var short = document.getElementById( arr[0] + arr[1] + "short" );
    var long = document.getElementById( arr[0] + arr[1] + "long" );
    if( short.style.display == 'block' )
    {
        short.style.display = 'none';
        long.style.display = 'block';
    }
    else
    {
        short.style.display = 'block';
        long.style.display = 'none';
    }
};

function cropString( string, delim, times )
{
    var cropstring = string;

    for( var i = 0; i < times; i++ )
    {
        var loc = cropstring.lastIndexOf(delim);
        cropstring = cropstring.substring(0,loc);
    }

    return cropstring;
}

function makeMessageShort( id, board, string )
{
    var html = '';
    var countMax = 12;
    var count = string.split("<br>").length - 1;

    if( count > countMax )
    {
        html += '<div id=\'' + id + board + 'long\' style=\'display:none\'>';
        html += '<blockquote>';
        html += string;
        html += '</blockquote>';
        html += '</div>';

        html += '<div id=\'' + id + board + 'short\'>';
        html += '<blockquote>';
        html += cropString(string, "<br>", count - countMax );
        html += '</blockquote>';
        html += '</div>';

        html += '<a href="javascript:void(0)" onclick="toggle_visibility(\'' + id + '!' + board + '\');">Message too long. Click here to toggle text.</a>';
        return html;
    }
    else
    {
        html += '<blockquote>';
        html += string;
        html += '</blockquote>';
        return html;
    }
}

function getDims( string )
{
    var arr = [0,0];
    var breakdown = string.split(',');
    breakdown = breakdown[1].replace(/\s/g, "").split('x');
    arr[0] = Number(breakdown[0]);
    arr[1] = Number(breakdown[1]);
    return arr;
}

function getScaled( string, maxSize )
{
    var arrDim = getDims( string );
    var arr = [0,0,0,0];
    arr[2] = arrDim[0];
    arr[3] = arrDim[1];
    var scale = 0;

    if( arr[2] <= maxSize && arr[3] <= maxSize )
        return arr;

    if( arr[2] > arr [3] )
    {
        scale = maxSize / arr[2];
        arr[0] = scale * arr[2];
        arr[1] = scale * arr[3];
    }
    else
    {
        scale = maxSize / arr[3];
        arr[0] = scale * arr[2];
        arr[1] = scale * arr[3];
    }

    return arr;
}

function makePost( post, pos )
{
    var html = '';

    if( post.topicID == post.postID )
    {
        html += '<span class="reply" style=\'padding:0px 10px 0px 10px\'>/' + post.boardStr + '/</span><br><br>';
    }

    // HAS IMAGE
    if( post.imgDetails !== "" )
    {
        if( post.topicID == post.postID )
            var thumbDim = getScaled( post.imgDetails, 200 );
        else
            var thumbDim = getScaled( post.imgDetails, 125 );

        // IMAGE
        html += '<a target="_blank" href="http://www.touhou-project.com/' + post.boardStr + '/src/' + post.imgNumber + '.' + post.imgType + '">';
        html += '<span id="thumb' + post.postID + '">';
        html += '<img src="http://www.touhou-project.com/' + post.boardStr + '/thumb/' + post.imgNumber + 's.' + post.imgType + '" alt="' + post.postID + '" class="thumb" height="' + thumbDim[1] + '" width="' + thumbDim[0] + '" />';
        html += '</span>';
        html += '</a>';

        // FILE EXPANDLINK + DETAILS + IQDB
        html += '<span class="filesize">';
        html += 'File ';
        html += '<a href="http://www.touhou-project.com/' + post.boardStr + '/src/' + Number(post.imgNumber) + '.' + post.imgType + '" onclick="javascript:expandimg(\'' + Number(post.postID) + '\', \'http://www.touhou-project.com/' + post.boardStr + '/src/' + Number(post.imgNumber) + '.' + post.imgType + '\', \'http://www.touhou-project.com/' + post.boardStr + '/thumb/' + Number(post.imgNumber) + 's.' + post.imgType + '\', \'' + thumbDim[2] + '\', \'' + thumbDim[3] + '\', \'' + thumbDim[0] + '\', \'' + thumbDim[1] + '\');return false;">' + post.imgNumber + '.' + post.imgType + '</a>';
        html +=  post.imgDetails +  ' ';
        html += '[<a href="http://iqdb.org/?url=http://www.touhou-project.com/' + post.boardStr + '/src/' + post.imgNumber + '.' + post.imgType + '" target="_blank">iqdb</a>]';
        html += '</span>';
        html += '<br/>';
    }

    // TITLE
    html += '<a name="' + post.postID + '"></a>';
    html += '<span class="filetitle">';
    html += post.threadName + ' ';
    html += '</span>';

    // USER
    html += '<span class="postername">' + post.posterName + '</span>';
    html += '<span class="postertrip">' + post.posterTrip + '</span>';
    html += ' ';

    // TIME+DATE
    html += post.date;
    html += ' ';

    // REFLINK
    html += '<span class="reflink">';
    html += '<a href="/' + post.boardStr + '/res/' + post.topicID + '.html#' + post.postID + '" onclick="return highlight("' + post.postID + '");">No.&nbsp;</a>';
    html += '<a href="/' + post.boardStr + '/res/' + post.topicID + '.html#i' + post.postID + '" onclick="return insert(\'>>' + post.postID + '\n\');">' + post.postID + '</a>';
    html += '</span>';

    if( post.topicID == post.postID )
    {
        // REPLY
        html += ' [';
        html += '<a href=\'http://www.touhou-project.com/' + post.boardStr + '/res/' + post.topicID + '.html\'>Reply</a>';
        html += ']';
    }


    // SOME KIND OF ID?
    html += '<span id="dnb-' + post.boardStr + '-' + post.postID + '-y"></span>';
    html += '<br />';

    // BLOCK QUOTE
    html += makeMessageShort( post.postID, post.boardStr, post.text);

    return html;
}

function NavigationBar()
{
    var html = '';

    html += '<div class="navbar">';

    html += '[ ';
    html += '<a title="General Discussion" href="/gensokyo/">gensokyo</a> / ';
    html += '<a title="Drawing" href="/i/">i</a> / ';
    html += '<a title="18+ Touhou" href="/at/">at</a> / ';
    html += '<a title="Words Words Words" href="/words/">words</a>';
    html += ' ] ';

    html += '[ ';
    html += '<a title="General" href="/th/">th</a> / ';
    html += '<a title="Eientei &amp; Lunar Capital" href="/eientei/">eientei</a> / ';
    html += '<a title="Forest of Magic &amp; Flower Fields" href="/forest/">forest</a> / ';
    html += '<a title="Hakurei Border &amp; Afterlife" href="/border/">border</a> / ';
    html += '<a title="Hakurei Shrine, Human Village &amp; Myouren Temple" href="/shrine/">shrine</a> / ';
    html += '<a title="Scarlet Devil Mansion &amp; Misty Lake" href="/sdm/">sdm</a> / ';
    html += '<a title="Youkai Mountain &amp; Heaven" href="/youkai/">youkai</a> / ';
    html += '<a title="Underground &amp; Makai" href="/underground/">underground</a> / ';
    html += '<a title="Others" href="/others/">others</a> / ';
    html += '<a title="Short Stories" href="/shorts/">shorts</a>';
    html += ' ] ';

    html += '[ ';
    html += '<a title="not a color we know" href="/blue/">blue</a> / ';
    html += '<a title="Downloads" href="/rs/">rs</a>';
    html += ' ] ';

    html += '[ ';
    html += '<a title="Story List" href="/storylist.html">Story List</a>';
    html += ' ] ';

    html += '</div>';

    return html;
}

function ScriptInject()
{
    var html = '';

    html += '<script>';

    //General Scripts
    html += getCurrentFrameDoc;

    //Cookie + Style Set Scipt
    html += cookieValue;
    html += cookieStyle;
    
    html += addStyles;
    html += deleteStyles;
    //html += disableStyles;
    html += setStyles;

    //AJAX request for preview
    html += AJAXLike;
    //Preview Script
    html += addPreview;
    html += delPreview;
    html += parsePreview;
    
    html += toggle_visibility;

    html += 'cookieStyle();';
    html += 'parsePreview();';

    html += '</script>';

    return html;
}

function StyleSelect()
{
    var html = '';
    html += '<script type="text/javascript" src="http://www.touhou-project.com//lib/javascript/gettext.js"></script>';
    html += '<script type="text/javascript" src="http://www.touhou-project.com/lib/javascript/protoaculous-compressed.js"></script>';

    html += '<script type="text/javascript"><!--';
    html += 'var ku_boardspath = "http://www.touhou-project.com";';
    html += 'var ku_cgipath = "http://www.touhou-project.com";';
    html += 'var style_cookie = "kustyle";';
    html += 'var ispage = true;';
    html += '//--></script>';

    html += '<script type="text/javascript" src="http://www.touhou-project.com/lib/javascript/kusaba.js"></script>';

    html += '<div class="adminbar">';
    html += '<select onchange="javascript:if(selectedIndex != 0)set_stylesheet(options[selectedIndex].value);return false;">';
    html += '<option>Styles</option>';
    html += '<option value="Burichan">Burichan</option>;';
    html += '<option value="Futaba">Futaba</option>;';
    html += '<option value="Photon">Photon</option>;';
    html += '<option value="Chernobyl">Chernobyl</option>;';
    html += '<option value="Darkish">Darkish</option>;';
    html += '</select>';
    html += '</div>';

    return html;
}

/////////////////////////////
// JAVASCRIPT CREATED PAGES
/////////////////////////////

function sizeLocalStorage()
{
    var arrNames = GM_listValues();
    var size = 0;

    for( var i = 0; i < arrNames.length; i++ )
        size += GM_getValue(arrNames[i]).length;

    return size;
}

function clearLocalStorage()
{
    var arrNames = GM_listValues();

    for( var i = 0; i < arrNames.length; i++ )
        GM_deleteValue(arrNames[i]);
}

function printLocalPosts()
{
    var arrNames = GM_listValues();
    for( var i = 0; i < arrNames.length; i++ )
        console.log( arrNames[i] );
}

function saveLocalPosts( arr )
{
    for( var i = 0; i < arr.length; i++ )
        arr[i].savePost();
}

function loadLocalPosts()
{
    var arr = [];
    var arrNames = GM_listValues();

    var arrbreaks = [];
    var arrdata = [];

    for( var i = 0; i < arrNames.length; i++ )
    {
        if( arrNames[i].indexOf("breaks") !== -1)
            arrbreaks.push(arrNames[i]);
        if( arrNames[i].indexOf("data") !== -1 )
            arrdata.push(arrNames[i]);
    }

    for( var i = 0; i < arrbreaks.length; i++ )
    {
        var breakbrk = arrbreaks[i].split('!');
        for ( var j = 0; j < arrdata.length; j++ )
        {
            var databrk = arrdata[j].split('!');
            if( breakbrk[0] === databrk[0] && breakbrk[1] === databrk[1] )
            {
                var post = new Post();
                post.loadPost( breakbrk[0], breakbrk[1] );
                arr.push(post);
            }
        }

    }

    return arr;
}

function threadSavePost( doc, board )
{
    //console.log( "SAVEPOST: " + board );
    var post = new Post();
    post.fromSinglePost( doc, board );
    post.savePost();
    //console.log(window.location.host);
}

function savePostsRSS( doc, board )
{
    //console.log( "RSS BOARD: " + board );
    var items = doc.getElementsByTagName("item");
    var requestArr = [];
    for( var i = 0; i < items.length; i++ )
    {
        var cn = items[i].childNodes;
        var s = cn[4].textContent.replace(/\s/g,"").split(/[.\/#]/g);

        if( !hasLocalPost( s[s.length-3], board ) && requestArr.indexOf("" + s[s.length-3] + board) === -1 )
        {
            requestArr.push("" + s[s.length-3] + board);
            var thread1 = new RequestThread();
            var url1 = 'http://www.touhou-project.com/read.php?b=' + board + '&t=' + s[s.length-3] + '&p=' + s[s.length-3] + '&single';
            thread1.requestHTML( url1, threadSavePost, board );
        }

        if( !hasLocalPost( s[s.length-1], board ) && requestArr.indexOf("" + s[s.length-1] + board) === -1 )
        {
            requestArr.push("" + s[s.length-1] + board);
            var thread2 = new RequestThread();
            var url2 = 'http://www.touhou-project.com/read.php?b=' + board + '&t=' + s[s.length-3] + '&p=' + s[s.length-1] + '&single';
            thread2.requestHTML( url2, threadSavePost, board );
        }
    }
}

function currentTimeMilli()
{
    var d = new Date();
    return d.valueOf();
}

function AllStoriesPageHTML()
{
    thps.posts = loadLocalPosts();
    sortPostArrayByPostNum();
    //printThreads();

    var html = '';

    html += NavigationBar();
    html += StyleSelect();
    html += '<div class="logo"> RSS Feed </div>';

    var currentthread = "";
    var count = 0;
    for( var i = 0; i < thps.posts.length; i++ )
    {
        var post = thps.posts[i];
        if( !post.isBlank() )
        {
            var thread = thps.threads[threadIndex(post.topicID)];
            if( thread.latestDate.stringToMilli() - currentTimeMilli() + thps.timeThreshold > 0 )
            {
                if( currentthread != post.topicID )
                {
                    currentthread = post.topicID;
                    count = thread.numChild;
                }
                else
                {
                    if( currentthread != post.postID )
                        count -= 1;
                }
                if( post.isChild() && count < (thread.numChild - (thread.numChild - thps.maxReplies)) )
                    html += makeChildPost(makePost( post, 1+i ));
                //else
                //console.log( 'Hidden post - ' + post.postID + ' ' + post.boardStr );
                if( !post.isChild() )
                    html += "<hr>" + makeOpeningPost(makePost( post, 1+i ));
            }
        }
    }
    html += '<hr/>';
    html += NavigationBar();
    html += ScriptInject();

    return html;
}

function WatchedThreadsPage( open )
{
    open.document.write( NavigationBar() );
    open.document.write( StyleSelect() );
    var html = '<div class="logo"> Watched Threads </div><hr /><u1>Work in progress...</u1><hr/>';
    open.document.write( html );
    open.document.write( NavigationBar() );
    open.document.close();
}

function OptionsPageHTML( open )
{
    var html = '';
    html += NavigationBar();
    html += StyleSelect();
    html += '<div class="logo"> Options </div>';
    html += '<hr />';
    html += '<h2>RSS OPTIONS</h2>';
    html += '<u1>Check Boards</u1><br>';
    for( var i = 0; i < thps.allBoards.length; i++ )
        html += '<label><input type="checkbox" value="' + thps.allBoards[i] + '" >/' + thps.allBoards[i] + '/ - ' + thps.allFullBoards[i] + '</label><br>';
    html += '<br><input type="text" id="refreshrate" value="' + thps.refreshRSS/60000 + '" size="1" maxlength="4"><u1> Minutes - Refresh Rate</u1><br>';
    html += '<hr />';
    html += '<h2>THREAD DISPLAY OPTIONS</h2>';
    html += '<input type="text" id="maxreplies" value="' + thps.maxReplies + '" size="1" maxlength="4"><u1> Max visible replies</u1><br><br>';
    html += '<input type="text" id="oldthreshhold" value="' + thps.timeThreshold/86400000 + '" size="1" maxlength="4"><u1> Days - Old thread threshhold</u1><br>';
    html += '<hr />';
    html += '<h2>OFFLINE LOCAL STORAGE</h2>';
    html += '<input type="button" id="ClearCache" value="Clear Cache"><u1> - ' + (sizeLocalStorage()/1048576).toFixed(2) +' MB</u1><br>';
    html += '<hr />';
    html += '<input type="button" id="Save" value="Save">';
    html += '<hr />';
    html += NavigationBar();
    html += ScriptInject();
    return html;
}

function exec_body_scripts(body_el) {
    // Finds and executes scripts in a newly added element's body.
    // Needed since innerHTML does not run scripts.
    //
    // Argument body_el is an element in the dom.

    function nodeName(elem, name) {
        return elem.nodeName && elem.nodeName.toUpperCase() ===
            name.toUpperCase();
    }

    function evalScript(elem) {
        var data = (elem.text || elem.textContent || elem.innerHTML || "" ),
            head = getCurrentFrameDoc().getElementsByTagName("head")[0] ||
            getCurrentFrameDoc().documentElement,
            script = getCurrentFrameDoc().createElement("script");

        script.type = "text/javascript";
        try {
            // doesn't work on ie...
            script.appendChild(getCurrentFrameDoc().createTextNode(data));      
        } catch(e) {
            // IE has funky script nodes
            script.text = data;
        }

        head.insertBefore(script, head.firstChild);
        head.removeChild(script);
    }

    // main section of function
    var scripts = [],
        script,
        children_nodes = body_el.childNodes,
        child,
        i;

    for (i = 0; children_nodes[i]; i++) {
        child = children_nodes[i];
        if (nodeName(child, "script" ) &&
            (!child.type || child.type.toLowerCase() === "text/javascript")) {
            scripts.push(child);
        }
    }

    for (i = 0; scripts[i]; i++) {
        script = scripts[i];
        if (script.parentNode) {script.parentNode.removeChild(script);}
        evalScript(scripts[i]);
    }
}

function parseTextNumber( text, min, multi, def )
{
    var num = def * multi;
    var tonum = Number(text);
    if( !isNaN(tonum) )
    {
        if(tonum >= min )
            num = tonum * multi;
        else
            num = min * multi;
    }
    return num;
}

function optionsLoad()
{
    var s = GM_getValue("settings");
    if( s !== undefined && s!== null )
    {
        thps.storyDomains = [];
        var arr = s.split('!');
        for( var i = 0; i < arr.length; i++ )
        {
            if( i > 0 && i < arr.length - 3 )
                thps.storyDomains.push(arr[i]);
            if( i == arr.length - 3 )
                thps.refreshRSS = Number(arr[i]);
            if( i == arr.length - 2 )
                thps.maxReplies = Number(arr[i]);
            if( i == arr.length - 1 )
                thps.timeThreshold = Number(arr[i]);
        }
    }
}

function optionsSave( focus )
{
    var inputs = focus.getElementsByTagName("input");

    thps.storyDomains = [];

    for( var i = 0; i < inputs.length; i++ )
    {
        if( inputs[i].type == "checkbox" && inputs[i].checked )
            thps.storyDomains.push(inputs[i].value);
        if( inputs[i].id == "refreshrate" )
            thps.refreshRSS = parseTextNumber(inputs[i].value, 5, 60000, 30);
        if( inputs[i].id == "maxreplies" )
            thps.maxReplies = parseTextNumber(inputs[i].value, 0, 1, 3);
        if( inputs[i].id == "oldthreshhold" )
            thps.timeThreshold = parseTextNumber(inputs[i].value, 0, 86400000, 7);
    }
}

function optionsSaveString( focus )
{
    var s = "";
    var inputs = focus.getElementsByTagName("input");

    for( var i = 0; i < inputs.length; i++ )
    {
        if( inputs[i].type == "checkbox" && inputs[i].checked )
            s += '!' + inputs[i].value;
        if( inputs[i].id == "refreshrate" )
            s += '!' + parseTextNumber(inputs[i].value, 5, 60000, 30);
        if( inputs[i].id == "maxreplies" )
            s += '!' + parseTextNumber(inputs[i].value, 0, 1, 3);
        if( inputs[i].id == "oldthreshhold" )
            s += '!' + parseTextNumber(inputs[i].value, 0, 86400000, 7);
    }

    GM_setValue( "settings", s );
}

function OptionsPage( focus )
{    
    clearIntervals();
    optionsLoad();

    var head = focus.getElementsByTagName("head")[0];
    var body = focus.getElementsByTagName("body")[0];
    body.innerHTML = OptionsPageHTML();
    exec_body_scripts( head );
    exec_body_scripts( body );

    var evt = getCurrentFrameDoc().createEvent('Event');  
    evt.initEvent('load', false, false);  
    window.dispatchEvent(evt);
    
    var bar = focus.getElementsByClassName("navbar");
    for( var i = 0; i < bar.length; i++ )
    {
        bar[i].appendChild(document.createTextNode("[ "));
        bar[i].appendChild(NewScriptMenuLink(function(){AllStoriesPage(getCurrentFrameDoc());}, "RSS Feed"));
        //bar[i].appendChild(document.createTextNode(" / "));
        //bar[i].appendChild(NewScriptMenuLink(function(){GetPage(WatchedThreadsPage,"_self");}, "Watched Threads"));
        bar[i].appendChild(document.createTextNode(" / "));
        bar[i].appendChild(NewScriptMenuLink(function(){OptionsPage(getCurrentFrameDoc());}, "Options"));
        bar[i].appendChild(document.createTextNode(" ]"));
    }

    var inputs = focus.getElementsByTagName("input");
    for( var i = 0; i < inputs.length; i++ )
        if( inputs[i].type == "checkbox" && thps.storyDomains.indexOf(inputs[i].value) != -1 )
            inputs[i].checked = true;

    focus.getElementById("ClearCache").onmousedown = function(){clearLocalStorage();};
    focus.getElementById("Save").onmousedown = function(){optionsSaveString(focus); optionsLoad();};
}

function AllStoriesPage( focus )
{
    clearIntervals();
    thps.posts = loadLocalPosts();

    for( var i = 0; i < thps.storyDomains.length; i++ )
    {
        var thread = new RequestThread();
        thread.requestHTML( 'http://www.touhou-project.com/' + thps.storyDomains[i] + '/rss.xml', savePostsRSS, thps.storyDomains[i] );
    }

    var head = focus.getElementsByTagName("head")[0];
    var body = focus.getElementsByTagName("body")[0];
    body.innerHTML = AllStoriesPageHTML();
    exec_body_scripts( head );
    exec_body_scripts( body );

    var evt = getCurrentFrameDoc().createEvent('Event');  
    evt.initEvent('load', false, false);  
    window.dispatchEvent(evt);
    
    var bar = focus.getElementsByClassName("navbar");
    for( var i = 0; i < bar.length; i++ )
    {
        bar[i].appendChild(document.createTextNode("[ "));
        bar[i].appendChild(NewScriptMenuLink(function(){AllStoriesPage(getCurrentFrameDoc());}, "RSS Feed"));
        //bar[i].appendChild(document.createTextNode(" / "));
        //bar[i].appendChild(NewScriptMenuLink(function(){GetPage(WatchedThreadsPage,"_self");}, "Watched Threads"));
        bar[i].appendChild(document.createTextNode(" / "));
        bar[i].appendChild(NewScriptMenuLink(function(){OptionsPage(getCurrentFrameDoc());}, "Options"));
        bar[i].appendChild(document.createTextNode(" ]"));
    }

    thps.intervals.push(setInterval( function(){
        thps.posts = loadLocalPosts();

        for( var i = 0; i < thps.storyDomains.length; i++ )
        {
            var thread = new RequestThread();
            thread.requestHTML( 'http://www.touhou-project.com/' + thps.storyDomains[i] + '/rss.xml', savePostsRSS, thps.storyDomains[i] );
        }
        var offset = window.pageYOffset;
        var head = focus.getElementsByTagName("head")[0];
        var body = focus.getElementsByTagName("body")[0];
        body.innerHTML = AllStoriesPageHTML();
        exec_body_scripts( head );
        exec_body_scripts( body );

        var evt = getCurrentFrameDoc().createEvent('Event');  
        evt.initEvent('load', false, false);  
        window.dispatchEvent(evt);
        
        var bar = focus.getElementsByClassName("navbar");
        for( var i = 0; i < bar.length; i++ )
        {
            bar[i].appendChild(document.createTextNode("[ "));
            bar[i].appendChild(NewScriptMenuLink(function(){AllStoriesPage(getCurrentFrameDoc());}, "RSS Feed"));
            //bar[i].appendChild(document.createTextNode(" / "));
            //bar[i].appendChild(NewScriptMenuLink(function(){GetPage(WatchedThreadsPage,"_self");}, "Watched Threads"));
            bar[i].appendChild(document.createTextNode(" / "));
            bar[i].appendChild(NewScriptMenuLink(function(){OptionsPage(getCurrentFrameDoc());}, "Options"));
            bar[i].appendChild(document.createTextNode(" ]"));
        }
        
        window.scrollTo(0, offset);
    }, thps.refreshRSS ));
}

function GetPage( page, focus )
{
    var open = window.open("", focus);
    page( open );
}

/////////////////////////////
// HELPER FUNCTIONS
/////////////////////////////

String.prototype.removeWhiteSpace = function()
{
    this.replace(/\t|\r|\n|\s/g,"");
    return this;
};

String.prototype.popFront = function()
{
    var size = this.length;
    var remainder = "";
    if( size > 0 )
        remainder = this.substring(1,size);
    return remainder;
};

String.prototype.popBack = function()
{
    var size = this.length;
    var remainder = "";
    if( size > 0 )
        remainder = this.substring(0,size-1);
    return remainder;
};

function nodeHTML( className, html )
{
    var node = document.createElement( "span" );
    node.className = className;
    node.innerHTML = html;
    return node;
}

function numpad( num, pad )
{
    var string = "";
    string += num;
    while (string.length < pad) string = "0" + string;
    return string;
}

function NewScriptMenuLinkBR( script, text )
{
    var line = document.createElement("li");
    var link = document.createElement("a");
    var t = document.createTextNode(text);
    line.appendChild(link);
    link.appendChild(t);
    link.href = "javascript:void(0)";
    link.onclick = script;
    return line;
}

function NewScriptMenuLink( script, text )
{
    var link = document.createElement("a");
    var t = document.createTextNode(text);
    link.appendChild(t);
    link.href = "javascript:void(0)";
    link.onclick = script;
    return link;
}

function CheckForScript( name )
{
    var scripts = document.getElementsByTagName("script");
    for( var i = 0; i < scripts.length; i++ )
        if( scripts[i].src == name )
            return true;
    return false;
}

function PrintByElementTag( doc, tag )
{
    var tags = doc.getElementsByTagName( tag );
    for( var i = 0; i < tags.length; i++ )
        console.log( tags[i] );
}


/////////////////////////////
// MAIN EXECUTION SECTION
/////////////////////////////

//clearLocalStorage();

if( CheckForScript("http://www.touhou-project.com/lib/javascript/menu.js") )
{
    var title = document.createElement("h2");
    var links = document.createElement("u1");
    title.innerHTML = 'THPsupplemental';
    links.appendChild(NewScriptMenuLinkBR(function(){AllStoriesPage(window.top.frames[1].document);}, "RSS Feed"));
    //links.appendChild(NewScriptMenuLinkBR(function(){GetPage(WatchedThreadsPage,"main");}, "Watched Threads"));
    links.appendChild(NewScriptMenuLinkBR(function(){OptionsPage(window.top.frames[1].document);}, "Options"));
    document.body.appendChild(title);
    document.body.appendChild(links);
}

if( CheckForScript("http://www.touhou-project.com/banner.js") )
{    
    var bar = document.getElementsByClassName("navbar");
    for( var i = 0; i < bar.length; i++ )
    {
        bar[i].appendChild(document.createTextNode("[ "));
        bar[i].appendChild(NewScriptMenuLink(function(){AllStoriesPage(document);}, "RSS Feed"));
        //bar[i].appendChild(document.createTextNode(" / "));
        //bar[i].appendChild(NewScriptMenuLink(function(){GetPage(WatchedThreadsPage,"_self");}, "Watched Threads"));
        bar[i].appendChild(document.createTextNode(" / "));
        bar[i].appendChild(NewScriptMenuLink(function(){OptionsPage(document);}, "Options"));
        bar[i].appendChild(document.createTextNode(" ]"));
    }
}