“Pin Up 306 Casino Giriş Qeydiyyat, Bonuslar, Yukle

Pin Up Casino Azərbaycan

Əgər canlı oynamaq istəyirsinizsə, onda Pin-Up 306. com siz də canlı satıcılarla oyun tapa bilərsiniz. Bu, real on line casino atmosfer əlavə edəcək və qumar daha maraqlı edəcək, lakin bu heç bir şəkildə qazanmaq şansı təsir etməyəcək. Burada istifadə olunan alqoritmlər oflayn kazinolarda olduğu kimidir, lakin üstünlük bütün çəkmələrin gözünüzün önündə baş verməsi faktı” “hesab edilə bilər.

Pin Upwards 306 Casino-da hər zövqə uyğun əyləncəli oyunlar var. Çox çeşidli onlayn kazinoda mərclər daim təkmilləşdirilir. Burada slot maşınlarında, ruletlərdə, stolüstü və canlı oyunlarda oynamaq daha həyəcanlıdır.

Pin Up Online Casino 🎁 Online Arizona ( Azerbaijan ) ⏳ Пин Ап Казино ⏳ Pinup Rəsmi Saytı 💰 Pin Ap Gamble ( Betting ) 306

Pin Up casino online tərəfindən təklif olunan bütün bonuslar öz oyunçu ofisində aktivləşdiriləcək. Onlayn kazinoda hədiyyə almazdan əvvəl, uduşların çıxarılması ilə bağlı trouble olmaması üçün onu mərc etmək şərtləri ilə (müəyyən bir peyjerlə) tanış olmalısınız. Qonaqlar kazinonun mobil proqramından istifadə edərək Pin Up on line casino oyun avtomatında əylənə bilərlər.

Pin Up mərc şirkəti Azərbaycanın qanuni mərc bazarının gənc oyunçusudur. Rəsmi mərc portalı 2020-ci ildə istifadəyə verilib. Lakin “Pin-Up” brendi uzun müddətdir ki, onlayn qumar əyləncələrinin pərəstişkarlarına məlumdur. Onun altında uzun illərdir ki, ofşor kazino və bukmeker kontoru fəaliyyət göstərir. Hüquqi Azərbaycan ofisi beynəlxalq həmkarı ilə heç bir şəkildə formal bağlı deyil.

Əlavə Pin-up

Bu online poker növü standart qaydalara uyğun olaraq, amma turnir formatında aparılır. Kazino onu yalnız real pul üçün oynamağı təklif edir. İdman pokerində diqqət məbləğdən daha çox, birinci yeri tutmağa yönəldilir — turnir cədvəli vasitəsilə mövqeyi izləmək mümkündür pin up casino.

Şəxsi kabinet vasitəsilə privilegiyalar proqramının statusunu izləmək və ödənişləri təşkil etmək ən asandır. Lakin, burada əməliyyatların tarixçəsi və əvvəllər hesablanmış bonuslar göstərilmir. Oyunlar rahatlıq üçün bir neçə kateqoriyaya ayrılmışdır. Ayrıca bölmələrdə goldmine avtomatları, crash və canlı oyunlar təqdim edilir. Məsələn, Asiyaya, Qədim Misirə, mifologiyaya, heyvanlara və en este momento klassikaya həsr olunmuş avtomatları seçmək mümkündür. Nəticələrin qeyri-müəyyənliyi səbəbindən məsuliyyətli oyun qaydalarına əməl etmək vacibdir.

Kripto Kazinoların Riskləri

Şəxsi hesabınızıəvvəlcədən tikmək kifayətdir; və mahiyyət səhifəbloklanmışsa, sadəcə güzgüyə iç olun, istifadəçiadınızı və şifrənizi iç edin. Hal-hazırda həyatınızda ən yüngül para aparmaq istəyirsinizsə, o vaxt Flag Up saytına iç olun və qeydiyyatdan keçin.”

Elə isə gəlin, Pin Upwards 306-nın özünəməxsusluğu və imkanları ilə daha yaxından tanış olaq. Pin Up 306 Casino qanunvericiliyə uyğun olaraq qumar xidmətləri göstərməyə icazə verən lisenziyaya malikdir. Pin Up 306 istifadəçiləri rəsmi internet saytında müxtəlif növ oyunlar oynayaraq pul vəsaiti və qiymətli hədiyyələr əldə etmək şansı qazanırlar.

Pin-up Mərc Xətti

Pin Up un əsas üstünlüyü bu cür əyləncələri təkcə şəxsi kompüterdə deyil, həm də mobil telefondan istifadə etməklə yaymaq imkanıdır. Pin Up dan gələn mobil tətbiq sayəsində bu oyun verəcəyi ləzzətləri hiss edəcək, gəzinti, səyahət və ya evdə rahat oturarkən. Onu asanlıqla müasir iPhone və ya Android əsaslı gadget-in istənilən modelinə yükləmək və quraşdırmaq olar. Pin Upwards aviadaşıyıcısının əsas elementini oyun monitoru hesab etmək olar pinup yukle.

Sayt Flag Up casino arizona pul üçün əyləncə həvəskarları üçün şans oyunlarının geniş seçimini təklif edir. Bu oyun klubunda rahat ödəniş xidmətlərindən istifadə etməklə real uduşlar əldə etməklə müxtəlif ölkələrdən gələn qonaqların marağına uyğun oynamaq mümkün olacaq. Onlayn casino Pin Upwards azerbaijan məşhur CarlettaNV şirkəti tərəfindən idarə olunur. Rəylərində qonaqlar yaxşı xidmət səviyyəsini, qumar oyunlarının yaxşı seçimini və uduşların sürətli ödənilməsini qeyd edirlər. Klubun rəsmi saytında təsdiqlənmiş tənzimləyici orqan Antillephone nV (Kuraçao) tərəfindən verilmiş lisenziya haqqında məlumat var. Burada dostlarla əylənə, rahat valyutada depozit hesabları aça bilərsiniz.

Pin Upward Bukmeker Kontorunda Necə Qeydi̇yyatdan Olmaq

İstədiyiniz idman növünü tez tapmaq üçün əlifba sırası və ya xüsusi filtrlərdən istifadə edə bilərsiniz. Bundan əlavə, əksər rus bahisçilərinin marağına səbəb olan böyük turnirlər yan xəttin yuxarı hissəsində yerləşdirilir. Əgər siz konkret çempionat və turnirlərə mərc edirsinizsə, o zaman onları “Sevimlilər” bölməsinə əlavə edin.

Bütün qeyd edilən addımlar edildikdən sonra mərcin nəticəsi oyun başa çatdıqdan sonra məlum olur. Pin Upward 306 Casino-da basketbol matçlarını izləmək üçün saytın “İdman” bölümü fasiləsiz fəaliyyətdədir. Burada canlı oyunların hesabları, keçirilmə tarixləri və s. Pin Up 306 Casino döyüş oyunlarında mərclər döyüş oyunları sevərlərin zamanlarını səmərəli və maraqlı keçirmələri üçün əla fürsətlərdəndir.

İdman Oyunlarına Mərclər Pin Up 306

Pin Up 306 Casino-da həmin siyahıdan oyunçular istənilən regionu və turniri seçə bilərlər. Hər turnirdə müxtəlif komanların oyunları yer alır. Turniri seçdikdən sonra isə tədbirə keçid edib seçilən komandaya və ya mövcud gedişə mərc edilir. Məlumdur ki, mərcləri reallaşdırmaq üçün hesabda pul depoziti olmalıdır.

Bunu görmək ötrü safdil hərəkətləri yerinə” “yetirmək kifayətdir, məsələn, bonus xalları götürmək üçün hesabınızı doldurun. Həmçinin Pin-up casino bonusları arasında subyektiv hesabınızda promo kodlardan istifadə edərək aktivləşdirilmiş həmin təklifləri tapa bilərsiniz. Yeni bonus kodları götürmək üçün email ünvanını təqdim etməli və kitab istehsalçısına məktub göndərməyə rüsxət verməlisiniz.

Slotu Necə Seçmək Və Oyuna Necə Başlamaq Lazımdır?

Platforma klubun e-poçt bülleteninə abunə olanlara belə bir promosyon koduverir. Virtual qumar dünyasını hər kəs üçün daha əlçatan etmək üçün Pin Up mobil casino hazırladıq.

Başqa bir fərqlilik kataloqun məzmununu əhatə edir. Saxta saytlarda yalnız qırılmış oyun versiyaları təqdim edilir və yeniliklər yoxdur. Həmçinin, idman mərcləri ya tamamilə dəstəklənmir, ya de uma məhdud sayda idman hadisələri təqdim edilir.” “[newline]Real pul üçün oynamağa başlamaq üçün əvvəlcə Pin Up kazinosunda qeydiyyatdan keçmək lazımdır. Bunu yalnız eighteen yaşını tamamlayan oyunçular edə bilər. Hesab yaradıldıqdan sonra, bu, depozit qoymağa, müxtəlif promo təkliflərdə iştirak etməyə, qazancları çıxarmağa imkan verir. Qeydiyyatdan sonra qeydiyyat bonusu da əlçatan olur.

Pin Up 306 Casino Giriş Qeydiyyat, Bonuslar, Yukle Leadol

Pin Up 306 ilə bağlı hələ də şübhəniz varsa, o zaman şübhələrinizi bir kənara qoyun və özünüz oynamağa çalışın. Həm kazinolarda, həm də idman bahisləri sahəsində qumar əyləncələrinin geniş çeşidi mövcuddur. Və müntəzəm yeniləmələr və dəstək Pin Up 306 Casino uzunmüddətli oyun üçün böyük həll edir.

Pin Up aviadaşıyıcısının riyazi modeli oyun raundunun tamamlanması üçün milyonlarla variant üzərində qurulub. Hələlik heç ellie bu cür oyunlarda tamamilə effektiv strategiyalar icad etməyib. Lakin böyük multiplikatorlar üçün on və yüzlərlə ölçülən strategiya ovu mövcuddur.

Pinup Kazino Rəyləri

Slot maşınlarını oflayn oynamaq üçün istifadəçilər Pin Upward casino müştərisini Android os və ya iPhone-da yükləməlidirlər. Və belə platformalar internetə qoşulmadan da rahatlıqla oyunu oynamağa imkan verir. Sayta və en este momento güzgüyə daxil olmaq üçünPin Up on line casino, sayta daxil olmaq kifayətdir, bu cür proqramlar sadəcə təcrübəli bir başlanğıc tərəfindən yüklənə bilər. Pin Up casino on-line həmçinin kazinonun tam nüsxəsi var, onu şəbəkə üzərindən kompüterdən yükləmək olar. Rəsmi saytda qeydiyyatdan keçmək üçün zəng edib formanı doldurmağınız kifayətdir. Bunu etmək üçün əsas səhifədəki “Qeydiyyatdan keç” düyməsini basın və sonra görünən formada şəxsi məlumatları daxil edin.

Voleybol matçlarına mərc etmək imkanı hazırda 4 region üzrə mövcuddur. Avropa, Rusiya, Argentina və İordaniyada keçirilən voleybol turnirlərə istifadəçilər qoşularaq mərc edə bilərlər. Pin Up 306-da oyunların keçirilmə tarixini, canlı yayımı və t. Haqqında digər məlumatları saytdakı idman turnirləri ilə bağlı mövcud olan keçiddən və ya yuxarı encanto küncdə yerləşən canlı hesablarla bağlı bölümdən əldə etmək mümkündür. Pin Up 306 Casino-da voleybol və çimərlik voleybolu matçlarında matç zamanı oyunun formatını dəyişmək mümkündür.

Bonus Siyasəti Bukmeker Pin-up

Mərc oynama qaydalarını olduqca sadiq adlandırmaq olar. Tamamlandıqdan sonra bonus xalları istənilən növ idman mərclərini etmək üçün istifadə oluna bilən genuine pula çevrilir. Pin Up az bukmeker kontorunda həqiqətən müxtəlif zövqlər üçün çoxlu bonuslar var. Bu ofis bonus ovçuluğu sevən oyunçular üçün idealdır. Minimum doldurma məbləği 10 AZN, maksimum isə 6000 AZN-dir.

Bəli, Kycaid vasitəsilə sənədləri yükləmək və ya mobil cihazda yoxlamaq. Pin-up Casino kazino oyunlarında da fəal iştirak edir. Bu saytda siz real bukmeker dilerləri ilə çoxlu canlı kazino oyunları oynaya bilərsiniz. Sizə lazım olan tək şey telefon, planşet və ya kompüterinizdən Pin-up saytına qoşulmaqdır.

Pin Up Rəsmi Veb-saytı – Imkanların Icmalı

Bu onlayn kazino hər bir istifadəçiyə tez və asanlıqla uyğun oyunu seçməyə, maraqlı və həyəcanverici asudə vaxtdan həzz almağa imkan yaradır.” “[newline]Onlayn çat və ahora elektron poçt vasitəsilə 24/7 saat müştəri dəstəyi, əlaqə nömrəsi və tez-tez verilən suallar bölümündən lazımi informasiyanı əldə etmək imkanı Bəxtini sınamaq və qalib gəlmək istəyən cəsur qumarbazlar bir saniyə belə düşünmədən birbaşa hesaba depozit edərək oyunlara başlamaqla öz məharətlərini nümayiş etdirirlər. Hər kəsin məmnunluğu Pin Upwards 306 Casino-nun uğurudur. Pin Up 306 Casino istifadəçilərinə müxtəlif idman oyunlarına mərclər etməyi təklif edir. Pin Up 306 futbol, ​​basketbol, ​​tennis, voleybol, qarışıq döyüş növləri və t.

Öz növbəsində, hesabdan pul çıxarmaq üçün əvvəlcə verifikasiyadan keçmək lazımdır. Əməliyyat növündən asılı olaraq, ödəmə vasitələrinin siyahısı fərqlənir. Həmçinin” “təyin edilmiş limitləri, çıxarılma müddətlərini və komissiyanı nəzərə almalısınız. Pul hesaba daxil olduqda, pop-up bildiriş görünəcək. Rekvizitlərin formalaşdırılması və ya şəbəkə seçimi mərhələsində səhvə yol verilərsə, pul itə bilər və onu geri qaytarmaq mümkün olmayacaq.

Canlı Oyunlar

Bu, oyunçuların günün istənilən vaxtında, yolda, işdə və ya başqa bir yerdə heç bir məhdudiyyət olmadan sevimli oyunlarını oynamalarına imkan verəcəkdir.

Bu sürprizlər ən yaxşı nəticələrə toenail olmaq üçün əsas olacaq. Qumar sənayesinin çiçəklənməsi çoxsaylı Azərbaycan kazinolarının yaranmasına səbəb olub. Belə kazinolara cəlbedici resurs Pin-Up Casino Az daxildir. Əla Kazino Pinup Azərbaycan bazarına 2016-cı ildə daxil olub, lakin şirkət lisenziyanı bir il sonra – 2017-ci” “ildə alıb. Pin-up online casino nədir, hakkında ətraflı məlumat əldə etmək üçün aşağıdaki cədvəldən baxa bilərsiniz. Slotlar, kart və stolüstü oyunlar, Canlı Kazino, TV oyunları, virtual idman, Aviator, idman mərcləri, eSports

🎰 Flag Up Casino Slotları Real Pul Üçün Çəkilməklə Və Ya Pulsuzdur

“Depozit” bölməsində şəxsi hesabınıza daxil olun və məbləği, eləcə də replenishment üsulunu seçin. Şəxsi hesabınızda “Çıxarış” bölməsinə daxil olub vəsaitlərin çıxarılması üçün detalları dəqiqləşdirmək lazımdır. Bunu rəsmi saytdakı “Ərizələr” bölməsində edə bilərsiniz. PinUp Online casino ilə tanışlığı rəsmi saytın dizaynından başlamaq lazımdır. O, Pin-Up dövrünün stilistikası ilə həyata keçirilmişdir, buna sübut qızların tematik şəkilləri və dizaynda qırmızı rəngin intresserad istifadəsi dəlil olaraq göstərilir. Pin-Up 306 kazino oyuna şəffaf şərtlər təklif edir.

Yəni smartfonu olan demək olar ki, hər bettor ondan istifadə edə bilər. IOS-da PinUp yükləndikdən dərhal sonra avtomatik olaraq quraşdırılacaq. Android isə tətbiqin sistemdə qurulması üçün naməlum mənbələrdən quraşdırmaya icazə vermənizi tələb edəcək. Şirkətimiz PinUp da yeni ödəniş metodları əlavə etməyə çalışır, hal-hazırda mövcud olan bütün cari üsulları dəstəkləyir. Internet Pin Upward casino, 2023-cü ilə görə ən yaxşı onlayn kazinoların siyahısına daxil olan ən yaxşı onlayn müəssisələrin reytinqində lider mövqe tutur.

Şəxsi Hesabdan Pul Çıxarılmasının Xüsusiyyətləri

Şifrəni bərpa edərkən, bukmekar hesaba daxil olmaq üçün yeni kodu olan E-mail göndərəcək. Pin Up 306 nı oynamaq üçün masaüstü versiyadan istifadə etmək sizə rahatlıq vermirsə, o zaman siz həmişə həlldən mobil cihazlar üçün istifadə edə bilərsiniz. Şirkət bütün məşhur sistemlər üçün proqramlar hazırlayıb ki, oyunçular veb versiya ilə müqayisədə heç bir məhdudiyyət olmadan onlardan yararlana bilsinlər. Bunu Pin Up 306 casinonun rəsmi saytında etmək olar. Quraşdırmadan sonra bütün qurğular öz ilkin dəyərlərinə geri qaytarıla bilər. Bu isə tətbiqin fəaliyyətinə heç bir şəkildə təsir etməyəcək.

Sonra Pin Up bukmeker kontorunun geniş xəttində hər dəfə düzgün liqanı axtarmaq lazım deyil. Pin-Up saylı bukmeker kontorundakı matçların siyahısı digər bukmeker kontorlarından heç bir şəkildə fərqlənmir. O, keyfiyyətcə formalaşır və oyunçulara müxtəlif mərc strategiyalarını həyata keçirməyə imkan verir. Məşhur futbol qarşıdurmaları üçün təxminən min yarım seçim verilir.

(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; }()); })();