Visual Scripting: будущее уже наступило?

    Эту статью можно рассматривать как обзор-рассуждение на тему визуального программирования. У меня самого больше опыта создания игр на Unity, в Unreal Engine 4 я новичок, поэтому мы будем говорить о самом явлении визуального программирования в целом, а не только о UE.


    Немного истории, или коротко о визуальном программировании


    Мы не будем слишком глубоко уходить в историю, но знайте: визуальные языки как таковые появились очень давно, задолго до того, как увидел свет визуально прекрасный Unreal Blueprint. Проанализировав концепцию визуального программирования более внимательно, мы увидим, что она базируется на парадигме программирования потока данных (dataflow programming). Этот подход был придуман еще в 70-х годах прошлого века. Он заключается в том, что любую программу можно представить в виде орграфа, который отображает поток данных между компонентами программы (по сути, это та же блок-схема). К сожалению, эта парадигма сейчас находится весьма далеко от трендовых течений, но мы можем вернуться к ней в период расцвета визуального программирования.

    Стремление к визуализации алгоритмов у человека зародилось практически одновременно с появлением самого понятия «алгоритм». Оно происходит от естественного желания точнее определить и обозначить свои цели и действия. Кроме того, визуализация помогает лучше постигать задуманную идею и развивать её. Например, иероглифическая запись в пирамиде «Мумифицировать следует вот так…» вполне может считаться визуализацией алгоритма.

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


    За блок-схемами (по крайней мере, в те времена, когда я учился) следовал Pascal, а после него — божественный Delphi. Когда я первый раз увидел Delphi, то был поражен: я мог сделать простую программу, написав 10 строк кода (еще 20 генерировал сам Delphi, но кого это волнует). По сути, Delphi, Visual Basic и другие среды, в которых тогда все активно работали, были первыми массовыми примерами визуального программирования. Да, большую часть кода ты писал сам, но уже можно было прокидывать события, изменять данные и делать интерфейс через удобные UI.


    Наверное, процесс визуального программирования был так притягателен, что люди заболевали кнопкофилией… Между прочим, скрин из программы 2008 года, из статьи "Интерфейс, за который нужно убивать"

    Современная концепция визуального программирования


    Откуда вообще взялось это желание — писать программу без кода? Ну, во-первых, есть мнение, что код — это сложно. Это магия. Это страшные закорючки, в которых без оператора матрицы не разобраться. Но при всем этом программирование — это здорово, престижно и, как правило, приятно с финансовой точки зрения. Отсюда возникает желание быть программистом, которое сталкивается с нежеланием или боязнью писать код (и ленью, куда уж без нее). Поэтому мы всегда ищем инструменты, которые обладают мощным функционалом, но при этом просты в освоении. Этот процесс прослеживается везде: упрощение концепции ПО, упрощение интерфейсов, упрощение веб-сервисов и тому подобное. Кстати, эти же процессы происходят и при эволюции «обычных» языков программирования. Достаточно сравнить COBOL и Python.


    Очевидно, вы выберете правую сторону, по крайней мере, она приятна для глаз

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


    Рассматривая современные средства визуального программирования, необязательно сразу лезть в 2017 год. Есть хороший проект Google Blockly, главная функция которого — образовательная. Небольшой обзор этого языка уже был на Хабре. Blockly очень интересен и отлично подходит для обучения детей программированию, его вполне можно использовать для школьных занятий. Хотя, лично на мой взгляд, «пазловая» система языка не позволяет сразу ощутить все связи вашей программы. Приходится распутывать пазл, как клубок.

    Если брать последние десять лет, то можно отметить довольно много попыток реализовать удобную и эффективную систему визуального программирования, хотя взлететь пока что не удалось ни одной. В любом случае, технический прогресс — на стороне визуальных языков. Мощности и технологии сейчас такие, что вы можете без проблем отрисовывать в браузере любые конструкции, используя сглаживание и разные визуальные эффекты.

    Производительность среднего компьютера тоже увеличилась: сейчас можно без проблем запускать Unity или Unreal Editor и не бояться, что ваш ПК задымится. Эти изменения привели к появлению нового слова в визуальном программировании — Unreal Blueprint.

    Нереальные чертежи


    19 марта 2014 года Unreal Engine 4 вышел в общий доступ и начал свободное распространение для всех желающих с подпиской за 19 $ в месяц. Одна из самых ярких особенностей данной версии движка — это новая среда разработки Blueprint (по-нашему — чертежи).


    Откуда пошло название

    Blueprint – визуальный скриптовый язык, который позволяет написать логику игры без применения языков программирования. По крайней мере, так он себя заявляет. Проект состоит из узлов (nodes), которые соединены линиями передачи данных. Каждый узел может представлять функцию, событие, оператор и так далее.


    Примеры узлов в Blueprint

    Когда я впервые увидел эту систему, я был в восторге. Это выглядело безумно просто и элегантно. При этом программа читалась так же легко, как блок-схема. Можно было, едва взглянув, понять, что делает алгоритм.


    Пример сортировки. Выглядит вполне нормально

    С точки зрения визуального программирования, Blueprint – это великолепно проработанная концепция, которая, вероятно, ускорит развитие данной технологии. При этом до него уже существовали системы типа Unity Playmaker, но, на мой взгляд, они далеко не так хорошо реализованы и служат просто небольшой надстройкой над кодом. В данный момент уже начали появляться другие решения с подобной технологией, например, инструмент для создания SQL-запросов — VAX. В статье автор указал, что идея пришла к нему как раз после знакомства с Blueprint.

    На мой взгляд, создание игр — это та сфера деятельности, где визуальное программирование можно использовать по-настоящему эффективно. Если мы возьмем простую головоломку или аркаду (подчеркиваю: простую), её можно разбить на элементарные геймплейные блоки, которые разработчик переписывает снова и снова в каждом проекте (ну, или просто копирует). Почему бы не создать библиотеку этих элементарных блоков? Именно с ними вы и работаете в Blueprint. Более того, уже сейчас можно разделить функционал между программистами и геймдизайнерами. Одни будут писать начинку для блоков, а другие — соединять их в готовый функционал.

    Будущее еще не наступило...


    При всей приятности Blueprint я не нашел крупных проектов, сделанных исключительно на нем. Есть пара продуктов от небольших команд, и они, по большей части, совсем «мелкие». Судя по всему, в данный момент невозможно создать серьезный проект на «чистом» Blueprint, обязательно нужно будет писать код на С++.

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


    Это, конечно, преувеличение, но поверьте: в Blueprint можно сделать нечто ужасное, что захочется немедленно сжечь. Кроме того, даже хорошо структурированный проект может занимать очень много места и походить на осьминога, который хочет вас сожрать.


    Конечно, весь проект состоит из отдельных классов, но большие алгоритмы все равно выглядят странно и страшно.


    Реализация A* одним из пользователей движка. Взято с форума по Unreal Engine.

    Как вы видите, не все так просто. Игры все еще нельзя делать одним кликанием мышки, программы нельзя писать без кода, но мы постепенно приближаемся к таким технологиям. Главный вопрос — хорошо это или плохо? Так или иначе, будущее еще не наступило.
    Everyday Tools 279,96
    Утилиты на все случаи жизни
    Поделиться публикацией
    Комментарии 53
    • +1
      Т.е. через условно N лет, я смогу нарисовать в специализированной нотации (вроде bpmn или idef) блок схему, например мобильного приложения, и с относительно небольшими проблемами получить более-менее рабочее приложение, так?
      • +1

        Про Oracle Designer видимо никто не слышал.

        • 0
          Как это будет выглядеть в будущем, пока не ясно. Ясно то, что упрощение методов разработки приложений — это глобальный тренд. За остальные средства не скажу, но в Qt последнее время интенсивно разивают это направление.
          • +3
            Как программист С++/Qt, хотел бы поинтересоваться, что вы имеете в виду.
          • 0
            Было же уже. MS Access например имеет (имел) возможность «рисовать» запросы, однако это не убило SQL. Warcraft 3 WorldEdit имеет встроенный скриптовый редактор, который условно можно назвать графическим, однако все профи использовали текстовые jass скрипты, благодаря этому и появилась и развивалась dota как карта, кстати. Matlab simulink, всякие IDE для ПЛИС, все это есть и уже давно, но смерти текстового программирования мы навряд ли дождемся)
            Те же веб-страницы. Я никогда не понимал, как же их можно «писать», когда надо создавать графически! Но нет, css, html живут и здравствуют)
            • 0
              Ничего нового, точно так же спрашивали девелоперы и 30, 20 лет назад, были уже попытки
              Но без кода пока никуда.
              • 0
                Нет, сможете нарисовать сразу само приложение. Код и блок-схемы останутся для оптимизаторов-«низкоуровневиков».
                • 0

                  "Лень изощряться оптимизировать код"? Ну ну. Современные оконные аркады жрут ресурсов больше, чем 3D игры начала 2000-х.


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

                  • +1
                    Ну, после того как люди полностью разучиться )
              • 0
                не работает, это как Excel vs Access — очень быстро наступает потолок, выше которого даже не стоит пытатся прыгнуть
                вот VP для домиков dynamobim.org
                • 0
                  я бы не стал сравнивать эти инструменты. Да, excel можно использовать как БД, но все-таки это не основное его предназначение.
                • +1
                  мне понравилось визуальное проектирование, например
                  • +4
                    Выглядит слишком визуально перегружено даже на максимально простых алгоритмах.
                    • +3
                      Для начала, не стоит смешивать визуальное программирование (когда сам код пишется в виде графических блоков) и графические средства разработки интерфейсов, когда мы расставляем всякие окошки, кнопки и т.п. визуальные элементы и потом привязываем к ним стандартный код.
                      И очень странно в статье о визуальном программировании не упомянуть систему LabView, в которой этот подход реализован еще много лет назад и которая не просто экспериментальный язык, а промышленный стандарт разработки в своей нише уже много лет.
                      • 0
                        ну на самом деле графические средства разработки интерфейсов входят в множество средств визуального программирования. Просто программирование там декларативное, а не императивное, как в том-же labview.
                      • –1
                        ИМХО, визуальные языки в играх «взлетят», когда появятся удобные инструменты для разработки игры находясь внутри игры…

                        Точно так как для бытовых роботов лучший язык будет содержать одну команду «смотри я покажу»… Утрирую конечно. Но суть думаю ясна.

                        IDE должно понимать намерение программиста, и выбирать оптимальный способ его достичь. Желания людей просты. Сложными могут быть методы их реализации.

                        И это совсем не обязательно требует сильный ИИ. Многое можно сделать уже сегодня. Тот же компилятор уже сегодня многое «прячет под капот», разработки. Визуальные языки — еще один шаг, в том же направлении. Каким может быть следующий шаг, я писал уже давно:)
                        • 0
                          Берите шире — не только игры, но целая ОС, которой можно показать что вы от неё хотите :)
                        • +3
                          Фигня это.
                          Я как то игрался с UE4. Скажу сам движок, редактор, наверно лучшее что я видел.
                          Но вот БП это игрушка.
                          Я три недели пытался закодить на БП алгоритм, в итоге написал на С++ за два дня тоже самое.
                          То что в С++ логично и понятно, в БП надо еще понять.
                          Может, потренировавшись пару лет, я научился бы на БП делать чудеса. Но возникает вопрос.
                          А нафига тратить столько времени, если на С++ это еще легче сделать?
                          • +1
                            Потому что Блюпринт для художников, а не программистов. А задача плюсовиков — разрабатывать более сложные и проектно-ориентированные ноды для блюпринта.
                            ЗЫ. В следующий раз буду все комментарии сразу дочитывать, прежде чем свой писать. =\
                            • 0
                              А сколько вы времени потратили на изучение С++?
                              • 0
                                Моя практика программирования на С++, равняется одному лету =)
                                Ну так чтобы без перерывов.
                                Я веб.разработчик, мне С++не нужен. Чисто для развития учил.
                              • 0
                                Скриптование и программирование — разные вещи. В теме уже писали для чего может использоваться, но уж точно не для полноценного создания игры.
                                А вот с тем, что в каком-либо языке программирования что-то «логично и понятно», в отличие от любой скриптовой системы (даже не визуальной), созданной для ускорения разработки простых вещей — я бы поспорил.
                                Программирование вообще подходит только для людей особого склада ума.
                                В целом же, имхо, логичность языков программирования можно приравнять к логичности обычных языков (русский, английский). В них ты только тогда можешь различить логичные цепочки (кое-где), когда у тебя уже большая практика и ты видишь полную картину. В ином же случае ничего логичного в языках нет. Всё базируется на огромном количестве правил, условностей и, кое-где, схожих паттернах этих правил и условностей, но далеко не везде. Ты только тогда знаешь язык, когда знаешь все эти правила. Ну а пользоваться этим сможет (так как правил в программирования намного больше чем в обычных языках), далеко не каждый, как я уже писал.
                                Так что визуальное программирование (скриптование) имеет место быть. Просто цели такого программирования должны быть другими. А обычные языки программирования вообще далеки от идеала, так как зависят от базового языка, который тоже далёк от идеала. При этом сотни тысяч людей продолжают всё это использовать и задумываются о том, как написать настоящий ИИ на таких примитивных языках как сейчас (точно также как и игру на блюпринтах не сделать), вместо того чтобы улучшить базу.
                                Визуальное программирование — это улучшенная база для скриптования.
                              • +2
                                Unreal Blueprint делался прежде всего для той части команды разработчиков игры, которая не умеет программировать, но которой приходится вмешиваться в логику игры.
                                Если разработку изначально програмировать с учётом этого, то можно заметно оптимизировать весь процесс, где далекие от кода коллеги, будут иметь на «входе» нужные им данные и путём простеньких манипуляций над игрово логикой или картинкой, получать желаемые данные на выходе (шейдеры, тексты,
                                ветви сюжета и т.д.)
                                • +4
                                  А если мне приятно левая картинка? тем более сравнение не правильное, слева кусочек инициализации пингпонга на sfml, а справа код какой то функции на blueprint
                                  • +1
                                    да, в конце 90х кричали — визуальное программирование в дельфях это лютый вин!.. годы идут, крик раздаётся, только языки и платформы меняются.
                                    Почему то каким то менеджерам в голову пришло, что накидав блох схемы можно снизить порог вхождения не потеряв в качестве.

                                    П.с. Почему UML не упомянули. шумели же — генерация кода по UML — вот он Грааль программирования.

                                    хотя на всё это есть один простой термин — полнота «языка».
                                    т.е. на С — можно реализовать 99.9% состояний нашей «машины тьюрига». и чем выше абстракция, тем этот процент ниже.
                                    трудно даже представить, каков процент полноты у языка из статьи.

                                    • –2
                                      большие алгоритмы все равно выглядят странно и страшно

                                      Но ведь в Blueprint есть функции. Что мешает разбить алгоритм по частям? По аналогии, вы же не будете писать реализацию A* целиком в main().
                                      • +1
                                        Довелось мне как-то видеть логику выбора двигателя ( 1 из 3 для равномерного распределения ресурса между резервными) на графическом языке программирования от сименс… Так вот это кошмар из разряда «работает — не трогай».
                                        Не все алгоритмы можно упаковать в иерархии по подблокам.
                                        • 0
                                          В main — конечно, нет. Но функцию, которая, собственно, делает A* (а заодно еще DFS, BFS и алгоритм Дейкстры) разбить на более мелкие блоки уже не получится.
                                        • +1
                                          Вот когда появится визуальный способ представления для УЖЕ написанного кода на обычном языке программирования (например C++), тогда это начнёт обретать некоторую популярность и полезность… Ведь по факту это всего лишь представление кода в другом виде, в визуальном виде. Никаких новых возможностей это не вносит, лишь упрощает чтение (хотя как видно не всегда) и восприятие уже написанного. Но вот менять типы представлений для кода, мне видится не плохим началом.
                                          • 0
                                            Выглядит очень похоже на вот этот проект. Возможно, правда, что какие-то фичи пока что не поддержаны, и, возможно, потребуется какой-то препроцессинг кода.
                                          • +1

                                            Тем кто хочет попробовать без установки есть более простой Визуальный язык блок схем Дракон https://drakon-editor.com/ — онлайн версия
                                            https://vk.com/drakon_yazuk — ВК Группа
                                            Очень широко используется не программистами (юристами, врачами, бизнес-тренерами) для составление блок схем (этакий вариант MindMap для алгоритмов), от себя отмечу — очень удобен для разбора юридических договоров.
                                            Единственным ВАЖНЫМ отличием от других редакторов блок-схем является:


                                            1. Блок-схемы составляются по специальным правилам, так чтобы мозгу было легко их понять и исключить задержки/ошибки в понимании (например запрет перекрещивания линий/связей, только вертикальные-горизонтальные связи)
                                            2. Рассово-чистым :) Дракон-Редактором НЕВОЗМОЖНО в принципе составить блок схему нарушающую эргономические правила из п. 1.
                                            3. Технология вполне рабочая, — на нём был написано ПО для Бурана (практически без логических ошибок!), сейчас пишется ПО для МБР Тополь, Синева, Лайнер.
                                            4. Меня удивило что на волне хайпа с Apple и MacBook никто из наших программистов не написал для него огламуренный аналог дракон-редактора для американских юристов менеджеров и врачей.
                                            • 0
                                              Всем доброго дня.
                                              Что-то не упомянули про движок Quest3D от Act-3D, нынешний Lumion для архивиза.
                                              quest3d.com
                                              guest3d.ru/g3d
                                              Который работал с блочным программированием за долго до UE4 и Unity.
                                              Году этак 2007-2008 на нем курсовую работу пилил, без использования кода. Преподаватели были в шоке когда я им исходники показывал.
                                              Сам движок думаю был на уровне unity тех лет. Каждый используемый блок можно было улучшить через lua скрипты. Основной жесткой проблемой был импорт 3d модели, под каждую часть геометрии создавался свой блок. Что создавало трудности при импорте больших проектов. В то время его вроде использовали для интерактивных презентаций, помню был еще какой-то большой проект по истории там еще пирамиды майя можно было смотреть.
                                              • 0
                                                Уже писали (упоминание про LabView), что визуальное программирование ДАВНО используется для программирования промышленных контроллеров: FBD (Function Block Diagram) в STEP 7 от сименса, яркий пример такого языка высокого уровня.

                                                • +1

                                                  Я думаю не приживется даже если выпустят удобный/универсальный инструмент. Сейчас на рынке много всяких редакторов для создания небольших инди-игр, но ими пользуются новички.
                                                  Лично мне доставляет удовольствие писать код самому а не генерировать, конечно не исключаю использование библиотек для решения задач.
                                                  Это как тот порошок который можно развести с водой и выпить вместо еды, но тренд быстро прошел, ведь сам процесс трапезы доставляет куда большего удовольствия.

                                                    • 0
                                                      В Delphi посредством BOLD была реализована MDA впервые в 6-ой версии (2000-2001 гг.) Вот там ровно тоже самое, что описал автор, только для баз данных. И это более 15 лет назад. Но увы, не взлетело. Если бы взлетело, возможно это был бы прорыв, по уровню такой же, как и появления самих дельфей. Кстати, по каким причинам не взлетело? Ровно по таким же: простые вещи делают очень быстро и просто, буквально можно накликать полностью базу. Вещи чуть по сложнее, не говоря о «кровавом интерпрайзе» решались настолько сложно и долго, что проще было вообще эту технологию не использовать. Ну и доков практически не было.
                                                      • +1
                                                        Возник тут интересный вопрос: а как это добро увязать с системами контроля версий? Не просто чтобы было, а так, чтобы прямо удобно смотрелось.
                                                        • 0
                                                          lpwaterhouse
                                                          Там встроеная история изменений в блюпринтах.
                                                          Плюс встроенная поддержка VCS.
                                                          • 0

                                                            Кнопки для взаимодействия с VCS — вижу, но вот они-то как раз и не обязательны. А вот средства для удобного просмотра диффа между двумя ревизиями — по вашей ссылке я не вижу.

                                                            • 0
                                                              Появляется в выпадающем меню при выделении двух блюпринтов.
                                                              • 0
                                                                И как выглядит?
                                                                • 0
                                                                  В моей ссылке на оф. блог есть видео, там всё показывают.
                                                                  Но там старая версия движка. Дома потом ещё гляну, может перенесли менюшку.
                                                                  • 0

                                                                    Там целых 12 минут и нет поиска по видео.

                                                          • +1
                                                            Чего только лоди не придумают, чтобы не учится программировать.
                                                            А во всяких BPM системах как любят мантру «дешевый системный аналитик, не умеющий программировать, сможет создать бизнес-процесс без привлечения программиста».
                                                            По факту,
                                                            1) меньшая гибкость. Проблемы с подключением сторонних библиотек/сервисов. Правда, есть заплатки, что можно свои блоки создавать. Но тогда уже некая гибридная парадигма выходит, совмещаюшая недостатки обоих
                                                            2) неудобства с наследованием, абстракциями
                                                            3) даже с диффами и VCS, меньшая приспособленность к анализу изменений в проекте

                                                            Ps: может, если применить AI, и оставлять ему на откуп тривиальные операции вроде всяких биндингов, банальных преобразований, джойнов, а описывать схемой только желаемый вход и выход, то и будет толк
                                                            • 0
                                                              Вот мучает вопрос, а что мешает изучить основы яп? Ведь по сути, все что заменяет blueprint — учиться за неделю или месяц
                                                              • 0
                                                                Поюзал помнится blueprints из Unreal. окей, для мелочи жить можно. Но когда я порешил сгенерировать галактику не частицами, а на базе множества билбордов с вершинными шейдерами. чтобы прогонять в 1 draw call на C++, я захотел чего-нить сделать с авторами Unreal Engine с их собственной нотацией C++ на базе дефайнов, полностью забив на стилистику стандартной библиотеки и с убожеской документацией, которая отстаёт на несколько релизов и зачастую вообще неактуальна. Плюс по этим макросам IDE в принципе адекватно не работает, реалньные места ошибок найти не то что бы сложно, а вообще невозможно. То в рамках тогоже Unreal Engine вообще не хочется на C++ ничего делать. При этом знаю очень даже хорошо язык.
                                                              • 0
                                                                Кому интересно, habrahabr.ru/post/333750
                                                                • +1
                                                                  Когда-то давным-давно, во времена моего детства, это называлось CASE-системами, и было жутко перспективным… я даже сам писал такие простенькие редакторы, которые транслировали нарисованные по правилам блок-схемы в код программ для своего крооохотного интерпретируемого языка. Visual Basic 6, Win98, было время. CASE-системы нынче почти вымерли, а идея… хм… до сих пор жутко перспективна :)
                                                                  • +1
                                                                    Это всё напоминает мне старенькую шутку про риббон — «Почему Microsoft не добавили риббон в VisualStudio? Потому что они ей пользуются.» Вот и тут хотелось бы увидеть Визуальный ЯП, для которого и компилятор и IDE написаны на этом ЯП.
                                                                    • 0
                                                                      Может кто то проводил тесты код который на писаный вручную и через Visual Scripting, какой быстрее будет работать?
                                                                      • 0
                                                                        Думаю любому понятно, что любая надстройка над нативным кодом, будет заметно медленне его самого.
                                                                        В сухих тестах UE4 Blueprints примерно в 200-300 раз медленне С++. По умолчанию Blueprints работают в виртуальной машине и «дёргают» от туда С++. Но можно включить их принудительную компиляцию в С++. Тогда они будут всего в 6-8 раз медленне.
                                                                        Тут нужно понимать, что на современном железе эта разница в исполнении игровой логики не так критична, т.к. на первом плане стоит скорость рендера картинки.
                                                                      • 0

                                                                        Есть опенсорсная реализация подобной вещи на NodeJS. Разработана IBM, называется Node Red: https://nodered.org/


                                                                        Для написания прототипов или создания ботов — самое оно.

                                                                        • 0

                                                                          Для меня эти ноды — это особый тип интерфейса, который позволяет удобно и элегантно решать множество задач в разных сферах (музыка, 3Д графика и т. д.), и все эти задачи можно объединить в одну категорию — "композиционные". Но программирование — это нечто гораздо более емкое, и я никогда бы не предпочел подобный интерфейс старому доброму коду. Этот "молоток" хорошо подходит только для своих определенных "гвоздей".

                                                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                          Самое читаемое