|string)} val\n * @return {String}\n */\n\nexports.style = pug_style;\nfunction pug_style(val) {\n if (!val) return '';\n if (typeof val === 'object') {\n var out = '';\n for (var style in val) {\n /* istanbul ignore else */\n if (pug_has_own_property.call(val, style)) {\n out = out + style + ':' + val[style] + ';';\n }\n }\n return out;\n } else {\n return val + '';\n }\n};\n\n/**\n * Render the given attribute.\n *\n * @param {String} key\n * @param {String} val\n * @param {Boolean} escaped\n * @param {Boolean} terse\n * @return {String}\n */\nexports.attr = pug_attr;\nfunction pug_attr(key, val, escaped, terse) {\n if (val === false || val == null || !val && (key === 'class' || key === 'style')) {\n return '';\n }\n if (val === true) {\n return ' ' + (terse ? key : key + '=\"' + key + '\"');\n }\n var type = typeof val;\n if ((type === 'object' || type === 'function') && typeof val.toJSON === 'function') {\n val = val.toJSON();\n }\n if (typeof val !== 'string') {\n val = JSON.stringify(val);\n if (!escaped && val.indexOf('\"') !== -1) {\n return ' ' + key + '=\\'' + val.replace(/'/g, ''') + '\\'';\n }\n }\n if (escaped) val = pug_escape(val);\n return ' ' + key + '=\"' + val + '\"';\n};\n\n/**\n * Render the given attributes object.\n *\n * @param {Object} obj\n * @param {Object} terse whether to use HTML5 terse boolean attributes\n * @return {String}\n */\nexports.attrs = pug_attrs;\nfunction pug_attrs(obj, terse){\n var attrs = '';\n\n for (var key in obj) {\n if (pug_has_own_property.call(obj, key)) {\n var val = obj[key];\n\n if ('class' === key) {\n val = pug_classes(val);\n attrs = pug_attr(key, val, false, terse) + attrs;\n continue;\n }\n if ('style' === key) {\n val = pug_style(val);\n }\n attrs += pug_attr(key, val, false, terse);\n }\n }\n\n return attrs;\n};\n\n/**\n * Escape the given string of `html`.\n *\n * @param {String} html\n * @return {String}\n * @api private\n */\n\nvar pug_match_html = /[\"&<>]/;\nexports.escape = pug_escape;\nfunction pug_escape(_html){\n var html = '' + _html;\n var regexResult = pug_match_html.exec(html);\n if (!regexResult) return _html;\n\n var result = '';\n var i, lastIndex, escape;\n for (i = regexResult.index, lastIndex = 0; i < html.length; i++) {\n switch (html.charCodeAt(i)) {\n case 34: escape = '"'; break;\n case 38: escape = '&'; break;\n case 60: escape = '<'; break;\n case 62: escape = '>'; break;\n default: continue;\n }\n if (lastIndex !== i) result += html.substring(lastIndex, i);\n lastIndex = i + 1;\n result += escape;\n }\n if (lastIndex !== i) return result + html.substring(lastIndex, i);\n else return result;\n};\n\n/**\n * Re-throw the given `err` in context to the\n * the pug in `filename` at the given `lineno`.\n *\n * @param {Error} err\n * @param {String} filename\n * @param {String} lineno\n * @param {String} str original source\n * @api private\n */\n\nexports.rethrow = pug_rethrow;\nfunction pug_rethrow(err, filename, lineno, str){\n if (!(err instanceof Error)) throw err;\n if ((typeof window != 'undefined' || !filename) && !str) {\n err.message += ' on line ' + lineno;\n throw err;\n }\n try {\n str = str || require('fs').readFileSync(filename, 'utf8')\n } catch (ex) {\n pug_rethrow(err, null, lineno)\n }\n var context = 3\n , lines = str.split('\\n')\n , start = Math.max(lineno - context, 0)\n , end = Math.min(lines.length, lineno + context);\n\n // Error context\n var context = lines.slice(start, end).map(function(line, i){\n var curr = i + start + 1;\n return (curr == lineno ? ' > ' : ' ')\n + curr\n + '| '\n + line;\n }).join('\\n');\n\n // Alter exception message\n err.path = filename;\n err.message = (filename || 'Pug') + ':' + lineno\n + '\\n' + context + '\\n\\n' + err.message;\n throw err;\n};\n","export default {site:{privacy_policy:'политика конфиденциальности',terms:'пользовательское соглашение',banner_bottom:'Проводим курсы по JavaScript и фреймворкам.',action_required:'Требуется действие',gdpr_dialog:{title:'Этот сайт использует cookie',text:'Мы используем браузерные технологии, такие как cookie и local storage для хранения ваших предпочтений. Вы принимаете политику конфиденциальности и соглашение пользователя?',accept:'Принять',cancel:'Отмена'},theme:{light:'Светлая тема',dark:'Тёмная тема',change:'Сменить тему оформления'},toolbar:{lang_switcher:{cta_text:'Мы хотим сделать этот проект с открытым исходным кодом доступным для людей во всем мире. Пожалуйста, помогите нам перевести это руководство на другие языки.',footer_text:'количество контента, переведенное на соотвествующий язык',old_version:'Опубликована полная, но предыдущая версия учебника.'},logo:{normal:{svg:'sitetoolbar__logo_ru.svg',width:171},'normal-white':{svg:'sitetoolbar__logo_ru-white.svg'},small:{svg:'sitetoolbar__logo_small_ru.svg',width:80},'small-white':{svg:'sitetoolbar__logo_small_ru-white.svg'}},sections:[{slug:'tutorial',url:'/',title:'Учебник'},{slug:'courses',title:'Курсы'},{url:'https://javascript.ru/forum/',title:'Форум'},{slug:'quiz',title:'Тесты знаний'}],sections_bak:[{slug:'jobs',title:'Стажировки'}],buy_ebook_extra:'Купить',buy_ebook:'EPUB/PDF',search_placeholder:'Искать на Javascript.ru',search_button:'Найти',public_profile:'Публичный профиль',account:'Аккаунт',notifications:'Уведомления',admin:'Админ',logout:'Выйти'},sorry_old_browser:'Извините, Internet Explorer не поддерживается, пожалуйста используйте более новый браузер.',contact_us:'связаться с нами',about_the_project:'о проекте',ilya_kantor:'Илья Кантор',comments:'Комментарии',loading:'Загружается...',search:'Искать',share:'Поделиться',read_before_commenting:'перед тем как писать…',last_updated_at:'Последнее обновление: #{date}','tablet-menu':{choose_section:'Выберите раздел',search_placeholder:'Поиск в учебнике',search_button:'Поиск'},comment:{help:['Если вам кажется, что в статье что-то не так - вместо комментария напишите на GitHub.','Для одной строки кода используйте тег <code>
, для нескольких строк кода — тег <pre>
, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)','Если что-то непонятно в статье — пишите, что именно и с какого места.']},meta:{description:'Современный учебник JavaScript, начиная с основ, включающий в себя много тонкостей и фишек JavaScript/DOM.'},edit_on_github:'Редактировать на GitHub',error:'ошибка',close:'закрыть',hide_forever:'не показывать',hidden_forever:'Эта информация больше не будет выводиться.',subscribe:{title:'Следите за обновлениями javascript.ru',text:'Мы не рассылаем рекламу, все только по делу. Вы сами выбираете, что получать:',agreement:'Подписываясь на рассылку, вы соглашаетесь с пользовательским соглашением.',button:'Подписаться',button_unsubscribe:'Отписаться от всех',common_updates:'Общие обновления',common_updates_text:'новые курсы, интенсивы, выпуски статей и скринкастов',your_email:'ваш@email',newsletters:'рассылка,рассылки,рассылок',no_selected:'Не выбрано'},form:{value_must_not_be_empty:'Значение не должно быть пустым.',value_is_too_long:'Значение слишком длинное.',value_is_too_short:'Значение слишком короткое.',invalid_email:'Некорректный email.',invalid_value:'Некорректное значение.',invalid_autocomplete:'Пожалуйста, выберите значение из списка',invalid_date:'Дата неверна, формат: дд.мм.гггг.',invalid_range:'Такой даты здесь не может быть.',save:'Сохранить',upload_file:'Загрузить файл',cancel:'Отмена',server_error:'Ошибка загрузки, статус'}}};","export default {line1:'Настоящим удостоверяется, что с #{dateStart} по #{dateEnd}',line1_0:'Настоящим удостоверяется, что #{date}',line2:'прошёл(а) обучение по программе',no_user:'Нет такого пользователя',no_participant:'Нет такого участника',no_certificate:'Нет такого сертификата'};","export default {invite:{invitation:'Приглашение на курс',invitation_masterclass:'Приглашение на интенсив',seat_has_been_reserved:'На сайте javascript.ru была оформлена запись для вас на #{title}.',click_to_join:'Перейдите по ссылке #{link}, чтобы присоединиться к группе.',contact_person:'Контактное лицо, указанное в записи: #{name}.',questions:'Если возникнут какие-либо вопросы – вы всегда можете ответить на это письмо.'},invite_remind:{title:'Присоединитесь, пожалуйста, к группе',hello:'Здравствуйте!',still_not_joined:'Вы – в списке участников, но до сих пор не присоединились к группе #{title}.',join_for:'Это нужно сделать, чтобы вы могли участвовать и получать материалы группы.',click_to_join:'Присоединиться к группе можно по ссылке #{link}.',questions:'Если возникнут какие-либо вопросы – вы можете ответить на это письмо.'},materials:{title:'Уведомление о материалах #{type}а',materials_added:'На страницу #{link} добавлены материалы.',click_to_download:'Вы можете скачать файл по прямой ссылке (если залогинены на сайте): #{fileTitle}.'},move:{title:'Оповещение о переводе',hello:'Здравствуйте!',you_were_moved:'Вы были переведены из группы \"#{oldGroup}\" в группу \"#{newGroup}\".',questions:'Если возникнут какие-либо вопросы – вы можете ответить на это письмо.'},order_cancel:{subject:'[Курсы, система регистрации] Отмена заказа #{number} на сайте #{host}',title:'Ваш заказ #{number} аннулирован по истечению времени',order_cancelled:'Ваш заказ на Javascript.ru под номером #{number} автоматически аннулирован',group_start_soon:' в связи со скорым началом обучения, ввиду отсутствия информации о платеже.',payment_expired:' по истечению времени ожидания, ввиду отсутствия информации о платеже.',duplicate:'У вас есть другой, оплаченный, заказ под номером #{number} в ту же группу, так что, вероятно, аннулирован лишний, дублирующий, заказ.',list_orders:'Список активных заказов доступен в личном кабинете: ',need_login:' (нужно авторизоваться на сайте).',already_payed_or_soon:'Если вы собираетесь оплатить заказ сегодня – перейдите по одноразовой ссылке #{restoreLink}.',already_payed:'Для того, чтобы восстановить заказ – перейдите по одноразовой ссылке: #{restoreLink}.',valid_one_day:'Ссылка будет активна в течение суток.',info:'Автоматическая отмена неоплаченных заказов предназначена для удаления несостоявшихся заказов.'},payment_confirmation:{title:'Подтверждение оплаты',payment_confirmed:'Подтверждаем получение оплаты за заказ #{number}',participation_confirmed:'Ваша запись одобрена',free_participation:'Ваш заказ #{number} одобрен без оплаты',is_participant:'Перейдите по ссылке #{orderUserInviteLink}, чтобы присоединиться к группе.',questions:'Если возникнут какие-либо вопросы – вы всегда можете ответить на это письмо.'}};","export default {title:'Отзыв о #{type}е\\n #{title}',title_all:'Отзывы о #{type}е\\n #{title}',average_grade:'средняя оценка',grades:{'1':'Плохо','2':'Так себе','3':'Нормально','4':'Хорошо','5':'Отлично'},participated:'Оценки от разработчиков, которые участвовали в #{type}е',recommend_text:'учеников, оставивших отзывы, рекомендуют этот #{type}',recommend_text_frontpage:'Пользователей рекомендуют этот #{type}',all_feedbacks:'все отзывы',feedback_cut:'весь отзыв',page:{recommend:'Рекомендует #{type} \"#{title}\"',course:'#{type}',teacher:'Преподаватель',edit:'редактировать',share:'Поделиться'},form:{grade:'Как вы в целом оцениваете #{type}?*',recommend:'Порекомендовали бы вы этот #{type} другим?*',recommend_yes:'Да',recommend_no:'Нет',feedback:'Отзыв*',feedback_placeholder:'Несколько слов о том, насколько полезным #{type} оказался для вас, доступно ли излагается материал, устраивает ли квалификация ведущего и т.д.',is_public:'Публичный отзыв',is_public_note:'(будет опубликован на javascript.ru)',edit:'Редактировать',name:'Имя',photo:'Фото',photo_upload:'Загрузить новое фото',country:'Страна',city:'Город',occupation:'Область работы',social:'Профиль в соц. сети или личная страница, где можно узнать о вашей профессиональной деятельности',social_note:'Эта ссылка будет доступна только в контексте вашего отзыва. пожалуйста, укажите её.',submit:'Отправить','delete':'удалить',delete_confirm:'Вы уверены, что хотите удалить этот отзыв?',deleted:'Отзыв был успешно удален'},list:{policy:'Политика отзывов javascript.ru',policy_list:'Отзыв может оставить любой участник #{type}а, после прохождения.\\nПоказываются все опубликованные отзывы, даже если оценка нам \"не нравится\".\\nОтзывы показываются \"как есть\", не модерируются, если нет нарушения правил сайта и #{type}а (нецензурная лексика и др).\\nОтзывы показываются только для последней версии #{type}а.'},filter:{teachers:'все преподаватели',all:'с любой оценкой',courses:'на любой курс',grade:'с оценкой'}};","export default {title:'Онлайн-курсы по JavaScript-технологиям',description:'Здесь находятся «правильные» курсы по профессиональному JavaScript и смежным технологиям. С теорией, ответами на вопросы, практикой, обратной связью по коду (\"code review\"). Каждый курс ведёт преподаватель - опытный действующий разработчик.\\n',opened_courses:'Перейти к списку открытых курсов',people_talk_about:'Что говорят о курсах участники',people_talk_about_single:'Что говорят о #{type}е участники',features:[{name:'quality',title:'Качество',text:'Это самое главное. Мы изучаем разработку на профессиональном уровне'},{name:'online',onclick:'document.getElementById(\\'online\\').checked = true',title:'Дистанционность',text:'На практике это оказывается удобнее, чем очные курсы'},{name:'study',title:'Поддержка',text:'Вы получите советы по развитию именно для вас'},{name:'feedback',title:'Результат',text:'Цель курсов - получить конкретные результаты в плане знаний и умений'},{name:'guarantee',title:'Гарантия',text:'Возврат денег, если что-то не так'}],program:'Программа курсов и запись',master_class:'Интенсивы',master_class_text:'В отличии от курсов, интенсивы - это однодневные или двухдневные вебинары с более узкой программой. Основная цель интенсивов – приобрести или закрепить знания по конкретной технологии в сжатые сроки. Интенсивы, как и курсы, являются интерактивными и предусматривают общение с преподавателем.\\n',opinions:'Мнение профессионалов',ongoing:'Идёт набор в группы',teachers_title:'Преподаватель,Преподаватели,Преподаватели',teachers_description:'Курсы проводятся только опытными и проверенными профессионалами. Каждый преподаватель обладает как практическими, так и теоретическими знаниями, приобретёнными за годы работы в сфере веб-разработки.\\n',phone_toggler:'Информация о ведущем и особенностях курсов.',learn_more:'Подробнее',faq:{title:'Часто задаваемые вопросы',another_question:'У вас другой вопрос? Напишите его в комментариях внизу этой страницы или на почту help@javascript.ru (ответ обычно в течение дня), а если срочно — по телефону +7-903-5419441.',old_comments:'Почитать предыдущие комментарии к этой странице можно в старом движке.'},participant_logos:{title:'У нас обучались',description:'Интенсивы и мастер-классы для профессионалов в области JavaScript проводятся примерно с 2006 года, а курсы – с 2011 года. За это время обучились тысячи человек из сотен компаний, всех их перечислить сложно. В частности, проходили обучение сотрудники этих компаний:\\n',notes:'За время обучения были оставлены сотни отзывов, некоторые из которых вы можете видеть выше на этой странице, а также, в более подробном виде, на странице курса и в профилях преподавателей. Мнение о курсах профессионалов вы также можете увидеть выше.\\n'},professionals:{title:'Мнение профессионалов',articles:[{userpic:'/img/courses/dmitryx.jpg',username:'Дмитрий Поляков',linkedin_link:'https://www.linkedin.com/in/dmitryx',about:'Frontend-разработчик в Google, делает Youtube, общий опыт работы архитектором и ведущим разработчиком различных проектов более 15 лет.\\n',feedback:'Участвовал в мастер-классах Ильи несколько раз, узнал много полезного. Очень нравится профессиональное и отлично организованное изложение и структуризация материала, приводимые примеры и паттерны применения в настоящей разработке. Считаю Илью одним из лучших JS разработчиков и ведущих. Крайне рекомендую курсы для тех, кто хочет отточить свои знания и стать профессионалом.\\n'},{userpic:'/img/courses/andrewsumin.jpg',username:'Андрей Сумин',linkedin_link:'https://ru.linkedin.com/in/andrewsumin',about:'Главный по Frontend в компании Mail.ru, также принимал участие в таких проектах как hh.ru и yandex.ru.\\n',feedback:'В далёком 2006 году, будучи frontend-разработчиком в Яндекс, я посетил курс по JavaScript. Уже тогда его занятия отличались сильной базой, подробным разбором важных и сложных аспектов и грамотной организацией. Я искренне рекомендую курсы Ильи всем кто хочет знать всё о языке JavaScript.\\n'},{userpic:'/img/courses/tyv.jpg',username:'Юрий Ткаченко',linkedin_link:'https://ua.linkedin.com/in/tkachenkoyuri',about:'Frontend-разработчик, в Яндекс 3 года руководил одной из команд верстальщиков, общий опыт Frontend-разработки более 10 лет .\\n',feedback:'Во время работы руководителем одной из групп верстки в Яндексе передо мной встала задача повышения квалификации большой команды верстальщиков. После длительного анализа я выбрал курс на learn.javascript.ru и остался очень доволен результатом, считаю этот курс лучшим из существующих на русском языке.\\n'}]}};","export default {dropbox_share:{enter_email:'Введите ниже email, с которым вы зарегистрированы на Dropbox. Вам придёт инвайт (функциональность в бете).\\n',by_default:'\"По умолчанию\" в поле введён ваш email на этом сайте, но, если вы уже используете Dropbox с другим email, то можете его поменять.\\n',request_access:'Запросить доступ к каталогу',no_dropbox:'У этой группы не включён Dropbox',success:'Готово, проверьте, в Dropbox должен быть инвайт. Он также придёт на email.'},materials:{notify_me:'Уведомлять меня по email о появлении материалов.',title:'Добавление материалов',filename:'Имя файла, по времени занятия: ',comment:'Комментарий (опционально)',notifications:'Рассылать уведомления',submit:'Добавить',serial_number:'Серийный номер для видео:',name:'Название',size:'Размер',added_date:'Добавлено',no_materials:'Материалов пока нет, будут доступны позже.',chat_logs:'Логи чата'},slack_logs:{title:'Логи группового чата'}};","export default {course_feedback:{missing_score:'Не стоит оценка.',missing_text:'Отсутствует текст отзыва.',missing_country:'Страна не указана.'},course_group:{invalid_timeStart:'Некорректное время начала',invalid_timeEnd:'Некорректное время конца'},course_participant:{missing_name:'Имя отсутствует.',invalid_name:'Имя дожно состоять из одного слова.',missing_surname:'Фамилия отсутствует.',invalid_surname:'Фамилия должна состоять из одного слова.',missing_country:'Страна не указана.',invalid_url:'Некорректный URL страницы.'}};","export default {courses:'Курсы',type:{masterclass:'интенсив',course:'курс'},by_user:{title:'Описание',info:'Инструкции по настройке окружения',slack_logs:'Логи slack чата',jb:'Скидка на редакторы Jetbrains',ical:'Расписание в формате iCal',tasklist:'Задачник',materials:'Материалы для обучения',participants:'Анкеты участников',participants_json:'JSON участников (для CORS)'},group_feedback_list:{plural_feedback:'отзыв,отзыва,отзывов'},group_feedback_edit:{no_participant:'Оставлять отзыв могут только участники группы.',no_rights:'Не хватает прав',title:'Отзыв',public_feedback:'Ваш отзыв успешно сохранен. При желании, вы можете поделиться им в соц сетях.',private_feedback:'Ваш отзыв успешно сохранен. Он будет виден только нам.',rate_course:'Поставьте, пожалуйста, #{type}у оценку.',missing_feedback_text:'Вы забыли написать текст отзыва.'},group_feedback_show:{private_feedback:'Отзыв не публичный',title:'Отзыв',head_title:'Отзыв на',comment_saved:'Комментарий сохранён',comment_save_error:'Не получилось сохранить комментарий',edit:'редактировать'},group_finish:'Группа #{title} успешно завершена.',group_cancel:'Группа #{title} успешно отменена.',group_materials:{title:'Материалы для обучения',added_with_notifications:'Материал добавлен, уведомления разосланы.',added_wo_notifications:'Материал добавлен, уведомления НЕ рассылались.',email_subject:'Добавлены материалы #{type}а',remove_file:'Удалить файл',file_removed:'Файл удалён.',settings_saved:'Настройка сохранена.'},group_materials_download:{invalid_link:'Ссылка неверна. Возможно, этот материал был добавлен по ошибке и позже удалён из преподавателем.'},group_slack_register:{already_slack_user:'Пользователь с адресом #{email} уже зарегистрирован в Slack.',user_invited:'Приглашение отправлено на адрес #{email}.'},group_telegram_role:{not_participant:'Не участник курса',no_target:'Не участник и не преподаватель',invite_generated:'Ссылка-инвайт создана.'},group_slack_invite:{not_participant:'Не участник курса',no_slack_user:'Пользователь с адресом #{email} не зарегистрирован в Slack, сначала запросите приглашение.',user_added:'Пользователь #{email} приглашён в slack-канал #{groupSlug}.'},participants:{data_updated:'Данные обновлены.',fix_errors:'Исправьте, пожалуйста, ошибки.'},invite:{order:'Заказ #{order}',success:'Поздравляем, вы присоединились к #{type}у. Ниже, рядом с #{type}ом, вы найдёте инструкцию.',already_accepted_title:'Это приглашение уже принято',already_accepted:'Это приглашение уже принято. Зайдите в учётную запись участника для доступа к #{type}у.',outdated_link_title:'Ссылка устарела',outdated_link:'Извините, ссылка по которой вы перешли, устарела. Если у вас возникли какие-либо вопросы – пишите на #{email}',already_added:'Вы уже участник #{type}а. Ниже, рядом с #{type}ом, вы найдёте инструкцию.',choose_country:' выберите страну ',details_form:{title:'Анкета участника',first_name:'Имя на русском*',surname:'Фамилия на русском*',first_name_en:'Имя на английском*',surname_en:'Фамилия на английском*',photo:'Фото',photo_upload:'Загрузить новое фото',country:'Страна *',city:'Город',occupation:'Текущая работа или учёба (если есть)',occupation_note:'Кем или в какой области работаете (кратко)',experienceGit:'Знаете Git? *',experienceGitOptions:[null,'Нет','Использовал для себя','Использовал в командной разработке'],experienceDoc:'Умеете пользоваться технической документацией и справочной литературой? *',experienceDocOptions:[null,'Почти не читал таковую','Иногда у меня возникают проблемы с чтением тех. документации','Да, у меня хороший опыт самостоятельной работы с тех. документацией'],experienceHtmlCss:'Сколько лет опыта с HTML/CSS? *',experienceHtmlCss_note:'Можно дробное число, например, полгода: 0.5',experienceProgramming:'Сколько лет опыта в коммерческой (оплачиваемой) разработке на любом языке с ООП? *',experienceProgramming_note:'Например, на PHP, Java, C# или другом языке, НЕ считая HTML/CSS',experienceJs:'Сколько лет опыта в JavaScript? *',experienceJs_note:'Можно дробное число, например, полгода: 0.5',needJob:'Ищу работу',social_note:'Профиль в соц. сети или личная страница, где можно узнать о вашей профессиональной деятельности.',purpose:'С какой целью записались на #{type}?',wishes:'Ваши пожелания по #{type}у?',submit:'Отправить'},signup_form:{signup_needed:'Для продолжения вам необходимо зарегистрироваться.',username:'Имя пользователя',password:'Пароль',submit:'Зарегистрироваться'}},signup:{order:'Заказ',title:'Запись на #{course}',title_order:'Заказ #{order}',amount:'Стоимость',no_such_group:'Нет такой группы.',signup_finished_title:'Запись в эту группу завершена',signup_finished:'Запись в эту группу завершена. Перейдите на страницу #{type}а, чтобы увидеть открытые группы.',signup_title:'Регистрация\\n #{title}',tutorial:'Учебник',course_description:'описание курса',choose_group:'Выберите, пожалуйста, группу из списка.',login_please:'Пожалуйста, войдите в сайт или зарегистрируйтесь.',plural_human:'человека,человек,человек',plural_participant:'участник,участника,участников',plural_participant2:'участника,участников,участников',receiptTitle:'Участие в #{type}е для #{count} #{people}',email_subject:'Заказ #{order}',payment_failed:'Оплата не прошла, попробуйте ещё раз.',questions:'По вопросам, касающимся оплаты, пишите на #{ordersMail}.',contact_info:'Контактная информация:',payment:'Оплата:',payment_succeed:'Осуществлена успешно',payment_pending:'Ожидается подтверждение',thanks_for_order:'Спасибо за заказ!',confirmation:'Вам направлено уведомление на адрес #{email}.',click_to_join_group:'Перейдите в раздел Курсы вашей учетной записи, чтобы присоединиться к группе.',edit_participants:'В разделе профиля Заказы введите, пожалуйста, данные участников.
',questions_after:'Если у вас возникли какие-либо вопросы, присылайте их на #{emailText}.',teacher:'Ведущий',seats_pluralize:'место,места,мест',seats_left:'Осталось #{seats} #{seats_pluralized}',seats_limited:'Количество мест ограничено',signup_button:'Записаться',subscribe:'Подписаться',confirmation_email:'На ваш email придёт письмо с информацией о дате и деталях программы.',this_course:'Этот курс',conducted_plural:'ведут:',conducted_single:'ведёт:'},statistic:{title:'Статистика участников'},feedback_loader:{no_feedback:'Отзывов пока нет.'},photo_load_widget:{wrong_format:'Неверный тип файла или изображение повреждено.'},participant_item:{participant:'Участник',invalid_email:'введите корректный email'},comment_form:{submit:'Опубликовать',cancel:'Отмена'},admin:{no_such_order:'Нет такого заказа.',no_such_group:'Нет такого заказа',no_such_file:'Нет такого файла',transfer_participant:'Вы переведены в группу #{title}',transfer_succeed_notified:'Перевод завершён, уведомление отослано.',transfer_succeed_not_notified:'Перевод завершён, уведомление НЕ отсылалось.',participant_edited:'Данные участника успешно изменены: #{email}',participant_deducted:'Участник отчислен: #{email}',document_uploaded:'Администратор загрузил документы к заказу #{order}'},course:{participant_discount:'Скидка 10% предоставлена EMAIL как участнику предыдущих курсов.'},patch:{information_updated_notified:'Информация обновлена, приглашения высланы на адреса: #{emails}.',information_updated_not_notified:'Информация об участниках обновлена.'},chat_logs:{title:'Логи группового чата',timeframe_from:'Временной диапазон c',timeframe_to:'по',apply:'Применить'},contacts:{title:'Контактная информация',note:'Оставьте ваши контактные данные, чтобы мы могли связаться с вами в случае необходимости',name_surname:'Имя и Фамилия:',phone:'Телефон:',data_secured:'Ваши данные в безопасности',personal_info:'Никакие ваши личные данные не будут переданы третьим лицам, кроме как по вашему желанию или для целей выполнения заключенного с вами договора.',save_and_continue:'Сохранить и продолжить'},grayed_list:{contact_info:'Контактная информация',payment:'Оплата',confirmation:'Подтверждение'},participant_register:{title:'Места и участники',participants_count:'Количество мест',only_one_place:'есть только 1 место, извините',enter_count:'введите значение от 1 до #{max}',already_participant:'Я являюсь участником',no:'НЕТ',yes:'ДА',amount:'Стоимость',add_participants:'Указать участников',add_later:'(это можно сделать позже)',save_and_continue:'Сохранить и продолжить'},payment:{title:'Оплата',do_not_pay_twice:'Не оплачивайте дважды. Меняйте метод оплаты лишь если уверены, что оплата не произошла.',terms_accept:'Оплачивая #{type}, вы соглашаетесь с договором оферты.',questions:'Если у вас возникли какие-либо вопросы, присылайте их на #{ordersMail}.',renew_order:'Заказ #{number} успешно переведен в статус ожидания оплаты.',renew_order_fail:'Вы не можете перевести заказ #{number} в статус ожидания оплаты, так как занятия уже начались.',goto_payment:'Перейти к оплате'},participant_info:{country:'Страна',city:'Город',about_link:'Ссылка на профиль',occupation:'Область работы',purpose:'С какой целью записались на #{type}?',wishes:'Ваши пожелания по #{type}у'},guarantee:{title:'Гарантия',description:'\\n - Если объяснения будут вам непонятны
\\n - Если курсы не дадут вам новых знаний и умений
\\n - Если вы не сможете подключиться к системе онлайн-обучения
\\n
…то вы сможете получить деньги назад.
\\nДля этого достаточно не позже окончания первой недели курса написать, что именно вас не устраивает, и тогда ваше участие будет прекращено, а вы получите деньги обратно.
\\n'},certificate:{title:'Сертификат',description:'По окончанию курсов каждый участник получает сертификат в электронном виде на русском и английском языках.'},additional_information:'Дополнительная информация',back_to_all:'Все курсы',create_order:{signup_finished:'Запись в эту группу завершена, извините.',no_seats:'Извините, в этой группе уже нет мест.',seats_limit:'Извините, уже нет такого количества мест. Уменьшите количество участников до #{max}.',no_contact_person:'Не указано контактное лицо.',no_email:'Не указан email.',invalid_email:'Некорректный email.',set_participants:'Отсутствуют участники.',not_authorized:'Вы не авторизованы.',title_check_prefix:'Обучение: #{title} (#{count}чел)',title_invoice_prefix:'Обучение: #{title}'},invite_email_subject:'Приглашение на #{type}: #{title}',invite_remind_email_subject:'#{group} – вы не присоединились к группе',request_notification:'Вы можете запросить уведомление:',promo_video:{text:'Обзор #{type}а'}};","export default {enter_email:'Введите, пожалуйста, email.'};","export default {group_start_soon:'Скоро группа: #{title}',reminder:'Напоминание #{title}',no_such_course:'Нет такого курса',not_a_teacher:'Вы не ведёте данный курс',days:['','пн','вт','ср','чт','пт','сб','вс'],group_exists:'Группа #{slug} уже существует'};","export default {server_connection_error:'Ошибка связи с сервером.',server_request_timeout:'Превышено максимально допустимое время ожидания ответа от сервера.',request_aborted:'Запрос был прерван.',no_response:'Не получен ответ от сервера.',server_error:'Ошибка на стороне сервера (код #{status}), попытайтесь позднее.',server_error_info:'Ошибка на стороне сервера (код #{status}). #{info}.',invalid_format:'Некорректный формат ответа от сервера.'};","export default {choose_newsletter:'Выберите рассылки из списка.',email_please:'Ваш e-mail?'};","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import Player from \"@vimeo/player\";\n\nexport default class VimeoVideoPlayer {\n\n constructor(options) {\n this.videoId = options.videoId;\n this.onClose = options.onClose;\n this.sizeList = [\n {width: 0, height: 0}, // mobile screens lower than any player => new window\n {width: 640, height: 360},\n {width: 853, height: 480},\n {width: 1280, height: 720}\n ];\n }\n\n\n openVideo() {\n let i = 0;\n\n for (i; i < this.sizeList.length; i++) {\n if (document.documentElement.clientHeight < this.sizeList[i].height ||\n document.documentElement.clientWidth < this.sizeList[i].width) break;\n }\n i--;\n\n this.currentWidth = this.sizeList[i].width;\n\n if (i === 0) {\n window.location.href = `https://vimeo.com/${this.videoId}`;\n } else {\n let modal = new Modal();\n modal.setContent(``);\n\n modal.elem.addEventListener('modal-remove', () => {\n if (this.player) {\n this.player.destroy();\n this.player = null;\n }\n if (this.onClose) this.onClose.call(this);\n });\n\n this.initPlayer();\n }\n }\n\n initPlayer() {\n if (this.player) {\n this.player.destroy();\n }\n\n this.player = new Player('player', {\n id: this.videoId,\n autoplay: true,\n width: this.currentWidth\n });\n }\n}\n","let newsletter = require('newsletter/client');\nlet Carousel = require('client/carousel');\nlet notification = require('client/notification');\nlet gaHitCallback = require('gaHitCallback');\n\nimport VimeoVideoPlayer from 'client/vimeoVideoPlayer';\n\nconst modalTemplate = require('./modal.pug');\nconst clientRender = require('client/clientRender');\n\nnewsletter.initNewsletterForm();\n\nconst LANG = require('config').lang;\nconst t = require('engine/i18n/t');\n\nconst videoContainer = document.querySelector('.courses-overview__video-container');\nif (videoContainer) initPlayer(videoContainer);\n\nfunction initPlayer(elem) {\n const video = elem.querySelector('.courses-overview__video[data-video-id]');\n const videoId = video.getAttribute('data-video-id');\n\n video.addEventListener('click', (e) => {\n e.preventDefault();\n elem.classList.add('courses-overview__video-container_playing');\n const player = new VimeoVideoPlayer({\n videoId,\n onClose: function() {\n elem.classList.remove('courses-overview__video-container_playing');\n }\n });\n\n player.openVideo();\n });\n}\n\nt.i18n.add('courses', require('../../locales/' + LANG + '.yml'));\n\nconst coursesFeedback = document.querySelector('.courses-feedback-inline');\n\nif (coursesFeedback) new Carousel({\n elem: coursesFeedback\n});\n\n{\n let courseSignupRef1 = document.getElementById('course-signup-ref-1');\n let courseSignupRef2 = document.getElementById('course-signup-ref-2');\n\n if (courseSignupRef1 && courseSignupRef2) {\n let initialBottom = courseSignupRef1.getBoundingClientRect().bottom + window.pageYOffset;\n // console.log(initialBottom);\n window.addEventListener('scroll', function toggleSignupButton() {\n if (courseSignupRef1.getBoundingClientRect().bottom < 0) { // top button scrolled out\n courseSignupRef2.style.display = '';\n } else if (window.pageYOffset < initialBottom) { // scrolled up till the old top button locationn\n courseSignupRef2.style.display = 'none';\n }\n });\n }\n}\n\n{\n window.addEventListener('scroll', showActiveCourseNav, {passive: true});\n //window.addEventListener('scroll', stickToRightCourseNav, {passive: true});\n\n function showActiveCourseNav() {\n let newActive = document.querySelector('.course-nav__bar-link');\n\n for(let link of document.querySelectorAll('.course-nav__bar-link')) {\n let id = link.getAttribute('href').slice(1);\n let a = document.getElementById(id);\n\n if (!a) continue; // incorrect document!\n\n if (a.getBoundingClientRect().top < 160) {\n newActive = link;\n } else {\n break;\n }\n }\n\n let oldActive = document.querySelector('.course-nav__bar-link_active');\n if (oldActive != newActive) {\n if (oldActive) {\n oldActive.classList.remove('course-nav__bar-link_active');\n }\n // console.log(newActive);\n newActive.classList.add('course-nav__bar-link_active');\n }\n\n }\n/*\n function stickToRightCourseNav() {\n let nav = document.querySelector('.course-nav');\n if (nav.style.position == 'fixed' && )\n }*/\n}\n\n{\n let subscribeLink = document.querySelector('[data-course-subscribe-open]');\n if (subscribeLink) {\n subscribeLink.onclick = () => {\n let form = document.querySelectorAll('[data-newsletter-subscribe-form]');\n form = form[form.length - 1];\n form.style.display = form.style.display == 'none' ? '' : 'none';\n }\n }\n}\n\n\n{\n function openCourseCarousel(imageNumber) {\n let modal = new Modal();\n modal.elem.classList.add('course-modal');\n\n let dataElem = document.querySelector('[data-course-carousel]');\n let options = JSON.parse(dataElem.dataset.courseCarousel);\n\n modal.setContent(clientRender(modalTemplate, options));\n\n let carousel = new Carousel({\n elem: modal.elem,\n });\n\n carousel.setPosition(imageNumber - 1);\n\n function keydown(event) {\n if (event.code == 'ArrowLeft') {\n carousel.prev();\n }\n if (event.code == 'ArrowRight') {\n carousel.next();\n }\n }\n\n\n document.addEventListener('keydown', keydown);\n modal.elem.addEventListener('modal-remove', () => document.removeEventListener('keydown', keydown));\n }\n\n document.body.addEventListener('click', event => {\n let opener = event.target.closest('[data-course-carousel-open-image]');\n if (opener) {\n openCourseCarousel(+opener.dataset.courseCarouselOpenImage);\n }\n });\n\n}\n\n/*\nlet coursesSignupButton = document.querySelector('[data-course-signup-button]');\n\nif (coursesSignupButton) {\n\n coursesSignupButton.addEventListener('click', function() {\n\n let form = coursesSignupButton.form;\n let slug = form.elements.slug.value; // hidden\n if (!slug) {\n // radio\n let checkedRadio = Array.from(form.slug).filter(e => e.checked)[0];\n if (!checkedRadio) {\n new notification.Error(t('courses.signup.choose_group'));\n return;\n }\n slug = checkedRadio.value;\n }\n\n window.location.href = '/courses/groups/' + slug + '/signup';\n\n });\n}\n*/\n"],"names":["map","webpackContext","req","id","webpackContextResolve","__webpack_require__","o","e","Error","code","keys","Object","resolve","module","exports","constructor","elem","this","list","querySelector","arrowLeft","arrowRight","position","onclick","next","bind","prev","render","children","length","setPosition","style","transform","setAttribute","removeAttribute","thumb","require","config","t","template","locals","lang","env","addStandardHelpers","create","LANG","localCurrency","shopCurrency","NODE_ENV","rateShopTo","countryCode","ordersMail","providers","stripeKey","paypalClientId","telegramBotId","lookatCodeUrlBase","isRTL","delegate","topElement","selector","eventName","handler","context","addEventListener","event","found","currentNode","target","matches","currentTarget","parentElement","findDelegateTarget","delegateTarget","call","delegateMixin","obj","csrfCookie","document","cookie","match","url","width","height","pixelRatio","window","devicePixelRatio","modifier","slice","lastIndexOf","NotificationManager","options","notifications","verticalSpace","register","notification","unshift","setTimeout","recalculate","unregister","idx","indexOf","splice","top","forEach","init","notificationManager","Notification","html","type","timeout","elemHtml","body","insertAdjacentHTML","lastElementChild","undefined","TIMEOUT_DEFAULT","TIMEOUT_SLOW","TIMEOUT_FAST","setupCloseHandler","setupCloseTimeout","close","parentNode","remove","offsetHeight","value","prototype","Info","super","Warning","Success","Recaptcha","initForms","loadScript","async","submitButtons","querySelectorAll","button","disabled","form","recaptcha","onsubmit","preventDefault","validateForm","checkValidity","submit","reportValidity","promise","RECAPTCHA_ID","Promise","reject","recaptchaCallback","script","createElement","src","onerror","head","appendChild","renderPromise","renderPromiseResolve","renderPromiseReject","widgetId","container","append","grecaptcha","sitekey","size","callback","execute","token","getResponse","input","elements","name","Spinner","class","elemClass","start","classList","toggle","stop","spinnerElem","getCsrfCookie","i18n","add","reason","request","XMLHttpRequest","method","open","sync","skipCsrf","setRequestHeader","responseType","toString","JSON","stringify","noDocumentEvents","timeStart","Date","now","wrapEvent","dispatchEvent","result","raw","normalStatuses","CustomEvent","originalEvent","fail","status","response","responseText","getResponseHeader","json","parse","includes","success","info","send","err","console","error","phrase","hasPhrase","arguments","setFallback","args","arg","__esModule","default","addPhrase","count","string","n","Math","floor","values","split","f","wasCalled","xhr","MultiSelect","submitSubscribeForm","onSuccess","email","slugElem","slug","userLogged","slugs","option","replace","action","submitButton","spinner","message","gaEvent","initNewsletterForm","forms","isLogged","select","multiSelect","formButton","formButtonTextEl","getValues","textContent","pluralize","textContainer","defaultValue","createDropdown","setButtonTitle","bindHandlers","selected","join","toggleDropdown","item","onChange","stopPropagation","toggleStatus","boundCloseDropdown","closeDropdown","closest","removeEventListener","filter","getAttribute","pop","contains","Event","isNode","global","getMethodName","prop","toLowerCase","concat","substr","toUpperCase","isDomElement","element","Boolean","nodeType","ownerDocument","defaultView","isInteger","isNaN","parseFloat","isFinite","isVimeoUrl","test","isVimeoEmbed","getOembedDomain","domain","_i","_customDomains","customDomain","endsWith","getVimeoUrl","oEmbedParameters","idOrUrl","TypeError","subscribe","onName","offName","eventNames","evName","cancel","arrayIndexOfSupport","Array","postMessageSupport","postMessage","self","WeakMap","hasOwnProperty","hasDefine","defineProperty","x","object","configurable","writable","genId","checkInstance","methodName","isObject","prefix","rand","random","substring","key","entry","_id","globalThis","commonjsGlobal","definition","builtInProp","cycle","scheduling_queue","ToString","timer","setImmediate","fn","val","schedule","drain","isThenable","_then","o_type","then","notify","i","chain","notifyIsolated","state","failure","cb","ret","msg","triggered","def","def_wrapper","MakeDefWrapper","apply","iteratePromises","Constructor","arr","resolver","rejecter","MakeDef","executor","__NPO__","push","first","last","Item","PromisePrototype","len","msgs","callbackMap","storeCallback","player","playerCallbacks","get","set","getCallbacks","removeCallback","index","shiftCallbacks","shift","swapCallbacks","oldElement","newElement","delete","parseMessageData","data","params","contentWindow","ieVersion","navigator","userAgent","origin","processData","param","callbacks","getOEmbedParameters","defaults","reduce","createEmbed","_ref","div","innerHTML","firstChild","getOEmbedData","videoUrl","encodeURIComponent","XDomainRequest","onload","domain_status_code","initializeEmbeds","parent","handleError","catch","resizeEmbeds","VimeoPlayerResizeEmbeds_","onMessage","iframes","source","paddingBottom","bottom","initAppendVideoMetadata","VimeoSeoMetadataAppended","iframe","isValidMessageSource","Player","callMethod","location","href","checkUrlTimeParam","VimeoCheckedUrlTimeParam","_loop","getVideoId","videoId","RegExp","exec","sec","decodeURI","setCurrentTime","initializeScreenfull","fnMap","l","eventNameMap","fullscreenchange","fullscreenerror","screenfull","onFullScreenEntered","off","on","returnPromise","documentElement","requestFullscreen","exit","isFullscreen","onFullScreenExit","exitFullscreen","defineProperties","fullscreenElement","enumerable","isEnabled","fullscreenEnabled","defaultOptions","role","autoPlayMuted","allowedDrift","maxAllowedDrift","minCheckInterval","maxRateAdjustment","maxTimeToCatchUp","TimingSrcConnector","_EventTarget","_inherits","_super","_createSuper","_player","timingObject","_this","logger","_classCallCheck","_defineProperty","_assertThisInitialized","_asyncToGenerator","_regeneratorRuntime","mark","_callee","newAdjustment","newPlaybackRate","wrap","_context","speedAdjustment","abrupt","getPlaybackRate","t0","sent","t1","t2","t3","log","setPlaybackRate","_x","_x2","_objectSpread2","_createClass","_init","_callee2","playerUpdater","positionSync","timingObjectUpdater","_this2","_context2","waitForTOReadyState","updatePlayer","maintainPlaybackPosition","updateTimingObject","_x3","_x4","_x5","_updateTimingObject","_callee3","_context3","getCurrentTime","getPaused","t4","velocity","update","_x6","_x7","_updatePlayer","_callee5","_timingObject$query","_context5","query","pause","play","_ref2","_callee4","_context4","setMuted","err2","_x11","_x8","_x9","_x10","_this3","syncInterval","min","max","check","_ref3","_callee6","diff","diffAbs","adjustment","_context6","abs","adjustSpeed","sign","interval","setInterval","clearInterval","_this$logger","readyState","once","_wrapNativeSuper","EventTarget","playerMap","readyMap","jQuery","warn","getElementById","nodeName","has","_window","readyPromise","npo_src","_onMessage","isReadyEvent","isPingResponse","_originalElement","fullscreenchangeHandler","ready","_this4","time","language","kind","_this5","removeChild","autopause","camera","all","color","colors","isArray","nullPromise","colorPromises","currentTime","loop","muted","playbackRate","quality","volume","_setTimingSrc","connector","_this6","setTimingSrc","parser","plural","_class","isString","isNumber","isBoolean","nativeForEach","iterator","formatRegExp","format","String","Number","flatten","sub_val","sub_key","keySeparator","makePhraseKey","locale","searchPhraseKey","storage","_storage","_defaultLocale","fb_cache","_fallbacks_cache","fb_key","fb","_fallbacks","pluralizer","BabelFish","defaultLocale","_plurals_cache","translation","flattenLevel","fl","Infinity","fallbacks","CAN_HAVE_DIRECTIVES_RE","translate","compiled","str","nodes","buf","strict_exec","forms_exec","plurals_cache","text","node","anchor","strict","k","parsed","unescaped","Function","compile","noFallback","getLocale","unique","out","fallback","locales","load","phrases","rule","SyntaxError","expected","offset","line","column","child","ctor","peg$subclass","peg$result","peg$FAILED","peg$startRuleFunctions","peg$parsestart","peg$startRuleFunction","peg$c1","peg$c2","peg$c3","description","peg$c4","peg$c5","peg$c6","peg$c7","regularForms","strictForms","peg$c8","peg$c9","peg$c10","part","more","peg$c11","peg$c12","peg$c13","peg$c14","peg$c15","peg$c16","peg$c17","peg$c18","peg$c19","peg$c20","peg$c21","peg$c22","peg$c23","peg$c24","char","peg$c25","peg$c26","peg$c27","peg$c28","peg$c29","peg$c30","peg$c31","peg$c32","peg$c33","peg$c34","peg$c35","peg$c36","peg$c37","peg$c38","peg$c39","peg$c40","peg$c41","peg$c42","peg$c43","lc","peg$c44","literal_chars","peg$c45","peg$c46","peg$currPos","peg$reportedPos","peg$cachedPos","peg$cachedPosDetails","seenCR","peg$maxFailPos","peg$maxFailExpected","peg$silentFails","startRule","peg$computePosDetails","pos","details","startPos","endPos","p","ch","charAt","advance","peg$fail","peg$buildException","posDetails","sort","a","b","cleanupExpected","expectedDescs","s","hex","charCodeAt","stringEscape","buildMessage","s0","s1","peg$parseliteral","peg$parseplural","peg$parsevariable","s2","s3","s4","peg$parseplural_forms","peg$parseidentifier","peg$parseplural_anchor","peg$parseplural_part","s5","peg$parseplural_char","peg$parseidentifier_part","peg$parseliteral_char","normalize","loc","c_re","cFn","sval","spl","pow","v","w","o_indexOf","oFn","c","ordinal","FORMS","unpack","B","y","IN","n100","i10","i100","i1000","n10","n1000000","f10","f100","i1000000","n1000","n100000","pug","pug_html","locals_for_with","deployed","attr","pug_has_own_property","pug_classes","escaping","className","classString","padding","escapeEnabled","pug_escape","pug_classes_array","pug_classes_object","pug_style","pug_attr","escaped","terse","toJSON","merge","pug_merge","attrs","valA","valB","classes","pug_match_html","_html","regexResult","lastIndex","escape","rethrow","pug_rethrow","filename","lineno","ex","lines","end","curr","path","site","privacy_policy","terms","banner_bottom","action_required","gdpr_dialog","title","accept","theme","light","dark","change","toolbar","lang_switcher","cta_text","footer_text","old_version","logo","normal","svg","small","sections","sections_bak","buy_ebook_extra","buy_ebook","search_placeholder","search_button","public_profile","account","admin","logout","sorry_old_browser","contact_us","about_the_project","ilya_kantor","comments","loading","search","share","read_before_commenting","last_updated_at","choose_section","comment","help","meta","edit_on_github","hide_forever","hidden_forever","agreement","button_unsubscribe","common_updates","common_updates_text","your_email","newsletters","no_selected","value_must_not_be_empty","value_is_too_long","value_is_too_short","invalid_email","invalid_value","invalid_autocomplete","invalid_date","invalid_range","save","upload_file","server_error","line1","line1_0","line2","no_user","no_participant","no_certificate","invite","invitation","invitation_masterclass","seat_has_been_reserved","click_to_join","contact_person","questions","invite_remind","hello","still_not_joined","join_for","materials","materials_added","click_to_download","move","you_were_moved","order_cancel","subject","order_cancelled","group_start_soon","payment_expired","duplicate","list_orders","need_login","already_payed_or_soon","already_payed","valid_one_day","payment_confirmation","payment_confirmed","participation_confirmed","free_participation","is_participant","title_all","average_grade","grades","participated","recommend_text","recommend_text_frontpage","all_feedbacks","feedback_cut","page","recommend","course","teacher","edit","grade","recommend_yes","recommend_no","feedback","feedback_placeholder","is_public","is_public_note","photo","photo_upload","country","city","occupation","social","social_note","delete_confirm","deleted","policy","policy_list","teachers","courses","opened_courses","people_talk_about","people_talk_about_single","features","program","master_class","master_class_text","opinions","ongoing","teachers_title","teachers_description","phone_toggler","learn_more","faq","another_question","old_comments","participant_logos","notes","professionals","articles","userpic","username","linkedin_link","about","dropbox_share","enter_email","by_default","request_access","no_dropbox","notify_me","serial_number","added_date","no_materials","chat_logs","slack_logs","course_feedback","missing_score","missing_text","missing_country","course_group","invalid_timeStart","invalid_timeEnd","course_participant","missing_name","invalid_name","missing_surname","invalid_surname","invalid_url","masterclass","by_user","jb","ical","tasklist","participants","participants_json","group_feedback_list","plural_feedback","group_feedback_edit","no_rights","public_feedback","private_feedback","rate_course","missing_feedback_text","group_feedback_show","head_title","comment_saved","comment_save_error","group_finish","group_cancel","group_materials","added_with_notifications","added_wo_notifications","email_subject","remove_file","file_removed","settings_saved","group_materials_download","invalid_link","group_slack_register","already_slack_user","user_invited","group_telegram_role","not_participant","no_target","invite_generated","group_slack_invite","no_slack_user","user_added","data_updated","fix_errors","order","already_accepted_title","already_accepted","outdated_link_title","outdated_link","already_added","choose_country","details_form","first_name","surname","first_name_en","surname_en","occupation_note","experienceGit","experienceGitOptions","experienceDoc","experienceDocOptions","experienceHtmlCss","experienceHtmlCss_note","experienceProgramming","experienceProgramming_note","experienceJs","experienceJs_note","needJob","purpose","wishes","signup_form","signup_needed","password","signup","title_order","amount","no_such_group","signup_finished_title","signup_finished","signup_title","tutorial","course_description","choose_group","login_please","plural_human","plural_participant","plural_participant2","receiptTitle","payment_failed","contact_info","payment","payment_succeed","payment_pending","thanks_for_order","confirmation","click_to_join_group","edit_participants","questions_after","seats_pluralize","seats_left","seats_limited","signup_button","confirmation_email","this_course","conducted_plural","conducted_single","statistic","feedback_loader","no_feedback","photo_load_widget","wrong_format","participant_item","participant","comment_form","no_such_order","no_such_file","transfer_participant","transfer_succeed_notified","transfer_succeed_not_notified","participant_edited","participant_deducted","document_uploaded","participant_discount","patch","information_updated_notified","information_updated_not_notified","timeframe_from","timeframe_to","contacts","note","name_surname","phone","data_secured","personal_info","save_and_continue","grayed_list","participant_register","participants_count","only_one_place","enter_count","already_participant","no","yes","add_participants","add_later","do_not_pay_twice","terms_accept","renew_order","renew_order_fail","goto_payment","participant_info","about_link","guarantee","certificate","additional_information","back_to_all","create_order","no_seats","seats_limit","no_contact_person","no_email","set_participants","not_authorized","title_check_prefix","title_invoice_prefix","invite_email_subject","invite_remind_email_subject","request_notification","promo_video","reminder","no_such_course","not_a_teacher","days","group_exists","server_connection_error","server_request_timeout","request_aborted","no_response","server_error_info","invalid_format","choose_newsletter","email_please","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","getter","d","g","r","Symbol","toStringTag","VimeoVideoPlayer","onClose","sizeList","openVideo","clientHeight","clientWidth","currentWidth","modal","Modal","setContent","destroy","initPlayer","autoplay","newsletter","Carousel","modalTemplate","clientRender","videoContainer","video","coursesFeedback","courseSignupRef1","courseSignupRef2","initialBottom","getBoundingClientRect","pageYOffset","display","showActiveCourseNav","newActive","link","oldActive","passive","subscribeLink","openCourseCarousel","imageNumber","dataElem","dataset","courseCarousel","carousel","keydown","opener","courseCarouselOpenImage"],"sourceRoot":""}