您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows WWWJDIC vocab with Forvo audio for each kanji in lessons, reviews, and kanji pages. A paid Forvo API key is required for audio.
// ==UserScript== // @name WaniKani Vocab Beyond // @author Norman Sue // @description Shows WWWJDIC vocab with Forvo audio for each kanji in lessons, reviews, and kanji pages. A paid Forvo API key is required for audio. // @version 0.6.0 // @update 4/28/2019, 7:24:38 PM // @grant GM_xmlhttpRequest // @include https://www.wanikani.com/* // @run-at document-start // @namespace https://gf.qytechs.cn/en/users/56591-normful // @connect nihongo.monash.edu // @connect apifree.forvo.com // @license The MIT License (MIT); http://opensource.org/licenses/MIT // ==/UserScript== /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gm_http_1 = __webpack_require__(1); var app_1 = __webpack_require__(2); // Set `debug: true` to enable GM.xmlHttpRequest logging gm_http_1.default.setConfig({ debug: true }); var app = new app_1.App(); app.init(); /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { (function webpackUniversalModuleDefinition(root, factory) { if(true) module.exports = factory(); else {} })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * Created by axetroy on 17-6-23. */ /// <reference path="./index.d.ts" /> var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); function isFunction(func) { return typeof func === 'function'; } var Http = (function () { function Http(config) { if (config === void 0) { config = {}; } this.config = config; } Http.prototype.setConfig = function (config) { if (config === void 0) { config = {}; } this.config = __assign({}, this.config, config); }; Http.prototype.create = function (config) { return new Http(config); }; Http.prototype.request = function (method, url, data, header, config) { var _this = this; if (data === void 0) { data = ''; } if (header === void 0) { header = {}; } if (config === void 0) { config = {}; } return new Promise(function (resolve, reject) { var commonRequestConfig = { method: method, url: url, data: data, header: header }; var GM_xmlhttpRequestConfig = __assign({}, commonRequestConfig, config, _this.config); var onreadystatechange = GM_xmlhttpRequestConfig.onreadystatechange, onerror = GM_xmlhttpRequestConfig.onerror, onabort = GM_xmlhttpRequestConfig.onabort, ontimeout = GM_xmlhttpRequestConfig.ontimeout; GM_xmlhttpRequestConfig.synchronous = true; // async GM_xmlhttpRequestConfig.onreadystatechange = function (response) { try { isFunction(onreadystatechange) && onreadystatechange.call(this, response); } catch (err) { reject(err); } if (response.readyState !== 4) return; response.status >= 200 && response.status < 400 ? resolve(response) : reject(response); }; GM_xmlhttpRequestConfig.onerror = function (response) { try { isFunction(onerror) && onerror.call(this, response); reject(response); } catch (err) { reject(err); } }; GM_xmlhttpRequestConfig.onabort = function (response) { try { isFunction(onabort) && onabort.call(this, response); reject(response); } catch (err) { reject(err); } }; GM_xmlhttpRequestConfig.ontimeout = function (response) { try { isFunction(ontimeout) && ontimeout.call(this, response); reject(response); } catch (err) { reject(err); } }; if (_this.config.debug) { console.log("%c[" + commonRequestConfig.method.toUpperCase() + "]%c: " + commonRequestConfig.url, 'color: green', 'color: #000;text-style: under-line'); } GM_xmlhttpRequest(__assign({}, GM_xmlhttpRequestConfig)); }); }; Http.prototype.get = function (url, data, header, config) { return this.request('GET', url, data, header, config); }; Http.prototype.post = function (url, data, header, config) { return this.request('POST', url, data, header, config); }; Http.prototype.put = function (url, data, header, config) { return this.request('PUT', url, data, header, config); }; Http.prototype['delete'] = function (url, data, header, config) { return this.request('DELETE', url, data, header, config); }; Http.prototype.head = function (url, data, header, config) { return this.request('HEAD', url, data, header, config); }; return Http; }()); exports.Http = Http; var timeout = 5000; exports.timeout = timeout; var http = new Http({ timeout: timeout }); exports.http = http; exports.default = http; /***/ }) /******/ ]); }); /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var runAllWkofDependentCode_1 = __webpack_require__(3); var App = /** @class */ (function () { function App() { } App.prototype.init = function () { addEventListener("DOMContentLoaded", this.onDomContentLoaded.bind(this)); }; App.prototype.onDomContentLoaded = function () { runAllWkofDependentCode_1.runAllWkofDependentCode(); }; return App; }()); exports.App = App; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); var logger_1 = __webpack_require__(4); var appConstants_1 = __webpack_require__(5); var insertInitialDOMElements_1 = __webpack_require__(6); var waitForWkof_1 = __webpack_require__(21); var wkofConstants_1 = __webpack_require__(24); var Log = new logger_1.Logger(); function runAllWkofDependentCode() { waitForWkof_1.waitForWkof(appConstants_1.prettyScriptName, function (wkof) { wkof.include("Menu,Settings"); wkof.ready("Menu,Settings").then(function () { wkof.Menu.insert_script_link({ name: wkofConstants_1.MenuScriptLinkId, submenu: "Settings", title: "Vocab Beyond", on_click: onSettingsMenuLinkClick.bind(null, wkof) }); wkof.Settings.load(wkofConstants_1.SettingsScriptId).then(function (settings) { insertInitialDOMElements_1.insertInitialDOMElements(settings); }); }); }); } exports.runAllWkofDependentCode = runAllWkofDependentCode; function onSettingsMenuLinkClick(wkof) { var dialog = new wkof.Settings(__assign({}, wkofConstants_1.WkofSettingsMenuConfig, { on_save: onSettingsSave.bind(null, wkof) })); dialog.open(); } function onSettingsSave(wkof) { window.location.reload(false); } /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* tslint:disable:no-console */ Object.defineProperty(exports, "__esModule", { value: true }); var logPrefix = "[WKVB] "; var Logger = /** @class */ (function () { function Logger() { this.prefix = logPrefix; this.disableLogging = false; // Set to false for development } Logger.prototype.debug = function (msg) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (this.disableLogging) { return; } console.debug.apply(console, [this.prefix + msg].concat(args)); }; Logger.prototype.info = function (msg) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (this.disableLogging) { return; } console.log.apply(console, [this.prefix + msg].concat(args)); }; Logger.prototype.warn = function (msg) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (this.disableLogging) { return; } console.warn.apply(console, [this.prefix + msg].concat(args)); }; Logger.prototype.error = function (msg) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } if (this.disableLogging) { return; } console.error.apply(console, [this.prefix + msg].concat(args)); }; return Logger; }()); exports.Logger = Logger; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.prettyScriptName = "WaniKani Vocab Beyond"; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var logger_1 = __webpack_require__(4); var determinePageType_1 = __webpack_require__(7); var domConstants_1 = __webpack_require__(8); var queryWwwjdicThenInsertParsedResults_1 = __webpack_require__(9); var Log = new logger_1.Logger(); function insertInitialDOMElements(settings) { Log.debug("insertInitialDOMElements called"); var pageType = determinePageType_1.determinePageType(document.URL); if (pageType === determinePageType_1.PageType.kanji && !settings.show_vocab_beyond_first) { insertPageListHeaderLink(); } maybeLoadVocabDependingOnPage(pageType, settings); } exports.insertInitialDOMElements = insertInitialDOMElements; var insertedPageListHeaderLink = false; function insertPageListHeaderLink() { Log.debug("insertPageListHeaderLink called"); if (insertedPageListHeaderLink) { return; } var header = $(".page-list-header"); var listItem = $("<li>"); var link = $("<a href='#" + domConstants_1.sectionHeaderID + "''>Vocab Beyond</a>"); listItem.append(link); // Other scripts may have altered this list, so just insert this link at the end listItem.insertAfter(header.siblings().last()); insertedPageListHeaderLink = true; } function maybeLoadVocabDependingOnPage(pageType, settings) { Log.debug("maybeLoadVocabDependingOnPage called"); if (pageType === determinePageType_1.PageType.other) { Log.debug("maybeLoadVocabDependingOnPage returning early. PageType.other"); return; } var optAttrs = { attributes: true }; var optChildList = { childList: true }; if (pageType === determinePageType_1.PageType.kanji) { Log.debug("maybeLoadVocabDependingOnPage PageType.kanji"); createSectionAndRunQuery(settings); } else if (pageType === determinePageType_1.PageType.reviews) { Log.debug("maybeLoadVocabDependingOnPage PageType.reviews"); var ob = new MutationObserver(function (mutationRecords) { mutationRecords.forEach(checkReviewMut.bind(null, settings)); }); // Observe the element that is mutated after clicking the // Item Info icon with the eye on it ob.observe(document.getElementById("item-info-col2"), optChildList); } else if (pageType === determinePageType_1.PageType.lessons) { Log.debug("maybeLoadVocabDependingOnPage PageType.lessons"); var obs = new MutationObserver(function (mutationRecords) { if (isKanjiLesson()) { createSectionAndRunQuery(settings); } else { Log.debug("not doing anything because not kanji lesson"); } }); // Observe the 3 elements for the 3 lesson types, that are modified // when switching to each new lesson item obs.observe(document.getElementById("supplement-rad"), optAttrs); obs.observe(document.getElementById("supplement-kan"), optAttrs); obs.observe(document.getElementById("supplement-voc"), optAttrs); } } function createSectionAndRunQuery(settings) { var emptySection = maybeInsertEmptyVocabSectionOnce(settings); queryWwwjdicThenInsertParsedResults_1.queryWwwjdicThenInsertParsedResults(settings, emptySection); } function isKanjiLesson() { var mainInfo = document.getElementById("main-info"); return mainInfo && mainInfo.className === "kanji"; } var createdSectionForKanjiReview = false; function checkReviewMut(settings, mutationRecord) { var isKanjiReview = $("#question-type") .text() .toLowerCase() .includes("kanji"); if (mutationRecord.target.id.includes("item-info") && isKanjiReview && !createdSectionForKanjiReview) { createdSectionForKanjiReview = true; createSectionAndRunQuery(settings); } } function maybeInsertEmptyVocabSectionOnce(settings) { var pageType = determinePageType_1.determinePageType(document.URL); Log.debug("maybeInsertEmptyVocabSectionOnce pageType", pageType); if ($("#" + domConstants_1.sectionID).length === 0) { var sectionHTML = "<section>" + '<h2 id="' + domConstants_1.sectionHeaderID + '">Vocab Beyond</h2>' + '<div id="' + domConstants_1.sectionID + '"></div>' + "</section>"; if (pageType === determinePageType_1.PageType.kanji) { Log.debug("maybeInsertEmptyVocabSectionOnce inserting for kanji page"); var informationSection = $("#information"); if (settings.show_vocab_beyond_first) { $(sectionHTML).insertAfter(informationSection); } else { var lastSection = informationSection.siblings().last(); $(sectionHTML).insertAfter(lastSection); } } else if (pageType === determinePageType_1.PageType.reviews) { Log.debug("maybeInsertEmptyVocabSectionOnce inserting for reviews page"); if (settings.show_vocab_beyond_first) { $("#item-info-col2").prepend(sectionHTML); } else { $("#item-info-col2").append(sectionHTML); } } else if (pageType === determinePageType_1.PageType.lessons) { Log.debug("maybeInsertEmptyVocabSectionOnce inserting for lessons page"); if (settings.show_vocab_beyond_first) { $("#supplement-kan-breakdown .col1").append(sectionHTML); } else { $("#supplement-kan-related-vocabulary .col1").append(sectionHTML); } } else { Log.debug("maybeInsertEmptyVocabSectionOnce not inserting because page type does not match"); } } return $("#" + domConstants_1.sectionID); } /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var PageType; (function (PageType) { PageType[PageType["other"] = 0] = "other"; PageType[PageType["radicals"] = 1] = "radicals"; PageType[PageType["kanji"] = 2] = "kanji"; PageType[PageType["vocabulary"] = 3] = "vocabulary"; PageType[PageType["reviews"] = 4] = "reviews"; PageType[PageType["reviewsSummary"] = 5] = "reviewsSummary"; PageType[PageType["lessons"] = 6] = "lessons"; PageType[PageType["lessonsReviews"] = 7] = "lessonsReviews"; })(PageType = exports.PageType || (exports.PageType = {})); function determinePageType(url) { if (/\/radicals\/./.test(url)) { return PageType.radicals; } else if (/com\/kanji\/./.test(url)) { return PageType.kanji; } else if (/com\/vocabulary\/./.test(url)) { return PageType.vocabulary; } else if (/com\/review\/session/.test(url)) { return PageType.reviews; } else if (/com\/review/.test(url)) { return PageType.reviewsSummary; } else if (/com\/lesson\/./.test(url)) { return PageType.lessons; } // TODO: Figure out what URL lessonsReviews is for return PageType.other; } exports.determinePageType = determinePageType; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sectionHeaderID = "wanikani_vocab_beyond_section_header"; exports.sectionID = "wanikani_vocab_beyond_section"; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gm_http_1 = __webpack_require__(1); var logger_1 = __webpack_require__(4); var determinePageType_1 = __webpack_require__(7); var getKanji_1 = __webpack_require__(10); var makeWwwjdicUrl_1 = __webpack_require__(11); var parsing_1 = __webpack_require__(12); var insertForvoAudioForWord_1 = __webpack_require__(19); var Log = new logger_1.Logger(); var cachedSections = {}; var DISABLE_FORVO_DEFAULT = false; function shouldDisableForvo(settings) { var retVal = DISABLE_FORVO_DEFAULT; if (!settings.forvo_api_key || settings.forvo_api_key === "") { retVal = true; } Log.debug("shouldDisableForvo", retVal); return retVal; } function queryWwwjdicThenInsertParsedResults(settings, emptySection) { Log.debug("queryWwwjdic"); if (!emptySection.length) { Log.debug("queryWwwjdicThenInsertParsedResults returning early because emptySection has no elements"); return; } var pageType = determinePageType_1.determinePageType(document.URL); var kanji = getKanji_1.getKanji(pageType); if (!kanji) { Log.error("queryWwwjdicThenInsertParsedResults could not get kanji"); return; } if (cachedSections[kanji]) { Log.debug("queryWwwjdicThenInsertParsedResults reusing cachedSection and returning early"); emptySection.replaceWith(cachedSections[kanji]); return; } var showMessage = function (message) { emptySection.html(message); }; showMessage("Loading..."); Log.debug("Querying WWWJDIC for ", kanji); var wwwJdicUrl = makeWwwjdicUrl_1.makeWwwjdicUrl(kanji, settings); gm_http_1.default .get(wwwJdicUrl) .then(function (res) { onWwwJdicResponse(res.responseText, emptySection, showMessage, settings, kanji); }) .catch(function (err) { Log.error("WWWJDIC error: ", err); showMessage("Error contacting WWWJDIC server"); }); } exports.queryWwwjdicThenInsertParsedResults = queryWwwjdicThenInsertParsedResults; var appendedForvoAttribution = false; function onWwwJdicResponse(res, section, showMessage, settings, kanji) { Log.debug("onWwwJdicResponse raw res", res); var lines = parsing_1.extractLines(res); if (lines.length === 0) { showMessage(settings.show_all_wwwjdic_vocab ? "No vocabulary found." : "No common vocabulary found."); return; } // Clear loading text showMessage(""); var renderables = parsing_1.parseLines(lines); var maybeOnlyCommonRenderables = renderables.filter(function (renderable) { if (settings.show_all_wwwjdic_vocab) { return true; } var isCommon = renderable.cm; return isCommon; }); Log.debug("WWWJDIC maybeOnlyCommonRenderables.length", maybeOnlyCommonRenderables.length); var sliceEnd = maybeOnlyCommonRenderables.length; var limit = settings.max_wwwjdic_vocab_shown; if (limit > 0) { sliceEnd = limit; } var renderablesWithinLimit = maybeOnlyCommonRenderables.slice(0, sliceEnd); Log.debug("WWWJDIC renderablesWithinLimit.length", renderablesWithinLimit.length); Log.debug("WWWJDIC renderablesWithinLimit", renderablesWithinLimit); var disableForvo = shouldDisableForvo(settings); if (!disableForvo) { insertForvoAudioForWord_1.populateForvoUserWhitelist(settings); } var promises = renderablesWithinLimit.map(function (renderable) { var jpText = renderable.jp; var enPOSText = renderable.pos; var isCommon = renderable.cm; var definitions = renderable.en; var vocabForQueryingForvo = renderable.q; var listItem = $("<div>"); listItem.css({ marginBottom: "35px" }); var jpEl = $("<h3>"); var _loop_1 = function (codePoint) { var span = $("<span>"); span.text(codePoint); var codePointInt = codePoint.codePointAt(0); span.css("font-size", shouldRenderBig(codePointInt) ? "45px" : "11px"); // Clicking on kanji opens page for it if (isKanjiCodePoint(codePointInt)) { span.on("click", function () { window.open("https://www.wanikani.com/kanji/" + encodeURIComponent(codePoint), "_blank"); }); span.hover(function () { $(this).css("cursor", "pointer"); }); } span.css({ fontWeight: "normal", lineHeight: "45px" }); jpEl.append(span); }; // for...of iterates over Unicode code points // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator for (var _i = 0, jpText_1 = jpText; _i < jpText_1.length; _i++) { var codePoint = jpText_1[_i]; _loop_1(codePoint); } if (!isCommon && !settings.hide_uncommon_indicator) { // uncommon vocab indicator var uc = $("<span>"); uc.text("稀"); uc.css({ position: "absolute", display: "block", fontSize: "12px", height: "22px", width: "22px", top: "0", left: "-25px", margin: "0", padding: "0", boxSizing: "border-box", borderRadius: "50%", textAlign: "center", lineHeight: "22px", textShadow: "0.7px 0.2px 4.1px #FFF9DE", backgroundColor: "#E38B32", boxShadow: "0 -3px 0 rgba(0,0,0,0.2) inset, 0 0 10px rgba(255,255,255,0.5)", color: "#F41300", zIndex: "999" }); jpEl.append(uc); } jpEl.css({ position: "relative", marginTop: "20px", marginRight: "0", marginBottom: "15px", marginLeft: "0", padding: "0" }); listItem.append(jpEl); var enPOSEl = $("<h3>"); enPOSEl.text(enPOSText); enPOSEl.css({ fontSize: "20px", fontWeight: "normal", lineHeight: "20px", padding: "0" }); listItem.append(enPOSEl); definitions.forEach(function (definition) { var enDefnEl = $("<p>"); enDefnEl.text(definition); enDefnEl.css({ margin: "0", padding: "0" }); listItem.append(enDefnEl); }); section.append(listItem); if (!disableForvo) { return insertForvoAudioForWord_1.insertForvoAudioForWord(vocabForQueryingForvo, settings, listItem); } return Promise.resolve(); }); Promise.all(promises).then(function () { if (!disableForvo && !appendedForvoAttribution) { var forvoAttribution = $('<p><a href="https://forvo.com/" target="_blank">Pronunciations by Forvo</a></p>'); section.append(forvoAttribution); appendedForvoAttribution = true; } var sectionDeepClone = section.clone(true, true); cachedSections[kanji] = sectionDeepClone; }); } function isKanjiCodePoint(codePointInt) { return codePointInt >= 19968 && codePointInt <= 40879; } function shouldRenderBig(codePointInt) { // Determined from "\u3040".codePointAt(0) // All other hiragana, katakana, kanji have higher code points var firstHiraganaCodePointInt = 12352; if (codePointInt > firstHiraganaCodePointInt) { return true; } var punctuationToRenderBig = [ 11816, 11817, 12289, 12293 // repeater ]; if (punctuationToRenderBig.includes(codePointInt)) { return true; } return false; } exports.shouldRenderBig = shouldRenderBig; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var determinePageType_1 = __webpack_require__(7); function getKanji(pageType) { switch (pageType) { case determinePageType_1.PageType.kanji: return document.title[document.title.length - 1]; case determinePageType_1.PageType.reviews: var curItem = $.jStorage.get("currentItem"); if ("kan" in curItem) { return curItem.kan.trim(); } else { return null; } case determinePageType_1.PageType.lessons: var kanjiNode = $("#character"); if (kanjiNode === undefined || kanjiNode === null) { return null; } return kanjiNode.text().trim(); } return null; } exports.getKanji = getKanji; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // API Docs: http://www.edrdg.org/wwwjdic/wwwjdicinf.html#backdoor_tag function makeWwwjdicUrl(kanji, settings) { var encodedKanji = encodeURIComponent(kanji); var useEDICT = "1"; var useBackdoorEntryRawOutput = "Z"; var searchType; var dictionaryLookupWithUTF8LookupText = "U"; searchType = dictionaryLookupWithUTF8LookupText; var keyType; var lookupKanjiInAnyPosition = "L"; keyType = lookupKanjiInAnyPosition; var queryCode = useEDICT + useBackdoorEntryRawOutput + searchType + keyType; return ("http://nihongo.monash.edu/cgi-bin/wwwjdic?" + queryCode + encodedKanji); } exports.makeWwwjdicUrl = makeWwwjdicUrl; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var vocab_header_1 = __webpack_require__(13); var part_of_speech_1 = __webpack_require__(17); var definition_line_1 = __webpack_require__(18); function extractLines(rawResponseText) { if (rawResponseText.indexOf("No matches were found for this key") > -1) { return []; } var noHeader = rawResponseText.slice(rawResponseText.indexOf("<pre>") + 6); var preBody = noHeader.slice(0, noHeader.indexOf("</pre>") - 1); return preBody.split(/\r?\n/); } exports.extractLines = extractLines; var commonP = /(.*)\/\(P\)$/; function parseLines(lines) { return lines.map(function (untrimmed) { var line = untrimmed.trim(); // Extract vocab header var sepIdx = line.indexOf(" /"); var vocabHeader = line.substring(0, sepIdx); var rest = line.substring(sepIdx + 2); // Extract part of speech var firstRightParen = rest.indexOf(")"); var partOfSpeech = rest.substring(1, firstRightParen); var englishAndMaybeCommonP = rest.substring(firstRightParen + 2, rest.length - 1); // Extract common indicator from end of line var commonMatches = englishAndMaybeCommonP.match(commonP); var isCommon; var english; if (commonMatches) { isCommon = true; english = commonMatches[1].replace(/\//g, "; "); } else { isCommon = false; english = englishAndMaybeCommonP.replace(/\//g, "; "); } var definitions = []; var thisDefn; if (english.indexOf("(1) ") === 0) { var nextDefNum = 2; var cur = 0; // index of start of current definition text var next = 0; // index of start of next definition text while (true) { next = english.indexOf("(" + nextDefNum + ")", cur); if (next > -1) { thisDefn = english.substring(cur, next - 1); definitions.push(definition_line_1.formatDefinitionLine(dottedListItem(thisDefn))); nextDefNum++; cur = next; } else { thisDefn = english.substring(cur); definitions.push(definition_line_1.formatDefinitionLine(dottedListItem(thisDefn))); break; } } } else { definitions.push(definition_line_1.formatDefinitionLine(english)); } return { jp: vocab_header_1.formatVocabHeader(vocabHeader), pos: part_of_speech_1.formatPartOfSpeech(partOfSpeech), cm: isCommon, en: definitions, q: extractVocab(vocabHeader) }; }); } exports.parseLines = parseLines; var parenListItemRegExp = /\((\d+)\)(.*)/; function dottedListItem(text) { var matches = text.match(parenListItemRegExp); if (!matches) { return text; } return matches[1] + "." + matches[2].replace(/;$/, ""); } // 3040-309F: hiragana // 30A0-30FF: katakana // 4E00-9FAF: common and uncommon kanji var jpRegex = /([\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FAF])+/; function extractVocab(jpText) { var matches = jpText.match(jpRegex); return matches ? matches[0] : jpText; } /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var vocab_1 = __webpack_require__(14); var pronunciation_1 = __webpack_require__(16); var pronunciationSplitter = /(.*)\[(.+)\]$/; function formatVocabHeader(text) { var m = text.match(pronunciationSplitter); if (!m) { return text; } return vocab_1.formatVocab(m[1].trim()) + pronunciation_1.formatPronunciation(m[2]); } exports.formatVocabHeader = formatVocabHeader; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dict_codes_1 = __webpack_require__(15); var dictCodeSplitter = /(.*)\(([a-z,A-Z-,0-9]+)\)$/; function formatVocab(words) { return words .replace(/\(P\)/g, "(common)") .split(";") .map(function (word) { var trimmed = word.trim(); var m = trimmed.trim().match(dictCodeSplitter); if (!m) { return trimmed; } return m[1] + "(" + (dict_codes_1.DICT_CODES[m[2]] || m[2]) + ")"; }) .join("、"); } exports.formatVocab = formatVocab; /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DICT_CODES = { abbr: "abbreviation", "adj-f": "noun or verb acting prenominally", "adj-i": "i-adjective", "adj-kari": "'kari' adjective (archaic)", "adj-ku": "'ku' adjective (archaic)", "adj-na": "na-adjective", "adj-nari": "archaic/formal form of na-adjective", "adj-no": "no-adjective", "adj-pn": "pre-noun adjectival (rentaishi)", "adj-s": "special adjective", "adj-shiku": "'shiku' adjective (archaic)", "adj-t": "'taru' adjective", adv: "adverb", "adv-n": "adverbial noun", "adv-to": "adverb taking the と particle", an: "adjectival noun (keiyoudoushi)", anat: "anatomical term", arch: "archaism", archit: "architecture term", astron: "astronomy term", ateji: "ateji reading", aux: "auxiliary", "aux-adj": "auxiliary adjective", "aux-v": "auxiliary verb", baseb: "baseball term", biol: "biology term", bot: "botany term", Buddh: "Buddhist term", bus: "business term", c: "company name", chem: "chemistry term", chn: "children's language", col: "colloquialism", comp: "computer terminology", conj: "conjunction", ctr: "counter", derog: "derogatory word or expression", econ: "economics term", eK: "exclusively written in kanji", engr: "engineering term", exp: "expression", f: "female given name", fam: "familiar language", fem: "female term or language", finc: "finance term", food: "food term", g: "given name, as-yet not classified by sex", geol: "geology term", geom: "geometry term", gikun: "gikun (meaning) reading", gram: "grammatical term", h: "full (family plus given) name of a person", hob: "Hokkaido-ben", hon: "honorific language (sonkeigo)", hum: "humble language (kenjougo)", id: "idiomatic expression", ik: "irregular kana", iK: "irregular kanji", int: "interjection", io: "irregular okurigana", iv: "irregular verb", joc: "jocular, humorous term", ksb: "Kansai-ben", ktb: "Kantou-ben", kyb: "Kyoto-ben", kyu: "Kyuushuu-ben", law: "law term", ling: "linguistics terminology", m: "male given name", "m-sl": "manga slang", MA: "martial arts term", male: "male term or language", "male-sl": "male slang", math: "mathematics", med: "medical term", mil: "military", music: "music term", n: "noun", "n-adv": "adverbial noun", "n-pr": "proper noun", "n-pref": "prefix noun", "n-suf": "suffix noun", "n-t": "temporal noun", nab: "Nagano-ben", neg: "negative (in a negative sentence, or with negative verb)", "neg-v": "negative verb (when used with)", num: "numeral", o: "organization name", obs: "obsolete term", obsc: "obscure term", ok: "outdated kana", oK: "outdated kanji", "on-mim": "onomatopoeic or mimetic word", osb: "Osaka-ben", p: "place-name", physics: "physics terminology", pn: "pronoun", poet: "poetical term", pol: "polite language", pr: "product name", pref: "prefix", proverb: "proverb", prt: "particle", qv: "quod vide (see another entry)", rare: "rare", rkb: "Ryukyuan language", s: "surname", sens: "sensitive", Shinto: "Shinto term", sl: "slang", sports: "sports term", st: "station name", suf: "suffix", sumo: "sumo term", thb: "Touhoku-ben", tsb: "Tosa-ben", tsug: "Tsugaru-ben", u: "unclassified name", uk: "usually written using kana alone", uK: "usually written using kanji alone", "v-unspec": "verb unspecified", v1: "ichidan verb", "v2a-s": "nidan verb (archaic)", "v2b-k": "nidan verb (archaic)", "v2b-s": "nidan verb (archaic)", "v2d-k": "nidan verb (archaic)", "v2d-s": "nidan verb (archaic)", "v2g-k": "nidan verb (archaic)", "v2g-s": "nidan verb (archaic)", "v2h-k": "nidan verb (archaic)", "v2h-s": "nidan verb (archaic)", "v2k-k": "nidan verb (archaic)", "v2k-s": "nidan verb (archaic)", "v2m-k": "nidan verb (archaic)", "v2m-s": "nidan verb (archaic)", "v2n-s": "nidan verb (archaic)", "v2r-k": "nidan verb (archaic)", "v2r-s": "nidan verb (archaic)", "v2s-s": "nidan verb (archaic)", "v2t-k": "nidan verb (archaic)", "v2t-s": "nidan verb (archaic)", "v2w-s": "nidan verb (archaic)", "v2y-k": "nidan verb (archaic)", "v2y-s": "nidan verb (archaic)", "v2z-s": "nidan verb (archaic)", v4b: "yodan verb (archaic)", v4g: "yodan verb (archaic)", v4h: "yondan verb (archaic)", v4k: "yodan verb (archaic)", v4m: "yodan verb (archaic)", v4n: "yodan verb (archaic)", v4r: "yondan verb (archaic)", v4s: "yodan verb (archaic)", v4t: "yodan verb (archaic)", v5aru: "godan verb", v5b: "godan verb", v5g: "godan verb", v5k: "godan verb", "v5k-s": "godan verb", v5m: "godan verb", v5n: "godan verb", v5r: "godan verb", "v5r-i": "godan verb", v5s: "godan verb", v5t: "godan verb", v5u: "godan verb", "v5u-s": "godan verb", v5uru: "godan verb", v5z: "godan verb", vi: "intransitive verb", vk: "kuru verb", vn: "irregular nu verb", vr: "irregular ru verb, plain form ends with -ri", vs: "suru verb", "vs-c": "su verb - precursor to the modern suru", "vs-i": "suru verb - irregular", "vs-s": "suru verb - special class", vt: "transitive verb", vulg: "vulgar expression or word", vz: "ichidan verb - -zuru special class (alternative form of -jiru verbs)", X: "rude or X-rated term", zool: "zoology term" }; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* tslint:disable:no-console */ Object.defineProperty(exports, "__esModule", { value: true }); var dict_codes_1 = __webpack_require__(15); // 3040-309F: hiragana // 30A0-30FF: katakana // 4E00-9FAF: common and uncommon kanji var kanjiAndCodeSplitter = /^(.*)\(([\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]+)\)\(([a-zA-Z0-9,]+)\)$/; var codeSplitter = /^(.*)\(([a-zA-Z0-9,]+)\)$/; var kanjiSplitter = /^(.*)\(([\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]+)\)$/; var kanjiAndParenthesizedCsvSplitter = /^([\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]+)\(([\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF,]+)\)/; function formatPronunciation(pronunciation) { var parts = pronunciation.split(";"); var mapped = parts .map(function (part) { var kcm = part.match(kanjiAndCodeSplitter); if (kcm) { return (kcm[1] + "⸨" + kcm[2] + "⸩" + "(" + (dict_codes_1.DICT_CODES[kcm[3]] || kcm[3]) + ")"); } var kp = part.match(kanjiAndParenthesizedCsvSplitter); if (kp) { return kp[1] + "⸨" + kp[2].replace(",", "、") + "⸩"; } var cm = part.match(codeSplitter); if (cm) { var code = cm[2]; var expandedCode = code; if (code === "P") { expandedCode = "common"; } else if (dict_codes_1.DICT_CODES[code]) { expandedCode = dict_codes_1.DICT_CODES[code]; } return cm[1] + "(" + expandedCode + ")"; } var km = part.match(kanjiSplitter); if (km) { return km[1] + "⸨" + km[2] + "⸩"; } return part; }) .join("、"); return "(" + mapped + ")"; } exports.formatPronunciation = formatPronunciation; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dict_codes_1 = __webpack_require__(15); function capitalize(text) { return text.charAt(0).toUpperCase() + text.slice(1); } function formatPartOfSpeech(commaDelimitedPos) { if (!commaDelimitedPos) { return ""; } return (commaDelimitedPos.split(",") || []) .map(function (part) { var expandedPos = dict_codes_1.DICT_CODES[part]; return expandedPos ? capitalize(expandedPos) : capitalize(part); }) .join(", "); } exports.formatPartOfSpeech = formatPartOfSpeech; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var dict_codes_1 = __webpack_require__(15); function formatDefinitionLine(line) { return replaceAbbreviations(replaceDictCodesAtEnd(replaceDictCodesAtStart(line))); } exports.formatDefinitionLine = formatDefinitionLine; function replaceDictCodesAtStart(text) { // Both regexes account for an optional numbered list prefix (e.g. "1. ") var dictCodeInParens = /^([0-9]\.\s)?\(([a-z,A-Z,-,0-9]+)\)(.*)/; var dictCodeInBraces = /^([0-9]\.\s)?\{([a-z,A-Z,-,0-9]+)\}(.*)/; var parenMatches = text.match(dictCodeInParens); var braceMatches = text.match(dictCodeInBraces); if (parenMatches) { var listPrefix = parenMatches[1] ? parenMatches[1] : ""; return listPrefix + replaceDictCode(parenMatches[2]) + parenMatches[3]; } if (braceMatches) { var listPrefix = braceMatches[1] ? braceMatches[1] : ""; return listPrefix + replaceDictCode(braceMatches[2]) + braceMatches[3]; } return text; } function replaceDictCode(maybeDictCode) { var longForm = dict_codes_1.DICT_CODES[maybeDictCode]; if (!longForm) { return "(" + maybeDictCode + ")"; } return "[" + longForm + "]"; } function replaceDictCodesAtEnd(text) { var dictCodesInParens = /(.*)\(([a-z,A-Z,0-9\,\-]+)\)$/; var m = text.match(dictCodesInParens); if (!m) { return text; } var longFormCodes = m[2] .split(",") .map(function (maybeDictCode) { var longForm = dict_codes_1.DICT_CODES[maybeDictCode]; return longForm ? longForm : maybeDictCode; }) .join(", "); return m[1] + "(" + longFormCodes + ")"; } function replaceAbbreviations(text) { return text.replace(/usu\./g, "usually").replace(/esp\./g, "especially"); } /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var logger_1 = __webpack_require__(4); var getWordPronunciations_1 = __webpack_require__(20); var Log = new logger_1.Logger(); var forvoUserWhitelist = [""]; var EMPTY_FORVO_USER_WHITELIST = JSON.stringify(forvoUserWhitelist); function populateForvoUserWhitelist(settings) { if (typeof settings.forvo_username_whitelist_csv === "string") { forvoUserWhitelist = settings.forvo_username_whitelist_csv .trim() .replace(/ /g, "") .split(","); } } exports.populateForvoUserWhitelist = populateForvoUserWhitelist; function insertForvoAudioForWord(jpVocabText, settings, destAppendee) { if (!destAppendee) { Log.error("destAppendee missing"); return Promise.reject(new Error()); } Log.debug("Querying Forvo for ", jpVocabText); return getWordPronunciations_1.getWordPronunciations(jpVocabText, settings) .then(function (responseText) { if (!responseText) { Log.warn("no Forvo responseText"); return Promise.resolve(); } return handleForvoSuccess(responseText, settings, destAppendee); }) .catch(function (res) { Log.error("Forvo API error: ", res.statusText); }); } exports.insertForvoAudioForWord = insertForvoAudioForWord; function handleForvoSuccess(responseText, settings, destAppendee) { var parsedForvoJson; try { parsedForvoJson = JSON.parse(responseText); } catch (parseErr) { Log.error("JSON parseErr", parseErr); } var forvoItems = parsedForvoJson.items; if (!forvoItems || forvoItems.length === 0) { Log.warn("no forvoItems"); return Promise.resolve(); } var audioSection = $("<div>"); audioSection.css("margin-top", "10px"); forvoItems.forEach(function (forvoItem) { if (!forvoItem.pathmp3) { Log.error("!forvoItem.pathmp3"); return; } if (!forvoItem.username) { Log.error("!forvoItem.username"); return; } if (JSON.stringify(forvoUserWhitelist) !== EMPTY_FORVO_USER_WHITELIST && !forvoUserWhitelist.includes(forvoItem.username)) { Log.debug("skipping pronunciation from " + forvoItem.username); return; } var audioContainer = $("<div>"); audioContainer.css({ fontSize: "12px", display: "inline-block", boxSizing: "border-box", width: "250px", marginTop: "0", marginRight: "5px", marginBottom: "5px", marginLeft: "0", padding: "0" }); var audioEl = document.createElement("audio"); audioEl.src = forvoItem.pathmp3; audioEl.controls = true; audioEl.preload = "none"; audioEl.style.width = "250px"; if (settings.show_forvo_usernames) { var usernameEl = $("<span>"); usernameEl.text(forvoItem.username); usernameEl.css({ fontSize: "12px", color: "#888888", margin: "0", padding: "0" }); audioContainer.prepend(usernameEl); } audioContainer.append(audioEl); audioSection.append(audioContainer); }); destAppendee.append(audioSection); return Promise.resolve(); } /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var gm_http_1 = __webpack_require__(1); var logger_1 = __webpack_require__(4); var Log = new logger_1.Logger(); function getWordPronunciations(jpWord, settings) { if (!jpWord) { return Promise.reject(new Error("jpWord missing")); } var forvoApiKey = settings ? settings.forvo_api_key : null; if (!forvoApiKey) { return Promise.reject(new Error("Forvo api key missing")); } var forvoUrl = "https://apifree.forvo.com/key/" + forvoApiKey + "/format/json" + "/action/word-pronunciations" + "/word/" + encodeURIComponent(jpWord) + "/language/ja" + "/rate/" + String(settings.forvo_min_rating || 0) + "/country/JPN" + "/order/rate-desc"; return gm_http_1.default .get(forvoUrl) .then(function (res) { return Promise.resolve(res.responseText); }) .catch(function (err) { Log.error("Forvo error: ", err); }); } exports.getWordPronunciations = getWordPronunciations; /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var windowHelpers_1 = __webpack_require__(22); var WKOF_POLL_INTERVAL_MS = 10; var WKOF_WAIT_TIMEOUT_MS = 10000; var WKOF_INSTALL_PAGE = "https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549"; var prompted = false; function promptInstall(scriptName, overridingGetWindowFunc) { if (prompted) { return; } var win = (overridingGetWindowFunc || windowHelpers_1.getWindow)(); prompted = true; if (win.confirm(scriptName + " requires the Wanikani Open Framework.\nDo you want to be forwarded to the installation instructions?")) { win.location.href = WKOF_INSTALL_PAGE; } } // waitForWkof calls onLoad with the global wkof object after wkof is loaded function waitForWkof(scriptName, onLoad) { windowHelpers_1.waitUntilWindowPropLoads(windowHelpers_1.getWindow, "wkof", WKOF_POLL_INTERVAL_MS, WKOF_WAIT_TIMEOUT_MS, onLoad, promptInstall.bind(null, scriptName)); } exports.waitForWkof = waitForWkof; /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(global) { Object.defineProperty(exports, "__esModule", { value: true }); function getWindow() { return global; } exports.getWindow = getWindow; function waitUntilWindowPropLoads(getWindowFunc, windowProp, pollingIntervalMs, maxWaitMs, onLoad, onTimeout) { var startMs = new Date().getTime(); var intervalID = setInterval(function () { if (getWindowFunc()[windowProp]) { clearInterval(intervalID); onLoad(getWindowFunc()[windowProp]); return; } if (new Date().getTime() - startMs > maxWaitMs) { clearInterval(intervalID); onTimeout(); } }, pollingIntervalMs); } exports.waitUntilWindowPropLoads = waitUntilWindowPropLoads; /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(23))) /***/ }), /* 23 */ /***/ (function(module, exports) { var g; // This works in non-strict mode g = (function() { return this; })(); try { // This works if eval is allowed (see CSP) g = g || Function("return this")() || (1, eval)("this"); } catch (e) { // This works if the window reference is available if (typeof window === "object") g = window; } // g can still be undefined, but nothing to do about it... // We return undefined, instead of nothing here, so it's // easier to handle this case. if(!global) { ...} module.exports = g; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SettingsScriptId = "wanikani_vocab_beyond_settings"; exports.MenuScriptLinkId = "wanikani_vocab_beyond_settings_link"; exports.WkofSettingsMenuConfig = { script_id: exports.SettingsScriptId, title: "WaniKani Vocab Beyond", autosave: true, background: false, content: { forvo_page_id: { type: "page", label: "Audio", hover_tip: "Settings for Forvo.com audio pronunciations", content: { forvo_instructions: { type: "html", html: "<p><a href='https://forvo.com' target='_blank'>Forvo.com</a> has an audio collection of words pronounced by native Japanese speakers.</p>" + "<p>To enable Forvo pronunciations of vocabulary words:</p>" + "<p>1. <a href='https://forvo.com/signup/' target='_blank'>Sign up for a Forvo.com account</a></p>" + "<p>2. <a href='https://api.forvo.com/plans-and-pricing' target='_blank'>Purchase an API key here</a></p>" + "<p>3. Enter your key below</p>" }, forvo_api_key: { type: "text", default: "", label: "Forvo API key", full_width: true, hover_tip: "Your API key from https://api.forvo.com/" }, forvo_caveat: { type: "html", html: "<p>(WaniKani Vocab Beyond will work without a Forvo API key, but audio for vocabulary won't be shown.)</p>" }, forvo_divider_id: { type: "divider" }, forvo_rating_instructions: { type: "html", html: "<p>Forvo pronunciations are voted on by users. Limit displayed audio to at least this overall rating. Zero is the default and recommended value.</p>" }, forvo_min_rating: { type: "number", label: "Minimum Forvo rating", hover_tip: "Only show Forvo pronunciations with at least this rating", placeholder: "0", default: 0, full_width: false }, forvo_divider_id_2: { type: "divider" }, forvo_whitelist_instructions: { type: "html", html: "<p>Comma-separated list of Forvo users whose pronunciations should be shown. If blank, pronunciations from all users are shown.</p>" }, forvo_username_whitelist_csv: { type: "text", label: "Favorite Forvo users", full_width: true, placeholder: "Example: skent, usako_usagiclub, strawberrybrown", default: "", hover_tip: "A comma-separated list of Forvo usernames whose pronunciations should be shown" } } }, vocab_page_id: { type: "page", label: "Vocab", hover_tip: "Settings for WWWJDIC vocabulary words", content: { vocab_instructions_1: { type: "html", html: "<p>By default, only common words are retrieved and displayed from <a href='http://nihongo.monash.edu/cgi-bin/wwwjdic' target='_blank'>WWWJDIC</a>. You can also retrieve uncommon words and phrases by checking the box below.</p>" }, show_all_wwwjdic_vocab: { type: "checkbox", label: "Show uncommon vocab", hover_tip: "Show both common and uncommon WWWJDIC vocab", default: false, full_width: false }, vocab_instructions_2: { type: "html", html: "<p>Set the maximum number of WWWJDIC vocab to display per kanji below. 0 means unlimited. (Warning: showing WWWJDIC unlimited results may quickly exhaust your Forvo API key's daily request limits.)</p>" }, max_wwwjdic_vocab_shown: { type: "number", label: "Maximum number of WWWJDIC vocab to display per kanji", hover_tip: "Maximum number of WWWJDIC vocabulary to display per kanji", full_width: true, placeholder: "15", default: 15, min: 0 } } }, appearance_page_id: { type: "page", label: "Appearance", hover_tip: "Appearance settings", content: { appearance_instructions_1: { type: "html", html: "<p>Check to show Vocab Beyond at top of kanji pages and in the first tab of kanji reviews and lessons.</p>" }, show_vocab_beyond_first: { type: "checkbox", label: "Show Vocab Beyond first", hover_tip: "Show the Vocab Beyond section at the top of kanji pages and in the first tab of kanji reviews and kanji lessons", default: false, full_width: false }, appearance_instructions_2: { type: "html", html: "<p>Check to show Forvo usernames above audio clips.</p>" }, show_forvo_usernames: { type: "checkbox", label: "Show Forvo usernames", hover_tip: "Show Forvo usernames above each audio clip", default: false, full_width: false }, appearance_instructions_3: { type: "html", html: "<p>Check below to hide icon beside uncommon vocab.</p>" }, hide_uncommon_indicator: { type: "checkbox", label: "Hide uncommon icon", hover_tip: "Hide uncommon vocabulary icon", default: false, full_width: false } } } } }; /***/ }) /******/ ]);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址