- // ==UserScript==
- // @name WME Assist
- // @author borman84 (Boris Molodenkov), madnut, turbopirate, Griev0us + (add yourself here)
- // @description Check and fix street names for POI and segments.
- // @require https://greasyfork.org/scripts/31773-wme-assist-scanner/code/WME_Assist_Scanner.js?version=208266
- // @require https://greasyfork.org/scripts/31774-wme-assist-analyzer/code/WME_Assist_Analyzer.js?version=208269
- // @grant none
- // @include /^https:\/\/(www|beta)\.waze\.com(\/\w{2,3}|\/\w{2,3}-\w{2,3}|\/\w{2,3}-\w{2,3}-\w{2,3})?\/editor\b/
- // @version 0.5.28
- // @namespace WazeRus
- // ==/UserScript==
-
- var WME_Assist = WME_Assist || {}
-
- WME_Assist.debug = function (message) {
- if (!$('#assist_debug').is(':checked')) return;
- console.log("WME ASSIST DEBUG: " + message);
- }
-
- WME_Assist.info = function (message) {
- console.log("WME ASSIST INFO: " + message);
- }
-
- WME_Assist.warning = function (message) {
- console.log("WME ASSIST WARN: " + message);
- }
-
- WME_Assist.series = function (array, start, action, alldone) {
- var helper = function (i) {
- if (i < array.length) {
- action(array[i], function () {
- helper(i + 1);
- });
- } else {
- if (alldone) {
- alldone();
- }
- }
- }
-
- helper(start);
- }
-
- function run_wme_assist() {
- var ver = '0.5.28';
-
- var debug = WME_Assist.debug;
- var info = WME_Assist.info;
- var warning = WME_Assist.warning;
-
- function getWazeApi() {
- var wazeapi = window.Waze;
-
- if (!wazeapi) return null;
- if (!wazeapi.map) return null;
- if (!wazeapi.model) return null;
- if (!wazeapi.model.countries) return null;
- if (!wazeapi.model.countries.top) return null;
-
- return wazeapi;
- }
-
- var Rule = function (comment, func, variant) {
- this.comment = comment;
- this.correct = func;
- this.variant = variant;
- }
-
- var CustomRule = function (oldname, newname) {
- var title = '/' + oldname + '/ ➤ ' + newname;
- this.oldname = oldname;
- this.newname = newname;
- this.custom = true;
- $.extend(this, new Rule(title, function (text) {
- return text.replace(new RegExp(oldname), newname);
- }));
- }
-
- var ExperimentalRule = function (comment, func) {
- this.comment = comment;
- this.correct = func;
- this.experimental = true;
- }
-
- var Rules = function (countryName) {
- var rules_basicRU = function () {
- return [
- new Rule('Unbreak space in street name', function (text) {
- return text.replace(/\s+/g, ' ');
- }),
- new Rule('ACUTE ACCENT in street name', function (text) {
- return text.replace(/\u0301|\u0300|\"|\'/g, '');
- }),
- new Rule('Dash in street name', function (text) {
- return text.replace(/\u2010|\u2011|\u2012|\u2013|\u2014|\u2015|\u2043|\u2212|\u2796/g, '-');
- }),
- new Rule('No space after the word', function (text) {
- return text.replace(/\.(?!\s)/g, '. ');
- }),
- new Rule('Мусорный знак препинания после пробела', function (text) {
- return text.replace(/(^|\s+)(\.|,|;)/g, '$1');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/улицаица/, 'улица');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/скя( |$)/, 'ская$1'); // Волгостроевскя набережная
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(мая)( |$)/, '$1Мая$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(мкрн?\.?|мк?р?-н)( |$)/, '$1микрорайон$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(р-о?н)( |$)/, '$1район$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(им\.?)( |$)/, '$1имени$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(пос\.?)( |$)/i, '$1посёлок$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(д\.?)( |$)/, '$1деревня$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(просп\.?)( |$)/i, '$1проспект$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(ул\.?)( |$)/i, '$1улица$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(р-д)( |$)/i, '$1разъезд$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(з-д)( |$)/i, '$1заезд$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(пер\.?)( |$)/i, '$1переулок$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(пр\.?|пр?-з?д\.?)( |$)/i, '$1проезд$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(пр?-к?т\.?)( |$)/i, '$1проспект$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(тр-т)( |$)/i, '$1тракт$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(пл\.?)( |$)/i, '$1площадь$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(ш\.?)( |$)/, '$1шоссе$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(б-р|бул\.?)( |$)/i, '$1бульвар$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(дор\.)( |$)/i, '$1дорога$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(о\.?)( |$)/, '$1остров$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(наб\.?)( |$)/i, '$1набережная$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(туп\.?)( |$)/i, '$1тупик$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(кв\.?)( |$)/i, '$1квартал$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(набережная р\.?)( |$)/i, '$1набережная реки$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/^На /, 'на ');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)(-ая)( |$)/, '$1-я$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)(-о?го|-ое)( |$)/, '$1$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)(-[оыи]й)( |$)/, '$1-й$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)(-ти)( |$)/, '$1-и$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)й/, '$1-й');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)я/, '$1-я');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(\d)(\sЛет)(\s|$)/, '$1 лет$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(Проектируемый проезд)\s+[№#]\s*(\d+)/, '$1 $2');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/([а-яё])-\s+/, '$1 - ');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/\s+км\./i, ' км');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/\[([^P]+)\]/, '$1');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^|\()СН?Т\s([^\)]+)/, '$1$2 снт');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/^ЖД$/i, 'ж/д');
- }),
- new Rule('Incorrect highway name', function (text) {
- return text.replace(/^M-?(\d)/, 'М$1')
- .replace(/^A-?(\d)/, 'А$1')
- .replace(/^P-?(\d)/, 'Р$1')
- .replace(/^([МАР])-(\d)/, '$1$2')
- .replace(/^(\d{2})A-(\d)/, '$1А-$2')
- .replace(/^(\d{2})K-(\d)/, '$1К-$2')
- .replace(/^(\d{2})H-(\d)/, '$1Н-$2')
- .replace(/^(\d{2})P-(\d)/, '$1Р-$2')
- .replace(/^(\d+)А(:|\s+|$)/, '$1A$2')
- .replace(/^(\d+)В(:|\s+|$)/, '$1B$2');
- }),
- ];
- };
-
- var rules_RU = function () {
- return rules_basicRU().concat([
- new Rule('Incorrect status position', function (text) {
- // Неоднозначные улицы, требуется проверка на город
- // Москва: Козлова, Мишина
- // Питер: Абросимова, Гусева, Комарова, Панфилова, Тарасова, Старцева, Крюкова, Миронова, Перфильева, Шарова, Зеленина, Осокина
- // Великий Новгород: Яковлева, Ильина
- // Ижевск: Черезова
- // Краткие притяжательные прилагательные похожие на фамилии
- var exAdjW = 'Репищева|Малая Зеленина|Карташихина|Опочинина|Остоумова|Гаврикова|Прасковьина|Усачёва|Бармалеева|Ильмянинова|Остоумова|Плуталова|Подрезова|Полозова|Рашетова|Сегалева|Шамшева|Эсперова|Замшина|Куракина|Ольгина|Опочинина|Осокина|Рюхина|Тосина|Веткина|Жукова|Абросимова|Черезова|Алымова|Княжнина|Ванчакова|Новоажимова|Чудинцева';
-
- // Женские статусы
- var wStatus = 'улица|набережная|дорога|линия|аллея|площадь|просека|автодорога|эстакада|магистраль|дамба|хорда|коса|деревня|переправа|площадка|дорожка|трасса';
-
- // Мужские статусы
- var mStatus = 'проспект|переулок|проезд|тупик|бульвар|тракт|просек|взвоз|спуск|разъезд|переезд|квартал|путепровод|мост|сад|сквер|тоннель|туннель|парк|проток|канал|остров|микрорайон|район|городок|посёлок|поселок|вал|проулок|объезд|заезд|съезд|обвод|обход|подъезд|выход';
-
- // Средние статусы
- var nStatus = 'шоссе|кольцо|село';
-
- // Названия улиц похожие на прилагательные
- var exW = 'Нехая|Тукая|Мая|Барклая|Батырая|Маклая|Бикбая|Амантая|Нечая|Эшпая|Орая|Прикамья|Алтая|Ухсая|Хузангая|Галлая|Николая|Гая|Эркая|Камая|Пченушая|Здоровья|Палантая|Ярвенпяя|Гулая|Заполярья|Крылья|Приморья|Калина Красная|Краснолесья|Мазая|Умырзая|Абая|Сибая|Алибая|Шахрая';
-
- // Названия проспектов похожие на прилагательные
- var exM = 'Расковой|Дуровой|Космодемьянской|.+?строй|Ковалевской|Борисовой|Давлетшиной|Крупской|Шевцовой|Чайкиной|Богомоловой|Савиной|Попковой|Петровой|Ангелиной|Терешковой|Новоселовой|Красноармейской|Гризодубовой|Красноярский рабочий|Цеткин|Молдагуловой|Чайкиной|Цветаевой|Тимофеевой|Дубровиной|Ульяны Громовой|[Нн]абережной|Давлетшиной|Перовской|Шпаковой|Ульяновой|Гачхой|Исаевой|Бой|Плевицкой';
-
- // Отделить примечания в скобках (дублёр)
- var brackets = '';
- text = text.replace(/\s*(.*?)\s*(\(.*\))/,
- function (all, s, b) {
- brackets = b;
- return s;
- });
-
- // Игнорируем исключения. Не нужно добавлять статус или изменять порядок слов
- if (/^$| - |\/|,|:|дцать\s|десят\s|сорок\s|^\d+(:|$)|\d+[AB]|[МАРН]\d|\d{2}[АКНР]-|ТТК|КАД|ЗСД|АГ?ЗС|(^|\s|-)(лестница|зимник|объезд|заезд|съезд|обвод|обход|подъезд|closed|[Сс]троительство|[Дд]убл[её]р|Rail|грунтовка|[Тт]ропа|[Тт]рек|[Пп]лотина|метро|монорельс|ворота|шлагбаум|трамвай|пути|Транссиб|Мост|подход|подъезд|обход|въезд|выезд|разворот|шлагбаум|слобода|Грейдер|брод|на|в|к|под|с|от|во|из|по|об|у|о|над|около|при|перед|про|до|без|за|через|ж\/д|плотина|снт|кп|станция|[Пп]ромзона|паркинг|парковка|Козлова|Абросимова|Гусева|Комарова|Панфилова|Тарасова|Яковлева|Мишина|Старцева|Крюкова|Ильина|Миронова|Перфильева|Шарова|Зеленина|Жукова|Черезова|Осокина|~)(-|\s|$)/.test(text) )
- return text + ' ' + brackets;
-
- // коттеджный, дачный, клубный посёлок в начало
- text = text.replace(/(.*?)(?:\s+)((?:.*ый )посёлок)/, '$2 $1');
-
- // Добавляем пропущенный статус
- if ( ! new RegExp('(^|\\s+)(' + wStatus + '|' + mStatus + '|' + nStatus + ')(\\s+|$)').test(text) ) {
- if ( text == 'Набережная') {
- text = 'Набережная улица';
- } else
- if ( new RegExp('(^|\\s+)(' + wStatus + '|' + mStatus + '|' + nStatus + ')(\\s+|$)', 'i' ).test(text) ) {
- // Если статус есть, но записан с заглавной буквы
- text = text.replace( new RegExp('(^|\\s+)(' + wStatus + '|' + mStatus + '|' + nStatus + ')(?=\\s+|$)', 'i' ), function (all, space, status) {
- return space + status.toLowerCase();
- });
- } else
- if ( /(^|\s+)[Оо]б[ъь]ездная(\s+|$)/.test(text)) {
- text = text.replace(new RegExp('(^|\\s+)[Оо]б[ъь]ездная(\\s+|$)(?!=(' + wStatus + '))'), '$1Объездная дорога$2');
- } else
- if ( /(^|\s+)[Оо]кружная$/.test(text)) {
- text = text.replace(/(^|\s+)[Оо]кружная$/, '$1Окружная дорога');
- } else
- if ( /[-аяь]я$/.test(text)) { // Прилагательное без статуса (Русско-Полянская)
- text = text + ' улица';
- } else
- if (/[а-я]-[А-Я]/.test(text)) { // Не хватает пробелов вокруг тире (Москва-Петушки)
- text = text.replace(/([а-я])-([А-Я])/g, '$1 - $2');
- } else
- text = 'улица ' + text;
- }
-
- // Голые числительные без склонения
- if ( ! new RegExp('\\d\\s+мая(\\s|$)', 'i' ).test(text) )
- text = text.replace(new RegExp('(\\d)(?=(\\s+[^\\s]+(?:-я|ая|ья|яя|яся))*\\s+(' + wStatus + ')(\\s|$))', 'g'), '$1-я'); // 1 линия
- text = text.replace(new RegExp('(\\d)(?=(\\s+[^\\s]+(?:[-иоы]й|ин|[оеё]в))*\\s+(' + mStatus + ')(\\s|$))', 'g'), '$1-й'); // 2 проезд, 5 Донской проезд
-
- // Распространённые сокращения
- text = text.replace(/М\.\s+(?=Горького)/, 'Максима ');
- text = text.replace(/К\.\s+(?=Маркса|Либкнехта)/, 'Карла ');
- text = text.replace(/Р\.\s+(?=Люксембург)/, 'Розы ');
- text = text.replace(/А\.\s+(?=Невского)/, 'Александра ');
- text = text.replace(/Б\.\s+(?=Хмельницкого)/, 'Богдана ');
-
- // Всё пишем заглавными буквами, кроме статусов, предлогов и гидронимов
- text = text.replace(/(^|\s+)набережная улица/, '$1Набережная улица');
- var foundStatus = false;
- text = (' ' + text)
- .replace(/([-\s])([^-\s]+)/g,
- function(all, space, word) {
- if ( ! foundStatus )
- if ( new RegExp('^(' + wStatus+ '|' + mStatus + '|' + nStatus + ')$').test(word) ) {
- foundStatus = true;
- return all;
- };
- if ( /^(летия|лет|года|реч?к[аи]|канала?|острова?|стороны|год|съезда|имени|области|ручей|канавки|за|из|от|км|километр|де|в|к|о|с|у|на|и)$/i.test(word)
- || ( space == '-' && /^(лейтенанта|майора|полковника|губернатора|й|я|ти|го|е|ей|х)$/.test(word) ) )
- return space + word.toLowerCase();
- else return space + word.charAt(0).toUpperCase() + word.substr(1);
- })
- .replace(/\s+(.*)/, '$1')
- .replace(/Железная дорога/, 'железная дорога')
- .replace(/пос[её]лок остров/i, 'поселок Остров')
- .replace(/улица остров (.*)/i, 'улица Остров $1')
- .replace(/микрорайон в/i, 'микрорайон В');
-
- // Статусы женского рода
- if ( new RegExp('(^|\\s)(' + wStatus + ')(\\s|$)').test(text) ) {
-
- // Распространённые сокращения
- text = text.replace(/М\.\s+(?=[^\s]+?(?:ая|ья|яя|яся)( |$))/, 'Малая ');
- text = text.replace(/Б\.\s+(?=[^\s]+?(?:ая|ья|яя|яся)( |$))/, 'Большая ');
-
- // перед статусом могут быть только прилагательные
- // Строителей 1-я улица -> улица Строителей 1-я
- text = text.replace(new RegExp('(?:\\s*)(.+?)(?:\\s+)(' + wStatus + ')(?=\\s+|$)'),
- function (all, adj, s) {
- if ( new RegExp(exAdjW).test(adj) ) return all;
- if ( (! new RegExp(exW).test(adj)) &&
- (/^((\s+[^\s]+?(-я|ая|ья|яя|яся))+)$/.test(' ' + adj)) ) return all;
- return s + ' ' + adj;
- });
-
- // Прилагательные вперёд
- if ( ! new RegExp('(^|\\s|-)(' + exW + ')(-|\\s|$)').test(text) ) {
- // улица Малая Зеленина -> Малая Зеленина улица
- // улица Мягкая -> Мягкая улица
- // улица Авиаконструктора Яковлева, улица Малиновая Гора
- text = text.replace(new RegExp('(' + wStatus + ')((?:\\s+(?:' + exAdjW + ')|\\s+[^\\s]+(?:-я|ая|ья|яя|яся))+)$'), '$2 $1');
- // улица *** Малая Набережная -> Малая Набережная улица ***
- text = text.replace(new RegExp('(' + wStatus + ')(.*?)((?:\\s+[^\\s]+(?:-я|ая|ья|яя|яся))+)$'), '$3 $1$2');
- // улица Мягкая 1-й Проезд -> Мягкая улица 1-й Проезд
- text = text.replace(new RegExp('(' + wStatus + ')(?:\\s+)([^\\s]+(?:-я|ая|ья|яя|яся))(?=\\s+\\d+-й\\s+Проезд|\\s+\\d+-я\\s+Линия)'), '$2 $1');
- };
-
- // Числительное всегда вначале если оно согласовано с прилагательным
- // Мягкая 1-я -> 1-я Мягкая
- text = text.replace(/(.+(?:ая|ья|яя|яся))(?:\s+)(\d+-я)(?! Линия| Ферма| Рота)/, '$2 $1');
- // улица 1-я Строителей -> 1-я улица Строителей
- text = text.replace(new RegExp('(' + wStatus + ')(?:\\s+)(\\d+-я)(?!\\s+[^\\s]+(?:ая|ья|яя|яся|лка)( |$)|\\s+(' + wStatus + '|Ферма|Авеню|Пристань|Рота|Слобода))', 'i'), '$2 $1');
- // 1-я улица Лесоперевалка -> улица 1-я Лесоперевалка
- text = text.replace(new RegExp('(\\d+-я)\\s+(' + wStatus + ')\\s+([^\\s]+(?:лка|ель|аза|йка|летка|арка))$'), '$2 $1 $3');
- } else
-
- // Статусы мужского рода
- if ( new RegExp('(^|\\s)(' + mStatus + ')(\\s|$)').test(text) ) {
-
- // Распространённые сокращения
- text = text.replace(/М\.\s+(?=[^\s]+?(?:[-иоы]й|ин|[оеё]в)( |$))/, 'Малый ');
- text = text.replace(/Б\.\s+(?=[^\s]+?(?:[-иоы]й|ин|[оеё]в)( |$))/, 'Большой ');
-
- // перед статусом могут быть только прилагательные
- text = text.replace(new RegExp('(?:\\s*)(.+?)(?:\\s+)(' + mStatus + ')(?=\\s+|$)'),
- function (all, adj, s){
- // if ( /[а-яё]+([-иоы]й|ин)(\s+|$)/.test(adj) ) return all;
- if ( (! new RegExp(exM, 'i').test(adj)) &&
- (/^((\s+[^\s]+?([-иоы]й|ин|[оеё]в))+)$/.test(' ' + adj)) ) return all;
- return s + ' ' + adj;
- });
-
- // Прилагательное вперёд
- if (( ! new RegExp('(^|\\s)(' + exM + ')(\\s|$)', 'i').test(text) ) &&
- ( ! new RegExp('^(проезд|переулок)([^\.]*?)((?:\\s+[^\\s]+ой)+)$').test(text) ) ) {
- // переулок *** 1-й -> 1-й переулок ***
- text = text.replace(new RegExp('^(' + mStatus + ')([^\.]*?)((?:\\s+[^\\s]+(?:[-иоы]й|ин))+)$'), '$3 $1$2');
- text = text.replace(
- new RegExp('^(' + mStatus + ')((?:\\s+[^\\s]+(?:[-иоы]й|ин))+)$'), '$2 $1');
- text = text.replace(
- new RegExp('^(' + mStatus + ')(?:\\s+)([^\\s]+(?:[-иоы]й|ин))(?=\\s+\\d+-й\\s+Проезд|\\s+\\d+-я\\s+Линия)'), '$2 $1');
- }
-
- // Числительное всегда вначале если оно согласовано с прилагательным
- // переулок 1-й Дунаевского -> 1-й переулок Дунаевского
- //text = text.replace(new RegExp('(' + mStatus + ')(?:\\s+)(\\d+-й)(?!\\s+[^\\s]*(?:' + exM + ')|\\s+[^\\s]+(?:[-иоы]й|ин|[оеё]в)( |$)', 'i'), '$2 $1');
-
- text = text.replace(/(.+[иоы]й)(?:\s+)(\d+-й)/, '$2 $1');
- text = text.replace(new RegExp('(' + mStatus + ')(?:\\s+)(\\d+-й)(?!\\s+[^\\s]+[иоык][ий]( |$)|\\s+(' + mStatus + '|Ряд|км|километр|Поворот))', 'i'), '$2 $1');
- } else
-
- // Статусы среднего рода
- if ( new RegExp('(^|\\s)(' + nStatus + ')(\\s|$)').test(text) ) {
-
- // Энтузиастов шоссе -> шоссе Энтузиастов
- text = text.replace(new RegExp('(?:\\s*)(.+?)(?:\\s+)(' + nStatus + ')(?=\\s+|$)'),
- function (all, adj, s){
- if ( /[а-яё]+(ое)(\s+|$)/.test(adj) ) return all;
- return s + ' ' + adj;
- });
-
- // шоссе Воткинское -> Воткинское шоссе, Верхнее шоссе
- text = text.replace( new RegExp('^(' + nStatus + ')(?:\\s+)(.+[ео]е)$'), '$2 $1');
- }
-
- // Возвращаем скобки в конце
- return text + ' ' + brackets;
- }),
- new Rule('Move status to begin of name', function (text) {
- return text.replace(/(.*)(улица)(.*)/, '$2 $1 $3');
- }, 'Tula'),
- new ExperimentalRule('Experimental', function (text) {
- return text.replace(/experimental/, 'corrected_experimental');
- }),
- ]);
- };
-
- var rules_BY = function () {
- var isStatus = function (str) {
- var list = ['улица', 'переулок', 'проспект', 'проезд',
- 'площадь', 'шоссе', 'бульвар', 'тракт',
- 'тупик', 'спуск', 'вуліца', 'завулак',
- 'праспект', 'праезд', 'плошча', 'шаша'];
- if (list.indexOf(str) > -1) return true;
- return false;
- }
-
- var isPseudoStatus = function (str) {
- var list = ['шоссе', 'тракт', 'площадь', 'шаша', 'плошча', 'спуск'];
- if (list.indexOf(str) > -1) return true;
- return false;
- }
-
- var isNumber = function (str) {
- return /([0-9])-[іыйя]/.test(str);
- }
-
- var replaceParts = function (text) {
- var arr = text.split(' ');
- var result = [];
- var status;
- var number;
-
- var previousPart = '';
- for (var i = 0; i < arr.length; ++i) {
- var part = arr[i];
-
- if (isStatus(part) && !isPseudoStatus(part)) {
- status = part;
- } else if (isNumber(part) && previousPart.toLowerCase() != 'героев') {
- number = part;
- } else {
- result.push(part);
- }
-
- previousPart = part;
- }
-
- if (status) {
- result.splice(0, 0, status);
- }
-
- if (number) {
- result.push(number);
- }
-
- return result.join(' ');
- }
-
- return rules_basicRU().concat([
- new Rule('Delete space in initials', function (text) {
- return text.replace(/(^|\s+)([А-Я]\.)\s([А-Я]\.)/, '$1$2$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(тр-т)( |$)/, '$1тракт$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(вул\.?)( |$)/, '$1вуліца$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(зав)( |$)/, '$1завулак$3');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/(^| )(прасп)( |$)/, '$1праспект$3');
- }),
-
- new Rule('Incorrect street name', function (text) {
- return text.replace(/-ая/, '-я').replace(/-ой/, '-й');
- }),
- new Rule('Incorrect street name', function (text) {
- return text.replace(/([РрНнМмPpHM])-?([0-9])/, function (a, p1, p2) {
- p1 = p1
- .replace('р', 'Р')
- .replace('н', 'Н')
- .replace('м', 'М')
- .replace('P', 'Р')
- .replace('p', 'Р')
- .replace('H', 'Н')
- .replace('M', 'М');
-
- return p1 + '-' + p2;
- });
- }),
- new Rule('Incorrect street name', replaceParts),
- ]);
- }
-
- var getCountryRules = function (name) {
- var commonRules = [
- // Following rules must be at the end because
- // previous rules might insert additional spaces
- new Rule('Лишние пробелы', function (text) {
- return text.replace(/[\s]+/g, ' ');
- }),
- new Rule('Пробелы в начале улицы или после открывающей скобки', function (text) {
- return text.replace(/(^|\()[\s]+/, '$1');
- }),
- new Rule('Пробелы в конце улицы или перед закрывающей скобкой', function (text) {
- return text.replace(/[\s]+(\)|$)/, '$1');
- }),
- ];
- var countryRules;
- info('Get rules for country: ' + name);
- switch (name) {
- case 'Russia':
- countryRules = rules_RU();
- break;
- case 'Ukraine':
- countryRules = rules_RU();
- break;
- case 'Belarus':
- countryRules = rules_BY();
- break;
- default:
- info('There are not implemented rules for country: ' + name);
- countryRules = [];
- }
- return countryRules.concat(commonRules);
- }
-
- var rules = [];
- var customRulesNumber = 0;
-
- var onAdd = function (rule) {}
- var onEdit = function (index, rule) {}
- var onDelete = function (index) {}
-
- this.onAdd = function (cb) { onAdd = cb }
- this.onEdit = function (cb) { onEdit = cb }
- this.onDelete = function (cb) { onDelete = cb }
-
- this.onCountryChange = function (name) {
- info('Country was changed to ' + name);
- rules.splice(customRulesNumber, rules.length - customRulesNumber);
- rules = rules.concat(getCountryRules(name));
- }
-
- this.get = function (index) {
- return rules[index];
- }
-
- this.correct = function (variant, text) {
- var newtext = text;
- var experimental = false;
-
- for (var i = 0; i < rules.length; ++i) {
- var rule = rules[i];
-
- if (rule.experimental && !this.experimental) continue;
-
- if (rule.variant && rule.variant != variant) continue;
-
- var previous = newtext;
- newtext = rule.correct(newtext);
- var changed = (previous != newtext);
- if (rule.experimental && previous != newtext) {
- experimental = true;
- }
- previous = newtext;
- // if (rule.custom && changed) {
- // // prevent result overwriting by common rules
- // break;
- // }
- }
-
- return {
- value: newtext,
- experimental: experimental
- };
- }
-
- var save = function (rules) {
- if (localStorage) {
- localStorage.setItem('assistRulesKey', JSON.stringify(rules.slice(0, customRulesNumber)));
- }
- }
-
- this.load = function () {
- if (localStorage) {
- var str = localStorage.getItem('assistRulesKey');
- if (str) {
- var arr = JSON.parse(str);
- for (var i = 0; i < arr.length; ++i) {
- var rule = arr[i];
- this.push(rule.oldname, rule.newname);
- }
- }
- }
-
- rules = rules.concat(getCountryRules(countryName));
- }
-
- this.push = function (oldname, newname) {
- var rule = new CustomRule(oldname, newname);
- rules.splice(customRulesNumber++, 0, rule);
- onAdd(rule);
-
- save(rules);
- }
-
- this.update = function (index, oldname, newname) {
- var rule = new CustomRule(oldname, newname);
- rules[index] = rule;
- onEdit(index, rule);
-
- save(rules);
- }
-
- this.remove = function (index) {
- rules.splice(index, 1);
- --customRulesNumber;
- onDelete(index);
-
- save(rules);
- }
- }
-
- var ActionHelper = function (wazeapi) {
- var WazeActionUpdateObject = require("Waze/Action/UpdateObject");
- var WazeActionAddOrGetStreet = require("Waze/Action/AddOrGetStreet");
- var WazeActionAddOrGetCity = require("Waze/Action/AddOrGetCity");
-
- var ui;
-
- var type2repo = function (type) {
- var map = {
- 'venue': wazeapi.model.venues,
- 'segment': wazeapi.model.segments
- };
- return map[type];
- }
-
- this.setUi = function (u) {
- ui = u;
- }
-
- this.Select = function (id, type, center, zoom) {
- var attemptNum = 10;
-
- var select = function () {
- info('select: ' + id);
-
- var obj = type2repo(type).objects[id];
-
- wazeapi.model.events.unregister('mergeend', map, select);
-
- if (obj) {
- wazeapi.selectionManager.select([obj]);
- } else if (--attemptNum > 0) {
- wazeapi.model.events.register('mergeend', map, select);
- }
-
- WME_Assist.debug("Attempt number left: " + attemptNum);
-
- wazeapi.map.setCenter(center, zoom);
- }
-
- return select;
- }
-
- this.isObjectVisible = function (obj) {
- if (!onlyVisible) return true;
- if (obj.geometry)
- return wazeapi.map.getExtent().intersectsBounds(obj.geometry.getBounds());
- return false;
- }
-
- var addOrGetStreet = function (cityId, name, isEmpty) {
- var foundStreets = wazeapi.model.streets.getByAttributes({
- cityID: cityId,
- name: name,
- });
-
- if (foundStreets.length == 1)
- return foundStreets[0];
-
- var city = wazeapi.model.cities.objects[cityId];
- var a = new WazeActionAddOrGetStreet(name, city, isEmpty);
- wazeapi.model.actionManager.add(a);
-
- return a.street;
- }
-
- var addOrGetCity = function (countryID, stateID, cityName) {
- var foundCities = Waze.model.cities.getByAttributes({
- countryID: countryID,
- stateID: stateID,
- name : cityName
- });
-
- if (foundCities.length == 1)
- return foundCities[0];
-
- var state = Waze.model.states.objects[stateID];
- var country = Waze.model.countries.objects[countryID];
- var a = new WazeActionAddOrGetCity(state, country, cityName);
- Waze.model.actionManager.add(a);
- return a.city;
- }
-
- var cityMap = {};
- var onlyVisible = false;
-
- this.newCityID = function (id) {
- var newid = cityMap[id];
- if (newid) return newid;
- return id;
- }
-
- this.renameCity = function (oldname, newname) {
- var oldcity = wazeapi.model.cities.getByAttributes({name: oldname});
-
- if (oldcity.length === 0) {
- console.log('City not found: ' + oldname);
- return false;
- }
-
- var city = oldcity[0];
- var newcity = addOrGetCity(city.countryID, city.stateID, newname);
-
- cityMap[city.getID()] = newcity.getID();
- onlyVisible = true;
-
- console.log('Do not forget press reset button and re-enable script');
- return true;
- }
-
- this.fixProblem = function (problem) {
- var deferred = $.Deferred();
- var attemptNum = 10; // after that we decide that object was removed
-
- var fix = function () {
- var obj = type2repo(problem.object.type).objects[problem.object.id];
- wazeapi.model.events.unregister('mergeend', map, fix);
-
- if (obj) {
- // protect user manual fix
- var currentValue = wazeapi.model.streets.objects[obj.attributes[problem.attrName]].name;
- if (problem.reason == currentValue) {
- var correctStreet = addOrGetStreet(problem.cityId, problem.newStreetName, problem.isEmpty);
- var request = {};
- request[problem.attrName] = correctStreet.getID();
- wazeapi.model.actionManager.add(new WazeActionUpdateObject(obj, request));
- } else {
- ui.updateProblem(problem.object.id, '(ручное: ' + currentValue + ')');
- }
- deferred.resolve(obj.getID());
- } else if (--attemptNum <= 0) {
- ui.updateProblem(problem.object.id, '(Не исправлено. Удалено?)');
- deferred.resolve(problem.object.id);
- } else {
- wazeapi.model.events.register('mergeend', map, fix);
- wazeapi.map.setCenter(problem.detectPos, problem.zoom);
- }
-
- WME_Assist.debug('Attempt number left: ' + attemptNum);
- }
-
- fix();
-
- return deferred.promise();
- }
- }
-
- var Ui = function () {
- var addon = document.createElement('section');
- addon.innerHTML = '<b>WME Assist</b> v' + ver;
-
- var section = document.createElement('p');
- section.style.paddingTop = "8px";
- section.style.textIndent = "16px";
- section.id = "assist_options";
- section.innerHTML = '<b>Настройки:</b><br/>' +
- '<label><input type="checkbox" id="assist_enabled" value="0"/> Включен</label><br/>' +
- '<label><input type="checkbox" id="assist_debug" value="0" checked/> Отладка</label><br/>';
- var variant = document.createElement('p');
- variant.id = 'variant_options';
- variant.innerHTML = '<b>Правила:</b><br/>' +
- '<label><input type="radio" name="assist_variant" value="Moscow" checked/> Россия</label><br/>' +
- '<label><input type="radio" name="assist_variant" value="Tula"/> Тула</label><br/>';
- section.appendChild(variant);
- addon.appendChild(section);
-
- section = document.createElement('p');
- section.style.paddingTop = "8px";
- section.style.textIndent = "16px";
- section.id = "assist_custom_rules";
- $(section)
- .append($('<p>').addClass('message').css({'font-weight': 'bold'}).text('Пользовательские правила'))
- .append($('<button>').prop('id', 'assist_add_custom_rule').addClass('btn btn-default btn-primary').text('Добавить'))
- .append($('<button>').prop('id', 'assist_edit_custom_rule').addClass('btn btn-default').text('Изменить'))
- .append($('<button>').prop('id', 'assist_del_custom_rule').addClass('btn btn-default btn-warning').text('Удалить'))
- .append($('<ul>').addClass('result-list'));
- addon.appendChild(section);
-
- section = document.createElement('p');
- section.style.paddingTop = "8px";
- section.style.textIndent = "16px";
- section.id = "assist_exceptions";
- $(section)
- .append($('<p title="Right click on error in list to add">').addClass('message').css({'font-weight': 'bold'}).text('Исключения'))
- .append($('<ul>').addClass('result-list'));
- addon.appendChild(section);
-
- var newtab = document.createElement('li');
- newtab.innerHTML = '<a href="#sidepanel-assist" data-toggle="tab">Assist</a>';
- $('#user-info #user-tabs .nav-tabs').append(newtab);
-
- addon.id = "sidepanel-assist";
- addon.className = "tab-pane";
- $('#user-info > div > .tab-content').append(addon);
-
- var selectedCustomRule = -1;
-
- this.selectedCustomRule = function () {
- return selectedCustomRule;
- }
-
- this.addCustomRule = function (title) {
- var thisrule = $('<li>').addClass('result').click(function () {
- selectedCustomRule = $('#assist_custom_rules li.result').index(thisrule);
- info('index: ' + selectedCustomRule);
- $('#assist_custom_rules li.result').css({'background-color': ''});
- $('#assist_custom_rules li.result').removeClass('active');
- $(this).css({'background-color': 'lightblue'});
- $(this).addClass('active');
- }).hover(function () {
- $(this).css({
- cursor: 'pointer',
- 'background-color': 'lightblue'
- });
- }, function () {
- $(this).css({
- cursor: 'auto'
- });
- if (!$(this).hasClass('active')) {
- $(this).css({
- 'background-color': ''
- });
- }
- })
- .append($('<p>').addClass('additional-info clearfix').text(title))
- .appendTo($('#assist_custom_rules ul.result-list'));
- }
-
- this.updateCustomRule = function (index, title) {
- $('#assist_custom_rules li.result').eq(index).find('p.additional-info').text(title);
- }
-
- this.removeCustomRule = function (index) {
- $('#assist_custom_rules li.result').eq(index).remove();
- selectedCustomRule = -1;
- }
-
- this.addException = function (name, del) {
- var thisrule = $('<li>').addClass('result').click(function () {
- var index = $('#assist_exceptions li.result').index(thisrule);
- del(index);
- }).hover(function () {
- $(this).css({
- cursor: 'pointer',
- 'background-color': 'lightblue'
- });
- }, function () {
- $(this).css({
- cursor: 'auto'
- });
- if (!$(this).hasClass('active')) {
- $(this).css({
- 'background-color': ''
- });
- }
- })
- .append($('<p>').addClass('additional-info clearfix').text(name))
- .appendTo($('#assist_exceptions ul.result-list'));
- }
-
- this.removeException = function (index) {
- $('#assist_exceptions li.result').eq(index).remove();
- }
-
- this.showMainWindow = function () {
- $('#WazeMap').css('overflow', 'hidden');
- mainWindow.dialog('open');
- mainWindow.dialog('option', 'position', {
- my: 'right top',
- at: 'right-50 top',
- of: '#WazeMap',
- });
- // Minimize window
- mainWindow.prev('.ui-dialog-titlebar').find('button').click();
- }
-
- this.hideMainWindow = function () {
- mainWindow.dialog('close');
- }
-
- $('<div>', {
- id: 'WME_AssistWindow',
- title: 'WME Assist',
- })
- .append($('<div>').css({
- padding: 10,
- })
- .append($('<button id="assist_fixall_btn" class="btn btn-danger">Исправить</button>'))
- .append($('<button id="assist_scanarea_btn" class="btn btn-warning">Скан</button>'))
- .append($('<button id="assist_clearfixed_btn" class="btn btn-success">Очистить</button>'))
- .append($('<h2>Проблемы</h2>').css({
- 'font-size': '100%',
- 'font-weight': 'bold',
- }))
- .append($('<ol id="assist_unresolved_list"></ol>').css({
- border: '1px solid lightgrey',
- 'padding-top': 2,
- 'padding-bottom': 2,
- })))
- .append($('<div>').css({
- padding: 10,
- })
- .append($('<h2>Исправлено</h2>').css({
- 'font-size': '100%',
- 'font-weight': 'bold',
- }))
- .append($('<ol id="assist_fixed_list"></ol>').css({
- border: '1px solid lightgrey',
- 'padding-top': 2,
- 'padding-bottom': 2,
- })))
- .appendTo($('#WazeMap'));
-
- $('<div>').prop('id', 'assist_custom_rule_dialog')
- .append($('<p>Заполните все поля</p>'))
- .append($('<form>')
- .append($('<fieldset>')
- .append($('<label>').prop('for', 'oldname').text('Регулярное выражение'))
- .append($('<input>', {
- type: 'text',
- name: 'oldname',
- 'class': 'text ui-widget-content ui-corner-all',
- id: 'oldname',
- }))
- .append($('<label>').prop('for', 'newname').text('Текст замены'))
- .append($('<input>', {
- type: 'text',
- name: 'newname',
- 'class': 'text ui-widget-content ui-corner-all',
- id: 'newname',
- }))
- )
- )
- .appendTo($('#map'));
-
-
- $('#assist_custom_rule_dialog label').css({display: 'block'});
- $('#assist_custom_rule_dialog input').css({display: 'block', width: '100%'});
-
- var customRuleDialog_Ok = function () {}
- var customRuleDialog = $('#assist_custom_rule_dialog').dialog({
- autoOpen: false,
- height: 300,
- width: 350,
- modal: true,
- buttons: {
- Ok: function () {
- customRuleDialog_Ok();
- customRuleDialog.dialog('close');
- },
- Cancel: function () {
- customRuleDialog.dialog('close');
- }
- }
- });
-
- var mainWindow = $('#WME_AssistWindow').dialog({
- autoOpen: false,
- appendTo: $('#WazeMap'),
- width: 500,
- draggable: true,
- height: 600,
- dragStop: function () {
- $('#WME_AssistWindow').parent().css('height', 'auto');
- }
- });
- mainWindow.parent('.ui-dialog').css({
- 'zIndex': 1040,
- 'opacity': '0.9',
- });
- mainWindow.prev('.ui-dialog-titlebar').css('background','lightblue');
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title').append($('<span> - </span>'));
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title')
- .append($('<span>', {
- id: 'assist-error-num',
- title: 'Количество нерешенных проблем',
- text: 0,
- }).css({color: 'red'}));
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title').append($('<span> / </span>'));
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title')
- .append($('<span>', {
- id: 'assist-fixed-num',
- title: 'Количество исправленных',
- text: 0,
- }).css({color: 'green'}));
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title').append($('<span> - </span>'));
- mainWindow.prev('.ui-dialog-titlebar').find('.ui-dialog-title')
- .append($('<span>', {
- id: 'assist-scan-progress',
- title: 'Прогресс сканирования',
- text: 0,
- }).css({color: 'blue'}));
-
- // Hack jquery ui dialog
- var icon = mainWindow.prev('.ui-dialog-titlebar').find('span.ui-icon');
- if (!icon.hasClass('ui-icon-minusthick')) {
- icon.addClass('ui-icon-minusthick');
- }
- if (icon.hasClass('ui-icon-closethick')) {
- icon.removeClass('ui-icon-closethick');
- }
- var btn = mainWindow.prev('.ui-dialog-titlebar').find('button');
- mainWindow.prev('.ui-dialog-titlebar').find('button').unbind('click');
- var visible = true;
- var height;
- mainWindow.prev('.ui-dialog-titlebar').find('button').click(function () {
- if ($('#WME_AssistWindow').is(':visible')) {
- $('#WME_AssistWindow').hide();
- btn.prop('title', 'Развернуть');
-
- icon.removeClass('ui-icon-minusthick');
- icon.addClass('ui-icon-arrow-4-diag');
- } else {
- $('#WME_AssistWindow').show();
- btn.prop('title', 'Свернуть');
-
- icon.addClass('ui-icon-minusthick');
- icon.removeClass('ui-icon-arrow-4-diag');
- }
- })
-
- var self = this;
-
- this.addProblem = function (id, text, func, exception, experimental) {
- var problem = $('<li>')
- .prop('id', 'issue-' + id)
- .append($('<a>', {
- href: "javascript:void(0)",
- text: text,
- click: function (event) {
- func(event);
- },
- contextmenu: function (event) {
- exception(event);
- event.preventDefault();
- event.stopPropagation();
- },
- }))
- .appendTo($('#assist_unresolved_list'));
-
- if (experimental) {
- problem.children().css({color: 'red'}).prop('title', 'Experimental rule');
- }
- }
-
- this.updateProblem = function (id, text) {
- var a = $('li#issue-' + escapeId(id) + ' > a');
- a.text(a.text() + ' ' + text);
- }
-
- this.setUnresolvedErrorNum = function (text) {
- $('#assist-error-num').text(text);
- }
-
- this.setFixedErrorNum = function (text) {
- $('#assist-fixed-num').text(text);
- }
-
- this.setScanProgress = function (text) {
- $('#assist-scan-progress').text(text);
- }
-
- var escapeId = function (id) {
- return String(id).replace(/\./g, "\\.");
- }
-
- this.moveToFixedList = function (id) {
- $("#issue-" + escapeId(id)).appendTo($('#assist_fixed_list'));
- }
-
- this.removeError = function (id) {
- $("#issue-" + escapeId(id)).remove();
- }
-
- var fixallBtn = $('#assist_fixall_btn');
- var clearfixedBtn = $('#assist_clearfixed_btn');
- var scanAreaBtn = $('#assist_scanarea_btn');
- var unresolvedList = $('#assist_unresolved_list');
- var fixedList = $('#assist_fixed_list');
- var enableCheckbox = $('#assist_enabled');
-
- var addCustomRuleBtn = $('#assist_add_custom_rule');
- var editCustomRuleBtn = $('#assist_edit_custom_rule');
- var delCustomRuleBtn = $('#assist_del_custom_rule');
-
- this.fixallBtn = function () { return fixallBtn }
- this.clearfixedBtn = function () { return clearfixedBtn }
- this.scanAreaBtn = function () { return scanAreaBtn }
-
- this.unresolvedList = function () { return unresolvedList }
- this.fixedList = function () { return fixedList }
-
- this.enableCheckbox = function () { return enableCheckbox }
- this.variantRadio = function (value) {
- if (!value) {
- return $('[name=assist_variant]');
- }
-
- return $('[name=assist_variant][value=' + value + ']');
- }
-
- this.addCustomRuleBtn = function () { return addCustomRuleBtn }
- this.editCustomRuleBtn = function () { return editCustomRuleBtn }
- this.delCustomRuleBtn = function () { return delCustomRuleBtn }
- this.customRuleDialog = function (title, params) {
- var deferred = $.Deferred();
-
- if (params) {
- customRuleDialog.find('#oldname').val(params.oldname);
- customRuleDialog.find('#newname').val(params.newname);
- }
-
- customRuleDialog_Ok = function () {
- deferred.resolve({
- oldname: customRuleDialog.find('#oldname').val(),
- newname: customRuleDialog.find('#newname').val(),
- });
- }
-
- customRuleDialog.dialog('option', 'title', title);
- customRuleDialog.dialog('open');
-
- return deferred.promise();
- }
- this.variant = function () {
- return $('[name=assist_variant]:checked')[0].value;
- }
- };
-
- var Application = function (wazeapi) {
- var scaner = new WME_Assist.Scaner(wazeapi);
- var analyzer = new WME_Assist.Analyzer(wazeapi);
-
- var FULL_ZOOM_LEVEL = 5;
-
- var scanForZoom = function (zoom) {
- scaner.scan(wazeapi.map.calculateBounds(), zoom, function (bounds, zoom, data) {
- console.log(data);
- analyzer.analyze(bounds, zoom, data, function (obj, title, reason) {
- ui.addProblem(obj.id, title, action.Select(obj.id, obj.type, obj.center, zoom), function () {
- analyzer.addException(reason, function (id) {
- ui.removeError(id);
- ui.setUnresolvedErrorNum(analyzer.unresolvedErrorNum());
- });
- }, false);
-
- ui.setUnresolvedErrorNum(analyzer.unresolvedErrorNum());
- });
- }, function (progress) {
- ui.setScanProgress(Math.round(progress) + '%');
- });
- }
-
- var fullscan = function () {
- scanForZoom(FULL_ZOOM_LEVEL);
- }
-
- var scan = function () {
- scanForZoom(wazeapi.map.getZoom());
- }
-
- var countryName = function () {
- var id = wazeapi.model.countries.top.id;
- var name = wazeapi.model.countries.objects[id].name;
- return name;
- }
-
- var country = countryName();
-
- var action = new ActionHelper(wazeapi);
- var rules = new Rules(country);
- var ui = new Ui();
-
- analyzer.setRules(rules);
- analyzer.setActionHelper(action);
-
- action.setUi(ui);
-
- analyzer.onExceptionAdd(function (name) {
- ui.addException(name, function (index) {
- if (confirm('Удалить исключение: ' + name + '?')) {
- analyzer.removeException(index);
- }
- });
- });
-
- analyzer.onExceptionDelete(function (index) {
- ui.removeException(index);
- });
-
- // rules.experimental = true;
-
- rules.onAdd(function (rule) {
- ui.addCustomRule(rule.comment);
- });
-
- rules.onEdit(function (index, rule) {
- ui.updateCustomRule(index, rule.comment);
- });
-
- rules.onDelete(function (index) {
- ui.removeCustomRule(index);
- });
-
- wazeapi.model.events.register('mergeend', map, function () {
- var name = countryName();
- if (name != country) {
- rules.onCountryChange(name);
- country = name;
- }
- });
-
- analyzer.loadExceptions();
- rules.load();
-
- this.start = function () {
- ui.enableCheckbox().click(function () {
- if (ui.enableCheckbox().is(':checked')) {
- localStorage.setItem('assist_enabled', true);
- ui.showMainWindow();
-
- info('enabled');
-
- var savedVariant = localStorage.getItem('assist_variant');
- if (savedVariant != null) {
- ui.variantRadio(savedVariant).prop('checked', true);
- analyzer.setVariant(ui.variant());
- }
-
- scan();
- wazeapi.model.events.register('mergeend', map, scan);
- } else {
- localStorage.setItem('assist_enabled', false);
- ui.hideMainWindow();
-
- info('disabled');
-
- wazeapi.model.events.unregister('mergeend', map, scan);
- }
- });
-
- ui.variantRadio().click(function () {
- localStorage.setItem('assist_variant', this.value);
-
- analyzer.setVariant(ui.variant());
- ui.scanAreaBtn().click();
- });
-
- if (localStorage.getItem('assist_enabled') == 'true') {
- ui.enableCheckbox().click();
- }
-
- ui.fixallBtn().click(function () {
- ui.fixallBtn().hide();
- ui.clearfixedBtn().hide();
- ui.scanAreaBtn().hide();
-
- wazeapi.model.events.unregister('mergeend', map, scan);
-
- setTimeout(function () {
- analyzer.fixAll(function (id) {
- ui.setUnresolvedErrorNum(analyzer.unresolvedErrorNum());
- ui.setFixedErrorNum(analyzer.fixedErrorNum());
- ui.moveToFixedList(id);
- }, function () {
- ui.fixallBtn().show();
- ui.clearfixedBtn().show();
- ui.scanAreaBtn().show();
-
- wazeapi.model.events.register('mergeend', map, scan);
- });
- }, 0);
- });
-
- ui.clearfixedBtn().click(function () {
- ui.fixedList().empty();
- });
-
- ui.scanAreaBtn().click(function () {
- ui.fixedList().empty();
- ui.unresolvedList().empty();
-
- analyzer.reset();
-
- ui.setUnresolvedErrorNum(0);
- ui.setFixedErrorNum(0);
-
- fullscan();
- });
-
- ui.addCustomRuleBtn().click(function () {
- ui.customRuleDialog('Add', {
- oldname: '',
- newname: ''
- }).done(function (response) {
- rules.push(response.oldname, response.newname);
- });
- });
-
- ui.editCustomRuleBtn().click(function () {
- var id = ui.selectedCustomRule();
- if (id >= 0) {
- ui.customRuleDialog('Edit', {
- oldname: rules.get(id).oldname,
- newname: rules.get(id).newname
- }).done(function (response) {
- rules.update(id, response.oldname, response.newname);
- });
- } else {
- alert('Правило не выбрано');
- }
- });
-
- ui.delCustomRuleBtn().click(function () {
- var id = ui.selectedCustomRule();
- if (id >= 0) {
- rules.remove(id);
- } else {
- alert('Правило не выбрано');
- }
- });
-
- window.assist = this;
- }
-
- this.renameCity = action.renameCity;
- };
-
- function waitForWaze(done) {
- var wazeapi = getWazeApi();
-
- // Does not get jQuery.ui
- // Relies on WME Toolbox plugin
- if (wazeapi === null || !jQuery.ui) {
- console.log("WME ASSIST: waiting for Waze");
- setTimeout(function () {
- waitForWaze(done);
- }, 500);
- return;
- }
-
- done(wazeapi);
- }
-
- function getByAttr(obj, attr) {
- return obj.getByAttributes().filter(function (e) {
- for (var key in attr) {
- if (e.attributes[key] != attr[key]) {
- return false;
- }
- }
-
- return true;
- });
- }
-
- waitForWaze(function (wazeapi) {
- var app = new Application(wazeapi);
- app.start();
- });
- }
-
- run_wme_assist();