AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 30.09.2021, 08:34   #1  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,895 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от Logger Посмотреть сообщение
Что, правда ? Мне казалось что Дамгаарды просто посмотрели на Java 1.0 и сделали по мотивам, но все сами. Как же оно было на самом деле?
Я тоже много раз читал рассуждения mazzy по поводу того что Аксапта использует древнюю явовскую VM, но никогда не читал что-то подобного в воспоминаниях участников процесса или даже архивных внутренних документах MS. При этом схожесть с явой в старой аксапте - она тоже достаточно относительная. Я бы скорее назвал X++ версии 2.5 "Visual Basic с явовским синтаксисом". Все-таки многие очень фундаментальные явовские идеи - типа интерфейсов, появились в языке только где-то в DAX2009 (хотя да - interface был reserved word со времен версии 2.1).

Последний раз редактировалось fed; 30.09.2021 в 10:19.
Старый 30.09.2021, 09:02   #2  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от fed Посмотреть сообщение
Я тоже много раз читал рассуждения mazzy по поводу того что Аксапта использует древнюю явовскую VM, но никогда не читал что-то подобного в воспоминаниях участников процесса или даже архивных внутренних документах MS.
Маззи явно не отделяет свои гипотезы от того, что ему точно известно.

В Ax<=2012 своя ВМ и свой рантайм. Это можно даже по внешним свойствам догадаться. Оно ведет себя не как ява, а как динамический рантайм со статическим проверщиком типа тайпскрипт.

final - оно ж прежде всего логическая вещь, а не для перформанса.
Старый 29.09.2021, 21:20   #3  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,283 / 3491 (123) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от axm2017 Посмотреть сообщение
D365

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

Не могли бы помочь сформулировать все «за» и «против» реализации инкапсуляции и особенности D365FO, которые надо учитывать при использовании модификаторов доступа. В идеале с примерами.

В общем хочется BP
ps и понять конечно где правильно писать final
На самом деле не очень ясно - "а какая разница, если ты не вендор"?
Т.е. все эти красивые слова по сути нужны только Microsoft-у. Либо любой компании, от кода которой наследуются многие другие компании.
internal внутри одной модели использовать бессмысленно по определению
final требуется ставить на Extension-ах, но для своих методов смысла особого нет. Можно особо выпендриться и ставить final на parm-методах (исходя из условия, что они точно не будут наследоваться), но ... нужно ли?
Подход к использованию private / protected / private не меняется по сравнению со старыми версиями АХ, если работать в одной модели

Если работа производится с несколькими моделями - то тут вопрос - насколько нужно именно несколько моделей? И как часто их приходится поддерживать (часто - в плане обращений потребителей)

Если же вопрос ставится от имени Microsoft - то тут отдельный вопрос. Тут перед закрытием кода нужно API готовить и т.д.. В общем - отдельный разговор.
__________________
Возможно сделать все. Вопрос времени
Старый 29.09.2021, 23:06   #4  
axm2017 is offline
axm2017
Участник
 
1,772 / 293 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
На самом деле не очень ясно - "а какая разница, если ты не вендор"?
Т.е. все эти красивые слова по сути нужны только Microsoft-у.
"За державу обидно"
А вот ни фига. Так же как ТБ написана кровью так и BPзачастую написаны после потери n часов и дней.

Не вижу принципиальной разницы между ребятами из MS и нами. У них просто как правило более масштабная промышленная разработка и соответственно некоторые мелкие вещи играют на массе бОльшую роль (тот же отказ от тестировщиков к примеру зато переход к авто тестам)
Старый 29.09.2021, 23:29   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от axm2017 Посмотреть сообщение
Не вижу принципиальной разницы между ребятами из MS и нами.
у ребят из MS полный доступ к коду.
__________________
полезное на axForum, github, vk, coub.
Старый 30.09.2021, 00:13   #6  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,283 / 3491 (123) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от axm2017 Посмотреть сообщение
"За державу обидно"
А вот ни фига. Так же как ТБ написана кровью так и BPзачастую написаны после потери n часов и дней.

Не вижу принципиальной разницы между ребятами из MS и нами.
Я конечно погорячился - прошу прощения.
Про BP я не говорил - речь шла именно про расширения. Т.е. в моем понимании правила использования private / public / protected методов с т.з. BP - не поменялись с прошлых версий АХ, если использовать их в одной модели. А слово internal в этом случае вообще не нужно.

А вот разница между ребятами из MS и прочими ребятами как раз-таки и есть в том, что при соблюдении правил BP с прошлых версий АХ - ребята из MS должны больше думать о точках расширений, нежели все остальные. Потому что количество людей, которые использует код ребят из MS, как закрытый к правке - гораздо больше, нежели количество людей, которые используют код других ребят, как закрытый к правке.

Грубо говоря - мне дали задачу, я написал класс, в котором 20 методов private и 10 методов public / protected. Если я обычный программист - я не думаю о последователях - ибо их нет, а расставлять точки расширения наобум - это бестолковая задача. А вот если я программист MS - я обязан дополнительно подумать об (условно) 5 точках расширения, которые я должен заложить в свой код.

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

В общем - посмотрим. Наверное Вы правы - постепенно к осознанию необходимости "феншуйности" кода все придут.
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 30.09.2021 в 00:25.
Старый 30.09.2021, 00:22   #7  
axm2017 is offline
axm2017
Участник
 
1,772 / 293 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
...

Грубо говоря - мне дали задачу, я написал класс, в котором 20 методов private и 10 методов public / protected. Если я обычный программист - я не думаю о последователях - ибо их нет, а расставлять точки расширения наобум - это бестолковая задача. А вот если я программист MS - я обязан подумать об (условно) 5 точках расширения, которые я должен заложить в свой код
Увы. Есть такое понятие как карма и поддержка.

Лучики добра при разработке наследства от тех кто не думал шлю регулярно. Думаю что и в мою сторону летят, поэтому иногда пытаюсь думать.
Старый 30.09.2021, 00:31   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,283 / 3491 (123) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от axm2017 Посмотреть сообщение
Увы. Есть такое понятие как карма и поддержка.

Лучики добра при разработке наследства от тех кто не думал шлю регулярно. Думаю что и в мою сторону летят, поэтому иногда пытаюсь думать.
Ну в Вашем случае получается, что есть последователи вашего закрытого кода. А это "в корне меняет ситуацию". Конечно в этом случае, когда потребители вашего закрытого кода "под боком" и могут "оперативно настучать" - Вам действительно приходится думать о поддержке. Но опять-таки... полагаю, что таких последователей у Вас если не всего один, то явно крайне мало по сравнению с MS. Т.е. можно в принципе попытаться "угадать", где делать точки расширения. MS-у в этом плане гораздо сложнее
__________________
Возможно сделать все. Вопрос времени
Старый 30.09.2021, 18:41   #9  
trud is offline
trud
Участник
Лучший по профессии 2017
 
1,038 / 1629 (57) ++++++++
Регистрация: 07.06.2003
Записей в блоге: 1
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Грубо говоря - мне дали задачу, я написал класс, в котором 20 методов private и 10 методов public / protected. Если я обычный программист - я не думаю о последователях - ибо их нет, а расставлять точки расширения наобум - это бестолковая задача. А вот если я программист MS - я обязан дополнительно подумать об (условно) 5 точках расширения, которые я должен заложить в свой код.
Этож не так работает, у программистов МС тоже есть свои сроки и задачи. Т.е. там где партнер использует рефлекшн, они просто ставят internal.
Потом возникает вопрос частоты обновлений, тут на помощь приходит микросервисная архитектура. Делается микросервис(идельно - работающий только на Тир2, что отсекает большую часть разработчиков из репортинга багов ), который уже отдельная команда пилит по своему расписанию.
Т.е. архитектура системы подстраивается под структуру огранизации разрабатывающей ПО, вроде такой закон даже есть
Вообще модификаторы идеально были сделаны в начальной версии АХ, т.е. private не запрещал вызов метода, а выдавал ошибку BP. Это как бы на порядок лучше использование Reflection.
За это сообщение автора поблагодарили: sukhanchik (3), vmoskalenko (5).
Старый 29.09.2021, 21:45   #10  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
Мне кажется - тут дискуссия слегка ушла в сторону. То, для чего нужны нужны final\private всем в той или иной мере понятно, и почитать об этом можно в любом учебнике.

Проблема поднята немного другая:

Цитата:
В компании принят подход при котором этот модификатор должен ставиться по умолчанию для методов
Цитата:
В D365 чей-то недальновидный мозг решил проставлять Private по умолчанию
Так вот в результате в системе мы имеем через один приватный метод. Программисты просто-напросто не заморачиваются какой там у них модификатор стоит и уж меньше всего думает о том, кто там и как его классы будет наследовать. И вместо того, чтобы это "умолчание" убрать - имеем

Цитата:
Они могут себе попросить точку расширения, которой им не хватает.
Мы регулярно их делаем.
Вам там больше делать нечего? Или партнерам больше делать нечего, как тикет суппорты вам писать вместо 2-х минутного создания наследника?
А клиенты за это платят бешеные деньги и к нашему с вами счастью, пока не понимают - за какую чушь.

Закрыли код и понеслась фантазия: COC, ивенты, хукабл\не хукабл, рефлекшн в бизнесс-логике. Превратили систему в неуправляемую помойку... Точки расширения они делают регулярно. Деятели...
За это сообщение автора поблагодарили: sukhanchik (6).
Старый 29.09.2021, 22:32   #11  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от DSPIC Посмотреть сообщение
Программисты просто-напросто не заморачиваются какой там у них модификатор стоит и уж меньше всего думает о том, кто там и как его классы будет наследовать. И вместо того, чтобы это "умолчание" убрать - имеем
Свергни тирана - получишь щастье?!

Неее. Это не так работает.
Программисты не заморачиваются там, где их не заморачивают типлиды.
Тимлиды и не думают там, где их не напрягают архитекторы и руководство.

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

Это ж не только private. Продавать только Azure версию, Seal классов, закрытые механизмы развертывания, сильно ограниченный доступ SQL...

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

Цитата:
Сообщение от DSPIC Посмотреть сообщение
То, для чего нужны нужны final\private всем в той или иной мере понятно, и почитать об этом можно в любом учебнике.
нееее. ни в каком учебние не раскрывается что делать пользователям ЗАКРЫТОГО фреймворка, когда вендор этого фреймворка использует эти модификаторы как полный невменько.

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


===============
добавлено:
и да!
полностью согласен, что вместо private почти всегда лучше использовать protected.
и полностью не согласен, что изменение модификатора по умолчанию хоть что-то изменит.
...хотя бы потому, что private-методы внутри Майкрософт не обязательно покрывать тестами.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 29.09.2021 в 22:48.
За это сообщение автора поблагодарили: sukhanchik (6).
Старый 30.09.2021, 08:36   #12  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от DSPIC Посмотреть сообщение
Точки расширения они делают регулярно. Деятели...
Тут такая логическая цепочка: регулярные обновления => совместимость => органичение объема API.

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

Вот, допустим кто-то написал

X++:
public void foo(string bar)
{
   ...- 
}
Теперь нам надо сделать дополнительный параметр.

X++:
public void foo(string bar, int baz)
- так делать нельзя. Расширение может вызывать этот метод и оно перестанет компилироваться и работать.

X++:
public void foo(string bar, int baz = 0)
Тут расширение из предыдущей фразы будет работать, но
1. Может быть расширение которое обернуло этот код и не прокидывает новый параметр
2. Если параметр baz логически обязательный, то все скомпилируется и сработает но неправильно. Фактически, это означает, что логически обязательный параметр вообще никак нельзя добавить без потери обратной совместимости.

X++:
public void foo(string bar)
{
     this.fooWithBaz(bar, 0);
}
public void fooWithBaz(string bar, int baz)
Так можно, но нельзя перестать вызывать foо в том месте, где он изначально вызывался, потому, что расширение может подписаться на вызовы foo или обернуть и тогда оно тихо перестанет работать.

Еще можно сделать disposable context - фактически передавать дополнительные данные через статический метод, но будут пролемы с рекурсией.

Можно изначально передавать параметры завернутые в parameter object.

A самое главное, от логически обязательного параметра не спасает ничего.

При этом всем этот метод в реальности, скорее всего, никакими расширениями не используется (потому, что большинство методов не используется) и делать его piblic значит просто закрыть себе возможность развития этого участка кода без какой бы то ни было выгоды для кого-то.
За это сообщение автора поблагодарили: sukhanchik (6), DSPIC (5).
Старый 30.09.2021, 09:35   #13  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Кстати, конкретно от модуля ER есть API которые бы вы хотели, но не просили официально?
Старый 30.09.2021, 10:14   #14  
axm2017 is offline
axm2017
Участник
 
1,772 / 293 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от belugin Посмотреть сообщение
Кстати, конкретно от модуля ER есть API которые бы вы хотели, но не просили официально?
Хотелки (как разраба):
а) возможность создавать свою среду разработки. Не уверен что сейчас это возможно без финтов. +

б) возможность встроить свои форматы (как Excel и ко) Вроде писали что можно но не тестил. + но- по идее конечно могу выгрузить в формате xml или json и далее уже все сделать но выглядеть это будет колхозно.

в) возможность связать явно маппинг и формат +++

Последний раз редактировалось axm2017; 30.09.2021 в 10:39.
Старый 30.09.2021, 16:23   #15  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от axm2017 Посмотреть сообщение
а) возможность создавать свою среду разработки. Не уверен что сейчас это возможно без финтов. +
Это вряд ли - получается надо открыть все-все а потом это поддерживать.

Цитата:
б) возможность встроить свои форматы (как Excel и ко) Вроде писали что можно но не тестил. + но- по идее конечно могу выгрузить в формате xml или json и далее уже все сделать но выглядеть это будет колхозно.
Это можно завести как запрос на точку расширения, только с бизнес мотивацией. Желательно с описанием примера.

Цитата:
в) возможность связать явно маппинг и формат +++
Мы кажется это обсуждали уже, но я забыл зачем именно это нужно и по-быстрому не нашел.
Старый 01.10.2021, 11:36   #16  
axm2017 is offline
axm2017
Участник
 
1,772 / 293 (13) ++++++
Регистрация: 15.05.2017
Цитата:
Сообщение от belugin Посмотреть сообщение
Мы кажется это обсуждали уже, но я забыл зачем именно это нужно и по-быстрому не нашел.
На текущий момент при запуске ER отчета действует следующая схема, как понимаю:

Формат (format) находит в модели (model) структуру (root?), на основе которой он создан, и далее модель по структуре, находит соответствие (mapping) с данными системы.
Однако соответствий может быть несколько.

В настоящий момент система не позволяет выбрать и для корректной работы администратор ER обязан всегда поддерживать уникальность связки
format - mapping - structure of model.

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

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

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

Последний раз редактировалось axm2017; 01.10.2021 в 11:39.
Старый 30.09.2021, 14:43   #17  
VORP is offline
VORP
Участник
Аватар для VORP
 
146 / 95 (4) ++++
Регистрация: 26.05.2006
Цитата:
Какие-то точки расширения были продуманы, какие-то нет. Какие-то были лишние
В новом модуле CreditManagement (Управление кредитными лимитами, CredMan) вообще вся функциональность сделана internal, то есть даже копи-паст не очень поможет(если только скопировать всю модель).
Старый 30.09.2021, 17:57   #18  
Stitch_MS is offline
Stitch_MS
Участник
Аватар для Stitch_MS
Соотечественники
 
396 / 478 (16) +++++++
Регистрация: 27.02.2006
Адрес: Дания
Цитата:
Сообщение от VORP Посмотреть сообщение
В новом модуле CreditManagement (Управление кредитными лимитами, CredMan) вообще вся функциональность сделана internal, то есть даже копи-паст не очень поможет(если только скопировать всю модель).
О, это вообще песня. Чтобы эта приблуда заработала в Intercompany без копи-пасты, пришлось жестоко изобретать.

Например, через reflection в нужные моменты временно активировать кредит-чекпоинты для типа proforma confirmation в настройках, а потом постить этот документ для original SO, чтобы сработал кредит-чек и, если надо, заблокировал его.

Или, скажем, при нажатии Release to warehouse в intercompany SO, переходить в original SO, запускать кредит-чек для чекпоинта Release to warehouse, и если там получался кредит-холд, перебрасывать этот кредит-холд в IC SO. Так чтобы в итоге задолженность конечного покупателя не дала отпустить товар на склад в другой компании.
Старый 30.09.2021, 19:02   #19  
imir is offline
imir
Участник
 
159 / 161 (6) ++++++
Регистрация: 28.05.2010
Ладно со старыми методами, там private по-умолчанию переехал из 12-й, это можно объяснить (не)злым умыслом. Но в новых модулях, кторые пишутся с нуля.. смотрим написанный недавно с нуля Asset leasing:

- все классы помечены internal final class AssetLease*
Все методы:
-все что можно private
- там где нельзя поставить private по смыслу - internal
- нельзя ни то, ни другое - [Hookable(false)]

ну т.е. не то что точки не заложены, а модуль целиком и полностью с особой паранойей закрыт изначально.

Допускаю, что это задумано для того, чтобы репортили баги вместо заплаток, потому что модуль сырой, но тенденция однако может распространиться на все остальное.
Старый 30.09.2021, 19:37   #20  
Stitch_MS is offline
Stitch_MS
Участник
Аватар для Stitch_MS
Соотечественники
 
396 / 478 (16) +++++++
Регистрация: 27.02.2006
Адрес: Дания
Цитата:
Сообщение от imir Посмотреть сообщение
Допускаю, что это задумано для того, чтобы репортили баги вместо заплаток
А ещё это освобождает вендора от неприятных раздумий типа «а не breaking ли change я сейчас пилю?»
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
d365technext: Private, Protected and Public attribute access in Class Extension Blog bot DAX Blogs 0 30.07.2018 20:13
i-neti: X++ in AX7: элементы с уровнями доступа private и public. Часть 4 Blog bot DAX Blogs 0 18.04.2017 13:11
mfp: X++ in AX7: Private and public members Blog bot DAX Blogs 12 10.12.2015 09:08
dynamics-ax: Microsoft Highlights New ERP Public Sector Capabilities for AX 2012 Blog bot DAX Blogs 0 23.05.2011 19:11
Rahul Sharma: Convert Dynamics AX Entity Private Address into Public GAB Address Blog bot DAX Blogs 0 07.04.2011 02:15

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 06:50.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.