Greasy Fork is available in English.

Wanikani Scrollbox

Adds a space on the dashboard that displays items randomly to help remember them without seeing them in 'the wild'.

2014-12-24 일자. 최신 버전을 확인하세요.

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name        Wanikani Scrollbox
// @namespace   wkscrollbox
// @description Adds a space on the dashboard that displays items randomly to help remember them without seeing them in 'the wild'.
// @exclude	*.wanikani.com
// @include     *.wanikani.com/dashboard*
// @version     0.8.5
// @author     Samuel H
// @grant       none

/* This script is licensed under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) license
*  Details: http://creativecommons.org/licenses/by-nc/4.0/ */

//IMPORTANT: IF THIS IS THE FIRST TIME YOU'VE USED ONE OF MY SCRIPTS THEN YOU NEED TO PUT YOUR API KEY BETWEEN THE DOUBLE QUOTES ON THE LINE BELOW.
apiKey = "";

$("head").append('<script src="https://rawgit.com/WaniKani/WanaKana/master/lib/wanakana.min.js" type="text/javascript"></script>' +
                  '<script src="https://rawgit.com/tobia/Pause/master/jquery.pause.min.js" type="text/javascript"></script>"');

function getSBSection() {
    var intSectionHeight = SBHeight * 100;
    var strSection = '<section id="scroll-box-section" style="overflow: hidden; width: 100%; height: ' + (intSectionHeight + 30) + 'px; border-radius: 5px; position: relative">' +
        '<div id="scroll-box-buttons" style="width: 100%; height: 30px"></div>' +
        '<div id="scroll-box" style="overflow: hidden; width: 100%; height: ' + intSectionHeight + 'px; border-radius: 5px; position: relative">' +
            '<div id="loadingSB" style="background-color: #d4d4d4; width: 100%; height: ' + intSectionHeight + 'px; border-radius: 5px; position: relative; text-align: center; padding-top: ' + (intSectionHeight * 0.375) + 'px"></div>' +
                            '<div id="scroll-box-bg" style="background-color: #fff; width: 100%; height: ' + intSectionHeight + 'px; border-radius: 5px; position: absolute"></div>' +
            '</div></section>';
    return strSection;
}

function newSBItem() {
    
    var curSBI = -1;
    var SBIType = -1;
    var SBISrs = -1;
    var SBIIndex = -1;
    var indexArray = [];
    var indexArrayLoc = [];
    var iaLen = 0;

    if (SBRadicalsEnabled) {
        if (SBKanjiEnabled) {
            if (SBVocabularyEnabled) {
                if (SBApprenticeEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.apprentice, SBIndex.kanji.apprentice, SBIndex.vocabulary.apprentice);
                    indexArrayLoc.push([0, 0, 0], [0, 1, SBIndexCount.radicals.apprentice], [0, 2, SBIndexCount.radicals.apprentice + SBIndexCount.kanji.apprentice]);
                    iaLen = indexArray.length;
                }
                if (SBGuruEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.guru, SBIndex.kanji.guru, SBIndex.vocabulary.guru);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.guru], [1, 2, iaLen + SBIndexCount.radicals.guru + SBIndexCount.kanji.guru]);
                    iaLen = indexArray.length;
                }
                if (SBMasterEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.master, SBIndex.kanji.master, SBIndex.vocabulary.master);
                    indexArrayLoc.push([2, 0, iaLen], [2, 1, iaLen + SBIndexCount.radicals.master], [2, 2, iaLen + SBIndexCount.radicals.master + SBIndexCount.kanji.master]);
                    iaLen = indexArray.length;
                }
                if (SBEnlightenEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.enlighten, SBIndex.kanji.enlighten, SBIndex.vocabulary.enlighten);
                    indexArrayLoc.push([3, 0, iaLen], [3, 1, iaLen + SBIndexCount.radicals.enlighten], [3, 2, iaLen + SBIndexCount.radicals.enlighten + SBIndexCount.kanji.enlighten]);
                    iaLen = indexArray.length;
                }
                if (SBBurnedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.burned, SBIndex.kanji.burned, SBIndex.vocabulary.burned);
                    indexArrayLoc.push([4, 0, iaLen], [4, 1, iaLen + SBIndexCount.radicals.burned], [4, 2, iaLen + SBIndexCount.radicals.burned + SBIndexCount.kanji.burned]);
                    iaLen = indexArray.length;
                }
                if (SBLockedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.locked, SBIndex.kanji.locked, SBIndex.vocabulary.locked);
                    indexArrayLoc.push([5, 0, iaLen], [5, 1, iaLen + SBIndexCount.radicals.locked], [5, 2, iaLen + SBIndexCount.radicals.locked + SBIndexCount.kanji.locked]);
                    iaLen = indexArray.length;
                }
            } else {
                if (SBApprenticeEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.apprentice, SBIndex.kanji.apprentice);
                    indexArrayLoc.push([0, 0, 0], [0, 1, SBIndexCount.radicals.apprentice]);
                    iaLen = indexArray.length;
                }
                if (SBGuruEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.guru, SBIndex.kanji.guru);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.guru]);
                    iaLen = indexArray.length;
                }
                if (SBMasterEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.master, SBIndex.kanji.master);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.master]);
                    iaLen = indexArray.length;
                }
                if (SBEnlightenEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.enlighten, SBIndex.kanji.enlighten);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.enlighten]);
                    iaLen = indexArray.length;
                }
                if (SBBurnedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.burned, SBIndex.kanji.burned);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.burned]);
                    iaLen = indexArray.length;
                }
                if (SBLockedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.locked, SBIndex.kanji.locked);
                    indexArrayLoc.push([1, 0, iaLen], [1, 1, iaLen + SBIndexCount.radicals.locked]);
                    iaLen = indexArray.length;
                }
            }
        } else {
            if (SBVocabularyEnabled) {
                if (SBApprenticeEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.apprentice, SBIndex.vocabulary.apprentice);
                    indexArrayLoc.push([0, 0, 0], [0, 2, SBIndexCount.radicals.apprentice]);
                    iaLen = indexArray.length;
                }
                if (SBGuruEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.guru, SBIndex.vocabulary.guru);
                    indexArrayLoc.push([1, 0, iaLen], [1, 2, iaLen + SBIndexCount.radicals.guru]);
                    iaLen = indexArray.length;
                }
                if (SBMasterEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.master, SBIndex.vocabulary.master);
                    indexArrayLoc.push([2, 0, iaLen], [2, 2, iaLen + SBIndexCount.radicals.master]);
                    iaLen = indexArray.length;
                }
                if (SBEnlightenEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.enlighten, SBIndex.vocabulary.enlighten);
                    indexArrayLoc.push([3, 0, iaLen], [3, 2, iaLen + SBIndexCount.radicals.enlighten]);
                    iaLen = indexArray.length;
                }
                if (SBBurnedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.burned, SBIndex.vocabulary.burned);
                    indexArrayLoc.push([4, 0, iaLen], [4, 2, iaLen + SBIndexCount.radicals.burned]);
                    iaLen = indexArray.length;
                }
                if (SBLockedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.locked, SBIndex.vocabulary.locked);
                    indexArrayLoc.push([5, 0, iaLen], [5, 2, iaLen + SBIndexCount.radicals.locked]);
                    iaLen = indexArray.length;
                }
            } else {
                if (SBApprenticeEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.apprentice);
                    indexArrayLoc.push([0, 0, 0]);
                    iaLen = indexArray.length;
                }
                if (SBGuruEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.guru);
                    indexArrayLoc.push([1, 0, iaLen]);
                    iaLen = indexArray.length;
                }
                if (SBMasterEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.master);
                    indexArrayLoc.push([2, 0, iaLen]);
                    iaLen = indexArray.length;
                }
                if (SBEnlightenEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.enlighten);
                    indexArrayLoc.push([3, 0, iaLen]);
                    iaLen = indexArray.length;
                }
                if (SBBurnedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.burned);
                    indexArrayLoc.push([4, 0, iaLen]);
                    iaLen = indexArray.length;
                }
                if (SBLockedEnabled) {
                    indexArray = indexArray.concat(SBIndex.radicals.locked);
                    indexArrayLoc.push([5, 0, iaLen]);
                    iaLen = indexArray.length;
                }
            }
        }
    } else if (SBKanjiEnabled) {
        if (SBVocabularyEnabled) {
            if (SBApprenticeEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.apprentice, SBIndex.vocabulary.apprentice);
                indexArrayLoc.push([0, 1, 0], [0, 2, SBIndexCount.kanji.apprentice]);
                iaLen = indexArray.length;
            }
            if (SBGuruEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.guru, SBIndex.vocabulary.guru);
                indexArrayLoc.push([1, 1, iaLen], [1, 2, iaLen + SBIndexCount.kanji.guru]);
                iaLen = indexArray.length;
            }
            if (SBMasterEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.master, SBIndex.vocabulary.master);
                indexArrayLoc.push([2, 1, iaLen], [2, 2, iaLen + SBIndexCount.kanji.master]);
                iaLen = indexArray.length;
            }
            if (SBEnlightenEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.enlighten, SBIndex.vocabulary.enlighten);
                indexArrayLoc.push([3, 1, iaLen], [3, 2, iaLen + SBIndexCount.kanji.enlighten]);
                iaLen = indexArray.length;
            }
            if (SBBurnedEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.burned, SBIndex.vocabulary.burned);
                indexArrayLoc.push([4, 1, iaLen], [4, 2, iaLen + SBIndexCount.kanji.burned]);
                iaLen = indexArray.length;
            }
            if (SBLockedEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.locked, SBIndex.vocabulary.locked);
                indexArrayLoc.push([5, 1, iaLen], [5, 2, iaLen + SBIndexCount.kanji.locked]);
                iaLen = indexArray.length;
            }
        } else {
            if (SBApprenticeEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.apprentice);
                indexArrayLoc.push([0, 1, 0]);
                iaLen = indexArray.length;
            }
            if (SBGuruEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.guru);
                indexArrayLoc.push([1, 1, iaLen]);
                iaLen = indexArray.length;
            }
            if (SBMasterEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.master);
                indexArrayLoc.push([2, 1, iaLen]);
                iaLen = indexArray.length;
            }
            if (SBEnlightenEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.enlighten);
                indexArrayLoc.push([3, 1, iaLen]);
                iaLen = indexArray.length;
            }
            if (SBBurnedEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.burned);
                indexArrayLoc.push([4, 1, iaLen]);
                iaLen = indexArray.length;
            }
            if (SBLockedEnabled) {
                indexArray = indexArray.concat(SBIndex.kanji.locked);
                indexArrayLoc.push([5, 1, iaLen]);
                iaLen = indexArray.length;
            }
        }
    } else {
        if (SBApprenticeEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.apprentice);
            indexArrayLoc.push([0, 2, 0]);
            iaLen = indexArray.length;
        }
        if (SBGuruEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.guru);
            indexArrayLoc.push([1, 2, iaLen]);
            iaLen = indexArray.length;
        }
        if (SBMasterEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.master);
            indexArrayLoc.push([2, 2, iaLen]);
            iaLen = indexArray.length;
        }
        if (SBEnlightenEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.enlighten);
            indexArrayLoc.push([3, 2, iaLen]);
            iaLen = indexArray.length;
        }
        if (SBBurnedEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.burned);
            indexArrayLoc.push([4, 2, iaLen]);
            iaLen = indexArray.length;
        }
        if (SBLockedEnabled) {
            indexArray = indexArray.concat(SBIndex.vocabulary.locked);
            indexArrayLoc.push([5, 2, iaLen]);
            iaLen = indexArray.length;
        }
    }
    //alert(Object.keys(indexArray).length)
    curSBI = rand(0, Object.keys(indexArray).length - 1);
    /*if (SBIType == 0) curSBType = 0;
    else { 
       	curSBType = rand(0, 1);
        
        if (SBIType == 1) {
            if (SBRadicalsEnabled) curSBI -= Object.keys(SBRadicalData).length;
        } else if (SBIType == 2) {
            if (SBRadicalsEnabled) {
                if (SBKanjiEnabled) curSBI -= (Object.keys(SBRadicalData).length + Object.keys(SBKanjiData).length);
                else curSBI -= (Object.keys(SBRadicalData).length);
            } else if (SBKanjiEnabled) curSBI -= Object.keys(SBKanjiData).length;
        }
    }*/
    //alert(SBLockedEnabled + " " + SBEnlightenEnabled + " " + SBApprenticeEnabled);
    //curSBI = indexArrayLoc[SBICount][2];
    
    var foundLoc = false;
    
    for (var t = 1; t <= Object.keys(indexArrayLoc).length; t++) {
        /*if (t < Object.keys(indexArrayLoc).length && indexArrayLoc[t-1][2] == indexArrayLoc[t][2]) {
            indexArrayLoc = indexArrayLoc.splice(t-1);
        }*/
        if (!foundLoc) {
                if (t == Object.keys(indexArrayLoc).length || curSBI < indexArrayLoc[t][2]) {
                    SBIType = indexArrayLoc[t-1][1];
                    SBIIndex = indexArray[curSBI];
                    SBISrs = (SBIType == 0) ? SBRadicalData[SBIIndex].srs : ((SBIType == 1) ? SBKanjiData[SBIIndex].srs : SBVocabData[SBIIndex].srs);
                    switch(SBISrs) {
                        case "apprentice":
                            SBISrs = 0;
                            break;
                        case "guru":
                            SBISrs = 1;
                            break;
                        case "master":
                            SBISrs = 2;
                            break;
                        case "enlighten":
                            SBISrs = 3;
                            break;
                        case "burned":
                            SBISrs = 4;
                            break;
                        case null:
                            SBISrs = 5;
                    }
                    if (SBISrs !== indexArrayLoc[t-1][0]) alert("SRS mismatch: " + indexArrayLoc[t-1][0] + " should be " + SBISrs);
                    foundLoc = true;
                }
        }
    }

    var SBISize = rand(14, 49);
    var SBISpeed = rand(0.75, 1.25);
    var SBIx = 1170;
    var SBIy = 0;
    
    SBICount++;
    //alert(SBIndex.kanji);
    $("#scroll-box").prepend('<a href="https://www.wanikani.com/' + ((SBIType == 0) ? "radicals" : ((SBIType == 1) ? "kanji" : "vocabulary")) + '/' + 
    ((SBIType == 0) ? SBRadicalData[SBIIndex].meaning : ((SBIType == 1) ? SBKanjiData[SBIIndex].character : SBVocabData[SBIIndex].character)) +
                             '" target="_blank" id="SB' + SBICount + '" lang="ja">' + ((SBIType == 0) ? SBRadicalData[SBIIndex].character : ((SBIType == 1) ? SBKanjiData[SBIIndex].character :
                             SBVocabData[SBIIndex].character)) + '</a>');
    
    var SBI = $("#SB" + SBICount);
    SBI.css({"font-size": SBISize, "text-decoration": "none", "line-height": (SBISize * 1.25) + "px", "min-width": (SBISize * 1.1) + "px", "text-align": "center", "padding": "0px " + ((SBISize / 35) * 2) + "px 0px " + ((SBISize / 35) * 2)  + "px"});
    var SBIw = SBI.width();
    var SBIh = SBI.height();
    //alert(SBIh);
    SBIy = rand(0, (SBHeight * 100) - (SBISize * 1.25));
    switch (SBISrs) {
        case 0:
            SBI.addClass("Apprentice");
            break;
        case 1:
            SBI.addClass("Guru");
            break;
        case 2:
            SBI.addClass("Master");
            break;
        case 3:
            SBI.addClass("Enlightened");
            break;
        case 4:
            SBI.addClass("Burned");
            break;
        case 5:
            SBI.addClass("Locked");
    }
    SBI.css({"color": ((SBISrs < 5) ? "#fff" : "#E3E3E3"), "margin-top": SBIy, "left": SBIx + SBISize, "margin-right": -SBIw * 1.5, "border-radius": (SBISize * 0.15) + "px", "z-index": SBISize, "position": "absolute",
           	"-webkit-touch-callout": "none", "-webkit-user-select": "none", "-khtml-user-select": "none", "-moz-user-select": "none", "-ms-user-select": "none", "user-select": "none"});
    SBI.animate({ "left": -SBIw*1.5}, {"duration": (SBISpeed * Math.pow((SBISize / 17), -1.1)) * 49000, "complete": function() {
        																											$(this).remove();
    																											}
                                  }, "linear" );
    SBI.mouseover(function() {
        SBPause = true;
        clearInterval(newSBItemTimer);
        
        var SBIP;
        
        for (var p = 1; p <= SBICount; p++) {
            SBIP = $("#SB" + p);
            SBIP.pause();
        }
        
        SBSelect($(this), SBIType);
        $(this).attr("oldZ", $(this).css("z-index")).css("z-index", 99);
    }).mouseout(function() {
        SBPause = false;
        newSBItemTimer = setInterval(newSBItem, 1500);
        
        var SBIR;
        
        for (var r = 1; r <= SBICount; r++) {
            SBIR = $("#SB" + r);
            SBIR.resume();
        }
        SBSelect(null);
        $(this).css({"z-index": $(this).attr("oldZ")});
    });
}

function getSBRadicalData() {
    
    if (!SBLangJP) $("#loadingSB").html('<h3 style="color: #00a0f1">Retrieving radical data...</h3>');
    else $("#loadingSB").html('<h3 style="color: #00a0f1">部首データを検索中…</h3>');
    
    var req = new XMLHttpRequest();
    
    req.open('GET', 'https://www.wanikani.com/api/user/' + apiKey + '/radicals/' + SBLevels, true);
    req.onreadystatechange = function() {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                SBRadicalData = filterSBRadicalData(req.responseText.split('"character":"'));
                localStorage.setItem("SBRadicals", JSON.stringify(SBRadicalData));
                getSBKanjiData();
            } else {
                alert("error");
            }
        }
    };
    req.send();
    
}

function getSBKanjiData() {
    
    if (!SBLangJP) $("#loadingSB").html('<h3 style="color: #f100a0">Retrieving kanji data...</h3>');
    else $("#loadingSB").html('<h3 style="color: #f100a0">漢字データを検索中…</h3>');
    
    var req = new XMLHttpRequest();
    
    req.open('GET', 'https://www.wanikani.com/api/user/' + apiKey + '/kanji/' +  SBLevels , true);
    req.onreadystatechange = function() {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                SBKanjiData = filterSBKanjiData(req.responseText.split('"character":"'));
                localStorage.setItem("SBKanji", JSON.stringify(SBKanjiData));
                getSBVocabData(true);
            } else {
                alert("error");
            }
        }
    };
    req.send();

}

function getSBVocabData(firstPart) {
    
    if (!SBLangJP) $("#loadingSB").html('<h3 style="color: #a000f1">Retrieving vocabulary data...</h3>');
    else $("#loadingSB").html('<h3 style="color: #a000f1">単語データを検索中…</h3>');
        
    var req = new XMLHttpRequest();
    req.open('GET', 'https://www.wanikani.com/api/user/' + apiKey + '/vocabulary/' + ((firstPart) ? SBLevels.substring(0, SBLevels.indexOf(",26")) : SBLevels.substring(SBLevels.indexOf("26"))), true);
    req.onreadystatechange = function() {
        if (req.readyState === 4) {
            if (req.status >= 200 && req.status < 400) {
                if (!firstPart) {
                    SBVocabData[1] = req.responseText.split('"character":"');
                    SBVocabData = filterSBVocabData(SBVocabData);
                    localStorage.setItem("SBVocab", JSON.stringify(SBVocabData));
                    localStorage.setItem("SBIndex", JSON.stringify(SBIndex));
                    localStorage.setItem("SBIndexCount", JSON.stringify(SBIndexCount));
                    initScrollBox();
                } else {
                    SBVocabData[0] = req.responseText.split('"character":"');
                    getSBVocabData(false);
                }
            } else {
                alert("error");
            }
        }
    };
    req.send();
}

function switchSBLang() {
    
    SBLangJP = !SBLangJP;
    
    if (SBLangJP) {
        $(".bsbsa span").html("見習い");
        $(".bsbsg span").html("尊師");
        $(".bsbsm span").html("達人");
        $(".bsbse span").html("啓発");
        $(".bsbsb span").html("焦げ");
        $(".bsbsl span").html("ロック");
        $(".bsbtc span").html("キャッシュ").css({"font-size": "14px", "padding-top": "3px"});
        $(".bsbts span").html("スタート\nボタン").css({"font-size": "14px", "margin-top": "-3px"});
    } else {
        $(".bsbsa span").html("Appr");
        $(".bsbsg span").html("Guru");
        $(".bsbsm span").html("Master");
        $(".bsbse span").html("Enlight");
        $(".bsbsb span").html("Burned");
        $(".bsbsl span").html("Locked"); 
        $(".bsbtc span").html("Cache").css({"font-size": "inherit", "padding-top": "0px"});
        $(".bsbts span").html("Start\nButton").css({"font-size": "12px", "margin-top": "0px"});
    }
}


function getSBWKData() {
    
    if (localStorage.getItem("SBRadicals") == null || localStorage.getItem("SBKanji") == null || localStorage.getItem("SBVocab") == null) getSBRadicalData();
    else {
		SBRadicalData = JSON.parse(localStorage.getItem("SBRadicals"));
        SBKanjiData = JSON.parse(localStorage.getItem("SBKanji"));
        SBVocabData = JSON.parse(localStorage.getItem("SBVocab"));
        initScrollBox();
    }
}

function clearSBItemData() {
    localStorage.removeItem("SBRadicals");
    localStorage.removeItem("SBKanji");
    localStorage.removeItem("SBVocab");
    localStorage.removeItem("SBIndex");
    localStorage.removeItem("SBIndexCount");
    SBIndex = {
        	"radicals": {
        		"apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }, "kanji": {
                "apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }, "vocabulary": {
                "apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }
    };
    SBIndexCount = {
        	"radicals": {
        		"apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }, "kanji": {
                "apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }, "vocabulary": {
                "apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }
    };
}

function initScrollBox() {
    $("#loadingSB").remove();
    $("head").append("<style type=text/css>\
    	.bsbi div, .bsbs div, .bsbt div {\
            background-color: rgb(49, 49, 49);\
            background-image: linear-gradient(to bottom, rgb(67, 67, 67), rgb(49, 49, 49));\
            color: #E3E3E3\
			-moz-box-shadow: inset 2px 2px 2px rgba(255, 255, 255, .2), inset -2px -2px 2px rgba(0, 0, 0, .2);\
    	    -webkit-box-shadow: inset 2px 2px 2px rgba(255, 255, 255, .2), inset -2px -2px 2px rgba(0, 0, 0, .2);\
    	    box-shadow: inset 2px 2px 2px rgba(255, 255, 255, .2), inset -2px -2px 2px rgba(0, 0, 0, .2);\
        }\
        .bsbir.on {\
            background-color: #00a0f1; background-image: linear-gradient(to bottom, #0af, #0093dd);\
        }\
        .bsbik.on {\
            background-color: #f100a0; background-image: linear-gradient(to bottom, #f0a, #dd0093);\
        }\
        .bsbiv.on {\
            background-color: #a000f1; background-image: linear-gradient(to bottom, #a0f, #9300dd);\
        }\
        .bsbt .on {\
            background-color: #80c100; background-image: linear-gradient(to bottom, #8c0, #73ad00);\
        }\
		.Apprentice, .bsbsa.on {\
          background: #f100a0;\
          border-color: #f100a0;\
          background-image: linear-gradient(to bottom, #f0a, #dd0093);\
        }\
        .Guru, .bsbsg.on {\
          background: #882d9e;\
          border-color: #882d9e;\
		  background-image: linear-gradient(to bottom, #aa38c6, #882d9e);\
        }\
        .Master, .bsbsm.on {\
          background: #294ddb;\
          border-color: #294ddb;\
		  background-image: linear-gradient(to bottom, #5571e2, #294ddb);\
        }\
        .Enlightened, .bsbse.on {\
          background: #0093dd;\
          border-color: #0093dd;\
		  background-image: linear-gradient(to bottom, #0af, #0093dd);\
        }\
        .Burned, .bsbsb.on {\
          background: #434343;\
          border-color: #434343;\
		  background-image: linear-gradient(to bottom, #555, #434343);\
        }\
		.Locked, .bsbsl.on {\
		  background: #868686;\
          border-color: #313131;\
		  background-image: linear-gradient(to bottom, #bbb, #a3a3a3);\
        }\
		.on {\
		  color: #FFF\
		}\
		.SBSelect {\
		  opacity: 0.5;\
		  pointer-events: none;\
		}\
        </style>");
    $("#scroll-box-buttons").append('<div class="bsbi" style="width: 0px; height: 0px; position: absolute; z-index: 11">\
<div class="bsbir' + ((SBRadicalsEnabled) ? ' on' : '') + '" style="position: absolute"><span lang="ja" style="font-size: inherit">部首</span></div>\
<div class="bsbik' + ((SBKanjiEnabled) ? ' on' : '') + '" style="margin-left: 56px; position: absolute"><span lang="ja" style="font-size: inherit;">漢字</span></div>\
<div class="bsbiv' + ((SBVocabularyEnabled) ? ' on' : '') + '" style="margin-left: 112px; position: absolute"><span lang="ja" style="font-size: inherit">単語</span></div>\
                            </div>\
<div class="bsbs" style="width: 0px; height: 0px; position: absolute; z-index: 11">\
<div class="bsbsa' + ((SBApprenticeEnabled) ? ' on' : '') + '" style="margin-left: 168px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Appr" : "見習い") + '</span></div>\
<div class="bsbsg' + ((SBGuruEnabled) ? ' on' : '') + '" style="margin-left: 248px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Guru" : "尊師") + '</span></div>\
<div class="bsbsm' + ((SBMasterEnabled) ? ' on' : '') + '" style="margin-left: 328px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Master" : "達人") + '</span></div>\
<div class="bsbse' + ((SBEnlightenEnabled) ? ' on' : '') + '" style="margin-left: 408px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Enlight" : "啓発") + '</span></div>\
<div class="bsbsb' + ((SBBurnedEnabled) ? ' on' : '') + '" style="margin-left: 488px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Burned" : "焦げ") + '</span></div>\
<div class="bsbsl' + ((SBLockedEnabled) ? ' on' : '') + '" style="margin-left: 568px; position: absolute"><span lang="ja" style="font-size: inherit">' + ((!SBLangJP) ? "Locked" : "ロック") + '</span></div></div>\
<div class="bsbt" style="width: 0px; position: absolute; z-index: 11; margin-left: 648px">\
<div class="bsbtj' + ((SBLangJP) ? ' on' : '') + '" style="position: absolute"><span lang="ja" style="font-size: inherit">日本語</span></div>\
<div class="bsbtc' + ((SBUseCache) ? ' on' : '') + '" style="margin-left: 80px; position: absolute"><span lang="ja" style="font-size: ' + ((!SBLangJP) ? "inherit" : "14px; padding-top: 3px") + '">' + ((!SBLangJP) ? "Cache" : "キャッシュ") + '</span></div>\
<div class="bsbts' + ((SBStart) ? ' on' : '') + '" style="margin-left: 160px; position: absolute"><span lang="ja" style="font-size: ' + ((!SBLangJP) ? "12px" : "14px; margin-top: -3px") + '">' + ((!SBLangJP) ? "Start\nButton" : "スタート\nボタン") + '</span></div>\
                            </div>');
    $(".bsbi div, .bsbs div, .bsbt div").css({"background-repeat": "repeat-x", "color": "#fff", "padding": "5px 4px 0px 4px", "width": "72px", "text-align": "center", "vertical-align": "middle", 
                                              "font-size": "20px", "text-shadow": "none", "-webkit-touch-callout": "none", "-webkit-user-select": "none", "-khtml-user-select": "none",
                                              "-moz-user-select": "none", "-ms-user-select": "none", "user-select": "none"}).mouseover(function() {
        $(this).css("text-shadow", "0 0 0.2em #fff");
    }).mouseout(function() {
        $(this).css("text-shadow", "none");
    });
    $(".bsbi div, .bsbs div").css({"height": "24px"});
    $('.bsbi div').css({"width": "48px"}).click(function() {
        var cancel = false;
        if ($(this).hasClass("on")) {
            if ((SBRadicalsEnabled && SBKanjiEnabled) || (SBRadicalsEnabled && SBVocabularyEnabled) || (SBKanjiEnabled && SBVocabularyEnabled)) {
                if ($(this).attr("class") == "bsbir on") {
                    localStorage.setItem("SBRadicalsEnabled", false);
                    SBRadicalsEnabled = false;
                    //if (curSBItemType == 0) skipItem();
                } else if ($(this).attr("class") == "bsbik on") {
                    localStorage.setItem("SBKanjiEnabled", false);
                    SBKanjiEnabled = false;
                    //if (curSBItemType == 1) skipItem();
                } else if ($(this).attr("class") == "bsbiv on") {
                    localStorage.setItem("SBVocabularyEnabled", false);
                    SBVocabularyEnabled = false;
                    //if (curSBItemType == 2) skipItem();
                }
            } else cancel = true;
        } else {
            if ($(this).attr("class") == "bsbir") {
                localStorage.removeItem("SBRadicalsEnabled");
                SBRadicalsEnabled = true;
            } else if ($(this).attr("class") == "bsbik") {
                localStorage.removeItem("SBKanjiEnabled");
                SBKanjiEnabled = true;
            } else if ($(this).attr("class") == "bsbiv") {
                localStorage.removeItem("SBVocabularyEnabled");
                SBVocabularyEnabled = true;
            }
        }
        if (!cancel) $(this).toggleClass("on");
    });
	$('.bsbs div').css({"font-size": "20px", "width": "72px"}).click(function() {
        var cancel = false;
        if ($(this).hasClass("on")) {
            if ((SBApprenticeEnabled && SBGuruEnabled) || (SBApprenticeEnabled && SBMasterEnabled) || (SBApprenticeEnabled && SBEnlightenEnabled) ||
               (SBApprenticeEnabled && SBBurnedEnabled) || (SBApprenticeEnabled && SBLockedEnabled) || (SBGuruEnabled && SBMasterEnabled) ||
               (SBGuruEnabled && SBEnlightenEnabled) || (SBGuruEnabled && SBBurnedEnabled) || (SBGuruEnabled && SBLockedEnabled) ||
               (SBMasterEnabled && SBEnlightenEnabled) || (SBMasterEnabled && SBBurnedEnabled) || (SBMasterEnabled && SBLockedEnabled) ||
               (SBEnlightenEnabled && SBBurnedEnabled) || (SBEnlightenEnabled && SBBurnedEnabled) || (SBBurnedEnabled && SBLockedEnabled)) {
                if ($(this).attr("class") == "bsbsa on") {
                    localStorage.setItem("SBApprenticeEnabled", false);
                    SBApprenticeEnabled = false;
                    $(".Apprentice").css("visibility", "hidden");
                } else if ($(this).attr("class") == "bsbsg on") {
                    localStorage.setItem("SBGuruEnabled", false);
                    SBGuruEnabled = false;
                    $(".Guru").css("visibility", "hidden");
                } else if ($(this).attr("class") == "bsbsm on") {
                    localStorage.setItem("SBMasterEnabled", false);
                    SBMasterEnabled = false;
                    $(".Master").css("visibility", "hidden");
                } else if ($(this).attr("class") == "bsbse on") {
                    localStorage.setItem("SBEnlightenEnabled", false);
                    SBEnlightenEnabled = false;
                    $(".Enlightened").css("visibility", "hidden");
                } else if ($(this).attr("class") == "bsbsb on") {
                    localStorage.setItem("SBBurnedEnabled", false);
                    SBBurnedEnabled = false;
                    $(".Burned").css("visibility", "hidden");
                } else if ($(this).attr("class") == "bsbsl on") {
                    localStorage.setItem("SBLockedEnabled", false);
                    SBLockedEnabled = false;
                    $(".Locked").css("visibility", "hidden");
                }
            } else cancel = true;
        } else {
            if ($(this).attr("class") == "bsbsa") {
                localStorage.removeItem("SBApprenticeEnabled");
                SBApprenticeEnabled = true;
                $(".Apprentice").css("visibility", "inherit");
            } else if ($(this).attr("class") == "bsbsg") {
                localStorage.removeItem("SBGuruEnabled");
                SBGuruEnabled = true;
                $(".Guru").css("visibility", "inherit");
            } else if ($(this).attr("class") == "bsbsm") {
                localStorage.removeItem("SBMasterEnabled");
                SBMasterEnabled = true;
                $(".Master").css("visibility", "inherit");
            } else if ($(this).attr("class") == "bsbse") {
                localStorage.removeItem("SBEnlightenEnabled");
                SBEnlightenEnabled = true;
                $(".Enlightened").css("visibility", "inherit");
            } else if ($(this).attr("class") == "bsbsb") {
                localStorage.removeItem("SBBurnedEnabled");
                SBBurnedEnabled = true;
                $(".Burned").css("visibility", "inherit");
            } else if ($(this).attr("class") == "bsbsl") {
                localStorage.removeItem("SBLockedEnabled");
                SBLockedEnabled = true;
                $(".Locked").css("visibility", "inherit");
            }
        }
        if (!cancel) $(this).toggleClass("on");
    });
    $('.bsbt div').css({"height": "24px"}).click(function() {
        $(this).toggleClass("on");
        if ($(this).children(".bsbt div span").html() == "日本語") {
            if (!SBLangJP) localStorage.setItem("SBLangJP", true);
            else localStorage.removeItem("SBLangJP");
            switchSBLang();
        } else if ($(this).children(".bsbt div span").html() == "Cache" || $(this).children(".bsbt div span").html() == "キャッシュ") {
            if (!SBUseCache) localStorage.setItem("SBUseCache", true);
            else localStorage.removeItem("SBUseCache");
            SBUseCache = !SBUseCache;
        } else {
            if (SBStart) localStorage.setItem("SBStart", false);
            else localStorage.removeItem("SBStart");
            SBStart = !SBStart;
        }
    });
    /*$("#scroll-box-bg").click(function() {
        //StartSBDrag();
    });*/
    //for (var l = 0; l < Object.keys(SBIndex.vocabulary.locked).length; l++) alert(SBIndex.vocabulary.locked[l]);
    newSBItemTimer = setInterval(newSBItem, 1500);
}

function SBSelect(target, type) {
    $(".SBSelect").remove();
    if (target !== null) {
        $('<div class="SBSelect"></div>').insertBefore($(target));
        $(".SBSelect").attr("style", $(target).attr("style")).css({"z-index": 100, "min-width": ($(target).width() - 4), "height": ($(target).height() - 4), "background": ((type == 0) ? "#0af" : ((type == 1) ? "#f0a" : "#a0f")),
                                                                   "border": "2px inset " + ((type == 0) ? "#0093dd" : ((type == 1) ? "#dd0093" : "#9300dd"))});
    }
}

function rand(low, high) {
    return Math.floor(Math.random()*(high+1)) + low;
}

function filterSBRadicalData(data) {
    var dataArr = {};
    
    for (var d = 1; d < data.length; d++) {
        dataArr[Object.keys(dataArr).length] = {"character": data[d].substring(0, 1), "meaning": data[d].substring(data[d].indexOf('"meaning":"') + 11, data[d].indexOf('","image"')).split(", "),
                                                "image": data[d].substring(data[d].indexOf('"image":"') + 10, data[d].indexOf('","level"')).split(", "),
                                                "srs": ((data[d].indexOf('"srs":') > -1) ? data[d].substring(data[d].indexOf('"srs":"') + 7, data[d].indexOf('","unl')) : null)
                                               };
        if (dataArr[Object.keys(dataArr).length - 1].srs !== null) {
            SBIndex.radicals[dataArr[Object.keys(dataArr).length - 1].srs][SBIndexCount.radicals[dataArr[Object.keys(dataArr).length - 1].srs]] = d - 1;
            SBIndexCount.radicals[dataArr[Object.keys(dataArr).length - 1].srs]++;
        } else {
            SBIndex.radicals.locked[SBIndexCount.radicals.locked] = d - 1;
            SBIndexCount.radicals.locked++;
        }
    }
    
    //alert(SBIndexCount.radicals);
        
    return dataArr;
}

function filterSBKanjiData(data) {
    var dataArr = {};
    
    for (var d = 1; d < data.length; d++) {
        dataArr[Object.keys(dataArr).length] = {"character": data[d].substring(0, 1), "meaning": data[d].substring(data[d].indexOf('"meaning":"') + 11, data[d].indexOf('","onyomi"')).split(", "),
                                                "onyomi": data[d].substring(data[d].indexOf('"onyomi":"') + 10, data[d].indexOf('","kunyomi"')).split(", "), "kunyomi": data[d].substring(data[d].indexOf('"kunyomi":"') + 11,
                                                                                                                                                                                          data[d].indexOf('","important')).split(", "), "important_reading": data[d].substring(data[d].indexOf('"important_reading":"') + 21, data[d].indexOf('","level"')),
                                                "srs": ((data[d].indexOf('"srs":') > -1) ? data[d].substring(data[d].indexOf('"srs":"') + 7, data[d].indexOf('","unl')) : null)
                                               };
        if (dataArr[Object.keys(dataArr).length - 1].srs !== null) {
            SBIndex.kanji[dataArr[Object.keys(dataArr).length - 1].srs][SBIndexCount.kanji[dataArr[Object.keys(dataArr).length - 1].srs]] = d - 1;
            SBIndexCount.kanji[dataArr[Object.keys(dataArr).length - 1].srs]++;
        } else {
            SBIndex.kanji.locked[SBIndexCount.kanji.locked] = d - 1;
            SBIndexCount.kanji.locked++;
        }
    }
        
    return dataArr;
}

function filterSBVocabData(data) {
    var dataArr = {};
    
    for (var p = 0; p < Object.keys(data).length; p++) {
        for (var d = 1; d < Object.keys(data[p]).length; d++) {
            dataArr[Object.keys(dataArr).length] = {"character": data[p][d].substring(0, data[p][d].indexOf('"')), "kana": data[p][d].substring(data[p][d].indexOf('"kana":"') + 8, data[p][d].indexOf('","meaning"')).split(", "),
                                                    "meaning": (data[p][d].substring(data[p][d].indexOf('"meaning":"') + 11, data[p][d].indexOf('","level"'))).split(", "),
                                                    "srs": ((data[p][d].indexOf('"srs":') > -1) ? data[p][d].substring(data[p][d].indexOf('"srs":"') + 7, data[p][d].indexOf('","unl')) : null)
                                                   };
            if (dataArr[Object.keys(dataArr).length - 1].srs !== null) {
                SBIndex.vocabulary[dataArr[Object.keys(dataArr).length - 1].srs][SBIndexCount.vocabulary[dataArr[Object.keys(dataArr).length - 1].srs]] = Object.keys(dataArr).length - 1;
                SBIndexCount.vocabulary[dataArr[Object.keys(dataArr).length - 1].srs]++;
            } else {
                SBIndex.vocabulary.locked[SBIndexCount.vocabulary.locked] = Object.keys(dataArr).length - 1;
                SBIndexCount.vocabulary.locked++;
            }
        }
    }
    
    return dataArr;
}

cancelExecution = false;

if (localStorage.getItem("apiKey") !== null && localStorage.getItem("apiKey").length == 32) apiKey = localStorage.getItem("apiKey");
else if (apiKey.length == 32) localStorage.setItem("apiKey", apiKey);
else {
    cancelExecution = true;
    alert("Please enter your API key near the top of the WanaKani Scroll Box userscript.");
}

newSBItemTimer = 0;

if (!cancelExecution) {
    
    SBLangJP = (localStorage.getItem("SBLangJP") == null) ? false : true;
    SBUseCache = (localStorage.getItem("SBUseCache") == null) ? false : true;
    SBStart = (localStorage.getItem("SBStart") == null) ? true : false;
    if (localStorage.getItem("SBHeight") == null) localStorage.setItem("SBHeight", 2);
    SBHeight = localStorage.getItem("SBHeight");
    SBICount = 0;
    SBScrollLeft = 0;
    SBPause = false;
    SBRadicalsEnabled = (localStorage.getItem("SBRadicalsEnabled") !== null) ? false : true;
    SBKanjiEnabled = (localStorage.getItem("SBKanjiEnabled") !== null) ? false : true;
    SBVocabularyEnabled = (localStorage.getItem("SBVocabularyEnabled") !== null) ? false : true;
    SBApprenticeEnabled = (localStorage.getItem("SBApprenticeEnabled") !== null) ? false : true;
    SBGuruEnabled = (localStorage.getItem("SBGuruEnabled") !== null) ? false : true;
    SBMasterEnabled = (localStorage.getItem("SBMasterEnabled") !== null) ? false : true;
    SBEnlightenEnabled = (localStorage.getItem("SBEnlightenEnabled") !== null) ? false : true;
    SBBurnedEnabled = (localStorage.getItem("SBBurnedEnabled") !== null) ? false : true;
    SBLockedEnabled = (localStorage.getItem("SBLockedEnabled") !== null) ? false : true;
    SBRadicalData = {};
    SBKanjiData = {};
    SBVocabData = {};
    SBLevels = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50";
    SBIndex = (localStorage.getItem("SBIndex") !== null) ? JSON.parse(localStorage.getItem("SBIndex")) : {
        	"radicals": {
        		"apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }, "kanji": {
                "apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }, "vocabulary": {
                "apprentice": [], "guru": [], "master": [], "enlighten": [], "burned": [], "locked": []
            }
    };
    SBIndexCount =  (localStorage.getItem("SBIndexCount") !== null) ? JSON.parse(localStorage.getItem("SBIndexCount")) : {
        	"radicals": {
        		"apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }, "kanji": {
                "apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }, "vocabulary": {
                "apprentice": 0, "guru": 0, "master": 0, "enlighten": 0, "burned": 0, "locked": 0
            }
    };
    $(getSBSection()).insertBefore($(".review-status ul"));
    if (!SBLangJP) $("#loadingSB").html('<a lang="ja" href="javascript:void(0)" style="font-size: 52px; color: #434343; text-decoration: none">Start</a>');
    else $("#loadingSB").html('<a lang="ja" href="javascript:void(0)" style="font-size: 52px; color: #434343; text-decoration: none">開始</a>');
    $("#loadingSB a").click( function() {
        
        if (!SBUseCache) clearSBItemData(); 
        getSBWKData();
        
    });
    
    if (!SBStart) $("#loadingSB a").click();
    
}
// ==/UserScript==