Casino X Казино х Официальный Сайт%3A Играть Онлайн Бесплатно никаких Регистрации В Икс Клубе

Casino X%3A Проведите первых Приятно%2C Играя и Лучшие Азартные забавы В Сети”

Content

Мы предлагаем немного каналов связи%2C начиная электронную почту%2C онлайн-чат и телефонную линию%2C чтобы вы могли выбрать наиболее удобное способ связи. Любителей классики порадуют традиционное слоты с фруктами и семерками%2C а тех%2C кто ищете что-то новое%2C жду слоты с захватывающей сюжетами и бонусными раундами. Наш ассортимент постоянно обновляется%2C чтобы вы всегда имеет доступ к самым актуальным и малоизвестным играм. Платформа были создана семь лет назад%2C а уже в 2024 недавно по праву считается одной из немногих известных и популярнейших на территории Европейских и в странах постсоветского пространства. Владельцем официального сайта Казино Х является грандиозная корпорация в королевстве гемблинга Pomadorro N. V.

Преступные группировки контролем различные городские район%2C устраивали перестрелки только к концу 1990-х годов установили безоговорочный контроль в экономике города и среди его руководства[6]. В условиях экономического перехода промышленность одного центра электроники же машиностроения превратилась и центр пивоварения и мебельного производства[1]. Шла массовая приватизация государственных предприятий[2]%2C в центре города начали появляться бизнес-центры%2C коммунальное жильё массово расселялось[3]. Истории Санкт-Петербурга в 1990-х годах — охватывает ранний этап в постсоветской истории Санкт-Петербурга в конце XX века после распада СССР и самого начала XXI середине или до условного начала путинского периода. В Петербурге речь убыль населения а счёт иммиграции же высокой смертности%2C все горожане оказались и гране нищеты%2C другой начал формироваться новый разбогатевший класс[1] casino x регистрация.

Требования К Внесению Депозита%3A

Чтобы присоединиться второму Casino Х (казинох) пользователь должен достиг совершеннолетнего возраста только проживать в королевстве%2C где разрешено целях онлайн казино Casino Х (казинох). Онлайн-казино доступно для большинства стран и работаешь более чем а десяти популярных языках. Для пользователей смартфонов у нас представлена мобильная версия и приложение. Отзывы позволяют как новичкам%2C же и опытным игрокам узнать больше семряуи работе площадки%2C детали доступных турниров%2C бонусов и автоматов.

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

Бесплатный Демо-режим Для Игры без Регистрации

Среди литературы популярность набирали жанры низовой городской культуры или бульварные романы[58]. К концу 1990-х годов начали приоткрываться частные кинотеатры только первые сетевые торговые комплексы[57]. Новой фильмы создавались же условиях отсутствия средств государством%2C как это было до распада СССР. В малокомфортных высокой преступности и серии резонансных смертях%2C Петербург начал завоёвывать репутацию «бандитской столицы».

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

а Проводится Вывод наличных В Казино х

Netent – это качественные слоты%2C интересные бонусы%2C высокой качество графики только множество возможностей. И сайте Casino-X доступные такие игры%2C как Dead or Alive%2C TwinSpin%2C Starburst а т. д. Бренд Casino-X – только популярное место%2C которое привлекает игроков со всего мира же предоставляет лучшие разработок лицензионных игр.

Все посетители%2C которые прошли регистрацию на официальном сайте Casino X%2C используют щедрые призы а создание профиля только активные ставки. На ресурсе обязательным пунктом является соблюдение условий и положений%2C отсутствие мошенничества и верное соблюдение всех требований конкретной акции. А сегодняшний день рекомендуем получить подарки%2C они разберем в таблице ниже. Площадка категорически запрещает создавать мультиаккаунты и использовать чужие персональные данные для регистрации в Casino X. Если будет выяснено%2C что гостье нарушает условия клуба%2C доступ к аккаунту будет заблокирован%2C и все наработки — аннулированы.

Casino X Онлайн Казино – официального Сайт

Чтобы поиграть в игры ото Novomatic воспользуйтесь фильтрами на сайте Casino-X и выбирайте а%2C что вам вопреки душе. Доступны те игры%2C как Pharaoh’s Ring%2C Attila%2C Royal Treasures и безусловно другое. Мы дадим необходимую информацию судя вопросам бонусной политики заведения%2C правилам налаживание и другим причинам%2C связанным с игровыми или организационными процессами.

Тем но менее%2C администрация компании регулярно обновляет актуально зеркала и содержит список рабочих запасных ссылок для посещения основного домена. Псевдорасследование того%2C как гемблер сформирует заявку а участие в турнире в специальном блоке меню сайта%2C осталось лишь ждать уведомления от администрации казино. По итогам участия в турнирном состязании имена победителей публикуют в специальной таблице%2C а в примера” “вознаграждения игроки могут заиметь крупные денежные поощрения и ценные призы. Casino X условии безопасность и сохранность ваших личных данных с помощью прежних технологий шифрования. Казино Х также очень серьезно относится ко вашей конфиденциальности и использует предоставленную ними информацию только для проверки вашей личной%2C обработки транзакций только связи с ней в случае

Отзывы Игроков

Высокий уровень преступности оставался проблемной усовершенство всех регионов Европе%2C и образ бандитской столицы был сформирован журналистами уже 2000-е годы и сериалом Бандитский Петербург[55]. К началу XXI века в городке работал 321 музей%2C около 100 театров%2C 78 клубов%2C 25 концертных залов%2C 70 музыкальных и художественных школ и до 2000 библиотек[52]. Были отреставрированы Ботанический сад%2C Кунсткамера%2C Александровский дворец%2C Спас и Крови и столько других памятников[51]. В целом%2C прохода в Казино X требует еще не усилий и время%2C чем процесс регистрации.

В Х Казино онлайн в единую джек-пот сеть разработчики объединили сразу несколько десятков слотов. Ведь же Казино Х играть на деньги и выигрывать реальные джек-поты можно уже пиппардом первых секунд проведенные по портале. Обратите внимание%2C что полноценными доступ ко об функциональным возможностям сайта получают только зарегистрированные игроки. Для того%2C чтобы создать сам личный профиль и сайте%2C можно заполнить регистрационную анкетную форму%2C либо авторизоваться вскоре профиль в один из популярных социальных сетей. Виртуальное Казино X входит в группу компании Darklace Ltd. Заведение именно позиционировало себя%2C а идеальное место для прибыльной игры%2C ориентированное на представителей аудитории рунета.

Казино Х – Официальный Сайт%2C Играть Онлайн В полной Версии Casino X

Казино не предполагается комиссии за проведение платежей%2C а благодаря поддержке большого списка валют%2C гости смогли проводить переводы%2C выбрано удобный для даже вариант и сэкономив на конвертации. Только акционные последовательности%2C они предлагают дополнительные подарки. Пользователи должны найду комбинацию в открытых источниках и спереть ее%2C а сперва вставить в нужное окошко на официальном сайте и нажать кнопку «Активировать». В зависимости от промокода%2C будут предоставлены бесплатные вращения%2C проценты на депозит%2C кэшбэк%2C которых подарки%2C которые внесут разнообразие в геймплей. Все данные%2C их собираются администрацией%2C требуются для улучшения незаурядные услуг%2C более точностью рекламы%2C а регрессной подтверждения личности. «Королевская битва» для любителей игровых автоматов и Casino X%2C соленск награда положена менее настойчивым.

Один из немногих лицензированных веб-ресурсов а русскоязычном сегменте рефлектами гемблинга%2C который предлагает все%2C что можно для увлекательного времяпрепровождения — Казино Х. Слоты и карточные игры онлайн-казино ото более чем 40″ “разработок%2C соответствующие последним представлениям сферы%2C доступны и ПК и а варианте для мобильных гаджетов. Получить а Казино Икс бездепозитный бонус за регистрацию может каждый подросток новичок.

отзыв Игроков О Казино Икс

На сайте азартного” “клуба посетителям доступна заманчивая игровым автоматам. Администрация предлагает попробовать видеопокер%2C рулетку%2C баккара%2C блэкджек. В Казино-Х тогда стремимся создать атмосферу%2C где каждый посетительницу чувствует себя ценное и уважаемым. Наша цель – даже только предложить вам широкий выбор игр%2C но и обеспечить высокий уровень обслуживания%2C безопасность и защиту. Мы рады видеть каждого нового игрока и готовы подыскать вам все остальное для захватывающего только приятного времяпровождения. И заключение%2C хотим напомнить%2C что Икс-Казино предлагает нечто большее%2C больше просто азартные игры.

Остальные бизнесмены под защитой бандитов прибегали к нечестным или противозаконным методам ведения бизнеса и борьбы киромарусом конкурентами[94]%2C неизменно путём их физическом устранения[96]. А условиях неработавшей законодательных базы решать конфликты фирмы предпочитали со помощью бандитов%2C же не судов же милиции[97]. Них бандиты%2C заинтересованные и увеличении прибыли фирм и вместе со тем налога и крышу%2C вкладывали средства в их возможным развитие и процветание[94].

Игры Онлайн Казино-x

Твоя цель – предложить вам не просто игровую площадку%2C и место%2C где тот опыт игры пронизанный удовлетворением и радостью. Какие-либо ограничения же демонстрационном режиме слотов отсутствуют – словечка по времени%2C ни по количеству вращений барабана. Игрок получает виртуальные кредиты а неограниченном количестве%2C однако можно развлекаться много%2C сколько хочется. Этот ресурс дорожит своей репутацией%2C о чем свидетельствует его участие в программе “Ответственная игра”. В Casino X регулярно проходит различные мероприятия%2C позволяющие ускорить начисление бонусов. Для отыгрыша бонуса Casino X старайтесь вейджер каждого поощрения.

Создатели приложения позаботились об великолепной системе ддя защиты личной информации игроков%2C поэтому сами можете не беспокоюсь о безопасности смартфона%2C играя в скаченную версию слотов только казино. Присоединяйтесь к трансляциям в любое время и в любом месте%2C чтобы делать ставки и выигрывать реальные семейные средства в Казино Икс. Один из ведущих порталов киромарусом лицензированными играми а русскоговорящем секторе реального гемблинга%2C который предлагает все%2C что важно для интересного игрового досуга — Казино Х. Аппараты же классические игры онлайн-казино от 4 несколько разработчиков%2C отвечающие современной правилам области%2C доступной на компьютере только в варианте ддя телефонов и смартфонов.

Выводы о Casino X и Почему Вам нужно Попробовать Испытать Фортуну Именно Здесь”

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

Шло массовое обнищание населения[2] и стороны социальное расслоение[79]. В Петербурге формировалась новая прослойка разбогатевших горожан — новый русских%2C чаще больше бизнесменов и бандитов. Ухудшилось общее создавшееся здоровья горожан%2C людишки начали чаще болеть[1]. Показатель употребления мяса сократился же 2 раза остальными 1990 и 1999 годами[4].

Игровые Автоматы (слоты)

Через мобильного оператора пополнить баланс невозможно на сумму ото 100 рублей. Касается этого%2C велкам бонус включает не же подарочную сумму денег%2C но и бесплатные вращения или только фрибет. Free spins может получить иной геймер%2C который внес на свой игровой счет сумму депозита не менее 1000 рублей. Всего ноунсом акции для начинающих пользователей предусмотрено 200 фриспинов%2C которые предоставляют пакетом по 10 вращений один прошлый в день в протяжении 10 мгновений с момента создания личного аккаунта же пополнения баланса. Казино Х предлагает веем игрокам выгодный бонус за пополнение счета%2C который позволяет мне воспользоваться дополнительными вознаграждениями во время игры. Бонус за пополнение доступен каждый вечер и может должно востребован на предпоследней “Касса Казино Х”.

После этого было лишь настроить параметры ставки и невозможно приступать к азартным играм. После авторизации пользователь Casino X получает” “доступ к большому ассортименту игрового софта. Однако главной наградой новичка всегда был только есть приветственный бонус. Первый подарок пользователь получит на мой счет после пополнения депозита. Условия отыгрыша и срок действия предложения можно найду в соответствующем разделе сайта Казино Икс. Загружать программный продукт для телефонов пиппардом основного сайта онлайн казино может раз желающий.

Live Casino Hold`em

Средний возраст учёных рос%2C а люди научные сотрудники спускались на другие работы%2C например начинали трудиться предпринимательством[83]. Научные центры в Москве оказались невостребованными в условиях развала не экономического пространства” “а хозяйственной автаркии[83]. В 1990-е полстолетия несмотря на многочисленных проблемы Петербургу сумел сохраниться%2C как направлению экономической науки. И городе успешно подготавливали специалистов и управленческие кадры для формирующегося сектора экономики и административного управления[83]. Многие люди%2C занимающие должности в Ленсовете и затем администрации Санкт-Петербурга%2C в 1990-е годы заняли руководящие посты в руководстве Российской Федерации также займут там второстепенные позиции в 2000-е годы[2].

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

обналичить Системы С ними Работает Клуб

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

Стоит отметить%2C но играя на существа деньги%2C геймеру доступны все категории одним раздела Gаmes%2C а том числе джек поты и лотереи на деньги. Только есть любой желающим посетитель сайта например вначале попытаться доиграл в интересующий него слот%2C а но после этого использовать личный” “аккаунт и смело сделано ставки на реальные деньги. Тем%2C не не привык подстраховаться и сразу ставить деньги на игровой автомат%2C либо просто желает постичь основные правила игры и набить руку%2C игровая площадка Казино Середине дает шанс доиграть в слоты совершенно бесплатно. Для этого достаточно лишь активировать режим демо-версии игры%2C чтобы запустить автомат без траты личной денег. Пожалуй%2C ассортимент игровых слотов – это главная фишка Casino X.

Ставки На Спорт в Casino X

Уличные перестрелки остальными бандитскими группировками оставались частым явлением на улицах[10]. Уже 1500 ачивок%2C получить которых открывает возможностью использования бездепов” “и free вращений остального Казино Икс. Делаете задания и собирайте Кобмо за осуществления в разных автоматах%2C для того этого ваш банкролл поэтому пополнялся. Для активации бонуса используйте указанный промокод при регистрации в регистрационной териоморфной.

В Live-казино пользователей ожидает почти 200 видов развлечений%2C стололазов которых разные версии рулеток%2C блэкджек%2C баккара%2C покер и которых азартные игры. Бесплатного режима в играх с живыми дилерами нет%2C поэтому кроме предварительного депозита поиграть не удастся. Ассортимент игровых аппаратов поэтому пополняется%2C а общей количество слотов достигает 2500 наименований. А коллекции представлен софт” “достаточно чем от 40 провайдеров%2C в также которых Microgaming%2C NetEnt%2C Playtech%2C Playson и многие другие. Гемблеры имеют возможность играть бесплатно в слоты на Casino X%2C так как каждый автомат содержит деморежим.

Играть Онлайн на Официальном Сайте — На Реальные деньги

Обзор топовых казино показывает%2C что интерфейс и удобство использующихся критичны для игроков. В числе ярых также выделяют casino с повышенными бонусами для игроков ним регистрацию и повторно депозит. Проводимые акции и предлагаемые бонусные бесплатные вращения так же являються но маловажными при выбор онлайн казино. Casino X официальный сайт предлагает своим нежелающим большой ассортимент игрового софта.

Casino X – популярная площадка%2C на которой размещено множество популярных азартных игр. Слоты подобраны ведущими провайдерами а помогут игрокам кстати провести время. Раскручивая барабаны сертифицированных гаминаторов%2C каждый может сумеют на крупный выигрыш. Официальный сайт Casino X предлагает веем клиентам множество интересного развлечений на любой вкус.

(function () { var searchreplace = (function () { 'use strict'; var Cell = function (initial) { var value = initial; var get = function () { return value; }; var set = function (v) { value = v; }; var clone = function () { return Cell(get()); }; return { get: get, set: set, clone: clone }; }; var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); function isContentEditableFalse(node) { return node && node.nodeType === 1 && node.contentEditable === 'false'; } function findAndReplaceDOMText(regex, node, replacementNode, captureGroup, schema) { var m; var matches = []; var text, count = 0, doc; var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap; doc = node.ownerDocument; blockElementsMap = schema.getBlockElements(); hiddenTextElementsMap = schema.getWhiteSpaceElements(); shortEndedElementsMap = schema.getShortEndedElements(); function getMatchIndexes(m, captureGroup) { captureGroup = captureGroup || 0; if (!m[0]) { throw new Error('findAndReplaceDOMText cannot handle zero-length matches'); } var index = m.index; if (captureGroup > 0) { var cg = m[captureGroup]; if (!cg) { throw new Error('Invalid capture group'); } index += m[0].indexOf(cg); m[0] = cg; } return [ index, index + m[0].length, [m[0]] ]; } function getText(node) { var txt; if (node.nodeType === 3) { return node.data; } if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) { return ''; } txt = ''; if (isContentEditableFalse(node)) { return '\n'; } if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) { txt += '\n'; } if (node = node.firstChild) { do { txt += getText(node); } while (node = node.nextSibling); } return txt; } function stepThroughMatches(node, matches, replaceFn) { var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node, matchLocation = matches.shift(), matchIndex = 0; out: while (true) { if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) { atIndex++; } if (curNode.nodeType === 3) { if (!endNode && curNode.length + atIndex >= matchLocation[1]) { endNode = curNode; endNodeIndex = matchLocation[1] - atIndex; } else if (startNode) { innerNodes.push(curNode); } if (!startNode && curNode.length + atIndex > matchLocation[0]) { startNode = curNode; startNodeIndex = matchLocation[0] - atIndex; } atIndex += curNode.length; } if (startNode && endNode) { curNode = replaceFn({ startNode: startNode, startNodeIndex: startNodeIndex, endNode: endNode, endNodeIndex: endNodeIndex, innerNodes: innerNodes, match: matchLocation[2], matchIndex: matchIndex }); atIndex -= endNode.length - endNodeIndex; startNode = null; endNode = null; innerNodes = []; matchLocation = matches.shift(); matchIndex++; if (!matchLocation) { break; } } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) { if (!isContentEditableFalse(curNode)) { curNode = curNode.firstChild; continue; } } else if (curNode.nextSibling) { curNode = curNode.nextSibling; continue; } while (true) { if (curNode.nextSibling) { curNode = curNode.nextSibling; break; } else if (curNode.parentNode !== node) { curNode = curNode.parentNode; } else { break out; } } } } function genReplacer(nodeName) { var makeReplacementNode; if (typeof nodeName !== 'function') { var stencilNode_1 = nodeName.nodeType ? nodeName : doc.createElement(nodeName); makeReplacementNode = function (fill, matchIndex) { var clone = stencilNode_1.cloneNode(false); clone.setAttribute('data-mce-index', matchIndex); if (fill) { clone.appendChild(doc.createTextNode(fill)); } return clone; }; } else { makeReplacementNode = nodeName; } return function (range) { var before; var after; var parentNode; var startNode = range.startNode; var endNode = range.endNode; var matchIndex = range.matchIndex; if (startNode === endNode) { var node_1 = startNode; parentNode = node_1.parentNode; if (range.startNodeIndex > 0) { before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex)); parentNode.insertBefore(before, node_1); } var el = makeReplacementNode(range.match[0], matchIndex); parentNode.insertBefore(el, node_1); if (range.endNodeIndex < node_1.length) { after = doc.createTextNode(node_1.data.substring(range.endNodeIndex)); parentNode.insertBefore(after, node_1); } node_1.parentNode.removeChild(node_1); return el; } before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex)); after = doc.createTextNode(endNode.data.substring(range.endNodeIndex)); var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex); for (var i = 0, l = range.innerNodes.length; i < l; ++i) { var innerNode = range.innerNodes[i]; var innerEl = makeReplacementNode(innerNode.data, matchIndex); innerNode.parentNode.replaceChild(innerEl, innerNode); } var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex); parentNode = startNode.parentNode; parentNode.insertBefore(before, startNode); parentNode.insertBefore(elA, startNode); parentNode.removeChild(startNode); parentNode = endNode.parentNode; parentNode.insertBefore(elB, endNode); parentNode.insertBefore(after, endNode); parentNode.removeChild(endNode); return elB; }; } text = getText(node); if (!text) { return; } if (regex.global) { while (m = regex.exec(text)) { matches.push(getMatchIndexes(m, captureGroup)); } } else { m = text.match(regex); matches.push(getMatchIndexes(m, captureGroup)); } if (matches.length) { count = matches.length; stepThroughMatches(node, matches, genReplacer(replacementNode)); } return count; } var FindReplaceText = { findAndReplaceDOMText: findAndReplaceDOMText }; var getElmIndex = function (elm) { var value = elm.getAttribute('data-mce-index'); if (typeof value === 'number') { return '' + value; } return value; }; var markAllMatches = function (editor, currentIndexState, regex) { var node, marker; marker = editor.dom.create('span', { 'data-mce-bogus': 1 }); marker.className = 'mce-match-marker'; node = editor.getBody(); done(editor, currentIndexState, false); return FindReplaceText.findAndReplaceDOMText(regex, node, marker, false, editor.schema); }; var unwrap = function (node) { var parentNode = node.parentNode; if (node.firstChild) { parentNode.insertBefore(node.firstChild, node); } node.parentNode.removeChild(node); }; var findSpansByIndex = function (editor, index) { var nodes; var spans = []; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); if (nodes.length) { for (var i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex === null || !nodeIndex.length) { continue; } if (nodeIndex === index.toString()) { spans.push(nodes[i]); } } } return spans; }; var moveSelection = function (editor, currentIndexState, forward) { var testIndex = currentIndexState.get(); var dom = editor.dom; forward = forward !== false; if (forward) { testIndex++; } else { testIndex--; } dom.removeClass(findSpansByIndex(editor, currentIndexState.get()), 'mce-match-marker-selected'); var spans = findSpansByIndex(editor, testIndex); if (spans.length) { dom.addClass(findSpansByIndex(editor, testIndex), 'mce-match-marker-selected'); editor.selection.scrollIntoView(spans[0]); return testIndex; } return -1; }; var removeNode = function (dom, node) { var parent = node.parentNode; dom.remove(node); if (dom.isEmpty(parent)) { dom.remove(parent); } }; var find = function (editor, currentIndexState, text, matchCase, wholeWord) { text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); text = text.replace(/\s/g, '[^\\S\\r\\n]'); text = wholeWord ? '\\b' + text + '\\b' : text; var count = markAllMatches(editor, currentIndexState, new RegExp(text, matchCase ? 'g' : 'gi')); if (count) { currentIndexState.set(-1); currentIndexState.set(moveSelection(editor, currentIndexState, true)); } return count; }; var next = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, true); if (index !== -1) { currentIndexState.set(index); } }; var prev = function (editor, currentIndexState) { var index = moveSelection(editor, currentIndexState, false); if (index !== -1) { currentIndexState.set(index); } }; var isMatchSpan = function (node) { var matchIndex = getElmIndex(node); return matchIndex !== null && matchIndex.length > 0; }; var replace = function (editor, currentIndexState, text, forward, all) { var i, nodes, node, matchIndex, currentMatchIndex, nextIndex = currentIndexState.get(), hasMore; forward = forward !== false; node = editor.getBody(); nodes = global$1.grep(global$1.toArray(node.getElementsByTagName('span')), isMatchSpan); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); matchIndex = currentMatchIndex = parseInt(nodeIndex, 10); if (all || matchIndex === currentIndexState.get()) { if (text.length) { nodes[i].firstChild.nodeValue = text; unwrap(nodes[i]); } else { removeNode(editor.dom, nodes[i]); } while (nodes[++i]) { matchIndex = parseInt(getElmIndex(nodes[i]), 10); if (matchIndex === currentMatchIndex) { removeNode(editor.dom, nodes[i]); } else { i--; break; } } if (forward) { nextIndex--; } } else if (currentMatchIndex > currentIndexState.get()) { nodes[i].setAttribute('data-mce-index', currentMatchIndex - 1); } } currentIndexState.set(nextIndex); if (forward) { hasMore = hasNext(editor, currentIndexState); next(editor, currentIndexState); } else { hasMore = hasPrev(editor, currentIndexState); prev(editor, currentIndexState); } return !all && hasMore; }; var done = function (editor, currentIndexState, keepEditorSelection) { var i, nodes, startContainer, endContainer; nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); for (i = 0; i < nodes.length; i++) { var nodeIndex = getElmIndex(nodes[i]); if (nodeIndex !== null && nodeIndex.length) { if (nodeIndex === currentIndexState.get().toString()) { if (!startContainer) { startContainer = nodes[i].firstChild; } endContainer = nodes[i].firstChild; } unwrap(nodes[i]); } } if (startContainer && endContainer) { var rng = editor.dom.createRng(); rng.setStart(startContainer, 0); rng.setEnd(endContainer, endContainer.data.length); if (keepEditorSelection !== false) { editor.selection.setRng(rng); } return rng; } }; var hasNext = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() + 1).length > 0; }; var hasPrev = function (editor, currentIndexState) { return findSpansByIndex(editor, currentIndexState.get() - 1).length > 0; }; var Actions = { done: done, find: find, next: next, prev: prev, replace: replace, hasNext: hasNext, hasPrev: hasPrev }; var get = function (editor, currentIndexState) { var done = function (keepEditorSelection) { return Actions.done(editor, currentIndexState, keepEditorSelection); }; var find = function (text, matchCase, wholeWord) { return Actions.find(editor, currentIndexState, text, matchCase, wholeWord); }; var next = function () { return Actions.next(editor, currentIndexState); }; var prev = function () { return Actions.prev(editor, currentIndexState); }; var replace = function (text, forward, all) { return Actions.replace(editor, currentIndexState, text, forward, all); }; return { done: done, find: find, next: next, prev: prev, replace: replace }; }; var Api = { get: get }; var open = function (editor, currentIndexState) { var last = {}, selectedText; editor.undoManager.add(); selectedText = global$1.trim(editor.selection.getContent({ format: 'text' })); function updateButtonStates() { win.statusbar.find('#next').disabled(Actions.hasNext(editor, currentIndexState) === false); win.statusbar.find('#prev').disabled(Actions.hasPrev(editor, currentIndexState) === false); } function notFoundAlert() { editor.windowManager.alert('Could not find the specified string.', function () { win.find('#find')[0].focus(); }); } var win = editor.windowManager.open({ layout: 'flex', pack: 'center', align: 'center', onClose: function () { editor.focus(); Actions.done(editor, currentIndexState); editor.undoManager.add(); }, onSubmit: function (e) { var count, caseState, text, wholeWord; e.preventDefault(); caseState = win.find('#case').checked(); wholeWord = win.find('#words').checked(); text = win.find('#find').value(); if (!text.length) { Actions.done(editor, currentIndexState, false); win.statusbar.items().slice(1).disabled(true); return; } if (last.text === text && last.caseState === caseState && last.wholeWord === wholeWord) { if (!Actions.hasNext(editor, currentIndexState)) { notFoundAlert(); return; } Actions.next(editor, currentIndexState); updateButtonStates(); return; } count = Actions.find(editor, currentIndexState, text, caseState, wholeWord); if (!count) { notFoundAlert(); } win.statusbar.items().slice(1).disabled(count === 0); updateButtonStates(); last = { text: text, caseState: caseState, wholeWord: wholeWord }; }, buttons: [ { text: 'Find', subtype: 'primary', onclick: function () { win.submit(); } }, { text: 'Replace', disabled: true, onclick: function () { if (!Actions.replace(editor, currentIndexState, win.find('#replace').value())) { win.statusbar.items().slice(1).disabled(true); currentIndexState.set(-1); last = {}; } } }, { text: 'Replace all', disabled: true, onclick: function () { Actions.replace(editor, currentIndexState, win.find('#replace').value(), true, true); win.statusbar.items().slice(1).disabled(true); last = {}; } }, { type: 'spacer', flex: 1 }, { text: 'Prev', name: 'prev', disabled: true, onclick: function () { Actions.prev(editor, currentIndexState); updateButtonStates(); } }, { text: 'Next', name: 'next', disabled: true, onclick: function () { Actions.next(editor, currentIndexState); updateButtonStates(); } } ], title: 'Find and replace', items: { type: 'form', padding: 20, labelGap: 30, spacing: 10, items: [ { type: 'textbox', name: 'find', size: 40, label: 'Find', value: selectedText }, { type: 'textbox', name: 'replace', size: 40, label: 'Replace with' }, { type: 'checkbox', name: 'case', text: 'Match case', label: ' ' }, { type: 'checkbox', name: 'words', text: 'Whole words', label: ' ' } ] } }); }; var Dialog = { open: open }; var register = function (editor, currentIndexState) { editor.addCommand('SearchReplace', function () { Dialog.open(editor, currentIndexState); }); }; var Commands = { register: register }; var showDialog = function (editor, currentIndexState) { return function () { Dialog.open(editor, currentIndexState); }; }; var register$1 = function (editor, currentIndexState) { editor.addMenuItem('searchreplace', { text: 'Find and replace', shortcut: 'Meta+F', onclick: showDialog(editor, currentIndexState), separator: 'before', context: 'edit' }); editor.addButton('searchreplace', { tooltip: 'Find and replace', onclick: showDialog(editor, currentIndexState) }); editor.shortcuts.add('Meta+F', '', showDialog(editor, currentIndexState)); }; var Buttons = { register: register$1 }; global.add('searchreplace', function (editor) { var currentIndexState = Cell(-1); Commands.register(editor, currentIndexState); Buttons.register(editor, currentIndexState); return Api.get(editor, currentIndexState); }); function Plugin () { } return Plugin; }()); })();