Архив рубрики: Autodesk

Об отображении нажимаемых клавиш в Autodesk ScreenCast

Autodesk ScreenCast в своей работе использует Snagit, о чём Autodesk информирует пользователя в сообщении, когда просит его подождать некоторое время до окончания публикации видео на сайте. Если записываемый пользователем набор операций выполняется на локальном компьютере, то в конечном видеоролике эти нажатия показываются текстом. Но возможны и другие варианты записи...

Например, возможны ситуации, когда Autodesk ScreenCast установлен на физической машинке, но в видеоролике пользователь, помимо прочего, демонстрирует ещё и некоторый набор действий, выполняемых им на произвольном виртуальном компьютере, работающем под управлением VMWare или Virtual Box. Либо ещё один вариант: часть демонстрируемых операций происходит на удалённом компьютере, к которому выполнено подключение по RDP (при помощи mstsc.exe).

Обозначенные выше два сценария могут возникать тогда, когда на локальной машине установлен Visual Studio, а целевые приложения, под которые пишется код (AutoCAD, Revit, NanoCAD, BricsCAD, SharePoint, и т.д. и т.п.) установлены на отдельных тестовых виртуальных машинках, часть из которых работает на локальном компьютере под управлением VMWare, а др. часть - тоже под управлением VMWare, но на сервере и подключение к ним выполняется по RDP. Т.е. например, когда программист пишет видео, в котором присутствует использование удалённой отладки кода.

В первом из обозначенных выше случаев, информация о нажимаемых клавишах отображаться не будет (от слова "совсем").

Во втором - результат будет почти таким же как и в первом, за исключением того, что в случае нажатия комбинаций клавиш, например Ctrl + A, всё же будет выводиться информация о нажатии функциональной клавиши Ctrl (что, наверняка, будет сбивать зрителя с толку).


Об отображении нажимаемых клавиш в Autodesk ScreenCast

Autodesk ScreenCast в своей работе использует Snagit, о чём Autodesk информирует пользователя в сообщении, когда просит его подождать некоторое время до окончания публикации видео на сайте. Если записываемый пользователем набор операций выполняется на локальном компьютере, то в конечном видеоролике эти нажатия показываются текстом. Но возможны и другие варианты записи...

Например, возможны ситуации, когда Autodesk ScreenCast установлен на физической машинке, но в видеоролике пользователь, помимо прочего, демонстрирует ещё и некоторый набор действий, выполняемых им на произвольном виртуальном компьютере, работающем под управлением VMWare или Virtual Box. Либо ещё один вариант: часть демонстрируемых операций происходит на удалённом компьютере, к которому выполнено подключение по RDP (при помощи mstsc.exe).

Обозначенные выше два сценария могут возникать тогда, когда на локальной машине установлен Visual Studio, а целевые приложения, под которые пишется код (AutoCAD, Revit, NanoCAD, BricsCAD, SharePoint, и т.д. и т.п.) установлены на отдельных тестовых виртуальных машинках, часть из которых работает на локальном компьютере под управлением VMWare, а др. часть - тоже под управлением VMWare, но на сервере и подключение к ним выполняется по RDP. Т.е. например, когда программист пишет видео, в котором присутствует использование удалённой отладки кода.

В первом из обозначенных выше случаев, информация о нажимаемых клавишах отображаться не будет (от слова "совсем").

Во втором - результат будет почти таким же как и в первом, за исключением того, что в случае нажатия комбинаций клавиш, например Ctrl + A, всё же будет выводиться информация о нажатии функциональной клавиши Ctrl (что, наверняка, будет сбивать зрителя с толку).


Об отображении нажимаемых клавиш в Autodesk ScreenCast

Autodesk ScreenCast в своей работе использует Snagit, о чём Autodesk информирует пользователя в сообщении, когда просит его подождать некоторое время до окончания публикации видео на сайте. Если записываемый пользователем набор операций выполняется на локальном компьютере, то в конечном видеоролике эти нажатия показываются текстом. Но возможны и другие варианты записи...

Например, возможны ситуации, когда Autodesk ScreenCast установлен на физической машинке, но в видеоролике пользователь, помимо прочего, демонстрирует ещё и некоторый набор действий, выполняемых им на произвольном виртуальном компьютере, работающем под управлением VMWare или Virtual Box. Либо ещё один вариант: часть демонстрируемых операций происходит на удалённом компьютере, к которому выполнено подключение по RDP (при помощи mstsc.exe).

Обозначенные выше два сценария могут возникать тогда, когда на локальной машине установлен Visual Studio, а целевые приложения, под которые пишется код (AutoCAD, Revit, NanoCAD, BricsCAD, SharePoint, и т.д. и т.п.) установлены на отдельных тестовых виртуальных машинках, часть из которых работает на локальном компьютере под управлением VMWare, а др. часть - тоже под управлением VMWare, но на сервере и подключение к ним выполняется по RDP. Т.е. например, когда программист пишет видео, в котором присутствует использование удалённой отладки кода.

В первом из обозначенных выше случаев, информация о нажимаемых клавишах отображаться не будет (от слова "совсем").

Во втором - результат будет почти таким же как и в первом, за исключением того, что в случае нажатия комбинаций клавиш, например Ctrl + A, всё же будет выводиться информация о нажатии функциональной клавиши Ctrl (что, наверняка, будет сбивать зрителя с толку).


Немного о качестве accoreconsole.exe

Как говорится, страна должна знать своих героев... В данном контексте речь пойдёт о багах, с которыми предстоит столкнуться пользователям утилиты accoreconsole.exe. Ранее я уже писал об этом инструменте здесь. За четыре года уж точно можно было бы выявить очевидные ляпы и исправить их. Однако "можно было бы", не означает, что это "было сделано" в реальности.


Все мы прекрасно помним, что издавна, при запуске acad.exe с ключом /p и указанием нужного профиля, этот профиль, ежели он хранится в ARG-файле, импортируется в реестр и устанавливается текущим. Видимо это было скучно и Autodesk решил разнообразить наши серые будни...

Когда я запускаю accoreconsole.exe для AutoCAD 2015 и 2016 с ключом /p, указывающим нужный профиль, хранящийся в ARG-файле, то в последствии, по завершении сеанса accoreconsole и запуская acad.exe этих версий вижу этот профиль в диалоговом окне на вкладке Options (он же установлен и текущим). Это поведение аналогично тому, которое присутствовало в старых версиях AutoCAD, когда accoreconsole.exe ещё и в помине не было. Идём дальше...

Для AutoCAD 2013 и 2014 в диалоговом окне Options в аналогичной ситуации новый профиль не появляется. 

В AutoCAD 2013 после работы accoreconsole.exe я вижу наличие ветки:
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R19.0\CoreUser\ran\Profiles\
в которой присутствует только запись <<Unnamed Profile>>
Мой профиль не появился.

Подобная картина в AutoCAD 2013 наблюдается и с веткой
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R19.0\ACAD-B001:409\Profiles
там так же присутствует только запись <<Unnamed Profile>>, а профиль, подключаемый мною через ключ /p не появился.

Т.е. при использовании accoreconsole.exe в AutoCAD 2013 указанный мною при помощи ключа /p профиль, подгружаемый из ARG-файла, не сохранился в реестре нигде, насколько я вижу.

АutoCAD 2014 так же не содержит информации о подключавшемся профиле в своей ветке
HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R19.1\ACAD-D001:409\Profiles
присутствует только <<Unnamed Profile>>, как и в AutoCAD 2013.

Во всех др. версиях AutoCAD, отличных от 2013-го, аналогичная подветка CoreUser\ran\Profiles\ вовсе отсутствует и не появляется в т.ч. и после работы accoreconsole.exe.

Т.о. налицо поведение "кто в лес, кто по дрова".

Не будем останавливаться на "достигнутом", пойдём дальше...

AutoCAD 2013-2015 SP1 x64 Enu.


Если консольное окно accoreconsole.exe закрывать путём нажатия соответствующей кнопки в верхнем правом углу консольного приложения, то значение системной переменной FILEDIA, изменённое обозначенной утилитой в ходе своей работы, остаётся равным 0. Т.е. если в дальнейшем запустить acad.exe, то это соответствующим образом отражается на его работе. Но ежели закрывать консольное окно командами _.quit или _.exit, то такая проблема не наблюдается.

Компания Autodesk порекомендовала (не утруждая себя проверкой работоспособности обозначенной рекомендации):  для того, чтобы не портилась системная переменная FILEDIA в AutoCAD (как и другие системные переменные), нужно использовать ключ запуска /isolate <userid>, где userid - произвольное имя.

Однако, как показала практика, не работает и обозначенное выше решение с /isolate:

Autodesk: В DevHelp подтвердили некорректность работы /isolate с AutoCAD 2015 SP2 и 2016 и передали команде инженеров для анализа.

Про более ранние версии видимо постеснялись написать...

Идём далее...

AutoCAD 2013-2015 x64 Enu

Запускаем accoreconsole.exe и загружаем в него некоторую сборку. Смотрим первый скрин.



Меняем ширину консольного окошка (смотрим второй скрин) и перезапускаем accoreconsole.



Снова загружаем ту же самую сборку. Смотрим третий скрин - для 2015-го и 4-й скрин - для 2013-го. 



Как видим, после изменении ширины консольного окна, мусора стало меньше. При этом в 2013-м он вообще исчез - корректно выводит информацию, в то время как 2015-й дублирует каждую строку:



Autodesk: Замечание приняли и передали в работу Eng Team.

Печальная практика показывает, что зачастую это - стандартная отписка. Многие пользователи хорошо помнят о баге с переключением раскладки клавиатуры при помощи Shift + Alt. Для тех, кто переключает раскладку иным способом - почитать о данном баге можно здесь. Кстати, этот баг, как и многие другие, не устранён до сих пор! Кстати, до сих пор (т.е. и в AutoCAD 2016) присутствует баг, о котором я когда-то писал здесь. Причём второй из них исправляется всего парой строчек кода... Если даже такие простые (но важные) исправления Autodesk не удосуживается делать, то что можно говорить о чём-то более серьёзном?

Все обозначенные выше баги выявляются первым же запуском accoreconsole.exe. Компания Autodesk не тестирует своё программное обеспечение: откомпилировалось, значит можно отправлять на продажу, а юзерам, столкнувшимся с багами, нужно рекомендовать покупку "более новой версии", в которой может быть что-то будет исправлено.

То, что подобным качеством ПО они позорят себя, в компании Autodesk, к сожалению, себя не "грузят", т.к. практика показывает, что главное для них (как и для многих др. современных компаний) - продать (т.е. втюхать), а думать о качестве - это не современно. Покупатели ПО попутно являются и бесплатными тестерами - чем не отличное решение? А то, что они не только тестируют, но и платят деньги за это ПО - так это и вдвойне хорошо: иметь бесплатных тестеров, которые к тому же ещё и немалые деньги платят компании, чей софт тестируют - мечта любой "современной" компании. Потом можно выборочно устранять пару багов (пофиг, что попутно добавится ещё пара-тройка) и попутно прикрутить пару бантиков, вроде глянцевых кнопочек, после чего можно презентовать новую версию... Неплохо устроились ребята... Чувство совести, похоже, им не ведомо к сожалению (имхо).

Autodesk и санкции против России

Заявление генерального директора Autodesk в России и СНГ Алексея Рыжова заставляет серьёзно задуматься о том, какие "сюрпризы" могут неожиданно свалиться нам на голову, поскольку и мы являемся пользователями AutoCAD... На всякий случай продублирую содержимое обозначенного заявления, т.к. не исключено, что со временем оно может исчезнуть с сайта Autodesk, или подвергнуться редактированию (политика ведь и всё такое...).

Итак, официальное письмо генерального директора Autodesk в России и СНГ Алексея Рыжова, адресованное клиентам, пользующимся продуктами компании Autodesk, а так же её технической поддержкой:

Уважаемые коллеги,
После введения санкций США в некоторых российских средствах массовой информации распространилось мнение, что компания Autodesk вводит собственные санкции в отношении ряда российских компаний, произвольно ограничивая доступ к своим продуктам. Я хотел бы опровергнуть эту информацию, разъяснить ситуацию и высказать некоторые мысли по данному вопросу:
  1. То, что Autodesk вводит санкции против России – это миф. Вопросы «вводит ли Autodesk санкции» или «поддерживает ли Autodesk санкции» неверны по своей сути. Как известно, штаб-квартира Autodesk, как и у многих ведущих ИТ-компаний, находится в США. Поэтому если правительство США вводит торговые санкции, действующее законодательство запрещает нам осуществлять поставки для компаний, на которые эти санкции распространяются. По этой причине у нас нет другого выхода, кроме как приостановить поставки для компаний из санкционного списка. Сегодня поставки этим компаниям технически невозможны из-за требований экспортного контроля.

    На сегодняшний день санкции коснулись только небольшого числа клиентов Autodesk. Тем не менее, мы сожалеем о тех негативных последствиях, с которыми столкнулись и эти компании, и мы сами. Для Autodesk эта ситуация является форс-мажором в точно такой же мере, как для других компаний со штаб-квартирой в Европе или США.
  2. ПО Autodesk является для наших клиентов средством производства, и отказ от него может оказаться для них довольно болезненным. Поэтому мы посчитали важным предупредить об ограничении поставок заранее, что и сделали письмом для наших партнеров, которое попало в СМИ. Мы сочли необходимым в сложившейся ситуации работать максимально открыто и заблаговременно сообщить нашим контрагентам о ситуации, вместо того, чтобы блокировать транзакции по факту заказа.
  3. Мы готовы предоставить консультации любым клиентам, кто сомневается, распространяются ли на их компании ограничение поставок.
  4. Выскажу и некоторые свои соображения об импортозамещении и дальнейшем развитии рынка САПР в России. На мой взгляд, отечественные разработки в области САПР должны развиваться вне зависимости от внешнеполитической ситуации. Однако только открытый, конкурентный рынок может помочь клиентам выбрать лучшие инструменты для решения насущных задач, а всем компаниям-поставщикам инвестировать в развитие и разработку новых ИТ-решений.

    Так Autodesk вкладывает в исследования и разработку более 600 миллионов долларов ежегодно (более четверти годового оборота). В то же время мы активно поддерживаем российских разработчиков в рамках инициативы Autodesk Developer Network (ADN). Наши ADN-партнеры, на мой взгляд, формируют наиболее перспективный, развивающийся сегмент на рынке российского программного обеспечения для проектирования.
  5. Успех нашего бизнеса напрямую зависит от развития промышленности и строительства в России. Поэтому мы заинтересованы в стабильности как американской, так и российской экономики. Российский рынок – важная часть глобального бизнеса Autodesk. Autodesk работает здесь с 1989 года, и за это время приобрела более десяти тысяч корпоративных клиентов и миллионы пользователей домашних приложений. В России компания осуществляет многомиллионные инвестиции в сферу образования, а также в проекты, направленные на развитие инноваций, решение социальных и экологических проблем.
  6. Мы продолжаем развивать бизнес в России, и вы сможете сами услышать о наших программах, предложениях и инвестициях на ежегодной конференции Autodesk University, которая пройдет 1-2 октября 2014 г. в Москве.
 
С уважением,
Алексей Рыжов
Генеральный директор Autodesk в России и СНГ


 На мой взгляд, любому здравомыслящему человеку совершенно очевидно, что конечному пользователю не важно, кто именно перекрывает ему кислород - компания Autodesk или же "дядя Обама": важен конечный результат. Отлично понимает это и Алексей Рыжов (было бы очень странно, если бы не понимал). А тут ещё вроде как наша компания выиграла тендер на проектирование моста через Керченский пролив (всё что касается Крыма, как хорошо известно, вызывает у США сильный зуд в нижней части туловища). Не удивлюсь, если американский "список прокажённых" вдруг пополнится наименованием нашей организации. И дело здесь не в Autodesk - по аналогии будут поступать и др. зарубежные компании (пусть даже и вынужденно).

Похоже на то, что нужно постепенно как-то уходить от использования программного обеспечения зарубежных компаний, выискивая подходящие под наши нужны российские аналоги. Из российских разработчиков САПР мне известна только компания Нанософт, хотя и тут ситуация достаточно сложная: nanoCAD спроектирован на основе платформы Teigha компании ODA. Несмотря на то, что в ODA работают и российские программисты, но факт остаётся фактом - ODA является зарубежной компанией, что не может не наводить на некоторые невесёлые размышления...

Что же касается nanoCAD, то версия 6, продемонстрированная сегодня на конференции, меня приятно удивила. Впечатлил и продемонстрированный nanoCAD СПДС. Продукты Нанософт вообще динамически развиваются. То, каким образом и с какой скоростью эта компания реагирует на пожелания и замечания пользователей, так же настраивает на позитивный лад (Autodesk, по моему опыту, в этом отношении нервно курит в сторонке). Да, в ряде достаточно важных вопросов nanoCAD всё ещё отстаёт от AutoCAD, но в то же время в ряде других, не всегда менее важных тем, он уже оставил AutoCAD далеко позади.

Я задумался над тем, чтобы установить триальную версию nanoCAD СПДС одному из сотрудников, занимающихся нормоконтролем, а так же нескольким проектировщикам с тем, чтобы они в течении месяца поработали в nanoCAD вместо AutoCAD. Правда сначала нужно будет научить их грамотно, полноценно использовать nanoCAD СПДС (скорее всего посредством курсов от Нанософт). Затем, по окончанию триального периода, будем анализировать результаты и думать, взвешивая все плюсы и минусы, выявленные в процессе работы... К сожалению, насколько я понял, в настоящее время компания не предоставляет средств электронной проверки чертежей, подобных Design Review, но хочется верить, что со временем и эта проблема будет решена.

Баг BlockTableRecord.HasAttributeDefinitions.

На форуме adn-cis.org недавно появилось сообщение о том, что BlockTableRecord.HasAttributeDefinitions возвращает неверное значение для тех записей, из которых определения атрибутов на самом деле были ранее удалены. Наличие данного бага было подтверждено и заявка отправлена в ADN. Соответственно, придётся писать свою, корректную реализацию данного функционала.

По обозначенной выше ссылке проблема обозначалась следующим образом (отредактированная цитата):
1. Создаем определение блока c одним произвольным объектом (например с полилинией).
2. Добавляем определение атрибута в наше 
определение блока.
3. Видим, что свойство BlockTableRecord.HasAttributeDefinitions равно true, как и полагается.
4. Итерацией проходим по объектам нашей BlockTableRecord и видим, что их два: полилиния и определение атрибута.
5. Теперь удаляем ранее добавленное определение атрибута.
6.Итерацией проходим по объектам нашей BlockTableRecord и видим лишь один объект (как и полагается): полилинию.
7. Теперь смотрим свойство BlockTableRecord.HasAttributeDefinitions и видим, что оно равно true вместо ожидаемого false.
Свою версию обозначенного выше функционала реализуем в виде метода расширения, которому присвоим имя HasAttDefs:

   1:  // BlockTableRecordExtentions.cs
   2:  // © Andrey Bushman, 2014
   3:  // Extention methods for the BlockTableRecord class
   4:  using System;
   5:  using System.Collections.Generic;
   6:  using System.Linq;
   7:  using System.Text;
   8:   
   9:  /// В целях переносимости кода и отсутствия в псевдонимах наименований
  10:  /// конкретного САПР, целесообразней формировать псевдонимы в 
  11:  /// нейтральной форме, например: cad, вместо acad, Ap вместо AcAp, Db 
  12:  /// вместо AcDb и т.д. Построенная таким способом система наименований
  13:  /// будет более удобной программисту, портирующему ваш код под другую 
  14:  /// САПР. Ниже приведён вариант определений таких нейтральных псевдонимов
  15:  /// под некоторый набор различных САПР.
  16:  #if AUTOCAD
  17:  using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  18:  using Ap = Autodesk.AutoCAD.ApplicationServices;
  19:  using Db = Autodesk.AutoCAD.DatabaseServices;
  20:  using Ed = Autodesk.AutoCAD.EditorInput;
  21:  using Gm = Autodesk.AutoCAD.Geometry;
  22:  using Rt = Autodesk.AutoCAD.Runtime;
  23:  #elif BRICSCAD
  24:  using cad = Bricscad.ApplicationServices.Application;
  25:  using Ap = Bricscad.ApplicationServices;
  26:  using Db = Teigha.DatabaseServices;
  27:  using Ed = Bricscad.EditorInput;
  28:  using Gm = Teigha.Geometry;
  29:  using Rt = Bricscad.Runtime;
  30:  #elif NANOCAD
  31:  using cad = HostMgd.ApplicationServices.Application;
  32:  using Ap = HostMgd.ApplicationServices;
  33:  using Db = Teigha.DatabaseServices;
  34:  using Ed = HostMgd.EditorInput;
  35:  using Gm = Teigha.Geometry;
  36:  using Rt = Teigha.Runtime; 
  37:  #endif
  38:   
  39:  namespace Bushman.CAD.Extentions {
  40:      /// <summary>
  41:      /// Методы расширения для экземпляров класса BlockTableRecord
  42:      /// </summary>
  43:      public static class BlockTableRecordExtentions {
  44:          /// <summary>
  45:          /// Данный метод проверяет наличие экземпляров <c>Db.AttributeDefinition</c> в
  46:          /// составе объекта <c>BlockTableRecord</c> и представляет собой замену методу
  47:          /// <c>BlockTableRecord.HasAttributeDefinitions</c>, который реализован 
  48:          /// неверно - в виду этого и возникла необходимость написать корректный вариант
  49:          /// реализации. Информация о некорректной работе 
  50:          /// <c>BlockTableRecord.HasAttributeDefinitions</c> была подтверждена и
  51:          /// отправлена в ADN. Подробности на странице 
  52:          /// http://adn-cis.org/forum/index.php?topic=625.0
  53:          /// </summary>
  54:          /// <param name="btr">экземпляр <c>BlockTableRecord</c>, подлежащий проверке.</param>
  55:          /// <returns>true - в составе указанного объекта <c>BlockTableRecord</c>
  56:          /// содержатся элементы <c>Db.AttributeDefinition</c>, иначе - false.</returns>
  57:          public static Boolean HasAttDefs(this Db.BlockTableRecord btr) {
  58:              String name = Rt.RXClass.GetClass(typeof(Db.AttributeDefinition)).Name;
  59:              return btr.Cast<Db.ObjectId>().Any(n => !n.IsNull && n.IsValid
  60:                  && !n.IsErased && !n.IsEffectivelyErased && String.Equals(
  61:                  n.ObjectClass.Name, name, StringComparison.InvariantCulture));
  62:          }
  63:   
  64:  #if DEBUG
  65:          /// <summary>
  66:          /// Команда, демонструрующая некорректную работу 
  67:          /// <c>BlockTableRecord.HasAttributeDefinitions</c>
  68:          /// и корректность работы метода <c>HasAttDefs</c>.
  69:          /// За основу взят код 
  70:          /// http://adn-cis.org/forum/index.php?topic=625.msg2168#msg2168
  71:          /// </summary>
  72:          [Rt.CommandMethod("TestBlock")]
  73:          public static void TestBlock() {
  74:              Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  75:              Ed.Editor ed = doc.Editor;
  76:              Ed.PromptResult res = ed.GetString("nType name of block: ");
  77:              if (res.Status != Ed.PromptStatus.OK) return;
  78:              using (Db.Transaction tr = doc.TransactionManager.StartTransaction()) {
  79:                  Db.BlockTable bt = tr.GetObject(doc.Database.BlockTableId,
  80:                      Db.OpenMode.ForRead) as Db.BlockTable;
  81:                  if (bt != null) {
  82:                      if (bt.Has(res.StringResult)) {
  83:                          Db.BlockTableRecord btr = tr.GetObject(bt[res.StringResult],
  84:                              Db.OpenMode.ForRead) as Db.BlockTableRecord;
  85:                          if (btr != null) {
  86:                              ed.WriteMessage("nAutodesk: Block {0} has{1} attribute definitions.n",
  87:                                  res.StringResult, btr.HasAttributeDefinitions ? "" : " not");
  88:                              // Мною добавлена эта строка кода:
  89:                              ed.WriteMessage("nBushman: Block {0} has{1} attribute definitions.n",
  90:                                  res.StringResult, btr.HasAttDefs() ? "" : " not");
  91:                          }
  92:                      }
  93:                      else {
  94:                          ed.WriteMessage("nBlock {0} not found", res.StringResult);
  95:                      }
  96:                  }
  97:                  tr.Commit();
  98:              }
  99:          }
 100:  #endif
 101:      }
 102:  }

Последовательно выполняем все шаги, демонстрирующие появление проблемы и запускаем команду TestBlock:


Как видим - наша реализация работает корректно.