// ==UserScript==
// @name ЧАС-коррект
// @namespace http://www.example.com/gmscripts
// @description Исправление наиболее частотных ошибок на просматриваемых страницах
// @include http://*
// @include https://*
// @version 0.2.0.1
// ==/UserScript==
(function(){'use strict';
/*
Copyright Nikolay Avdeev aka NickKolok aka Николай Авдеев 2015
Всем привет из снежного Воронежа!
This file is part of CHAS-CORRECT.
CHAS-CORRECT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CHAS-CORRECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CHAS-CORRECT. If not, see <http://www.gnu.org/licenses/>.
(Этот файл — часть CHAS-CORRECT.
CHAS-CORRECT - свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней
версии.
CHAS-CORRECT распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.)
*/
var storageWrapper={
///Обёртка над хранилищем, в данном случае - GreaseMonkey
getKey: function(key,defaultValue){
return JSON.parse(GM_getValue(key,defaultValue)) || defaultValue;
},
setKey: function(key,value){
GM_setValue(key,JSON.stringify(value));
},
};
/*
Copyright Nikolay Avdeev aka NickKolok aka Николай Авдеев 2015
Всем привет из снежного Воронежа!
This file is part of CHAS-CORRECT.
CHAS-CORRECT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CHAS-CORRECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CHAS-CORRECT. If not, see <http://www.gnu.org/licenses/>.
(Этот файл — часть CHAS-CORRECT.
CHAS-CORRECT - свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней
версии.
CHAS-CORRECT распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.)
*/
'use strict';
var oldTime = new Date().getTime();
var sya="(?=(?:ся|)(?:[^А-Яа-яЁёA-Za-z]|^|$))";
var ca="[цc]+[ао]";
var orphoWordsToCorrect=[
/*
["",""],
["",""],
["",""],
["",""],
["",""],
["",""],
*/
["по-*которой","по которой"],//Да, и такое бывает. TODO: просклонять
["про-*запас","про запас"],
["свеч","свеч"],
["по-*крайней","по крайней"],
["н[ао]-*[ао]б[ао]рот","наоборот"],
["говорю","говорю"],//TODO: проспрягать
["тол*ь*к[ао]-*что","только что"],
["покруче","покруче"],
["поначалу","поначалу"],
["кое[\s]*где","кое-где"],//TODO: аналоги
["где-*угодно","где угодно"],
["луч[ёе]м","лучом"],
["куда-*как","куда как"],
["наконец-таки","наконец-таки"],
["по[\s-]немногу","понемногу"],
["как-*только","как только"],
["в-*сч[ёе]т","в счёт"],
["молодежь","молодежь"],
["в-*первую","в первую"],
["понадежнее","понадежнее"],
["покрупнее","покрупнее"],
["потому как","потому как"],
["по сети","по сети"],
["по-*идее","по идее"],
["н[еи]зна[еи]т","не знает"],
["сегодня","сегодня"],
["зачем-то","зачем-то"],
["помочь","помочь"],
["тем-*более","тем более"],
["так-*что","так что"],
["иметь в-*виду","иметь в виду"],//TODO: проспрягать
["как-*нить","как-нибудь"],
["изменишь","изменишь"],
["в-*случае","в случае"],
["так-*как","так как"],
["во+бще-*то","вообще-то"],
["рука[\\s-]*об[\\s-]*руку","рука об руку"],
["вроде-*бы","вроде бы"],
["по-*возможности","по возможности"],
["слышь","слышь"],
["вещь*","вещь"],
["н[еи][\\s-]+ужели","неужели"],
["по[\\s]*английски","по-английски"],//TODO: другие языки
["пол-литра","пол-литра"],
["не могли","не могли"],//TODO: окончания
["поподробнее","поподробнее"],
["тысяч","тысяч"],
["до-*свидания","до свидания"],
["до-*свиданья","до свиданья"],
["м[оа]л[оа]д[её]ж[еи]","молодёжи"],
["щ[еи]таю","считаю"],
["кирпич[её]м","кирпичом"],
["вовремя","вовремя"],
["по-*факту","по факту"],
["в[\\s-]*конце[\\s-]*концов","в конце концов"],
["по-твоему","по-твоему"],
["режет","режет"],
["конце-*концов","конце концов"],
["не[\\s-]гоже","негоже"],
["по-*делу","по делу"],
["по[\\s-]пугай","попугай"],
["по-*отдельности","по отдельности"],
["вроде","вроде"],
["по-*аналогии","по аналогии"],
["не-*совсем","не совсем"],
["пол-экрана","пол-экрана"],
["по-лучь*ше","получше"],
["надо-*бы","надо бы"],
["на лету","на лету"],//налёт не обижать!
["что[\\s-]*ле","что ли"],
["куда ж","куда ж"],
["не\\s-]*совсем","не совсем"],
["всего[\\s-]*лишь","всего лишь"],
["п[ао]дреж","подрежь"],//TODO: приставки
["ч[иае][вг]о","чего"],
["б[еи][сз][\\s-]*п[оа]нят[ие]я","без понятия"],
["как[\\s-]*н[ие][\\s-]*в[\\s-]*ч[еёо]м[\\s-]*н[еи][\\s-]*бывало","как ни в чем не бывало"],
["ни[\\s-]*за[\\s-]*что","ни за что"],
["движ[её]к","движок"],
["каждого","каждого"],
["написано","написано"],
["по[\\s-]+наслышке","понаслышке"],
["тысячу","тысячу"],
["позиционирование","позиционирование"],
["н[еи]-*надо","не надо"],
["ни-*черта","ни черта"],
["тысячи","тысячи"],
["в[\\s-]*кратце","вкратце"],
//[Katzen Gott]: может быть стоит вынести "команд" в префиксы? Нортон Командер с одной "м" вроде нормально выглядит
["команды","команды"],//TODO: просклонять, не обидев Norton Commander. Или обидев.
["по\\s*аглийски","по-английски"],
//? ["чесслово","честное слово"],
["как бы","как бы"],
["в виде","в виде"],
["в[\\s-]*догонку","вдогонку"],
["почему","почему"],
["это-*ж","это ж"],
["ес+е*с*т*н[оа]","естественно"],
["к-*стат[еи]","кстати"],
["по-*поводу","по поводу"],
["потому что","потому что"],
["можно","можно"],
["в-*целом","в целом"],
["честно","честно"],//TODO: честный и т. д., не обидеть чеснок
["по-*сути","по сути"],
["по-*крайней","по крайней"],
["поэтому","поэтому"],
["пол-*года","полгода"],
["со+твет*ст*вен+о","соответственно"],
["та же","та же"],
["тот же","тот же"],
["возможно","возможно"],
["кто-то","кто-то"],
["со[бп]с+т*н[оа]","собственно"],
["ни разу","ни разу"],
["по-*минимуму","по минимуму"],
["по-*максимуму","по максимуму"],
["по\\s*товарищески","по-товарищески"],
["финиш","финиш"],
["от-*тудова","оттуда"],
["временно","временно"],
["по\\s*обывательски","по-обывательски"],
["как-*раз","как раз"],
["в[\\s-]*том[\\s-]*то[\\s-]*и[\\s-]*дело","в том-то и дело"],
["по[-]больше","побольше"],
["поменьше","поменьше"],
["иное","иное"],//TODO: просклонять, лучше - окончания в кучку
["границы","границы"],
["в-*принципе","в принципе"],
["те-*же","те же"],//TODO: допросклонять
["из-за","из-за"], //[Katzen Gott]: Не уверена, что к этому нет противопоказаний. Если есть — убирайте.
["из-за","из-за"],
["тысяч","тысяч"],
["по-*умолчанию","по умолчанию"],
["делает","делает"],
["взяться","взяться"],
["каждого","каждого"],
["поменяться","поменяться"],
["мериться","мериться"],
["меряться","меряться"],
["иметься","иметься"],//Поднимется [Katzen Gott]: может это было "имеется"?
["говорится","говорится"],
["учатся","учатся"],//Но обучаться
["пр[ие]д[её]ть*ся","придётся"],
["какую-*т[уоа]","какую-то"],
["отве[дт]ь*те","ответьте"],
["не[\\s-]*охото","неохота"],
["неохота","неохота"],
["хотя-*бы","хотя бы"],
["душ","душ"],
["какайа-*то","какая-то"],
["по-геройски","по-геройски"],
["по соседству","по соседству"],
["по привычке","по привычке"],
["ч[ёо]","что"],
["по новой","по новой"],
["по русскому","по русскому"],
["потихоньку","потихоньку"],
["по полной","по полной"],
["ес+-н+о","естественно"],
["по-*старинке","по старинке"],
["походу","походу"],
["да-да","да-да"],
["занят*"+ca,"заняться"],
/*
[""+ca,""],
[""+ca,""],
[""+ca,""],
[""+ca,""],
*/
["пяли"+ca,"пялится"],
["просну"+ca,"проснуться"],
["меняю"+ca,"меняются"],
["каже"+ca,"кажется"],
["верит"+ca,"верится"],
["кати"+ca,"катиться"],
["с[чщ]а[сс]*","сейчас"],
["станови"+ca,"становится"],
["н[ие]ч[ёео]","ничего"],
["валя"+ca,"валяться"],
["валяю"+ca,"валяются"],
["будто","будто"],
["то есть","то есть"],
["чья-то","чья-то"],
["рыться","рыться"],
["напиться","напиться"],
["добиться","добиться"],
["режется","режется"],
["уборщица","уборщица"],
["померять*ся","помериться"],
["мерять*cя","мериться"],
["меняться","меняться"],
["прид[её]ться","придётся"],
["по умолчанию","по умолчанию"],
["что нибу[дт]ь","что-нибудь"],
["помимо","помимо"],
["кое-как","кое-как"], //TODO: аналоги
["в[\\s-]*конце[\s-]*то[\\s-]*концов","в конце-то концов"],
["ни[\\s-]*при[\\s-]*ч[еёо]м","ни при чём"],//Да, это два разных!
["не[\\s-]*при[\\s-]*ч[еёо]м","не при чем"],
["не-*зря","не зря"],
["кстати","кстати"],
["мужич[ёе]к","мужичок"],
["однажды","однажды"],
["повозражав","повозражав"],
// ["сейчас","сейчас"],
["бе[сз]толоч","бестолочь"],
["вовнутрь","вовнутрь"],
["что-*ль","что ль"],//TODO: просклонять
["говорит","говорит"],//TODO: добить окончаниями
["что","что"],// [Katzen Gott]: а если это стилистический прием? (для передачи акцента например)
["эх","эх"],//Ибо сил моих больше нет
["шт*об","чтоб"],
["значит","значит"],
["короче*","короче"],
["вы б","вы б"],
["по-женски","по-женски"],
["при встрече","при встрече"],
["все же","все же"],
["всё же","всё же"],
["не действует","не действует"],
["красивее","красивее"],
["доев","доев"],
["помоги","помоги"],//Помогичить
["не-*был","не был"],
["не-*была","не была"],
["не-*было","не было"],
["не были","не были"],
["хоч[еи]м","хотим"],//хохочем
["хочешь","хочешь"],
["хоч[еи]те","хотите"],
["хочет","хочет"],
["хотят","хотят"],
["по слухам","по слухам"],
["под дых","под дых"],
["полкило","полкило"],
["н[еи][ -]*в[ -]*ко[еи]м случа[еи]","ни в коем случае"],
["во-*скоко","во сколько"],
["вылезает ","вылезает "],//TODO: аналоги
["и(?:сч|щ|ш)о","ещё"],
["лучше","лучше"],
["жизни","жизни"],
["сидишь","сидишь"],
["до кучи","до кучи"],
["к[ао]во","кого"],
["ч[ёо]нить","что-нибудь"],//Как отличить от "чинить", не знаю
["ч[еоё]-нить","что-нибудь"],
["н[ие]з*ь*зя","нельзя"],
["ч[ёое]гонить","чего-нибудь"],
["д[ао]фига","очень много"],//Ибо нефиг!
["ч[ёое]-*то","что-то"],//TODO: дополнить!
//["миня","меня"],//Нельзя, речка такая есть! [Katzen Gott] речка с большой буквы должна быть. Так что, наверное, можно
["опять","опять"],
["н[ие][фв]курс[ие]","не в курсе"],
["запиши","запиши"],
["н[ие][ -]над[ао]","не надо"],
["кто-*нить","кто-нибудь"],//TODO: допросклонять!
["что-*нить","что-нибудь"],//TODO: допросклонять!
["нехоц+а","не хочется"],
["п[ао]любому","по-любому"],
["наверн[ао]е*","наверное"],
["ес[ст]+ес+н[ао]","естественно"],
["я б","я б"],
["этими","этими"],//TODO: просклонять, не обидев йети!
["такой же","такой же"],//TODO: просклонять
["по-*идее","по идее"],
["жал бы","жал бы"],
["было бы","было бы"],
["не влезает","не влезает"],
["что-*ж","что ж"],
["катац+о","кататься"],
["когда","когда"],
["скуп","скуп"],
["в-*зад[еи]","сзади"],
["с-*зад[еи]","сзади"],
["з-*зад[еи]","сзади"],
["на[\s-]*р[ао]вне","наравне"],
["серебряного","серебряного"],//TODO: просклонять
["со мной","со мной"],
["сначала","сначала"],
["ещё","ещё"],
["её","её"],
["к[ао]роч[еь]*","короче"],
["пароль","пароль"],
["дрожь","дрожь"],
["жжёт","жжёт"],
["не хочу","не хочу"],
["молодёжь","молодёжь"],
["пуловер","пуловер"],
["врасплох","врасплох"],
["продавца","продавца"],
["в смысле","в смысле"],
["штол[еь]","что ли"],
["н[еи]знаю","не знаю"],
["это ж","это ж"],
["подожди","подожди"],
["во-первых","во-первых"],
["пожалу*ста","пожалуйста"],
// ["бесплатно","бесплатно"],
["до свидания","до свидания"],
["вс[её]таки","всё-таки"],
["в[\s-]кратце","вкратце"],
["ключ","ключ"],
["стороной","стороной"],
["не могу","не могу"],
["в[-]*о+бщем","в общем"],
["тоже","тоже"],
["также","также"],
["в(?:об|а)ще","вообще"],
// ["пожалуйста","пожалуйста"],//Объединено
["сколько","сколько"],
["с[её]дня","сегодня"],
["потому","потому"],
["тогда","тогда"],
["жутко","жутко"],
["поорать","поорать"],
["сандалии","сандалии"],
["что","что"],
["скачать","скачать"],
// ["отзов(?=(?:ы||а|у|ом|ам|ами))","отзыв"],
["тролль","тролль"],
["прийти","прийти"],
["класть","класть"],
// ["я ложу","кладу"],//Подойти к ложу / подойти к кладу
["кладём","кладём"],
["кладёшь","кладёшь"],
["кладёте","кладёте"],
["лож[ау]т","кладут"],
["лож[ие]т","кладёт"],
// ["светой","святой"],//TODO: склонять
["не могу","не могу"],
["ночь","ночь"],
["вконтакте","вконтакте"],
["что-то","что-то"],
["с кем","с кем"],
["смотреть","смотреть"],
["ихн(?:ий|его|ему|им|ем|её|яя|ей|юю|ие|их|ими)","их"],
["натощак","натощак"],
["что ли","что ли"],
["здесь","здесь"],
["не за что","не за что"],
["колеса","колеса"],
["какойт[ао]","какой-то"],//TODO: допросклонять
["какиет[ао]","какие-то"],
["какаят[ао]","какая-то"],
["то есть","то есть"],
["по-другому","по-другому"],
["значит[её]к","значок"],
["вкратце","вкратце"],
["напоследок","напоследок"],
["по-*мо[ей]му","по-моему"],
["положить","положить"],
["никого","никого"],
["когда","когда"],
["п[ао]ч[ие]му","почему"],
["наконец-то","наконец-то"],
["где бы","где бы"],
["вс[её]-*время","всё время"],
["чуть-*ли","чуть ли"],
["вря[дт]-*ли","вряд ли"],
["ка[кг]-*бу[дт]то","как будто"],
["вдогонку","вдогонку"],
["экспрес*о","эспрессо"],
["в смысле","в смысле"],
["вообще","вообще"],
["потому что","потому что"],
["что бы","чтобы"],
["что бы","чтобы"],
["видите","видите"],//TODO: проспрягать
["видишь","видишь"],
["видит","видит"],
["видим","видим"], //[Katzen Gott]: тут вроде все. Может быть можно как-то их "склеить"?
["вдогонку","вдогонку"],
["сп[оа]сиб[оа]","спасибо"],
["типа","типа"],
["грамот","грамот"],
["к[ао]не[шч]но","конечно"], //[Katzen Gott]: надеюсь, я все правильно сделала...
["ключ[её]м","ключом"],
["не дай","не дай"],
["нович[ёе]к","новичок"],
["надо","надо"],
["вс[её]-*равно","всё равно"],
["то бишь","то бишь"],
["забеременею","забеременею"],
["не завалялся","не завалялся"],
["не поверишь","не поверишь"],
["ни к чему","ни к чему"],
["щ[ая][сз]*","сейчас"],
["балкон","балкон"],//TODO: просклонять, не обидев князя Болконского
["хочешь","хочешь"],
["очень*(?!-ч)","очень"],
["н[ие]разу","ни разу"],
["завтра","завтра"],
["гаусс","Гаусс"],//TODO: просклонять. В префиксы нельзя, ибо c -> сс
["из *за","из-за"],
["из *под","из-под"],
["металлы","металлы"],//TODO: просклонять, помнить про глагол "метал"
["щелч[её]к","щелчок"],
["пол[\- ]часа","полчаса"],
["не на чем","не на чем"],
["вещь","вещь"],
["паранойя","паранойя"],//TODO: досклонять
["паранойи","паранойи"],
["не работает","не работает"],
["не сможешь*","не сможешь"],
["чему-нибудь","чему-нибудь"],
["каком-нибудь","каком-нибудь"],
["что же","что же"],
["чтонибу[дт]ь","что-нибудь"],
["н[ие]люблю","не люблю"],
["почему-то","почему-то"],
["поскорее","поскорее"],
["на кого","на кого"],
["конечно","конечно"],
["какую-нибудь","какую-нибудь"],//TODO: просклонять
["рядов","рядов"],
["будет","будет"],
["истощена","истощена"],
["истощено","истощено"],
["истощены","истощены"],
["по[ -]*ди[ао]г[ао]нал[еи]","по диагонали"],
["пребь[ёе]т","прибьёт"],//TODO: проспрягать
["сотри","сотри"],
["и[сс][- ]*под[- ]*лобья","исподлобья"],
["по-русски","по-русски"],
["подошло","подошло"],
["и[сс][ -]*д[ао]л[еи]ка","издалека"],
["по-*порядку","по порядку"],
["молодожён","молодожён"],//TODO: просклонять
["не-*спеша","не спеша"],
//["амбула",??], // [Katzen Gott]: хочется уже убивать за "амбулу", но надо придумать на что её менять.
];
var orphoPrefixToCorrect=[
/*
["",""],
["",""],
["",""],
["",""],
["",""],
["",""],
*/
["солнц","солнц"],
["выставк","выставк"],
["ковычь*к","кавычк"],
["к[оа]выч[еи]к","кавычек"],
["корыстн","корыстн"],
["д[еи][ао]лект","диалект"],
["спорт*цмен","спортсмен"],
["совпад","совпад"],
["ограничив","ограничив"],
["помощь*ник","помощник"],
["предъ*истори","предыстори"],
["прекрасн","прекрасн"],
["обеспеч","обеспеч"],
["об[ьъ][её]м","объём"],
["х[ао]р[ао]ш","хорош"],
["опада","опада"],
["большинств","большинств"],
["г[еи]м+[оа]ро","геморро"],
["количеств","количеств"],
["медленн(?!н)","медленн"],
["попробова","попробова"],
["помощь","помощь"],
["чёрт","чёрт"],
["рассчит","рассчит"],
["отсутств","отсутств"],
["здрав*ст*вуй","здравствуй"],
["неот[ъь]емлим","неотъемлем"],
["к[оа]м+ентар","комментар"],
["п[еи]р[еи][оа]дич","периодич"],
["выигр","выигр"],
["продава","продава"],
["встрепен","встрепен"],
["многомерн","многомерн"],
["неопасн","неопасн"],
["безопасн","безопасн"],
["опасн","опасн"],
["кулер","кулер"],
["повтор","повтор"],
["пр[ие]вр[ао]щ","превращ"],
["возрожд","возрожд"],
["заморач","заморач"],
// ["сь","съ"],//TODO: прочие приставки//Мэри Сью
["учён","учён"],
["уделя","уделя"],
["избира","избира"],
/*
[""+sya,""],
[""+sya,""],
*/
["держат"+sya,"держат"],
["получит"+sya,"получит"],
["неполуч[еи]т"+sya,"не получит"],
["обидеть"+sya,"обидеть"],
["дирать"+sya,"дирать"],
["творит"+sya,"творит"],
["перепих","перепих"],
["уедин","уедин"],
["извин","извин"],
["оборач","оборач"],
["бь","бь"],
["под(?=ск[ао]льз)","по"],
["называет","называет"],//5 шт. на Баше
["металлич","металлич"],
["печаль","печаль"],
["покров","покров"],
["отдира","отдира"],//TODO: другие приставки
["пофайлов","пофайлов"],
["спичеч","спичеч"],
["дуэл","дуэл"],
["невидим","невидим"],
["щелч","щелч"],
["сильне","сильне"],
["б[ие]бл[ие]о","библио"],
["бессвязн","бессвязн"],
["тролл(?!л)","тролл"],
["ощущени","ощущени"],
["миндал","миндал"],
["сиделок","сиделок"],
["сиделк","сиделк"],
["женщин","женщин"],
["из[- ]*под-","из-под "],
["из[- ]*за-","из-за "],
["друг друг","друг друг"],
["вопрос","вопрос"],
["спроси","спроси"],
["ч+[иеа]ст*лив","счастлив"],//TODO: сделать так, чтобы умещалось в одну!
["щ+[иеа]ст*лив","счастлив"],
["с[щч]+[иеа]ст*лив","счастлив"],
["щ+[иеа]ст","счаст"],
["с[чщ]+[иеа]ст","счаст"],
["эксплоит","эксплоит"],
["эксплоит","эксплоит"],
["п[ао]м[ао]г","помог"],
["крадуц+а","крадутся"],
["объясн","объясн"],
["мороз","мороз"],
["порнух","порнух"],
["еп+он","япон"],
["биомехан","биомехан"],
["мобил","мобил"],
["жестян","жестян"],
["осили(?!н)","осили"],
["успок","успок"],
["орангутан","орангутан"],
["ар[ао]нгутан","орангутан"],
["мотив","мотив"],
["пельмен","пельмен"],
["детств","детств"],
["ужас","ужас"],
["кр[еи]ве[тд]к","креветк"], //[Katzen Gott]: "креветко" тоже встречается, или его не трогать?
["тигров","тигров"],
["испепел","испепел"],
["сдрав*ств","здравств"],
["здравств","здравств"],
["собутыльник","собутыльник"],
["окута","окута"],
["хлыщ","хлыщ"],
["ево[шн][а-яё]+","его"],
["коров","коров"],
["шпаргал","шпаргал"],
["аттракцион","аттракцион"],
["режис[ёе]р","режиссёр"],
["соединен","соединен"],
["симпатич","симпатич"],
["девч[её]н","девчон"],
["мужчин","мужчин"],
["большинств","большинств"],
["сидени","сидени"],
["электр","электр"],
["преимуществ","преимуществ"],
["офис","офис"],
["агентств","агентств"],
["одн[оа]классник","одноклассник"],
["одноклассник","одноклассник"],
["видео","видео"],
["русск","русск"],
["смотре","смотре"],
["рассчит","рассчит"],
["контакт","контакт"],
["мастурб","мастурб"],
["серебрян","серебрян"],
["правильн","правильн"],
["баллон","баллон"],
["комментар","комментар"],
["прид","прид"],
["раз*сказ","рассказ"],
["классн","классн"],
["оргазм","оргазм"],
["регистрац","регистрац"],
["курин","курин"],
["восстанов","восстанов"],
["дешёв","дешёв"],
["пр[ие]з[ие]ватив","презерватив"],
["телефон","телефон"],
["где-то","где-то"],
["частн","частн"],
["распис","распис"],
["официал","официал"],
["здравств","здравств"],
["тысяч","тысяч"],
["жест","жест"],
["премьер","премьер"],
["сь[её]м","съём"],
["правил","правил"],
["если б","если б"],
["свин","свин"],
["рассве","рассве"],
["расписани","расписани"],
["гостиниц","гостиниц"],
["коммерч","коммерч"],
["би[сс]плат","бесплат"],
["больш","больш"],
["без(?=[кпстфхцчшщ])","бес"],//TODO: раз/роз
["бес(?=[бвгджзлмр])","без"],
["раз(?=[кпстфхцчшщ])","рас"],
["рас(?=[бвгджзлмнр])","раз"],
["воз(?=[пстфхцчшщ])","вос"],
["вос(?=[бгджзлмнр])","воз"],
["через(?=[кпстфхцчшщ])","черес"],
["черес(?=[бвгджзлмр])","через"],
["безы","безы"],
// ["бест","бест"],//TODO: доделать
["недолюбли","недолюбли"],
["баян","баян"],
["будущ","будущ"],
["лучш","лучш"],
["курсов","курсов"],
["винчестер","винчестер"],
["брошюр","брошюр"],
["бе[сз]пелот","беспилот"],
["вместим","вместим"],
["жёлуд","жёлуд"],
["возвра","возвра"],
["в-*течени[ие]","в течение"],
["выращен","выращен"],
["коррект","коррект"],
["грустн","грустн"],
["грамот","грамот"],
["не остановлюсь","не остановлюсь"],
["пол-(?=[бвгджзкмнпрстфхцчшщ])","пол"],//TODO!
["третьеклассник","третьеклассник"],//TODO!
["организм","организм"],
["голов","голов"],
["ро[сз]сол","рассол"],
["милостын","милостын"],
["сатан","сатан"],
["школьниц","школьниц"],
["как-то","как-то"],
["во[\\s-]*первых ","во-первых, "],
["во-вторых, ","во-вторых, "],
["в-треть*их ","в-третьих, "],
["капрал","капрал"],
["леност","леност"],
["лестничн","лестничн"],
["опозда","опозда"],
["сохран","сохран"],
["умира","умира"],
["убира","убира"],
["собира","собира"],
["разбира","разбира"],
["поголовн","поголовн"],
["пеня","пеня"],
["иссиня ч[еоё]рн","иссиня-чёрн"],
["Транс+[еи]льван","Трансильван"],
["кофе","кофе"],
["влаз[ие]л","влезал"],
["свин+","свин"],
["переборщ","переборщ"],
["бутерброд","бутерброд"],
["ч[ие]хотк","чахотк"],
["прилюдн","прилюдн"],
["вздохн","вздохн"],
["тщательн","тщательн"],
["мальчуган","мальчуган"],
["не-*многа","немного"],
["р[ао][сс]д[оа][ёе]т","раздаёт"],
["р[ие]п[ао]з[ие]т[ао]ри","репозитори"],
["пр[ие]з[ие]нтац","презентац"],
];
var orphoPostfixToCorrect=[
/*
["",""],
["",""],
["",""],
["",""],
["",""],
*/
["прячься","прячься"],
["хранилищ","хранилищ"],
["знакомься","знакомься"],
["выгонит","выгонит"],
["кажется","кажется"],
["ругался","ругался"],
["глядит","глядит"],
["давным\\s*давно","давным-давно"],
["в-*курсе","в курсе"],
["\\s*-*\\s+на-*все[вг][оа]","-навсего"],
["\\s*-*\\s+н[ие]бу[дт]ь","-нибудь"],
["бер[её]ться","берётся"],
["кажутся","кажутся"],
["носятся","носятся"],
["несутся","несутся"],
["прягаться","прягаться"],
["глядеться","глядеться"],
["казывается","казывается"],
["удивляться","удивляться"],
["обращается","обращается"],
["обращаться","обращаться"],
["обновятся","обновятся"],
["обновляться","обновляться"],
["пишутся","пишутся"],
["постятся","постятся"],
["ходятся","ходятся"],
["бражаться","бражаться"],
["цепляться","цепляться"],
["вращаться","вращаться"],
["видеться","видеться"],
["йдутся","йдутся"],
["станется","станется"],
["станутся","станутся"],
["бороться","бороться"],
["смотрится","смотрится"],
["стремятся","стремятся"],
["дастся","дастся"],
["глашаться","глашаться"],
["нимется","нимется"],
["-нть","-нибудь"],
["н[ие]буть","нибудь"],
["надеяться","надеяться"],
["гадаться","гадаться"],
["печататься","печататься"],
/*
[""+ca,""],
[""+ca,""],
[""+ca,""],
[""+ca,""],
[""+ca,""],
[""+ca,""],
*/
["сыпае"+ca,"сыпается"],
["рву"+ca,"рвутся"],
["крыва"+ca,"крываться"],
["крывае"+ca,"крывается"],
["нрави"+ca,"нравится"],
["зывае"+ca,"зывается"],
["готовятся","готовятся"],
["боится","боится"],
["думаться","думаться"],
["мчится","мчится"],
["обидеться","обидеться"],
["ждаться","ждаться"],
["маяться","маяться"],
["мыться","мыться"],
["рваться","рваться"],
["тираться","тираться"],
["кусаться","кусаться"],
["дираться","дираться"],
["ниматься","ниматься"],
["ложатся","ложатся"],
["нравятся","нравятся"],
["смеяться","смеяться"],
["сядется","сядется"],
["гуляться","гуляться"],
["жаловаться","жаловаться"],
["пытаться","пытаться"],
["оваться","оваться"],
["з[ао]бот[яю]ть*ся","заботятся"],
["б[ие]ратся","бираться"],
["плавятся","плавятся"],
["дерутся","дерутся"],
["хвастаться","хвастаться"],
["вертится","вертится"],
["одеться","одеться"],
["греться","греться"],
["еваться","еваться"],
["ываться","ываться"],
["зываться","зываться"],
["врубаться","врубаться"],
["гружаться","гружаться"],
["пользоваться","пользоваться"],
["стебаться","стебаться"],
["иваться","иваться"],
["писаться","писаться"],
["общаться","общаться"],
["двигаться","двигаться"],
["колоться","колоться"],
["являться","являться"],
["режутся","режутся"],
["встречатся","встречатся"],
["браться","браться"],
["начинаться","начинаться"],
["трахаться","трахаться"],
["заняться","заняться"],
["кажется","кажется"],
["хочется","хочется"],
["ходишь","ходишь"],
["просятся","просятся"],
["к[оа]зать*ся","казаться"],
["-ка","-ка"],
["видил(?=а|и|о|)(?=с[яь])","видел"],
["трахац+[оа]","трахаться"],
["батареек","батареек"],
["глядывац+[ао]","глядываться"],
["играц+[оа]","играться"],
["товарищ","товарищ"],
["сушняч[её]к","сушнячок"],
["пишется","пишется"],
["щ[еёо]лк[ао][еи]т","щёлкает"],
["читаец+а","читается"],
["будешь","будешь"],
["пользуются","пользуются"],
["пытаюц+а","пытаются"],
["ругаец+о","ругается"],
["явятся","явятся"],
["садят","садят"],
["пускаюц+а","пускаются"],
["хочешь","хочешь"],
["следующую","следующую"],
["борются","борются"],
["сыпется","сыпется"],
["г[ао]в[ао]риш","говоришь"],
["ются","ются"],
["ётся","ётся"],
["ается","ается"],
["оется","оется"],
["уется","уется"],
["яется","яется"],
["еется","еется"],
["юется","юется"],
[" ли"," ли"],
[" же"," же"],
[" бы"," бы"],
// ["-что"," что"],//кое-что
["можешь","можешь"],
["аешь","аешь"],
["шься","шься"],
["гл[аея]диш","глядишь"],
["сыпаться","сыпаться"],
["рвутся","рвутся"],
["изм","изм"],//TODO: просклонять
["ция","ция"],//TODO: просклонять
["качать","качать"],//TODO: проспрягать
["рвутся","рвутся"],
["пользуется","пользуется"],
["пожж[еа]","позже"],
["качает","качает"],
["кочаеть*ся","качается"],
["алась","алась"],
["шёл","шёл"],
["смотр[ие]ш","смотришь"],
["смотрим","смотрим"],//TODO: допроспрягать. И вообще все глаголы-исключения
["тирад","тирад"],
["цами","цами"],
];
var orphoFragmentsToCorrect=[
/*
["",""],
["",""],
["",""],
*/
["матер[еи]ял","материал"],
["с[ие]р[ьъ][её]з","серьёз"],
["элемент","элемент"],
["тренажёр","тренажёр"],
["обезьян","обезьян"],
["р[еи]с+т[ао]ран","ресторан"],
["ат+р[ие]бут","атрибут"],
["искусств","искусств"],
["естеств","естеств"],
["ъезд","ъезд"],
["ъезж","ъезж"],
["нюанс","нюанс"],
["параллел","параллел"],
["распростран","распростран"],
["съ*о+риентир","сориентир"],
["перманент","перманент"],
["парашют","парашют"],
["ъявл","ъявл"],
["милиц","милиц"],
["пр[оа]т+[оа]тип","прототип"],
["[оа]р[еи]нтир","Орентир"],
["раствор","раствор"],
["баллотир","баллотир"],
["интерес","интерес"],
["тренир","тренир"],
["полагают","полагают"],
["ворачива","ворачива"],
//];[
["топчет"+sya,"топчет"],//sya уже включает границу слова
["полагает*"+sya,"полагает"],
// ["видит"+sya,"видеть"],//Бред
["видит"+sya,"видит"],
["клеит"+sya,"клеит"],
["клеят"+sya,"клеят"],
["пялит"+sya,"пялит"],
["тащит"+sya,"тащит"],
["бьёт"+sya,"бьёт"],
["смотрит"+sya,"смотрит"],
["тр[еия]с[ёе]т"+sya,"трясёт"],//TODO: проспрягать
["хочет"+sya,"хочет"],
["зачёт","зачёт"],
["щетин","щетин"],
["участн","участн"],
["розет","розет"],
["если-*что","если что"],
["чувств","чувств"],
["секунд","секунд"],
["лучш","лучш"],
["ч[ие]л[оа]в*[еэ]к","человек"],
["советск","советск"],
["инсталл(?![лл])","инсталл"],
["нч","нч"],
["нщ","нщ"],
["чн","чн"],
["щн","щн"],
["чк","чк"],
["ы","ы"],
["э","э"],
["тендер","тендер"],
["будущ","будущ"],
["следующ","следующ"],
["праздн","праздн"],
["пр[ие]з[ие]дент","президент"],
["цикл","цикл"],
["мед[еи]ц[иы]н","медицин"],
["интересн","интересн"],
["классн","классн"],
["эксплуоат","эксплуоат"],
["принцип","принцип"],
["субъект","субъект"],
["объект","объект"],
["мыслим","мыслим"],
["пристег","пристег"],
["пристёг","пристёг"],
["формат","формат"],
["ъедин","ъедин"],
// ["ьед[еи]н","ъедин"],//Объедение
// ["ъед[еи]н","ъедин"],
["монет","монет"],
["проблем","проблем"],
["пропаган","пропаган"],
["каблук","каблук"],
["будет","будет"],
["хотя б","хотя б"],
["регистр","регистр"],//Или "реестр", но сочтём это санкциями
["рецидив","рецидив"],
["очень[еи]рова","очарова"],
["ъясн","ъясн"],
["чёрн","чёрн"],
["авторизир","авторизир"],
["ил*[еи]м*[еи]нт","элемент"],
["эл*[еи]м*[еи]нт","элемент"],//TODO: дебажить до "[эи]л*[еи]м*[еи]нт"
["пробова","пробова"],
["бутерброд","бутерброд"],
["cочельнтик","cочельник"],
["глядыв","глядыв"],
["бретельк","бретельк"],
["р[еи]к[ао]ш[еи]т","рикошет"],
["м[ие]н[ие]рал","минерал"],
];
var matyuki=[
];
var yo=[
];
try{
module.exports.orphoWordsToCorrect = orphoWordsToCorrect;
module.exports.orphoPrefixToCorrect = orphoPrefixToCorrect;
module.exports.orphoPostfixToCorrect = orphoPostfixToCorrect;
module.exports.orphoFragmentsToCorrect = orphoFragmentsToCorrect;
}catch(e){
//Значит, не node.js
}
/*
Copyright Nikolay Avdeev aka NickKolok aka Николай Авдеев 2015
Всем привет из снежного Воронежа!
This file is part of CHAS-CORRECT.
CHAS-CORRECT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CHAS-CORRECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
(Этот файл — часть CHAS-CORRECT.
CHAS-CORRECT - свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней
версии.
CHAS-CORRECT распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.)
*/
'use strict';
try{
var dict=require('./dictionary.js');
for(var chto in dict)
global[chto]=dict[chto];
}catch(e){
//Значит, не node.js
}
var wordSplitSymbol="([^А-Яа-яЁёA-Za-z]|^|$)";
//var wordSplitSymbolSafe="(?=[^А-Яа-яЁёA-Za-z]|^|$)";
var leftEnd="(.|^)";//TODO: переписать так, чтобы стал не нужен
//var rightEnd="(.|$)";
//var rightEndSafe="(?=.|[\\s\\S]|$)";
var actionArray=[
[/[ь]{2,}/g,"ь",/ь/i],
[/[ъ]{2,}/g,"ъ",/ъ/i],
[/([ЖжШшЩщ])[ыЫ]/g,"$1и",/[жшщ]ы/i],
[/([ЧчЩщ])[яЯ]/g,"$1а",/[чщ]я/i],
[/([ЧчЩщ])[юЮ]/g,"$1у",/[чщ]ю/i],
[/([^А-Яа-яЁёA-Za-z]|^)з(?=[бжкстф-щБЖКПСТФ-Щ]|д(?!ани|ань|ес|еш|оров|рав|рас))/g,"$1с",/([^А-Яа-яЁёA-Za-z]|^)з(?=[бджкпстф-щБДЖКПСТФ-Щ])/],
[/([^А-Яа-яЁёA-Za-z]|^)З(?=[бжкстф-щБЖКПСТФ-Щ]|д(?!ани|ань|ес|еш|оров|рав|рас))/g,"$1С",/([^А-Яа-яЁёA-Za-z]|^)З(?=[бджкпстф-щБДЖКПСТФ-Щ])/],
];
var qmInReg=/\(\?[\=\!]/;
function prepareExpression(word, str, prefix, postfix){
if(word[0] !== str[0])
return prepareReplaceHeavy(word, str, prefix, postfix);
var firstLetter=word[0];
var lostWord=word.substr(1);
// var safe=qmInReg.test(word)
// var wordSplitSymbolHere=(postfix && safe) ? wordSplitSymbolSafe : wordSplitSymbol;
// if(postfix && qmInReg.test(word))
// correct.log(word+rightEndHere);
var pattern =
(prefix ? wordSplitSymbol : leftEnd ) +
"(["+firstLetter.toLowerCase()+firstLetter.toUpperCase()+"])"+lostWord+
(postfix ? wordSplitSymbol : "");
var regexp=new RegExp(pattern,"gm");
// correct.log(regexp);
actionArray.push([regexp,"$1$2"+str.substr(1)+(postfix?"$3":""),new RegExp(word,"i"),word]);
// megaexpressionParts.push(pattern);
}
function prepareReplaceHeavy(reg, str, prefix, postfix){
var lostreg=reg.substr(1);
var loststr=str.substr(1);
var pattern1 =
(prefix ? wordSplitSymbol : leftEnd ) +
reg[0].toLowerCase()+lostreg+
(postfix ? wordSplitSymbol : "" );
var regexp1=new RegExp(pattern1,"gm");
var pattern2 =
(prefix ? wordSplitSymbol : leftEnd ) +
reg[0].toUpperCase()+lostreg+
(postfix ? wordSplitSymbol : "" );
var regexp2=new RegExp(pattern2,"gm");
actionArray.push([regexp1,"$1"+str[0].toLowerCase()+loststr+(postfix ? "$2" : ""),new RegExp(reg,"i"),str]);
actionArray.push([regexp2,"$1"+str[0].toUpperCase()+loststr+(postfix ? "$2" : ""),new RegExp(reg,"i"),str]);
}
var megaexpressionParts=[];
var globalArray=[
[orphoFragmentsToCorrect,orphoPostfixToCorrect],
[orphoPrefixToCorrect,orphoWordsToCorrect],
];
for(var i1=0; i1<=1;i1++)
for(var i2=0; i2<=1;i2++)
for(var i=0; i<globalArray[i1][i2].length; i++){
prepareExpression(globalArray[i1][i2][i][0],globalArray[i1][i2][i][1],i1,i2);
// megaexpressionParts.push(globalArray[i1][i2][i][0]);
}
var actionArrayCopy=actionArray.slice();
var megaexpression;//=new RegExp("("+megaexpressionParts.join(")|(")+")","im");
var correct={
logArray:[],
log: function(param){
this.logArray.push(param);
},
logToConsole: function(){
console.log("chas-correct: "+this.logArray.join("\n\r"));
this.logArray=[];
},
replacedPairs:[],
logReplaced: function(){
var rez="";
var len=this.replacedPairs.length;
for(var i=0; i<len;i+=2){
if(this.replacedPairs[i]!=this.replacedPairs[i+1]){
var slen=this.replacedPairs[i].length;
for(var j=0; j<slen && this.replacedPairs[i][j]===this.replacedPairs[i+1][j]; j++){
}
rez+="\n\r\n\r"+this.replacedPairs[i]+"\n\r->\n\r"+this.replacedPairs[i+1].substr(j-10<0?0:j-10);
}
}
this.replacedPairs=[];
return rez;
},
logTimestamp: function(text, timestamp){
correct.log(text+" (мс): "+(new Date().getTime() - timestamp));
},
};
//Теперь удаляем исходные словари - они больше не нужны, все слова уже обработаны, только память занимают
//TODO: делать это вообще при сборке. Когда она будет
orphoWordsToCorrect=orphoPrefixToCorrect=orphoPostfixToCorrect=orphoFragmentsToCorrect=globalArray=null;
try{
module.exports.actionArray = actionArray;
}catch(e){
//Значит, не node.js
correct.log("chas-correct: на подготовку массива регулярных выражений затрачено (мс): "+(new Date().getTime() - oldTime));
}
/*
Copyright Nikolay Avdeev aka NickKolok aka Николай Авдеев 2015
Всем привет из снежного Воронежа!
This file is part of CHAS-CORRECT.
CHAS-CORRECT is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CHAS-CORRECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CHAS-CORRECT. If not, see <http://www.gnu.org/licenses/>.
(Этот файл — часть CHAS-CORRECT.
CHAS-CORRECT - свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней
версии.
CHAS-CORRECT распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.)
*/
'use strict';
Array.prototype.spliceWithLast=function(index){
///Заменить элемент под номером index последним, последний удалить
///Это, очевидно, эффективнее, чем сдвигать весь массив и даже чем просто заменять на null
'use strict';
this[index]=this[this.length-1];
this.length--;
};
var notCyrillicToTrim=/^[^а-яё]+|[^а-яё]+$/i;
function trimNotCyrillic(text) {
//Да, быстрее так, а не методом-членом
return text.replace(notCyrillicToTrim,"");
//TODO: проверить, быстрее одной регуляркой или двумя
}
var observeDOM = (function(){
///Наблюдение за DOM и вызов корректора при добавлении новых нод
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
eventListenerSupported = window.addEventListener;
return function(obj, callback){
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
var shouldBeHandled=0;
var len=mutations.length;
for(var i=0; i<len; i++){
for(var j=0; j<mutations[i].addedNodes.length; j++){
extractTextNodesFrom(mutations[i].addedNodes[j]);
}
//Гоняем проверялку только по тем нодам, которые добавились
//Сложность в том, что добавиться могло целое дерево
shouldBeHandled+=mutations[i].addedNodes.length;
}
if(shouldBeHandled){
domChangedHandler();
}else{
correct.log("Изменение DOM, не добавляющее ноды");
}
});
obs.observe( obj, { childList:true, subtree:true });
}
else if( eventListenerSupported ){
obj.addEventListener('DOMNodeInserted', domChangedHandler, false);
}
}
})();
//Кэшируем строки и регэкспы. Вроде как помогает.
var reun1=/[(]{6,}/g , stun1="(((";
var reun2=/[)]{6,}/g , stun2=")))";
var reun3=/[!]1+/g , stun3="!";
var reun4=/[?]7+/g , stun4="?";
var reun5=/([.?!])\1{3,}/g , stun5="$1$1$1";
function replaceUniversal(ih){
return ih.
replace(reun1,stun1).
replace(reun2,stun2).
replace(reun3,stun3).
replace(reun4,stun4).
replace(reun5,stun5);
}
var reg3podryad=/([А-Яа-яЁё])\1{3,}/g;
function specialWork(ih){
ih=ih.replace(reg3podryad,"$1$1$1");//Это не выносится из-за сигнатуры
return ih;
}
var lAr=[];
var totalNodes=0;
var errorNodes=0;
function mainWork(ih){
ih=specialWork(ih);
totalNodes++;
if(!megaexpression.test(ih))
return ih;
errorNodes++;
correct.replacedPairs.push(ih);
for(var i=0; i<actionArray.length;i++){
// if(actionArray[i])
/* if(ih.length>50 && /\./.test(ih)){
var temparr=ih.split(".");
var len=temparr.length;
for(var j=0; j<len; j++){
if(actionArray[i][2].test(temparr[j]))
temparr[j]=temparr[j].replace(actionArray[i][0],actionArray[i][1]);
}
ih=temparr.join(".");
}else
*/
if(actionArray[i][2].test(ih))
ih=ih.replace(actionArray[i][0],actionArray[i][1]);
}
correct.replacedPairs.push(ih);
return ih;
}
var regCyr=/[А-Яа-яЁё]/;
function notContainsCyrillic(str){
return !regCyr.test(str);
}
var textNodes=[];
var kuch=3;
function extractTextNodesFrom(rootNode) {
///Добавить все текстовые ноды-потомки rootNode в масссив textNodes
var walker = document.createTreeWalker(
rootNode,
NodeFilter.SHOW_TEXT,
null,
false
);
var node;
while(node = walker.nextNode()) {
if(node.data!="" && node.data.trim()!=""){
node.data=replaceUniversal(node.data);
if(!notContainsCyrillic(node.data)){
textNodes.push(node);
}
}
}
}
function extractAllTextNodes() {
///Заменить textNodes на список
var timeBeforeNodesExtracting=new Date().getTime();
textNodes=[];
extractTextNodesFrom(document.body);
correct.logTimestamp("На подготовку массива текстовых нод затрачено", timeBeforeNodesExtracting);
}
var regKnown;
var typicalNodes;
var lastActionArrayLength=storageWrapper.getKey("lastActionArrayLength",0);
if(lastActionArrayLength==actionArrayCopy.length){
typicalNodes=storageWrapper.getKey("chas-correct-typical-nodes",{totalPages:0,nodes:{}});
}else{
typicalNodes={totalPages:0,nodes:{}};
storageWrapper.setKey("lastActionArrayLength",actionArrayCopy.length);
correct.log("Длина словаря изменилась - сбрасываем кэш");
}
var flagEchoMessageDomChanged;
var flagFixMistakesScheduled=0;
var flagAsyncFixLoopFinished=1;
var flagFirstTimeFixLaunch=1;
var firstChangingNode,lastChangingNode;
var timeBeforeMain;
function fixMistakes() {
/*
if(!flagAsyncFixLoopFinished){
if(!flagFixMistakesScheduled){
setTimeout(fixMistakes,20);
flagFixMistakesScheduled=1;
}
return;
}
*/
var len=textNodes.length-1;
var i=0;
var oldTime3=new Date().getTime();
var timeBeforeHeader=new Date().getTime();
if(typicalNodes.nodes){
//Пропускаем "шапку" страницы
while(i<=len && textNodes[i].data in typicalNodes.nodes){
i++;
};
//И низушку
while(i<=len && textNodes[len].data in typicalNodes.nodes){
len--;
};
}
len++;//Иначе глючит :(
var cachedNodes=i+textNodes.length-len;
correct.log("Нод отнесено к шапке: "+cachedNodes+"("+(cachedNodes/textNodes.length*100)+"%), до "+i+"-й и после "+(len-1)+"-й");
correct.logTimestamp("Выделение шаблона", timeBeforeHeader);
selectRegs(i,len);
timeBeforeMain=new Date().getTime();
firstChangingNode=i;//TODO: зарефакторить
lastChangingNode=len;
/* if(flagFirstTimeFixLaunch){
setTimeout(asyncFixLoop,0);
}else{
asyncFixLoop();
}
*/
// flagFixMistakesScheduled=0;
asyncFixLoop();
flagFirstTimeFixLaunch=0;
flagEchoMessageDomChanged=1;
}
function firstRun() {
extractAllTextNodes();
fixMistakes();
typicalNodes.totalPages++;//Логично, считаем настоящее количество страниц
setTimeout(cacheRemoveOutdated,4000);//TODO: кэширование вообще растащить
}
firstRun();
var asyncFixLoopStartTime;
var asyncCount=0;
function asyncFixLoop(){
asyncCount++;
asyncFixLoopStartTime=new Date().getTime();
flagEchoMessageDomChanged=1;
for(;firstChangingNode<=lastChangingNode;firstChangingNode++){
/* var textArr=[];
if(i%kuch == 0){
for(var j=0; (i+j<len) && (j<kuch); j++){
textArr.push(textNodes[i+j].data);
}
if(!megaexpression.test(textArr.join(" "))){
i+=kuch;
continue;
}
}
*/
var currentNode=textNodes[firstChangingNode];
if(!currentNode)//Не знаю, что имеется в виду
continue;
if(currentNode.data in typicalNodes.nodes){
typicalNodes.nodes[currentNode.data]+=20;
}else{
currentNode.data=mainWork(currentNode.data);
typicalNodes.nodes[currentNode.data]=20;
}
/* if(
(firstChangingNode % 100 == 0)
// || (new Date().getTime() - asyncFixLoopStartTime > 146)
){
firstChangingNode++;
setTimeout(asyncFixLoop,10);
return;
}
*/
}
correct.logTimestamp("Основной цикл", timeBeforeMain);
flagAsyncFixLoopFinished=1;
actionsAfterFixLoop();
}
function actionsAfterFixLoop(){
observeDOM(document.body, domChangedHandler);
//Нечего память кушать! Надо будет - новые нагенерятся
textNodes=[];
//Кэш не резиновый
setTimeout(cacheCrop,3000);
correct.logTimestamp("chas-correct отработал. С момента запуска", oldTime);
correct.logToConsole();
}
var domChangedLastTime=new Date().getTime();
var keydownLastTime=new Date().getTime();
var domChangedScheduled=0;
var domChangeTimes=0;
var domChangingTimeout=0;
function scheduleDomChangeHandler(time){
clearTimeout(domChangingTimeout);
domChangingTimeout=setTimeout(domChangedHandler,time);
}
function domChangedHandler(){
var newt=new Date().getTime();
if(flagEchoMessageDomChanged){
flagEchoMessageDomChanged=0;
return;
}
if(newt - domChangedLastTime < 1468 || newt - keydownLastTime < 2*1468){
// if(!domChangedScheduled){
// domChangedScheduled=1;
scheduleDomChangeHandler(1468);
// }
return;
}
domChangedLastTime=new Date().getTime();
domChangedScheduled=0;
fixMistakes();
domChangeTimes++;
correct.logTimestamp("Вызов chas-correct по смене DOM "+domChangeTimes+"-й раз", newt);
correct.logToConsole();
}
//Кэширование типичных нод
function cacheMetrika(text) {
return Math.pow(typicalNodes.nodes[text],2)/( typicalNodes.nodes[text].length + 6);
}
function cacheCrop() {
///Удаление из кэша лишних (по некоторой метрике) нод
//Считаем количество нод в кэше
var cacheNodesCount=Object.keys(typicalNodes.nodes).length;
var timeBefore=new Date().getTime();
var cacheLength=JSON.stringify(typicalNodes.nodes).length;
var currentMin;
var deletedNodes=0;
var deletedNodesLength=0;
var lastNode;
while(
//Ограничиваем кэш 100 килобайтами на сайт (или 200, т. к. юникод? Не важно)
cacheLength > 102400
||
//Не более 1024 нод
cacheNodesCount > 1024
){
for(var text in typicalNodes.nodes){
break;
}
//Да, это так мы получаем первую ноду из кэша
//Считаем её минимальной
currentMin = cacheMetrika(text);
//Ищем ноду с минимальным отношением квадрата повторяемости к длине
for(var text2 in typicalNodes.nodes){
var otherMetrika = cacheMetrika(text2);
if( otherMetrika < currentMin ){
text = text2;
currentMin = otherMetrika;
}
}
//Удаляем одну ноду
deletedNodes++;
deletedNodesLength+=text.length;
delete typicalNodes.nodes[text];
//Пересчитываем показатели
cacheNodesCount--;
cacheLength -= text.length+6;
//Эталонной нодой снова становится последняя
text = lastNode;
//TODO: метрики тоже куда-то кэшировать
}
storageWrapper.setKey("chas-correct-typical-nodes",typicalNodes);
correct.logTimestamp("Редукция кэша (нод: "+deletedNodes+", сумма длин удалённых нод: "+deletedNodesLength+")",timeBefore);
correct.log("В кэше нод: "+cacheNodesCount+" общей длиной "+cacheLength+", минимум метрики "+currentMin);
}
function cacheRemoveOutdated() {
for(var text in typicalNodes.nodes){
typicalNodes.nodes[text]--;
if(typicalNodes.nodes[text] < 0){
delete typicalNodes.nodes[text];
}
}
}
//Объединение текста всех нод и выкидывание ненужных регулярок
var text="";
function selectRegs(i,len){
// var textArr=[];
// megaexpressionParts=[];
text="";
var megaexpressionSource="(";
var delimiter=")|(";
var t=new Date().getTime();
var notCyrTest=/^[^а-яё]{2,}|[^а-яё]{2,}$/i
for(;i<len;i++){
if(!(textNodes[i].data in typicalNodes.nodes))
// textArr.push(textNodes[i].data);
// if(notCyrTest.test(text))
// text+=" "+trimNotCyrillic(textNodes[i].data);
// else
text+=" "+textNodes[i].data;
}
text=text.replace(/[^а-яё]{4,}/gi," ");
if(text.trim()!=""){
actionArray=actionArrayCopy.slice();//Да, так быстрее: http://jsperf.com/array-slice-vs-push
}else{
correct.log("Все ноды в кэше - незачем делать копию словаря");
actionArray=[];
}
// var text=textArr.join(" ");
// correct.log(text);
//{{Экспериментальное выкидывание регэкспов парами - медленнее
/* var l=actionArray.length;
for(var j=1; j<l; j+=2){
if(
actionArray[j] && actionArray[j][3] &&
actionArray[j-1] && actionArray[j-1][3]
){
if(!(
new RegExp(
"("+
actionArray[j][3]+")|("+
actionArray[j-1][3]+
")"
)
).test(text))
{
actionArray.spliceWithLast(j);
actionArray.spliceWithLast(j-1);
l-=2;
j-=2;
}
}
}
console.log(l);
*/
//}}
var l=actionArray.length;
for(var j=0; j<l; j++){
if(actionArray[j] && actionArray[j][2]){
if(!actionArray[j][2].test(text)){
actionArray.spliceWithLast(j);//Это быстрее, чем забивать нулями
l--;
j--;
}else{
megaexpressionParts.push(actionArray[j][2].source);
// megaexpressionSource+=actionArray[j][3]+delimiter;
}
}
}
// megaexpression=new RegExp("("+megaexpressionParts.join(")|(")+")","im");
megaexpression=new RegExp(megaexpressionSource.replace(/\)\|\($/,"")+")","im");
// correct.log(megaexpression);
correct.logTimestamp("Выбор регэкспов", t);
}
//Сбросить кэш
function clearNodeCache(){
storageWrapper.setKey("chas-correct-typical-nodes",{totalPages:0,nodes:{}});
}
//Расстановка типографики + откладывание автокоррекции при наборе
document.onkeydown = keydownHandler;
function keydownHandler(e) {
keydownLastTime=new Date().getTime();
e = e || event;
if ((e.ctrlKey && e.shiftKey && e.keyCode == "A".charCodeAt(0))) {
forceTypo();
return false;
}
}
function forceTypo(){
extractAllTextNodes();
var len=textNodes.length;
for(var i=0; i<len; i++)
textNodes[i].data=forceTypoInString(textNodes[i].data);
}
//var typoLeft=/ *([,\.!?\):;])( *(?![,\.!?\):;]))/g;
var typoLeft=/ *([,\.!?\):;»]) */g;
var typoRight=/ *([\(«]) */g;
var typoJoin=/([,\.!?\):;]+) *([,\.!?\):;»]+)/g;
var typoSmallLetter=/([а-яё]{2,}[\.!?]) *[а-яё]/g;
function replaceSmallLetter(m,$1){
console.log(m, $1);
return $1+" "+m.substr(-1).toUpperCase();
}
function forceTypoInString(ih){
return ih.
replace(typoLeft , "$1 ").
replace(typoRight, " $1").
replace(typoJoin , "$1$2").
replace(typoJoin , "$1$2").
replace(typoSmallLetter,replaceSmallLetter)
;
}
})();