Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0 > Статьи

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 27.10.2006, 12:54
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 1  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 77. Определение добавления или удаления со Stage

В предыдущем примере показано как определить добавление и удаление объекта от другого отображаемого объекта. Но если с экрана будет удален наш родительский объект, то события ADDED/ REMOVED не сработают. Как же отследить реальное добавление или удаление с экрана? Можно воспользоваться классом StageDetection (com.senocular.events.StageDetection)
Код:
package com.senocular.events {
    
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.utils.Dictionary;
    
    /**
     * StageDetection 
     * Позволяет DisplayObject реагировать на добавление и удаление со stage
     *
     * Использовать в конструкторе
     * var stageDetect:StageDetection = new StageDetection(this);
     * stageDetect.addEventListener(StageDetection.ADDED_TO_STAGE, addedToStage);
     * stageDetect.addEventListener(StageDetection.REMOVED_FROM_STAGE, removedFromStage);
     */
    public class StageDetection extends EventDispatcher {
        
        protected var target:DisplayObject;
        protected var parents:Dictionary;
        protected var detect:String;
        
        public static const ADDED_TO_STAGE:String = "addedToStage";
        public static const REMOVED_FROM_STAGE:String = "removedFromStage";
        
        /**
         * Конструктор
         */
        public function StageDetection(targetObject:DisplayObject) {
            target = targetObject;
            
            // Определяем за чем нужно следить, за добавлением или удалением
            detect = (target.stage == null) ? Event.ADDED : Event.REMOVED; 
            
            // Обновляем слушателей у родителей
            updateListeners();
        }
        
        /**
         * Обновляет слушателей событий ADDED и REMOVED
         */
        protected function updateListeners(newDetect:String = null):void {
            
            // Очищаем старые listeners у родителей
            if (parents) {
                for (var key:Object in parents) {
                    key.removeEventListener(detect, stageCheck, false);
                }
            }
            
            // Запомним на какие события подписываемся
            if (newDetect) detect = newDetect;
                
            // Прописывает слушателей этого события у родителей
            parents = new Dictionary(true);
            var parent:DisplayObject = target;
            while (parent) {
                parent.addEventListener(detect, stageCheck, false, 0, true);
                parents[parent] = true;
                parent = parent.parent;
            }
        }
        
        
        /**
         * В обработчике ADDED и REMOVED проверяем наличие stage
         */
        protected function stageCheck(evt:Event):void {
            
            // Реагируем только на оригинальный источник события
            if (evt.target != evt.currentTarget) return;
                
            // evt.type или ADDED или REMOVED
            switch(evt.type) {
                
                // Кого-то из родителей добавили к другому объекту
                case Event.ADDED:
                    
                    // stage доступен, значит нас добавили на экран
                    if (target.stage != null) {
                        
                        // Рассылаем событие и обновляем listeners
                        dispatchEvent(new Event(ADDED_TO_STAGE));
                        updateListeners(Event.REMOVED);
                        
                    // stage недоступен, значит просто добавили к другому объекту
                    } else {
                        
                        // Список родителей изменился, значит обновим listeners
                        updateListeners();
                    }
                    break;
                    
                // Родителя удалили со stage
                case Event.REMOVED:
                    
                    // Рассылаем событие и обновляем listeners
                    dispatchEvent(new Event(REMOVED_FROM_STAGE));
                    updateListeners(Event.ADDED);
                    break;
            }
        }
    }
}
MerlinTwi: На данный момент этот класс стоит рассматривать только в ознакомительных целях, как можно красиво реализовать решение поставленной задачи. Практической пользы нет, т.к. с очередным обновлением Flash плеера были добавлены события ADDED_TO_STAGE и REMOVED_FROM_STAGE позволяющие DisplayObject 'у проверять доступность stage. Событие ADDED_TO_STAGE отправляется DisplayObject 'у когда он один или дерево объектов с ним добавляются на сцену, REMOVED_FROM_STAGE при удалении.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 27.10.2006, 13:21
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 2  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 78. Фазы событий

В ActionScript 3 для отображаемых объектов добавлены три фазы распространения событий:
  • Захват, capturing
  • Обработка, targeting
  • Подъем, bubbling

1. захват (capturing)
Событие начинается со stage и спускается вниз, вызывая обработчики связанные с этим событием у всех объектов (если же обработчика не существует, ничего не происходит).
Код:
       event
+---------|----+
| parent  |    |
|  +------V-+  |
|  |child   |  |
|  |        |  |
|  +--------+  |
+--------------+
2. обработка (targeting)
На стадии обработки вызывается обработчик события объекта которому собственно оно и предназначалось.
Код:
+--------------+
| parent       |
|  +------ -+  |
|  |child   |  |
|  |event X |  |
|  +--------+  |
+--------------+
3. подъем (bubbling)
Перебираются все объекты, начиная с "виновника" события и до stage.
Код:
+---------^----+
| parent  |    |
|  +------|-+  |
|  |child | |  |
|  | event| |  |
|  +--------+  |
+--------------+
По умолчанию addEventListener подписывает обработчик события только на две фазы 2 (обработка) и 3 (подъем). Это позволяет вашему обработчику события реагировать на событие у себя а так же на это событие и у детей.
Если вы хотите реагировать на стадию захвата (1), необходимо в addEventListener указать третьим параметром true.
Код:
target.addEventListener("event", listener, true);
При этом обработчик события будет реагировать только на стадию захвата. Если вы хотите подписать обработчик события на все стадии нужно вызвать addEventListener дважды:
Код:
target.addEventListener("event", listener, true); // захват 
target.addEventListener("event", listener, false); // обработка и подъем
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 30.10.2006, 12:46
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 3  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 80. Предотвращение распространения события

Если нужно пресечь дальнейшее распространение события можно использовать методы stopPropagation() (flash.events.Event.stopPropagation()) или stopImmediatePropagation() (flash.events.Event.stopImmediatePropagation()).
stopPropagation – предотвращает дальнейшее распространение события в стадии захвата (capturing) или подъема (bubbling)
stopImmediatePropagation – блокирует вообще все, в том числе и фазу обработка (targeting).
Смотрим пример:
Код:
var circle:Sprite = new Sprite();
circle.graphics.beginFill(0x4080A0);
circle.graphics.drawCircle(50, 50, 25);
addChild(circle);

circle.addEventListener(MouseEvent.CLICK, clickCircle1);
circle.addEventListener(MouseEvent.CLICK, clickCircle2);
stage.addEventListener(MouseEvent.CLICK, clickStage);

function clickCircle1(evt:MouseEvent):void {
    // evt.stopPropagation();
    // evt.stopImmediatePropagation();
    trace("clickCircle1");
}
function clickCircle2(evt:MouseEvent):void {
    trace("clickCircle2");
}
function clickStage(evt:MouseEvent):void {
    trace("clickStage");
}
При клике мышкой по кругу (circle), без использования прерывания распространения события:
Код:
//output
clickCircle1
clickCircle2
clickStage
Срабатывают два обработчика событий на клик мышки "clickCircle1","clickCircle2" фаза обработка (targeting) и обработчик "clickStage" на фазе подъема (bubbling).

Если убрать комментарий с evt.stopPropagation();
Код:
//output с использованием stopPropagation
clickCircle1
clickCircle2
В обработчике "clickCircle1" вызывается stopPropagation, которое предотвращает дальнейшее распространение события по фазам захвата (capturing) и подъема (bubbling), поэтому далее нормально вызывается обработчик "clickCircle2" в фазе обработка (targeting), но не вызывается "clickStage", поскольку он уже на фазе подъема (bubbling).

Если убрать комментарий с evt.stopImmediatePropagation();
Код:
// output с использованием stopImmediatePropagation 
clickCircle1
В этом случае не будет вызван даже обработчик "clickCircle2" в фазе обработка (targeting).
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 01.11.2006, 13:56
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 4  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 84. Доступ к stage и root

Stage (сцена) – это фактически первый контейнер в который загружаются все остальные отображаемые объекты, включая root. Stage может быть только один, а вот root может быть сколько угодно, по одному на каждую загруженную внешнюю флешку.
Все отображаемые объекты (flash.display.DisplayObject) имеют свойства stage и root. До тех пор, пока объект не добавлен на сцену (stage) эти свойства равны null. Свойство stage, когда доступно, всегда ссылается на объект stage. А вот свойство root в разный случаях содержит разные ссылки:
  • Для stage, свойство root всегда ссылается на stage
  • Для всех объектов, расположенных на главной timeline, свойство root ссылается на главную timeline
  • Если объект добавлен прямо на сцену (stage) из любой timeline, свойство root для него и его детей будет ссылаться на stage
  • Для объектов расположенных в подгруженном внешнем SWF-файле, свойство root ссылается на главную timeline этого SWF-файла
  • Для загруженных картинок, свойство root ссылается на экземпляр класса Bitmap, куда была загружена картинка
Помните, что только после добавления на сцену, или к любому другому объекту уже добавленному на сцену, есть доступ к свойствам stage и root. Это серьезное отличие от ActionScript 1 и 2 и на то есть две причины:
  1. В AS1 и 2 мувиклипы в момент своего создания уже были добавлены на сцену. В AS3 это не так. Фактически только document class (см. предыдущий совет) изначально расположен на stage (во Flash 9 еще и объекты, расположенные на timeline в IDE до публикации).
  2. В AS1 и 2 все скрипты и классы были определены внутри timeline или мувиклипов, как результат отовсюду был доступ к свойству _root.В AS3 классы не привязаны к timeline и могут не иметь доступа к root или stage.
Это сильно ограничивает наш доступ к stage или root в скриптах. К примеру, не отображаемый класс в AS3 вообще не может получить доступ к stage или root, только если получит ссылку извне.
Код:
package {
    
    import flash.display.Stage;

    public class CustomObject {
    
        private var stage:Stage;
    
        public function CustomObject(stageRef:Stage) {
        
            // Ссылку на stage нужно передавать как параметр конструктора
            stage = stageRef;
        }
    }
}
Отображаемые объекты в момент создания в конструкторе не имеют доступа к stage и root (если только они не были расположены на timeline до компиляции)
Код:
package {
    
    import flash.display.Sprite;
    import flash.events.Event;

    public class CustomDisplayObject extends Sprite {
    
        public function CustomObject() {
        
            // stage недоступен до тех пор, 
            // пока объект не будет добавлен на сцену
            trace(stage); // null
        }
    }
}
Это создает определенные трудности. Нужно добавлять дополнительный обработчик события добавления на сцену (ADDED_TO_STAGE), из которого уже вызывать функцию init для совершения необходимых действий.
Другой вариант решения создать статичное свойство в каком-либо классе, в которое прописать ссылку на root или stage и уже к этому свойству обращаться из любого места. Лучше всего для этого подойдет document class, т.к. он изначально имеет доступ к stage и сам является root.
Пример:
Код:
package {
    
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.display.Stage;
    
    public class TopLevel extends MovieClip {
        
        public static var stage:Stage;
        public static var root:DisplayObject;
            
        public function TopLevel() {
            TopLevel.stage = this.stage;
            TopLevel.root = this;
        }
    }
}
Доступ к stage из неотображаемого класса:
Код:
package {
        
    public class RandomClass {
            
        public function RandomClass() {
            trace(TopLevel.stage); // [object Stage]
        }
    }
}
В идеале стоит писать код так, чтобы не было необходимости в создании классов подобных TopLevel и жесткой привязке к нему. Особенно если в разработке участвуют несколько программистов. Определять доступность stage лучше по событию.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 20.10.2006, 11:51
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 5  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 59. MXMLC: SWF Metadata Tag

Если вы используете MXMLC (компилятор из Flex 2 SDK) для компиляции ActionScript 3 SWFs, вы можете использовать SWF metadata tag для назначения свойств флешки. Всего можно установить 4 свойства:
  • width
  • height
  • frameRate
  • backgroundColor
Пример:
Код:
package {
    [SWF(width="500", height="450", frameRate="24", backgroundColor="#FFFFFF")]
    public class MyApp extends Sprite {

    }
}
После компиляции будет создан SWF размером 500x450 с белым фоном и частотой кадров 24.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 20.10.2006, 12:35
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 6  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 60. Класс Proxy

В ActionScript 3 добавлен новый класс Proxy (flash.utils.Proxy) для замены методов addProperty и __resolve из ActionScript 1 и 2.
  • addProperty(prop:String, getFunc:Function, setFunc:Function) : Boolean
    использовался для динамического добавления getter/setter свойств в объект или класс. Параметры:
    prop - имя создаваемого свойства объекта.
    getFunc - функция, которая вызывается для возвращения значения свойства;
    setFunc - функция, которая вызывается для установки значения свойства;
  • __resolve - ссылка на определяемую пользователем функцию, которая вызывается, если ActionScript код ссылается на неопределенное свойство или метод.
В ActionScript 3 вы можете создать класс наследник от класса Proxy, который предоставляет следующие возможности:
  • Перехватить чтение свойства
  • Перехватить запись свойства
  • Перехватить проверку свойства (на наличие)
  • Перехватить удаление свойства
  • Перехватить вызов метода
  • Перехватить установку атрибутов
  • Использовать [] для доступа к свойствам
Хоть возможности Proxy и превосходят то, что было доступно в AS1 и AS2, здесь есть и свои недостатки. Вы обязаны наследоваться от класса Proxy, нельзя унаследоваться от произвольного класса, например от Display objects, и получить возможности класса Proxy.
Proxy классы обычно используются для создания набора переменных с гибкими возможностями (например, Flex классы ArrayCollection, ListCollectionView, XMLListCollection).

Proxy класс более детально будет рассмотрен в следующих советах
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 20.10.2006, 12:44
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 7  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 61. Оператор «in»

В ActionScript 3 добавлен новый оператор in (in operator), который используется для проверки наличия свойства в объекте. Это аналогично hasOwnProperty, но работает и для унаследованных свойств.
Код:
trace("PI" in Math);         // true
trace("myProperty" in Math); // false
Так же оператор in можно использовать для проверки правильности номера индекса в массиве:
Код:
var myArray:Array = ["zero", "one", "two"];
trace(0 in myArray); // true
trace(1 in myArray); // true
trace(2 in myArray); // true
trace(3 in myArray); // false
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 23.10.2006, 13:18
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 8  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 62. Методы getProperty и setProperty класса Proxy

Методы getProperty и setProperty используются для управления необъявленными свойствами класса. Если какое-то свойство явно не объявлено в классе, то при попытке прочитать его значение, будет вызван метод getProperty. Аналогично при записи вызывается метод setProperty.
Как и все методы класса Proxy, getProperty и setProperty объявлены в пространстве имен «flash_proxy» (flash.utils.flash_proxy), чтобы не возникало конфликтов с публичными методами. Для переопределения этих методов в своем классе обязательно нужно указывать пространство имен flash_proxy.
Пример: класс CustomObject наследуется от Proxy и переопределяет методы getProperty и setProperty для управления динамическими свойствами.
Код:
package {
    
    import flash.utils.Proxy;
    import flash.utils.flash_proxy;
    
    dynamic public class CustomObject extends Proxy {
        
        public var classProperty:String = "classProperty"; // объявленное свойство
        private var customProperties:Object = new Object(); // хранилище динамических свойств
        
        public function CustomObject() {
        }
        
        // Вызывается при чтении динамического свойства
        override flash_proxy function getProperty(name:*):* {
            if (name in customProperties) {
                return customProperties[name];
            }
            return "Property does not exist";
        }
        // Вызывается при записи в динамическое свойство
        override flash_proxy function setProperty(name:*, value:*):void {
            customProperties[name] = "Property "+name+": "+value;
        }
    }
}
Код:
// Пример использования
var myObj:CustomObject = new CustomObject();
trace(myObj.foo); // Property does not exist
myObj.foo = "bar";
trace(myObj.foo); // Property foo: bar

trace(myObj.classProperty); // classProperty
myObj.classProperty = "bar";
trace(myObj.classProperty); // bar
Обратите внимание, что методы getProperty и setProperty вызываются при попытке доступа к необъявленным свойствам класса. В примере, при доступе к явно объявленному свойству «classProperty» эти методы не вызывались.
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 23.10.2006, 13:43
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 9  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 63. instance name мувиклипа на сцене

Во Flash 9, когда вы размещаете MovieClip на сцене (timeline) с указанием имени (instance name), автоматически происходят сразу два действия:
1. Вы присваиваете методу «name» этого мувиклипа строку эквивалентную instance name.
2. Вы создаете переменную в timeline с именем аналогичным instance name мувиклипа со ссылкой на этот мувиклип.
Флеш делает все это самостоятельно при компиляции SWF файла, чтобы помочь вам управлять мувиклипами на сцене. Важно понимать, что при создании мувиклипами средствами ActionScript, эти действия не выполняются автоматически.
К примеру:
Код:
// Здесь «my_mc» это instance name мувиклипа на сцене
trace(my_mc); // [object MovieClip]
trace(my_mc.name); // my_mc

// Создаем мувиклип с помощью AS и добавляем его к my_mc
var another_mc:MovieClip = new MovieClip();
another_mc.name = "child_mc";
my_mc.addChild(another_mc);

// Переменная для доступа к созданному мувиклипу 
// автоматически не создается в  my_mc
trace(another_mc);  // [object MovieClip]
trace(my_mc.child_mc); // undefined
trace(my_mc.another_mc); // undefined
Если нужно получить ссылку на мувиклип (или любой DisplayObject) по его имени (свойству name), нужно использовать метод getChildByName();
Код:
trace(my_mc.getChildByName("child_mc"));  // [object MovieClip];
MerlinTwi: В дополнение к примеру стоит отметить, что поскольку любой мувиклип размещенный на timeline является динамическим, то можно просто создать в нем новое свойство ссылающееся на созданный мувиклип.
Код:
// Создаем мувиклип с помощью AS и добавляем его к my_mc
var another_mc:MovieClip = new MovieClip();
another_mc.name = "child_mc";
my_mc.addChild(another_mc);
// создаем в my_mc новое свойство «another_mc» для ссылки на новый мувиклип
my_mc.another_mc = another_mc;
// проверяем 
trace(my_mc.another_mc); // [object MovieClip]
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Старый 23.10.2006, 13:57
MerlinTwi вне форума Посмотреть профиль Отправить личное сообщение для MerlinTwi Посетить домашнюю страницу MerlinTwi Найти все сообщения от MerlinTwi
  № 10  
Ответить с цитированием
MerlinTwi
 
Аватар для MerlinTwi

Регистрация: Oct 2003
Адрес: Москва
Сообщений: 328
По умолчанию 65. Константы

ActionScript 3 позволяет определять константы, для этого используется ключевое слово const (const keyword), которое записывается вместо var (var keyword). Обычно константы записывают большими буквами, разделяя слова подчеркиванием, например, Event.ENTER_FRAME это константа.
Пример объявления константы:
Код:
package {
    
    import flash.display.Sprite;

    public class MyClass extends Sprite {

        public const MY_CONSTANT:String = "constant";

        public function MyClass () {
        }
    }
}
Константу нельзя переопределить. Хотя, если константа является ссылкой на объект, например массивом, то в такой массив можно добавлять новые элементы, или удалять старые, но нельзя присвоить константе ссылку на другой массив.
Код:
package {
    
    import flash.display.Sprite;

    public class MyClass extends Sprite {

        public const MY_CONSTANT:Array = new Array(1,2,3);

        public function MyClass () {
            MY_CONSTANT.push(4); // ok
            MY_CONSTANT = new Array(5,6,7); // error
        }
    }
}
__________________
Создатель: Бойцовский клуб | TimeZero | Sky2Fly
Я возьму сам.

Создать новую тему Ответ Часовой пояс GMT +4, время: 03:45.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра
Комбинированный вид Комбинированный вид

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 03:45.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.