Scripts discussion (1)

Discuss and announce AkelPad plugins
  • Author
  • Message
Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

VladSh wrote:C однострочными коментариями ведь работает!
Я про
// коммент
и
/*
тоже
коммент
*/
Чтобы её восстановить, её нужно каждый раз пересчитывать, т.к. символы добавляются/убираются.
Ну, именно это-то трудностей особых не вызывает. Просто не вижу смысла этим заниматься, пока главная сложность во взаимодействии с AkelPad'ом. Я к тому, что
Тогда надо использовать GetFirstVisibleChar.js, но мне с этим реально лень было заморачиваться..
И на это я смотрел...
Т.е., я так понимаю, мы можем только сделать

Code: Select all

AkelPad.SetSel(selStart, selEnd);
И при этом потеряем исходную позицию курсора. И перейдем от неудобного дрыганья к не менее неудобному убегающему курсору. Или я что-то упускаю?

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Infocatcher wrote:Я про
// коммент
У меня скрипт в для однострочного коммента строке работает так - выделяешь текст и получается /* выделенный текст */
В принципе можно добавить в мой скрипт строку - если нет выделения, то просто ставить перед строкой //, но проблема возникнет при снятии, т.е. тогда снимать такие комментарии нужно будет вручную.
Infocatcher wrote:Т.е., я так понимаю, мы можем только сделать

Code: Select all

AkelPad.SetSel(selStart, selEnd);
И при этом потеряем исходную позицию курсора. И перейдем от неудобного дрыганья к не менее неудобному убегающему курсору. Или я что-то упускаю?
Мы сначала можем запомнить "позицию окна", т.е. позицию первого видимого символа в окне - в отдельных переменных. Потом мы можем запомнить текущую позицию курсора для перерасчёта - у меня они сохраняются в "глобальных переменных".
Потом можем выполнять какие-то действия.
После всего (и после замены выделения новым текстом) мы можем восстановить положение окна установив курсор в позицию, которая соответствовала первому видимому символу в окне до внесения изменений. Правда как потом установить курсор в первоначальную позицию и чтобы окно опять не сдвинулось, я не знаю; но это всё уже мелочи жизни :)


У меня вот к Вам предложение - Вы хорошо соображаете в RegExp'ах, может сможете реализовать одну штуку.. у меня никак не получается. :D

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

VladSh wrote:если нет выделения, то просто ставить перед строкой //, но проблема возникнет при снятии, т.е. тогда снимать такие комментарии нужно будет вручную.
Ну, снятие таких комментов реализуется довольно просто (если не пытаться учитывать, что «///» – тоже коммент, а также штуки вроде var re = /^http:\/\//).
Я, если нет выделения, делаю так:
1) пытаюсь найти слева от позиции курсора «/*» и «*/»;
2) ищу справа «/*» и «*/»;
3) если комментирование найдено (наличие и правильная очередность «скобок»), удаляю его и выхожу из скрипта.
4) если возможны комментарии вида «//», получаю текущую строку («\n...\n»);
5) ищу в строке комментарий, если есть – выхожу из скрипта (в этом месте у меня был один баг – в районе 106-107-й строк – исправил).

Т.е. у меня проблема в том, что для таких манипуляций мне требуется получать весь текст – со всеми вытекающими вышеописанными траблами.
VladSh wrote:После всего (и после замены выделения новым текстом) мы можем восстановить положение окна установив курсор в позицию, которая соответствовала первому видимому символу в окне до внесения изменений. Правда как потом установить курсор в первоначальную позицию и чтобы окно опять не сдвинулось, я не знаю; но это всё уже мелочи жизни :)
Ну так я и сказал, что мы убегающий курсор получим... Но сделать все же попробую – есть у меня такое подозрение, что это получше дрыганья будет.
VladSh wrote:У меня вот к Вам предложение - Вы хорошо соображаете в RegExp'ах, может сможете реализовать одну штуку.. у меня никак не получается. :D
Ну, не так, чтобы очень уж хорошо... Но посмотреть могу. :)

P.S. И скрипт для вставки даты: insertDate.js. Изначально была вот такая штука (плюс ie_fix.js) для создания часиков на HTML-страничках.
Например,

Code: Select all

var date = deteServ.get("<day>, <date>.<month>.<fullYear>, <hours>:<minutes>", ["вс", "пн", "вт", "ср", "чт", "пт", "сб"]);
var date = deteServ.get(); // будут использованы deteServ.gDateTemplate и deteServ.gDays
Last edited by Infocatcher on Tue May 06, 2008 5:41 pm, edited 1 time in total.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Infocatcher wrote:И скрипт для вставки даты: ...
Вы вместо <month> специально <momth> во всех скриптах поставили? :D
А вообще стиль написания мне очень понравился, правда с моим опытом не всё явно, но чувствуется серьёзный кодер! 8)

Infocatcher wrote:
VladSh wrote:У меня вот к Вам предложение - Вы хорошо соображаете в RegExp'ах, может сможете реализовать одну штуку.. у меня никак не получается. :D
Ну, не так, чтобы очень уж хорошо... Но посмотреть могу. :)
Задача такая - хотелось написать скриптец, который преобразовывает текст в соответствиями с правилами пунктуации.
Часто в инете текст написан как попало... - очень утомительно читать.
Некоторые правила:
1. После ".", "!", "?", ",", ";" должен идти пробел (очень многие личности пишут последующие слова слитно с символом окончания предложения - это бесит больше всего!).
2. Пробел должен быть один; т.е. если внутри предложения, да и за знаками пунктуации несколько пробелов, то преобразовывать к одному.
3. В многоточии не вставлять пробел после каждой из точек (между точками).
4. В многоточии (а также в "!!!" и "???") должно быть 3 точки (иногда их пишут целую кучу); если поставлено 2, то оставлять без изменения, т.е. 2.
5. Убирать множественные символы ",", ";", оставлять один.
6. Можно ещё после символов ".", "!", "?" и после пробела переводить букву начала предложения в верхний регистр.

Что-то вроде этого. :D Я как-то пытался, но не смог разобраться с этими РегЭкспами. :oops:

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

VladSh wrote:Вы вместо <month> специально <momth> во всех скриптах поставили? :D
:lol: Очепятка (и вредность копипаста)... Исправил.
VladSh wrote:А вообще стиль написания мне очень понравился, правда с моим опытом не всё явно, но чувствуется серьёзный кодер! 8)
Вы мне льстите. Я скорее несерьезный любитель. :)
А если «не всё явно» – спрашивайте. :)
VladSh wrote:Задача такая - хотелось написать скриптец, который преобразовывает текст в соответствиями с правилами пунктуации.
Часто в инете текст написан как попало... - очень утомительно читать.
Гм, в принципе, вполне реализуемо. Более того, я делал такую штуку в расширении для Firefox для вставки BB-кодов на форумах (увы, до ума я тогда эту функцию так и не довел, а переписать так и не собрался). Основная сложность – конструкции вида «;)» (и [сode]...[/сode], но в данном случае это не актуально).
С регистром тоже можно, если в подробности не вдаваться, например (да и многоточия бывают посередине предложений):
А это – как по-вашему я должен был отреагировать? – самое настоящие безобразие!

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Набросал демо-версию: punctuationFixer.js (перезалил в 0:19 по МСК)

Вроде, преобразуется все, кроме регистра... Плюс « - » -> « – » (для собственных нужд :)). Но длинные тире еще надо доработать.
Еще хочу замену кавычек ("" -> «») прикрутить...

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Класно! 8)
Ещё одно правило забыл: 7. Убирать пробелы спереди знаков пунктуации!

И лучше, если бы напротив соотв. куска в коментах расписать правила, например после //. Так было бы лучше разбираться с выражениями RegExp.
Infocatcher wrote:Еще хочу замену кавычек ("" -> «») прикрутить...
Ну это специфическое... мне, например, обычные "" нравятся :)
Infocatcher wrote:А если «не всё явно» – спрашивайте.
Хорошо, поинтересуюсь :D
Буду задавать вопросы и писать свои догадки :)

Code: Select all

String.prototype.trim = function()
Это, я так понял, к стандартному объекту добавляется метод?

Code: Select all

var PunctuationFixer = function(dash)
Это создаём свой типа "класс". Но не понял, что значит

Code: Select all

this.dash = dash;

Code: Select all

PunctuationFixer.prototype = {
	convert: function(txt) {...
Это вроде как добавляем метод в свой класс - описание (сама запись) метода "convert" странноватая.

Только сейчас понял, что

Code: Select all

txt = txt
- и дальше последовательный вызов методов без закрывающей точки с запятой, типа укороченная запись - интересно!

Не понял, как это внутри .replace(...) может идти function(...)?! Тоже никогда не видел такой записи.

Для чего алерт? /Предполагаю, что он был для отладки, просто забыли убрать/.

Интересная запись:

Code: Select all

var text = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
Я о таком не знал.
Но вся равно не до конца понимаю - интуитивно - это "берём весь текст, если выделенного текста нет", но зачем тогда AkelPad.GetSelText() 2 раза?

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

VladSh wrote:Ещё одно правило забыл: 7. Убирать пробелы спереди знаков пунктуации!
Я тоже забыл... Добавил.
VladSh wrote:И лучше, если бы напротив соотв. куска в коментах расписать правила
Угу... Просто регулярные выражения из-за их многозначности не так просто комментировать :D
VladSh wrote:
Infocatcher wrote:Еще хочу замену кавычек ("" -> «») прикрутить...
Ну это специфическое... мне, например, обычные "" нравятся :)
Ну, это можно сделать опциональным.
VladSh wrote:

Code: Select all

String.prototype.trim = function()
Это, я так понял, к стандартному объекту добавляется метод?
Да. Впрочем, это не всегда удобно – надо проверять, строка ли это, перед вызовом, например:

Code: Select all

(str || "").trim(); // скажем, ([1, 2] || "").trim(); выдаст ошибку... 
// или:
if(typeof str == "string") // наиболее корректно
    str.trim();
Пояснение.

Code: Select all

var foo = 1 || 2*3 || 4*5;
Вычисляется только до первого истинного выражения (2*3 и далее вычисляться не будет) и возвращает его (т.е. foo == 1).
Если все части вычисляются в false, то конструкция вернет последнее выражение:

Code: Select all

var foo = null || undefined || ""; // foo == "", более того, foo === "" (например, false == "")
(т.е. === и !== сравнивают без преобразования типов)
VladSh wrote:

Code: Select all

var PunctuationFixer = function(dash)
Это создаём свой типа "класс".
Угу. Это конструктор объектов. Удобно, когда заранее неизвестно, что именно мы должны получить (или если вдобавок нужно за время работы скрипта использовать разные настройки).
VladSh wrote:Но не понял, что значит

Code: Select all

this.dash = dash;
Инициализация. Выполняется при создании экземпляра (new PunctuationFixer("-")).
Т.е. у создаваемого объекта будет свойство dash (this внутри объекта ссылается на сам объект).
VladSh wrote:

Code: Select all

PunctuationFixer.prototype = {
	convert: function(txt) {...
Это вроде как добавляем метод в свой класс - описание (сама запись) метода "convert" странноватая.
Да. У всех экземпляров, созданных через new ... будет этот метод.
Более того, при изменении прототипа новые методы сразу появляются у всех уже созданных экземпляров:

Code: Select all

var text = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
var pf = new PunctuationFixer("\u2013");
PunctuationFixer.prototype.convert = function() {
	alert("Hello!");
};
text = pf.convert(text);
[Урезано, ибо иначе не шлет... Также прошу прощения за кучу сообщений, но иначе никак не удавалось отправить.]
Last edited by Infocatcher on Thu May 08, 2008 9:13 pm, edited 3 times in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

[Гм, либо много тэгов, либо много букв...]
VladSh wrote:Только сейчас понял, что

Code: Select all

txt = txt
- и дальше последовательный вызов методов без закрывающей точки с запятой, типа укороченная запись - интересно!
Ага, все верно – там кучу раз вызывается метод replace.
Собственно, есть приоритеты операций, скажем:

Code: Select all

var d = new Date();
alert(d.getTime());
и

Code: Select all

alert(new Date().getTime());
Короче, но отлаживать удобнее методом «разделяй и властвуй» :D, а не

Code: Select all

AkelPad.ReplaceSel(
	new PunctuationFixer("\u2013").convert(
		AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText()
	)
);
:)
VladSh wrote:Не понял, как это внутри .replace(...) может идти function(...)?! Тоже никогда не видел такой записи.

Code: Select all

var someText = "abc1def2";
someText = someText
    .replace(
        /\d/g, // ищем цифры (g – множественный поиск)
        "~$0~" // $0 будет заменено на часть строки, совпавшую с регулярным выражением
    );         // если бы были скобки, то $1 заменяется на первую скобку (то, что ей соответствует).

Code: Select all

var someText = "abc1def2";
someText = someText
    .replace(
        /\d/g, // ищем цифры (g – множественный поиск)
        function($0) {
        	return "~" + $0 + "~"; // делает то же самое, что и предыдущий пример
        }
    );
VladSh wrote:Для чего алерт? /Предполагаю, что он был для отладки, просто забыли убрать/.
Да, для отладки. Вот когда скрипт будет отлажен (говорил же – демо-версия :)), тогда и удалю.
VladSh wrote:Интересная запись:

Code: Select all

var text = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
Я о таком не знал.
Но вся равно не до конца понимаю - интуитивно - это "берём весь текст, если выделенного текста нет", но зачем тогда AkelPad.GetSelText() 2 раза?
Если есть выделение, то возвращаемое первым AkelPad.GetSelText() вычисляется в true и «хвост» уже не выполняется (true || что_угодно == true).
Если выделения нет, получаем:

Code: Select all

var text = "" || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
"" вычисляется в false, AkelPad.SetSel(0, -1) также возвращает значение, вычисляемое в false, и переменной text присваивается значение, возвращаемое функцией AkelPad.GetSelText(). А поскольку до этого было «выделить все», мы получим весь текст.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

[И – наконец-то! – окончание :)]

P.S. Будем надеяться, ничего не упустил...

P.P.S. Странно, что

Code: Select all

.replace(/\s+$/mg, "")
не работает (должно удалять пробельные символы в конце строк)... Не понятно, какая тогда вообще польза от построчного режима (флаг m). :? (не помню, как в IE, но в нормальных браузерах :D такая штука работает). Я, конечно, понимаю, что JScript – не JavaScript, но это как-то слишком.
Работает только

Code: Select all

.replace(/[ \t]+(\n|\r)/g, "$1");
и

Code: Select all

.replace(/[ \t]+$/mg, "");
[тут не хватало «$», обозначающего конец строки, – исправил, скрипт перезалил]
\s означает [ \t\r\n] (пробел или табуляция, или перевод каретки, или перевод строки, возможно, еще и \v – вертикальная табуляция – лень искать / проверять).

P.P.P.S. Только у меня akelpad.sourceforge.net тормозит? Т.е. ограничения на длину сообщения (или количество тэгов в нем) это одно, а очень низкая скорость соединения с сервером – уже другое...

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

RegExp

Post by Xephon »

Подскажите, а есть ли возможность при замене с помощью регулярных выражений проводить замену на табуляцию или символ новой строки? При подстановке \t в строку замены, замена происходит непосредственно на "\t", а не на табуляцию.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Infocatcher wrote:А это – как по-вашему я должен был отреагировать? – самое настоящие безобразие!
:D Это, наверное, как у меня:
VladSh wrote:У меня вот к Вам предложение - Вы хорошо соображаете в RegExp'ах, может сможете реализовать одну штуку.. у меня никак не получается.
Я так (2 точки) пишу, когда предложение разрывать нельзя, но нужно в одном месте сделать паузу (допустим, мне неудобно просить или я в затруднении). Приходится что-то выдумывать :) Это как пишут букву в верхнем регистре, чтобы показать, куда ударение :D


Sorry, долго отсуствовал - меняю работу.

Практически получился мануал по тонкостям JS - супер! Спасибо!!!

Infocatcher wrote:Пояснение.

Code: Select all

var foo = 1 || 2*3 || 4*5;
Вычисляется только до первого истинного выражения (2*3 и далее вычисляться не будет) и возвращает его (т.е. foo == 1).
Т.е. эта контрукция вычисляестя до 1-го true, но возвращает результат, который = false, находящийся перед первым найденным true?
Infocatcher wrote:(т.е. === и !== сравнивают без преобразования типов)
Ага, это понятно.
А в чём отличие == от = ? Когда-то в старом мануале по C читал, что == - это не "равно", а "соответствует"; и что используется только в конструкциях сравнения. Всё бы ничего, но иногда пишу здесь, в скриптах к AkelPad'у == и ОНО не работает - кажет ошибку, хотя в других, вроде таких же, местах всё нормально... В чём, всё-таки, отличие?
Infocatcher wrote:
VladSh wrote:Интересная запись:

Code: Select all

var text = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
Я о таком не знал.
Но вся равно не до конца понимаю - интуитивно - это "берём весь текст, если выделенного текста нет", но зачем тогда AkelPad.GetSelText() 2 раза?
Если есть выделение, то возвращаемое первым AkelPad.GetSelText() вычисляется в true и «хвост» уже не выполняется (true || что_угодно == true).
О, а здесь получается возвращается весь текст, почему? Ведь в пред. примере он возвращал результат, который false.
Infocatcher wrote:Если выделения нет, получаем:

Code: Select all

var text = "" || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
"" вычисляется в false, AkelPad.SetSel(0, -1) также возвращает значение, вычисляемое в false,
Почему, ведь оно не пустое?
Infocatcher wrote:и переменной text присваивается значение, возвращаемое функцией AkelPad.GetSelText(). А поскольку до этого было «выделить все», мы получим весь текст.
Что-то я совсем запутался... Читал мануал по JS - всё равно ничего не понял :shock:

Кстати очень желательно вкл/откл REDRAW, чтобы текст не дёргался.

Infocatcher wrote:Странно, что

Code: Select all

.replace(/\s+$/mg, "")
не работает (должно удалять пробельные символы в конце строк)... Не понятно, какая тогда вообще польза от построчного режима (флаг m). :? (не помню, как в IE, но в нормальных браузерах :D такая штука работает). Я, конечно, понимаю, что JScript – не JavaScript, но это как-то слишком.
Я в своё время напарился с этим... но так и не понял в чём бока. Хорошо Вам - знаете где и как должно работать :)

Infocatcher wrote:Только у меня akelpad.sourceforge.net тормозит? Т.е. ограничения на длину сообщения (или количество тэгов в нем) это одно, а очень низкая скорость соединения с сервером – уже другое...
У меня это самый дуплёвый сайт, на котором я бываю, иногда вообще даёт отлуп. Сегодня вроде нормально... с чем это связано - непонятно.

Ещё раз большое спасибо за пояснения! 8)

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Практически получился мануал по тонкостям JS - супер! Спасибо!!!
Пожалуйста :)
Как мне однажды ответили, «By helping, I learn».
Только не все это тонкости, ой, не все... :D
Кстати очень желательно вкл/откл REDRAW, чтобы текст не дёргался.
Угу, но позже... А сейчас особо времени нет =(

Т.е. эта контрукция вычисляестя до 1-го true, но возвращает результат, который = false, находящийся перед первым найденным true?
Я думаю, лучше на примерах :)
Проверять можно в браузере в виде
javascript: код
– скопировать в адресную строку и нажать <Enter>.
В глупом IE не работает из about:blank (может, и еще где-то) – только с «нормальных страниц».
В Firefox: Инструменты – Консоль ошибок – Проанализировать (и можно без добавления «javascript:»).

Еще можно в виде
javascript: alert( код );

Code: Select all

1 || 2*3 || 4*5 // 1
0 || 2*3 || 4*5 // 6
0 || 2*0 || 4*5 // 20
"" || false || 4*0 // 0
"Превед!" || alert(0) // "Превед!" (alert не сработает)
alert(0) || "Превед!" // alert(0) и возвращяет "Превед!"

1 && 2*3 && 4*5 // 20
1 && 2*3 && 4*0 // 0
1 && 2*0 && 4*5 // 0
0 && 2*3 && 4*5 // 0
0 && alert(0) // 0 (alert не сработает)
1 && alert(0) // alert(0) и возвращяет undefined от alert'а
(1 && !alert(0)) || (1 && alert(1)) // только alert(0) и возвращает !alert(0) - т.е. true
(0 && !alert(0)) || (1 && alert(1)) // только alert(1) и возвращает alert(1) - т.е. undefined

Пример от Google :D (translate_tools):

Code: Select all

var t = (
	(window.getSelection && window.getSelection()) || // работает в Firefox и Opera
	(document.getSelection && document.getSelection()) || // Konqueror (возможно, еще где-нибудь)
	(document.selection && document.selection.createRange && document.selection.createRange().text) // IE
);
В принципе, внешние скобки ( var t = ( ... ); ) не особо нужны (разве что для старых браузеров).
Т.е. мы вызываем функцию (func()) только если она вычисляется в true.
В случае IE получим:

Code: Select all

var t = (
	(undefined && [i]не_вычисляется[/i]) || // вычисляется в false
	(undefined && [i]не_вычисляется[/i]) || // вычисляется в false
	(document.selection && document.selection.createRange && document.selection.createRange().text)
);
Таким образом, вычисляются последние скобки:
вычисляется_в_true && вычисляется_в_true && document.selection.createRange().text // возвращает document.selection.createRange().text

Code: Select all

var text = AkelPad.GetSelText() || AkelPad.SetSel(0, -1) || AkelPad.GetSelText();
Текст выделен:
var text = "выделенный_текст" || что-то_там; // "выделенный_текст"

Текст не выделен:
var text = "" || undefined || AkelPad.GetSelText(); // AkelPad.GetSelText()

Пояснение: AkelPad.SetSel(0, -1) возвращает нечто, вычисляющееся в false (не проверял, что именно, но, видимо, undefined).
Собственно,
javascript: function test() { var c = 0; } alert(test());
и
javascript: function test() { var c = 0; return c; } alert(test());


P.S. В false вычисляется:
false, undefined, null, 0, "", NaN (Not a Number)
Если ничего не упустил, то все остальное вычисляется в true.
Самый простой способ проверки:
!! выражение // два раза «не»

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

Post by Xephon »

Заметил в 4.0.0 глюк при замене с помощью SearchReplace.js:
Если надо удалить какие-то строки, допустим начинающиеся с буквы "а", то после замены "^a.*?\r" на "" я продолжаю видеть текст, который был удален. Он пропадает только после сворачивания-разворачивания окна.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Xephon
Подобного не наблюдаю. Версия 4.0.0 final?
Locked