// ==UserScript== // @name KG_ComplexityPanel // @version 2.0.0 // @namespace klavogonki // @author Silly_Sergio // @description Добавляет панель прогноза сложности текста в заездах // @include http*://klavogonki.ru/g/* // @grant none // ==/UserScript== function embed() { var COMPLEXITY_TEXT = [ "СУПЕР РЕКОРДНЫЙ ТЕКСТ", // < 1 "РЕКОРДНЫЙ ТЕКСТ", // < 2 "очень лёгкий текст", // < 3 "лёгкий текст", // < 4 "нормальный текст", // < 5 "нормальный текст", // < 6 "текст сложней нормального",// < 7 "сложноватый текст", // < 8 "сложный текст", // < 9 "очень сложный текст", // < 10 "очень сложный текст", // < 11 "крайне сложный текст", // < 12 "крайне сложный текст", // < 13 "мега сложный текст", // < 14 "мега сложный текст", // < 15 "текст - жесть", // < 16 "текст - жесть", // < 17 "запредельная сложность" // < 18 ]; // 2 letters combinations for the Russian language, ordered by their frequency. Only the first 791 most common combinations are included. // The rest will get the worst coefficient. var SYLLABLES_RU = "тостнанопонеконираеналроовголипркаосерреотволаолтатьонваореллоеттеомодзавеилриатдеанлеогесдальитактиемасмеойсяныдообскмо" + "инчежесеамазтрмикиависвиедбысоманнимарсьчтслегнурутвбовыдииевсизейивикпеокэтхооеадожчабемушеспаяихияудкрочсидневчиляылкузнсапаты" + "дуульншиутнящежитсеесвыйрыопозекмнидаетуусичглужлуятлсвнийыеымезгабребтныхиражмыжадруюьсснлюпиечгднтбугрииахрярнабжнаюссучачьквл" + "ньумчноиугапывцеплщизвбиепгиешсмашблсуцишазджддвошбактврукицагайртежпуялупклдлвуурытоязолытккенсубещысянушвшдыувцаютишиггуйсшьох" + "хатяехядндчуьшзирьшкющибшлбягеясдьнквзземязыьюзуямзмрврмышиюкндснцухщайнявлнунбнюдркрсьефилкиоецпырдсычкущллржсрдяацзрзгузфоиаюб" + "счргязлжеоксвягнижшнджьяащвтоойтвкзлипдкящощхнуефебщхишовдтлыршувпзяоюсдчьыбьмжуфаршмлпяхрмпквяхнгцоофяецыбсынхвсхеяыкищаивьдцоц" + "якфрйднчьзрхыпычйчауафзбючмсюсяжзкэлпньтбъяюсюрлцущунюхулгеювмдттдеарюнщзьхлуабкмкгкэнчшдпеиыдэкъеыгтчйкммррячрплчъятттпштеуяржк" + "ягжоьцуйэрьбптоупппкоэйшефифрчрбмьсшяяюрхерцлднрызлткцсбдммбчоймбхпьддцвфлфущнжчьгзжнфтмюньчэмьдьицкпсдшйокжуятцйцтюхмсцйлуивввч" + "бвдчяцмряйхсэйдхщьюзаоккрзябыжмгсэтбсфюкбмвхюмнзмчэсмэжьчлбьяпьфлпффрэжбюлдбэдвцнвгчуэвгиулбяилмхтюцдздгшвоаюжьврфсжэвкэнжьодюсг" + "съмцююдъэпрщлздэыягвюшббэфюглвчргсфтаэкззсггшпуфтщйруошмжсззпчмвтхфыюхгтзъааяшбюбдэгуцйеншбжгмлэыцкшйзхэмфнбвщжрфстэлштъпцбшзтжл" + "иэнхйвшрыщьщжжтгкмжгйфтшэхзчтфвънлыивблхсзнэйбйабэлфэшхшьпэзюпкгжмпшбтзцйгчвгэмтйхбзмюйяэбтзфьзюшцюйфюйпкпмъюабцпюхьювкхгбщрхъвэ" + "пэчмзшмзбчууфнцзкдлщчжхгфэыумщгюфгкюгшжюшюбгнъщоцлццфммхюикъкбцнпбнмцмйикьнплъюепфъюдфлрьхцсмшкчххюфьркфжтмдвжзэцрхкфчгхсщюэшсцд" + "ччхчгпфбеэхдшээямжжэяугзшхвюйщфяжцээйюгфпвхпэожвчэтжцп"; // 2 letters combinations for English, ordered by their frequency. Usual English and mini-marathons English dictionaries were used. // Only the first 274 most common combinations are included. // The rest will get the worst coefficient. var SYLLABLES_EN = "hethineranreedndnghaenonatastohiouitstorarwaofleteesiseasevealnentrometiadlldelibeelcoshrieeutnohoomowlychraloceunlaotwefoacmaooldwiwhghimetpeulurilicsitauskesoirmoaidicarstrgessemioidwoigoleynsckhtecrtdobuniiencpaosmievayblfetsambofifrsuttrdugporysaplpragavfactabgrbaovgaapeiodspifuptuopvitlivmprncrnadakiclwngobrokefpippepciewdrdsrryeslawrutybyexftucffscakgirmflhrqultauumianyknrluicuochutwlsgllulfnlikmyfuyomurkoaipoimsnkuepubimbptegnnrcsmafuduaysvatcguddobgsdypsskrgjududlswmmibzeognuubkseolkvoyirvccizdnphxpjoehgngglmsnoylvnfwsrpdgrfwlwrxtnvsy"; // Complexity weight for each character. Russian letters and special characters use different formulas, so even if you // see the same weights for some Russian letter and some special character, they will contribute different final weights. var CHAR_WEIGHTS_RU = { "а": 105, "б": 142, "в": 119, "г": 140, "д": 125, "е": 105, "ж": 153, "з": 142, "и": 107, "й": 150, "к": 122, "л": 117, "м": 122, "н": 108, "о": 100, "п": 126, "р": 118, "с": 115, "т": 110, "у": 127, "ф": 155, "х": 157, "ц": 175, "ч": 145, "ш": 160, "щ": 180, "ъ": 200, "ы": 140, "ь": 137, "э": 183, "ю": 167, "я": 135, "\n": 0.3, " ": 0.3, ".": 2.0, ",": 2.5, "!": 4.0, "?": 3.0, ":": 4.0, ";": 4.5, "\"": 7.0, "«": 5.0, "»": 5.0, "'": 9.0, "_": 8.0, "%": 8.0, "—": 5.0, "–": 5.0, "-": 5.0, "(": 5.0, ")": 5.0, "*": 7.0, "=": 7.0, "+": 7.0, "№": 5.0, "#": 9.0, "$": 9.0, "&": 9.0, "/": 9.0, "\\": 10.0, "|": 10.0, "<": 11.0, ">": 11.0, "@": 11.0, "[": 11.0, "]": 11.0, "^": 11.0, "~": 11.0, "`": 11.0, "{": 11.0, "}": 11.0, "0": 5.0, "1": 5.0, "2": 5.0, "3": 5.0, "4": 5.0, "5": 5.0, "6": 5.0, "7": 5.0, "8": 5.0, "9": 5.0 }; // Complexity weight for each character in English QWERTY layout. // TODO: consider separate processing for apostrophe in words vs single quota var CHAR_WEIGHTS_EN_QWERTY = { "f": 105, /*",": 142,*/ "d": 119, "u": 140, "l": 125, "t": 105, /*";": 153,*/ "p": 142, "b": 107, "q": 150, "r": 122, "k": 117, "v": 122, "y": 108, "j": 100, "g": 126, "h": 118, "c": 115, "n": 110, "e": 127, "a": 155, /*"[": 157,*/ "w": 175, "x": 145, "i": 160, "o": 180, /*"]": 200,*/ "s": 140, "m": 137, /*"'": 183,*/ /*".": 167,*/ "z": 135, "\n": 0.3, " ": 0.3, ".": 1.5, ",": 1.0, "!": 4.0, "?": 2.5, ":": 2.0, ";": 1.5, "\"": 2.5, "«": 2.5, "»": 2.5, "'": 2.0, "_": 8.0, "%": 8.0, "—": 5.0, "–": 5.0, "-": 5.0, "(": 5.0, ")": 5.0, "*": 7.0, "=": 7.0, "+": 7.0, "№": 9.0, "#": 5.0, "$": 4.5, "&": 3.0, "/": 2.0, "\\": 10.0, "|": 10.0, "<": 1.5, ">": 2.0, "@": 11.0, "[": 2.5, "]": 3.0, "^": 4.0, "~": 8.0, "`": 5.0, "{": 3.0, "}": 3.5, "0": 5.0, "1": 5.0, "2": 5.0, "3": 5.0, "4": 5.0, "5": 5.0, "6": 5.0, "7": 5.0, "8": 5.0, "9": 5.0 }; // Spectrum canvas settings var CANVAS_HEIGHT = 12; var CANVAS_OPACITY = 0.65; // This is the upper threshold for the spectrum complexity. Everything up will be pure red. var MAX_SPECTRUM_COMPLEXITY = 310; // This is the bottom threshold for the spectrum complexity. Everything down will be pure green. var MIN_SPECTRUM_COMPLEXITY = 120; var SPECTRUM_COMPLEXITY_RANGE = MAX_SPECTRUM_COMPLEXITY - MIN_SPECTRUM_COMPLEXITY; // If character is not found, then it will be treated as a special character with the given weight var UNKNOWN_CHAR_WEIGHT = 15.0; // All Russian letters, with the exception of the first one, in the word will get such default weight var DEFAULT_LETTER_WEIGHT = 100; // Characters for Russian language. var ALPHABETICAL_CHARACTERS_RU = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"; // Characters for English. var ALPHABETICAL_CHARACTERS_EN = "abcdefghijklmnopqrstuvwxyz"; // If letter is a capital, we add such a number to its weight var CAPITAL_WEIGHT = 200.0; // If the some word has number of capitals more than this value, then we stop apply CAPITAL_COEF, because user will likely use Caps key var CAPS_LENGTH = 4; // If character is not part of Russian letters, we multiply weight by this number var SPECIAL_CHARACTER_COEF = 200.0; // Whole word's weight will get coefficient multiplied depending on its size. Longer words are harder to type. // If a word has only a single letter, then it will take longer to type it, because it doesn't have keys combination // with other letters. var WORD_LENGTH_COEF = [2.0, 1.0, 1.0, 1.0, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0]; // Dictionary with 2 letters combinations and their frequency orders. We use associative array for search, because it is much faster (if it is hot), // than other approaches: String#indexOf, RegExp, Array#indexOf. var dictionary = {}; // A flag for preventing clone panel creation: var initialized = false; // Saving the original prototype method: var proxied = window.XMLHttpRequest.prototype.send; window.XMLHttpRequest.prototype.send = function () { this.addEventListener('load', function () { try { var json = JSON.parse(this.responseText); if ('text' in json) { createPanel(json.text.text); } } catch (e) {} }.bind(this)); return proxied.apply(this, [].slice.call(arguments)); }; function createPanel (text) { if (initialized) { return false; } initialized = true; var complexityObject = getComplexity(text); var complexity = complexityObject.complexity.toFixed(2); var params = document.getElementById("params"); if (params) { // We use wrapper only as a workaround to support KTS custom styles. // KTS changes panel style by ID. We use "statistics" ID, which is also used by another panel. // HTML 5 allows duplicate IDs. They just need to be in different subtrees. I don't like // such approach, but I fear it's the only way for now, unless we ask KTS developer to // include some lines into img/apply.js file. var wrapper = document.createElement("div"); wrapper.id = "complexity-panel"; var elem = document.createElement("div"); elem.style.setProperty("background", "none repeat scroll 0 0 #F8F4E6", null); elem.style.setProperty("margin-top", "10px", null); elem.style.setProperty("margin-bottom", "10px", null); elem.id = "statistics"; wrapper.appendChild(elem); params.parentNode.insertBefore(wrapper, params); elem.innerHTML = '