// ==UserScript==
// @name WK Community Mnemonics
// @namespace wkcm
// @description This script allows WaniKani members to contribute their own mnemonics which appear on any page that includes item info.
// @exclude *.wanikani.com
// @exclude *.wanikani.com/level/radicals*
// @include *.wanikani.com/level/*
// @include *.wanikani.com/kanji*
// @include *.wanikani.com/vocabulary*
// @include *.wanikani.com/review/session
// @include *.wanikani.com/lesson/session
// @version 0.9.7.8
// @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/ */
CMVersion = "0.9.7.8";
CMIsReview = (window.location.pathname.indexOf("/review/") > -1);
CMIsLesson = (window.location.pathname.indexOf("/lesson/") > -1);
CMIsList = (!CMIsReview && !CMIsLesson && (new RegExp("level/[0-9]{1,2}$", "i").test(window.location.pathname.slice(window.location.pathname.indexOf("com/") + 2)) ||
new RegExp("[kanji|vocabulary].[difficulty=[A-Z]$|$]", "i").test(window.location.pathname.slice(window.location.pathname.indexOf("com/") + 2))));
CMIsChrome = (navigator.userAgent.toLowerCase().indexOf('chrome') > -1);
$("head").prepend('<script src="https://rawgit.com/jsoma/tabletop/master/src/tabletop.js" type="text/javascript"></script>' +
'<script src="https://rawgit.com/jackmoore/autosize/v1/jquery.autosize.js" type="text/javascript"></script>');
if (CMIsReview || CMIsLesson) {
$(document).ready(function() {
var checkContentLoaded = setInterval(function() {
if ((CMIsReview && $("#character span").html() !== "") || ($("#character").html() !== "" && $("#character").html() !== " ")) {
clearInterval(checkContentLoaded);
checkCMNewestVersion(0)
}
}, 1000);
});
} else {
document.addEventListener("DOMContentLoaded", function() { checkCMNewestVersion(0); });
}
var public_spreadsheet_url = 'https://docs.google.com/spreadsheet/pub?hl=en_US&hl=en_US&key=1sXSNlOITCaNbXa4bUQSfk_5Uvja6qL3Wva8bPv-3B2o&output=html';
function checkCMNewestVersion(failCount) {
$.ajax({
url: "https://gf.qytechs.cn/en/scripts/7954-wk-community-mnemonics/versions.html",
success: function(data, textStatus, jqXHR) {
var latestVersion = data.slice(data.indexOf('">v') + 3, data.indexOf("</a>", data.indexOf('">v') + 3));
var versionChanges = "";
if (CMVersionCheck.v !== latestVersion && CMVersion !== latestVersion) {
CMVersionCheck.c = false;
CMVersionCheck.v = latestVersion;
}
if (CMVersionCheck.c === false) {
versionChanges = data.slice(data.indexOf("- ", data.indexOf("</time>")) + 2, data.indexOf("</li>", data.indexOf("</time>"))).trim().replace("'", "'");
if (latestVersion !== CMVersion && confirm('It looks like you aren\'t using the latest version of WaniKani Community Mnemonics (v' + latestVersion + ').\n\n' +
'This update contains the following change(s): \n"' + versionChanges + '"\n\nWhile it is not mandatory, it is highly recommended that you update.' +
'Will you update from v' + CMVersion + ' to v' + latestVersion + '?'))
window.open('https://gf.qytechs.cn/scripts/7954-wk-community-mnemonics/code/WK%20Community%20Mnemonics.user.js', '_self');
else CMVersionCheck.c = true;
}
localStorage.setItem("CMVersionCheck", JSON.stringify(CMVersionCheck));
init();
},
error: function(jqXHR, textStatus, errorThrown) {
if (failCount < 3) checkCMNewestVersion(failCount + 1);
else alert(failCount + "An error occured while trying to check the newest version of WaniKani Community Mnemonics: " + xhr.status + ": " + xhr.statusText + ". Make sure your internet connection is working " +
"properly and then reload the page to try again.");
}
});
}
function init() {
if (!CMIsList) {
if (CMIsReview) {
initCMReview(false);
} else if (CMIsLesson) {
initCMLesson(false);
} else {
$('<h2>Community Meaning Mnemonic</h2><section id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></section>').insertAfter($("#note-meaning"));
$('<h2>Community Reading Mnemonic</h2><section id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></section>').insertAfter($("#note-reading"));
}
} else {
$(".additional-info.level-list.legend li").parent().prepend(getCMLegend(true)).prepend(getCMLegend(false));
$(".legend.level-list span.commnem").css("background-color", "#71aa00").parent().parent().parent().children("li").css("width", 188).parent().children("li:first-child, li:nth-child(6)")
.css("width", 187);
$(".legend.level-list span.commnem-req").css("background-color", "#e1aa00");
}
//Start Code Credit: jsoma from Github
try {
Tabletop.init( { key: public_spreadsheet_url,
callback: showInfo,
simpleSheet: true } );
} catch(e) {
if (!CMIsReview && !CMIsLesson) $(".loadingCM").html("An error occurred while trying to access the database; reload the page to try again.");
else alert('The following error occurred while trying to access the database: "' + e + '". If the problem persists, make sure your internet connection is working properly.');
}
//End Code Credit
}
function initCMList() {
initCMTableItems();
if (CMIndex === 0) {
CMType = "k";
$("#level-" + window.location.pathname.slice(window.location.pathname.lastIndexOf("/") + 1) + "-kanji .character-item").each(checkCMComMnem);
CMType = "v";
$("#level-" + window.location.pathname.slice(window.location.pathname.lastIndexOf("/") + 1) + "-vocabulary .character-item").each(checkCMComMnem);
} else {
if (CMIndex === 1) {
CMType = "k";
$(".character-item").each(checkCMComMnem);
} else {
CMType = "v";
$(".character-item").each(checkCMComMnem);
}
}
$("head").append('<style type="text/css">' +
'.commnem-badge, .commnem-badge-req { position: absolute; left: 0 } ' +
'.commnem-badge:before, .commnem-badge-req:before { ' +
'content: "\\5171\"; display: block; position: absolute; top: -0.6em; left: -0.6em; width: 2em; height: 2em; color: #fff; font-size: 16px; font-weight: normal; ' +
'line-height: 2.2em; -webkit-box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset,0 0 10px rgba(255,255,255,0.5); ' +
'-moz-box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset,0 0 10px rgba(255,255,255,0.5); box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset,0 0 10px rgba(255,255,255,0.5); ' +
'-webkit-border-radius: 50%; -moz-border-radius: 50%; border-radius: 50%; z-index: 999 }' +
'ul.multi-character-grid .commnem-badge:before, ul.multi-character-grid .commnem-badge-req:before { top: 1.1em; left: -1.1em; font-size: 11px; text-align: center }' +
'.commnem-badge:before { background-color: #71aa00; text-shadow: 0 2px 0 #1a5300; }' +
'.commnem-badge-req:before { background-color: #e1aa00; text-shadow: 0 2px 0 #7a5300 }</style>');
$(".commnem-badge, .commnem-badge-req").fadeIn();
}
function checkCMComMnem() {
CMChar = $(this).children("a").children(".character").text();
CMIndex = getCMIndex() + 2;
if (CMIndex > 1 && CMData[CMType][CMChar] !== undefined) {
if (!CMInitData) {
if (!CMDataMatch(CMData[CMType][CMChar])) {
CMData[CMType][CMChar].m.t = CMTableData[CMIndex - 2].Meaning_Mnem.split("|");
CMData[CMType][CMChar].m.u = CMTableData[CMIndex - 2].Meaning_User.split("|");
CMData[CMType][CMChar].r.t = CMTableData[CMIndex - 2].Reading_Mnem.split("|");
CMData[CMType][CMChar].r.u = CMTableData[CMIndex - 2].Reading_User.split("|");
} else CMDataConvert();
}
if (CMData[CMType][CMChar].m.t[0].length > 0 || CMData[CMType][CMChar].r.t[0].length > 0 || CMData[CMType][CMChar].m.t[0] == "!" || CMData[CMType][CMChar].r.t[0] == "!") {
var isReq = (CMData[CMType][CMChar].m.t[0] == "!" || CMData[CMType][CMChar].r.t[0] == "!");
if (($(this).children(".recently-unlocked-badge").length > 0)) $(getCMBadge(true, isReq)).insertAfter($(this).children("span")).hide().prev().css("top", "-0.5em");
else $(getCMBadge(false, isReq)).insertAfter($(this).children("span")).hide();
}
}
}
function getCMLegend(isReq) {
return $('<li><div><span class="commnem' + ((isReq) ? "-req" : "") + '" lang="ja">共</span></div>' + ((isReq) ? "Mnemonic Requested" : "Community Mnemonics") + '</li>');
}
function getCMBadge(isRecent, isReq) {
return $('<span lang="ja" ' + ((isRecent) ? ' style="top: ' + ((CMType == "k") ? '2.25em" ' : '1em" ') : '') + 'class="item-badge commnem-badge' + ((isReq) ? "-req" : "") + '"></span>');
}
function initCMReview(isLessonQuiz) {
if (isLessonQuiz) {
CMIsReview = true;
$("#cm-meaning, #cm-reading").prev().remove();
$("#cm-meaning, #cm-reading").remove();
$("#supplement-nav li:nth-child(2), #supplement-nav li:nth-child(3)").off("click", clickCMLessonTab);
$("#supplement-nav li:last-child").off("click", clickLastLessonTab);
$("#batch-items li:not(.active)").off("click", clickCMLessonItem);
var checkFirstItemLoaded = setInterval(function() {
if ((!isLessonQuiz && $("#character span").html() !== "" && $("#character span").html() !== undefined) || (isLessonQuiz && $("#character").html() !== "" && $("#character").html() !== undefined))
clearInterval(checkFirstItemLoaded);
newCMReviewItem();
}, 300);
}
$("#user-response").next().on("click", clickCMReviewSubmit);
$("#all-info").on("click", clickCMReviewAllInfo);
}
function clickCMReviewSubmit() {
if ($(this).prev().attr("disabled") == "disabled") {
var oldChar = CMChar;
var oldType = CMType;
if (!CMIsLesson) {
CMChar = decodeURIComponent($("#character span").html());
CMType = $("#character").attr("class") !== "radical" ? (($("#character").attr("class") == "kanji") ? "k" : "v") : "r";
} else {
CMChar = decodeURIComponent($("#character").html());
CMType = $("#main-info").attr("class") !== "radical" ? (($("#main-info").attr("class") == "kanji") ? "k" : "v") : "r";
}
if (oldChar !== CMChar || oldType !== CMType) {
CMReady = false;
newCMReviewItem();
}
var checkInfoLoaded = setInterval(function() {
if (CMReady && !$("#screen-lesson-ready").is(":visible") && $("#item-info-col2").html().length > 0 && $("#option-item-info").hasClass("active") &&
$("#additional-content-load").css("display") !== "block") {
clearInterval(checkInfoLoaded);
if ($("#cm-meaning").length == 0 && $("#cm-reading").length == 0) {
$('<h2>Community Meaning Mnemonic</h2><section id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></section>')
.insertAfter($("#note-meaning"));
$('<h2>Community Reading Mnemonic</h2><section id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></section>')
.insertAfter($("#note-reading"));
if (CMType !== "r") loadCM(false, false);
} else if ($("#item-info-col2 #cm-meaning").length === 0 && $("#item-info-col2 #cm-reading").length === 0) {
var checkPreloadReady = setInterval(function() {
if (CMPreloadReady) {
clearInterval(checkPreloadReady);
CMReady = false;
var meaning = $("#cm-meaning-container").detach();
var reading = $("#cm-reading-container").detach();
meaning.insertAfter($("#note-meaning")).children("h2, div").unwrap();
reading.insertAfter($("#note-reading")).children("h2, div").unwrap();
updateCMMargins(true, true);
}
}, 250);
}
if ($("#all-info").css("display") !== "none") {
if (!$("#question-type").hasClass("meaning") || CMType == "r") $("#cm-meaning").hide().prev().hide();
if (!$("#question-type").hasClass("reading") || CMType == "r") $("#cm-reading").hide().prev().hide();
}
} else if ($("#screen-lesson-ready").is(":visible") || $("#quiz").css("display") == "none") {
clearInterval(checkInfoLoaded);
if (CMIsReview) initCMLesson(true);
} else if (CMReady && $("#cm-meaning").length === 0 && $("#cm-reading").length === 0) {
$("#information")
.append($('<div id="cm-meaning-container" style="display: none"><h2>Community Meaning Mnemonic</h2><section id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></section></div>'))
.append($('<div id="cm-reading-container" style="display: none"><h2>Community Reading Mnemonic</h2><section id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></section></div>'));
if (CMType !== "r") loadCM(false, false);
}
}, 500);
$("#user-response").next().one("click", function() {
setTimeout(function() {
if (CMReady && !$("#screen-lesson-ready").is(":visible")) clearInterval(checkInfoLoaded);
}, 500);
});
} else {
setTimeout(function() {
$("#cm-meaning-container").remove();
$("#cm-reading-container").remove();
CMReady = false;
newCMReviewItem();
}, 300);
}
}
function clickCMReviewAllInfo() {
$("#note-meaning + h2").show();
$("#note-reading + h2").show();
updateCMMargins(true, true);
}
function newCMReviewItem() {
CMPreloadReady = false;
if (!CMIsLesson) {
CMChar = decodeURIComponent($("#character span").html());
CMType = $("#character").attr("class") !== "radical" ? (($("#character").attr("class") == "kanji") ? "k" : "v") : "r";
} else {
CMChar = decodeURIComponent($("#character").html());
CMType = $("#main-info").attr("class") !== "radical" ? (($("#main-info").attr("class") == "kanji") ? "k" : "v") : "r";
}
if (CMType !== "r") {
$("#cm-meaning, #note-meaning + h2").remove();
$("#cm-reading, #note-reading + h2").remove();
if (CMData[CMType][CMChar] === undefined) {
CMIndex = Object.keys(CMData.k).length + Object.keys(CMData.v).length + 2;
CMSettings[CMType][CMChar] = {"m": {"p": "", "c": false}, "r": {"p": "", "c": false}};
CMVotes[CMType][CMChar] = {"m": [], "r": []};
CMData[CMType][CMChar] = {"i": CMIndex, "m": {"t": [""], "s": [], "u": [""]}, "r": {"t": [""], "s": [], "u": [""]}};
CMPageIndex = {"m": 0, "r": 0};
CMSortMap = getCMSortMap([], []);
CMPageMap = getCMPageMap([], []);
checkCMTableChanges(true);
var checkPostReady = setInterval(function() {
if (CMPostReady) {
clearInterval(checkPostReady);
postCM(0);
}
}, 200);
} else {
checkCMTableChanges(false);
if (!CMInitData) CMDataConvert();
CMSortMap = getCMSortMap(CMData[CMType][CMChar].m.s, CMData[CMType][CMChar].r.s);
CMPageMap = getCMPageMap(CMData[CMType][CMChar].m.u, CMData[CMType][CMChar].r.u);
CMSettingsCheck();
if (CMVotes[CMType][CMChar] === undefined) CMVotes[CMType][CMChar] = {"m": [], "r": []};
}
if (CMData[CMType][CMChar] !== undefined) CMPageIndex = {"m": $.inArray( CMPageMap.m[CMSettings[CMType][CMChar].m.p], CMSortMap.m ),
"r": $.inArray( CMPageMap.r[CMSettings[CMType][CMChar].r.p], CMSortMap.r )};
}
}
function initCMLesson(fromLessonQuiz) {
if (fromLessonQuiz) {
CMIsReview = false;
$("#user-response").next().off("click", clickCMReviewSubmit);
$("#all-info").off("click", clickCMReviewAllInfo);
}
var checkLessonReady = setInterval(function() {
if (!$("#screen-lesson-ready").is(":visible")) {
clearInterval(checkLessonReady);
if (fromLessonQuiz) {
CMChar = decodeURIComponent($("#character").html());
CMType = (($("#main-info").attr("class") !== "radical") ? (($("#main-info").attr("class") == "kanji") ? "k" : "v") : "r");
if (CMType !== "r") {
$('<h2>Community Meaning Mnemonic</h2><div id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-meaning-notes"));
$('<h2>Community Reading Mnemonic</h2><div id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-reading-notes"));
}
if (CMData[CMType][CMChar] === undefined) {
CMIndex = Object.keys(CMData.k).length + Object.keys(CMData.v).length + 2;
CMSettings[CMType][CMChar] = {"m": {"p": "", "c": false}, "r": {"p": "", "c": false}};
CMVotes[CMType][CMChar] = {"m": [], "r": []};
CMData[CMType][CMChar] = {"i": CMIndex, "m": {"t": [""], "s": [], "u": [""]}, "r": {"t": [""], "s": [], "u": [""]}};
CMPageIndex = {"m": 0, "r": 0};
CMSortMap = getCMSortMap([], []);
CMPageMap = getCMPageMap([], []);
checkCMTableChanges(true);
var checkPostReady = setInterval(function() {
if (CMPostReady) {
clearInterval(checkPostReady);
postCM(0);
}
}, 200);
} else {
checkCMTableChanges(false);
if (!CMInitData) CMDataConvert();
CMSortMap = getCMSortMap(CMData[CMType][CMChar].m.s, CMData[CMType][CMChar].r.s);
CMPageMap = getCMPageMap(CMData[CMType][CMChar].m.u, CMData[CMType][CMChar].r.u);
CMSettingsCheck();
if (CMVotes[CMType][CMChar] === undefined) CMVotes[CMType][CMChar] = {"m": [], "r": []};
}
if (CMData[CMType][CMChar] !== undefined) CMPageIndex = {"m": $.inArray( CMPageMap.m[CMSettings[CMType][CMChar].m.p], CMSortMap.m ),
"r": $.inArray( CMPageMap.r[CMSettings[CMType][CMChar].r.p], CMSortMap.r )};
loadCM(false, false);
}
$("#supplement-nav li:nth-child(2), #supplement-nav li:nth-child(3)").on("click", clickCMLessonTab);
$("#supplement-nav li:last-child").on("click", clickLastLessonTab);
$("#batch-items li:not(.active)").on("click", clickCMLessonItem);
}
}, 300);
}
function clickCMLessonItem() {
CMReady = false;
setTimeout(function() {
var prevType = CMType;
CMChar = decodeURIComponent($("#character").html());
CMType = ($("#main-info").attr("class") !== "radical") ? (($("#main-info").attr("class") == "kanji") ? "k" : "v") : "r";
if (CMType !== "r") {
if (CMType !== prevType) {
$("#cm-meaning, #cm-reading").prev().remove();
$("#cm-meaning, #cm-reading").remove();
$('<h2>Community Meaning Mnemonic</h2><div id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-meaning-notes"));
$('<h2>Community Reading Mnemonic</h2><div id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-reading-notes"));
} else $("#cm-meaning, #cm-reading").html('<p class="loadingCM">Loading...</p>');
if (CMData[CMType][CMChar] === undefined) {
CMIndex = Object.keys(CMData.k).length + Object.keys(CMData.v).length + 2;
CMSettings[CMType][CMChar] = {"m": {"p": "", "c": false}, "r": {"p": "", "c": false}};
CMVotes[CMType][CMChar] = {"m": [], "r": []};
CMData[CMType][CMChar] = {"i": CMIndex, "m": {"t": [""], "s": [], "u": [""]}, "r": {"t": [""], "s": [], "u": [""]}};
CMPageIndex = {"m": 0, "r": 0};
CMSortMap = getCMSortMap([], []);
CMPageMap = getCMPageMap([], []);
checkCMTableChanges(true);
var checkPostReady = setInterval(function() {
if (CMPostReady) {
clearInterval(checkPostReady);
postCM(0);
}
}, 200);
} else {
checkCMTableChanges(false);
if (!CMInitData) CMDataConvert();
CMSortMap = getCMSortMap(CMData[CMType][CMChar].m.s, CMData[CMType][CMChar].r.s);
CMPageMap = getCMPageMap(CMData[CMType][CMChar].m.u, CMData[CMType][CMChar].r.u);
CMSettingsCheck();
if (CMVotes[CMType][CMChar] === undefined) CMVotes[CMType][CMChar] = {"m": [], "r": []};
}
if (CMData[CMType][CMChar] !== undefined) CMPageIndex = {"m": $.inArray( CMPageMap.m[CMSettings[CMType][CMChar].m.p], CMSortMap.m ),
"r": $.inArray( CMPageMap.r[CMSettings[CMType][CMChar].r.p], CMSortMap.r )};
loadCM(false, false);
}
$("#supplement-nav li:last-child").off("click", clickLastLessonTab).on("click", clickLastLessonTab);
}, 200);
}
function clickCMLessonTab() {
var failCount = 0;
var checkReady = setInterval(function() {
if (CMReady) {
clearInterval(checkReady);
var failCount = 0;
if ($(this).attr("data-index") == 1) {
var checkMeaningVisible = setInterval(function() {
if ($("#cm-meaning p").width() > 0) {
clearInterval(checkMeaningVisible);
updateCMMargins(true, false);
} else if (failCount < 30) failCount++;
else clearInterval(checkMeaningVisible);
}, 100);
} else {
var checkReadingVisible = setInterval(function() {
if ($("#cm-reading p").width() > 0) {
clearInterval(checkReadingVisible);
updateCMMargins(false, true);
} else if (failCount < 30) failCount++;
else clearInterval(checkReadingVisible);
}, 100);
}
} else if (failCount < 10) failCount++;
else clearInterval(checkReady);
}, 200);
}
function clickLastLessonTab() {
if ($("#batch-items .read").length >= $("#batch-items li").length - 2) {
var checkLessonQuiz = setInterval(function() {
if ($("#quiz").css("display") !== "none") {
clearInterval(checkLessonQuiz);
initCMReview(true);
}
}, 500);
$("#supplement-nav li").one("click", function() {
clearInterval(checkLessonQuiz);
});
}
}
function showInfo(data, tabletop) {
var curItem = "";
var curType = "";
var curM = [];
var curR = [];
var curMText = "";
var curRText = "";
var curMScores = 0;
var curRScores = 0;
var curMUsers = "";
var curRUsers = "";
var curMLength = 0;
var curRLength = 0;
var curSortMap = [];
var curPageMap = [];
var newItem = true;
var addItems = Object.keys(data).length;
CMTableData = data;
if (!CMIsList) {
CMChar = (CMIsReview) ? decodeURIComponent($("#character span").html()) : ((CMIsLesson) ? decodeURIComponent($("#character").html()) :
decodeURIComponent(window.location.pathname.substring(window.location.pathname.lastIndexOf("/") + 1)));
CMType = (CMIsReview) ? (($("#character").attr("class") !== "radical") ? (($("#character").attr("class") == "kanji") ? "k" : "v") : "r") :
((CMIsLesson) ? (($("#main-info").attr("class") !== "radical") ? (($("#main-info").attr("class") == "kanji") ? "k" : "v") : "r") : ((window.location.pathname.indexOf("kanji") > -1) ? "k" : "v"));
for (var a = 0; a < Object.keys(data).length; a++) {
if (data[a].Item.substring(1) == CMChar && data[a].Item.substring(0, 1) == CMType) {
newItem = false;
CMIndex = a + 2;
break;
}
}
} else {
var urlString = window.location.pathname;
newItem = false;
if ((urlString).indexOf("/level/") > -1) CMIndex = 0;
else {
if ((urlString).indexOf("/kanji") > -1) CMIndex = 1;
else CMIndex = 2;
}
}
if (CMInitSettings || CMInitVotes) CMInitData = true;
if (!CMInitData && !newItem && Object.keys(data).length > (Object.keys(CMData.k).length + Object.keys(CMData.v).length)) {
var lastItem = data[Object.keys(CMData.k).length + Object.keys(CMData.v).length - 1].Item;
if (lastItem == "k" + Object.keys(CMData.k)[Object.keys(CMData.k).length - 1] || lastItem == "v" + Object.keys(CMData.v)[Object.keys(CMData.v).length - 1]) addItems = Object.keys(CMData.k).length + Object.keys(CMData.v).length;
else {
CMInitData = true;
CMData = {"k": [], "v": []};
}
} else if (!CMInitData && Object.keys(data).length < (Object.keys(CMData.k).length + Object.keys(CMData.v).length)) {
CMInitData = true;
CMData = {"k": [], "v": []};
}
for (var d = 0; d < Object.keys(data).length; d++) {
if (CMInitData || d + 2 == CMIndex || d >= addItems) {
curItem = data[d].Item.substring(1);
curType = data[d].Item.substring(0, 1);
curMText = data[d].Meaning_Mnem.split("|");
curRText = data[d].Reading_Mnem.split("|");
curMScores = data[d].Meaning_Score.split("|");
curRScores = data[d].Reading_Score.split("|");
curMUsers = data[d].Meaning_User.split("|");
curRUsers = data[d].Reading_User.split("|");
curMLength = curMUsers.length;
curRLength = curRUsers.length;
if (!CMIsList && !newItem && d + 2 == CMIndex) {
if (CMData[CMType][CMChar] == undefined) {
CMData[CMType][CMChar] = {"m": {"t": curMText, "s": curMScores, "u": curMUsers}, "r": {"t": curRText, "s": curRScores, "u": curRUsers}};
}
if (!CMInitData) CMDataConvert();
CMSortMap = getCMSortMap(curMScores, curRScores);
CMPageMap = getCMPageMap(curMUsers, curRUsers);
}
curSortMap = (d + 2 !== CMIndex) ? getCMSortMap(curMScores, curRScores) : CMSortMap;
curPageMap = (d + 2 !== CMIndex) ? getCMPageMap(curMUsers, curRUsers) : CMPageMap;
if (CMInitSettings || CMSettings[curType][curItem] === undefined ) CMSettings[curType][curItem] = {"m": {"p": ((curMLength > 0) ? curMUsers[curSortMap.m[0]] : ""),
"c": ((($.inArray( CMUser, curMUsers )) > -1))}, "r": {"p": ((curRLength > 0) ? curRUsers[curSortMap.r[0]] : ""), "c": (($.inArray( CMUser, curRUsers )) > -1)}};
else {
if (($.inArray( CMSettings[curType][curItem].m.p, curMUsers )) < 0) CMSettings[curType][curItem].m.p = curMUsers[curSortMap.m[0]];
if (($.inArray( CMSettings[curType][curItem].r.p, curRUsers )) < 0) CMSettings[curType][curItem].r.p = curRUsers[curSortMap.r[0]];
CMSettings[curType][curItem].m.c = (($.inArray( CMUser, curMUsers )) > -1);
CMSettings[curType][curItem].r.c = (($.inArray( CMUser, curRUsers )) > -1);
}
if (CMInitVotes || CMVotes[curType][curItem] === undefined) {
CMVotes[curType][curItem] = {"m": [], "r": []};
for (var mv = 0; mv < curMLength; mv++) CMVotes[curType][curItem].m[curMUsers[mv] + ":" + curMText[mv]] = 0;
for (var rv = 0; rv < curRLength; rv++) CMVotes[curType][curItem].r[curRUsers[rv] + ":" + curRText[rv]] = 0;
}
for (var ms = 0; ms < curMLength; ms++) curMScores[ms] = parseInt(curMScores[ms]);
for (var rs = 0; rs < curRLength; rs++) curRScores[rs] = parseInt(curRScores[rs]);
CMData[curType][curItem] = {"i": d + 2, "m": {"t": curMText, "s": curMScores, "u": curMUsers}, "r": {"t": curRText, "s": curRScores, "u": curRUsers}};
curM = [];
curR = [];
if (!CMInitData && addItems == Object.keys(data).length) break;
}
}
if (newItem) {
if (CMChar.length > 0 && CMChar !== " " && CMType !== "r") {
CMIndex = (CMInitSettings) ? d : Object.keys(data).length + 2;
CMSettings[CMType][CMChar] = {"m": {"p": "", "c": false}, "r": {"p": "", "c": false}};
CMVotes[CMType][CMChar] = {"m": [], "r": []};
CMData[CMType][CMChar] = {"i": d + 2, "m": {"t": [""], "s": [], "u": [""]}, "r": {"t": [""], "s": [], "u": [""]}};
CMSortMap = getCMSortMap([], []);
CMPageMap = getCMPageMap([], []);
CMPageIndex.m = 0;
CMPageIndex.r = 0;
postCM(0);
}
} else {
if (!CMIsList) CMPageIndex = {"m": $.inArray( CMPageMap.m[CMSettings[CMType][CMChar].m.p], CMSortMap.m ), "r": $.inArray( CMPageMap.r[CMSettings[CMType][CMChar].r.p], CMSortMap.r )};
CMReady = true;
}
saveCMData();
saveCMSettings();
if (CMInitVotes) saveCMVotes();
if (CMIsLesson) {
if (CMType !== "r") {
$('<h2>Community Meaning Mnemonic</h2><div id="cm-meaning" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-meaning-notes"));
$('<h2>Community Reading Mnemonic</h2><div id="cm-reading" class="cm"><p class="loadingCM">Loading...</p></div>')
.insertAfter($("#supplement-" + ((CMType == "k") ? "kan" : "voc") + "-reading-notes"));
}
}
if (!CMIsReview && !CMIsList) loadCM(false, false);
else if (CMIsList) initCMList();
}
function updateCMText(isMeaning) {
var isMeaningStr = ((isMeaning) ? "m" : "r");
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-mnem-text").html(CMData[CMType][CMChar][isMeaningStr].t[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] +
'<br />by <a href="https://www.wanikani.com/community/people/' + CMData[CMType][CMChar][isMeaningStr].u[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] + '" target="_blank">' +
CMData[CMType][CMChar][isMeaningStr].u[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] + '</a>');
checkCMTextHighlight(isMeaning);
if (CMData[CMType][CMChar][isMeaningStr].u[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] == CMUser) $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-user-buttons div").removeClass("disabled");
else $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-user-buttons div").addClass("disabled");
updateCMMargins(isMeaning, !isMeaning);
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").html(CMData[CMType][CMChar][isMeaningStr].s[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]]);
if (CMData[CMType][CMChar][isMeaningStr].s[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] !== 0) {
if (CMData[CMType][CMChar][isMeaningStr].s[CMSortMap[isMeaningStr][CMPageIndex[isMeaningStr]]] > 0) $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("neg").addClass("pos");
else $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("pos").addClass("neg");
} else $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("pos").removeClass("neg");
}
function updateCMMargins(meaning, reading) {
if (meaning) {
$("#cm-meaning-info").css("margin-top", ($("#cm-meaning .cm-mnem-text").height() + 20 + ((CMIsReview || CMIsLesson) ? ((CMIsReview) ? 5 : 3) : 0)) + "px");
$("#cm-meaning-user-buttons").css({"margin-top": "-20px"});
$("#cm-meaning-next").css("margin-left", Math.min($("#cm-meaning .cm-mnem-text").width() + $("#cm-meaning-next").width() + 40,
$("#cm-meaning").width() - $("#cm-meaning-next").width() - 10) + "px");
}
if (reading) {
$("#cm-reading-info").css("margin-top", ($("#cm-reading .cm-mnem-text").height() + 20 + ((CMIsReview || CMIsLesson) ? ((CMIsReview) ? 5 : 3) : 0)) + "px");
$("#cm-reading-user-buttons").css({"margin-top": "-20px"});
$("#cm-reading-next").css("margin-left", Math.min($("#cm-reading .cm-mnem-text").width() + $("#cm-reading-next").width() + 40,
$("#cm-reading").width() - $("#cm-reading-next").width() - 10) + "px");
}
}
function checkCMTextHighlight(isMeaning) {
if (!CMIsReview && !CMIsLesson) {
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-mnem-text").children("[class]").each(function() {
if ($(this).attr("class").slice($(this).attr("class").indexOf("-") + 1) !== "highlight") $(this).attr("class", $(this).attr("class").slice($(this).attr("class").indexOf("-") + 1) + "-highlight");
});
}
}
function checkCMHTMLTags(text) {
var isValid = true;
var tags = ["b", "i", "u", "s", "span"];
var regOpen;
var regClose;
var regBR;
if (!new RegExp("<(a|script)", "ig").test($("#cm-reading-text").val())) {
for (var c = 0; c < tags.length; c++) {
if (tags[c] !== "span") {
regOpen = new RegExp("<" + tags[c] + ">", "ig");
regClose = new RegExp("</" + tags[c] + ">", "ig");
} else {
regOpen = new RegExp("<" + tags[c], "ig");
regClose = new RegExp("</" + tags[c], "ig");
}
if (text.match(regOpen) !== null && text.match(regClose) !== null) {
if (text.match(regOpen).length !== text.match(regClose).length) isValid = false;
} else if (text.match(regOpen) !== null || text.match(regClose) !== null) isValid = false;
if (!isValid) break;
}
} else return false;
return isValid;
}
function checkCMTableChanges(post) {
CMPostReady = false;
try {
Tabletop.init( { key: public_spreadsheet_url,
callback: onTableLoaded,
simpleSheet: true } );
} catch(e) {
if (!CMIsReview) $(".loadingCM").html("An error occurred while trying to access the database; reload the page to try again.");
else alert('The following error occurred while trying to access the database: "' + e + '". If the problem persists, make sure your internet connection is working properly.');
}
function onTableLoaded(data, tabletop) {
CMTableData = data;
initCMTableItems()
CMIndex = getCMIndex() + 2;
if (CMIndex < 2) CMIndex += data.length + 1;
if (post) CMPostReady = true;
else {
if (!CMInitData && CMIndex < CMTableData.length) {
if (!CMDataMatch(CMData[CMType][CMChar])) {
CMData[CMType][CMChar].m.t = CMTableData[CMIndex].Meaning_Mnem.split("|");
CMData[CMType][CMChar].m.u = CMTableData[CMIndex].Meaning_User.split("|");
CMData[CMType][CMChar].r.t = CMTableData[CMIndex].Reading_Mnem.split("|");
CMData[CMType][CMChar].r.u = CMTableData[CMIndex].Reading_User.split("|");
CMVotes[CMType][CMChar] = getCMVotes();
} else CMDataConvert();
}
CMReady = true;
}
}
}
function initCMTableItems() {
CMTableItems = [];
for (var i = 0; i < CMTableData.length; i++) CMTableItems[i] = CMTableData[i].Item;
}
function getCMIndex() {
return $.inArray(CMType + CMChar, CMTableItems);
}
function checkCMVotes(meaning, reading) {
if (meaning && CMData[CMType][CMChar].m.t.length > 0 && CMVotes[CMType][CMChar].m[CMData[CMType][CMChar].m.u[CMSortMap.m[CMPageIndex.m]] + ":" + CMData[CMType][CMChar].m.t[CMSortMap.m[CMPageIndex.m]]] === undefined) {
if (CMData[CMType][CMChar].m.t[0] !== "!") {
CMVotes[CMType][CMChar].m[CMData[CMType][CMChar].m.u[CMSortMap.m[CMPageIndex.m]] + ":" + CMData[CMType][CMChar].m.t[CMSortMap.m[CMPageIndex.m]]] = 0;
saveCMVotes();
}
}
if (reading && CMData[CMType][CMChar].r.t.length > 0 && CMVotes[CMType][CMChar].r[CMData[CMType][CMChar].r.u[CMSortMap.r[CMPageIndex.r]] + ":" + CMData[CMType][CMChar].r.t[CMSortMap.r[CMPageIndex.r]]] === undefined) {
if (CMData[CMType][CMChar].r.t[0] !== "!") {
CMVotes[CMType][CMChar].r[CMData[CMType][CMChar].r.u[CMSortMap.r[CMPageIndex.r]] + ":" + CMData[CMType][CMChar].r.t[CMSortMap.r[CMPageIndex.r]]] = 0;
saveCMVotes();
}
}
}
function getCMVotes() {
var votes = {"m": [], "r": []};
for (var mv = 0; mv < CMData[CMType][CMChar].m.t.length; mv++) {
if (votes.m[CMData[CMType][CMChar].m.u[mv] + ":" + CMData[CMType][CMChar].m.t[mv]] === undefined)
votes.m[CMData[CMType][CMChar].m.u[mv] + ":" + CMData[CMType][CMChar].m.t[mv]] = 0;
}
for (var rv = 0; rv < CMData[CMType][CMChar].r.t.length; rv++) {
if (votes.r[CMData[CMType][CMChar].r.u[rv] + ":" + CMData[CMType][CMChar].r.t[rv]] === undefined)
votes.r[CMData[CMType][CMChar].r.u[rv] + ":" + CMData[CMType][CMChar].r.t[rv]] = 0;
}
return votes;
}
function getCMSortMap(MScores, RScores) {
var sortMap = {"m": [], "r": []};
var MScoresSorted = [];
var RScoresSorted = [];
if (MScores[0] !== undefined && MScores[0] !== null) {
MScoresSorted = MScores.slice(0).sort(sortByScore);
for (var mu = 0; mu < MScores.length; mu++) {
for (var ms = 0; ms < MScores.length; ms++) {
if (sortMap.m[ms] == undefined && MScores[mu] == MScoresSorted[ms]) {
sortMap.m[ms] = mu;
break;
}
}
}
}
if (RScores[0] !== undefined && RScores[0] !== null) {
RScoresSorted = RScores.slice(0).sort(sortByScore);
for (var ru = 0; ru < RScores.length; ru++) {
for (var rs = 0; rs < RScores.length; rs++) {
if (sortMap.r[rs] == undefined && RScores[ru] == RScoresSorted[rs]) {
sortMap.r[rs] = ru;
break;
}
}
}
}
function sortByScore(a, b) {
return b - a;
}
return sortMap;
}
function getCMPageMap(MUsers, RUsers) {
var pageMap = {"m": {"": 0}, "r": {"": 0}};
for (var m = 0; m < MUsers.length; m++) pageMap.m[MUsers[m]] = m;
for (var r = 0; r < RUsers.length; r++) pageMap.r[RUsers[r]] = r;
return pageMap;
}
function getCMContent(item, itemType, mnemType) {
var CMItem = null;
var CMMnemType = (mnemType == "m") ? "meaning" : "reading";
var CMContent = '<p';
var CMLen = CMData[itemType][item][mnemType].t.length;
var CMPage = CMPageIndex[mnemType];
if (CMData[itemType][item][mnemType].t[0].length > 0 && CMData[itemType][item][mnemType].t[0] !== "!") {
CMItem = CMData[itemType][item][mnemType];
CMContent = '<div id="cm-' + CMMnemType + '-prev" class="cm-prev' + ((CMLen > 1 && CMPage > 0) ? "" : " disabled") + '"><span>◄</span></div>' + CMContent + ' class="cm-mnem-text">' + CMItem.t[CMSortMap[mnemType][CMPage]] +
'<br />by <a href="https://www.wanikani.com/community/people/' + CMItem.u[CMSortMap[mnemType][CMPage]] + '" target="_blank" >' +
CMItem.u[CMSortMap[mnemType][CMPage]] + '</a></p><div id="cm-' + CMMnemType + '-next" class="cm-next' + ((CMLen > 1 && CMPage < CMLen - 1) ? "" : " disabled") + '"><span>►</span></div>' +
'<div id="cm-' + CMMnemType + '-info" class="cm-info"><div class="cm-score">Score: <span id="cm-' + CMMnemType +
'-score-num" class="cm-score-num' + ((CMItem.s[CMSortMap[mnemType][CMPage]] !== 0) ? ((CMItem.s[CMSortMap[mnemType][CMPage]] > 0) ? " pos" : " neg") : "") + '">' +
CMItem.s[CMSortMap[mnemType][CMPage]] + '</span></div><div class="cm-upvote-highlight">Upvote</div><div class="cm-downvote-highlight">Downvote</div>' +
'<div id="cm-' + CMMnemType + '-user-buttons" class="cm-user-buttons"><div class="cm-edit-highlight' + ((CMItem.u[CMSortMap[mnemType][CMPage]] !== CMUser) ? " disabled" : "") + '">Edit</div><div class="cm-delete-highlight' +
((CMItem.u[CMSortMap[mnemType][CMPage]] !== CMUser) ? " disabled" : "") + '">Delete</div></div><br /><div id="cm-' + CMMnemType + '-submit" class="cm-submit-highlight">Submit Yours</div></div>';
} else {
CMContent += '>Nobody has posted a mnemonic for this item\'s ' + CMMnemType + ' yet. If you like, you can be the first to submit one!</p><div id="cm-' + CMMnemType + '-info" class="cm-info cm-nomnem">' +
'<div id="cm-' + CMMnemType + '-submit" class="cm-submit-highlight nomnem">Submit Yours</div><div id="cm-' + CMMnemType + '-req" class="cm-req-highlight">' +
(($.inArray(CMUser, CMData[itemType][item][mnemType].u) < 0) ? "Make Request" : "Delete Request") + '</div>';
if (CMData[itemType][item][mnemType].t[0].length > 0 && CMData[itemType][item][mnemType].u[0].length > 0)
CMContent += '<br/><br/><p id="cm-' + CMMnemType + '-reqtext" class="cm-reqtext" style="margin-bottom: 0">Mnemonic requested by: ' + getCMReqList(CMData[itemType][item][mnemType].u) + "</p>";
CMContent += "</div>";
}
return CMContent;
}
function getCMReqList(users) {
var reqList = "";
for (var u = 0; u < users.length; u++) {
if (u > 0) {
if (u < users.length - 1) reqList += ", ";
else reqList += ((u > 1) ? "," : "") + " and ";
}
reqList += '<a href="https://www.wanikani.com/community/people/' + users[u] + '" target="_blank" >' + users[u] + '</a>';
}
return reqList
}
function getCMForm(mnemType) {
var CMForm = '<form id="cm-' + mnemType + '-form" class="cm-form" onsubmit="return false"><div id="cm-' + mnemType + '-format" class="cm-format">' +
'<div class="btn cm-format-btn cm-format-bold"><b>b</b></div><div class="btn cm-format-btn cm-format-italic"><i>i</i></div><div class="btn cm-format-btn cm-format-underline"><u>u</u></div>' +
'<div class="btn cm-format-btn cm-format-strike"><s>s</s></div><div class="btn cm-format-btn cm-format-reading">読</div><div class="btn cm-format-btn cm-format-rad">部</div>' +
'<div class="btn cm-format-btn cm-format-kan">漢</div><div class="btn cm-format-btn cm-format-voc">語</div></div><fieldset><textarea id="cm-' +
mnemType + '-text" class="cm-text" maxlength="5000" placeholder="Submit a community mnemonic" style="overflow: hidden;' +
'word-wrap: break-word; resize: none; height: ' + ((CMIsReview) ? "53" : "55") + 'px;"></textarea><button id="cm-' + mnemType +'-form-cancel" class="cm-form-cancel">Cancel</button><button id="cm-' + mnemType + '-form-submit" class="cm-form-submit disabled" type="button">Submit</button><span class="counter-note"' +
'title="Characters Remaining">5000 <i class="icon-pencil"></i></span></fieldset></form>';
return CMForm;
}
function CMDataMatch(storedData) {
return (CMType + CMChar == CMTableData[CMIndex - 2].Item && storedData.m.t == CMTableData[CMIndex - 2].Meaning_Mnem && storedData.r.t == CMTableData[CMIndex - 2].Reading_Mnem &&
storedData.m.u == CMTableData[CMIndex - 2].Meaning_User && storedData.r.u == CMTableData[CMIndex - 2].Reading_User);
}
function CMDataConvert() {
CMData[CMType][CMChar].m.t = $.map(CMData[CMType][CMChar].m.t, function(mt) { return mt; });
CMData[CMType][CMChar].m.s = $.map(CMData[CMType][CMChar].m.s, function(ms) { return ms; });
CMData[CMType][CMChar].m.u = $.map(CMData[CMType][CMChar].m.u, function(mu) { return mu; });
CMData[CMType][CMChar].r.t = $.map(CMData[CMType][CMChar].r.t, function(rt) { return rt; });
CMData[CMType][CMChar].r.s = $.map(CMData[CMType][CMChar].r.s, function(rs) { return rs; });
CMData[CMType][CMChar].r.u = $.map(CMData[CMType][CMChar].r.u, function(ru) { return ru; });
}
function CMSettingsCheck() {
if (CMSettings[CMType][CMChar] === undefined) {
CMSettings[CMType][CMChar] = {"m": {"p": CMData[CMType][CMChar].m.u[curSortMap.m[0]],
"c": ($.inArray( CMUser, CMData[CMType][CMChar].m.u[curSortMap.m[0]] + 1))},
"r": {"p": CMData[CMType][CMChar].r.u[curSortMap.m[0]],
"c": ($.inArray( CMUser, CMData[CMType][CMChar].r.u[curSortMap.r[0]] + 1))}};
} else {
if (($.inArray( CMSettings[CMType][CMChar].m.p, CMData[CMType][CMChar].m.u[CMSortMap.m[0]] )) < 0) CMSettings[CMType][CMChar].m.p = CMData[CMType][CMChar].m.u[CMSortMap.m[0]];
if (($.inArray( CMSettings[CMType][CMChar].r.p, CMData[CMType][CMChar].r.u[CMSortMap.r[0]] )) < 0) CMSettings[CMType][CMChar].r.p = CMData[CMType][CMChar].r.u[CMSortMap.r[0]];
if (($.inArray( CMUser, CMData[CMType][CMChar].m.u[CMSortMap.m[0]] ) > -1) !== CMSettings[CMType][CMChar].m.c) CMSettings[CMType][CMChar].m.c = !CMSettings[CMType][CMChar].m.c;
if (($.inArray( CMUser, CMData[CMType][CMChar].r.u[CMSortMap.r[0]] ) > -1) !== CMSettings[CMType][CMChar].r.c) CMSettings[CMType][CMChar].r.c = !CMSettings[CMType][CMChar].r.c;
}
}
function loadCM(fromForm, meaning) {
var failCount = 0;
var checkCMReady = setInterval(function() {
if (CMReady) {
clearInterval(checkCMReady);
CMPreloadReady = true;
if (!fromForm) {
if (!CMStylesAdded) {
$("head").append('<style type="text/css">' +
'.cm-prev, .cm-next, .cm-upvote-highlight, .cm-downvote-highlight, .cm-delete-highlight, .cm-edit-highlight, .cm-submit-highlight, .cm-req-highlight { cursor: pointer !important }' +
'.cm-prev, .cm-next { font-size: 50px; margin: 0px 0px 0px 0px; padding: 15px 10px 0px 0px; float: left' + ((CMIsReview || CMIsLesson) ? "; margin-top: -10px; padding: 0 " : "" ) + '}' +
'.cm-prev.disabled, .cm-next.disabled { opacity: 0.25 }' +
'.cm-prev span, .cm-next span { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgb(85, 85, 85)), to(rgb(70, 70, 70))); -webkit-background-clip: text; ' +
'-webkit-text-fill-color: transparent; -webkit-text-stroke: 2px black; background: -moz-gradient(linear, 0% 0%, 0% 100%, from(rgb(85, 85, 85)), to(rgb(70, 70, 70)));' +
'-moz-background-clip: text; -moz-text-fill-color: transparent; -moz-text-stroke: 2px black }' +
'.cm-next { position: absolute; pointer-events: none; padding-left: 10px }' +
'.cm-next span { pointer-events: all }' +
'.cm-mnem-text { position: absolute; margin: 0 190px 0 60px' + ((CMIsReview || CMIsLesson) ? "; padding: 0" : "" ) + '}' +
'.cm-info { display: inline-block }' +
'.cm-info, .cm-info div { margin-bottom: 0px !important }' +
'.cm-score { float: left; width: 80px }' +
'.cm-score-num { color: #555 }' +
'.cm-score-num.pos { color: #5c5 }' +
'.cm-score-num.neg { color: #c55 }' +
'.cm-upvote-highlight, .cm-downvote-highlight, .cm-delete-highlight, .cm-edit-highlight, .cm-submit-highlight, .cm-req-highlight {' +
'text-align: center; font-size: 14px; width: 75px; margin-right: 10px; float: left; background-repeat: repeat-x; cursor: help; padding: 1px 4px; color: #fff; ' +
'text-shadow: 0 1px 0 rgba(0,0,0,0.2); white-space: nowrap; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; ' +
'-webkit-box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset; -moz-box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset; box-shadow: 0 -2px 0 rgba(0,0,0,0.2) inset' +
'} .cm-upvote-highlight { background-image: linear-gradient(to bottom, #5c5, #46ad46) }' +
'.cm-downvote-highlight { background-image: linear-gradient(to bottom, #c55, #ad4646) }' +
'.cm-user-buttons { position: absolute; margin-top: -34px }' +
'.cm-delete-highlight, .cm-edit-highlight { font-size: 12px; width: 50px; height: 12px; line-height: 1 }' +
'.cm-delete-highlight { background-image: linear-gradient(to bottom, #811, #6d0606); margin-right: 0 }' +
'.cm-edit-highlight { background-image: linear-gradient(to bottom, #ccc, #adadad) }' +
'.cm-delete-highlight.disabled, .cm-edit-highlight.disabled { display: none; pointer-events: none }' +
'.cm-submit-highlight { margin-top: 10px; width: 100px; background-image: linear-gradient(to bottom, #555, #464646) }' +
'.cm-submit-highlight.disabled { color: #8b8b8b !important }' +
'.cm-req-highlight { margin-top: 10px; width: 100px; background-image: linear-gradient(to bottom, #ea5, #d69646) }' +
'.cm-nomnem { margin-top: -10px !important }' + ((CMIsReview || CMIsLesson) ? ".cm-form fieldset { clear: left }" : "") +
'.cm-format { margin: 0 !important }' +
'.cm-format-btn { background-color: #f5f5f5; ' +
'background-image: -moz-linear-gradient(top, #fff, #e6e6e6); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#e6e6e6)); ' +
'background-image: -webkit-linear-gradient(top, #fff, #e6e6e6); background-image: -o-linear-gradient(top, #fff, #e6e6e6); ' +
'background-image: linear-gradient(to bottom, #fff, #e6e6e6); background-repeat: repeat-x; width: 10px; height: 10px; margin: 0 !important; ' +
'padding: ' + ((CMIsReview || CMIsLesson) ? "7px 13px 13px 7px" : "8px 12px 12px 8px") + '; line-height: 1; float: left }' +
'.cm-format-bold, .cm-format-underline, .cm-format-strike { padding-left: 10px; padding-right: 10px }' +
'.cm-format-voc { ' + ((CMIsReview || CMIsLesson) ? "" : "float: none") + ' }' +
'.cm-format-btn.active { background-color:#e6e6e6; background-color:#d9d9d9; background-image:none; outline:0; ' +
'-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05); ' +
'box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05) }' +
'.cm-delete-text { position: absolute; opacity: 0; text-align: center }' +
'.cm-delete-text h3 { margin: 0 }</style>');
CMStylesAdded = true;
}
$(".loadingCM").remove();
} else {
if (meaning) $("#cm-meaning .note-meaning").remove();
else $("#cm-reading .note-reading").remove();
}
if (!fromForm) checkCMVotes(true, true);
if (!fromForm || meaning) {
$("#cm-meaning").html($(getCMContent(CMChar, CMType, "m")));
$("#cm-meaning-delete-text").css({"width": $("#cm-meaning").width() + "px",
"height": $("#cm-meaning-delete-text h3").height() + "px",
"padding": (($("#cm-meaning").height() - $("#cm-meaning-delete-text h3").height())/2) + "px 0"});
updateCMMargins(true, false);
}
if (!fromForm || !meaning) {
$("#cm-reading").html($(getCMContent(CMChar, CMType, "r")));
$("#cm-reading-delete-text").css({"width": $("#cm-reading").width() + "px",
"height": $("#cm-reading-delete-text h3").height() + "px",
"padding": (($("#cm-reading").height() - $("#cm-reading-delete-text h3").height())/2) + "px 0"});
updateCMMargins(false, true);
}
checkCMTextHighlight(true);
checkCMTextHighlight(false);
$(".cm-prev span, .cm-next span").click(function() {
if (!$(this).parent().hasClass("disabled")) {
if ($(this).parent().parent().attr("id") == "cm-meaning") {
if ($(this).parent().attr("id") == "cm-meaning-prev") {
if (0 < CMPageIndex.m) {
CMPageIndex.m--;
CMSettings[CMType][CMChar].m.p = CMData[CMType][CMChar].m.u[CMSortMap.m[CMPageIndex.m]];
$("#cm-meaning-next").removeClass("disabled");
if (CMPageIndex.m < 1) $("#cm-meaning-prev").addClass("disabled");
checkCMVotes(true, false);
}
} else {
if (CMData[CMType][CMChar].m.t.length - 1 > CMPageIndex.m) {
CMPageIndex.m++;
CMSettings[CMType][CMChar].m.p = CMData[CMType][CMChar].m.u[CMSortMap.m[CMPageIndex.m]];
$("#cm-meaning-prev").removeClass("disabled");
if (CMPageIndex.m >= Object.keys(CMData[CMType][CMChar].m.t).length - 1) $("#cm-meaning-next").addClass("disabled");
checkCMVotes(true, false);
}
}
updateCMText(true);
} else {
if ($(this).parent().attr("id") == "cm-reading-prev") {
if (0 < CMPageIndex.r) {
CMPageIndex.r--;
CMSettings[CMType][CMChar].r.p = CMData[CMType][CMChar].r.u[CMSortMap.r[CMPageIndex.r]];
$("#cm-reading-next").removeClass("disabled");
if (CMPageIndex.r < 1) $("#cm-reading-prev").addClass("disabled");
checkCMVotes(false, true);
}
} else {
if (CMData[CMType][CMChar].r.t.length - 1 > CMPageIndex.r) {
CMPageIndex.r++;
CMSettings[CMType][CMChar].r.p = CMData[CMType][CMChar].r.u[CMSortMap.r[CMPageIndex.r]];
$("#cm-reading-prev").removeClass("disabled");
if (CMPageIndex.r >= Object.keys(CMData[CMType][CMChar].r.t).length - 1) $("#cm-reading-next").addClass("disabled");
checkCMVotes(false, true);
}
}
updateCMText(false);
}
saveCMSettings();
}
});
$(".cm-upvote-highlight, .cm-downvote-highlight").click(function() {
var isMeaning = ($(this).parent().attr("id") == "cm-meaning-info");
var key = CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]] + ":" +
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]];
if ((CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][key] == 0 || ($(this).hasClass("cm-upvote-highlight") &&
CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][key] == -1) || ($(this).hasClass("cm-downvote-highlight") &&
CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][key] == 1))) {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]] !== CMUser) {
if (isMeaning) {
if ($(this).hasClass("cm-upvote-highlight")) CMVotes[CMType][CMChar].m[key]++;
else CMVotes[CMType][CMChar].m[key]--;
if (CMVotes[CMType][CMChar].m[key] !== 0) CMData[CMType][CMChar].m.s[CMSortMap.m[CMPageIndex.m]] += CMVotes[CMType][CMChar].m[key];
else CMData[CMType][CMChar].m.s[CMSortMap.m[CMPageIndex.m]] += ($(this).hasClass("cm-upvote-highlight")) ? 1 : -1;
$("#cm-meaning-score-num").html(CMData[CMType][CMChar].m.s[CMSortMap.m[CMPageIndex.m]]);
} else {
if ($(this).hasClass("cm-upvote-highlight")) CMVotes[CMType][CMChar].r[key]++;
else CMVotes[CMType][CMChar].r[key]--;
if (CMVotes[CMType][CMChar].r[key] !== 0) CMData[CMType][CMChar].r.s[CMSortMap.r[CMPageIndex.r]] += CMVotes[CMType][CMChar].r[key];
else CMData[CMType][CMChar].r.s[CMSortMap.r[CMPageIndex.r]] += ($(this).hasClass("cm-upvote-highlight")) ? 1 : -1;
$("#cm-reading-score-num").html(CMData[CMType][CMChar].r.s[CMSortMap.r[CMPageIndex.r]]);
}
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]] !== 0) {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]] > 0) $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("neg").addClass("pos");
else $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("pos").addClass("neg");
} else $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-score-num").removeClass("pos").removeClass("neg");
if (CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][key] == -1) {
if ((isMeaning && parseInt(CMTableData[CMIndex - 2].Meaning_Score.split("|")[CMSortMap.m[CMPageIndex.m]]) <= -9) ||
(!isMeaning && parseInt(CMTableData[CMIndex - 2].Reading_Score.split("|")[CMSortMap.r[CMPageIndex.r]]) <= -9)) deleteCM(isMeaning, false);
else postCM(1);
} else postCM(1);
} else alert("Sorry, you can't vote on your own mnemonic.");
} else alert("It looks like you've already " + ($(this).hasClass("cm-upvote-highlight") ? "up" : "down") + "voted this mnemonic.");
});
$(".cm-delete-highlight").click(function() {
var isMeaning = ($(this).parent().attr("id") == "cm-meaning-user-buttons");
if ($(this).html() == "Delete") {
$(this).html("Really Delete?").css({"font-size": "8px", "line-height": ((CMIsReview || CMIsLesson) ? "1.5" : "1.8")});
setTimeout(function() {
if ($("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-info .cm-delete-highlight").attr("disabled") === undefined) {
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-info .cm-delete-highlight").html("Delete").css({"font-size": "12px", "line-height": "1"});
}
}, 3000);
} else {
$(this).attr("disabled", "disabled");
deleteCM(isMeaning, true);
}
});
$(".cm-edit-highlight, .cm-submit-highlight").click(function() {
var isEdit = ($(this).hasClass("cm-edit-highlight"));
$(this).attr("disabled", "disabled");
var isMeaning = ((isEdit && $(this).parent().attr("id") == "cm-meaning-user-buttons") || $(this).attr("id") == "cm-meaning-submit");
if ((isEdit && ((isMeaning && CMSettings[CMType][CMChar].m.c) || (!isMeaning && CMSettings[CMType][CMChar].r.c))) ||
(!isEdit && ((isMeaning && !CMSettings[CMType][CMChar].m.c) || (!isMeaning && !CMSettings[CMType][CMChar].r.c)))) {
if (isEdit || CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t.length < 10) {
if (isMeaning) $("#cm-meaning").html('<div class="note-meaning noswipe">' + getCMForm("meaning") + '</div>');
else $("#cm-reading").html('<div class="note-reading noswipe">' + getCMForm("reading") + '</div>');
if (isEdit) {
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").val(CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]])
.css({"transition-duration": "0s", "-webkit-transition-duration": "0s", "-moz-transition-duration": "0s", "-o-transition-duration": "0s"});
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").autosize({"callback": function() {
setTimeout(function() { $("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").css({"transition-duration": "0.2s", "-webkit-transition-duration": "0.2s", "-moz-transition-duration": "0.2s", "-o-transition-duration": "0.2s"}) }, 200);
}
});
$("#cm-" + (($(this).attr("id") == "cm-meaning-text") ? "meaning" : "reading") + "-form .counter-note").html($("#cm-" + ((isMeaning) ? "meaning" : "reading") +
" .cm-text").attr("maxlength")-$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").val().length + ' <i class="icon-pencil"></i>');
}
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").keydown(function() {
if (CMIsReview && !CMIsLesson) {
if ( event.which == 8 && (!CMIsChrome || $("#deleteButton").length > 0) ) {
var selStart = $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-text").prop("selectionStart");
var selEnd = $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-text").prop("selectionEnd");
if (selEnd == CMSelTemp && selStart == selEnd) {
selStart -= (selEnd - $(this).val().lastIndexOf("<", selStart));
if ($(".cm-format-btn.active").length > 0) {
$(".cm-format-btn").removeClass("active");
CMSelTemp = -1;
} else if ($(this).val().substr(selStart - 1, 1) == ">") {
switch($(this).val().slice($(this).val().lastIndexOf("<", selStart - 1) + 1, selStart - 1)) {
case "b":
$(".cm-format-bold").addClass("active");
break;
case "i":
$(".cm-format-italic").addClass("active");
break;
case "u":
$(".cm-format-underline").addClass("active");
break;
case "s":
$(".cm-format-strike").addClass("active");
break;
case 'span class="highlight-reading"':
case 'span class="reading-highlight"':
$(".cm-format-reading").addClass("active");
break;
case 'span class="highlight-radical"':
case 'span class="radical-highlight"':
$(".cm-format-rad").addClass("active");
break;
case 'span class="highlight-kanji"':
case 'span class="kanji-highlight"':
$(".cm-format-kan").addClass("active");
break;
case 'span class="highlight-vocabulary"':
case 'span class="vocabulary-highlight"':
$(".cm-format-voc").addClass("active");
break;
default:
}
CMSelTemp = selStart;
}
}
if (selStart == selEnd) {
if (selStart > 0) $(this).val($(this).val().slice(0, selEnd - 1) + $(this).val().slice(selEnd)).selectRange(selEnd - 1);
} else $(this).val($(this).val().slice(0, selStart) + $(this).val().slice(selEnd)).selectRange(selStart);
$("#cm-" + (($(this).attr("id") == "cm-meaning-text") ? "meaning" : "reading") + "-form .counter-note").html($(this).attr("maxlength")-$(this).val().length + '<i class="icon-pencil"></i>');
$(this).trigger("input");
}
}
if (event.which == 190) $(".cm-format-btn").removeClass("active");
});
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + " .cm-text").on('input propertychange', function(e) {
if ($(this).val() !== "") $(".cm-form-submit").removeClass("disabled");
else $("button[type=submit]").addClass("disabled");
$(this).autosize();
$("#cm-" + (($(this).attr("id") == "cm-meaning-text") ? "meaning" : "reading") + "-form .counter-note").html($(this).attr("maxlength")-$(this).val().length + '<i class="icon-pencil"></i>');
}).focus();
$(".cm-format-btn").click(function() {
var isMeaningStr = ($(this).parent().attr("id") == "cm-meaning-format") ? "meaning" : "reading";
var selStart = $("#cm-" + isMeaningStr + "-text").prop("selectionStart");
var selEnd = $("#cm-" + isMeaningStr + "-text").prop("selectionEnd");
var formatType = "";
var tagStart = "";
var tagEnd = "";
var includesClass = false;
CMSelTemp = -1;
switch($(this).attr("class").slice($(this).attr("class").lastIndexOf("-") + 1, ((!$(this).hasClass("active")) ? $(this).attr("class").length : $(this).attr("class").lastIndexOf(" ")))) {
case "bold":
tagStart = "b";
break;
case "italic":
tagStart = "i";
break;
case "underline":
tagStart = "u";
break;
case "strike":
tagStart = "s";
break;
case "reading":
tagStart = 'span class="highlight-reading"';
includesClass = true;
break;
case "rad":
tagStart = 'span class="highlight-radical"';
includesClass = true;
break;
case "kan":
tagStart = 'span class="highlight-kanji"';
includesClass = true;
break;
case "voc":
tagStart = 'span class="highlight-vocabulary"';
includesClass = true;
break;
default:
tagStart = "span";
}
if (!$(this).hasClass("active")) {
if ($(this).parent().children(".active").length > 0) {
tagEnd = "</" + ((CMLastTag.indexOf(" ") < 0) ? CMLastTag : CMLastTag.slice(0, CMLastTag.indexOf(" "))) + ">";
$("#cm-" + isMeaningStr + "-text").val($("#cm-" + isMeaningStr + "-text").val().slice(0, selStart) + tagEnd + $("#cm-" + isMeaningStr + "-text").val().slice(selStart));
if (selStart == selEnd) selStart += tagEnd.length;
selEnd += tagEnd.length;
}
$(".cm-format-btn").removeClass("active");
CMSelTemp = selEnd + tagStart.length + 2;
if (selStart == selEnd) {
$("#cm-" + isMeaningStr + "-text").val($("#cm-" + isMeaningStr + "-text").val().slice(0, selStart) + "<" + tagStart + ">" + $("#cm-" + isMeaningStr + "-text").val().slice(selStart));
$(this).addClass("active");
} else {
$("#cm-" + isMeaningStr + "-text").val($("#cm-" + isMeaningStr + "-text").val().slice(0, selStart) + "<" + tagStart + ">" +
$("#cm-" + isMeaningStr + "-text").val().slice(selStart, selEnd) + "</" + ((!includesClass) ? tagStart : tagStart.slice(0, tagStart.indexOf(" "))) + ">" +
$("#cm-" + isMeaningStr + "-text").val().slice(selEnd));
}
} else {
if (selStart !== selEnd) {
$("#cm-" + isMeaningStr + "-text").val($("#cm-" + isMeaningStr + "-text").val().slice(0, selStart) + $("#cm-" + isMeaningStr + "-text").val().slice(selEnd));
selEnd = selStart;
}
tagEnd = "</" + ((!includesClass) ? tagStart : tagStart.slice(0, tagStart.indexOf(" "))) + ">";
CMSelTemp = selStart + tagEnd.length;
$("#cm-" + isMeaningStr + "-text").val($("#cm-" + isMeaningStr + "-text").val().slice(0, selStart) + tagEnd + $("#cm-" + isMeaningStr + "-text").val().slice(selStart))
.selectRange(CMSelTemp);
$(this).removeClass("active");
}
$("#cm-" + isMeaningStr + "-text").trigger("propertychange").focus();
CMLastTag = tagStart;
});
$(".cm-form-submit").click(function() {
$(this).prop("disabled", true).prev().prop("disabled", true).parent().prop("disabled", true);
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-format .active").trigger("click");
var mnemText = "";
if (isEdit || !CMSettings[CMType][CMChar][((isMeaning) ? "m" : "r")].c) {
mnemText = $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-text").val().trim();
if (mnemText.length > 0) {
if (!/[|]/.test(mnemText)) {
if (!new RegExp(Base64.decode("ZnVja3xzaGl0fGRpY2t8bXkgY29ja3x5b3VyIGNvY2t8cyBjb2NrfHBlbmlzfHJhcGV8cmFwaW5nfHB1c3N5fGN1bnR8Y2xpdHxqaXp6fGN1bXxhbnVzfG5pZ2dlcnxmYWd8d" +
"Gl0fHBvcm58bW9sZXN0fHBlZG98aGF2ZSBzZXh8aGFkIHNleA==").toLowerCase(), "i").test(mnemText)) {
if (checkCMHTMLTags(mnemText)) {
var firstChar = (mnemText.substring(0, 1) !== "<") ? mnemText.substring(0, 1) : mnemText.substring(mnemText.indexOf(">") + 1, 1);
if (firstChar !== "!" ) {
mnemText = (mnemText.substr(0, 1) !== "<") ? (firstChar.toUpperCase() + mnemText.substring(1)) : (mnemText.slice(0, mnemText.indexOf(">") + 1) +
mnemText.substr(mnemText.indexOf(">") + 1, 1).toUpperCase() + mnemText.substring(mnemText.indexOf(">") + 2));
if (!/[.|!|?|。|!]$/.test(mnemText.slice(mnemText.length - 1)) && mnemText.length < 500) {
if (mnemText.slice(mnemText.length - 1) == ">") mnemText += (!/[.|!|?|。|!]$/.test(mnemText.substr(mnemText.lastIndexOf("<") - 1, 1))) ? "." : "";
else mnemText += ".";
}
if (isEdit) {
var index = CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]];
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[index] !== (mnemText)) {
CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[index] + ":" + mnemText] = CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[index] + ":" + CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[index]];
delete CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[index] + ":" + CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[index]];
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[index] = mnemText;
postCM(((isMeaning) ? 6 : 7));
} else $(this).prev().prop("disabled", false).trigger("click").prop("disabled", true);
} else {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[0].length > 0 && CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[0] !== "!") {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t.push(mnemText);
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s.push(0);
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.push(CMUser);
} else {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t = [mnemText];
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s = [0];
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u = [CMUser];
}
CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.length - 1] +
":" + CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t[CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t.length - 1]] = 0;
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s.length < 1) {
CMSortMap[((isMeaning) ? "m" : "r")].push(0);
CMPageIndex[((isMeaning) ? "m" : "r")] = 0;
} else {
for (var s = CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s.length - 1; s >= 0; s--) {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s[s] > -1 || s == 0) {
CMSortMap[((isMeaning) ? "m" : "r")] = CMSortMap[((isMeaning) ? "m" : "r")].slice(0, s).concat([CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].s.length - 1].concat(CMSortMap[((isMeaning) ? "m" : "r")].slice(s)));
CMPageIndex[((isMeaning) ? "m" : "r")] = s;
break;
}
}
}
CMPageMap[((isMeaning) ? "m" : "r")][CMUser] = CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t.length - 1;
postCM(((isMeaning) ? 2 : 3));
}
} else {
alert("You may not begin a mnemonic with an exclamation mark (!) because it is used to indicate mnemonic requests.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
} else {
alert("Your mnemonic contains unclosed, unopened, or restricted HTML tags. These must be fixed before you can post your mnemonic.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
} else {
alert("Your mnemonic contains inappropriate or otherwise vulgar content. Please change your mnemonic to be more family-friendly because young children may use this script too.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
} else {
alert("You may not use the vertical bar (|) in a mnemonic because it is used in the database as a separator.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
} else {
alert("Sorry, that input is invalid. Please enter a proper mnemonic.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
} else {
alert("Sorry, you've already submitted a " + ((isMeaning) ? "meaning" : "reading") + " mnemonic for this item. You must delete your old " + ((isMeaning) ? "meaning" : "reading") + " mnemonic submission to submit a new one.");
$(this).prop("disabled", false).prev().prop("disabled", false).parent().prop("disabled", false);
}
});
$(".cm-form-cancel").click(function() {
$(this).prop("disabled", true).next().attr("disabled", "disabled").parent().prop("disabled", true);
if ($(this).attr("id") == "cm-meaning-form-cancel") loadCM(true, true);
else loadCM(true, false);
});
} else alert("Sorry, but it appears that the limit of 10 mnemonics for this item's " + ((isMeaning) ? "meaning" : "reading") + " has been reached.");
} else {
alert("Sorry, you've already submitted a " + ((isMeaning) ? "meaning" : "reading") + " mnemonic for this item. You must delete your old " +
((isMeaning) ? "meaning" : "reading") + " mnemonic submission to submit a new one.");
}
});
$(".cm-req-highlight").click(function() {
var isMeaning = ($(this).attr("id") == "cm-meaning-req");
var hasRequested = $.inArray(CMUser, CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u) > -1;
var reqText = $(this).next().next().next().html();
if (!hasRequested) {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.length < 10) {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u[0].length > 0) {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.push(CMUser);
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-reqtext").html("Mnemonic requested by: " + getCMReqList(CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u));
} else {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t = ["!"];
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u = [CMUser];
$('<p id="cm-' + ((isMeaning) ? "meaning" : "reading") + '-reqtext" class="cm-reqtext" style="margin-bottom: 0">Mnemonic requested by: ' +
getCMReqList(CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u)).insertAfter($(this));
}
$(this).text("Delete Request");
saveCMData();
postCM(8);
} else alert("Sorry, but it appears that the limit of 10 mnemonic requests for this item's " + ((isMeaning) ? "meaning" : "reading") + " has been reached.");
} else {
if (CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.length > 1) {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.splice(CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u.indexOf(CMUser), 1);
$(this).next().next().next().html("Mnemonic requested by: " + getCMReqList(CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u));
} else {
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].t = [""];
CMData[CMType][CMChar][((isMeaning) ? "m" : "r")].u = [""];
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-reqtext").remove();
$(this).parent().children("br").remove();
}
$(this).text("Make Request");
saveCMData();
postCM(9);
}
});
} else {
failCount++;
if (failCount == 10) {
$(".loadingCM").html('Loading seems to be taking longer than it should and something may have gone wrong. If this issue continues after reloading the page, make sure your ' +
'internet connection is working properly. If your internet is working properly and the issue persists, try temporarily disabling all other ' +
'userscripts and extensions and try again. If it persists and you\'ve ensured that other userscripts or extensions are not the cause, check ' +
'<a href="https://www.wanikani.com/chat/api-and-third-party-apps/7568" target="_blank">here</a> to see if anyone else is having this issue and, ' +
'if not, please report it and include your operating system, browser, and version of the WaniKani Community Mnemonics userscript ' +
'(which should be the newest to ensure minimal bugs).');
clearInterval(checkCMReady);
} else if (failCount < 10) $(".loadingCM").html($(".loadingCM").html() + ".");
}
}, 1000);
}
function deleteCM(isMeaning, isUser) {
$('<div id="cm-' + ((isMeaning) ? "meaning" : "reading") + '-delete-text" class="cm-delete-text"><h3>Deleting Mnemonic...</h3></div>').insertBefore($("#cm-" + ((isMeaning) ? "meaning" : "reading")));
$("#cm-" + ((isMeaning) ? "meaning" : "reading")).prev().css({"width": $("#cm-" + ((isMeaning) ? "meaning" : "reading")).width() + "px",
"height": $("#cm-" + ((isMeaning) ? "meaning" : "reading")).prev().children("h3").height() + "px",
"padding": (($("#cm-" + ((isMeaning) ? "meaning" : "reading")).height() - $("#cm-" + ((isMeaning) ? "meaning" : "reading")).prev().children("h3").height())/2) + "px 0"});
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + ", #cm-" + ((isMeaning) ? "meaning" : "reading") + "-delete-text").css({"-webkit-transition": "opacity 1s ease-in-out",
"-moz-transition": "opacity 1s ease-in-out",
"-o-transition": "opacity 1s ease-in-out",
"transition": "opacity 1s ease-in-out"});
$("#cm-" + ((isMeaning) ? "meaning" : "reading")).css("opacity", "0").prev().css("opacity", "1");
var curItem = CMData[CMType][CMChar][((isMeaning) ? "m" : "r")];
var curItemSettings = CMSettings[CMType][CMChar][((isMeaning) ? "m" : "r")];
var curItemVotes = CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")];
var delIndex = CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]];
var delUser = curItemSettings.p;
delete CMVotes[CMType][CMChar][((isMeaning) ? "m" : "r")][curItem.u[delIndex] + ":" + curItem.t[delIndex]];
if (curItem.t.length > 0) curItem.t.splice(delIndex, 1);
else curItem.t[0] = "";
curItem.s.splice(delIndex, 1);
if (curItem.u.length > 0) curItem.u.splice(delIndex, 1);
else curItem.u[0] = "";
CMSettings[CMType][CMChar][((isMeaning) ? "m" : "r")] = {"p": ((delIndex > 0) ? curItem.u[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")] - 1]] : curItemSettings.p), "c": false};
CMSortMap[((isMeaning) ? "m" : "r")] = getCMSortMap(((isMeaning) ? curItem.s : []), ((!isMeaning) ? curItem.s : []))[((isMeaning) ? "m" : "r")];
CMPageMap[((isMeaning) ? "m" : "r")] = getCMPageMap(((isMeaning) ? curItem.u : []), ((!isMeaning) ? curItem.u : []))[((isMeaning) ? "m" : "r")];
if (CMPageIndex[((isMeaning) ? "m" : "r")] >= curItem.t.length) {
CMPageIndex[((isMeaning) ? "m" : "r")]--;
curItemSettings.p = curItem.u[CMSortMap[((isMeaning) ? "m" : "r")][CMPageIndex[((isMeaning) ? "m" : "r")]]];
$("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-next").addClass("disabled");
if (delIndex <= 1) $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-prev").addClass("disabled");
} else if (delIndex < 1) $("#cm-" + ((isMeaning) ? "meaning" : "reading") + "-prev").addClass("disabled");
postCM(((isMeaning) ? 4 : 5));
}
function postCM(postType) {
if (postType == 0) CMData[CMType][CMChar].i = CMIndex;
var serializedData = (postType == 0) ? 'Item=' + CMType + encodeURIComponent(CMChar) + "&Meaning_Mnem=&Reading_Mnem=&Meaning_Score=&Reading_Score=&Meaning_User=&Reading_User=&Index=" +
CMData[CMType][CMChar].i : "Item=" + CMType + encodeURIComponent(CMChar) + "&Meaning_Mnem=" + encodeURIComponent(CMData[CMType][CMChar].m.t.join("|")) + "&Reading_Mnem=" +
encodeURIComponent(CMData[CMType][CMChar].r.t.join("|")) + "&Meaning_Score=" + ((!isNaN(CMData[CMType][CMChar].m.s[0])) ? CMData[CMType][CMChar].m.s.join("|") : "") + "&Reading_Score=" +
((!isNaN(CMData[CMType][CMChar].r.s[0])) ? CMData[CMType][CMChar].r.s.join("|") : "") + "&Meaning_User=" + CMData[CMType][CMChar].m.u.join("|") + "&Reading_User=" +
CMData[CMType][CMChar].r.u.join("|") + "&Index=" + CMData[CMType][CMChar].i;
if ((postType !== 2 && postType !== 3) || CMSettings[CMType][CMChar][((postType == 2) ? "m" : "r")].c == false) {
if (postType == 2 || postType == 3) CMSettings[CMType][CMChar][((postType == 2) ? "m" : "r")].c = true;
$.ajax({
url: "https://script.google.com/macros/s/AKfycbznhpL43Ix-qqO3sNcJmQeQk5dsdW6u0uaZ9to4_8TQho0qcm0/exec",
type: "POST",
data: serializedData,
success: function(data, textStatus, jqXHR) {
if (postType == 0) {
CMReady = true;
} else {
if (postType > 1) {
if (postType == 2 || postType == 3) {
CMSettings[CMType][CMChar][((postType == 2) ? "m" : "r")].p = CMUser;
saveCMSettings();
loadCM(true, (postType == 2));
} else if (postType < 6) {
$("#cm-" + [((postType == 4) ? "meaning" : "reading")] + "-delete-text h3").html("Mnemonic successfully deleted!");
if ((postType == 4 && CMData[CMType][CMChar].m.t.length > 0) || (postType == 5 && CMData[CMType][CMChar].r.t.length > 0)) {
updateCMText((postType == 4));
} else {
CMData[CMType][CMChar][((postType == 4) ? "m" : "r")] = {"t": [""], "s": [], "u": [""]};
loadCM(true, (postType == 4));
}
saveCMSettings();
setTimeout(function() {
$("#cm-" + ((postType == 4) ? "meaning" : "reading") + "-user-buttons .cm-delete-highlight").html("Delete").css({"font-size": "12px", "line-height": "1"}).removeAttr("disabled");
$("#cm-" + ((postType == 4) ? "meaning" : "reading")).css("opacity", "1").prev().css("opacity", "0");
setTimeout(function() {
$("#cm-" + ((postType == 4) ? "meaning" : "reading")).css({"-webkit-transition": "none",
"-moz-transition": "none",
"-o-transition": "none",
"transition": "none"}).prev().remove();
}, 1000);
}, 3000);
} else if (postType < 8) {
updateCMText((postType == 6));
loadCM(true, (postType == 6));
}
}
saveCMVotes();
}
},
error: function(jqXHR, textStatus, errorThrown) {
alert("Error submitting data to database.");
}
});
}
}
function saveCMData() {
localStorage.setItem("CMData", JSON.stringify(CMData, function (key, value) {
//Start Code Credit: Mike Samuel from Stack Overflow
if (value && typeof value === 'object') {
var replacement = {};
for (var k in value) {
if (Object.hasOwnProperty.call(value, k)) {
replacement[decodeURIComponent(k)] = value[k];
}
}
return replacement;
}
return value;
//End Code Credit
}));
}
function saveCMSettings() {
localStorage.setItem("CMSettings", JSON.stringify(CMSettings, function (key, value) {
//Start Code Credit: Mike Samuel from Stack Overflow
if (value && typeof value === 'object') {
var replacement = {};
for (var k in value) {
if (Object.hasOwnProperty.call(value, k)) {
replacement[decodeURIComponent(k)] = value[k];
}
}
return replacement;
}
return value;
//End Code Credit
}));
}
function saveCMVotes() {
localStorage.setItem("CMVotes", JSON.stringify(CMVotes, function (key, value) {
//Start Code Credit: Mike Samuel from Stack Overflow
if (value && typeof value === 'object') {
var replacement = {};
for (var k in value) {
if (Object.hasOwnProperty.call(value, k)) {
replacement[k] = value[k];
}
}
return replacement;
}
return value;
//End Code Credit
}));
}
//Start Code Credit: Mark from Stack Overflow
$.fn.selectRange = function(start, end) {
if(!end) end = start;
return this.each(function() {
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
}
//End Code Credit
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));
o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){
t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){
var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);
t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){
t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|
(c2&63)<<6|c3&63);n+=3}}return t}};
CMTableData = [];
CMTableItems = [];
CMData = {"k": [], "v": []};
CMSettings = {"k": [], "v": []};
CMVotes = {"k": [], "v": []};
CMPageIndex = {"m": 0, "r": 0};
CMSortMap = {"m": [], "r": []};
CMPageMap = {"m": [], "r": []};
CMLastTag = {"m": "", "r": ""};
CMInitData = true;
CMInitSettings = true;
CMInitVotes = true;
CMStylesAdded = false;
CMReady = false;
CMPostReady = true;
CMPreloadReady = false;
CMIndex = -1;
CMSelTemp = -1;
CMChar = "";
CMType = "";
CMUser = (CMIsReview || CMIsLesson) ? $("#report-errors a").attr("href") : $('.account .nav-header').next().children()[1].href;
CMUser = (CMIsReview || CMIsLesson) ? CMUser.slice(CMUser.indexOf("from%20") + 7, CMUser.indexOf("%20%28")) : CMUser.substring(CMUser.lastIndexOf("/") + 1);
CMVersionCheck = {"v": CMVersion, "c": false };
if (localStorage.getItem("CMVersionCheck") !== null) {
CMVersionCheck = JSON.parse(localStorage.getItem("CMVersionCheck"));
localStorage.setItem("CMVersionCheck", JSON.stringify(CMVersionCheck));
}
if (localStorage.getItem("CMData") !== null) {
CMData = JSON.parse(localStorage.getItem("CMData"), function (key, value) {
//Start Code Credit: Mike Samuel from Stack Overflow
if (value && typeof value === 'object')
for (var k in value) {
if (/^[A-Z]/.test(k) && Object.hasOwnProperty.call(value, k)) {
value[encodeURIComponent(k)] = value[k];
delete value[k];
}
}
return value;
//End Code Credit
});
CMInitData = false;
}
if (localStorage.getItem("CMSettings") !== null) {
CMSettings = JSON.parse(localStorage.getItem("CMSettings"), function (key, value) {
//Start Code Credit: Mike Samuel from Stack Overflow
if (value && typeof value === 'object')
for (var k in value) {
if (/^[A-Z]/.test(k) && Object.hasOwnProperty.call(value, k)) {
value[encodeURIComponent(k)] = value[k];
delete value[k];
}
}
return value;
//End Code Credit
});
CMInitSettings = false;
}
if (localStorage.getItem("CMVotes") !== null) {
CMVotes = JSON.parse(localStorage.getItem("CMVotes"));
CMInitVotes = false;
}
// ==/UserScript==