Pull to refresh
-2
0
Send message

Спасибо за спонтанный сеанс психоанализа, премного благодарен. Куда чек прислать? :)

Получается, в ваши основные задачи написание кода не входит. Может, в этом причина несогласия?

Почему же, ещё как входит. Просто как-то так получилось, что на меня обычно падают задачи архитектурного плана, которые требуют переворошить половину кода. Все люди разные, кому-то нравится блестящие виджеты полировать, а мне вот по душе выжать соки из набора тестов и сделать, чтобы прогон pull request занимал не час, а полчаса. Или отбить в тряпочку все компоненты, чтобы поймать утечки памяти и заткнуть дырки, чтобы больше не текло. Или добавить поддержку accessibility там, где оно в принципе не росло.


Такие интересные штуки часто требуют глубокой хирургии, когда кода пишешь мало, а тестов дофига много, и потом гоняешь-гоняешь-гоняешь вдоль и поперёк, чтобы не дай бог что не сломалось. Можно на месяц-другой занырнуть и морщить лоб, а потом ещё в кучку всё это собирать. И основная работа идёт именно в браузерах, а IDE тут никаким боком не поможет.


Ну и баги надо фиксить, куда без них. Особенно вызванные вышеупомянутой хирургией, бывает что и пролезают, сколько ни тестируй. :)


Хотя вот иногда и без IDE трудно. Приблуда, которая тесты через WebDriver гоняет, написана на Java, и надо и её тоже переворошить, чтобы результаты стабильнее возвращались. Глаза в кучу...

Перестаньте читать между строк то, чего там не написано.

Не имею такой привычки. Зато сарказм иногда через край капает, прошу прощения, если невзначай обидел. В намерения не входило. :)


PHP я упомянул как пример интерпретируемого языка, которому не нужна стадия компиляции.

Про PHP я не в курсе, не эксперт. Когда-то пришлось несколько месяцев ковырять исходники vBulletin, обе руки отвалились креститься наотмашь — закодировался, завязал и больше не пробовал, тьфу*3.


А вот как минимум про Perl и Python вы глубоко ошибаетесь: это языки динамические, но стадию компиляции они проходят ещё как. Ruby тоже, если мне склероз не изменяет.

Я вам ничего продавать не собираюсь, просто ради исторической справедливости отмечу, что Ext JS 3 и Ext JS 6.5 (последний) — это вещи настолько разные, что похожи только названием.


Поэтому ваши впечатления, хоть и вполне заслуженные, от нынешнего состояния дел весьма оторваны.

Как-то вы так лихо перескочили с фразы "большинство проблем решаются с помощью TS" на "всем TS, я создал, кто не в TS, тот лох".

Ага, ну давайте в риторику тоже поиграем. :) С самого начала:


  1. Товарищ MooooM размашисто, сплеча обзывает небезызвестный фреймворк "монструозным архаизмом". Годный революционный тон, что характерно, без какой-либо аргументации (даёшь отмечание столетия!)
  2. Я выступаю и слегка язвительно парирую тем, что монструозный атавизм, на минуточку, работает и таки вполне неплохо себя чувствует. И давно уж.
  3. Товарищ MooooM невинно изумляется крамольной мысли о том, что кому-то может не хватать блистательных возможностей сиятельного ES6.
  4. Я на пальцах объясняю, что таки нет, не хватает, и таки да, вот по пунктам.
  5. Товарищ MooooM делает разворот на 180 и начинает уповать уже на TypeScript, хотя и несколько менее размашисто, чем в п.1.
  6. Я позволяю себе вежливо усомниться в весомости аргументов в пользу оного TypeScript, из которых я до сих пор слышал только дифирамбы Майкрософту и титанам мысли, решившим уже за нас, сирых и убогих, ну просто все-все-все проблемы, только нужно расписаться вот здесь. Да, кровью, а вы не в курсе что ли?

Так что нет уж, пардоньте. Это не я прыгаю. :) Я просто пытаюсь отбиваться от товарищей, назойливо тыкающих в лицо разными Авторитетными Решениями.


TS вполне себе годный инструмент (хоть это и MS) и со своими задачами справляется ну просто на ура.

Вот, хорошее замечание. Теперь сделайте следующий шаг и допустите, что существуют и другие годные инструменты, справляющиеся со своими задачами так же на ура. :)


Никто никому ничего не продает и уж тем более не гонит на святую сенчу :)

Да богов побойтесь, Сенча ни разу не святая и Ext JS полный говна кусок. Никакого другого мнения вы от меня никогда не услышите. :)


Тут только это, маленький ньюанс… (с) Всё остальное ещё хуже. Я проверял. :(


А вот вы пишите, TS не упал. И я знаю, что вы таки знаете толк в велосипедах :) не пробовали типизацию внедрять какую-нибудь? все-таки на динамике библиотечный код так себе пишется...

Не совсем понимаю спектр вопроса. Лично я пробовал, или команда Ext JS? Лично я начинал когда-то с нацистско-типизированного Паскаля, проходил огонь C и медные трубы C++, так что с идеалами статической типизации в некотором роде знаком. Правда, потом открыл для себя свет исуса прелести полностью динамической типизации, переметнулся на тёмную сторону и взад больше не смотрел. Остальные товарищи по команде тоже пороху нюхали изрядно; начальник наш вообще эксперт по Java, большой поклонник C# и адепт Microsoft по самое не балуйся.


И внедрять пробовали, точнее играться. И с TypeScript, и с другими штуками. Не дают они никаких весомых преимуществ с нашей позиции: мы не можем контролировать среду и код клиентов, а стало быть все наши предположения по поводу того, как код будет использоваться, автоматически идут лесом. Единственный безопасный выход, это оставаться в рамках ES5 и не рыпаться хотя бы до момента, когда старые браузеры отвалятся.


Да чего далеко за примерами ходить, ребята из соседнего отдела уже года три как периодически порываются выкинуть нафиг YUI compressor и заменить его на хвалёный Google Closure compiler. Баги лезут как зелёные черти после пол-литры, аж в глазах рябит. Это мы как бы только о минификации/оптимизации ES5 говорим, да? ES6-то тоже поддерживать надо, но как это сделать, чтобы не сломать весь мир — это как раз и есть вопрос на миллион.

Писать бы, да времени нет. Вот работать надо, а я тут всякую фигню строчу. :)


А по делу, IE нам поддерживать надо и поддерживаем. Даже распоследняя версия фреймворка работает в IE8 и тесты проходят (большей частью). Потому что клиенты требуют, а кто платит $$, тот и прав.


А вот TypeScript нам нафиг не упал по многим разным причинам, в т.ч. по причине наличия своей системы классов, с блекджеком и всем прочим. И я пытаюсь донести простую мысль, что не надо пытаться чесать всех под одну гребёнку и уповать на панацею от абсолютно всех болячек имени доброго и бескорыстного доктора Майкрософта.


Просто ради понимания моей перспективы, представьте что всё наборот, я работаю в Microsoft и жить не могу без TypeScript. Теперь продайте мне ES6 + Flow.

Ох, господи. Ну хорошо, давайте меряться тогда уж.


Моя уверенность строится не на самомнении или религии, а на анализе различных архитектур.

А моя уверенность строится на многолетнем опыте разработки той самой Ext JS, включая практически всю поддержку accessibility: управление фокусированием, поддержку клавиатурной навигации, ARIA, экранных читалок и дисплеев Брайля, и проч. Во всех компонентах, в т.ч. grids, trees, и всём остальном. Фактически в двух разных фреймворках, которые нынче сливаются в один. Которые для поддержки этой accessibility мне пришлось очень глубоко переделывать, иначе ни черта не работало, т.к. изначально всё проектировалось для тыкания мышками или пальчиками.


И суммируя этот многолетний опыт каждодневного бития башкой в бетонную стену, я вам говорю: нельзя просто взять и поместить поля ввода в grid, и всё.


Достаточно? Дальше уже давайте конструктивно.


Так вот, начнём с design pattern. Мы с вами уважаем стандарты, поэтому возьмём за основу WAI-ARIA 1.1 Grid, даже конкретно вот эту секцию: Keyboard interaction, раздел про редактирование данных. Суммируя по-быстрому, нам нужно, чтобы:


  • Enter или F2 на ячейке включало редактирование
  • Enter в режиме редактирования подтверждал изменения
  • Esc в режиме редактирования отменял изменения
  • Tab и Shift-tab перепрыгивали к следующему/предыдущему полю редактирования, не покидая режим редактирования и сохраняя изменения при покидании ячейки

Если вы просто добавите поля ввода в ячейки grid, при этом не озаботившись обработкой событий и состояний, то grid не будет в курсе ни о начале редактирования, ни о конце. Навигация с помощью Tab тоже будет работать только до конца строки с ячейками, и только если не дай бог где-то на странице не случился элемент с tabIndex > 0. Если случился, то пиши пропало — фокус улетел и состояние сломано. Если даже ничего не пропало, то по стандарту рекомендуется заворачивать навигацию с последней ячейки последней строки на первую ячейку первой строки.


Всё это требует от grid быть в курсе, что такое редактирование данных в нём же, и даже более того: активно управлять процессом.


Далее можно упомянуть такие дружественные к разработчику штуки, как возможность определять тип виджета для редактирования ячейки (text input, text area, combo, etc), и картинка усложняется. Далее мы можем вспомнить о том, что данные нужно не просто редактировать в памяти, а ещё неплохо было бы оповещать какие-нибудь сторонние объекты о том, что редактирование записи состоялось. Для этого как минимум нужно понимать, когда у нас редактирование смещается с одной строки на другую, а ещё лучше, иметь возможность организовать транзакционный подход с атомарным подтверждением или отменой изменений. Это тоже чуточку выходит за рамки понимания отдельного поля ввода, даже очень умного. Далее мы можем вспомнить о случаях, когда набор данных не влазит в экран и нужна прокрутка по горизонтали или, ещё хуже, по вертикали с динамической подкачкой данных с сервера. И чтобы табуляция по полям редактирования работала и в этом случае тоже. И что юзеры имеют привычку начать редактировать ячейку, а потом кликнуть мышкой в другую часть страницы и фокус улетает, а это надо отрабатывать без потерь.


И это даже без учёта специфичных браузерных приколов, типа отсутствия нормальных фокусных событий в Firefox (до недавнего времени) или идиотской отработки mousedown на scrollbar в IE. И тем более без учёта возможности использовать в качестве редактора какого-нибудь HtmlEditor на базе iframe, а там с фокусными событиями отдельный многоцветный коленкор. Или вот какой-нибудь клиент решит засунуть в grid что-нибудь типа <input type="file"> и вы с ним на%@#тесь и напляшетесь в IE/Edge, потому что оно на голову больное. Или ещё 100500 таких же козырных, но вполне оправданных случаев (потому что клиенты $$ платят).


Вот берёте все эти конфликтующие требования, смешиваете, помещаете в горшочек и поливаете-удобряете несколько лет, а на выходе как раз получается что-нибудь типа Ext JS grid. С фичами, плагинами, блекджеком и шлюхами. Безумно сложно, но работает и даже вполне быстро для своих возможностей и уровня совместимости со всем, что движется.


Поэтому, я думаю, $mol мог бы вам понравиться, когда нарастит побольше мяса из стандартных компонент.

Безумству храбрых… Но вам всё же проще будет, браузеры с тех пор чуточку попрямее стали. :)

Ваша преданность делу Microsoft достойна уважения, но предположительные причины оной восхитительно сомнительны и чрезмерной весомостью не располагают. Засим позвольте откланяться и не задерживать вас более от дел солидных своей непредусмотрительно бессмысленной светскою беседой.

Это называется "не поддерживается", а не "не работает".

Цитируя любимого домовёнка: а всё одно, всё едино! Если не поддерживается, то по определению не работает. И не будет.


И, вообще-то, давно уже существуют способы обойти это ограничение.

Конечно существуют. Один из них мы как раз и используем, а именно, собственную систему классов, написанную на чистом JavaScript и обратно совместимую вплоть до чёрти куда.


Вот скажите, а у ваших веб-приложений бакэнды есть? И если есть — на чем они написаны?

Есть и на всём, что угодно. Есть на Java и Scala и C#, и на ColdFusion и на PHP, и на всех скриптовых языках, и даже на Go мимо пролетало.


У каждого клиента свои предпочтения по тараканам в голове, я стараюсь не судить людей. /s


Если на PHP или каком-нибудь Perl — то вопросов больше нет.

Ой как я люблю вот такие вот обобщения. Какой-нибудь там PHP или Perl, или там Python или Ruby, несолидные такие штуки, негодные. Круто как, одним махом — эх! Половину индустрии под одну гребёнку и в мусор. Размах!


А если на других языках программирования — то возникает вопрос, почему необходимость компиляции исходников для бакэнда — это давно уже считается нормальным, а то же самое для фронтэнда — ужас-ужас.

Про считается нормальным — это вы вон тем, вышесметённым в мусор расскажите. А потом вас догонят извращенцы, которые на серверной стороне JavaScript пользуют, им тоже расскажите. Потом и я могу свои пять копеек вставить, если желание не отпадёт.


К чему привык — то и читается лучше, это не показатель. Но вот поддержка со стороны IDE у классов ES6 — лучше.

А у меня в носу козявки больше, бе-бе-бе. Аргумент примерно такого же плана.


Лично мне IDE вообще до одного места. Я бОльшую часть времени всё равно у браузера в отладчике живу, ну и в консоль одним глазом посматриваю.

ExtJS уже перестал требовать обмазываться километровыми JSDoc-ами со всех сторон?

Нет, не перестал и вряд ли перестанет. Любая сложная система требует изучения и использования документации, это как бы данность. Когда-нибудь пробовали писать нативное Win32 приложение? DVD с MSDN под руками держать не приходилось? Или томик Advanced Unix Programming вместе с батареей манов, если вы с другой стороны баррикад?


Интуитивно! Изучать не надо! Оно всё само! — кричали возбуждённые пионеры от JavaScript, обкурившиеся передовых псевдо-технологий. Няшная картинка, аж слеза наворачивается.


Я и сам писал раньше свою классовую модель с умными примесями,

Я вам страшную штуку скажу: я тоже писал. Да ладно, чего греха таить, все писали. Ничего страшного, пройдёт, главное не забыть потом руки помыть.


Это именно мелочи. Ну то есть и без них не чувствуешь себя калекой.

Конечно мелочи, ерунда какая. Всего-то полмиллиона строк кода в фреймворке надо будет переписать и протестировать, чтобы перестать чувствовать себя калекой.


Это не стандарт. Даже плохой стандарт лучше его отсутствия. Выражается это в богатстве инструментария, простоте изучения, переноса кода между проектами пр.

Вот именно такие аргументы вы и излагайте вашим клиентам, когда решите сломать поддержку старого API чуть более, чем полностью, ради абстрактных будущих стандартов, которые ещё и не везде работают.


А чтобы не сломать и поддерживать смесь старого с новым, надо малость мозгами пошевелить. Шевелят активно, но тема чуточку непростая и для решения проблем нужно время. Работающий инструментарий планируют в следующей версии.

Конечно смысла не было. Надо на Jasmine 2 обновляться, а не пинать труп 1й версии.

Ваш безграничный оптимизм меня умиляет. Ради мысленного эксперимента попробуйте представить себе масштаб изменений при переходе с псевдо-синхронного API на полностью асинхронное без гарантий выполнения блоков. Теперь шагните чуть дальше и попробуйте представить масштаб трудозатрат на такие изменения. Потом умножьте на 3, потому что проблемы обязательно вылезут.


А теперь сделайте шаг назад, отвлекитесь от всего этого ужаса и попробуйте найти хоть одну вескую причину заменить один глюкавый кусок говна на другой, такой же глюкавый.


Если найдёте, поделитесь пожалуйста. Я не нашёл. Проще было переписать Jasmine, чтобы добавить поддержку их нового API, не теряя старого. Ну и багов вычистить заодно.


Насколько я понял, у вас какая-то странная жутко энтерпрайзная система с очень большим и старым проектом.

Наш проект это Ext JS. :) Большой, старый. Сам фреймворк ещё ничего по сравнению с приложениями, которые на нём построены.


20000 тестов это большая цифра, интересно, как это вообще разрабатывается, и сколько человек это делают.

20k тестов было 3 года назад, текущая цифра ~66,500. Всё это добро прогоняется в 10+ браузерах, что даёт в сумме ~500,000 тестов за каждый прогон PR; в ночных сборках больше. Разрабатывается руками и головой, ничего принципиально нового. В основной команде 10 человек, включая меня.


Может быть, ExtJS там и неплохо смотрится, таких больших проектов я не видел, к счастью

Самый большой, что я видел своими глазами, состоит из примерно ~5,000,000 строк и компилируется в скрипт примерно 30 mb объёмом. Ничего, работает даже в IE8.


Ребята из services хвастались, что бывает и больше.

Вот один, самый зверский. Если мне память не изменяет, то проблема была в некорректной отработке выхода из waitsFor по таймауту, что приводило к неисполнению блоков afterEach. Ну, и понятным последствиям для всех последующих тестов.


Там ещё много чего было, но смысла открывать PR уже не было.

Кроме HTML у нас есть DOM API, которое никто не мешает использовать напрямую. Генерации HTML можно избежать практически на 100%.


А речь идёт о том, что вы как разработчик приложений можете просто писать код JavaScript, который просто исполняется в браузере напрямую, в том же виде, в каком вы его написали. Вы создаёте объекты с конфигурацией, дёргаете методы, реагируете на события, и т.д. Что там происходит с DOM вас не волнует, для этого есть специально обученные белки, знающие всю эту дребедень в деталях.


Насчёт "не приживаются" как бы могу поспорить. Коммерческие решения, приносящие многомиллионные выручки каждый год, чуточку противоречат гладкой картине мироустройства.

Пардон, при чём тут GWT? Я говорил о написании приложений на чистом JavaScript, а не Java.

Могу, конечно. Зачем? Ваш категоричный тон и авторитетные пассы руками два сообщения назад говорят о том, что вы очевидно уверены в своём глубочайшем знании предмета и полной непогрешимости. Т.е. слушать и обмениваться опытом не горите желанием.


А членами меряться мне недосуг, извините.


Хотя если я всё же ошибся и вам действительно интересно, то могу объяснить, почему нельзя просто взять и поместить поля ввода в grid, и всё. С подробностями и путями решения проблем.

Какое отношение IE имеет к ES6 классам?

Простое: они в IE не работают и никогда не будут. А используется этот браузер ещё много где, и использоваться будет ой как долго. Ну, вот реальность жизни такая. Если вы хотите писать ES6 код, то вам придётся использовать инструментарий для переваривания этого кода в ES5.


Классовая система Ext JS появилась задолго до ES6, и работает во всех браузерах. Работает хорошо, протестирована неплохо и сюрпризов не преподносит уже давно.


А вот теперь внимание, вопрос: если всё равно нужно использовать какой-то инструментарий, и он уже есть свой, то имеет ли смысл кидаться впопыхах заменять его на чей-то чужой, просто ради "совместимости с будущим"?


Вот товарищ выше утверждает, что очевидно надо. Потому что журавль в небе очевидно лучше синицы в руках, это же JavaScript ZOMG.


Кстати, держите миксины:

Спасибо за пример, выглядит забавно. Наследуем от функции, которая возвращает функцию-конструктор.


Теперь ответный пример:


Ext.define('FooMixin', {
    extend: 'Ext.Mixin',
    mixinConfig: {
        id: 'foo'
    },
    ...
});

Ext.define('BarMixin', {
    extend: 'Ext.Mixin',
    mixinConfig: {
        id: 'bar'
    },
    ...
});

Ext.define('Baz', {
    extends: 'Quux',
    mixins: [
        'foo',
        'bar',
        ...
    ],
    ...
});

Что лучше читается? А если 10 таких mixin? А если все эти классы не пихать в один файл, а разбить для читаемости на отдельные? Мне-то всё равно, загрузчик зависимости отследит и подкачает в нужной последовательности.


Но это ещё полбеды, я могу про overrides рассказать и как оно с mixins сочетается. Или как можно в mixin вклиниваться до/после метода в основном классе, и для этого не нужно бодаться с контекстом и замыканиями. Или про то, как можно вклиниться в процесс создания класса и декорировать его по необходимости. Или про то, как родительский класс может делать всякие хитрые штуки с наследником. Или ещё что-нибудь интересное, там много.


Но вот беда, вся эта полезность ужасно архаична, сомнительна и немодна. Зато работает хорошо. Пичалька.

HTML — это огромный кусок легаси, который упал нам на хвост, и приходится его везде за собой таскать. Неудобный, устаревший, с кучей костылей.

+100, и мало того: HTML вообще категорически не подходит для создания приложений. Это язык разметки документов, и сколько бы ни тужились W3C, таковым он и останется. Даже WebComponents ситуацию сильно не облегчат, это кривой костыль.


Впрочем, само русло таких мыслей уже крамола. Этак можно додуматься до страшных вещей, вроде написания приложений на чистом JavaScript и использования библиотеки компонентов, которая манипулирует HTML где-то под капотом.


Но постойте, где-то я это уже видел...

А откуда он качает новую версию?

Из репозитория Sencha, конечно.


В любом случае получается какой-то велосипед вместо NPM.

Безусловно. Как вы представляете себе распространение коммерческих продуктов через NPM?


Ссылки сможете показать? Очень интересно посмотреть, без сарказма.

Если интересно и без сарказма, то могу не только показать, но и многое рассказать. Мы на базе Jasmine сделали мощнейший QA инструмент, и кроме собственно юнит- и интеграционных тестов проверяем код на утечки памяти, таймеров, Ajax запросов и т.д. Гайки зажимаем, насколько можем дотянуться. Давно уже подумываю статью про это дело написать, но со временем совсем швах.


К сожалению, в публичной версии Ext JS этой сборки Jasmine пока нет, но есть в коммерческой. Пробную версию Ext JS можно взять здесь: https://www.sencha.com/products/extjs/evaluate/. Можете ввести какой-нибудь левый, но работающий, e-mail адрес, и потом скачать по ссылке. А дальше открывайте ext/test/lib/jasmine.js.


Если вы пишете на Javascript, то писать сборку не на Node.js будет странно.

Абсолютно ничего странного, если вы пишете на JavaScript только клиентскую сторону. А с серверной стороны у вас могут быть какие угодно инструменты, и Node/NPM как раз будут казаться ортогональными и неестественными.


Поэтому гипотетический Node killer будет более-менее совместим с текущей экосистемой.

Это до тех пор, пока какой-нибудь очередной амбициозный пионер не решит заделаться потрясателем ослов основ. А случается это с завидной регулярностью; как говорят буддисты, единственное постоянство — это изменения.

Так или иначе, но возможность переопределить метод у Ext.panel.Panel чтобы show делал совсем не show называется манкипатчингом, каким бы читаемым он не был.

Переопределение существующих классов это monkey patching, не спорю. Но вместо этого вы можете создать свой класс Foo.panel.Panel, унаследовать его от Ext.panel.Panel и переопределить метод show в своём классе. А это уже классическое ООП.


Можно прислать pull-request с фиксом и получить новый релиз в течение 1-2 недель,

Правда? https://github.com/angular/angular: 1,699 issues, 249 pull requests. Дальше смотреть лениво.


Кстати, а как правильно обновлять версии ExtJS?

Cmd и это тоже за вас умеет.


ничего такого, что нельзя сделать на классическом стеке с Webpack, Mocha, Jest и т.п.

Мне очень интересно было бы посмотреть на этот классический стек, который из коробки умеет масштабироваться до полумиллиона юнит-тестов за один прогон. Что-то (многолетний опыт?) мне подсказывает, что не всё тут так радужно, как вам кажется.


Скажем, Mocha я глубоко не копал, а вот Jasmine пришлось переписать практически с нуля. Дважды. Первый раз, чтобы убить титанически мохнатых багов, которые Pivotal фиксить отказались, а второй раз, чтобы стало бегать в разы быстрее. Это к вопросу о качестве модно-хайповых решений.


Но Sencha Cmd нельзя поставить командой npm install sencha-cmd, что сразу ставит на нем жирный минус.

Конечно, всё должно быть модно-молодёжное на npm и Node.js. Если не на Node.js, то автоматически хлам и говно.


Внимание, вопрос: когда завтра появится какой-нибудь "Node killer" и вся ваша инфраструктура в одночасье превратится в хламчинскую тыкву, вы тут же бросите всё и ломанётесь переделывать ради бытия в тренде? А что? Все побежали и я побежал! ©

Забавно, у вас так бомбит, что вы скатываетесь в обыкновенное плоское хамство.

Да зачем же скатываетесь, и не выкатывался даже. Это разве не общепринятый в местных пенатах тон? :)


Вы такой тут опытный эксперт, а все кругом плебеи, голова не жмет? :)

Вы будете смеяться, но таки да, опытный эксперт. :) Про плебеев это вы сами придумали, но мне правда становится чуточку смешно, когда люди начинают спорить со мной о вещах, которые я разрабатывал.


Я вам тут ничего не продаю и ничего доказывать не собираюсь

Взаимно. На том и закончим беседу, если не возражаете. :) Про гугля не переживайте, разберусь как-нибудь. :)

Information

Rating
Does not participate
Registered
Activity