diff --git a/1-js/1-getting-started/1-intro/article.md b/1-js/1-getting-started/1-intro/article.md
index 9dc5df7d..efa1111c 100644
--- a/1-js/1-getting-started/1-intro/article.md
+++ b/1-js/1-getting-started/1-intro/article.md
@@ -210,13 +210,13 @@ Adobe Flash -- кросс-браузерная платформа для мул
- Язык [CoffeeScript](http://coffeescript.org/) -- это "синтаксический сахар" поверх JavaScript, он сосредоточен на большей ясности и краткости кода. Как правило, его особенно любят программисты на Ruby.
- Язык [TypeScript](http://www.typescriptlang.org/) сосредоточен на добавлении строгой типизации данных, он предназначен для упрощения разработки и поддержки больших систем. Его разрабатывает MicroSoft.
-- Язык [Dart](https://www.dartlang.org/) предложен компанией Google как замена JavaScript, но другие ведущие интернет-компании объявили о своей незаинтересованности в Dart. Возможно, в будущем он может составить конкуренцию JS.
+- Язык [Dart](https://www.dartlang.org/) интересен тем, что он не только транслируется в JavaScript, как и другие языки, но и имеет свою независимую среду выполнения, которая даёт ему ряд возможностей и доступна для встраивания в приложения (вне браузера). Он разрабатывается компанией Google.
[smart header="ES6 и ES7 прямо сейчас"]
Существуют также трансляторы, которые берут код, использующий возможности будущих стандартов JavaScript, и преобразуют его в более старый вариант, который понимают все браузеры.
-Например, [6to5](https://6to5.org/).
+Например, [babeljs](https://babeljs.io/).
Благодаря этому, мы можем использовать многие возможности будущего уже сегодня.
[/smart]
diff --git a/1-js/4-data-structures/10-arguments-pseudoarray/article.md b/1-js/4-data-structures/10-arguments-pseudoarray/article.md
index 8db94177..12bf784e 100644
--- a/1-js/4-data-structures/10-arguments-pseudoarray/article.md
+++ b/1-js/4-data-structures/10-arguments-pseudoarray/article.md
@@ -268,72 +268,6 @@ function showWarning(width, height, title, contents) {
}
```
-### "Именованные аргументы"
-
-*Именованные аргументы* -- альтернативная техника работы с аргументами, которая вообще не использует `arguments`.
-
-Некоторые языки программирования позволяют передать параметры как-то так: `f(width=100, height=200)`, то есть по именам, а что не передано, тех аргументов нет. Это очень удобно в тех случаях, когда аргументов много, сложно запомнить их порядок и большинство вообще не надо передавать, по умолчанию подойдёт.
-
-Такая ситуация часто встречается в компонентах интерфейса. Например, у "меню" может быть масса настроек отображения, которые можно "подкрутить" но обычно нужно передать всего один-два главных параметра, а остальные возьмутся по умолчанию.
-
-В JavaScript для этих целей используется передача аргументов в виде объекта, а в его свойствах мы передаём параметры.
-
-Получается так:
-
-```js
-function showWarning(options) {
- var width = options.width || 200; // по умолчанию
- var height = options.height || 100;
-
- var title = options.title || "Предупреждение";
-
- // ...
-}
-
-showWarning({
-```
-
-Вызвать такую функцию очень легко. Достаточно передать объект аргументов, указав в нем только нужные:
-
-```js
-showWarning({
- contents: "Вы вызвали функцию" // и всё понятно!
-});
-```
-
-Сравним это с передачей аргументов через список:
-
-```js
-showWarning(null, null, "Предупреждение!");
-// мысль программиста "а что это за null, null в начале? ох, надо глядеть описание функции"
-```
-
-Не правда ли, объект -- гораздо проще и понятнее?
-
-Еще один бонус кроме красивой записи -- возможность повторного использования объекта аргументов:
-
-```js
-var opts = {
- width: 400,
- height: 200,
- contents: "Текст"
-};
-
-showWarning(opts);
-
-opts.contents = "Другой текст";
-
-*!*
-showWarning(opts); // вызвать с новым текстом, без копирования других аргументов
-*/!*
-```
-
-Именованные аргументы применяются во многих JavaScript-фреймворках.
-
-
-
-
-
## Устаревшее свойство arguments.callee [#arguments-callee]
[warn header="Используйте NFE вместо `arguments.callee`"]
@@ -407,6 +341,72 @@ function f3() {
В учебнике мы это свойство также не будем использовать.
+
+## "Именованные аргументы"
+
+*Именованные аргументы* -- альтернативная техника работы с аргументами, которая вообще не использует `arguments`.
+
+Некоторые языки программирования позволяют передать параметры как-то так: `f(width=100, height=200)`, то есть по именам, а что не передано, тех аргументов нет. Это очень удобно в тех случаях, когда аргументов много, сложно запомнить их порядок и большинство вообще не надо передавать, по умолчанию подойдёт.
+
+Такая ситуация часто встречается в компонентах интерфейса. Например, у "меню" может быть масса настроек отображения, которые можно "подкрутить" но обычно нужно передать всего один-два главных параметра, а остальные возьмутся по умолчанию.
+
+В JavaScript для этих целей используется передача аргументов в виде объекта, а в его свойствах мы передаём параметры.
+
+Получается так:
+
+```js
+function showWarning(options) {
+ var width = options.width || 200; // по умолчанию
+ var height = options.height || 100;
+
+ var title = options.title || "Предупреждение";
+
+ // ...
+}
+
+showWarning({
+```
+
+Вызвать такую функцию очень легко. Достаточно передать объект аргументов, указав в нем только нужные:
+
+```js
+showWarning({
+ contents: "Вы вызвали функцию" // и всё понятно!
+});
+```
+
+Сравним это с передачей аргументов через список:
+
+```js
+showWarning(null, null, "Предупреждение!");
+// мысль программиста "а что это за null, null в начале? ох, надо глядеть описание функции"
+```
+
+Не правда ли, объект -- гораздо проще и понятнее?
+
+Еще один бонус кроме красивой записи -- возможность повторного использования объекта аргументов:
+
+```js
+var opts = {
+ width: 400,
+ height: 200,
+ contents: "Текст"
+};
+
+showWarning(opts);
+
+opts.contents = "Другой текст";
+
+*!*
+showWarning(opts); // вызвать с новым текстом, без копирования других аргументов
+*/!*
+```
+
+Именованные аргументы применяются во многих JavaScript-фреймворках.
+
+
+
+
## Итого
diff --git a/1-js/9-prototypes/5-class-inheritance/article.md b/1-js/9-prototypes/5-class-inheritance/article.md
index f54db40a..80cf9349 100644
--- a/1-js/9-prototypes/5-class-inheritance/article.md
+++ b/1-js/9-prototypes/5-class-inheritance/article.md
@@ -354,5 +354,5 @@ function Rabbit() {
...Которой нет в прототипном подходе, потому что в процессе создания `new Rabbit` мы вовсе не обязаны вызывать конструктор родителя. Ведь методы находятся в прототипе.
-Поэтому прототипный подход стоит предпочитать функциональному как более быстрый и универсальный. А что касается красоты синтаксиса -- она сильно лучше в новом стандарте ES6, которым можно пользоваться уже сейчас, если взять транслятор [6to5](http://6to5.org/).
+Поэтому прототипный подход стоит предпочитать функциональному как более быстрый и универсальный. А что касается красоты синтаксиса -- она сильно лучше в новом стандарте ES6, которым можно пользоваться уже сейчас, если взять транслятор [babeljs](https://babeljs.io/).
diff --git a/1-js/9-prototypes/5-class-inheritance/class-inheritance-rabbit-run-animal.svg b/1-js/9-prototypes/5-class-inheritance/class-inheritance-rabbit-run-animal.svg
index a40ab833..31c8b462 100644
--- a/1-js/9-prototypes/5-class-inheritance/class-inheritance-rabbit-run-animal.svg
+++ b/1-js/9-prototypes/5-class-inheritance/class-inheritance-rabbit-run-animal.svg
@@ -10,7 +10,7 @@
jump: function
- run: function
+ run: function
Rabbit.prototype
diff --git a/1-js/9-prototypes/7-oop-errors/article.md b/1-js/9-prototypes/7-oop-errors/article.md
index 22134ca1..5a6de08c 100644
--- a/1-js/9-prototypes/7-oop-errors/article.md
+++ b/1-js/9-prototypes/7-oop-errors/article.md
@@ -14,7 +14,7 @@
Но могут быть и другие, например `PropertyError` -- эта ошибка будет возникать, если в прочитанном объекте нет свойства `name` или `age`.
-Реализуем её:
+Реализуем класс `PropertyError`:
```js
function PropertyError(property) {
@@ -34,17 +34,17 @@ function PropertyError(property) {
PropertyError.prototype = Object.create(Error.prototype);
```
-Посмотрим внимательнее на код -- в нём важные детали того, как можно позаботиться о стандартных свойствах объекта ошибки:
+В этом коде вы можете видеть ряд важных деталей, важных именно для ошибок:
- `name` -- имя ошибки.
-- Должно совпадать с именем функции, просто записали строку в него.
+- Должно совпадать с именем функции.
- `message` -- сообщение об ошибке.
- Несмотря на то, что `PropertyError` наследует от `Error` (последняя строка), конструктор у неё немного другой. Он принимает не сообщение об ошибке, а название свойства `property`, ну а сообщение генерируется из него.
-В результате в ошибке есть как стандартное свойство `message`, так и более точное `property`.
+В результате в объекте ошибки есть как стандартное свойство `message`, так и более точное `property`.
-Это полезная практика -- добавлять в объект ошибки свойства, более подробно описывающие ситуацию, которых нет в базовых объектах `Error`.
+Это частая практика -- добавлять в объект ошибки свойства, которых нет в базовых объектах `Error`, более подробно описывающие ситуацию для данного класса ошибок.
- `stack` -- стек вызовов, которые в итоге привели к ошибке.
- У встроенных объектов `Error` это свойство есть автоматически, вот к примеру:
```js
@@ -53,30 +53,28 @@ function f() {
alert( new Error().stack );
}
-f();
+f(); // выведет список вложенных вызовов, с номерами строк, где они были сделаны
```
-Если же объект делаем мы, то "по умолчанию" такого свойства у него не будет. Нам нужно как-то самим узнавать последовательность вложенных вызовов на текущий момент. Однако удобного способа сделать это в JavaScript нет, поэтому мы поступаем хитро и копируем его из нового объекта `new Error`, который генерируем тут же.
+Если же объект ошибки делаем мы, то "по умолчанию" у него такого свойства у него не будет. Нам нужно как-то самим узнавать последовательность вложенных вызовов на текущий момент. Однако удобного способа сделать это в JavaScript нет, поэтому мы поступаем хитро и копируем его из нового объекта `new Error`, который генерируем тут же.
В V8 (Chrome, Opera, Node.JS) есть нестандартное расширение [Error.captureStackTrace](https://code.google.com/p/v8-wiki/wiki/JavaScriptStackTraceApi), которое позволяет стек получать.
-Строка из кода выше:
+Это делает строка из кода выше:
```js
Error.captureStackTrace(this, PropertyError);
```
-Вызов записывает в объект `this` (текущий объект ошибки) стек вызовов, а второй аргумент -- это текущий конструктор, он не обязателен, но если есть, то говорит, что при генерации стека нужно на этой функции остановиться. В результате в стеке не будет информации о том, что делалось внутри конструктора `PropertyError`.
+Такой вызов записывает в объект `this` (текущий объект ошибки) стек вызовов, ну а второй аргумент -- вообще не обязателен, но если есть, то говорит, что при генерации стека нужно на этой функции остановиться. В результате в стеке будет информация о цепочке вложенных вызовов вплоть до вызова `PropertyError`.
То есть, будет последовательность вызовов до генерации ошибки, но не включая код самого конструктора ошибки, который, как правило, не интересен. Такое поведение максимально соответствует встроенным ошибкам JavaScript.
[smart header="Конструктор родителя здесь не нужен"]
-В коде выше не вызывается конструктор родителя. Обычно, когда мы наследуем, то мы вызываем его.
+Обычно, когда мы наследуем, то вызываем конструктор родителя. В данном случае вызов выглядел бы как `Error.call(this, message)`.
-В данном случае вызов выглядел бы как `Error.call(this, message)`.
-
-Однако, встроенный конструктор `Error` на редкость прост, он ничего полезного не делает, даже свойство `this.message` (не говоря уже об `name` и `stack`) не назначает. Поэтому и вызывать его здесь нет необходимости.
+Однако, встроенный конструктор `Error` ничего полезного не делает, даже свойство `this.message` (не говоря уже об `name` и `stack`) не назначает. Поэтому и вызывать его здесь нет необходимости.
[/smart]
@@ -93,7 +91,7 @@ function PropertyError(property) {
this.name = "PropertyError";
this.property = property;
- this.message = "Отсутствует свойство " + property;
+ this.message = "Ошибка в свойстве " + property;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, PropertyError);
@@ -137,49 +135,50 @@ try {
alert( "Здравствуйте, Аноним!" );
*/!*
} else {
- alert( err.message ); // Отсутствует свойство ...
+ alert( err.message ); // Ошибка в свойстве ...
}
} else if (err instanceof SyntaxError) {
- alert( "Ошибка в данных: " + err.message );
+ alert( "Ошибка в синтаксисе данных: " + err.message );
} else {
throw err; // неизвестная ошибка, не знаю что с ней делать
}
}
```
-Обратим внимание на проверку типа ошибки в `try..catch`.
+Всё работает -- и наша ошибка `PropertyError` и встроенная `SyntaxError` корректно генерируются, перехватываются, обрабатываются.
-Оператор `instanceof` поддерживает иерархию. Это значит, что если мы в дальнейшем решим как-то ещё уточнить тип ошибки `PropertyError`, то для объекта, наследующего от него, `e instanceof PropertyError` по-прежнему будет работать.
+Обратим внимание на проверку типа ошибки в `try..catch`. Оператор `instanceof` проверяет класс с учётом наследования. Это значит, что если мы в дальнейшем решим создать новый тип ошибки, наследующий от `PropertyError`, то проверка `err instanceof PropertyError` для класса-наследника тоже будет работать. Код получился расширяемым, это очень важно.
## Дальнейшее наследование
-Чтобы создать иерархию, нужно наследовать от `PropertyError`.
-
`PropertyError` -- это просто общего вида ошибка в свойстве. Создадим ошибку `PropertyRequiredError`, которая означает, что свойства нет.
-Типичный вид конструктора-наследника -- такой:
+Эт подвид `PropertyError`, так что унаследуем он неё. Общий вид конструктора-наследника -- стандартный:
```js
function PropertyRequiredError(property) {
+ // вызываем конструктор родителя и передаём текущие аргументы
PropertyError.apply(this, arguments);
...
}
```
-Можем ли мы просто вызвать конструктор родителя и ничего не делать в дополнение? Увы, нет.
+Достаточно ли в наследнике просто вызвать конструктор родителя? Увы, нет.
Если так поступить, то свойство `this.name` будет некорректным, да и `Error.captureStackTrace` тоже получит неправильную функцию вторым параметром.
-Можно ли как-то поправить конструктор родителя? Убрать из него все упоминания о конкретном классе `PropertyError` и сделать код универсальным?
+Можно ли как-то поправить конструктор родителя, чтобы от него было проще наследовать?
-Частично -- да. Как мы помним, существует свойство `constructor`, которое есть в `prototype` по умолчанию, и которое мы можем намеренно сохранить при наследовании:
+Для этого нужно убрать из него упоминания о конкретном классе `PropertyError`, чтобы сделать код универсальным. Частично -- это возможно. Как мы помним, существует свойство `constructor`, которое есть в `prototype` по умолчанию, и которое мы можем намеренно сохранить при наследовании.
+
+Исправим родителя `PropertyError` для более удобного наследования от него:
```js
function PropertyError(property) {
this.name = "PropertyError";
this.property = property;
- this.message = "Отсутствует свойство " + property;
+ this.message = "Ошибка в свойстве " + property;
if (Error.captureStackTrace) {
Error.captureStackTrace(this, *!*this.constructor*/!*); // (*)
@@ -195,9 +194,9 @@ PropertyError.prototype.constructor = PropertyError;
*/!*
```
-В строке `(*)` это свойство было использовано, чтобы получить конструктор уже не в виде жёсткой ссылки `PropertyError`, а тот, который использован для текущего объекта. В наследнике там будет `PropertyRequiredError`, как и задумано.
+В строке `(*)` вместо ссылки на `PropertyError` используем `constructor` чтобы получить именно конструктор для текущего объекта. В наследнике там будет `PropertyRequiredError`, как и задумано.
-Мы убрали одно упоминание, но с `this.name`, увы, сложности. Сейчас при наследовании оно будет всегда `"PropertyError"`. Все браузеры, кроме IE11-, поддерживают имя у Function Declaration, то есть имя функции можно было бы получить из `this.constructor.name`, но в IE11- это работать не будет.
+Мы убрали одну жёсткую привязку к `PropertyError`, но со второй (`this.name`), увы, сложности. Оно должно содержать имя ошибки, то есть, имя её функции-конструктора. Его можно получить через `this.name = this.constructor.name`, но в IE11- это работать не будет.
Если подерживать IE11-, то тут уж придётся в наследнике его записывать вручную.
@@ -218,13 +217,68 @@ var err = new PropertyRequiredError("age");
alert( err instanceof PropertyError ); // true
```
-Здесь заодно и `message` было перезаписано на более точное. Если хочется избежать записи и перезаписи, то можно оформить его в виде геттера через `Object.defineProperty`.
+Здесь заодно и `message` в наследнике было перезаписано на более точное. Если хочется избежать записи и перезаписи, то можно оформить его в виде геттера через `Object.defineProperty`.
## Итого
-- Чтобы наследовать встроенному классу ошибок `Error`, нужно самостоятельно позаботиться о `name`, `message` и `stack`.
-- Благодаря `instanceof` мы получили удобную поддержку иерархии ошибок, с возможностью в любой момент добавить новые классы, понятным кодом и предсказуемым поведением.
+- Чтобы наследовать от ошибок `Error`, нужно самостоятельно позаботиться о `name`, `message` и `stack`.
+- Благодаря тому, что `instanceof` поддерживает наследование, удобно организуются проверки на нужный тип. В иерархию ошибок можно в любой момент добавить новые классы, с понятным кодом и предсказуемым поведением.
-Чтобы создавать наследники от `Error` было проще, можно создать класс `CustomError`, записать в него универсальный код, наподобие `PropertyError` и далее наследовать уже от него.
+Чтобы создавать наследники от `Error` было проще, можно создать класс `CustomError`, записать в него универсальный код, наподобие `PropertyError` и далее наследовать уже от него:
+
+```js
+*!*
+// общего вида "наша" ошибка
+*/!*
+function CustomError(message) {
+ this.name = "CustomError";
+ this.message = message;
+
+ if (Error.captureStackTrace) {
+ Error.captureStackTrace(this, this.constructor);
+ } else {
+ this.stack = (new Error()).stack;
+ }
+
+}
+
+CustomError.prototype = Object.create(Error.prototype);
+CustomError.prototype.constructor = CustomError;
+
+*!*
+// наследник
+*/!*
+function PropertyError(property) {
+ CustomError.call(this, "Отсутствует свойство " + property)
+ this.name = "PropertyError";
+
+ this.property = property;
+}
+
+PropertyError.prototype = Object.create(CustomError.prototype);
+PropertyError.prototype.constructor = PropertyError;
+
+*!*
+// и ещё уровень
+*/!*
+function PropertyRequiredError(property) {
+ PropertyError.call(this, property);
+ this.name = 'PropertyRequiredError';
+ this.message = 'Отсутствует свойство ' + property;
+}
+
+PropertyRequiredError.prototype = Object.create(PropertyError.prototype);
+PropertyRequiredError.prototype.constructor = PropertyRequiredError;
+
+*!*
+// использование
+*/!*
+var err = new PropertyRequiredError("age");
+// пройдёт проверку
+alert( err instanceof PropertyRequiredError ); // true
+alert( err instanceof PropertyError ); // true
+alert( err isntanceof CustomError ); // true
+alert( err isntanceof Error ); // true
+```
diff --git a/1-js/9-prototypes/8-mixins/article.md b/1-js/9-prototypes/8-mixins/article.md
new file mode 100644
index 00000000..7cf96a71
--- /dev/null
+++ b/1-js/9-prototypes/8-mixins/article.md
@@ -0,0 +1,174 @@
+# Примеси
+
+В JavaScript невозможно унаследовать от двух и более объектов. Ссылка `__proto__` -- только одна.
+
+Но потребность такая существует -- к примеру, мы написали код, релизующий методы работы с шаблонизатором или методы по обмену событиями, и хочется легко и непринуждённо добавлять эти возможности к любому классу.
+
+Обычно это делают через примеси.
+
+Примесь (англ. mixin) -- класс или объект, реализующий какое-либо чётко выделенное поведение. Используется для уточнения поведения других классов, не предназначен для самостоятельного использования.
+
+
+
+## Пример примеси
+
+Самый простой вариант примеси -- это объект с полезными методами, которые мы просто копируем в нужный прототип.
+
+Например:
+
+```js
+//+ run
+*!*
+// примесь
+*/!*
+var sayHiMixin = {
+ sayHi: function() {
+ alert("Привет " + this.name);
+ },
+ sayBye: function() {
+ alert("Пока " + this.name);
+ }
+};
+
+*!*
+// использование:
+*/!*
+function User(name) {
+ this.name = name;
+}
+
+// передать методы примеси
+for(var key in sayHiMixin) User.prototype[key] = sayHiMixin[key];
+
+// User "умеет" sayHi
+new User("Вася").sayHi(); // Привет Вася
+```
+
+Как видно из примера, методы примеси активно используют `this` и предназначены именно для запуска в контексте "объекта-носителя примеси".
+
+Если какие-то из методов примеси не нужны -- их можно перезаписать своими после копирования.
+
+
+## Примесь для событий
+
+Теперь пример из реальной жизни.
+
+Важный аспект, который может понадобиться объектам -- это умение работать с событиями.
+
+То есть, чтобы объект мог специальным вызовом генерировать "уведомление о событии", а на эти уведомления другие объекты могли "подписываться", чтобы их получать.
+
+Например, объект "Пользователь" при входе на сайт может генерировать событие `"login"`, а другие объекты, например "Календарь" может такие уведомления получать и подгружать информацию о пользователе.
+
+Или объект "Меню" может при выборе пункта меню генерировать событие `"select"` с информацией о выбранном пункте меню, а другие объекты -- подписавшись на это событие, будут узнавать об этом.
+
+События -- это средство "поделиться информацией" с неопределённым кругом заинтересованных лиц. А там уже кому надо -- тот среагирует.
+
+Примесь `eventMixin`, реализующая события:
+
+```js
+var eventMixin = {
+
+ /**
+ * Подписка на событие
+ * Использование:
+ * menu.on('select', function(item) { ... }
+ */
+ on: function(eventName, handler) {
+ if (!this._eventHandlers) this._eventHandlers = {};
+ if (!this._eventHandlers[eventName]) {
+ this._eventHandlers[eventName] = [];
+ }
+ this._eventHandlers[eventName].push(handler);
+ },
+
+ /**
+ * Прекращение подписки
+ * menu.off('select', handler)
+ */
+ off: function(eventName, handler) {
+ var handlers = this._eventHandlers && this._eventHandlers[eventName];
+ if (!handlers) return;
+ for(var i=0; i
+- `.on(имя события, функция)` -- назначает функцию к выполнению при наступлении события с данным именем. Такие функции хранятся в защищённом свойстве объекта `_eventHandlers`.
+- `.off(имя события, функция)` -- удаляет функцию из списка предназначенных к выполнению.
+- `.trigger(имя события, аргументы)` -- генерирует событие, при этом вызываются все назначенные на него функции, и им передаются аргументы.
+
+
+Использование:
+
+```js
+//+ run
+// Класс Menu с примесью eventMixin
+function Menu() {
+ // ...
+}
+
+for(var key in eventMixin) Menu.prototype[key] = eventMixin[key];
+
+// Генерирует событие select при выборе значения
+Menu.prototype.choose = function(value) {
+*!*
+ this.trigger("select", value);
+*/!*
+}
+
+// Создадим меню
+var menu = new Menu();
+
+// При наступлении события select вызвать эту функцию
+*!*
+menu.on("select", function(value) {
+ alert("Выбрано значение " + value);
+});
+*/!*
+
+// Запускаем выбор (сработает событие)
+menu.choose("123");
+```
+
+...То есть, смысл событий -- обычно в том, что объект, в процессе своей деятельности, внутри себя (`this.trigger`) генерирует уведомления, на которые внешний код через `menu.on(...)` может быть подписан. И узнавать из них ценную информцию о происходящем, например -- что выбран некий пункт меню.
+
+Один раз написав методы `on/off/trigger` в примеси, мы затем можем использовать их во множестве прототипов.
+
+## Итого
+
+
+- Примесь -- объект, содержащий методы и свойства для реализации конкретного функционала.
+Возможны вариации этого приёма проектирования. Например, примесь может предусматривать конструктор, который должен запускаться в конструкторе объекта. Но как правило просто набора методов хватает.
+- Для добавления примеси в класс -- её просто "подмешивают" в прототип.
+- "Подмешать" можно сколько угодно примесей, но если имена методов в разных примесях совпадают, то возможны конфликты. Их уже разрешать -- разработчику. Например, можно заменить конфликтующий метод на свой, который будет решать несколько задач сразу. Конфликты при грамотно оформленных примесях возникают редко.
+
+
+
+
+
+
+
diff --git a/11-regular-expressions-javascript/1-regexp-introduction/article.md b/10-regular-expressions-javascript/1-regexp-introduction/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/1-regexp-introduction/article.md
rename to 10-regular-expressions-javascript/1-regexp-introduction/article.md
diff --git a/11-regular-expressions-javascript/13-regexp-ahchors/1-start-end/solution.md b/10-regular-expressions-javascript/10-regexp-ahchors/1-start-end/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/13-regexp-ahchors/1-start-end/solution.md
rename to 10-regular-expressions-javascript/10-regexp-ahchors/1-start-end/solution.md
diff --git a/11-regular-expressions-javascript/13-regexp-ahchors/1-start-end/task.md b/10-regular-expressions-javascript/10-regexp-ahchors/1-start-end/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/13-regexp-ahchors/1-start-end/task.md
rename to 10-regular-expressions-javascript/10-regexp-ahchors/1-start-end/task.md
diff --git a/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/solution.md b/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/solution.md
new file mode 100644
index 00000000..5a91a896
--- /dev/null
+++ b/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/solution.md
@@ -0,0 +1,21 @@
+Двузначное шестнадцатиричное число -- это ``pattern`[0-9a-f]{2}` (с учётом флага ``pattern`/i`).
+
+Нам нужно одно такое число, и за ним ещё 5 с двоеточиями перед ними: ``pattern`[0-9a-f]{2}(:[0-9a-f]{2}){5}`
+
+И, наконец, совпадение должно начинаться в начале строки и заканчиваться -- в конце. То есть, строка целиком должна подходить под шаблон. Для этого обернём шаблон в ``pattern`^...$`.
+
+Итого, в действии:
+
+
+```js
+//+ run
+var re = /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/i;
+
+alert( re.test('01:32:54:67:89:AB') ); // true
+
+alert( re.test('0132546789AB') ); // false (нет двоеточий)
+
+alert( re.test('01:32:54:67:89') ); // false (5 чисел, а не 6)
+
+alert( re.test('01:32:54:67:89:ZZ') ) // false (ZZ в конце)
+```
diff --git a/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/task.md b/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/task.md
new file mode 100644
index 00000000..fecf7dd0
--- /dev/null
+++ b/10-regular-expressions-javascript/10-regexp-ahchors/2-test-mac/task.md
@@ -0,0 +1,20 @@
+# Проверьте MAC-адрес
+
+MAC-адрес сетевого интерфейса состоит из шести двузначиных шестандцатиричных чисел, разделённых двоеточием.
+
+Например: ``subject`'01:32:54:67:89:AB'`.
+
+Напишите регулярное выражение, которое по строке проверяет, является ли она корректным MAC-адресом.
+
+Использование:
+```js
+var re = ваш регэксп
+
+alert( re.test('01:32:54:67:89:AB') ); // true
+
+alert( re.test('0132546789AB') ); // false (нет двоеточий)
+
+alert( re.test('01:32:54:67:89') ); // false (5 чисел, а не 6)
+
+alert( re.test('01:32:54:67:89:ZZ') ) // false (ZZ в конце)
+```
diff --git a/11-regular-expressions-javascript/13-regexp-ahchors/article.md b/10-regular-expressions-javascript/10-regexp-ahchors/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/13-regexp-ahchors/article.md
rename to 10-regular-expressions-javascript/10-regexp-ahchors/article.md
diff --git a/11-regular-expressions-javascript/14-regexp-multiline-mode/article.md b/10-regular-expressions-javascript/11-regexp-multiline-mode/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/14-regexp-multiline-mode/article.md
rename to 10-regular-expressions-javascript/11-regexp-multiline-mode/article.md
diff --git a/10-regular-expressions-javascript/12-regexp-lookahead/article.md b/10-regular-expressions-javascript/12-regexp-lookahead/article.md
new file mode 100644
index 00000000..2cd4438c
--- /dev/null
+++ b/10-regular-expressions-javascript/12-regexp-lookahead/article.md
@@ -0,0 +1,4 @@
+# Предпросмотр (неготово)
+
+Требуется добавить главу про предпросмотр lookahead.
+
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/article.md b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/article.md
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/article.md
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy1.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy1.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy1.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy1.png
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy11.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy11.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy11.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy11.png
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy2.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy2.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy2.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy2.png
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy3.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy3.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy3.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy3.png
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy4.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy4.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy4.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy4.png
diff --git a/11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy5.png b/10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy5.png
similarity index 100%
rename from 11-regular-expressions-javascript/17-regexp-infinite-backtracking-problem/bad_backtrack_greedy5.png
rename to 10-regular-expressions-javascript/13-regexp-infinite-backtracking-problem/bad_backtrack_greedy5.png
diff --git a/11-regular-expressions-javascript/2-regexp-methods/article.md b/10-regular-expressions-javascript/2-regexp-methods/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/2-regexp-methods/article.md
rename to 10-regular-expressions-javascript/2-regexp-methods/article.md
diff --git a/11-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/solution.md b/10-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/solution.md
rename to 10-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/solution.md
diff --git a/11-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/task.md b/10-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/task.md
rename to 10-regular-expressions-javascript/3-regexp-character-classes/1-find-time-hh-mm/task.md
diff --git a/11-regular-expressions-javascript/3-regexp-character-classes/article.md b/10-regular-expressions-javascript/3-regexp-character-classes/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/3-regexp-character-classes/article.md
rename to 10-regular-expressions-javascript/3-regexp-character-classes/article.md
diff --git a/11-regular-expressions-javascript/3-regexp-character-classes/hello-java-boundaries.svg b/10-regular-expressions-javascript/3-regexp-character-classes/hello-java-boundaries.svg
similarity index 100%
rename from 11-regular-expressions-javascript/3-regexp-character-classes/hello-java-boundaries.svg
rename to 10-regular-expressions-javascript/3-regexp-character-classes/hello-java-boundaries.svg
diff --git a/11-regular-expressions-javascript/3-regexp-character-classes/love-html5-classes.svg b/10-regular-expressions-javascript/3-regexp-character-classes/love-html5-classes.svg
similarity index 100%
rename from 11-regular-expressions-javascript/3-regexp-character-classes/love-html5-classes.svg
rename to 10-regular-expressions-javascript/3-regexp-character-classes/love-html5-classes.svg
diff --git a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/1-find-range-1/solution.md b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/1-find-range-1/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/1-find-range-1/solution.md
rename to 10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/1-find-range-1/solution.md
diff --git a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/1-find-range-1/task.md b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/1-find-range-1/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/1-find-range-1/task.md
rename to 10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/1-find-range-1/task.md
diff --git a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/2-find-time-2-formats/solution.md b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/2-find-time-2-formats/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/2-find-time-2-formats/solution.md
rename to 10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/2-find-time-2-formats/solution.md
diff --git a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md
similarity index 87%
rename from 11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md
rename to 10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md
index 13e0a440..dd03af58 100644
--- a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md
+++ b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/2-find-time-2-formats/task.md
@@ -1,4 +1,4 @@
-# Найдите время
+# Найдите время в одном из форматов
Время может быть в формате `часы:минуты` или `часы-минуты`. И часы и минуты состоят из двух цифр, например `09:00`, `21-30`.
diff --git a/11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/article.md b/10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/5-regexp-character-sets-and-ranges/article.md
rename to 10-regular-expressions-javascript/4-regexp-character-sets-and-ranges/article.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/1-find-text-manydots/solution.md b/10-regular-expressions-javascript/5-regexp-quantifiers/1-find-text-manydots/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/1-find-text-manydots/solution.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/1-find-text-manydots/solution.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/1-find-text-manydots/task.md b/10-regular-expressions-javascript/5-regexp-quantifiers/1-find-text-manydots/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/1-find-text-manydots/task.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/1-find-text-manydots/task.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/2-find-html-colors-6hex/solution.md b/10-regular-expressions-javascript/5-regexp-quantifiers/2-find-html-colors-6hex/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/2-find-html-colors-6hex/solution.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/2-find-html-colors-6hex/solution.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/2-find-html-colors-6hex/task.md b/10-regular-expressions-javascript/5-regexp-quantifiers/2-find-html-colors-6hex/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/2-find-html-colors-6hex/task.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/2-find-html-colors-6hex/task.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/3-find-decimal-positive-numbers/solution.md b/10-regular-expressions-javascript/5-regexp-quantifiers/3-find-decimal-positive-numbers/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/3-find-decimal-positive-numbers/solution.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/3-find-decimal-positive-numbers/solution.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/3-find-decimal-positive-numbers/task.md b/10-regular-expressions-javascript/5-regexp-quantifiers/3-find-decimal-positive-numbers/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/3-find-decimal-positive-numbers/task.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/3-find-decimal-positive-numbers/task.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/4-find-decimal-numbers/solution.md b/10-regular-expressions-javascript/5-regexp-quantifiers/4-find-decimal-numbers/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/4-find-decimal-numbers/solution.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/4-find-decimal-numbers/solution.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/4-find-decimal-numbers/task.md b/10-regular-expressions-javascript/5-regexp-quantifiers/4-find-decimal-numbers/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/4-find-decimal-numbers/task.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/4-find-decimal-numbers/task.md
diff --git a/11-regular-expressions-javascript/7-regexp-quantifiers/article.md b/10-regular-expressions-javascript/5-regexp-quantifiers/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/7-regexp-quantifiers/article.md
rename to 10-regular-expressions-javascript/5-regexp-quantifiers/article.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/1-lazy-greedy/solution.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/1-lazy-greedy/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/1-lazy-greedy/solution.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/1-lazy-greedy/solution.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/1-lazy-greedy/task.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/1-lazy-greedy/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/1-lazy-greedy/task.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/1-lazy-greedy/task.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/2-difference-find-quote/solution.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/2-difference-find-quote/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/2-difference-find-quote/solution.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/2-difference-find-quote/solution.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/2-difference-find-quote/task.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/2-difference-find-quote/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/2-difference-find-quote/task.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/2-difference-find-quote/task.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/3-find-html-comments/solution.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/3-find-html-comments/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/3-find-html-comments/solution.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/3-find-html-comments/solution.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/3-find-html-comments/task.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/3-find-html-comments/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/3-find-html-comments/task.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/3-find-html-comments/task.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/solution.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/solution.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/solution.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/4-find-html-tags-greedy-lazy/task.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/article.md b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/article.md
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/article.md
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy1.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy1.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy1.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy1.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy2.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy2.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy2.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy2.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy3.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy3.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy3.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy3.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy4.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy4.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy4.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy4.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy5.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy5.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy5.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy5.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy6.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy6.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_greedy6.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_greedy6.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy3.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy3.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy3.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy3.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy4.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy4.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy4.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy4.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy5.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy5.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy5.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy5.svg
diff --git a/11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy6.svg b/10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy6.svg
similarity index 100%
rename from 11-regular-expressions-javascript/8-regexp-greedy-and-lazy/witch_lazy6.svg
rename to 10-regular-expressions-javascript/6-regexp-greedy-and-lazy/witch_lazy6.svg
diff --git a/11-regular-expressions-javascript/9-regexp-groups/1-find-webcolor-3-or-6/solution.md b/10-regular-expressions-javascript/7-regexp-groups/1-find-webcolor-3-or-6/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/1-find-webcolor-3-or-6/solution.md
rename to 10-regular-expressions-javascript/7-regexp-groups/1-find-webcolor-3-or-6/solution.md
diff --git a/11-regular-expressions-javascript/9-regexp-groups/1-find-webcolor-3-or-6/task.md b/10-regular-expressions-javascript/7-regexp-groups/1-find-webcolor-3-or-6/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/1-find-webcolor-3-or-6/task.md
rename to 10-regular-expressions-javascript/7-regexp-groups/1-find-webcolor-3-or-6/task.md
diff --git a/11-regular-expressions-javascript/9-regexp-groups/2-parse-expression/solution.md b/10-regular-expressions-javascript/7-regexp-groups/2-parse-expression/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/2-parse-expression/solution.md
rename to 10-regular-expressions-javascript/7-regexp-groups/2-parse-expression/solution.md
diff --git a/11-regular-expressions-javascript/9-regexp-groups/2-parse-expression/task.md b/10-regular-expressions-javascript/7-regexp-groups/2-parse-expression/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/2-parse-expression/task.md
rename to 10-regular-expressions-javascript/7-regexp-groups/2-parse-expression/task.md
diff --git a/11-regular-expressions-javascript/9-regexp-groups/article.md b/10-regular-expressions-javascript/7-regexp-groups/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/article.md
rename to 10-regular-expressions-javascript/7-regexp-groups/article.md
diff --git a/11-regular-expressions-javascript/9-regexp-groups/regexp-nested-groups.svg b/10-regular-expressions-javascript/7-regexp-groups/regexp-nested-groups.svg
similarity index 100%
rename from 11-regular-expressions-javascript/9-regexp-groups/regexp-nested-groups.svg
rename to 10-regular-expressions-javascript/7-regexp-groups/regexp-nested-groups.svg
diff --git a/11-regular-expressions-javascript/10-regexp-backreferences/1-find-matching-bbtags/solution.md b/10-regular-expressions-javascript/8-regexp-backreferences/1-find-matching-bbtags/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/10-regexp-backreferences/1-find-matching-bbtags/solution.md
rename to 10-regular-expressions-javascript/8-regexp-backreferences/1-find-matching-bbtags/solution.md
diff --git a/11-regular-expressions-javascript/10-regexp-backreferences/1-find-matching-bbtags/task.md b/10-regular-expressions-javascript/8-regexp-backreferences/1-find-matching-bbtags/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/10-regexp-backreferences/1-find-matching-bbtags/task.md
rename to 10-regular-expressions-javascript/8-regexp-backreferences/1-find-matching-bbtags/task.md
diff --git a/11-regular-expressions-javascript/10-regexp-backreferences/article.md b/10-regular-expressions-javascript/8-regexp-backreferences/article.md
similarity index 100%
rename from 11-regular-expressions-javascript/10-regexp-backreferences/article.md
rename to 10-regular-expressions-javascript/8-regexp-backreferences/article.md
diff --git a/11-regular-expressions-javascript/12-regexp-alternation/1-find-programming-language/solution.md b/10-regular-expressions-javascript/9-regexp-alternation/1-find-programming-language/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/12-regexp-alternation/1-find-programming-language/solution.md
rename to 10-regular-expressions-javascript/9-regexp-alternation/1-find-programming-language/solution.md
diff --git a/11-regular-expressions-javascript/12-regexp-alternation/1-find-programming-language/task.md b/10-regular-expressions-javascript/9-regexp-alternation/1-find-programming-language/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/12-regexp-alternation/1-find-programming-language/task.md
rename to 10-regular-expressions-javascript/9-regexp-alternation/1-find-programming-language/task.md
diff --git a/11-regular-expressions-javascript/12-regexp-alternation/2-match-quoted-string/solution.md b/10-regular-expressions-javascript/9-regexp-alternation/2-match-quoted-string/solution.md
similarity index 100%
rename from 11-regular-expressions-javascript/12-regexp-alternation/2-match-quoted-string/solution.md
rename to 10-regular-expressions-javascript/9-regexp-alternation/2-match-quoted-string/solution.md
diff --git a/11-regular-expressions-javascript/12-regexp-alternation/2-match-quoted-string/task.md b/10-regular-expressions-javascript/9-regexp-alternation/2-match-quoted-string/task.md
similarity index 100%
rename from 11-regular-expressions-javascript/12-regexp-alternation/2-match-quoted-string/task.md
rename to 10-regular-expressions-javascript/9-regexp-alternation/2-match-quoted-string/task.md
diff --git a/10-regular-expressions-javascript/9-regexp-alternation/3-match-exact-tag/solution.md b/10-regular-expressions-javascript/9-regexp-alternation/3-match-exact-tag/solution.md
new file mode 100644
index 00000000..0a422af1
--- /dev/null
+++ b/10-regular-expressions-javascript/9-regexp-alternation/3-match-exact-tag/solution.md
@@ -0,0 +1,18 @@
+
+Начало шаблона очевидно: ``pattern`