Pondok Pesantren Tahfizul Qur'an

Казино 1xbet Играть Онлайн Бесплатно%2C Официальный Сайт%2C Скачать Клиент

Казино 1xbet Играть Онлайн Бесплатно%2C Официальный Сайт%2C Скачать Клиент”

1xbet 1хбет Кз Букмекерская Контора%3A Официальный Сайт%2C Обзор%2C Ставки В Казахстане

Content

Можно также связаться с оператором судя телефону%2C электронной почте или через формы обратной связи. Ученые техподдержки отвечают шустро и помогают четко разобраться с возникшей проблемой. В казино используется система преданности%2C состоящая из 8 статусов. Повышение ранга игрока зависит от заработанных им баллов%2C которые начисляются за депозиты и ставки.

  • У бренда 1xBet нет отделения в многочисленных странах%2C однако юридически с казахстанским офисом они не связаны.
  • Достаточно того%2C на сайте 1xBet предусмотрена возможностей составить удачную комбинацию и” “сокровенными своим купоном.
  • Причины%2C по которым 1xBet не работает%2C либо быть несколько.
  • Утилита создана так%2C чтобы быть более безопасной%2C чем сайт для мобильных устройств или настольных компьютеров.

Это делает этап ставок максимально захватывающим и действительно увлекательным. 1xBet — букмекерская контора%2C которая предлагает услуги по ставкам на различные события%2C от спорта конца развлекательных шоу а политики. Букмекерская контора предлагает казино же лайв-казино%2C виртуальные же киберспортивные игры. Есть также несколько бонусов%2C которые букмекерская контора предлагает клиентам%2C же другие функции%2C их делают процесс ставок интересным. Это но некоторые из услуг%2C которыми вы смогу воспользоваться в 1xbet kz вход%2C одной из самых преданных букмекерских контор самого времени. Пользователи девайсов могут спокойно сделано 1хБет ставки онлайн через браузер.

Место и Рейтинге Букмекеров от Meta-ratings

1xbet” “apk скачивать можно%2C же с официального портала%2C так и одним магазина приложений. Судя функционалу 1xbet приложение ничем не отличии от десктопа. Где также можно регистрироваться (если ранее этот пункт не который пройден)%2C пополнять баланс%2C активировать бонусы и т. п. Скачать приложение на Android можно на официальном сайте БК – баннер с замечанием установить ПО появиться на экране.

  • Для его отыгрывания” “невозможно использовать ставки%2C подобные “Экспресс”.
  • На отдельной странице собраны условия пользования сервисами%2C где вкратце описаны правила ставок в различных рассмотренных.
  • На сайте конторы представлены уже все спортивные а киберспортивные дисциплины%2C включая турниры и чемпионаты международного уровня.
  • БК 1xBet была основана в 2007 году и и прошедший период стало одним из активнейших букмекерского бизнеса во всем мире.

Bet Slip Battle фокусируется на игроках%2C делающих ставки со коэффициентом от 30 и выше%2C же предлагает бонусы. Каждый день приз а размере 700%24 вручается самому успешному менеджеру%2C участвующему в акции. Быстрый вход на сайт доступен пользователям%2C имеющим аккаунт в Одноклассниках%2C ВКонтакте также Telegram или учетную запись в Mail%2C Google или Яндексе. Дополнительно нужно же указать валюту счета и затем заполнить персональные данные. Севилестр можете делать в букмекерской конторе 1хБет разные виды ставок. Они могут быть ординарными (на другое событие)%2C” “экспрессами (несколько событий сразу)%2C системами (дуэт экспрессов)%2C а также многое другое 1xbet скачать.

Законны Ли Бк Онлайн В Казахстане%3F

Не начал делать ставки в 1 иксбет после того%2C как на работе только начали делать ставки и выигрывать. Нормализаторской – раздел “Банковские карты” и нажать на “Каспи голд”. В ППС а в online – портале принимают государственную валюту – тенге (KZT)%2C в деньгах евро и доллары. Для обращения применять любой язык%2C допустимый для 1xbet. Электронный способ возможен только на русском например английском%2C что не всегда удобно ддя пользователя. Все материалы сайта доступны судя лицензии Creative Commons Attribution 4. 0 International.

  • Зеркало — копия всем информации и функций сайта%2C расположенная по альтернативному адресу.
  • На сайте БК 1хБет регистрация предназначена любому жителю Казахстана%2C достигшему 21-летнего возраста.
  • Для многочисленных клиентов бонусы 1хБет — явление привычный.
  • 1XBet создала что простую платформу пиппардом большим количеством рынков ставок%2C доступ к которым можно получить в меню впереди от главного экрана.

“Дли того чтобы заключать пари в 1xbet kz%2C можно пользоваться как браузерной версией%2C так и скачать 1xbet бесплатно на телефон или планшет. Благодаря простому а понятному макету сайта даже те%2C никто делает ставки разу%2C могут быстро понять как найти интересующие рынки. На нашем портале можно поставить не только в классические спортивные дисциплины%2C но и в киберспорт. Пари такого типа становятся но популярнее%2C и 1xbet как лидер рынка предлагает широкий выбор савок на киберспорт.

Трансляции И Ставки 1xbet Live

Неоценимую помощь окажет APK (Android Package) – формат файла%2C со помощью которого устанавливают приложения и игры. Используются приложения операционных систем Android же iOS. Бесплатно скачать на телефон (андроид%2C айфон) можно на главной странице сайта. Сохранены все опции для осуществления мобильного беттинга. При можно%2C чтобы защитить аккаунт%2C включается двухфакторная аутентификация.

Экспресс отобразится в история ставок%2C которая%2C а свою очередь%2C находитесь в личном служебном. Приветственное вознаграждение позволяет новым игрокам непривычном в букмекерской конторе без финансовых рисков. Однако программы 1хWin%2C 1хAссess%2C 1xBrowser — продукты отделений 1xBet с другими лицензиями%2C на сайте в Казахстане они но представлены.

Акции И Бонусы 1xbet Kz

В Казахстане букмекерская контора 1хБет работает по лицензии ТОО «Realbet». Юридический адрес —%2C Республика Казахстан%2C Алматинская область%2C г. БК 1xBet была основана в 2007 году и и прошедший период стало одним из виднейших букмекерского бизнеса всяком всем мире. Так подтверждает ряд престижной наград и премий%2C победителем и номинантом которых становился букмекер — SBC Awards%2C Global Gaming Awards и International Gaming Awards. С 2019 года БК 1хБет является официальным беттинг-партнером ФК “Барселона”.

  • Стартовая страница встречает пользователей сжатым обзором главных нераспространенных компании – бонусы%2C перечень услуг%2C лучшие лайв и прематч ставки.
  • Можно нажать кнопку «Регистрация» в верхней части экрана%2C ввести номер телефона%2C подтвердить утвердительный с правилами букмекера и достижения возраста 21 года.
  • Для поиска автоматов по первым буквам в названии нельзя использовать поисковую строку.
  • Для того того собрать экспресс на 1хBet%2C открываем линию (прематч или лайв) и нажимаем в интересующий коэффициент.

Проверьте баланс своего бонусного счета а разделе промо и перейдите в прилавок промокодов. Выберите промо в зависимости от вида спорта%2C введите количество бонусных баллов%2C которые вы вас потратить%2C и сделайте ставку. Справедливо даем 1XBet очень высокую оценку за его производительность как пиппардом точки зрения прямых трансляций%2C так а с точки точки ставок в реальном времени. Например%2C а среднем в вчера или субботу однажды в режиме реальных времени доступно только менее 200 возможностей 1xbet live.

Ставки в Спорт 1xbet Kz

Выбран исходы автоматически добавляются в купон ставок. Следует воспользоваться вверх расположенным меню а верхней части. События%2C происходящие в реальный момент времени%2C отражаться в центре экрана. Выбирают заинтересовавшее событие и нажимают на ту ставку%2C которую хотят сделать. Его вписывают в предстало окно и нажимают “Ставку сделать”. Казахи предпочитают игровые видов спорта%2C но в 1xbet лайв их показывают редко.

  • Них информационные страницы находимся на нижней панели.
  • Наличие русские интерфейса%2C валютного счета в рублях РОССИЙСКОЙ и русскоговорящих операторов службы поддержки замечают внимание игроков из России и европе СНГ.
  • Бонусный кредит необходимо отыграть более 5 раз по экспресс-ставкам” “пиппардом коэффициентом 1%2C 40 или выше.
  • Дополнительно иногда требуется подтвердить намерение участвовать в конкретном розыгрыше.
  • В таком случает открыть окно дли авторизации%2C ввести ID%2C телефон или почту.

Для его отыгрывания” “невозможно использовать ставки%2C это “Экспресс”. Среда и пятница – дни%2C когда беттор%2C пополнивший счет%2C может иметь дополнительные деньги. Если бонус будет отыгран в течение дней%2C то бонусный счет увеличивают трехкратно. Самый простой вариант регистрации — на мобильном сайте букмекера. Нужно нажать кнопку «Регистрация» в верхней точки экрана%2C ввести номер телефона%2C подтвердить утвердительный с правилами букмекера и достижения преклонном 21 года. Зеркало — копия всем информации и функций сайта%2C расположенная вопреки альтернативному адресу.

Регистрация на Официальном Сайте 1xbet

Сервис 1хБет предлагает игрокам широкие малейшей для ставок. Причины%2C по которым 1xBet не работает%2C или быть несколько. Только с любыми делами%2C доступно легко связь со службой поддержки клиентов букмекерской конторы%2C чтобы решить их. Например%2C вы смогу использовать каналы живого чата%2C отправить электронное письмо или позвоню им по телефону. Если 1xbet скачать на телефон%2C то гэмблер получит подлинную БК в своем кармане. Утилита предназначенная так%2C чтобы может более безопасной%2C чем сайт для мобильных устройств или настольных компьютеров.

Это включает а себя выполнение задач%2C установленных 1XBet%2C них меняются ежедневно. Отличия лишь в том%2C что%2C если в сайте Линия и Лайв размещены на главном экране%2C же в приложении них находятся во вкладке «Меню» в правом нижнем углу. А обзоре на одной странице вы узнаете об особенностях БК 1xBet%2C о регистрации%2C методах транзакций%2C процессе совершения ставок.

Bet Kz Вход официального Сайт

БК 1хбет КЗ почисленно работает на всей территории Казахстана%2C его не блокируют. Вопреки законам Казахстана игроки из России не могут пользоваться услугами площадки в чистом доступе. Для заключения пари они вечно ищут обновленное пенальти зеркало на день. Во-первых%2C во вкладке «Статистика» представлена раскладка по видам спорта.

  • В БК можно применять опцию Multi Live – добавить несколько матчей в избранное и оформлять одновременного сделки.
  • Причин этому может быть несколько – технические работы%2C перегрузка сервера.
  • В декабре 2020-го БК получила государственную лицензию%2C получив легальный статус на территории республики.
  • Служба поддержки клиентов обращает заявки%2C одобряет но и присылает пользователям%2C что можно сделано с деньгами на счету.

Самая страница портала имеет приятный дизайн а сине-белых тонах. Благодаря простому и бессознательно понятному интерфейсу%2C но новички с легкостью найдут нужные им рынки и может начать делать ставки. Количество доступных опций в первые минуты ошеломить%2C но неправильная структура макета же фильтрование представленных рынков помогают быстро сообразить на площадке. Мобильная версия открывается в любых браузерах и имеет те только функции%2C что же десктопная%2C но страницы адаптируются к размерам%2C разрешению и ориентации экранов гаджетов. Игрокам не нужно ищете зеркало «1хБет» – букмекер осуществляет легальную деятельность в Казахстане.

Преимущества И преимущества Бк 1xbet

Случайное сочетание знаков%2C куда входят цифры%2C буквы%2C символы. Промокод разрабатывается сотрудниками конторы%2C его используют%2C чтобы получить бонус на первый депозит. В каждом 10-м слоте игроку начисляется 50% на бонусный счет. Колесо” “фортуны предпочитают новые игроки%2C не обладающие достаточным опытом. Если доля большая%2C то а силу вступает этапа верификации. Минимум%2C но можно ввести – 312 тенге%2C выходить – не менее 600 тенге.

  • Во-первых%2C во вкладке «Статистика» представлена раскладка по видам спорта.
  • Я приветствую%2C что на этом портале можно в сорт поставить и слоты крутить.
  • Кроме одиночных пари%2C букмекером%2C поэтому%2C предусмотрены и экспресс-ставки.
  • В 2016 году 1xbet КЗ букмекерская контора приобрела легальный статус%2C получив лицензию от 13 полугодовщина 2016 года.
  • На выигрыши%2C полученные также использовании фриспинов%2C но распространяется вейджер.
  • Что противоречит котировкам на равновероятностные исходы примерно в 1. 95.

Компания предлагает выгодные условия сотрудничества%2C широкую линию ставок на спорт же стимулирует как нового%2C так и зарегистрированных пользователей. На сайте конторы представлены почти все спортивные и киберспортивные дисциплины%2C начиная турниры и чемпионаты международного уровня. Букмекерская контора принимает ставки на события из” “мира политики%2C шоу-бизнеса. Разработчики предлагают игрокам скачать клиент казино 1xbet для ПК%2C только также мобильные приложения для Android же iOS. К сожалению%2C они позволяют а делать ставки и спорт. Для запуска игровых автоматов и смартфонах и планшетах предлагается использовать мобильную браузерную версию сайта.

Бонусы

Да%2C клиенты 1xbet могут получить промокод на дружественных ресурсы или воспользовавшись вопросом в уникальном разделе «Магазин промокодов». Ддя вывода средств 1xBet предлагает те же возможности%2C что и для депозитов. Букмекерская контора «1хБет» предложил опцию CashOut ддя отдельных ставок. Мобильный ресурс букмекера открывающийся в браузерах телефонов и планшетов. Также создании профиля в БК можно использовать только казахстанские мобильные номера.

  • В Интернете можно встретить жалобы клиентов на блокировки счетов%2C дополнительные проверки личности и проблемы со выплатой крупных выигрышей.
  • Среди них бонусы за неудачные ставки%2C награды за серии побед%2C подарки именинникам и другие.
  • Если не удается пойти%2C значит возникли технические вопросы — пиппардом интернет-соединением%2C девайсом или дело во временных работах у букмекера.
  • Однако другие вида%2C такие как наличные карты и наличными переводы%2C могут проходит с задержкой.

Другими партнерами 1xBet являются Федерация футбола Нигерии и главная лига другой страны – NPFL. В 2019-м году букмекер спонсировал проведение Кубка Африканских Наций. К услугам клиентов доступен весь необходимый инструментарий для безопасного совершения ставок. Каждой стоит отметить некоторое количество прямых видео трансляций спортивных произошедших%2C которые можно увидеть в полноэкранном режиме. Само количество помогающих прямых эфиров так зашкаливает – ото событий мирового статуса до узкорегиональных соревнований. Конторы обязуются удерживать эти налоги%2C не по своему своему могут компенсировать игрокам эти средства.

Как сделали Ставки На Мобильном Телефоне С помощи 1xbet%3F

Примером служит букмекерская контора 1xbet а Казахстане. Дизайн 1xBet KZ практически но менялся с даты основания компании. Как делает интерфейс а логотип букмекера крайне запоминающимися. Платформа полноценным выполнена в таких его оттенках – от тёмного вплоть небесно-голубого. Стартовая страница встречает пользователей сжатым обзором главных нераспространенных компании – бонусы%2C перечень услуг%2C самые лайв и прематч ставки.

Каждый игрок подберет именно тот тип ставки%2C тот соответствует индивидуальным предпочтениям. Помимо этого%2C вы можете подстраиваться надзором конкретную стратегию. Компания 1хБет предлагает высокого коэффициенты на разнообразные события.

Зеркало

Ставки во время трансляций позволят высокий уровень азарта и часто предоставляют неплохую прибыль. Нас клиенты могут иметь такой опыт%2C распахнул раздел 1xbet лайв. В этом разделе можно также найду результаты предыдущих состязаний и другую полезную информацию для ставок в игре. Служба потоковой передачи являлось высококачественной%2C поскольку ото этого зависят результаты пари и комфорт бэттеров.

Если хуже знать возможности%2C силы и преимущества разных спортивных команд%2C а можно постоянно выйдет в большой максимум. Здесь доступно потом большое количество матчей из разных категорий на выбор%2C поэтому есть возможность ставить ежедневно без особых затруднений. Раздел со трансляциями и live ставками обеспечивает желающим максимальное удовольствие же азарт.

Пополнение Депозита И вывод Выигрышных Денег

Стоимость досрочного выкупа определяет букмекер в основе текущих коэффициентов на проход заключенного пари. Приложение 1xBet на iOS ложится перед игроками основные и дополнительные никакой для ставок. Линия букмекера охватывает профессиональную турниры и региональные первенства по компьютерным играм. Котировки и лайв БК обновляет своевременно%2C задержки или заключении пари незначительных. Букмекер сопровождает игры онлайн-трансляциями%2C инфографикой а подробной статистикой.

  • Количество активных игроков доходит нескольких сотен некто%2C поэтому столы формируются достаточно быстро.
  • Же некоторые из них действительно интригуют а доставляют удовольствие.
  • Это букмекерская контора%2C начавшая свою деятельность в 2007 году.
  • Линии и коэффициенты – главное%2C ради ничего беттеры заходят и официальный сайт 1хбет.

Но учти%2C что отдельно промокоды применяются и в ходе ставок%2C и и качестве бонусов%2C же что с со придется разбираться дополнительные.”

Раздел Live

Параллельно и коэффициенты – главное%2C ради ничего беттеры заходят на официальный сайт 1хбет. В 2016 году 1xbet КЗ букмекерская контора приобрела легальный статус%2C получив лицензию от 13 накануне 2016 года. Старой версия интерпретирована же приспособлена к местных условиям.

  • “Ддя того чтобы заключать пари в 1xbet kz%2C можно обходиться как браузерной версией%2C так и скачать 1xbet бесплатно в телефон или планшет.
  • Регрессной беттерам доступны бесплатные ставки%2C возврат учетом суммы денег каждую неделю%2C прочие поощрения.
  • Оператор предложила широкий выбор спортивных и киберспортивных дисциплин%2C пари на судьбу политических событий и даже ставки в прогноз погоды.
  • К услугам клиентов доступен весь необходимые инструментарий для комфортного совершения ставок.

Достаточно указать страну и валюту игрового счета%2C чтобы автоматически оставались созданы логин а пароль. Впоследствии нельзя заполнить все поля с персональной информацией в личном кабинете. В отдельные категории вынесены популярные видеослоты и новинки%2C специально добавленные на сайт. Реализована возможность принимать тайтлы в подробный избранных для быстрого перехода к мной и просматривать предыстория%2C в которую попадет последние запущенные игры. Для поиска автоматов по первым буквам в названии можно использовать поисковую строчки. Это бездепозитные бонусы%2C раздаваемые активным игрокам за участие в промоакциях.

Как Вывести деньги Со Своего Счета 1xbet%3F

На верхняя горизонтальной панели и виде списка представлены ссылки на но основные разделы. 1хбет кз принимает ставки онлайн на официальном сайте и и приложениях на iOS Android. 1xBet — это в очередь очередь букмекерская контора%2C поэтому делать ставки можно практически на любое событие.” “[newline]Сначала зайдите на сайт 1xBet и войдите в собственную учетную запись. Потом найдите спортивное соображение%2C на которое вас сделать прогноз. Сделаете любые другие ставки на спорт%2C поставив на раунд твои деньги и нажмите на кнопку ставки. Любителям играть в тотализаторе оператор предложила большое количество акций.

  • Да%2C клиенты 1xbet могут получить промокод на дружественных ресурсах или воспользовавшись замечанием в уникальном разделе «Магазин промокодов».
  • Бонус всегда отыгрывается%2C пользователь вправе отказаться ото него.
  • Сервис 1хБет предложила игрокам широкие малейшей для ставок.
  • Только с любыми делами%2C доступно легко связывался со службой помощью клиентов букмекерской конторы%2C чтобы решить его.

Кешаут а 1хбет проходит почти также%2C как и пополнение. Необходимо учитывать%2C что вывести приличные можно” “только на тот счет ли кошелек%2C он был использован ддя депозитов. Посетители%2C них решили прекратить действие учетной записи%2C могло написать в дослужившись поддержки%2C указав мой ID и причины данного решения. Время одобрения заявки операторы вышлют клиенту информацию%2C которая поможет вывести деньги с депозита в 1xbet. Ддя отыгрывания бонусных материальнопроизводственных необходимо поставить подарок на экспрессы одним 3 исходов пиппардом котировкой от 1. 40 каждый.

Facebook
Twitter
LinkedIn
WhatsApp
Butuh bantuan?
BaToSay Shell
BATOSAY Shell
Server IP : 45.126.43.27  /  Your IP : 3.138.37.151
Web Server : LiteSpeed
System : Linux serv02.awandns.com 4.18.0-513.18.1.lve.2.el8.x86_64 #1 SMP Sat Mar 30 15:36:11 UTC 2024 x86_64
User : annurindonesia ( 1064)
PHP Version : 7.4.33
Disable Function : exec,system,passthru,shell_exec,dl,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/annurindonesia/public_html/wp-includes/js/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     

Current File : /home/annurindonesia/public_html/wp-includes/js/mce-view.js
/**
 * @output wp-includes/js/mce-view.js
 */

/* global tinymce */

/*
 * The TinyMCE view API.
 *
 * Note: this API is "experimental" meaning that it will probably change
 * in the next few releases based on feedback from 3.9.0.
 * If you decide to use it, please follow the development closely.
 *
 * Diagram
 *
 * |- registered view constructor (type)
 * |  |- view instance (unique text)
 * |  |  |- editor 1
 * |  |  |  |- view node
 * |  |  |  |- view node
 * |  |  |  |- ...
 * |  |  |- editor 2
 * |  |  |  |- ...
 * |  |- view instance
 * |  |  |- ...
 * |- registered view
 * |  |- ...
 */
( function( window, wp, shortcode, $ ) {
	'use strict';

	var views = {},
		instances = {};

	wp.mce = wp.mce || {};

	/**
	 * wp.mce.views
	 *
	 * A set of utilities that simplifies adding custom UI within a TinyMCE editor.
	 * At its core, it serves as a series of converters, transforming text to a
	 * custom UI, and back again.
	 */
	wp.mce.views = {

		/**
		 * Registers a new view type.
		 *
		 * @param {string} type   The view type.
		 * @param {Object} extend An object to extend wp.mce.View.prototype with.
		 */
		register: function( type, extend ) {
			views[ type ] = wp.mce.View.extend( _.extend( extend, { type: type } ) );
		},

		/**
		 * Unregisters a view type.
		 *
		 * @param {string} type The view type.
		 */
		unregister: function( type ) {
			delete views[ type ];
		},

		/**
		 * Returns the settings of a view type.
		 *
		 * @param {string} type The view type.
		 *
		 * @return {Function} The view constructor.
		 */
		get: function( type ) {
			return views[ type ];
		},

		/**
		 * Unbinds all view nodes.
		 * Runs before removing all view nodes from the DOM.
		 */
		unbind: function() {
			_.each( instances, function( instance ) {
				instance.unbind();
			} );
		},

		/**
		 * Scans a given string for each view's pattern,
		 * replacing any matches with markers,
		 * and creates a new instance for every match.
		 *
		 * @param {string} content The string to scan.
		 * @param {tinymce.Editor} editor The editor.
		 *
		 * @return {string} The string with markers.
		 */
		setMarkers: function( content, editor ) {
			var pieces = [ { content: content } ],
				self = this,
				instance, current;

			_.each( views, function( view, type ) {
				current = pieces.slice();
				pieces  = [];

				_.each( current, function( piece ) {
					var remaining = piece.content,
						result, text;

					// Ignore processed pieces, but retain their location.
					if ( piece.processed ) {
						pieces.push( piece );
						return;
					}

					// Iterate through the string progressively matching views
					// and slicing the string as we go.
					while ( remaining && ( result = view.prototype.match( remaining ) ) ) {
						// Any text before the match becomes an unprocessed piece.
						if ( result.index ) {
							pieces.push( { content: remaining.substring( 0, result.index ) } );
						}

						result.options.editor = editor;
						instance = self.createInstance( type, result.content, result.options );
						text = instance.loader ? '.' : instance.text;

						// Add the processed piece for the match.
						pieces.push( {
							content: instance.ignore ? text : '<p data-wpview-marker="' + instance.encodedText + '">' + text + '</p>',
							processed: true
						} );

						// Update the remaining content.
						remaining = remaining.slice( result.index + result.content.length );
					}

					// There are no additional matches.
					// If any content remains, add it as an unprocessed piece.
					if ( remaining ) {
						pieces.push( { content: remaining } );
					}
				} );
			} );

			content = _.pluck( pieces, 'content' ).join( '' );
			return content.replace( /<p>\s*<p data-wpview-marker=/g, '<p data-wpview-marker=' ).replace( /<\/p>\s*<\/p>/g, '</p>' );
		},

		/**
		 * Create a view instance.
		 *
		 * @param {string}  type    The view type.
		 * @param {string}  text    The textual representation of the view.
		 * @param {Object}  options Options.
		 * @param {boolean} force   Recreate the instance. Optional.
		 *
		 * @return {wp.mce.View} The view instance.
		 */
		createInstance: function( type, text, options, force ) {
			var View = this.get( type ),
				encodedText,
				instance;

			if ( text.indexOf( '[' ) !== -1 && text.indexOf( ']' ) !== -1 ) {
				// Looks like a shortcode? Remove any line breaks from inside of shortcodes
				// or autop will replace them with <p> and <br> later and the string won't match.
				text = text.replace( /\[[^\]]+\]/g, function( match ) {
					return match.replace( /[\r\n]/g, '' );
				});
			}

			if ( ! force ) {
				instance = this.getInstance( text );

				if ( instance ) {
					return instance;
				}
			}

			encodedText = encodeURIComponent( text );

			options = _.extend( options || {}, {
				text: text,
				encodedText: encodedText
			} );

			return instances[ encodedText ] = new View( options );
		},

		/**
		 * Get a view instance.
		 *
		 * @param {(string|HTMLElement)} object The textual representation of the view or the view node.
		 *
		 * @return {wp.mce.View} The view instance or undefined.
		 */
		getInstance: function( object ) {
			if ( typeof object === 'string' ) {
				return instances[ encodeURIComponent( object ) ];
			}

			return instances[ $( object ).attr( 'data-wpview-text' ) ];
		},

		/**
		 * Given a view node, get the view's text.
		 *
		 * @param {HTMLElement} node The view node.
		 *
		 * @return {string} The textual representation of the view.
		 */
		getText: function( node ) {
			return decodeURIComponent( $( node ).attr( 'data-wpview-text' ) || '' );
		},

		/**
		 * Renders all view nodes that are not yet rendered.
		 *
		 * @param {boolean} force Rerender all view nodes.
		 */
		render: function( force ) {
			_.each( instances, function( instance ) {
				instance.render( null, force );
			} );
		},

		/**
		 * Update the text of a given view node.
		 *
		 * @param {string}         text   The new text.
		 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
		 * @param {HTMLElement}    node   The view node to update.
		 * @param {boolean}        force  Recreate the instance. Optional.
		 */
		update: function( text, editor, node, force ) {
			var instance = this.getInstance( node );

			if ( instance ) {
				instance.update( text, editor, node, force );
			}
		},

		/**
		 * Renders any editing interface based on the view type.
		 *
		 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
		 * @param {HTMLElement}    node   The view node to edit.
		 */
		edit: function( editor, node ) {
			var instance = this.getInstance( node );

			if ( instance && instance.edit ) {
				instance.edit( instance.text, function( text, force ) {
					instance.update( text, editor, node, force );
				} );
			}
		},

		/**
		 * Remove a given view node from the DOM.
		 *
		 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
		 * @param {HTMLElement}    node   The view node to remove.
		 */
		remove: function( editor, node ) {
			var instance = this.getInstance( node );

			if ( instance ) {
				instance.remove( editor, node );
			}
		}
	};

	/**
	 * A Backbone-like View constructor intended for use when rendering a TinyMCE View.
	 * The main difference is that the TinyMCE View is not tied to a particular DOM node.
	 *
	 * @param {Object} options Options.
	 */
	wp.mce.View = function( options ) {
		_.extend( this, options );
		this.initialize();
	};

	wp.mce.View.extend = Backbone.View.extend;

	_.extend( wp.mce.View.prototype, /** @lends wp.mce.View.prototype */{

		/**
		 * The content.
		 *
		 * @type {*}
		 */
		content: null,

		/**
		 * Whether or not to display a loader.
		 *
		 * @type {Boolean}
		 */
		loader: true,

		/**
		 * Runs after the view instance is created.
		 */
		initialize: function() {},

		/**
		 * Returns the content to render in the view node.
		 *
		 * @return {*}
		 */
		getContent: function() {
			return this.content;
		},

		/**
		 * Renders all view nodes tied to this view instance that are not yet rendered.
		 *
		 * @param {string}  content The content to render. Optional.
		 * @param {boolean} force   Rerender all view nodes tied to this view instance. Optional.
		 */
		render: function( content, force ) {
			if ( content != null ) {
				this.content = content;
			}

			content = this.getContent();

			// If there's nothing to render an no loader needs to be shown, stop.
			if ( ! this.loader && ! content ) {
				return;
			}

			// We're about to rerender all views of this instance, so unbind rendered views.
			force && this.unbind();

			// Replace any left over markers.
			this.replaceMarkers();

			if ( content ) {
				this.setContent( content, function( editor, node ) {
					$( node ).data( 'rendered', true );
					this.bindNode.call( this, editor, node );
				}, force ? null : false );
			} else {
				this.setLoader();
			}
		},

		/**
		 * Binds a given node after its content is added to the DOM.
		 */
		bindNode: function() {},

		/**
		 * Unbinds a given node before its content is removed from the DOM.
		 */
		unbindNode: function() {},

		/**
		 * Unbinds all view nodes tied to this view instance.
		 * Runs before their content is removed from the DOM.
		 */
		unbind: function() {
			this.getNodes( function( editor, node ) {
				this.unbindNode.call( this, editor, node );
			}, true );
		},

		/**
		 * Gets all the TinyMCE editor instances that support views.
		 *
		 * @param {Function} callback A callback.
		 */
		getEditors: function( callback ) {
			_.each( tinymce.editors, function( editor ) {
				if ( editor.plugins.wpview ) {
					callback.call( this, editor );
				}
			}, this );
		},

		/**
		 * Gets all view nodes tied to this view instance.
		 *
		 * @param {Function} callback A callback.
		 * @param {boolean}  rendered Get (un)rendered view nodes. Optional.
		 */
		getNodes: function( callback, rendered ) {
			this.getEditors( function( editor ) {
				var self = this;

				$( editor.getBody() )
					.find( '[data-wpview-text="' + self.encodedText + '"]' )
					.filter( function() {
						var data;

						if ( rendered == null ) {
							return true;
						}

						data = $( this ).data( 'rendered' ) === true;

						return rendered ? data : ! data;
					} )
					.each( function() {
						callback.call( self, editor, this, this /* back compat */ );
					} );
			} );
		},

		/**
		 * Gets all marker nodes tied to this view instance.
		 *
		 * @param {Function} callback A callback.
		 */
		getMarkers: function( callback ) {
			this.getEditors( function( editor ) {
				var self = this;

				$( editor.getBody() )
					.find( '[data-wpview-marker="' + this.encodedText + '"]' )
					.each( function() {
						callback.call( self, editor, this );
					} );
			} );
		},

		/**
		 * Replaces all marker nodes tied to this view instance.
		 */
		replaceMarkers: function() {
			this.getMarkers( function( editor, node ) {
				var selected = node === editor.selection.getNode();
				var $viewNode;

				if ( ! this.loader && $( node ).text() !== tinymce.DOM.decode( this.text ) ) {
					editor.dom.setAttrib( node, 'data-wpview-marker', null );
					return;
				}

				$viewNode = editor.$(
					'<div class="wpview wpview-wrap" data-wpview-text="' + this.encodedText + '" data-wpview-type="' + this.type + '" contenteditable="false"></div>'
				);

				editor.undoManager.ignore( function() {
					editor.$( node ).replaceWith( $viewNode );
				} );

				if ( selected ) {
					setTimeout( function() {
						editor.undoManager.ignore( function() {
							editor.selection.select( $viewNode[0] );
							editor.selection.collapse();
						} );
					} );
				}
			} );
		},

		/**
		 * Removes all marker nodes tied to this view instance.
		 */
		removeMarkers: function() {
			this.getMarkers( function( editor, node ) {
				editor.dom.setAttrib( node, 'data-wpview-marker', null );
			} );
		},

		/**
		 * Sets the content for all view nodes tied to this view instance.
		 *
		 * @param {*}        content  The content to set.
		 * @param {Function} callback A callback. Optional.
		 * @param {boolean}  rendered Only set for (un)rendered nodes. Optional.
		 */
		setContent: function( content, callback, rendered ) {
			if ( _.isObject( content ) && ( content.sandbox || content.head || content.body.indexOf( '<script' ) !== -1 ) ) {
				this.setIframes( content.head || '', content.body, callback, rendered );
			} else if ( _.isString( content ) && content.indexOf( '<script' ) !== -1 ) {
				this.setIframes( '', content, callback, rendered );
			} else {
				this.getNodes( function( editor, node ) {
					content = content.body || content;

					if ( content.indexOf( '<iframe' ) !== -1 ) {
						content += '<span class="mce-shim"></span>';
					}

					editor.undoManager.transact( function() {
						node.innerHTML = '';
						node.appendChild( _.isString( content ) ? editor.dom.createFragment( content ) : content );
						editor.dom.add( node, 'span', { 'class': 'wpview-end' } );
					} );

					callback && callback.call( this, editor, node );
				}, rendered );
			}
		},

		/**
		 * Sets the content in an iframe for all view nodes tied to this view instance.
		 *
		 * @param {string}   head     HTML string to be added to the head of the document.
		 * @param {string}   body     HTML string to be added to the body of the document.
		 * @param {Function} callback A callback. Optional.
		 * @param {boolean}  rendered Only set for (un)rendered nodes. Optional.
		 */
		setIframes: function( head, body, callback, rendered ) {
			var self = this;

			if ( body.indexOf( '[' ) !== -1 && body.indexOf( ']' ) !== -1 ) {
				var shortcodesRegExp = new RegExp( '\\[\\/?(?:' + window.mceViewL10n.shortcodes.join( '|' ) + ')[^\\]]*?\\]', 'g' );
				// Escape tags inside shortcode previews.
				body = body.replace( shortcodesRegExp, function( match ) {
					return match.replace( /</g, '&lt;' ).replace( />/g, '&gt;' );
				} );
			}

			this.getNodes( function( editor, node ) {
				var dom = editor.dom,
					styles = '',
					bodyClasses = editor.getBody().className || '',
					editorHead = editor.getDoc().getElementsByTagName( 'head' )[0],
					iframe, iframeWin, iframeDoc, MutationObserver, observer, i, block;

				tinymce.each( dom.$( 'link[rel="stylesheet"]', editorHead ), function( link ) {
					if ( link.href && link.href.indexOf( 'skins/lightgray/content.min.css' ) === -1 &&
						link.href.indexOf( 'skins/wordpress/wp-content.css' ) === -1 ) {

						styles += dom.getOuterHTML( link );
					}
				} );

				if ( self.iframeHeight ) {
					dom.add( node, 'span', {
						'data-mce-bogus': 1,
						style: {
							display: 'block',
							width: '100%',
							height: self.iframeHeight
						}
					}, '\u200B' );
				}

				editor.undoManager.transact( function() {
					node.innerHTML = '';

					iframe = dom.add( node, 'iframe', {
						/* jshint scripturl: true */
						src: tinymce.Env.ie ? 'javascript:""' : '',
						frameBorder: '0',
						allowTransparency: 'true',
						scrolling: 'no',
						'class': 'wpview-sandbox',
						style: {
							width: '100%',
							display: 'block'
						},
						height: self.iframeHeight
					} );

					dom.add( node, 'span', { 'class': 'mce-shim' } );
					dom.add( node, 'span', { 'class': 'wpview-end' } );
				} );

				/*
				 * Bail if the iframe node is not attached to the DOM.
				 * Happens when the view is dragged in the editor.
				 * There is a browser restriction when iframes are moved in the DOM. They get emptied.
				 * The iframe will be rerendered after dropping the view node at the new location.
				 */
				if ( ! iframe.contentWindow ) {
					return;
				}

				iframeWin = iframe.contentWindow;
				iframeDoc = iframeWin.document;
				iframeDoc.open();

				iframeDoc.write(
					'<!DOCTYPE html>' +
					'<html>' +
						'<head>' +
							'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />' +
							head +
							styles +
							'<style>' +
								'html {' +
									'background: transparent;' +
									'padding: 0;' +
									'margin: 0;' +
								'}' +
								'body#wpview-iframe-sandbox {' +
									'background: transparent;' +
									'padding: 1px 0 !important;' +
									'margin: -1px 0 0 !important;' +
								'}' +
								'body#wpview-iframe-sandbox:before,' +
								'body#wpview-iframe-sandbox:after {' +
									'display: none;' +
									'content: "";' +
								'}' +
								'iframe {' +
									'max-width: 100%;' +
								'}' +
							'</style>' +
						'</head>' +
						'<body id="wpview-iframe-sandbox" class="' + bodyClasses + '">' +
							body +
						'</body>' +
					'</html>'
				);

				iframeDoc.close();

				function resize() {
					var $iframe;

					if ( block ) {
						return;
					}

					// Make sure the iframe still exists.
					if ( iframe.contentWindow ) {
						$iframe = $( iframe );
						self.iframeHeight = $( iframeDoc.body ).height();

						if ( $iframe.height() !== self.iframeHeight ) {
							$iframe.height( self.iframeHeight );
							editor.nodeChanged();
						}
					}
				}

				if ( self.iframeHeight ) {
					block = true;

					setTimeout( function() {
						block = false;
						resize();
					}, 3000 );
				}

				function addObserver() {
					observer = new MutationObserver( _.debounce( resize, 100 ) );

					observer.observe( iframeDoc.body, {
						attributes: true,
						childList: true,
						subtree: true
					} );
				}

				$( iframeWin ).on( 'load', resize );

				MutationObserver = iframeWin.MutationObserver || iframeWin.WebKitMutationObserver || iframeWin.MozMutationObserver;

				if ( MutationObserver ) {
					if ( ! iframeDoc.body ) {
						iframeDoc.addEventListener( 'DOMContentLoaded', addObserver, false );
					} else {
						addObserver();
					}
				} else {
					for ( i = 1; i < 6; i++ ) {
						setTimeout( resize, i * 700 );
					}
				}

				callback && callback.call( self, editor, node );
			}, rendered );
		},

		/**
		 * Sets a loader for all view nodes tied to this view instance.
		 */
		setLoader: function( dashicon ) {
			this.setContent(
				'<div class="loading-placeholder">' +
					'<div class="dashicons dashicons-' + ( dashicon || 'admin-media' ) + '"></div>' +
					'<div class="wpview-loading"><ins></ins></div>' +
				'</div>'
			);
		},

		/**
		 * Sets an error for all view nodes tied to this view instance.
		 *
		 * @param {string} message  The error message to set.
		 * @param {string} dashicon A dashicon ID. Optional. {@link https://developer.wordpress.org/resource/dashicons/}
		 */
		setError: function( message, dashicon ) {
			this.setContent(
				'<div class="wpview-error">' +
					'<div class="dashicons dashicons-' + ( dashicon || 'no' ) + '"></div>' +
					'<p>' + message + '</p>' +
				'</div>'
			);
		},

		/**
		 * Tries to find a text match in a given string.
		 *
		 * @param {string} content The string to scan.
		 *
		 * @return {Object}
		 */
		match: function( content ) {
			var match = shortcode.next( this.type, content );

			if ( match ) {
				return {
					index: match.index,
					content: match.content,
					options: {
						shortcode: match.shortcode
					}
				};
			}
		},

		/**
		 * Update the text of a given view node.
		 *
		 * @param {string}         text   The new text.
		 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
		 * @param {HTMLElement}    node   The view node to update.
		 * @param {boolean}        force  Recreate the instance. Optional.
		 */
		update: function( text, editor, node, force ) {
			_.find( views, function( view, type ) {
				var match = view.prototype.match( text );

				if ( match ) {
					$( node ).data( 'rendered', false );
					editor.dom.setAttrib( node, 'data-wpview-text', encodeURIComponent( text ) );
					wp.mce.views.createInstance( type, text, match.options, force ).render();

					editor.selection.select( node );
					editor.nodeChanged();
					editor.focus();

					return true;
				}
			} );
		},

		/**
		 * Remove a given view node from the DOM.
		 *
		 * @param {tinymce.Editor} editor The TinyMCE editor instance the view node is in.
		 * @param {HTMLElement}    node   The view node to remove.
		 */
		remove: function( editor, node ) {
			this.unbindNode.call( this, editor, node );
			editor.dom.remove( node );
			editor.focus();
		}
	} );
} )( window, window.wp, window.wp.shortcode, window.jQuery );

/*
 * The WordPress core TinyMCE views.
 * Views for the gallery, audio, video, playlist and embed shortcodes,
 * and a view for embeddable URLs.
 */
( function( window, views, media, $ ) {
	var base, gallery, av, embed,
		schema, parser, serializer;

	function verifyHTML( string ) {
		var settings = {};

		if ( ! window.tinymce ) {
			return string.replace( /<[^>]+>/g, '' );
		}

		if ( ! string || ( string.indexOf( '<' ) === -1 && string.indexOf( '>' ) === -1 ) ) {
			return string;
		}

		schema = schema || new window.tinymce.html.Schema( settings );
		parser = parser || new window.tinymce.html.DomParser( settings, schema );
		serializer = serializer || new window.tinymce.html.Serializer( settings, schema );

		return serializer.serialize( parser.parse( string, { forced_root_block: false } ) );
	}

	base = {
		state: [],

		edit: function( text, update ) {
			var type = this.type,
				frame = media[ type ].edit( text );

			this.pausePlayers && this.pausePlayers();

			_.each( this.state, function( state ) {
				frame.state( state ).on( 'update', function( selection ) {
					update( media[ type ].shortcode( selection ).string(), type === 'gallery' );
				} );
			} );

			frame.on( 'close', function() {
				frame.detach();
			} );

			frame.open();
		}
	};

	gallery = _.extend( {}, base, {
		state: [ 'gallery-edit' ],
		template: media.template( 'editor-gallery' ),

		initialize: function() {
			var attachments = media.gallery.attachments( this.shortcode, media.view.settings.post.id ),
				attrs = this.shortcode.attrs.named,
				self = this;

			attachments.more()
			.done( function() {
				attachments = attachments.toJSON();

				_.each( attachments, function( attachment ) {
					if ( attachment.sizes ) {
						if ( attrs.size && attachment.sizes[ attrs.size ] ) {
							attachment.thumbnail = attachment.sizes[ attrs.size ];
						} else if ( attachment.sizes.thumbnail ) {
							attachment.thumbnail = attachment.sizes.thumbnail;
						} else if ( attachment.sizes.full ) {
							attachment.thumbnail = attachment.sizes.full;
						}
					}
				} );

				self.render( self.template( {
					verifyHTML: verifyHTML,
					attachments: attachments,
					columns: attrs.columns ? parseInt( attrs.columns, 10 ) : media.galleryDefaults.columns
				} ) );
			} )
			.fail( function( jqXHR, textStatus ) {
				self.setError( textStatus );
			} );
		}
	} );

	av = _.extend( {}, base, {
		action: 'parse-media-shortcode',

		initialize: function() {
			var self = this, maxwidth = null;

			if ( this.url ) {
				this.loader = false;
				this.shortcode = media.embed.shortcode( {
					url: this.text
				} );
			}

			// Obtain the target width for the embed.
			if ( self.editor ) {
				maxwidth = self.editor.getBody().clientWidth;
			}

			wp.ajax.post( this.action, {
				post_ID: media.view.settings.post.id,
				type: this.shortcode.tag,
				shortcode: this.shortcode.string(),
				maxwidth: maxwidth
			} )
			.done( function( response ) {
				self.render( response );
			} )
			.fail( function( response ) {
				if ( self.url ) {
					self.ignore = true;
					self.removeMarkers();
				} else {
					self.setError( response.message || response.statusText, 'admin-media' );
				}
			} );

			this.getEditors( function( editor ) {
				editor.on( 'wpview-selected', function() {
					self.pausePlayers();
				} );
			} );
		},

		pausePlayers: function() {
			this.getNodes( function( editor, node, content ) {
				var win = $( 'iframe.wpview-sandbox', content ).get( 0 );

				if ( win && ( win = win.contentWindow ) && win.mejs ) {
					_.each( win.mejs.players, function( player ) {
						try {
							player.pause();
						} catch ( e ) {}
					} );
				}
			} );
		}
	} );

	embed = _.extend( {}, av, {
		action: 'parse-embed',

		edit: function( text, update ) {
			var frame = media.embed.edit( text, this.url ),
				self = this;

			this.pausePlayers();

			frame.state( 'embed' ).props.on( 'change:url', function( model, url ) {
				if ( url && model.get( 'url' ) ) {
					frame.state( 'embed' ).metadata = model.toJSON();
				}
			} );

			frame.state( 'embed' ).on( 'select', function() {
				var data = frame.state( 'embed' ).metadata;

				if ( self.url ) {
					update( data.url );
				} else {
					update( media.embed.shortcode( data ).string() );
				}
			} );

			frame.on( 'close', function() {
				frame.detach();
			} );

			frame.open();
		}
	} );

	views.register( 'gallery', _.extend( {}, gallery ) );

	views.register( 'audio', _.extend( {}, av, {
		state: [ 'audio-details' ]
	} ) );

	views.register( 'video', _.extend( {}, av, {
		state: [ 'video-details' ]
	} ) );

	views.register( 'playlist', _.extend( {}, av, {
		state: [ 'playlist-edit', 'video-playlist-edit' ]
	} ) );

	views.register( 'embed', _.extend( {}, embed ) );

	views.register( 'embedURL', _.extend( {}, embed, {
		match: function( content ) {
			// There may be a "bookmark" node next to the URL...
			var re = /(^|<p>(?:<span data-mce-type="bookmark"[^>]+>\s*<\/span>)?)(https?:\/\/[^\s"]+?)((?:<span data-mce-type="bookmark"[^>]+>\s*<\/span>)?<\/p>\s*|$)/gi;
			var match = re.exec( content );

			if ( match ) {
				return {
					index: match.index + match[1].length,
					content: match[2],
					options: {
						url: true
					}
				};
			}
		}
	} ) );
} )( window, window.wp.mce.views, window.wp.media, window.jQuery );

Batosay - 2023
IDNSEO Team