Время от времени в Twitter, Reddit или StackOverflow возникает такой вопрос.

Почти каждый, кто работал с Sass хотя бы раз задавал его себе - что выбрать, Compass или Bourbon?

Оба проекта Compass и Bourbon являются фреймворками под Sass. Sass, как вы помните, является препроцессором CSS, не правда ли? Хорошо. Точно также, как если бы вы имели дело с jQuery или Backbone при работе в JavaScript, использование фреймворка для Sass облегчает работу с последним.

В этой статье я выскажу свое мнение по поводу использования Compass или Bourbon. Но, прежде всего, нужно сделать небольшой экскурс в историю.

История Compass и Bourbon

Compass заявляет о себе как о CSS фреймворке под Sass. Он поддерживается Chris Eppstein, одним из двух разработчиков Sass. Compass - это наполовину Ruby и наполовину Sass, он представляет из себя полный набор миксинов и инструмент под Sass. Более подробно о нем позже.

С другой стороны, Bourbon создан на Sass и для Sass великолепной командой разработчиков Thoughtbot. Если верить домашней странице проекта, Bourbon - это скорее библиотека, нежели фреймворк; простая и легковесная библиотека миксинов под Sass.

В итоге мы имеем с одной стороны Ruby/Sass фреймворк, а с другой стороны мы имеем библиотеку Sass. Совершенно разные вещи, не правда ли?

Миксины Compass и Bourbon

Если спросить пользователя Compass/Bourbon, для какой цели он использует данный инструмент, высоки шансы услышать однозначный ответ: для кросс-браузерной совместимости. Возможно, он ответит не совсем так, но ответ будет иметь приблизительно такой же смысл.

Как Compass, так и Bourbon являются огромной коллекцией миксинов для создания CSS3-эффектов; благодаря этим миксинам отпадает необходимость детально вникать в браузерные префиксы или CSS-уловки (CSS hacks).

Ниже показан пример миксина box-sizing в обоих библиотеках Compass и Bourbon. Как видим, синтаксис и результат работы одинаков:

// Compass

  .boxsizing {
    @include box-sizing(border-box);
  }

// Bourbon

.boxsizing {
  @include box-sizing(border-box);
}

Тот факт, что Compass и Bourbon имеют одинаковый синтаксис для большинства миксинов, делает переход в использовании с Compass на Bourbon и с Bourbon на Compass очень легким.

Существует одно важное различие между этими инструментами: начиная с Compass 1.0 (вышел совместно с Sass 3.3), Compass получает информацию с сайта Can I Use. Это означает, что почти всегда данный фреймворк получает самую свежую информацию по браузерным префиксам.

В то время как библиотека Bourbon полностью зависит от обновлений, выпускаемых разработчиками данной библиотеки.

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

Типографика в Compass и Bourbon

Оба - Compass и Bourbon - предоставляют набор готовых миксинов, переменных и функций для работы с типографикой. Помимо этого, Compass имеет в своем составе полноценный модуль для создания вертикального ритма, включая набор переменных и пару миксинов:

// Compass Vertical Rhythm
  $base-font-size: 16px;
  $base-line-height: 1.35;
  $rhythm-unit: em;

  element{
    @include adjust-font-size-to(42px);
  }

// CSS result
element{
  font-size: 2.625em;
  line-height: 1.06071em;
}

У Compass также есть возможность поддержки единиц измерения rem с откатом к px, если вы используете rem в качестве значения переменной $rhythm-unit вместо em.

Есть еще целая куча различных настроек, так что если вы являетесь поклонником типографики, Compass сможет ответить всем вашим требованиям.

Библиотека Bourbon обладает менее впечатляющим набором возможностей для работы с типографикой; однако у нее также есть все для быстрого старта разработки. В Bourbon есть не только возможность преобразования пикселей в em или rem, но также такие великолепные функции, как golden-ratio() и modular-scale().

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

Собственно, Thoughtbot решили адресовать вопрос с типографикой другому их проекту (который может использоваться совместно с Bourbon) под названием Bitters. Более подробно о нем будет говориться в конце статьи.

CSS-сетки в Compass и Bourbon

Разве можно назвать фреймворк полноценным, если у него нет системы сеток (grid system), верно?

Фреймворк Compass имеет в составе систему Blueprint Grid, которая, насколько я знаю, не имеет ничего общего со старым фреймворком под названием Blueprint. Стоит сказать, что система Blueprint фреймворка Compass является неполноценной.

Среди всех людей, которые используют Compass и с которыми мне приходилось общаться, только один пробовал работать с Blueprint. Эта система настолько несовершенна, что Chris Eppstein решил убрать ее из Compass начиная с версии 1.0.0 (что соответствует Sass 3.3).

В тоже время библиотека Bourbon предоставляет пару миксинов, с помощью которых можно создать свою собственную сетку. Это функции flex-* (не стоит путать с моделью Flexbox) и grid-width().

Помимо этого, у команды Thoughtbot имеется своя собственная, отдельная от Bourbon, система сеток под названием Neat, которая позиционируется как легковесный семантичный фреймворк под Sass и Bourbon.

Таким образом, библиотека Bourbon не имеет в своем составе системы сеток (grid system), но можно свободно воспользоваться для этой цели фреймворком Neat.

Если сделать краткий итог по вопросу системы сеток, то можно сказать следующее. Если необходима система сеток с тесной интеграцией Sass-фреймворка, то мое мнение - это использовать связку Bourbon + Neat. Оба проекта были созданы одними и теми же людьми; в обоих проектах была заложена одна и таже основная идея. Это можно сравнить как два кусочка одного пазла.

Примечание переводчика: автор статьи упоминает о стороннем проекте Neat (система сеток) для библиотеки Bourbon. Но почему-то ни словом не говорит о проекте Susy?

Helpers

Одной интересной вещью Sass-фреймворков являются так называемые helpers. Helpers - это предустановленные CSS-правила, которые можно использовать в таблицах стилей как есть, для сокращения времени разработки проекта.

Например, Compass имеет набор helpers для float-clearing (включая несколько способов, как это сделать) и несколько CSS-хаков для старых версий браузера Internet Explorer; сброс стилей (несколько вариантов); несколько способов замещения текста изображением и многое другое.

В Bourbon такие helpers называются add-ons, но они выполняют туже работу; правда, в Bourbon их немного меньше, чем в Compass. Стоит сказать, что команда Thoughtbot включила с состав проекта Bitters большое количество helpers. Как было уже сказано выше, Bitters является сторонним проектом, который имеет прекрасную интеграцию с Bourbon и служит для целей создания типографики в проекте.

Спрайты Compass и Bourbon

Спросите пользователя Compass, почему он из месяца в месяц и из года в год использует эту библиотеку; клянусь, что в ответ услышим что-то о системе создания спрайтов. Это та вещь, которую Compass действительно выполняет хорошо. Благодаря тому, что Compass написан на языке Ruby, он может выполнять некоторые очень интересные вещи с файловой системой. Одной из таких фишек является способность создавать спрайты из коллекции изображений, размещенных в одной папке. Замечательно, не правда ли?

// Пример создания спрайтов в Compass
  @import "icon/*.png";
  @include all-icon-sprites;

Помимо автомагического способа генерации спрайтов, Compass предоставляет пару интересных функций для доступа к файлу изображений прямо из таблицы стилей, наподобие image-width(), image-height() и даже inline-image() для преобразования файла изображения в Base64:

// Функции Compass доступа к файловой системе
.logo{
  $image: "path/to/my/logo.png";
  width: image-width($image);
  height: image-height($image);
  background: inline-image($image) no-repeat;
}

Так как Bourbon построен только на Sass, у него нет возможности доступа к файловой системе и эта библиотека не может выполнить таких вещей, какие может Compass. Поэтому, если вы ищете способ динамического создания спрайтов и не хотите заморачиваться с такими менеджерами задач, как Grunt, Gulp или Ant, то выбор для вас очевиден.

Итог

И так, что же получаем в итоге - Compass или Bourbon?

Если спросить об этом меня, то я отвечу: никакой из них. Долгое время я был пользователем библиотеки Compass, покуда не отказался от его применения.

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

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

Библиотека Compass великолепно подходит для этих целей, но она выполняет свою задачу медленно, слишком медленно. Поэтому, если вас не устраивает такой факт, то посмотрите в сторону Bourbon. Эта библиотека замечательно быстрая хотя бы потому, что состоит из одних Sass-миксинов, выполняющих задачи Sass внутри таблиц стилей Sass.

Если вы решили использовать библиотеку Bourbon, то я бы рекомендовал вам также задействовать другие проекты команды Thoughtbot: Neat в качестве системы сеток (grid system), Bitters для типографики и еще не упомянутый до этого момента Refills (который является полной альтернативой фреймворка Bootstrap) с полным набором компонентов, готовый для использования в создаваемом проекте.

Примечание переводчика: в этой статье дан сравнительный обзор двух фреймворков - Compass и Bourbon. Лично для меня было бы интереснее посмотреть практические примеры использования библиотеки Bourbon.

Оригинал статьи: Sass Frameworks: Compass or Bourbon? от автора Hugo Giraudel.


Под локальным сервером XAMPP можно создавать неограниченное количество виртуальных хостов.

Что такое виртуальный хост (Virtual Host)? Применительно в серверу XAMPP - это поддиректории, в которых размещаются отдельные сайты. То есть, имеется директория htdocs, а в ней размещены поддиректории site_1, site_2, site_3 (или же так - redface, football, greenpark, название может быть любым).

В каждой из этих поддиректорий распакован и установлен движок CMS WordPress (к примеру). Вот эти поддиректории site_1, site_2, site_3 и являются виртуальными хостами под локальным сервером XAMPP.

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

Настройка виртуальных хостов на XAMPP под Linux Mint почти ничем не отличается от подобной настройки под Windows, меняются только пути конфигурационных файлов. Весь процесс настройки можно свести к двум шагам:

  1. Настройка хостов в файле /etc/hosts
  2. Настройка виртуальных хостов в файле /opt/lampp/etc/extra/httpd-vhosts.conf

Ниже на примере расмотрим подробное описание создания одного виртуального хоста на XAMPP под Linux Mint.

Создание поддиректории виртуального хоста (Virtual Host)

Для начала подготовим место, где будет располагаться будущий виртуальный хост. Для этого создадим поддиректорию redface (имя произвольное) и обязательно разместим в ней индексный файл index.html:

$ sudo mkdir -p /opt/lampp/htdocs/redface
$ sudo touch /opt/lampp/htdocs/redface/index.html

Виртуальный хост с именем redface почти создан. Осталось “сказать” об этом локальному серверу XAMPP и операционной системе Linux Mint.

Редактирование файла /etc/hosts

Операционной системе Linux Mint нужно “сказать”, что виртуальный хост redface размещен по адресу 127.0.0.1. Для этого открываем для редактирования файл /etc/hosts командой:

$ sudo nano -w /etc/hosts

… и дописываем в нем строку 127.0.0.1 redface.dev:

127.0.0.1 localhost
127.0.1.1 zmk

# Virtual hosts
127.0.0.1 redface.dev

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

Сохраняем Ctrl+O и выходим Ctrl+X из редактора nano.

Включение поддержки виртуального хоста в XAMPP

По умолчанию в настройках XAMPP отключена поддержка виртуальных хостов. Для включения такой возможности нужно отредактировать конфигурационный файл httpd.conf сервера Apache.

Для этого открываем его командой:

$ sudo nano -w /opt/lampp/etc/httpd.conf

В открытом файле httpd.conf нужно найти (в редакторе это сочетание Ctrl+W) строку # Virtual hosts и раскомментировать (снять знак решетки #) строку:

#Include etc/extra/httpd-vhosts.conf

Создание виртуального хоста в файле httpd-vhosts.conf

Открываем для редактирования файл httpd-vhosts.conf и знакомимся с его содержимым:

$ sudo nano -w /opt/lampp/etc/extra/httpd-vhosts.conf

В начале идет много закомментированных строк с кратким описанием виртуального хоста и принципом его создания в данном файле. Можно смело почистить файл httpd-vhosts.conf от этого мусора.

Далее идут два блока с открывающим тегом <VirtualHost *:80> и закрывающим тегом </VirtualHost>. Данные блоки являются виртуальными хостами - их два по умолчанию, но можно добавить сколько необходимо.

Эти блоки не рабочие, а всего лишь примеры, как нужно создавать свой собственный виртуальный хост. Внутри тегов <VirtualHost *:80>/</VirtualHost> размещена служебная информация - описание виртуального хоста:

<VirtualHost *:80>
  ServerAdmin webmaster@dummy-host.example.com
  DocumentRoot "/opt/lampp/docs/dummy-host.example.com"
  ServerName dummy-host.example.com
  ServerAlias www.dummy-host.example.com
  ErrorLog "logs/dummy-host.example.com-error_log"
  CustomLog "logs/dummy-host.example.com-access_log" common
</VirtualHost>

Жизненно необходимыми для существования виртуального хоста (Virtual Host) под XAMPP являются две строки:

  • DocumentRoot - путь размещения виртуального хоста в файловой системе
  • ServerName - доменное имя виртуального хоста

Остальные строки носят дополнительный характер:

  • ServerAdmin - e-mail адрес “администратора” хоста
  • ServerAlias - синоним доменного имени ServerName
  • ErrorLog и CustomLog - логи виртуального хоста

Эти два блока-примера можно отредактировать для конкретного случая, а можно создать свой собственный блок (виртуальный хост) на их основе. Давайте пойдем по второму пути и создадим свой собственный блок для виртуального хоста redface:

<VirtualHost *:80>
  ServerAdmin         redface@mail.dev
  DocumentRoot        "/opt/lampp/htdocs/redface"
  ServerName          redface.dev
  ServerAlias         www.redface.dev
  ErrorLog            "logs/redface-error_log"
  CustomLog           "logs/redface-access_log" common
</VirtualHost>

Обратите внимание, как поменялись значения в этм блоке на конкретные, под хост redface.

Запускаем (если еще не запущен) или перезапускаем (если уже был запущен) локальный сервер XAMPP:

$ sudo /opt/lampp/lampp start
Starting XAMPP for Linux 1.8.2-5...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...ok.

… и “вбиваем” в адресной строке браузера доменное имя созданного нами виртуального хоста redface.dev:

Virtual Host под XAMPP

ОК, все работает!

Проблемы с правами доступа на виртуальном хосте

При создании виртуального хоста (Virtual Host) под XAMPP в директории htdocs для создания или редактирования файлов потребуется изменение прав доступа. По умолчанию поддиректория, в которой располагается виртуальный хост, и все файлы внутри этого хоста имеют разрешение только на чтение.

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

$ sudo chmod g+w /opt/lampp/htdocs/redface/index.html

Изменение точки монтирования виртуального хоста

В этой статье точка монтирования виртуальных хостов (Virtual Hosts) располагалась по адресу - /opt/lampp/htdocs/. То есть, поддиректории виртуальных хостов находились внутри директории htdocs.

Однако, у локального сервера XAMPP имеется возможность переопределить местоположение виртуальных хостов внутри файловой системы Linux Mint. Например, можно расположить все хосты в домашней директории пользователя. Плюсом такого выбора является то, что нет необходимости настраивать права доступа для папок и файлов.

Вся настройка для переопределения точки монтирования виртуальных хостов (Virtual Hosts) сводится к одному действию - изменить значение строки DocumentRoot. Но, к моему сожалению, мне не удалось настроить XAMPP на своем ноутбуке подобным образом.

Все попытки переименовать значение строки DocumentRoot приводили к тому, что XAMPP не мог открыть индексную страницу.

В чем причина подобного отказа со стороны XAMPP, я так и не разобрался. Может быть, внимательный читатель подскажет, в чем причина?

P.S. от 09.09.2014

Добавил в статью комментарий пользователя Alexandr. Сам комментарий мне понравился - подробный и ценный. Поэтому перенес его в статью, как есть. Ниже привожу полный текст, с небольшими стилистическими правками.

Так можно добавить в рабочую папку с проектами на другом диске (например, для использования на Linux и Windows отдельно):

1. Файл httpd.conf

Найти строки и заменить (Имя пользователя):

  • User (username)
  • Group (по умолчанию или username)

Не меняем:

DocumentRoot "/opt/lampp/htdocs” и Directory “/opt/lampp/htdocs"

2. Создаем мягкую ссылку:

$ sudo ln s /media/(username)/mydisk/Open Server/domains /opt/lampp/htdocs

Права на мягкую ссылку “opt/lampp/htdocs/domains” д. б. 777 ( или около того )

3. Файл httpd-vhosts.conf

#localhost
  
  <VirtualHost *:80>
    DocumentRoot "/opt/lampp/htdocs"
    ServerName localhost
  </VirtualHost>

  <VirtualHost *:80>
    ServerAdmin mydomain@mail
    DocumentRoot "/opt/lampp/htdocs/domains/mydomain/www"
    ServerName mydomain
    ServerAlias http://www.mydomain
  </VirtualHost>

4. Файл /etc/hosts

#Virtual hosts
  127.0.0.1 localhost
  127.0.0.1 mydomain

5. Меняем владельца файла

Меняем владельца файла /opt/lampp/htdocs/xampp/lang.tmp:

$ chown (username) /opt/lampp/htdocs/xampp/lang.tmp

Иначе localhost xampp дальше стартовой страницы может не загрузиться.

6. Перезапуск сервера

Перезапуск сервера:

$ sudo /opt/lampp/lampp restart

… и проверка в браузере: http://mydomain/

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

Если каким-то образом, диск в Linux откажется монтироваться, нужно в Windows отключить быструю загрузку (Fast Boot) в параметрах электропитания.

Для тестирования IE в Linux ставится виртуальная машина (например, VirtualBox), куда устанавливаем Windows7 и любимый браузер IE. В самой Windows редактируем файл hosts также как и в Linux, с одним условием – нужно вписывать другой IP, вместо 127.0.0.1, нужно вписывать 10.0.2.2.

Вот так:

c:/windows/system32/drivers/etc/hosts
  10.0.2.2 localhost
  10.0.2.2 mydomain

Сайт через виртуальную машину будет также доступен.


Столкнулся с небольшой, но достаточно неприятной проблемой.

Занимался изучением настройки сверстанного HTML-шаблона под WordPress. То есть, другими словами - создания темы WordPress из готового HTML-шаблона.

Для этой задачи у меня на Linux Mint 17 Cinnanom 64-bit установлен локальный сервер XAMPP. Если кто не знает, как сервер XAMPP устанавливается под Linux, то могут почитать в этой статье - “Установка XAMPP под Linux Mint 17”. Под локальным сервером у меня “крутятся” виртуальные хосты на основе движка WordPress.

Предпросмотр темы не отображается в WordPress

После создания директории под новую тему - Choose закинул к нее скриншот готовой темы для preview в менедежере тем WordPress - wp-admin/themes.php. Но вот неожиданность - картинка-скриншот будущей темы Choose не отобразилась!

Перепробовал достаточно способов, в том числе и с официального сайта XAMPP - XAMPP работает, но почему картинки не отображаются?. То, что там описано - изменение двух строк файла /opt/lampp/etc/httpd.conf:

#EnableMMAP off
#EnableSendfile off

… не сработало, так как в моем конфигурационном файле httpd.conf обе строчки были расскоментированы по умолчанию:

EnableMMAP off
EnableSendfile off

Решение оказалось на удивление простым. Я и не подозревал, что настройка прав доступа в Linux может быть такой “коварной” штукой! Сначала обратил внимание на тот факт, что preview тем WordPress, которые идут “в комплекте” с ним - “Twenty Fourteen”, “Twenty Thirteen”, “Twenty Twelve” нормально отображаются на странице. А вот preview моей темы - не отображается:

Предпросмотр темы не отображается в WordPress

Решил проверить догадку методом “научного тыка” - тупо сравнить два файла-preview screenshot.png из разных тем, своей “Choose” и стандартной “Twenty Fourteen”:

$ ls -l choose/wp-content/themes/twentyfourteen/screenshot.png
-rw-r--r-- 1 choose/wp-content/themes/twentyfourteen/screenshot.png

$ ls -l choose/wp-content/themes/choose/screenshot.png
-rw------- 1 choose/wp-content/themes/choose/screenshot.png

Вот оно! У файла screenshot.png из темы “Twenty Fourteen” имеются права на чтение r для - владельца, группы и всех остальных -rw-r-r-. У файла screenshot.png из моей темы “Choose” имеются права на просмотр r только для владельца данного файла -rw- - -.

Ну что-же, нужно добавить + права чтения r для всех a пользователей файла screenshot.png темы “Choose”:

$ sudo chmod a+r /opt/lampp/htdocs/choose/wp-content/themes/choose/screenshot.png

… и проверить результат:

$ ls -l /opt/lampp/htdocs/choose/wp-content/themes/choose/screenshot.png
-rw-r--r-- 1 /opt/lampp/htdocs/choose/wp-content/themes/choose/screenshot.png

Перехожу в WordPress на страницу управления темами wp-admin/themes.php и смотрю, что получилось:

Рабочее preview создаваемой темы WordPress

Картинка по центру изображения - это preview создаваемой темы “Choose” под WordPress. Как видно, все прошло удачно.

Картинки темы WordPress не отображаются под XAMPP

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

Фоновые изображения, картинки в HTML-файле - ничего не появляется на странице. Firebug не смог мне помочь - единственное, что он “подсказал” - “Файл невозможно загрузить”. Многословно, ничего не скажешь!

Помог незаменимый ресурс для front-end разработчика - Stack Overflow. Решение проблемы заключено в двух строках:

$ cd /opt/lampp/htdocs
$ sudo chmod 777 -R .

То есть, переходим в директорию htdocs и меняем рекурсивно -R права на все действия 777 для всего содержимого текущей . директории. Не знаю, как там с вопросами безопасности в этом случае, но факт остается фактом - все стало работать, как и надо было:

Изображения темы WordPress корректно отображаются на странице

В принципе, на этом все.


Статья посвящена вопросу установки Node.js и пакетного менеджера npm под операционную систему Linux Mint 17 “Qiana” Cinnamon (64-bit).

Также рассмотрен вопрос установки пакетного менеджера Bower в этой же операционной системе.

Почему выбрана система Linux Mint - об этом не стоит говорить долго. Это система гораздо удобнее для задач кодинга, нежели Windows. Пакеты Node.js и пакетный менеджер npm необходим для дальнейшего изучения ремесла верстальщика.

Дело в том, что популярный фреймворк Foundation для своей корректной работы требует первоначальной установки Node.js. Автор планирует в дальнейшем познакомиться с фреймворком Foundation, поэтому ему потребовалась установка вышеназванных пакетов.

О том, что такое Node.js, в этой статье также не будет описано. Во-первых, автор статьи имеет лишь поверхностное представление об этом сервере. А во-вторых, в Интернете есть немало хороших материалов по данному вопросу.

Установка Node.js

Для установки пакета Node.js под систему Linux Mint можно воспользоваться официальным сайтом проекта - Node.js. В разделе Download имеется табличка для скачивания различных версий пакета Node.js. В случае системы Linux в этой таблице нужно найти строку Linux Binaries.

Однако я не буду “заморчиваться” установкой из исходного кода. В Linux Mint есть прекрасный менеджер пакетов apt-get, которым можно и нужно воспользоваться для быстрой и безопасной установки Node.js под Linux. Единственный минус такого подхода - в результате у меня на машине будет стоять не самая свежая версия сервера Node.js. Однако в данном случае это абсолютно не критично.

В терминале ввожу команду:

$ sudo apt-get install nodejs

… пару секунд терпения и у меня под Linux Mint 17 “Qiana” Cinnamon (64-bit) установлен пакет Node.js версии:

$ nodejs -v
v0.10.25

На момент написания статьи самая свежая версия Node.js (как указано на официальном сайте) - это 0.10.28. Как видим, разница в версиях небольшая, так что я поступил правильно, воспользовавшись apt-get.

Установка npm под Linux Mint

Как хорошо известно, у данного сервера имеется свой собственный менеджер пакетов npm (Node Packaged Modules), для установки дополнительных модулей под Node.js. Другими словами, с помощью менеджера npm можно установить под сервер Node.js любой модуль, имеющийся в наличии на репозитории GitHub. Модуль расширяет возможности сервера Node.js в зависимости от того, какой это модуль (тавтология). С кратким описанием и списком всех модулей под Node.js можно ознакомиться на официальном сайте проекта npm - Node Packaged Modules.

При установке в свою систему Linux Mint через apt-get у меня был установлен только сам сервер Node.js. При этом менеджер пакетов npm отстуствовал в системе. Не знаю, как это происходит при установке пакета Node.js из исходников, но при использовании apt-get у меня получилось именно так. Поэтому следующим шагом будет инсталляция менеджера пакетов npm под систему Linux Mint.

В терминале Linux ввожу команду:

$ sudo apt-get install npm

Пробежит много-много строк, но в результате в системе появиться пакет npm:

$ npm -v
1.3.10

Использование менеджера npm очень похоже на использование менеджеров пакетов a-la Linux: apt-get, emerge, pacman и так далее. npm также является консольной командой и у него схожие ключи, поэтому пользователи Linux без труда разберутся с ним:

$ npm -h

Давайте проверим работу установленного менеджера npm. Для этого я в специально отведенной директории Projects создам поддиректорию npm, перейду в нее для дальнейшего удобства работы и установлю в этой поддиректории модуль underscore из репозитория npm:

$ mkdir -p Projects/npm
$ cd Projects/npm
$ npm install underscore

Если теперь посмотреть содержимое поддиректории npm c помощью команды ls, то обнаружим появление папки node_modules, внутри которой располагается подпапка underscore c содержимым одноименного модуля:

$ ls node_modules/underscore/
LICENSE  package.json  README.md  underscore.js  underscore-min.js

Модуль Underscore успешно установлен и менеджер npm также успешно справился со своей задачей.

Установка менеджера Bower под Linux Mint

Переходим к заключительному (и продолжительному) вопросу данной статьи и рассмотрим установку менеджера пакетов Bower. Могу предвидеть у читателей логичный вопрос: “Как - еще один менеджер пакетов?! Но зачем? Разве не хватает npm, c которым мы только что познакомились?”

Все правильно! npm - это менеджер пакетов. И Bower - тоже менеджер пакетов. Отличие первого от второго заключается в том, что npm - это менеджер пакетов для сервера Node.js (и только). А Bower (хотя сам является модулем под Node.js) - это менеджер пакетов для всего проекта в целом.

Npm понимает и может работать только с JavaScript-приложениями (модулями под Node.js, написанными на этом языке). Bower умеет работать с пакетами на JavaScript, HTML, CSS. C помощью него можно одним движением добавить в разрабатываемый проект все, что нужно: библиотеку jQuery, фреймворк Foundation, модуль Underscore, сброс стилей Normalize.css и так далее.

Не нужно самому “вручную” выискивать на безбрежных просторах Интернет пакет и подключать его в проект - Bower это сделает сам. Заманчиво, не правда ли? На официальной странице проекта Bower можно почитать подробную информацию о данном менеджере (правда, на английском языке). В разделе Search Packages можно поискать нужный пакет для установки.

Я же приступлю к установке Bower на свою локальную машину. Так как Bower является модулем для Node.js, то его можно установить с помощью менеджера npm:

$ sudo npm install -g bower

Однако, если запустить после этого в терминале команду просмотра версии, то увидим такой результат:

$ bower -v
/usr/bin/env: node: No such file or directory

Исправить ситуацию можно созданием ссылки:

$ sudo ln -s /usr/bin/nodejs /usr/bin/node

Теперь если снова посмотреть версию установленного пакета, увидим следующее:

$ bower -v
1.3.3

Создаю специальную поддиректорию bower в директории Projects, перехожу туда и запускаю менеджер bower на установку пакета jquery:

$ mkdir -p Projects/bower
$ cd Projects/bower
$ bower install jquery

Если до этого момента на локальной машине (как у меня) не был установлен пакет git, то самое время это сделать, иначе bower не сможет установить указанный пакет jquery:

$ bower install jquery
bower jquery#*  ENOGIT git is not installed or not in the PATH

Все пакеты для скачивания и установки менеджер bower берет с GitHub, поэтому без пакета git этот менеджер не сможет обойтись.

Установка Git на Linux производится простой командой:

$ sudo apt-get install git

После этого, повторив команду установки jquery через bower, получаю следующий отзыв в консоли:

$ bower install jquery
  bower jquery#*              not-cached git://github.com/jquery/jquery.git#*
  bower jquery#*                 resolve git://github.com/jquery/jquery.git#*
  bower jquery#*                download https://github.com/jquery/jquery/archive/2.1.1.tar.gz
  bower jquery#*                 extract archive.tar.gz
  bower jquery#*                resolved git://github.com/jquery/jquery.git#2.1.1
  bower jquery#~2.1.1            install jquery#2.1.1

Если посмотреть на содержимое поддиректории bower, то увидим, что там появилась директория bower_components, в которой находится поддиректория jquery c установленным пакетом:

$ ls bower_components/jquery/
bower.json  dist  MIT-LICENSE.txt  src

В результате была установлена последняя версия библиотеки jQuery - 2.1.1. Если нужна какая-то конкретная версия пакета (jQuery, в частности), то нужно это указать с помощью тега:

$ bower install jquery#1.9.1

Внимательный читатель мог заметить, менеджер пакетов Bower также (как и npm) является консольным. Список доступных для него команд можно получить вызовом:

$ bower -h

В частности, для обновления уже установленного пакета существует команда:

$ bower update [name_package]

Для удаления установленного пакета имеется команда:

$ bower uninstall [name_package]

Посмотреть информацию о пакете:

$ bower info [name_package]

Этой командой можно воспользоваться при настройке файла пакетной установки bower.json

Плагин Bower под Sublime Text

Под редактор Sublime Text имеется одноименный плагин Bower, который в точности повторяет все возможности менеджера Bower. Все преимущество использования плагина Bower заключается в том, что производить инсталляцию, обновление или удаление пакетов можно прямо в редакторе Sublime Text, не переходя в консоль.

Установка плагина Bower выполняется стандартно - через менеджер пакетов Sublime Text: нажимаем сочетание клавиш Shift+Ctrl+P, введем в строке Install и выбираем из появившегося списка пакет Bower.

Теперь попробуем установить какой-либо пакет, не выходя из Sublime Text, c помощью плагина Bower. Для этого снова нажмем сочетание клавиш Shift+Ctrl+P, вводим Bower:Install и из появившегося списка выбираем пакет Foundation (к примеру).

Видим, как в панели проектов Sublime Text, в папке bower_components появилась целая куча подпапок, являющихся частью единого целого - фреймворка Foundation:

Установленный через Bower пакет Foundation в Sublime Text

Настройка плагина Bower

Поддиректория bower_components, в которую плагин Bower производит установку пакетов, не является чем-то постоянным. То есть, можно легко изменить имя и расположение этой директории. Делается это следующим образом - в Sublime Text нажимаем сочетание клавиш Shift+Ctrl+P и вводим Bower: Configure project (никто не запрещает создать файл конфигурации вручную).

В текущую директорию автоматически добавиться файл .bowerrc типа json, в котором будет всего лишь одна строка - имя директории, в которую производится установка пакетов через плагин Bower:

Файл настроек пакета Bower

Для эксперимента изменим имя папки с:

"directory": "components"

на:

"directory": "apps"

… удалим старую директорию bower_components с пакетом foundation и установим через Bower другой пакет - underscore. В результате получим следущее:

Новое имя директории с пакетами в Bower

Пакетная установка в менеджере Bower

У менеджера пакетов Bower есть еще одна замечательная особенность. Это возможность пакетной установки через специально созданный конфигурационный файл. Другими словами, создается специальный файл формата json (component.json), в котором прописываются имена всех пакетов, которые необходимы для установки в данном проекте. Затем в консоли запускается менеджер Bower c одной командой:

$ bower install

… менеджер bower прочитает файл component.json и автоматически установит все пакеты, перечисленные в нем. Отлично, не правда ли?

Примечание: начиная с Bower v.0.9 файл конфигурации component.json был переименован в файл bower.json, который я буду использовать в дальнейшем.

Файл bower.json имеет следующий формат:

{
"name": "name_of_project",
"version": "1.0.0",
  "dependencies": {
    "name_package": "version_package",
    "name_package": "version_package"
  }
}

… где name - это имя проекта, version - версия проекта, dependencies - зависимости проекта. Под зависимостями проекта подразумевается список сторонних пакетов (к примеру - foundation, backborne, jquery и так далее), которые используются при создании данного проекта.

Прописав в этом списке нужные пакеты, тем самым мы заставим Bower автоматически отслеживать наличие указанных пакетов для текущего проекта. Но, от слов к делу - давайте попрактикуемся и создадим примерный файл bower.json для текущего “проекта” bower. Для этого я удалю все ранее установленные в этой поддиректории пакеты:

$ bower uninstall [name_of_package]

… создам в этой директории пустой файл bower.json и наполню его следующим содержимым:

{
"name": "bower",
"version": "0.0.1",
  "dependencies": {
     "jquery": "1.9.1",
     "foundation": "latest"
   }
}

… где latest - самая последняя версия пакета. Сохраняю изменения, перехожу в консоль и запускаю команду:

$ bower install

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

...
Unable to find a suitable version for jquery, please choose one:
    1) jquery#1.9.1 which resolved to 1.9.1 and is required by bower
    2) jquery#>= 2.1.0 which resolved to 2.1.1 and is required by foundation#5.2.3
    3) jquery#>=1.2 which resolved to 2.1.1 and is required by jquery.cookie#1.4.1

Prefix the choice with ! to persist it to bower.json

[?] Answer:
...

… то есть, Bower отследил, что я устанавливаю библиотеку jQuery версии 1.9.1; но при этом самая последняя версия фреймворка Foundation 5.2.3 требует для своей работы jQuery версии 2.1.1. Вот менеджер и спрашивает у меня - как быть дальше? Ай да Bower!

Добавление зависимостей в файл bower.json

После создания пакетного файла bower.json в менеждере Bower можно автоматически добавлять в него запись при ручной установке отдельного пакета. Допустим, в ходе работы срочно потребовалась установка пакета backbone.

Тогда выполняем следующую команду:

$ bower install backbone --save

… пакет backbone (и его зависимость underscore) успешно установились. Но нас интересует факт добавления записи в файл bower.json, поэтому смотрим:

$ cat bower.json
{
"name": "bower",
"version": "0.0.1",
  "dependencies": {
    "jquery": "1.9.1",
    "foundation": "latest",
    "backbone": "~1.1.2"
  }
}

Автоматическое создание файла bower.json

Помимо ручного создания и настройки файла bower.json, у данного менеджера предусмотрена команда для автоматического создания и настройки этого файла. Для этого необходимо в консоли запустить команду:

$ bower init

… тогда менеджер проведет нас “за ручку” через все этапы создания настроек файла bower.json путем задания серии вопросов. Взгляните на примерный результат вышеназванной команды:

$ cat bower.json
{
  "name": "bower",
  "version": "0.0.1",
  "dependencies": {
    "jquery": "1.9.1",
    "foundation": "latest",
    "backbone": "~1.1.2"
  },
  "description": "my firts project",
  "moduleType": [
    "amd"
  ],
  "authors": [
    "zencoder"
  ],
  "license": "MIT",
  "homepage": "http://localhost:7788/third/",
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "apps",
    "test",
    "tests"
  ]
}

Плагин AutoFileName в Sublime Text

Редактор Sublime Text имеет неизмеримое количество полезных плагинов. Одним из них является AutoFileName - незаменимая вещь для автодополнения путей файлов в проекте. Кто имел мало-мальский опыт работы в Dreamveawer (или подобные ему IDE), могут сразу догадаться, о чем идет речь.

Поэтому данный плагин “must have” в коллекции под рабочую версию Sublime Text любого верстальщика.

Заключение

Завершаю обзор установки пакетов Node.js, npm и Bower под систему Linux Mint. Надеюсь, статья оказалась достаточно полной, точной и грамотной. В ее написании неоценимую помощь оказало видео “ Bower - Обзор пакетного менеджера “ Sorax’а.

На этом все.


Еще один фреймворк из бесчисленного на сегодняшний день полка фреймворков - Bootstrap 3. Точнее было бы сказать, что не еще один - а флагман CSS-фреймворков! Версия 2 вышла давно и на сегодня является устаревшей. Сегодня самая современная версия - это версия 3. Поэтому ее мы и будем рассматривать. Вопрос данной статьи будет посвящен основе данной фреймворка - CSS-сетке и особенностям ее создания в версии 3.

Установка и настройка Bootstrap 3

Ничего сложного и необычного в установке фреймворка Bootstrap 3 нет. Для этого скачиваем дистрибутив с официального сайта Bootstrap 3, распаковываем архив в готовый проект-директорию.

Затем с официального сайта берем готовый шаблон HTML-документа - Basic template и создаем свой собственный индексный файл HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Bootstrap 101 Template</title>

    <!-- Bootstrap -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="js/bootstrap.min.js"></script>
  </body>
</html>

В этом файле проверяем правильность путей для CSS и JS-файлов:

<link href="css/bootstrap.css" rel="stylesheet">
<link href="css/bootstrap-theme.css" rel="stylesheet">
...

Все готово для дальнейшей работы.

Система сеток Bootstrap 3

Важнейшей составляюшей любого CSS-фреймворка является система CSS-сетки (grid). Как и в предыдущей версии Bootstrap 2, в версии 3 используется 12-ти колоночная система.

Однако, в Bootstrap 3 применяются четыре типа классов для создания адаптивной (responsive) сетки. На официальном сайте Bootstrap 3 имеется таблица с побробным и наглядным описанием этих классов - Grid Options.

Таблица классов для CSS-сетки Bootstrap 3

В этой таблице представлены четыре ширины экрана устройства, на котором будет отображена страница. Колонка “Extra small devices” с шириной менее 768px обозначает мобильные устройства. Колонка “Small devices” с шириной равной или больше 768px представляет планшетные компьютеры (планшеты). Две остальные колонки представляют обычный настольный монитор через колонку “Medium devices” с шириной равной или больше 992px и широкоформатный монитор через колонку “Large devices” с шириной равной или больше 1200px.

Вышеназванные величины 768px, 992px и 1200px являются контрольными точками (breakpoints), служащими для обработки медиа-запросов в адаптивном дизайне страницы.

В данной таблице строка “Class prefix” является чуть ли не самой важной, так как в ней содержатся имена (префиксы) классов фреймворка Bootstrap 3 для каждого из четырех типов устройств. Для мобильного устройства имя (префикс) класса будет .col-xs-, для планшетного компьютера префикс будет .col-sm-, для обычного монитора - .col-md- и для широкоформатного монитора - .col-lg-. Для видно из названия префиксов, они являются сокращениями от названия самих устройств, поэтому их легко запомнить.

Вот и все, что необходимо знать о системе CSS-сеток в фреймворке Bootstrap 3. Дальше можно легко домыслить ход построения адаптивной сетки для конкретного сайта.

Пример создания CSS-сетки в Bootstrap 3

Допустим, необходимо создать следующий макет:

  • для широкоформатного монитора в макете должно быть 2 столбца - один шириной 10 колонок и второй шириной 2 колонки;
  • для обычного монитора 2 столбца - один шириной 8 колонок и второй шириной 4 колонки;
  • для планшета 2 столбца - один шириной 6 колонок и второй шириной также 6 колонок;
  • для мобильного устройства макет должен остаться, как и для планшета - два столбца одинаковой ширины.

То есть, при изменении ширины монитора устройства ширина столбцов в макете должна меняться, как показано выше. Для этого создадим простую разметку и добавим в нее классы Bootstrap 3:

<div class="container">
  <div class="row">
    <div class="col-lg-10 col-md-8 col-sm-6"></div>
    <div class="col-lg-2 col-md-4 col-sm-6"></div>
  </div>
</div>

Если открыть созданную страницу в окне браузера и попробовать менять ширину его окна, то в диспечере свойств страницы увидим метаморфозы, связанные с работой медиа-запросов media-queries. При ширине окна больше 1200px будем наблюдать левый столбец шириной в 10 колонок и правый столбец шириной в 2 колонки.

Уменьшив ширину окна до 992px, получим левый столбец шириной в 8 колонок и правый стлбец шириной в 4 колонки. Еще уменьшив окно до 768px, получим два одинаковых столбца шириной в 6 колонок. Если окно окончательно уменьшится (менее 768px), ширина столбцов останется прежней, но они расположаться вертикально, друг под другом (поведение по умолчанию).

Видимость элементов сетки в Bootstrap 3

Немного усложним задачу и сделаем ее интереснее ради теоретического примера работы фреймворка Bootstrap 3. Допустим, нам необходим такой макет:

  • широкоформатный монитор - 12 колонок;
  • обычный монитор - 3 колонки;
  • планшетный монитор - 3 колонки;
  • мобильный монитор - 2 колонки.

Тогда HTML-разметка и классы фреймворка Bootstrap 3 следующими:

<div class="container">
  <div class="row">
    <div class="col-lg-2 col-md-4  col-sm-4  col-xs-6"></div>
    <div class="col-lg-2 hidden-md hidden-sm hidden-xs"></div>
    <div class="col-lg-2 col-md-4  col-sm-4  col-xs-6"></div>
    <div class="col-lg-2 hidden-md hidden-sm hidden-xs"></div>
    <div class="col-lg-2 col-md-4  col-sm-4  hidden-xs"></div>
    <div class="col-lg-2 hidden-md hidden-sm hidden-xs"></div>
  </div>
</div>

В данном случае при измении ширины окна браузера будет меняться количество колонок внутри макета. При ширине большей 1200px число колонок будет равняться шести. При уменьшении окна до ширины в 992px число колонок изменится до 4-х и будет оставаться таковым при ширине окна 768px. Если окно еще уменьшится ниже 768px, то количество колонок измениться до двух.

Подобные метаморфозы возможны благодаря классу hidden-x, который вы могли заметить в разметке. Задача этого класса скрыть указанный элемент при достижении окном браузера определенной контрольной точки. Для каждого из предполагаемых состояний окна браузера необходимо указать класс - hidden-lg, hidden-md, hidden-sm, hidden-xs:

Сравнительная таблица классов hidden и visible в Bootstrap 3

Противоположностью класса hidden-x является класс visible-x. Несмотря на то, что действие этих классов должно быть прямо противоположным друг другу, на практике это различие уловить не так просто и тут может помочь сравнительная таблица с официального файта Bootstrap 3 - Responsive utilities. В этой таблице (см. таблицу выше) хорошо видно различие между этими классами.

В то время как класс hidden-x производит скрытие элемента в определенной контрольной точке (breakpoint), во всех остальных состояниях элемент видимый. Класс visible-x делает элемент видимым только в определенном состоянии - во всех остальных состояниях элемент невидимый.

Вложенность (nesting) сетки в Bootstrap 3

CSS-сетка в фреймворке Bootstrap 3 позволяет выполнять вложение одних ячеек в другие. Такое явление называется nesting. К примеру, необходим создать такую HTML-разметку:

<div class="container">
  <div class="row primo">
    <div class="col-lg-4"></div>
    <div class="col-lg-4"></div>
    <div class="col-lg-4"></div>
  </div>
  <div class="row secondo">
    <div class="col-lg-8">
      <div class="row">
        <div class="col-lg-6"></div>
        <div class="col-lg-6"></div>
      </div>
    </div>
    <div class="col-lg-4"></div>
  </div>
  <div class="row tetro">
    <div class="col-lg-6">
      <div class="row">
        <div class="col-lg-6"></div>
        <div class="col-lg-6"></div>
      </div>
    </div>
    <div class="col-lg-6">
      <div class="row">
        <div class="col-lg-6"></div>
        <div class="col-lg-6"></div>
      </div>
    </div>
  </div>
  <div class="row quattro">
    <div class="col-lg-2"></div>
    <div class="col-lg-2"></div>
    <div class="col-lg-2"></div>
    <div class="col-lg-2"></div>
    <div class="col-lg-2"></div>
    <div class="col-lg-2"></div>
  </div>
</div>

Для наглядности примера оставим для элементов только один класс .col-lg-. Блок с классом primo имеет три обычные колонки col-lg-4. Блок с классом secondo имеет две колонки - col-lg-8 и col-lg-4. Внутри колонки col-lg-8 размещено еще два блока равной ширины - две колонки с классом col-lg-6. Это пример вложенности (nesting) одних ячеек CSS-сетки Bootstrap 3 в другие ячейки.

Аналогичная ситуация с блоком класса tetro, но в нем в оба “первичных” блока вложены еще два блока. Всего получается четыре блока. С блоком класса quattro все просто - там “обычные” (не вложенные) шесть блоков класса col-lg-2.

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

Смещение (offsetting) колонок в Bootstrap 3

В Bootstrap 3 можно смещать колонки вправо с помощью класса .col-*-offset-*, который добавляет margin-left для указанной колонки. Смещение производится на ширину колонки, кратную указанному количеству.

Приведу пример, чтобы было наглядно понятно:

<div class="container">
  <div class="row">
    <div class="col-lg-8"></div>
    <div class="col-lg-2 col-lg-offset-2 right"></div>
  </div>
</div>

В этом примере колонка с классом right имеет ширину в два столбца и смещается вправо опять таки на два столбца - col-lg-offset-2. При этом стоит также заметить, что данное смещение будет выполняться только при ширине экрана больше 1200px (breakpoint), на что указывает имя класса - col-lg-. Если необходимо, чтобы такое смещение сохранялось при меньших размерах окна браузера, необходимо явно указать это в коде:

<div class="container">
  <div class="row">
    <div class="col-lg-8"></div>
    <div class="col-lg-2 col-lg-offset-2 col-md-offset-2 col-sm-offset-2 col-xs-offset-2 right"></div>
  </div>
</div>

Адаптивная (responsive) сетка в Bootstrap 3

Переключать ширину сетки с фиксированной на резиновую в Bootstrap 3 можно точно также, как и во 2-й версии. Для этого нужно заменить для блока-контейнера имя класса с container на container-fluid:

<div class="container-fluid">
  <div class="row">
    ...
  </div>
</div>

Заключение

На этом обзор CSS-сетки в фреймворке Bootstrap 3 можно считать законченным. Субъективно для меня был интересен именно этот вопрос. Что касается рассмотрения остальных классов, предназначенных для оформления различных элементов на странице, то мне они кажутся не такими интересныи и важными.

Может быть, в дальнейшем я и вернусь к расмотрению деталей фреймворка Bootstrap 3.