Greasy Fork is available in English.
Исправление наиболее частотных ошибок на просматриваемых страницах
// ==UserScript== // @name ЧАС-коррект // @namespace http://www.example.com/gmscripts // @description Исправление наиболее частотных ошибок на просматриваемых страницах // @include http://* // @include https://* // @version 0.2.0.8 // @grant GM_getValue // @grant GM_setValue // @grant GM.getValue // @grant GM.setValue // @license GNU GPLv3 // ==/UserScript== /* 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 storageWrapper={ ///Обёртка над хранилищем, в данном случае - GreaseMonkey getKey: function(key,defaultValue){ try { var val = GM_getValue(key); if (val === undefined) { return defaultValue; } else { return JSON.parse(val); }; } catch (e) { console.error(e); return defaultValue; } }, setKey: function(key,value){ try{ GM_setValue(key,JSON.stringify(value)); }catch(e){ console.error(e); } }, }; /* 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 = Date.now(); var sya="(?=(?:ся|)(?:[^А-Яа-яЁёA-Za-z]|^|$))"; var ca="[цc]+[ао]"; var orphoWordsToCorrect=[ /* ["",""], ["",""], ["",""], ["",""], */ ["в[\\s-]*пол+[\\s-]*голоса","вполголоса"], ["в[оа][\\s-]*и[сз]т[еи]ну","воистину"], ["в[-]*следстви[ие]","вследствие"], ["н[еи]зван+ый","незваный"], // TODO: просклонять ["д[ие]л+ем+а","дилемма"], // TODO: в префиксы, обработать мм на конце ["тяку","теку"], ["на-*глазок","на глазок"], ["н[еи]-*и[зс]","не из"], ["имейти","имейте"], ["как-*правило","как правило"], ["по-*которой","по которой"],//Да, и такое бывает. TODO: просклонять ["про-*запас","про запас"], ["свечь","свеч"], ["н[ао]-*[ао]б[ао]рот","наоборот"], ["иметь в-*виду","иметь в виду"], ["имею в-*виду","имею в виду"], ["имеем в-*виду","имеем в виду"], ["имеешь в-*виду","имеешь в виду"], ["имеете в-*виду","имеете в виду"], ["имеет в-*виду","имеет в виду"], ["имел в-*виду","имел в виду"], ["имела в-*виду","имела в виду"], ["имели в-*виду","имели в виду"], ["имеешь в-*виду","имеешь в виду"], //[Katzen Gott]: вроде всё ["на-*ощу[пб]ь","на ощупь"], ["в-*сч[ёе]т","в счёт"], ["в[-\\s]*случ[аеи]е","в случае"], ["в[-\\s]*том[-\\s]*случ[аеи]е","в том случае"], ["в[-\\s]*таком[-\\s]*случ[аеи]е","в таком случае"], ["случ[ие]и","случаи"], ["в-*виде","в виде"], ["в-*порядке","в порядке"], ["в-*целом","в целом"], ["в[\\s-]*принц[иеы]п[еи]","в принципе"], ["в-*смысле","в смысле"], ["в-*первую","в первую"], ["в-*о+бщем","в общем"], ["в[\\s-]*конце[\\s-]*то[\\s-]*концов","в конце-то концов"], ["в[\\s-]*конце[\\s-]*концов","в конце концов"], ["конце-*концов","конце концов"], ["в[\\s-]*том[\\s-]*то[\\s-]*и[\\s-]*дело","в том-то и дело"], ["во-*скоко","во сколько"], ["в[\\s-]+кратце","вкратце"], ["во-время","вовремя"], ["в[\\s-]+догонку","вдогонку"], ["во внутрь","вовнутрь"], ["в расплох","врасплох"], ["в догонку","вдогонку"],//TODO: почистить ["в догонку","вдогонку"], ["во первых","во-первых"], ["в[\\s-]*част*ности","в частности"], ["кое[\\s]*где","кое-где"],//TODO: аналоги ["кое[\\s]*кто","кое-кто"], ["кое[\\s]*что","кое-что"], ["кое[\\s]*кого","кое-кого"], ["кое[\\s]*кому","кое-куда"],//[Katzen Gott]: может быть "кое-к", "кое-г" и "кое-ч" префиксами сделать? А то очень много получается. ["кое[\\s]*как","кое-как"], //TODO: аналоги ["по[\\s-]*близ*же","поближе"], ["по-од[еи]ночь*ке","поодиночке"], ["по-круче","покруче"], ["по-надежнее","понадежнее"], ["по-крупнее","покрупнее"], ["по-подробнее","поподробнее"], ["по-лучь*ше","получше"], ["по[-]больше","побольше"], ["по-меньше","поменьше"], ["по-скорее","поскорее"], ["по-началу","поначалу"], ["по[\\s-]немногу","понемногу"], ["по[\\s-]+наслышке","понаслышке"], ["по[\\s-]+пугай","попугай"], ["по[\\s-]+тихоньку","потихоньку"], ["по[\\s-]+быстрей","побыстрей"], ["по-мимо","помимо"], ["по-этому","поэтому"], ["по-ходу","походу"], ["по возражав","повозражав"], ["по-*мат[еи]мат[еи]ке","по математике"], ["по[\\s]*русски","по-русски"], ["по[\\s]*аглийски","по-английски"], ["по[\\s]*английски","по-английски"],//TODO: другие языки ["по[\\s]*французски","по-французски"], ["по[\\s]*немецки","по-немецки"], ["по[\\s]*итальянски","по-итальянски"], ["по[\\s]*шведски","по-шведски"], ["по[\\s]*украински","по-украински"], ["по[\\s]*румынски","по-румынски"], ["по[\\s]*китайски","по-китайски"], ["по[\\s]*испански","по-испански"], ["по[\\s]*деревенски","по-деревенски"], ["потвоему","по-твоему"],// По твоему мнению ["по-*мо[ей]му","по-моему"], ["по\\s*товарищески","по-товарищески"], ["по\\s*обывательски","по-обывательски"], ["погеройски","по-геройски"], ["по женски","по-женски"], ["п[ао]любому","по-любому"], ["по[\\s-]*собачь*и","по-собачьи"], ["пон[оа]ст[ао]ящ[еи]му","по-настоящему"],//По настоящему асфальту //То, что никогда не пишется с "по" слитно или дефисно, а только раздельно //В основном по+существительное ["по-*душе","по душе"], ["по-*ошибке","по ошибке"], ["по[\\s-]*спр[ао]в[ие]дливости","по справедливости"], ["по-*правде","по правде"], ["по-сети","по сети"],// Посетить ["по-*идее","по идее"], ["по-*сути","по сути"], ["по-*факту","по факту"], ["по-*делу","по делу"], ["по-*поводу","по поводу"], ["по-*возможности","по возможности"], ["по-*отдельности","по отдельности"], ["по-*аналогии","по аналогии"], ["по-*минимуму","по минимуму"], ["по-*максимуму","по максимуму"], ["по-*умолчанию","по умолчанию"], ["по-*соседству","по соседству"], ["по-*привычке","по привычке"], ["по-новой","по новой"], ["по-*крайней","по крайней"], ["по-русскому","по русскому"], ["по-полной","по полной"], ["по-старинке","по старинке"], ["по-ходу","походу"], ["по-*слухам","по слухам"], ["по-*молодости","по молодости"], ["по[\\s-]*ди[ао]г[ао]нал[еи]","по диагонали"], ["по-*порядку","по порядку"], ["по-*очереди","по очереди"], ["по-*полочкам","по полочкам"], ["по-*плечу","по плечу"], ["по-*возможности","по возможности"], // ["по-интересному","по интересному"],//По-хорошему? /* ["",""], ["",""], ["",""], */ ["деляться","делятся"], // Но раздЕлЯт(ь)ся ["пол[\\s-]+кило","полкило"], ["пол[\- ]часа","полчаса"], ["пол-*года","полгода"], ["поллитра","пол-литра"], ["полэкрана","пол-экрана"], ["не-*был","не был"], ["не-*была","не была"], ["не-*было","не было"], ["не-были","не были"],// Небыль ["н[ие]-*понял","не понял"], ["н[ие]-*зна[ие]шь","не знаешь"], ["н[ие]-*с[ьъ]ел","не съел"], ["н[ие]-*забыли","не забыли"], ["н[ие]-*д[оа]гон[еи]шь*","не догонишь"], ["н[ие]-*н[ао]блюда[еи]ть*ся","не наблюдается"], ["н[ие]-*п[оа]н[еи]маю","не понимаю"], ["н[ие]-*пр[оа]дают","не продают"], ["н[ие]-*х[оа]тел[оа]сь","не хотелось"], ["не-*могли","не могли"],//TODO: окончания ["не-*могу","не могу"], ["не-*сможешь*","не сможешь"], ["не-*хоц+а","не хочется"], ["не-*хочу","не хочу"], ["не-*хуже+","не хуже"], ["н[еи]знаю","не знаю"], ["недай","не дай"], ["не-*завалялся","не завалялся"], ["не-*влезает","не влезает"], ["не-*действует","не действует"], ["н[еи]лежит", "не лежит"], ["неповеришь","не поверишь"], ["н[ие]люблю","не люблю"], ["не-*волнуюсь","не волнуюсь"], ["не-*подн[ия]лась","не поднялась"], ["не-*хв[ао]та[еи]т","не хватает"], ["не-*р[ао]бот[ао][еи]т","не работает"], ["не-*спеша","не спеша"], ["не-*совсем","не совсем"], //TODO: почистить ["не\\s-]*совсем","не совсем"], ["н[еи]-*надо","не надо"], ["ни-*черта","ни черта"], ["не-*зря","не зря"], ["н[ие][фв]курс[ие]","не в курсе"], ["не[\\s-]*за[\\s-]*что","не за что"], ["не[\\s-]*с[\\s-]*кем","не с кем"], ["не[\\s-]*на[\\s-]*чем","не на чем"], ["не[\\s-]*может","не может"], ["не[\\s-]*платим","не платим"], ["не[\\s-]*платит","не платит"], ["не[\\s-]*я[\\s-]*же","не я же"], ["не[\\s-]*при[\\s-]*ч[еёо]м","не при чем"], ["ни[\\s-]*при[\\s-]*ч[еёо]м","ни при чём"],//Да, это два разных! ["н[еи][\\s-]*в[\\s-]*ко[еи]м[\\s-]*случ[аеи][еи]","ни в коем случае"], ["ни[\\s-]*за[\\s-]*что","ни за что"], ["ни-*к-*чему","ни к чему"], ["ни-*разу","ни разу"], ["ни-*одна","ни одна"], ["ни-*одной","ни одной"], ["ни-*одну","ни одну"], ["ни-*одного","ни одного"], ["ни-*одним","ни одним"], ["ни-*одном","ни одном"], ["ни-*один","ни один"], ["ни-*одному","ни одному"], ["на[\\s-]*ед[ие]не","наедине"], ["не[\\s-]гоже","негоже"], ["н[еи][\\s-]+ужели","неужели"], ["не[\\s-]*охото","неохота"], //TODO: почистить ["не-охота","неохота"], ["н[еи][\\s-]*мно[жшщ]ь*к[ао]*","немножко"], ["н[ие][\\s-]*оч[ие]нь","не очень"], ["н[еи][\\s-]*с[\\s-]*пр[оа]ста","неспроста"], ["не[\\s-]*д[ао][\\s-]*к[ао]нца","не до конца"], ["кудаж","куда ж"], ["таже","та же"], ["тот-*же","тот же"], ["тем-*же","тем же"], ["те-*же","те же"],//TODO: допросклонять ["тех-*же","тех же"], ["теми-*же","теми же"], ["того-*же","того же"], ["тому-*же","тому же"], ["всеже","все же"], ["всёже","всё же"], ["все-*ж","все ж"], ["всё-*ж","всё ж"], ["все[\\s-]*[еи]щ[еёо]","все ещё"], ["что-*ж","что ж"], ["это-ж","это ж"], //TODO: почистить ["это-*ж","это ж"], ["такойже","такой же"],//TODO: просклонять ["такогоже","такого же"], ["такомуже","такому же"], ["такимже","таким же"], ["такомже","таком же"], ["такаяже","такая же"], ["такуюже","такую же"], ["такими-*же","такими же"], ["таких-*же","таких же"], ["такие-*же","такие же"], ["чтоже","что же"], ["тожэ","тоже"], ["такжэ","также"], ["какую-*ж","какую ж"], ["какая-*ж","какая ж"], ["какой-*ж","какой ж"], ["надо-*бы","надо бы"], ["какбы","как бы"], ["хотя-*бы","хотя бы"], ["жалбы","жал бы"], //[Katzen Gott]: похоже на опечатку в слове "жалобы". Я бы убрала, но если это реально частая ошибка, то пусть. ["былобы","было бы"], ["были-*б","были б"], ["гдебы","где бы"], ["вроде-*бы","вроде бы"], ["выб","вы б"], ["яб","я б"], ["лучш[еи][\\s-]*б","лучше б"], ["что[\\s-]*ле","что ли"], ["штол[еь]","что ли"], ["что-*ль","что ль"],//TODO: просклонять ["чего-*ль","чего ль"], ["чему-*ль","чему ль"], ["чуть-*ли","чуть ли"], ["вря[дт]-*ли","вряд ли"], ["зачемто","зачем-то"], ["во+бще-*то","вообще-то"], ["в[\\s-]*о+бщем[\\s-]*то","в общем-то"], ["почемуто","почему-то"], ["к[ао]кую[\\s-]*т[уоа]","какую-то"], ["к[ао]кайа[\\s-]*т[ао]","какая-то"], ["чьято","чья-то"], ["чтото","что-то"], ["ктото","кто-то"], ["к[ао]кой[\\s-]*т[ао]","какой-то"],//TODO: допросклонять ["к[ао]кому[\\s-]*т[ао]","какому-то"], ["к[ао]ким[\\s-]*т[ао]","каким-то"], ["к[ао]ком[\\s-]*т[ао]","каком-то"], ["к[ао]кого[\\s-]*т[ао]","какого-то"], ["к[ао]кие[\\s-]*т[ао]","какие-то"], ["к[ао]кая[\\s-]*т[ао]","какая-то"], ["наконецто","наконец-то"], ["наконецтаки","наконец-таки"], ["вс[её]таки","всё-таки"], ["куда-*как","куда как"], ["потому-*как","потому как"], ["так-*как","так как"], ["так[\\s-]*[чш]т[ао]","так что"], ["потомучто","потому что"], ["потому-что","потому что"], ["п[оа]т[оа]му[\\s-]*[шч]т[оа]","потому что"], ["где-*угодно","где угодно"], ["кого-*угодно","кого угодно"], ["как-*только","как только"], ["тем-*более","тем более"], ["рука[\\s-]*об[\\s-]*руку","рука об руку"], ["до-*свидания","до свидания"], ["до-*свиданья","до свиданья"], ["на-лету","на лету"],//налёт не обижать! ["всего[\\s-]*лишь","всего лишь"], ["б[еи][сз][\\s-]*п[оа]нят[ие]я","без понятия"], ["как[\\s-]*н[ие][\\s-]*в[\\s-]*ч[еёо]м[\\s-]*н[еи][\\s-]*бывало","как ни в чем не бывало"], ["к-*стат[еи]","кстати"], ["как-*раз","как раз"], ["дада","да-да"], ["буд-то","будто"], ["то-*есть","то есть"], ["при-*встрече","при встрече"], ["под-дых","под дых"], ["на[\\s-]*р[ао]вне","наравне"], ["до-*свидан[иь]е","до свидания"], ["с-*кем","с кем"], ["на[\\s-]тощак","натощак"], ["подругому","по-другому"], ["на последок","напоследок"], ["вс[её]-*время","всё время"], ["ка[кг]-*бу[дт]то","как будто"], ["что-бы","чтобы"],// Объединить нельзя, ибо первый символ ["што-бы","чтобы"], ["вс[её]-*равно","всё равно"], ["тобишь","то бишь"], ["из *за","из-за"], //TODO: почистить ["из за","из-за"], ["изза","из-за"], ["из *под","из-под"], ["и[зс][- ]*под[- ]*лобья","исподлобья"], ["и[зс][ -]*д[ао]л[еи]ка","издалека"], ["докучи","до кучи"], ["сомной","со мной"], ["чтоли","что ли"], ["видители","видите ли"], ["накого","на кого"], ["к[\\s-]*с[оа][\\s-]*ж[ие]ален[еи]ю","к сожалению"], ["к[\\s-]*с[оа][\\s-]*ж[ие]аленью","к сожаленью"], ["и[зc][\\s-]*вне","извне"], ["молодеж","молодежь"], ["помоч","помочь"], ["о[дт]стричь*","отстричь"], ["по[дт]стричь*","подстричь"], ["измен[еи]шь*","изменишь"], ["ра[сз]буд[еи]шь*","разбудишь"], ["тысячь","тысяч"], ["душь","душ"], ["весчь*","вещь"], ["п[ао]дреж","подрежь"],//TODO: приставки ["атрежь*","отрежь"], ["отреж","отрежь"], ["надрежь*","надрежь"], ["слыш","слышь"], ["дрож","дрожь"], ["финишь","финиш"], ["ключь","ключ"], ["ноч","ночь"], ["будеть","будет"], ["делаеть","делает"], ["менше","меньше"], ["взятся","взяться"], ["поменятся","поменяться"], ["мерится","мериться"], ["мерятся","меряться"], ["имется","иметься"],//Поднимется ["грится","говорится"], ["учаться","учатся"],//Но обучаться ["общатся","общаться"],//Приобщатся ["от[\\s-]*куд[ао]","откуда"], ["пологай","полагай"], ["хто","кто"], ["фсё","всё"],//TODO: допросклонять ["фсем","всем"], ["фсех","всех"], ["общё","общо"], ["юнный","юный"],//не могу в префиксы, есть "юннат" ["юнного","юного"],//больше 54 000 ["юнному","юному"],//больше 12 000 ["юнным","юным"],//больше 20 700 ["юнном","юном"],//больше 16 000 ["юнная","юная"],//больше 200 000. С женским родом проблема. Есть имя Юнна ["юнную","юную"],//больше 82 00 ["юнные","юные"],//больше 367 000 ["юнных","юных"],//больше 290 000 ["юнными","юными"],//больше 20 000 /* [""+ca,""], [""+ca,""], [""+ca,""], [""+ca,""], */ ["мы"+ca,"мыться"],//TODO: приставки. В постфиксы нельзя - слишком коротко ["найд[её]"+ca,"найдётся"], ["делае"+ca,"делается"], ["получи"+ca,"получится"], ["занят*"+ca,"заняться"], ["научи"+ca,"научиться"],//"а чем легче научица?", аналогичная ситуация. "Он научица!" ("Он научится!") ["пяли"+ca,"пялится"], ["просну"+ca,"проснуться"], ["меняю"+ca,"меняются"], ["работае"+ca,"работается"], ["каже"+ca,"кажется"], ["верит"+ca,"верится"], ["кати"+ca,"катиться"], ["с[чщ]а[зс]*","сейчас"], ["станови"+ca,"становится"], ["валя"+ca,"валяться"], ["валяю"+ca,"валяются"], ["оста[её]"+ca,"остаётся"], ["рытся","рыться"], ["напится","напиться"], ["добится","добиться"], ["режеться","режется"], ["померять*ся","помериться"], ["мерять*cя","мериться"], ["менятся","меняться"], ["грю","говорю"],//TODO: проспрягать //[Katzen Gott]: грит не трогать — единица измерения зернистости ["грят","говорят"], ["сьедал","съедал"], ["сьедала","съедала"], ["сьедает","съедает"], // больше 109 000 ["сьедаю","съедаю"], // больше 73 000 ["сьедает","съедает"], // больше 109 000 ["сьедают","съедают"], // больше 36 000 ["сьедят","съедят"], //больше 57 000 ["сьешь","съешь"], //больше 101 000 ["сьедим","съедим"], //больше 20 000 ["сьест","съест"], //больше 97 000 ["сьем","съем"], //больше 300 000, сложность. Может быть проблема со словом "съём" ["сьесть","съесть"], ["тыщу","тысячу"], ["тыщи","тысячи"], ["тыщ","тысяч"], //? ["чесслово","честное слово"], ["ес+-н+о","естественно"], ["ес+е*с*т*н[оа]","естественно"], ["со[бп]с+т*н[оа]","собственно"], ["ч[ёо]","что"], ["н[ие]ч[ёео]","ничего"], ["кста","кстати"], // ["счас","сейчас"], // ["грит","говорит"],//TODO: добить окончаниями [Katzen Gott]: грит — единица измерения зернистости ["шо","что"], ["щь*та+","что"], ["шт*об","чтоб"], ["знач","значит"], ["к[ао]рочь*","короче"], ["поченить","починить"], ["приминить","применить"], ["д[ао]фига","очень много"],//Ибо нефиг! ["ч[ёое]-*то","что-то"],//TODO: дополнить! ["как-*нить","как-нибудь"], ["кто-*нить","кто-нибудь"],//TODO: допросклонять! ["кого-*нить","кого-нибудь"], ["кому-*нить","кому-нибудь"], ["кем-*нить","кем-нибудь"], ["ком-*нить","ком-нибудь"], ["какой-*нить","какой-нибудь"], ["что-*нить","что-нибудь"],//TODO: допросклонять! ["ч[еи]го-*нить","чего-нибудь"], ["ч[еи]му-*нить","чему-нибудь"], ["чем-*нить","чем-нибудь"], ["чём-*нить","чём-нибудь"], ["ч[оё]-*нить","что-нибудь"],//Как отличить от "чинить", не знаю ["что[\\s-]*н[ие]бу[дт]ь","что-нибудь"],//TODO: просклонять ["ч[ёое]го-*нить","чего-нибудь"], ["ч[еоё]-нить","что-нибудь"], ["ч[оеё][\\s-]*н[ие]бу[дт]ь","что-нибудь"], ["ч[еи]му-*нить","чему-нибудь"], ["к[ао]кую[\\s-]*н[ие]бу[дт]ь","какую-нибудь"],//TODO: просклонять ["к[ао]кой[\\s-]*н[ие]бу[дт]ь","какой-нибудь"], ["к[ао]кая[\\s-]*н[ие]бу[дт]ь","какая-нибудь"], ["к[ао]кого[\\s-]*н[ие]бу[дт]ь","какого-нибудь"], ["к[ао]ком[\\s-]*н[ие]бу[дт]ь","каком-нибудь"], ["к[ао]ком-*нить","каком-нибудь"], ["к[ао]кое-*нить","какое-нибудь"], ["к[ао]кой[\\s-]*либ[ао]","какой-либо"], ["к[ао]кая[\\s-]*либ[ао]","какая-либо"], ["к[ао]кую[\\s-]*либ[ао]","какую-либо"], ["к[ао]ко[гв][оа][\\s-]*либ[ао]","какого-либо"], ["к[ао]ким[\\s-]*либ[ао]","каким-либо"], ["к[ао]кими[\\s-]*либ[ао]","какими-либо"], ["к[ао]ких[\\s-]*либ[ао]","каких-либо"], ["к[ао]кому[\\s-]*либ[ао]","какому-либо"], ["к[ао]кое[\\s-]*либ[ао]","какое-либо"], ["к[ао]кие[\\s-]*либ[ао]","какие-либо"], ["ес[ст]+ес+н[ао]","естественно"], ["катац+о","кататься"], ["к[ао]роч[еь]*","короче"], ["в-*[оа-]+[пб]*ще","вообще"], // ["пожалста","пожалуйста"],//Объединено ["скока","сколько"], ["с[её]дня","сегодня"], ["тада","тогда"], ["см[ао]реть","смотреть"], ["ваще","вообще"], ["к[ао]нечно","конечно"], ["к[ао]нешн[оа]","конечно"], ["щ[ая][сз]*","сейчас"], ["хошь*","хочешь"], ["весч","вещь"], ["канеш","конечно"], ["бля","эх"],//Ибо сил моих больше нет ["см[а]+ри","смотри"], ["кр[еи]ве[тд]к[оа]","креветка"], ["йа","я"], ["в[\\s-]*о+[пб]щем","в общем"], ["тол*ь*к[ао]-*что","только что"], ["почти-*[чш]то","почти что"], ["луч[ёе]м","лучом"], ["н[еи]зна[еи]т","не знает"], ["севодня","сегодня"], ["м[оа]л[оа]д[её]ж[еи]","молодёжи"], ["щ[еи]таю","считаю"], ["кирпич[её]м","кирпичом"], ["режит","режет"], ["вроди","вроде"], ["ч[иае][вг]о","чего"], ["движ[её]к","движок"], ["каждего","каждого"], ["написанно","написано"], ["позиционировнаие","позиционирование"], ["почемы","почему"], ["можна","можно"], ["чесно*","честно"],//TODO: честный и т. д., не обидеть чеснок ["возмоно","возможно"], ["от-*тудова","оттуда"], ["времено","временно"], ["инное","иное"],//TODO: просклонять, лучше - окончания в кучку ["граници","границы"], ["пятници","пятницы"], ["каждего","каждого"], ["пр[ие]д[её]ть*ся","придётся"], ["отве[дт]ь*те","ответьте"], ["уборщить*ся","уборщица"], ["мужич[ёе]к","мужичок"], ["однажд[уы]","однажды"], ["аднажд[уы]","однажды"], ["с-*нов[ао]","снова"], ["т[еи]хон[еи]чко","тихонечко"], ["смерчь","смерч"], ["чере[зс][\\s-]*чур","чересчур"], ["паш[ёео]л","пошёл"], ["п[ао]т[еи]ря[ие]шь*","потеряешь"], ["п[оа]р[оа]ш[еёо]к","порошок"], ["с[еи]рт[еи]ф[ие]кат[ао]в","сертификатов"], ["с[ао]мн[еи]ва[еи]шь*ся","сомневаешься"], ["в-*пре[тд]ь","впредь"], ["за-*муж[еёо]м","замужем"], ["уме[еи]шь*","умеешь"], ["фетишь","фетиш"], ["в[\\s-]*т[еи]х[ао]ря","втихаря"], ["выигрышь","выигрыш"], ["секреторя","секретаря"], //секреторные железы ["секреторю","секретарю"], ["секретор[её]м","секретарём"], ["секреторе","секретаре"], ["бе[сз]толоч","бестолочь"], ["красивше","красивее"], ["доевши","доев"], ["помаги","помоги"],//Помагичить ["хоч[еи]м","хотим"],//хохочем ["хотишь","хочешь"], ["хоч[еи]те","хотите"], ["хотит","хочет"], ["хочут","хотят"], // ["хачу","хочу"], // Хачам обидно! ["дышем","дышим"], // Но вкладышем ["вылазит ","вылезает "],//TODO: аналоги ["и(?:сч|щ|ш)о","ещё"], ["е(?:сч|щ|ш)о","ещё"], ["лучче","лучше"], ["жизне","жизни"], ["седишь","сидишь"], ["к[ао]во","кого"], ["н[ие]з*ь*зя","нельзя"], //["миня","меня"],//Нельзя, речка такая есть! [Katzen Gott] речка с большой буквы должна быть. Так что, наверное, можно ["апять","опять"], ["зопиши","запиши"], ["н[ие][ -]над[ао]","не надо"], ["наверн[ао]е*","наверное"], ["етими","этими"],//TODO: просклонять, не обидев йети! ["етим","этим"], ["етот","этот"], ["етому","этому"], ["етом","этом"], ["етой","этой"], ["ен*то","это"], // TODO: тогда уж и другим н* пририсовать ["ету","эту"], ["ета","эта"], ["скуб","скуп"], ["в[-\\s]*зади","сзади"], ["в-*зад[еи]","сзади"], ["з[-\\s]*зад[ие]","сзади"], ["с[-\\s]*зад[ие]","сзади"], ["в[-\\s]*пер[ие]ди","впереди"], ["в-*пер[ие]д[ие]","впереди"], ["с[-\\s]*пер[ие]д[ие]","спереди"], ["в[-\\s]*лев[ао]","влево"], ["с[-\\s]*лев[ао]","слева"], ["в-*прав[ао]","вправо"], ["с-*прав[ао]","справа"], ["серебреного","серебряного"],//TODO: просклонять ["серебреный","серебряный"], ["серебреному","серебряному"], ["серебреном","серебряном"], ["серебреным","серебряным"], ["серебреной","серебряной"], ["серебреная","серебряная"], ["серебреную","серебряную"], ["серебреные","серебряные"], ["серебреными","серебряными"], ["серебреных","серебряных"], ["сначало","сначала"], ["еще","ещё"], ["ее","её"], ["пороль","пароль"], ["жжот","жжёт"], ["молодёж","молодёжь"], ["полувер","пуловер"], ["продовца","продавца"], ["п[оа]д[оа]жди","подожди"], ["п[ао]жай*лу*й*ст[ао]","пожалуйста"], // ["безплатно","бесплатно"], ["староной","стороной"], ["патаму","потому"], ["жудко","жутко"], ["поарать","поорать"], ["сандали","сандалии"], ["што","что"], ["што-*то","что-то"], ["скочать","скачать"], // ["отзов(?=(?:ы||а|у|ом|ам|ами))","отзыв"], ["троль","тролль"], ["придти","прийти"], ["ложить","класть"], // ["я ложу","кладу"],//Подойти к ложу / подойти к кладу ["ложим","кладём"], ["ложишь","кладёшь"], ["ложите","кладёте"], ["лож[ау]т","кладут"], ["лож[ие]т","кладёт"], // ["светой","святой"],//TODO: склонять ["вкантакте","вконтакте"], ["ихн(?:ий|его|ему|им|ем|ее|яя|ей|юю|ие|их|ими)","их"], ["сдесь","здесь"], ["калеса","колеса"], ["знач[её]к","значок"], ["покласть","положить"], ["ник[ао][гв]о","никого"], ["каг*да","когда"], ["п[ао]ч[ие]му","почему"], ["экспрес*о","эспрессо"], ["вписаная","вписанная"], ["вписаной","вписанной"], ["вписаную","вписанную"], ["вписаный","вписанный"], ["вписаного","вписанного"], ["вписаному","вписанному"], ["вписаном","вписанном"], ["вписаным","вписанным"], ["вписаные","вписанные"], ["вписаное","вписанное"], ["вписаными","вписанными"], ["вписаных","вписанных"], ["увидить","увидеть"], ["видете","видите"], ["видешь","видишь"], ["видет","видит"], ["видют","видят"], ["видем","видим"], //[Katzen Gott]: тут вроде все. Может быть можно как-то их "склеить"? ["н[оа]р[оа]щ[её]н+ые","наращённые"],//помнить про "наращены" ["н[оа]р[оа]щ[её]н+ая","наращённая"], ["н[оа]р[оа]щ[её]н+ую","наращённую"], ["н[оа]р[оа]щ[её]н+ой","наращённой"], ["н[оа]р[оа]щ[её]н+ыми","наращёнными"], ["н[оа]р[оа]щ[её]н+ых","наращённых"], ["н[оа]р[оа]щ[её]н+ый","наращённый"], ["н[оа]р[оа]щ[её]н+ого","наращённого"], ["н[оа]р[оа]щ[её]н+ому","наращённому"], ["н[оа]р[оа]щ[её]н+ым","наращённым"], ["н[оа]р[оа]щ[её]н+ом","наращённом"], ["н[оа]р[оа]щ[её]н+ое","наращённое"], ["сп[оа]сиб[оа]","спасибо"], ["п[оа]сиб[оа]","спасибо"], ["типо","типа"], ["граммот","грамот"], ["ключ[её]м","ключом"], ["нович[ёе]к","новичок"], ["новечку","новичку"], ["навичог","новичок"], ["боч[её]нок","бочонок"], ["нада","надо"], ["оч+ень","очень"], ["экстримал","экстремал"], ["болкон","балкон"],//TODO: просклонять, не обидев князя Болконского ["очь*(?!-ч)","очень"], ["н[ие]разу","ниразу"], ["завтро","завтра"], ["пра+льно","правильно"], ["есле","если"], ["гаус","Гаусс"],//TODO: просклонять. В префиксы нельзя, ибо c -> сс ["гаусова","Гауссова"], //? ["металы","металлы"],//TODO: просклонять, помнить про глагол "метал" ["пешера","пещера"], ["можи*т","может"], ["пыво","пиво"], //["толко","только"], // Похоже на разовую опечатку, обсуждаемо ["адн[ао]значь*н[ао]","однозначно"], ["одн[ао]значь*но","однозначно"], ["никаг*да","никогда"], ["кат[её]нок","котенок"], ["нек[ао]да","некогда"], ["щелч[её]к","щелчок"], ["редов","рядов"], ["параноя","паранойя"],//TODO: досклонять ["паранои","паранойи"], ["параное","паранойе"], ["параною","паранойю"], ["параноей","паранойей"], ["истощенна","истощена"], ["истощенно","истощено"], ["истощенны","истощены"], ["пребь[ёе]т","прибьёт"],//TODO: проспрягать ["стери","сотри"], ["подощло","подошло"], ["молодожённых","молодожён"],//TODO: просклонять ["амбула","фабула"], // [Katzen Gott]: "фабула" подойдет, но если у кого-то есть версия лучше — welcome. ["чуть[\\s]*чуть","чуть-чуть"], ["от[ао][-\\s]*всюд[ау]","отовсюду"], ["по-*пути","по пути"], ["ск[ао]рее-*вс[еи]го","скорее всего"], ["на-*равных","на равных"], ["п[ао][-\\s]*быстрее","побыстрее"], ["по[-\\s]т[ие]хоньк[оу]","потихоньку"], ]; var orphoPrefixToCorrect=[ /* ["",""], ["",""], ["",""], ["",""], ["",""], */ ["европп","европа"], ["с[оа]мнительн","сомнительн"], ["ч[ео]тк","чётк"], ["р[ао]сп[оа]л[оа]га","располага"], ["н[еи]пр[еи]клон","непреклон"], ["с[ао]мн[еи]ва","сомнева"], ["и[сз]польз[ыоа]ва","использова"], ["ц[иые]фр[ао]в","цифров"], ["цыфр","цифр"], ["растоян","расcтоян"], // Но растаян (снег) ["сум+ар+н","суммарн"], ["бес+к[оа]нечь*н","бесконечн"], ["к[оа]+р+д[ие]н+ат+","координат"], ["преобрет","приобрет"], ["и[сз]+толков[ао]н","истолкован"], ["груп(?!п)","групп"], ["пр[еи][ао]д[ао]лен","преодолен"], ["на[ий][\\s-]*мень*[шщ]+","наименьш"], ["на[ий][\\s-]*боль*[шщ]+","наибольш"], ["н[еи]+-*[зс]т[еи]рпим","нестерпим"], ["н[еи]+з*с+[яи]ка","неиссяка"], //неиссекаемый - который нельзя иссечь ["п[еи]р[еи]с[еи]кае","пересекае"], ["п[еи]р[еи]с[еи]каю","пересекаю"], ["пр[еи]-*во[зc]-*н*[еи]*мог","превозмог"], ["прям[ао][\\s-]*пр[ао]п[ао]рц[еи][ао]наль*н","прямо пропорциональн"], ["учавств","участв"], ["п[оа]дск[ао]ж","подскаж"], ["вырасл","выросл"], ["выбирут","выберут"], ["выбиру","выберу"], ["выбире","выбере"], ["манет","монет"],//Обманет ["п[оа]д[оа]ван","падаван"], ["сонц","солнц"], ["выстовк","выставк"], ["ковычь*к","кавычк"], ["к[оа]выч[еи]к","кавычек"], ["подчерп","почерп"],//[Katzen Gott]: подчерпнуть и иже с ним. ["комманд(?!ос|ер|итн)","команд"], ["тюрм","тюрьм"], ["д[ао]сь*т[еи]жен","достижен"], ["пр[оа]ц[еи]дур","процедур"], ["ап[ие]рат[ао]р","оператор"], ["оп[ие]рат[ао]р","оператор"], ["пр[оа]гр[оа]м+ист","программист"], ["ст[еи]пень*ди","стипенди"], ["пр[еи]т[еэ]нь*зи","претензи"], ["прещепк","прищепк"], ["тр[ие]н[ие]ровк","тренировк"], ["кострюл","кастрюл"], ["эк[ие]п[ие]ров","экипиров"], ["пр[еи]д[ъь]яв","предъяв"], ["привыс","превыс"],//превысить ["привыш","превыш"],//превышать //["по-*сколько","по сколько"], //может конфликтовать с "поскольку" ["шопот","шёпот"], ["свитор","свитер"], ["перессказ","пересказ"], ["обажа","обожа"], ["абажа","обожа"], ["р[ао]сп[оа]л[оа]га","располага"], ["пр[еи]дл[ао]га(?=[А-ЛН-ФЦ-ЯЁа-лн-фц-яё])","предлага"],// Предлога, о предлогах, предлогами ["зобав","забав"], ["д[еи]р[еи]жаб[оаы]*л","дирижабл"], ["фирм[еи]н+","фирменн"], ["тренн*[ие]нг","тренинг"], ["ир+ац+[иеыэ][оа]н+аль*н+","иррациональн"], ["ап+л[ие]кат","аппликат"], ["ост*р*[ао]градск","остроградск"], ["р[ао]з[ао]б[ъь]*[её]","разобьё"], ["р[ао]з[ао]б[ъь]*ю","разобью"], ["п[оа]д[иы]нт[еэ]грал+ь*н","подынтегральн"], ["элип","эллип"],//[aisse-258] эллипсы ["случ[ие](?![влнмтш])","случа"],//[aisse-258]: "случий" -> "случай", но не трогаем "случИлось" ["корысн","корыстн"], ["прекрастн","прекрасн"], ["извесн","известн"], ["неопастн","неопасн"], ["безопастн","безопасн"], ["опастн","опасн"], ["часн","частн"], ["спорт*цмен","спортсмен"], ["продлива","продлева"], ["продова","продава"], ["попробыва","попробова"], ["священ+(?=[аыоу])","священн"], ["прогрес+","прогресс"], ["к[ао]м+[ие][рн]+дин+[ие]р+","камердинер"], ["с[еи]мань*тик","семантик"], ["н[ао]пр[еия]жен","напряжен"], ["д[еи][ао]лект","диалект"], ["совпод","совпад"], ["сожелен","сожален"], ["ограничев","ограничив"], ["помошь*ник","помощник"], ["предъ*истори","предыстори"], ["чотк","чётк"], ["драмот","драмат"], ["б[ао]р[ао]хл","барахл"], ["б[ао]р[ао]хол","барахол"], ["обезпеч","обеспеч"], ["гаряч","горяч"], ["подь[ёе]м","подъём"], ["об[ьъ][её]м","объём"], ["раз[ьъ][её]м","разъем"], ["сь[её]м","съём"], ["с[оа]п[оа]ст[оа]в","сопостав"], ["с[еи]м+инар","семинар"], ["п[оа]двласт*н","подвластн"], ["всп[оа]м[ие]на","вспомина"], ["н[ао]сл[оа]жд","наслажд"], ["ужастн","ужасн"], ["вычесл","вычисл"], ["приступлени","преступлени"], ["приступник","преступник"], ["почт[ао]ль[оё]н","почтальон"], ["еден","един"], ["г[оа]ст[ие]пр[ие]имн","гостеприимн"], ["упровл","управл"], ["инт[еи]л+ект","интеллект"], ["г[ао]р[оа]зд","горазд"], ["аб[еи]ж","обиж"], ["х[оа]зя[ие]н","хозяин"], ["х[оа]зя[ие]в","хозяев"], ["з[ао]пр[ие]т","запрет"], ["з[ао]пр[ие]щ","запрещ"], ["г[ао]р[ао]нт","гарант"], ["п[ао]с[еи]тит[ие]л","посетител"], ["стисня","стесня"], ["м[еи]х[оа]ни","механи"], ["ув[ао]жа","уважа"], ["ув[ао]жа[еи]м","уважаем"], ["пр[ао]изв[ао]дит[ие]л","производител"], ["л[еи]кв[еи]д","ликвид"], ["еф+[еи]кт","эффект"], ["аб+[оа]н[ие]мент","абонемент"], ["об+[оа]н[ие]мент","абонемент"], ["изчез","исчез"], ["пр[оа]й*[еэ]ктир[оа]в","проектиров"], ["со+тве[тц][в]*[сц]*т*в","соответств"], ["со+тве[тц]*[сц]т*вен+","соответственн"], ["озн[ао]комь*те","ознакомьте"], ["вычетани","вычитани"],//вычитание ["агр[еи]с+","агресс"], ["ко[еэ]ф+[ие]ц[иеэ]+нт","коэффициент"], ["с[ие]стем+","систем"], ["сум(?=ир|арн)","сумм"], ["х[ао]р[ао]ш","хорош"], ["опода","опада"], ["большенств","большинств"], ["модератер","модератор"], ["рай*[её]н","район"], ["п[ао]здр[ао]в","поздрав"], ["колекц","коллекц"], ["ц[еи]л+инд[оеыэ]*р","цилиндр"], ["г[еи]м+[оа]р+о","геморро"], ["колличеств","количеств"], ["медлен(?!н)","медленн"], ["помошь","помощь"], ["чорт","чёрт"], ["каридор","коридор"], ["расчит","рассчит"], ["карабл","корабл"], ["отсутсв","отсутств"], ["здрав*ст*вуй","здравствуй"], ["неот[ъь]емлим","неотъемлем"], ["к[оа]м+ентар","комментар"], ["п[еи]р[еи][оа]дич","периодич"], ["выйгр","выигр"], ["встрепин","встрепен"], ["многомернн","многомерн"], ["куллер","кулер"], ["повтар","повтор"], ["пр[ие]вр[ао]щ","превращ"], ["возражд","возрожд"], ["замарач","заморач"], // ["сь","съ"],//TODO: прочие приставки//Мэри Сью ["учон","учён"], ["удиля","уделя"], ["избера","избира"], ["координальн","кардинальн"], ["ёгурт","йогурт"], ["егурт","йогурт"], ["презнал","признал"], /* [""+sya,""], [""+sya,""], */ ["предьяв","предъяв"], ["держут"+sya,"держат"], ["получет"+sya,"получит"], ["неполуч[еи]т"+sya,"не получит"], ["обидить"+sya,"обидеть"], ["дерать"+sya,"дирать"], ["тварит"+sya,"творит"], ["пересикают"+sya,"пересекают"], ["перепех","перепих"], ["уеден","уедин"], ["извен","извин"], ["обворач","оборач"], ["металич","металлич"], ["бъ(?!лгар)","бь"], ["под(?=ск[ао]льз)","по"], ["назвает","называет"],//5 шт. на Баше ["пичаль","печаль"], ["пакров","покров"], ["отдера","отдира"],//TODO: другие приставки ["придера","придира"], ["задера","задира"], ["удера","удира"], ["по-файлов","пофайлов"], ["спичич","спичеч"], ["счелч","щелч"], ["тысеч","тысяч"], ["дуел","дуэл"], ["н[ие]видем","невидим"], ["сельне","сильне"], ["б[ие]бл[ие]о","библио"], ["без*связн","бессвязн"], ["трол(?!л)","тролл"], ["ощущене","ощущени"], ["мендал","миндал"], ["седелок","сиделок"], ["седелк","сиделк"], ["женс*чин","женщин"], ["из[- ]*под-","из-под "], ["из[- ]*за-","из-за "], ["друг-друг","друг друг"], ["вапрос","вопрос"], ["спраси","спроси"], ["ч+[еа]ст*лив","счастлив"],//Числившихся ["щ+[иеа]ст*лив","счастлив"], ["с[щч]+[иеа]ст*лив","счастлив"], ["щ+[иеа]ст","счаст"], // ["с[чщ]+[иеа]ст","счаст"],//счесть ["иксплоит","эксплоит"], ["експлоит","эксплоит"], ["п[ао]м[ао]г","помог"], ["обисн","объясн"], ["мароз","мороз"], ["парнух","порнух"], ["еп+он","япон"], ["беомехан","биомехан"], ["мабил","мобил"], ["жистян","жестян"], ["осиле(?!н)","осили"], ["успак","успок"], ["оронгутан","орангутан"], ["ар[ао]нгутан","орангутан"], ["матив","мотив"], ["пильмен","пельмен"], ["децтв","детств"], ["ужос","ужас"], ["кр[еи]ве[тд]к","креветк"], //[Katzen Gott]: "креведко" тоже встречается, или его не трогать? ["тегров","тигров"], ["испепил","испепел"], ["сдрав*ств","здравств"], ["здраств","здравств"], ["собутылочник","собутыльник"], ["обкута","окута"], ["хлыш","хлыщ"], ["ево[шн][а-яё]+","его"], ["каров","коров"], ["шпоргал","шпаргал"], ["атракцион","аттракцион"], ["режис[ёе]р","режиссёр"], ["соеденин","соединен"], ["симпотич","симпатич"], ["девч[её]н","девчон"], ["мущин","мужчин"], ["большенств","большинств"], ["седени(?!он)","сидени"], // Да, есть такая штука - седенион ["електр","электр"], ["приемуществ","преимуществ"], ["оффис","офис"], ["агенств","агентств"], ["одн[оа]класник","одноклассник"], ["однаклассник","одноклассник"], ["видио","видео"], ["руск","русск"], ["сматре","смотре"], ["расчит","рассчит"], ["кантакт","контакт"], ["маструб","мастурб"], ["серебрянн","серебрян"], ["правельн","правильн"], ["свинн(?!ертон)","свин"], ["балон","баллон"], ["коментар","комментар"], ["прийд","прид"], ["раз*сказ","рассказ"], ["класн","классн"], ["аргазм","оргазм"], ["регестрац","регистрац"], ["куринн","курин"], ["востанов","восстанов"], ["дешов","дешёв"], ["пр[ие]з[ие]ватив","презерватив"], ["телифон","телефон"], ["гдето","где-то"], ["кудато","куда-то"], ["когото","кого-то"], ["какомто","каком-то"], ["расспис","распис"], ["офицал","официал"], ["здраств","здравств"], ["жостк","жестк"],//Жостово ["примьер","премьер"], ["правел","правил"], ["еслиб","если б"], ["разсве","рассве"], ["росписани","расписани"], ["гостинниц","гостиниц"], ["комерч","коммерч"], ["би[зс]плат","бесплат"], ["бальш","больш"], ["разь","разъ"], ["без(?=[кпстфхцчшщ])","бес"],//TODO: раз/роз ["бес(?=[бвгджзмр]|л(?!ан))","без"], ["раз(?=[кпстфхцчшщ])","рас"], ["рас(?=[бвгджзлмнр])","раз"], ["воз(?=[пстфхцчшщ])","вос"], ["вос(?=[бгджзлмнр])","воз"], ["через(?=[кпстфхцчшщ])","черес"], ["черес(?=[бвгджзлмр])","через"], ["бези(?!кович)","безы"], // ["безт","бест"],//TODO: доделать ["не долюбли","недолюбли"], ["боян","баян"], ["будующ","будущ"], ["лутш","лучш"], ["курсав","курсов"], ["венчестер","винчестер"], ["брошур","брошюр"], ["бе[сз]пелот","беспилот"], ["вмистим","вместим"], ["жолуд","жёлуд"], ["возвро","возвра"], ["в-*течени[ие]","в течение"], ["вырощен","выращен"], ["корект","коррект"], ["грусн","грустн"], ["граммот","грамот"], ["неостановлюсь","не остановлюсь"], ["неожидал","не ожидал"], ["неимею","не имею"], ["пол-(?=[бвгджзкмнпрстфхцчшщ])","пол"],//TODO! ["третье классник","третьеклассник"],//TODO! ["организьм","организм"], ["галав","голов"], ["ро[сз]сол","рассол"], ["мылостын","милостын"], ["сотон","сатан"], ["школьнец","школьниц"], ["както","как-то"], ["во[\\s-]*первых\\s(?![-—–])","во-первых, "], ["во-вторых\\s(?![-—–])","во-вторых, "], ["в-треть*их\\s(?![-—–])","в-третьих, "], ["копрал","капрал"], ["ленност","леност"], ["лесничн","лестничн"], ["опазда","опозда"], ["сохрон","сохран"], ["умера","умира"], ["убера","убира"], ["собера","собира"], ["разбера","разбира"], ["разб[ие]р[её]","разберё"], ["погаловн","поголовн"], ["пиня","пеня"], ["иссиня ч[еоё]рн","иссиня-чёрн"], ["Транс+[еи]льван","Трансильван"], ["коффе","кофе"], ["влаз[ие]л","влезал"], ["свян+","свин"], ["переборш","переборщ"], ["бутербот","бутерброд"], ["ч[ие]хотк","чахотк"], ["привселюдн","прилюдн"], ["вздыхн","вздохн"], ["чательн","тщательн"], ["малчуган","мальчуган"], ["калкулятор","калькулятор"], ["не-*многа","немного"], ["р[ао][зс]д[оа][ёе]т","раздаёт"], ["р[ие]п[ао]з[ие]т[ао]ри","репозитори"], ["пр[ие]з[ие]нтац","презентац"], ["шка[вф]ч[ие]к","шкафчик"], ["ан[ао]л[еи]зир[ао]в","анализиров"],//Проанализировать, но рационализировать. TODO: таки приставки ["он[ао]л[еи]зир[ао]в","анализиров"], ["чесл","числ"], ["и[зс]ч[ие]сл","исчисл"], ["вычесл","вычисл"], ["зачесл","зачисл"], ["начесл","начисл"], ["отчесл","отчисл"], ["п[ие]р[ие]ч[ие]сл","перечисл"], ["мур[ао]ве[ий]","муравей"], //муравейник ["муровь","муравь"], //тоже к муравьям ["ц[иеы]пл[её]н","цыплён"], ["ц[ие]плят(?!ь)","цыплят"], //10 цыплят, но не цеплять канат ["д[ие]скр[ие]м[ие]н","дискримин"], //дискриминант, дискриминация ]; var orphoPostfixToCorrect=[ /* ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], ["",""], */ ["мно[жш]ь*те","множьте"], ["будте","будьте"], ["сушняч[её]к","сушнячок"], ["пауч[её]к","паучок"], ["ловиш","ловишь"], ["жаждит","жаждет"], ["кинте","киньте"], ["кинишь*","кинешь"], ["слуш[оа]ть*ся","слушаться"], ["грустиш","грустишь"], ["береч","беречь"], ["прячся","прячься"], ["расслабся","расслабься"], ["знакомся","знакомься"], ["ругалсо","ругался"], ["ждёш","ждёшь"], ["ищеш","ищешь"], ["разиш","разишь"], ["т[еи]ря[еи]шь*","теряешь"], ["пиш[иы]шь*","пишешь"], ["пил[еи]шь*","пилишь"], ["кин[еи]шь*","кинешь"], ["найд[её]шь*","найдёшь"], ["ходиш","ходишь"], ["помниш","помнишь"], ["г[ао]в[ао]риш","говоришь"], ["гл[аея]диш","глядишь"], ["смотр[ие]ш","смотришь"], ["будеш","будешь"], ["хочеш","хочешь"], ["можеш","можешь"], /* [""+ca,""], [""+ca,""], [""+ca,""], [""+ca,""], [""+ca,""], [""+ca,""], */ ["дра"+ca,"драться"], ["любова"+ca,"любоваться"], ["знакоми"+ca,"знакомиться"],// что делать, если фраза будет "он с ней знакомица" (знакомится)? ["мая"+ca,"маяться"], ["сыпае"+ca,"сыпается"], ["рву"+ca,"рвутся"], ["крыва"+ca,"крываться"], ["крывае"+ca,"крывается"], ["крывае"+ca,"крывается"], ["нрави"+ca,"нравится"], ["включае"+ca,"включается"], ["выключае"+ca,"выключается"], ["вырубае"+ca,"вырубается"], ["хоче"+ca,"хочется"], ["зывае"+ca,"зывается"], ["трахаю"+ca,"трахаются"], ["мая"+ca,"маяться"], ["включае"+ca,"включается"], ["заведу"+ca,"заведутся"], ["краду"+ca,"крадутся"], ["траха"+ca,"трахаться"], ["держиться","держится"], ["становяться","становятся"], ["бер[её]ться","берётся"], ["кажеться","кажется"], ["кажуться","кажутся"], ["носяться","носятся"], ["несуться","несутся"], ["казываеться","казывается"], ["прягатся","прягаться"], ["глядется","глядеться"], ["удивлятся","удивляться"], ["обращаеться","обращается"], ["обращатся","обращаться"], ["обновяться","обновятся"], ["обновлятся","обновляться"], ["пишуться","пишутся"], ["постяться","постятся"], ["ходяться","ходятся"], ["бражатся","бражаться"], ["цеплятся","цепляться"], ["вращатся","вращаться"], ["видиться","видеться"], ["станеться","станется"], ["стануться","станутся"], ["боротся","бороться"], ["смотриться","смотрится"], ["стремяться","стремятся"], ["глашатся","глашаться"], ["ниметься","нимется"], ["дасться","дастся"], ["йдуться","йдутся"], ["надеятся","надеяться"], ["гадатся","гадаться"], ["печататся","печататься"], ["б[еи]руть*ся","берутся"], ["готовяться","готовятся"], ["боиться","боится"], ["думатся","думаться"], ["мчиться","мчится"], ["обидется","обидеться"], ["ждатся","ждаться"], ["маятся","маяться"], ["мытся","мыться"], ["рватся","рваться"], ["тиратся","тираться"], ["кусатся","кусаться"], ["диратся","дираться"], ["ниматся","ниматься"], ["ложаться","ложатся"], ["нравяться","нравятся"], ["смеятся","смеяться"], ["сядеться","сядется"], ["гулятся","гуляться"], ["жаловатся","жаловаться"], ["пытатся","пытаться"], ["оватся","оваться"], ["з[ао]бот[яю]ть*ся","заботятся"], ["б[ие]ратся","бираться"], ["плавяться","плавятся"], ["деруться","дерутся"], ["хвастатся","хвастаться"], ["вертиться","вертится"], ["одется","одеться"], ["грется","греться"], ["еватся","еваться"], ["ыватся","ываться"], ["зыватся","зываться"], ["врубатся","врубаться"], ["гружатся","гружаться"], ["пользоватся","пользоваться"], ["стебатся","стебаться"], ["иватся","иваться"], ["писатся","писаться"], ["двигатся","двигаться"], ["колотся","колоться"], ["являтся","являться"], ["режуться","режутся"], ["встречатся","встречатся"], ["братся","браться"], ["начинатся","начинаться"], ["трахатся","трахаться"], ["занятся","заняться"], ["кажеться","кажется"], ["хочеться","хочется"], ["просяться","просятся"], ["к[оа]зать*ся","казаться"], ["глядывац+[ао]","глядываться"], ["играц+[оа]","играться"], ["пишеться","пишется"], ["читаец+а","читается"], ["пользуюца","пользуются"], ["пытаюц+а","пытаются"], ["ругаец+о","ругается"], ["явяться","явятся"], ["пускаюц+а","пускаются"], ["борятся","борются"], ["сыпится","сыпется"], ["сыпатся","сыпаться"], ["рвуться","рвутся"], ["рвуться","рвутся"], ["пользуеться","пользуется"], ["кочаеть*ся","качается"], ["ються","ются"], ["ёться","ётся"], ["аеться","ается"], ["оеться","оется"], ["уеться","уется"], ["яеться","яется"], ["ееться","еется"], ["юеться","юется"], [" ка","-ка"], ["видил(?=а|и|о|)(?=с[яь])","видел"], ["батареик","батареек"], ["товарищь","товарищ"], ["откудо","откуда"], ["-ли"," ли"], ["-же"," же"], ["-бы"," бы"], // ["-что"," что"],//кое-что ["аеш","аешь"], ["шся","шься"], ["изьм","изм"],//TODO: просклонять ["цыя","ция"],//TODO: просклонять ["кочать","качать"],//TODO: проспрягать ["пожж[еа]","позже"], ["кочает","качает"], ["алася","алась"], ["шол","шёл"], ["смотрем","смотрим"],//TODO: допроспрягать. И вообще все глаголы-исключения ["стелим","стелем"], ["бреим","бреем"], ["видем","видим"], ["щ[еёо]лк[ао][еи]т","щёлкает"], ["садют","садят"], ["следующию","следующую"], ["убъю","убью"], ["девушко","девушка"], ["хранилищь","хранилищ"], ["выгонет","выгонит"], ["глядет","глядит"], ["давным\\s*давно","давным-давно"], ["в-*курсе","в курсе"], ["го\\s*-*\\s+на-*все[вг][оа]","го-навсего"], ["\\s*-*\\s+н[ие]бу[дт]ь","-нибудь"], ["видить","видеть"], ["-нть","-нибудь"], ["н[ие]буть","нибудь"], ["беременяю","беременею"], ["терад","тирад"], ["цыми","цами"], ]; var orphoFragmentsToCorrect=[ /* ["",""], ["",""], */ ["значте","значьте"], //TODO: Разобраться, почему во фрагментах. ["преятн","приятн"], ["преяте","прияте"],//Приятель, приятен ["м[ао]т+[ие]р+[ие]й*[ая]л","материал"], ["п[ао]р+[ао]л+[еи]л+[ао]грам+","параллелограмм"], ["л[ао]г[ао]рифм","логарифм"], ["р[еи]с+т[ао]ран","ресторан"], ["инжинер","инженер"], ["товарисч","товарищ"], ["шампинь[её]н","шампиньон"], ["бутербр*о[тд]","бутерброд"], ["су[еи]ц[иы]д","суицид"], ["матер[еи]ял","материал"], ["елемент","элемент"], ["пр[ие]з[ие]дент","президент"], ["тренажор","тренажёр"], ["в[ао]л+[еи]й*бол","волейбол"], ["фу[дт]+бол+","футбол"], // TODO: другие аналогичные виды спорта ["адресс","адрес"], ["ньюанс","нюанс"], ["ат+р[ие]бут","атрибут"], ["парашут","парашют"], ["ц[еи]л+инд[аоеыэуь]*р","цилиндр"], ["маштаб","масштаб"], ["с[еи]рт[еи]ф[ие]кат","сертификат"], ["пр[оа]т+[оа]тип","прототип"], ["[оа]р[еи]нтир","орентир"], ["компромитир","компрометир"], //компрометировать ["инсцинир","инсценир"], ["зачот","зачёт"], ["тендор","тендер"], ["субьект","субъект"], ["обьект","объект"], ["проэкт","проект"], ["бытерброд","бутерброд"], ["cочельнтик","cочельник"], ["водоконал","водоканал"],// не могу поставить отдельно ["конал", "канал"]. Есть названия фирмы "конал" и "Конал" - имя ирландского героя ["искуств","искусств"], ["естесств","естеств"], ["чуств","чувств"], ["ьезд","ъезд"], ["ьезж","ъезж"], ["ьявл","ъявл"], ["с[ие]р[ьъ][её]з","серьёз"], ["обезъян","обезьян"], ["конъяк","коньяк"], ["ружъ","ружь"], ["парал+ел+(?!л)","параллел"], ["распрострон","распростран"], ["съ*о+риентир","сориентир"], ["пермонент","перманент"], ["миллиц(?!ент)","милиц"], ["расствор","раствор"], ["балотир","баллотир"], ["интерис","интерес"], ["тринир","тренир"], ["пологают","полагают"], ["пологай","полагай"], ["варачива","ворачива"], //];[ ["топчит"+sya,"топчет"],//sya уже включает границу слова ["пологаеть*"+sya,"полагает"], // ["видит"+sya,"видеть"],//Бред ["видет"+sya,"видит"], ["клеет"+sya,"клеит"], ["клеют"+sya,"клеят"], ["пялет"+sya,"пялит"], ["тащет"+sya,"тащит"], ["бъёт"+sya,"бьёт"], ["смотрет"+sya,"смотрит"], ["тр[еия]с[ёе]т"+sya,"трясёт"],//TODO: проспрягать ["хочит"+sya,"хочет"], ["щитин","щетин"], ["разет","розет"], ["если-*чо","если что"], ["сикунд","секунд"], ["лучьш","лучш"], ["ч[ие]л[оа]в*[еэ]к","человек"], ["совецк","советск"], ["инстал(?![лл])","инсталл"], ["ньч","нч"], ["ньщ","нщ"], ["чьн","чн"], ["щьн","щн"], ["чьк","чк"], ["ъи","ы"], ["ъэ","э"], ["будующ","будущ"], ["следущ","следующ"], ["празн","праздн"], ["цыкл","цикл"], ["мед[еи]ц[иы]н","медицин"], ["интерестн","интересн"], ["класн","классн"], ["учасн","участн"], ["эксплуот","эксплуоат"], ["принцып","принцип"], ["мыслем","мыслим"], ["престег","пристег"], ["престёг","пристёг"], ["фармат","формат"], ["ьедин","ъедин"], // ["ьед[еи]н","ъедин"],//Объедение // ["ъед[еи]н","ъедин"], ["проблемм","проблем"], ["пропоган","пропаган"], ["коблук","каблук"], ["брительк","бретельк"], ["буит","будет"], ["хотяб","хотя б"], ["регестр","регистр"],//Или "реестр", но сочтём это санкциями ["рецедив","рецидив"], ["оч[еи]рова","очарова"], ["ьясн","ъясн"], ["чорн","чёрн"], ["авторезир","авторизир"], ["ил*[еи]м*[еи]нт","элемент"], ["эл*[еи]м*[еи]нт","элемент"],//TODO: дебажить до "[эи]л*[еи]м*[еи]нт" ["пробыва","пробова"], ["глядав","глядыв"], ["р[еи]к[ао]ш[еи]т","рикошет"], ["м[ие]н[ие]рал","минерал"], ["в[ие]т[ие]р[ие]нар","ветеринар"], ["т[ие]л[ие]виз[аео]р","телевизор"], ["инж[иыэ]нер","инженер"], ["болкон","балкон"], ["ад[ыэ]кват","адекват"], ["сп[ие]ц[ие]ф[ие]","специфи"],//специфический, специфика ["к[ао]лб[ао]с","колбас"], ["тормаз","тормоз"], ]; 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\u00AD]|^|$)"; // 0xAD - "мягкий перенос" //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); } var actionArrayCopy=actionArray.slice(); 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+" (мс): "+(Date.now() - timestamp)); }, }; //Теперь удаляем исходные словари - они больше не нужны, все слова уже обработаны, только память занимают //TODO: делать это вообще при сборке. Когда она будет orphoWordsToCorrect=orphoPrefixToCorrect=orphoPostfixToCorrect=orphoFragmentsToCorrect=globalArray=null; try{ module.exports.actionArray = actionArray; }catch(e){ //Значит, не node.js correct.log("chas-correct: на подготовку массива регулярных выражений затрачено (мс): "+(Date.now() - 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'; //////////////////////////////////////////////////////////////////////// // ПРЕФИКСЫ // // Функции: // string - получает строку и возвращает строку // cache - работа с кэшем // // Переменные: // reg - регулярное выражение // str - строка // flag - флаг // concated - "слепленные": текст и регулярки // // В блоке типографики пока префиксов нет // TODO: сделать! //////////////////////////////////////////////////////////////////////// Array.prototype.spliceWithLast=function(index){ ///Заменить элемент под номером index последним, последний удалить ///Это, очевидно, эффективнее, чем сдвигать весь массив и даже чем просто заменять на null 'use strict'; this[index]=this[this.length-1]; this.length--; }; Array.prototype.replaceWith=function(index,replacerIndex){ ///Заменить элемент под номером index элементом под номером replacerIndex 'use strict'; this[index]=this[replacerIndex]; }; Object.defineProperty(Array.prototype, 'spliceWithLast', {enumerable: false}); Object.defineProperty(Array.prototype, 'replaceWith' , {enumerable: false}); //Сейчас эта функция не используется, но, возможно, очень скоро пригодится для оптимизаций var regNotCyrillicToTrim=/^[^а-яё]+|[^а-яё]+$/i; function stringTrimNotCyrillic(ih) { //Да, быстрее так, а не методом-членом return ih.replace(regNotCyrillicToTrim,""); //TODO: проверить, быстрее одной регуляркой или двумя } //Кэшируем строки и регэкспы. Вроде как помогает. var regUn1=/[(]{6,}/g , strUn1="((("; var regUn2=/[)]{6,}/g , strUn2=")))"; var regUn3=/[!]1+/g , strUn3="!"; var regUn4=/[?]7+/g , strUn4="?"; var regUn5=/([.?!])\1{3,}/g , strUn5="$1$1$1"; function stringReplaceUniversal(ih){ return ih. replace(regUn1,strUn1). replace(regUn2,strUn2). replace(regUn3,strUn3). replace(regUn4,strUn4). replace(regUn5,strUn5); } var reg3podryad=/([А-Яа-яЁё])\1{3,}/g; function stringSpecialWork(ih){ return ih.replace(reg3podryad,"$1$1$1");//Это не выносится из-за сигнатуры } var totalNodes=0; var errorNodes=0; function stringMainWork(ih){ ih=stringSpecialWork(ih); totalNodes++; if(!concatedRegexp.test(ih)) return ih; errorNodes++; correct.replacedPairs.push(ih); for(var i=0; i<actionArray.length;i++){ 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=stringReplaceUniversal(node.data); if(!notContainsCyrillic(node.data)){ textNodes.push(node); } } } } function extractAllTextNodes() { ///Заменить textNodes на список var timeBeforeNodesExtracting=Date.now(); textNodes=[]; extractTextNodesFrom(document.body); correct.logTimestamp("На подготовку массива текстовых нод затрачено", timeBeforeNodesExtracting); } var firstChangingNode,lastChangingNode; var timeBeforeMain; function selectNodes() { firstChangingNode = 0; lastChangingNode = textNodes.length-1; var timeBeforeHeader=Date.now(); if(typicalNodes.nodes){ //Пропускаем "шапку" страницы while( firstChangingNode <= lastChangingNode && cacheIncreaseIfExists(textNodes[firstChangingNode].data) ){ firstChangingNode++; }; //И низушку while( firstChangingNode <= lastChangingNode && cacheIncreaseIfExists(textNodes[lastChangingNode].data ) ){ lastChangingNode--; }; } var cachedNodes=firstChangingNode+textNodes.length-lastChangingNode-1; //TODO: проверить, в какую там сторону единичка correct.log("Нод отнесено к шапке: "+cachedNodes+"("+(cachedNodes/textNodes.length*100)+"%), до "+firstChangingNode+"-й и после "+lastChangingNode+"-й"); correct.logTimestamp("Выделение шаблона", timeBeforeHeader); var timeBeforeNotCachedNodesSelecting=Date.now(); concatedText=""; // Теперь выкидываем ноды, которые в кэше for(var i=firstChangingNode; i<=lastChangingNode; i++){ if(cacheIncreaseIfExists(textNodes[i].data)){ // Наша нода уже закэширована // Заменяем её на ту, которая должна быть последней textNodes[i] = textNodes[lastChangingNode]; lastChangingNode--; //И потом снова изучаем полученное i--; } else { concatedText+=" "+textNodes[i].data; } } //Да, так быстрее, чем обрезать каждую по отдельности. //Это вообще парадокс: практически всегда быстрее работать с одной большой строкой, а не с несколькими маленькими concatedText=concatedText.replace(/[^а-яё]{4,}/gi," "); // TODO: вынести это в selectNodes if(concatedText.trim()==""){ correct.log("Все ноды в кэше - нечего делать"); clearTemporaryData(); return 0; } correct.logTimestamp("Выбор незакэшированных нод", timeBeforeNotCachedNodesSelecting); return 1; } function fixMistakes() { if(!selectNodes()){ // Все ноды закешированы return 0; } if(!selectRegs()){ // Нет регулярок, с которыми нужно работать return 0; } timeBeforeMain=Date.now(); asyncFixLoop(); flagEchoMessageDomChanged=1; } function firstRun() { extractAllTextNodes(); fixMistakes(); typicalNodes.totalPages++;//Логично, считаем настоящее количество страниц setTimeout(cacheRemoveOutdated,4000);//TODO: кэширование вообще растащить observeDOM(document.body, domChangedHandler);//Ставим обработчик изменений DOM } //Объединение текста всех нод и выкидывание ненужных регулярок var concatedText=""; var concatedRegexp; function selectRegs(){ var concatedRegexpSource=""; var delimiter="|"; var t=Date.now(); actionArray=actionArrayCopy.slice();//Да, так быстрее: https://jsperf.com/array-slice-vs-push/3 //{{Экспериментальное выкидывание регэкспов парами - медленнее /* 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(concatedText)) { actionArray.spliceWithLast(j); actionArray.spliceWithLast(j-1); l-=2; j-=2; } } } console.log(l); */ //}} var l=actionArray.length; //TODO: аналогичный цикл, но идти с конца. А потом уже так. Как в selectNodes for(var j=0; j<l; j++){ if(actionArray[j] && actionArray[j][2]){ if(!actionArray[j][2].test(concatedText)){ actionArray.replaceWith(j,l-1);//Это быстрее, чем забивать нулями l--; j--; }else{ concatedRegexpSource+=actionArray[j][2].source+delimiter; } } } actionArray.length=l+1; concatedRegexpSource=concatedRegexpSource.replace(/\|$/,"") if(!concatedRegexpSource){ correct.log("Нет обнаруживаемых ошибок"); clearTemporaryData(); correct.logTimestamp("Выбор регэкспов", t); return 0; } concatedRegexp=new RegExp(concatedRegexpSource,"im"); correct.logTimestamp("Выбор регэкспов", t); return 1; } var asyncFixLoopStartTime; var asyncCount=0; function asyncFixLoop(){ asyncCount++; asyncFixLoopStartTime=Date.now(); 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(!concatedRegexp.test(textArr.join(" "))){ i+=kuch; continue; } } */ var currentNode=textNodes[firstChangingNode]; if(!currentNode)//Не знаю, что имеется в виду continue; if(!cacheIncreaseIfExists(currentNode.data)){ currentNode.data = stringMainWork(currentNode.data); typicalNodes.nodes[currentNode.data] = 20; } /* if( (firstChangingNode % 100 == 0) // || (Date.now() - asyncFixLoopStartTime > 146) ){ firstChangingNode++; setTimeout(asyncFixLoop,10); return; } */ } correct.logTimestamp("Основной цикл", timeBeforeMain); actionsAfterFixLoop(); } function actionsAfterFixLoop(){ //Нечего память кушать! Надо будет - новые нагенерятся clearTemporaryData(); //Кэш не резиновый setTimeout(cacheCrop,3000); correct.logTimestamp("chas-correct отработал. С момента запуска", oldTime); correct.logToConsole(); } function clearTemporaryData(){ ///Очищаем временные переменные, чтобы не кушали память в простое textNodes = []; actionArray = []; concatedText = ""; concatedRegexp = new RegExp(""); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // Блок работы с кэшем типичных нод ////////////////////////////////////////////////////////////////////////////////////////////////////////// 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("Длина словаря изменилась - сбрасываем кэш"); } function cacheMetrika(text) { return Math.pow(typicalNodes.nodes[text],2)/( typicalNodes.nodes[text].length + 6); } function cacheIncreaseIfExists(text){ if(text in typicalNodes.nodes){ typicalNodes.nodes[text]+=20; return 1; } return 0; } function cacheCrop() { ///Удаление из кэша лишних (по некоторой метрике) нод //Считаем количество нод в кэше var cacheNodesCount=Object.keys(typicalNodes.nodes).length; var timeBefore=Date.now(); var cacheLength=JSON.stringify(typicalNodes.nodes).length; var currentMin; var deletedNodes=0; var deletedNodesLength=0; var lastNode; while( //Ограничиваем кэш 100 килобайтами на сайт (или 200, т. к. юникод? Не важно) cacheLength > ####00 || //Не более #### нод cacheNodesCount > #### ){ 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]; } } } //Сбросить кэш function cacheClear(){ storageWrapper.setKey("chas-correct-typical-nodes",{totalPages:0,nodes:{}}); } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // Блок обработки событий: нажатия клавиш (ввода текста) и изменения DOM ////////////////////////////////////////////////////////////////////////////////////////////////////////// var domChangedLastTime=Date.now(); var keydownLastTime=Date.now(); var domChangeTimes=0; // Сколько раз менялся DOM? Служит только для логов var flagEchoMessageDomChanged=0; var domChangingTimeout=0; //Тут хранится идентификатор запланированного изменения DOM 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); } } })(); function scheduleDomChangeHandler(time){ clearTimeout(domChangingTimeout); domChangingTimeout=setTimeout(domChangedHandler,time); } function domChangedHandler(){ var thisTime=Date.now(); // Если поднят флаг эхо-события (то есть мы сами только что поменяли DOM, внеся исправления), // то флаг опустить и ничего не делать. if( flagEchoMessageDomChanged ){ flagEchoMessageDomChanged = 0; return; } if( thisTime < keydownLastTime + 2*1468 ){ // Ещё идёт набор текста пользователем - последний раз клавиша нажата менее 3 секунд назад. // Если сейчас начать исправлять текст, есть риск помешать набору, что нехорошо. // Да, был такой баг. scheduleDomChangeHandler(keydownLastTime + 2 * 1468); return; } if(thisTime - domChangedLastTime < 1468 ){ // Если недавно мы уже обрабатывали изменения DOM, то лучше дальнейшую обработку слегка отложить. // Возможно, следом прилетят ещё события. А то повиснем! scheduleDomChangeHandler(1468); return; } // Теперь ничто не мешает взять список добавленных или изменённых нод и провести в нём исправления domChangedLastTime=Date.now(); fixMistakes(); domChangeTimes++; correct.logTimestamp("Вызов chas-correct по смене DOM "+domChangeTimes+"-й раз", thisTime); correct.logToConsole(); } //Расстановка типографики + откладывание автокоррекции при наборе + коррекция раскладки собеседника document.addEventListener("keydown", keydownHandler, true); //document.onkeydown = keydownHandler; function keydownHandler(e) { keydownLastTime=Date.now(); e = e || event; if (e.ctrlKey && e.shiftKey && e.keyCode == "A".charCodeAt(0)) { forceTypo(); return false; } if (e.ctrlKey && e.shiftKey && e.keyCode == 109) { handleLayoutFix(regLayoutArrayCyr); return false; } if (e.ctrlKey && e.shiftKey && e.keyCode == 107) { handleLayoutFix(regLayoutArrayLat); 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) ; } //////////////////////////////////////////////////////////////////////// // По просьбам трудящихся - принудтранслит по Ctrl+Shift+? //////////////////////////////////////////////////////////////////////// var strCyr="ёйцукенгшщзхъфывапролджэячсмитьбю"+'.Ё"№;:?ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,'; var strLat="`qwertyuiop[]asdfghjkl;'zxcvbnm,."+'/~@#$^&QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?'; var regLayoutArrayCyr=[], regLayoutArrayLat=[]; var cyrArray=strCyr.split(""); var latArray=strLat.split(""); for(var i=0; i<cyrArray.length; i++){ regLayoutArrayCyr.push([cyrArray[i],latArray[i]]); regLayoutArrayLat.push([latArray[i],cyrArray[i]]); } function stringFixLayout(ih,arr){ var rez=""; for(var i=0; i<ih.length; i++){ var letter=ih.substr(i,1); for(var j=0; j<arr.length; j++) letter=letter.replace(arr[j][0],arr[j][1]); rez+=letter; } return rez; } function handleLayoutFix(arr){ var selectedText = window.getSelection().toString(); alert(stringFixLayout(selectedText,arr)); } //////////////////////////////////////////////////////////////////////// // Наконец, запускаем впервые коррекцию // В самом конце, когда все функции уже определены // На всякий случай //////////////////////////////////////////////////////////////////////// firstRun();