LINUX.ORG.RU
ФорумTalks

Я вляпался в js, подскажите лопату и редактор!

 , ,


1

1

Сабж. Нет соплей про то какое говно nodejs я писать не буду, про это нам может рассказать EnterpriseMobility.

Но у меня есть пахучая куча js кода из reactjs и сопуствующих тухнологий и... смущает то что там js мягко говоря странно отличается от того что я привык видеть:

 render: function() {
    return (
      <ul className="user-list">
// вот этот вот хочется чтобы подсвечивалось и рефакторилось 
        {this.state.users.map(function(user) {
          return (
            <li key={user.id}>
              <Link to="{'/users/' + user.id}">{user.name}</Link>
            </li>
          );
        })}
      </ul>
    );
  }

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

Deleted
Ответ на: комментарий от znenyegvkby

Как хочется видеть синьёрам - тут вообще не при чём) Будь моя воля - я бы всё писал на смеси джавы с хашкелем. Настоящая проблема - как обеспечить взаимодействие между дизайнерами, верстальщиками и программистами API компонентов.

Ты не заставишь дизайнера думать логически и раскладывать картинку на компоненты, для него UI выглядит как серия цельных скриншотов, картин размером на весь экран. Или даже - несколько экранов, целиком воркфлоу. Уже одно то, что из неё надо вычленять однотипные кнопочки - доставляет творческому человеку боль. Результат работы типичного дизайнера интерфейса - это PSD/PDF/PPT с виженом экрана или воркфлоу.

Формировать их в HTML дизайнер откажется. Поэтому для этого есть специальный верстальщик. Но этот верстальщик стал именно верстальщиком именно по той причине, что программирование ему в хрен не вперлось (или более печальный вариант - у него недостаточный IQ для программирования). Вне зависимости от причины, работать с JS он не сможет. Зато он сможет «оцифровать» изначальную растровую картинку в HTML код. Иногда он может разрезать исходную картинку на компоненты, иногда - нет (тогда получается верстка целкиом всей страницы на HTML)

Дальше к продукту работы дизайнеров и верстальщиков подключается программист интеграции компонентов. Если верстальщик не справился разрезать HTML на компоненты, он это делает. И далее как можно менее навязчиво пытается напрямую использовать готовую вёрстку, подключить её к экстеншен поинтам фреймворка (какой бы он ни был). На выходе получаются заготовки компонентов типа «кнопка», «прогрессбар»

Дальше подключаются программист компонентов и собственно пишет для них код в движке

Самое интересное случается, когда дизайнеры ОБНОВЛЯЮТ свои картинки интерфейса. Тепреь нужно каким-то образом протолкнуть изменения по всей цепочке. Протолкнуть так, чтобы не пришлось переделывать заново всю работу и перерисовывать все компоненты.

На этом этапе и выясняется, чего стоят твои решения касательно форматов данных, архитектуры фреймворка, и так далее. Например, если ты сделал хранение UI в каком-нибудь хипстерском недо-HTML или упаси бох в JSON, верстальщик никогда не сможет их наверстать. Как отлаживать HTML он знает, а как отлаживать JSON который отбражается самопальным внешним просмотровщиком - хрен знает. (возможно, он даже не сможет поднять среду для запуска этого самопального просмотровщика, ибо там будет сложнейший стек современного руби или ынтерпрайз джавы).

Так что прежде чем кричать «JSX говно» или «FreeMarker говно», я бы вначале разобрался, какие болезненные решения пришлось сделать, прежде чем дойти именно до такой реализации

stevejobs ★★★★☆
()
Ответ на: комментарий от x3al

Мой «велосипед» всего лишь показывает что писать каскад функций создающих и распихивающих друг в джруга элементы совсем не обязательно. Динамический/реюзабельный элемент (в этом примере) у нас создан и положен в переменную rootElement, собирать его статические внутренности таким же способом не нужно и вредно.

Но это касается естественно только все xml/html, кнопки браузеров, нативные элементы окон gtk или ios естественно реализуемы только через API функции (хотя при большом желании и умении можно и им похожее реализовать)б поэтому я темы фреймворков вообще касаться не хочу.

А насчет innerHTML вопрос довольно спорный, накатал вот небольшой тест сравнения трех разных способов (jsperf закрыт на ремонт, по этому вариант для вебконсоли):

_test(innerHTML);
_test(insertAdjacentHTML);
_test(createElement);

function _test(fn) {
   var c = 10000,
       ret = fn.toString(),
       name = ret.slice(9, ret.indexOf('('));
       
   console.time(name);
   while (1) {
     var o  = fn();
         c += o;
     if (c === 0) {
        console.timeEnd(name);
        break;
     }
   }
}

function innerHTML() {
  var rootElement = document.createElement('div');
   rootElement.innerHTML = '\
     <h1>Contacts</h1>\
     <ul><li>\
        <h2>James Nelson</h2>\
        <a href="mailto:james@jamesknelson.com">james@jamesknelson.com</a>\
     </li><li>\
        <h2>James Nelson</h2>\
        <a href="mailto:joe@example.com">joe@example.com</a>\
     </li></ul>';
  return -1;
}

function insertAdjacentHTML() {
  var rootElement = document.createElement('div');
   rootElement.insertAdjacentHTML('afterbegin', '\
     <h1>Contacts</h1>\
     <ul><li>\
        <h2>James Nelson</h2>\
        <a href="mailto:james@jamesknelson.com">james@jamesknelson.com</a>\
     </li><li>\
        <h2>James Nelson</h2>\
        <a href="mailto:joe@example.com">joe@example.com</a>\
     </li></ul>');
  return -1;
}

function createElement() {
  var cR = function(tag, attrs, childs) {
    
    var parent = document.createElement(tag);
    
     if (attrs !== null) {
       
       if ('text' in attrs) {
         attrs['textContent'] = attrs['text'];
         delete attrs['text'];
       }
       if ('html' in attrs) {
         attrs['innerHTML'] = attrs['html'];
         delete attrs['html'];
       }
       
       for (var key in attrs) {
         parent[key] = attrs[key];
       }
     }
     
     if (childs) {
       
       for (var i = 0; childs[i]; i++) {
          parent.appendChild(childs[i]);
       }
     }
     return parent;
  },
   rootElement = cR('div', null, [
     cR('h1', {text: "Contacts"}),
     cR('ul', null, [
       cR('li', null, [
         cR('h2', {text: "James Nelson"}),
         cR('a', {href: 'mailto:james@jamesknelson.com', text: 'james@jamesknelson.com'})
       ]),
       cR('li', null, [
         cR('h2', {text: "Joe Citizen"}),
         cR('a', {href: 'mailto:joe@example.com', text: 'joe@example.com'})
       ])
     ])
   ]);
   return -1;
}


как видно не особо то и медленный, а на огнелисе createElement так и вовсе тормоз какой то.

uin ★★★
()
Ответ на: комментарий от uin

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

В том числе и в окружениях, где нет document, не говоря об inlineHTML (хинт: сервер-сайд рендеринг) ?

Алсо, ты не прав: статический HTML хуже. Если у тебя порядка 500к строк, состоящих даже из сравнительно простой разметки — браузер будет тормозить, если ты попытаешься реально впихнуть их в DOM. А с виртуальным DOM подобных проблем нет.

x3al ★★★★★
()
Ответ на: комментарий от stevejobs

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

тем более что твой тупой верстальщик не полезет в недра jsx искать где там что

Deleted
()
Ответ на: комментарий от stevejobs

а innerHTML говорит рантайму что у твоего виртуального элемента DOM должны быть вот такие вот кишки как в этом стринг, рантайм берет этот стринг делает [ахалай МАХАЛАЙ] и у твоего виртуального элемента появляется rootElement.firstChild, rootElement.firstElementChild, rootElement.lastElementChild и так далее по списку со всеми наследуемыми свойствами.

bender
Не ну с ним (языком) что только не делают, я где то даже на гитхабе видел человек себе лямбды сделал и вообще какого то cpp наворотил и на этом пишет, потом компилирует уже в обычный.
Просто вот такие вещи как в верху вообще не оставляют шанса на понимание как это работает даже людям хорошо разбирающимся в джаваскрипте. У меня лично впечатление такое что это такой необычный html документ в котором js код вплетен в хтмл для придания каких то динамических свойств странице.

tailgunner
Я его всем усиленно навязываю что ли?
Ну а насчет космической глупости - document это по твоему что?
Это JS объект в котором собраны все элементы текущей страницы (точно такие же JS объекты).

uin ★★★
()
Ответ на: комментарий от x3al

В том числе и в окружениях, где нет document, не говоря об inlineHTML (хинт: сервер-сайд рендеринг) ?

Нет, я же написал что всякие нативные интерфейсы только через свои API функции без вариантов. Хотя и для них можно реализовать похожую штуку, что бы написать например innerBODY = 'json/ini/другой конфиг' и оно превращалось во внутреннюю структуру нативного интерфейса. Для тех кто хорошо разбирается это не проблема.

статический HTML хуже. Если у тебя порядка 500к строк, состоящих даже из сравнительно простой разметки — браузер будет тормозить, если ты попытаешься реально впихнуть их в DOM. А с виртуальным DOM подобных проблем нет.

Ты просто не понимаешь что не существует никаких статических и динамических html, джаваскрипт не знает ничего о хтмл ему браузер всучил объект document у которого внутри куча объектов соответствующих дереву хтмл, у объектов есть свойства и функции ты просто их вызываешь с какими то параметрами или без них document.body.lastElementChild.remove() document.getElementsByClassName("msg")
и браузерный движок получает команду удалить такой то элемент из тела html страницы (и из дерева объектов JS естественно) или вот собрать все элементы с таким то атрибутом (классом).

Короче динамическим html делает сам браузер а js только командует где и чего делать, и при помощи API функций которые ему сам же браузер предоставил.

uin ★★★
()
Ответ на: комментарий от uin

джаваскрипт не знает ничего о хтмл ему браузер всучил объект document

Вся цель реакта и подобных библиотек — абстрагироваться от этого document. Получается неплохо.

Нет, я же написал что всякие нативные интерфейсы только через свои API функции без вариантов

Эмм. То есть когда уже есть рабочий виртуальный DOM, который умеет в серверсайд-рендеринг и нативные интерфейсы ты приходишь и говоришь, что надо переписать код, работающий в трёх средах — браузер, node и мобильники — без модификаций только потому, что там «свои API функции»?

document.body.lastElementChild.remove() document.getElementsByClassName(«msg»)

Вот ради того, чтобы не было этого ужаса, и придумали virtualdom.

x3al ★★★★★
()
Ответ на: комментарий от stevejobs

у нас

кого волнует что там у вас?

Deleted
()

там js мягко говоря странно отличается от того что я привык видеть

Энджой йоур пхп на фронтенде.

Xellos ★★★★★
()
Ответ на: комментарий от Xellos

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

Поэтому лучше уж JSX и никакого HTML/шаблонов.

Отрисовка статики шаблонами — ещё ок, но динамические шаблоны выглядят странно.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от stevejobs

Не понимаю зачем ты мне рассказал процесс создания web-морды в вашей конторе, мне это не интересно если честно. Я всего лишь сказал что JSX и им подобное делается не от хорошей жизни. Мешать код уже само по себе преступление.

znenyegvkby
()
Ответ на: комментарий от Xellos

Nope. То, что предлагает JSX гораздо удобнее, чем то, что предлагают ангуляры и прочий кал. В конце-концов, следует различать бизнес-логику и логику интерфейса. Зачем нужно разделять логику и представление в представлении? Это разделение технологий, а не ответственности, разве нет? В чём польза?

Kilte ★★★★★
()
Ответ на: комментарий от Kilte

В этом треде уже обсуждали этот вопрос, если кому-то интересно.

Kilte ★★★★★
()
Ответ на: комментарий от x3al

Вся цель реакта и подобных библиотек — абстрагироваться от этого document. Получается неплохо.
Эмм. То есть когда уже есть рабочий виртуальный DOM, который умеет в серверсайд-рендеринг и нативные интерфейсы

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

Я если что не про реакт а про вообще говорил, ваш реакт мне до лампочки, понятно что если элементу добавить хтмл код родным способом в вашем фреймворке его внутренние объекты именуемые «виртуальный dom» не создадутся потому что ему никто не сказал, а никакой обратной связи с родным деревом элементов у него нет потому что он просто болтающаяся нахлобучка.

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

uin ★★★
()
Ответ на: комментарий от uin

Когда я в последний раз проверял, всякие preact (умеющие JSX), весили 4кб. Это — жирно? Или непродуманно?

x3al ★★★★★
()
Ответ на: комментарий от znenyegvkby

не в нашей конторе (сейчас я вообще не связан с ui), а в большинстве контор вообще

рассказал я затем, что фреймворк делается под процесс содзания веб-морды. Фреймворк неотделим от процесса создания: что для процесса хорошо - то хорошо для фреймворка, и наоборот

что-то мне подсказывает, что если ты называешь «мешать код преступление» - то ты не специальный разработчик UI, или по крайней мере писать современные динамичные веб-интерфейсы на JS не является занятием, которым ты занимаешься 100% рабочего времени. Иначе слова были бы совершенно другие.

stevejobs ★★★★☆
()

фреймворк

React — это не фреймворк, сколько можно?

Kilte ★★★★★
()
Ответ на: комментарий от stevejobs

то ты не специальный разработчик UI, или по крайней мере писать современные динамичные веб-интерфейсы на JS не является занятием, которым ты занимаешься 100% рабочего времени

И слава Богу, ***ть.

znenyegvkby
()
Ответ на: комментарий от stevejobs

что-то мне подсказывает, что если ты называешь «мешать код преступление» - то ты не специальный разработчик UI, или по крайней мере писать современные динамичные веб-интерфейсы на JS не является занятием, которым ты занимаешься 100% рабочего времени. Иначе слова были бы совершенно другие.

стиви, ты самто не фронтэндщик, что выступаешь то?

Deleted
()
Ответ на: комментарий от Deleted

друзья фронтендщики, и они писаются от счастья радугой, от того что свалили на реакт со всех этих GWT, Wicket, Vaadin и прочей сомнительной херни. Поэтому когда чувак начинает нести дичь, меня переклинивает, приходится сваливать трупы несогласных в подсобке

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

друзья фронтендщики,

тетушка подруги моего друга, ага

свалили на реакт со всех этих GWT, Wicket, Vaadin и прочей сомнительной херни.

что-то ты завираешься - эти поделки server-side, да с прибитым фронтендом, но сравнивать это и js поделки - как джопу с пальцем

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

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

поехавшие, пишущие на Викете, свято считают, что они делают на нём именно фронт. Фронт без HTML и JS - вот их мечта. Дебилы. Но это даёт полное основание сравнивать его с Реактом.

реакт: фронт - js (реакт, jquery), бэк - java (spring boot, springmvc, spring security), протокол - rest, websocket
wicket: фронт - java (викет), бэк - java (ошмётки wicket, spring ioc, spring security), протокол - особая викет-магия и wicket ajax

разница только в том, чем рендерится фронт, и протоколом взаимодействия с бэком

между фронтом на реакте есть разительное отличие. Например, разработка компонента «дерево каталогов» может занять на Викете до двух недель (двух недель, Карл!), а на Реакте с использованием всей остальной js инфраструктуры накидывается за считаные часы. При этом викетовская версия чуть менее чем целиком состоит из хаков и багов, а реактовская - работает идеально во всём

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 2)
Ответ на: комментарий от Deleted

есть проблема - для фронтендщиков нормально переписывать весь ui раз в N времени (иногда даже раз в год). Напишем сначала на jQuery, перепишем на Backbone+плагины, потом на Angular 1, потом на React, потом на Angular 2, потом на что-там-сейчас-популярно, и так до бесконечности. А я не хочу всю жизнь потратить на бесконечное переписывание UI. Это звучит как сферическое в вакууме прожигание жизни зря. Поэтому важно дистанцироваться от фронтендщиков, чтобы тебя кто-нибудь за него не принял :)

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от uin

Ты, главное, запомни - множественное число от «child» - это «children». Не «childs».

tailgunner ★★★★★
()
Ответ на: комментарий от stevejobs

два года на викете непоправимо отразились на твоем восприятии

потому что ты продолжаешь сравнивать несравнимое.

есть проблема - для фронтендщиков нормально переписывать весь ui раз в N времени (иногда даже раз в год).

это не проблема, это норм (скажи спасибо разрабам браузеров и т.п.) просто надо иметь архитектуру так чтобы это было безболезненно

Deleted
()
Ответ на: комментарий от uin

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

В JSX тоже есть вещи позабористее встроенных тегов. Как тебе статическая типизация или жаба-стайл ООП внутри js-файла?

class LikeButton extends React.Component {
  constructor() {
    super();
    this.state = {
      liked: false
    };
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    this.setState({liked: !this.state.liked});
  }
  render() {
    const text = this.state.liked ? 'liked' : 'haven\'t liked';
    return (
      <div onClick={this.handleClick}>
        You {text} this. Click to toggle.
      </div>
    );
  }
}

или так

import React from 'react';
import DropDownMenu from 'material-ui/DropDownMenu';
import MenuItem from 'material-ui/MenuItem';

const styles = {
  customWidth: {
    width: 200,
  },
};

export default class DropDownMenuSimpleExample extends React.Component {

  constructor(props) {
    super(props);
    this.state = {value: 1};
  }

  handleChange = (event, index, value) => this.setState({value});

  render() {
    return (
      <div>
        <DropDownMenu value={this.state.value} onChange={this.handleChange}>
          <MenuItem value={1} primaryText="Never" />
          <MenuItem value={2} primaryText="Every Night" />
          <MenuItem value={3} primaryText="Weeknights" />
          <MenuItem value={4} primaryText="Weekends" />
          <MenuItem value={5} primaryText="Weekly" />
        </DropDownMenu>
        <br />
        <DropDownMenu
          value={this.state.value}
          onChange={this.handleChange}
          style={styles.customWidth}
          autoWidth={false}
        >
          <MenuItem value={1} primaryText="Custom width" />
          <MenuItem value={2} primaryText="Every Night" />
          <MenuItem value={3} primaryText="Weeknights" />
          <MenuItem value={4} primaryText="Weekends" />
          <MenuItem value={5} primaryText="Weekly" />
        </DropDownMenu>
      </div>
    );
  }
}

Бейбел все перегоняет в обычный JavaScript на лету. Дебагер в браузере при этом тоже работает, но подглючивают номера строк с брейкпоинтами, как мне показалось.

На мой дилетантский взгляд, они его превратили в что-то типа Скалы, у которой, кстати, тоже есть возможность встраивать теги прямо в код, только, в отличие от JSX, там это действительно галимый html, который с таким же успехом можно закавычить - фигли взять с сервера.

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

У меня лично впечатление такое что это такой необычный html документ в котором js код вплетен в хтмл для придания каких то динамических свойств странице.

Так, да не так. Здесь не js код вплетен в html, а html (причем, реально там псевдо-html - строгий xml с именами элементов и атрибутами по большей части совпадающими с названиями html-тегов) вплетен в JS. Прочувствуй, как грицца, разницу. Весь этот «HTML» там сидит на строгом ошейнике (внутри функций render компонента) и еще в персональной клетке (компоненты хоть и не обязательно, но удобнее всего хранить в отдельных js-файлах). В другие места кода эти конструкции при сильном желании вставлять тоже можно (компилятор всё стерпит), но большой практической пользы в этом нет (ну ладно, есть еще одно место на все приложение - это ReactDOM.render, который отправляет финальное дерево в index.html).

Так же стоит добавить, что в js-файлы компонентов (где можно встретить эти миксы js-html-кода), следуя особенностям архитектуры и гайдлайнам реакта, не то, чтобы сложно, но не очень удобно засовывать какую-то бизнес-логику, не связанную напрямую с отрисовкой самого компонента (там компонент - это стейт-машина, внешний вид которой зависит от текущих значений статических пропертей this.props и динамических состояний this.state - поменялся this.state - перерисовываем, не поменялся - ничего не происходит). Бизнес-логика будет где-то в других местах в других файлах - можно на чистом JS, можно на расширенном JSX, куда лапшу из тегов при хорошем желании запихнуть тоже можно, но только со специальным злым умыслом.

На реакт наткнулся на прошлой деле, последний раз так кайфовал, когда познал серверную на scala+unfiltered после лет с томкатом и jsp.

bender ★★★★★
()
Ответ на: комментарий от x3al

получается каша вроде angular

Имплаинг JSX не каша.

Xellos ★★★★★
()
Ответ на: комментарий от Kilte

не, не смущает

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <!-- Для поддержки тегов script с параметром type="text/babel" -->
    <script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script>
    <!-- Для ReactDOM.render -->
    <script src="script/react/react.js"></script>
    <script src="script/react/react-dom.js"></script>
  </head>
  <body>
    <div id="hello-react"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world from React!</h1>,
        document.getElementById('hello-react')
      );
    </script>
    <div>
      Работает на чистом <a href="https://facebook.github.io/react/docs/getting-started.html">React starter pack</a>
    </div>
  </body>
</html>

bender ★★★★★
()

Для реакта я пользуюсь SublimeText-ом с плагином для Babel-а. С подключенным es2015 можно писать несколько более понятный код, вроде такого:

render() {
    const { users = [] } = this.state;

    return (
        <ul className='user-list'>
            { users.map(user => this.renderUser) }
        </ul>
    )
}

renderUser(user = {}) {
    return (
        <li key={ user.id }>
            <Link to={ `/users/${user.id}` }>{ user.name }</Link>
        </li>
    )
}

Можно ещё облегчить себе жизнь с алиасами для модулей, автолинтингом (саблайм умеет). Но никакого полноценного рефакторинга не жди, в JS даже переменные заменить автоматом не всегда возможно.

SOmni ★★
()
Ответ на: комментарий от bender

В JSX тоже есть вещи позабористее встроенных тегов. Как тебе статическая типизация или жаба-стайл ООП внутри js-файла?

Короче, гоню. Статическая типизация и ООП - это другой JSX. JSX из реакта - это только HTML-подобный XML. А тот синтаксис и ява-стайл ООП с import/class/extends и лямбды - это ES6 (типа расширенный синтаксис для яваскрипта, который компилируется в обычный яваскрипт бейбелом).

bender ★★★★★
()
Последнее исправление: bender (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.