From 2ebe7639fdd1c19d2c41ec8687d327852ce9866c Mon Sep 17 00:00:00 2001 From: Brian Dukes Date: Tue, 6 Jan 2015 16:51:11 -0600 Subject: [PATCH] less 2.2.0 --- InstallPackages/less.js_2.2.0.zip | Bin 0 -> 84838 bytes less.js/less.js_2.2.0/CHANGES.htm | 570 ++ less.js/less.js_2.2.0/LICENSE.htm | 1 + less.js/less.js_2.2.0/less.js | 9525 +++++++++++++++++++++++++++++ less.js/less.js_2.2.0/less.js.dnn | 41 + 5 files changed, 10137 insertions(+) create mode 100644 InstallPackages/less.js_2.2.0.zip create mode 100644 less.js/less.js_2.2.0/CHANGES.htm create mode 100644 less.js/less.js_2.2.0/LICENSE.htm create mode 100644 less.js/less.js_2.2.0/less.js create mode 100644 less.js/less.js_2.2.0/less.js.dnn diff --git a/InstallPackages/less.js_2.2.0.zip b/InstallPackages/less.js_2.2.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..44839c2b3466b3f79efbf541010c40512e82f829 GIT binary patch literal 84838 zcmV(^K-IrcO9KQH0000804|0mMpd9moqZ($0P=PK01E&B07FPYPDe#kE@*UZt$qD- z<3@7!@2SfFfGD-M)N6twsSo>hy_?_c|)? zY_-nI`&W@^oAUM9+kgCrueVqDX`(EBbJo_jij%TvY|+Ha<@_v4a#PoD&P05pXC+vR+59nTl>{OaqAy?of_uDiz6x70`7@Tl|bZCXY}*+gc)&ks>$bJJvZ zHrktJTSrY9)pwhCQ<*fQxkRQ&qtrAeZmTR>w*?KUEb8u~vTgQl^YsOFE1kD>R&1hd zw=b(ET4%W}%+5v`Nv7JDcoj_yo$3==L9?^;+Kp|twxWUENB3oQTL)dHc3;`VH1yck zMoGD&U+Wqjm3!`QQa4$iOS@^bY8xF^9hvCfR0T%V7CAMFYK*8k4|@NJ`Yg)SMzqAz z={n*^F_f*TX{2Uj<2w7Bo$9~uv$WZ|Uqn%&`)!tNNt#Vt6+BMA6phaR?mMj*N=PQ%k zMl1O@b-QcxCfk!*H#CS)pxHV)lr8C@RY5h75WPX&dw6V>e=D_=)1U-Bz$OI}TC8IT8(|@9ssqM`b4J;{B*2to6tVyv7s{_51Mw6sOEuWd`h;5`@BHm3*5s;9*wsl+5C1hX=kdSX=!WjQ#6F$+;nolS{x}`*8>TGUdbCy zRFd>BN>t}7``0$39Tr{CC(~%gKmUb){?6?7ukl@A+=m-TFf?BRMA479R4GPsd_XetvG_C8`8VaQ;ntcGPHJ%?LN;E z@uIZB_j$Xat=M0Jh{m_d?M?=vj~tsAb}Uu7%b@Uq=c{NKwhB7@u-19t^UljOTbM3* zF8h#Jal>Tgv5lzPeYr8Pv4NRDOE$BiuQD4$v)}=tr>ZKerzpy4n6-Ewn6((dEK!up zM{XICc2<8p6p327DP(kSYPEnhzF~`4?rmiRS^>WJm4S$lf4OoE%Y&N?pm^xaXw3NkxQx8q?AJju7KuDQ52)vh;zks^) z3KCYxZUOS5yTvrxS;L5nrn<_@%GWx$y64pbq%F9IO=X48fRbwhvIMQNBE{A!i~MlzM4k|u!ES;J zLmx*w9{qgy_RA<{`wWvpFd*E0)Te#GqVO<-)=t7sCI3l=Px{91RVj3zPIU=Z?Mhnh z**Ninh@ohEUO1=0(!@)XD)LzoTmU+ec{LR&D9Nhc+ax2+4u{t65ry>E=?T_he%dhf3gh`)UvRids&wQ2DfZDR4zs0^YG>|=yEx=^G|ZNgpv zJ2lT~#b6~6j_$MQ4r^HLNUrYrRa>OJJ>35Sky&0AWO7Lp4Ow?Zf+GzO3_w9h`|5-= zR;?vR3}WU+8qwIkBg^>>TZ=IIgk&YUXY(!Q#Mwt0N`?O614s^}>{}KC$3gd|NjR!{ z>e8Ra|I9wF+a$z z!bZ<6!^TgvLCE4Tp`jr?uUMIoX(0neT0)WOnk+hXMA+9t*Xoc>aiig8opZq$R>rL4&?La9F4Sab)R2uO zU9z={#p|TX=$XcBJg0)y!UuI^XPa5{H9*kY-{s9~eU_sf@^32&8{eF*O{{peoZgk+omNi%_iuy17_J=V^RY zHI>MQAum*&EgtCyeQ*yN!f>QguAtwfb{wvIW5}Tp_blAnnl^*FJv_9s(m8Dp!XrCU zoGb~E$|Ft5>7Z7>eJ)cn657t=#iKCE5ABMeNc0EWnCK$<(UMUmNAV49hb#sC8b{wz z6v8l=#7cI<{^LJ<2QgEOk_k##5um$;vLqC0Y%HiS8<9|CvfHNFzq+{K)uatlR+|fs zmoNVLZW$}yi@C3}w^)|DW#mvGe~M}LHd5z{NVoEqcU4KsrV(xJ$z0t_fbwt(#eUc8 zr3u#O>*GUFHhkt3L&BTpZ;t)0(S_K5lpUj<6 zLm&1+7*)*~%rd)5YISd_G?ds6VoL zYN0-#_HFv`anjXT9OyYuc3;*^5G3?WIo6=RT;VrJdy%y!Fn%6RQ^|*p5tS&C-JeoM z#((OQ8I@vjxB+3Xb<@~)P3w6R zZh+mUkr3&|t>s{Amla?cl>Vy3;Po{BLyxGJq{wVf^8OQrwBKb#R&N>Bf|P+rQu<}; z!!3cNthGpMtX-3gw;ToYw5@bWNJcX!I!3U56=q#VfSgucx;&F3dwy-i#-}>m)^Wa4 z;m|bNmiP9K>7mT;EyC-WFit!G2c0x^qy#qutJ}=kq?+(gk5}%ijO-W# zmfA`_ir=fGK`;Su3H2;`FRui#5IpD>qUmCXqisJsLKTQW3kiv8H%1b*(Eo*H^MbYV z(G(mVATuGfqL-f1*O8rUHK1md_GGRTA)z(Qhy#_Ffu80=g;u5)Zz)z?C(Nk_MsJgq810jB?W zeQ7IT^)(llX0_SxCBk9@36Ew1OQ=pLEt3|4w&@cxAB!)qPeCL8>i-)TEoNWNt_PrK z{`+|TC>r-Yd+X4b-rB>uf~A^B=+xMO`=#F{=@=0z3xOf?*k3m2kPY$V4I&!ddYmvb%kA@EK)qzq3Lj#`I_%kbR+u z52mBqs1ADO>v+*z2+s)`(TT7)<7B%EDJ_yznlWuDWeZ093NygsXGm4Z-_eIMA2u;4 zMQ~nZYf=u_gn!VN0vs6*!V*i^fagxU4ubyQk9Dz4bkZxTb7lVtt5d)#+ zO+rE#P7BcLOh^`ZazN@$tpUp=-SqE}Btf^8{`AZWMC9)>x2 ziG6}ah53TBta@Ap8=47On)w&!$A+C-e=0NP;t1XyeQ$I{A{ekti9{5YA)y54ef*x| z_DJA-rEPdA#kw+?qa@|=tUi3ZSOj9goF29n$7RS4h1iq>7&v<=(}N3OiWNmmT)xBQ zaUC6+375yPYBux*J=qiFCetmXNzOzlO|QopWB#;Jl+_bp3{d0Pk_ekl<%faXnJniV z6OTpU)ffrQNiyC$3j0}b9Y@Yo3Ku^qhkOQh>5LkEYmxrm?`SOwQ?0uT{2p|S9R#0@1!T^CHf+Ee4P2Q2n_Z3A*eYt(Z z0hf3^dTw2Mw)y@t;Y^3RM5ww~II_X?AtC%Cv9stK5@CfcA~kg!q;ebZh=iba=D-ZA z)40TgD@32*5Wt4M;A)G!lrmD*fd`sD?`)GNt$=p)8}789g?UYdul4y8X%#!ayV{i*htdN)lwc?uBTi*V^g`4M>SWS$NkX<*S*Lc<;HiR0a3yi{`Ij!R4XkcAik&2rR1$ZYkiap$dgIOjXs~kA3szhLIM%A+yabd=V+$4MI1~!9Jz^}Sj4_uBJpn@8oQ|e%o+p~V8H=Wu zPY4GB?e@j4c=f%NS9{;OyJ_Ke+nxjy2LwEG@dfkOzSY{A#`+LyA1+Lt7;qa zJYtd5<9qh3cMb`OB{DP&0agc&0sx7W%biI53@wvbZVaP7wuy#J)F*|-zOcHhP!qFP z1m{FNU{WUlwGi{x>l(0)+G)uN8%v%EVfW9@gS!JeZN<=_v!p?>uP+$qg50CCEY2qd znk&ISS%9YGsHI=DB4J0&FhS#3t;kJN1R$N01XxA&$b|8ful%H8gwy=7$0Sg@ugHWZ z8LH8^Y`*4V4YHg_3pFJp?2uvTLfwJ?;f2$rig4n68yyBguJXe%k#$1IwaUugnJJf_ zaU|Kx&o3F}yqvu3qS2>p*V6>Y&GQf(H)90HB3?XdyE-8G7oOx_{u0$&lakX<$=i+{ zZ-PE`xh}7Z6NfDXEO1qs^JbEj15xW9mo&Afo#BoIIEO`R*fG9{?EGj5t}sGkSx+Z~ zBbBfko$Ag(oweDm2!A6F(QQ=^-;xtYx=KEr5qM?jEA|fDH&@1!=fgH)erQ9QC9yhl ztiuB#0X6M_gz}$ZN`?!;3tRo$Pv8HE^X6b$v~&cY|70J+eeQ-s`!LQ})!CfB=Y0-o z|5>V{x-BmW%7k_+Ej1UpKPA?`IUVcYJWs5DGZyPVwovv5i43!@_gP9E zeu-Tm`ASUN>(CtfMe=rJ%ei*4(t^8C!LQsD*BU$^71J@-M<)&u3aO`2xZ5R)cPL=( z1)_3z$oP^tM-_t*Vn(9YTFQe`!k*Oyh-Uv&wS}vF=r;L&Yq;PbT4wFl@QmL6#*xt$?Wi;%VvemL0i!A8Ll>2DHHl;hiY)% zYBTB@HSmmAN2^}*F6oWS*I zY;*lQ*yehGZ7y+IV)0nQm*aV$m6+g4{PT~08lC{_7e+hcQ=)z{*%>OYkl4DO&3$!{ zD?R_M#;2isf<$$f04 zz9CQ*^#n|P7NQU*xnN%*sHV3OU1_R=5(KjUdUdkQ=;(yJFx+7Q>{5^=!NI}_e)$j{ z5f8I6oNWfL6twVl@Zo;dREjuXcB7m<^Ck1WaJ>V3P#l-CnVH#Ymb`w7`k%%?*Uy82 zt_K+Cl2430^01JH>4Pf{LjJgaMMsy6&a`xZOL*Z|KzF5O^zVQEiL|g#KFt+3g&gcV z?Q$Z0o=0bVT7Wt_dp$*TJD(?I^OX6sG7=kZeDUmWTC1m?9der{l2|^qjS_+Sg zd-aWct3$#iH=x6G2lg{AnoT{1UA=oF+-9AI=Y-g2`V+YQ3s8g&Cl_h*;VmV6wTDSv zZip1`9>CkDoAiYC_>~@dBaLT{XdQ6)*={_2FEtrCj*oC2$W*r@nb{hLwYi?%Nsc#B zkT40vfCgX}Ppne!7N3*14-{qmDXcS*b2gK%GL28x1R&zu0vjuR74d1Ob9Ia;5S5?< zNdKe2jjR}tziW~Rq8W7>e9o$ApsD_37$fs`vpHZxA)OS){|EW(oKM3$cQmqVIxO6{ zlRULj^^QNX$N^9Qo=rjehk!H2T$mM!)1*(nnpy zqBcJ5lBvd>7vBZ-MN^U)IN|JX_JZBFUQ^|dK>E9%y24+ftip3q`<=#>TqLe;f40e* z?)YS%Y7&1Uml+_o@=(F-sS(Zw!J&tZT=}oN_JA)(kX4@?wVHMY{o;ao2Y&h~Ig+c> zfyveL1SVG_fe9_{{Q5DA%OtADy@Ih1Z5DeEUqHN)d)C7Vc(;d!0{aAdTeVw zX|6GO7ZaZ@PY<4Wo|(((&EsNq62SE%ZwHigw@&FFTYF!d-o{v<%85d)HymSp4hwlQ-ph{dX+M>3nkV#B(mmadw%O z=l+Bmv{#;~Qc@*A?z&OmGSZ4tQy>_UJ!# zUGTH*gI-e7lgJa)auLVBfJ*RRmv>;~$n81BKC1KcAp1qQ_nD~;jY?%I*C$oZp zh77z_Pjy^}dR{8>v+UKvMUq(vX#M~=Qz@fEX z$iS!n+*#^b^b<^=ltTh;z2eGS$&*ZvO16S~I+L*ShLa8)tt0nbxpU)CEW&5%+iguy z$fmRCj}&PAitVjqGKQzDZ~aPa#Yy`s23A>TtqOI9VLnfGUo3WH87_Cz=+fJX%USec z?e9U99#Fs))IoAF6gZ9zpDvP(I^(0!m6RFbFe4M%{TXp@{TX?0z{YTFLjAKPyt0%3 zIeSO2=gjNj>2eUU3nb{Dso!^>snsuit;Oj~&?{Yu$JkY$ni%Y8Mt?6@BsWj!FHHE$ z1#n#M+hfV%lIz7}$Ue2`Mi{)#-@B=#u7_rYr$xB_xJvjaG#5|`M zJOYN!7mi{r!x}NE>#DhvBV_N>5SsDm5>_vPKVSL^#jNryEEmo6orxW}gjgd}9*t6z zxJQ?7-94^*s)*%J0+th@60rMw|e!?^ccOu z9UA0YwC?$q*nOAmHkI~G5@938$1T)k4utJEx+7WdGu-Cq%6wp+k+nO)8oFNd!_i{;2}ebzg7#NXk_ zy^KpqxVj1Kl#~;@gt)&nQQXtWdr%zgU&0wwR~|ep%?gl$Csi`47eOrmo9Pn?&I)3P$xMzzIdpsH0<&TP$VIRJwf6y$~c9tR$DHP z(Gw<}y7RZbHm>%kUb>=vX8^YAwM9sZgNR9KVUoRTDRS3ni5r&m32L;FW4EmQ^|KFM<0CD z<<9c(CD_5m+HyEo9*Vi-z}=ItHw?&EKX>1RL&05)9O7uB&@t&vHHL3j*LzG$p`Rg@ zk&`&0q+Uxj!&5RMdinaLJI92VFqt`?2%1I1Gbu{~q0?wVf$Hn?(c~c?St#XzvR;Yo za)f*=$qlNOil3@*HNI0V3DGFmAgJ8)g|i`DR^PFYA_vxsbBC2lJO&QJkzndqZX9Kx zPUAnVhnB6GOMEHg3|Bisl){(FYF!!Y=URXfuZPExK1pWs%9`{rVxKjNqnAux70otI zwppG|F3(5L&-6ljzN^#)19D9aZnGMB2R+1fHmQ~T5=Vye;-9~m&)+X%`tkdb5Y6AT z;d1xEVHq&ud`Ven@q*ydiFDH40|Xnf80%dZ#Cs{%mbnX`8|?1nIAL#JxGZPCerqa% z3Pq#_v}GWt2y1zLbKI?5*DPVGPWgqq_bAQoI7&T4i}}1e+UCwE4bs4TkhJti?q6sC z{bD(n>#!sz8cK)%Ttl$noc6*lu}LclUtb$3PpNazN|#(k@}YR$F7BWJpf zt{~d<4&u1D8BM|=t8B7@%P*}S*VckT)g5-F`fsgK<_oE?&_^59pRDe#OD>Br!$11G zxNTo#;;xjD7#~LfVPwPNzcQB#heXzyJJtSPG!P&nl*MPLOWblxc1IbX>jYhn6xo)&k z1?Fudovw03#}20t)Lgm2@Gsz;3XpnCmUD6MKAT_seSA}2^2Q&37Bv5g#z6j*xzaFL z#)VU&m0tf@Gx=1{NFl(k#m(`~bp16`X*hWdt1uk_q*r|zP z9e&%^=AnV8_#B$6qGXtMTnp4n&4%>PjENvOPLuWxnVU)qD&lSj!r>0bdiMaR=|0&F zk{fb|5=p1-?#LR|T7Pc91f*fyWEW2m>Uh^1~s#RY=eg3Ci z{l84$a(C^5KCUC_bL@W8$AwF8CS# zjh5cyK|ax6oD&|+)q4kJOrEhCQw`Ur8Z!SlnMpKmSx%a%!bD0^7#8M~}3WY+UP#E01dndRTykcb;^x#jFu_AbS zbQGMA`{Vu)^UkVjIT;L6C^9R{eqNkHDrP**msdq{dR7JDtP_lf!w0?baJ1VEo}}zD zDT5=HrU`(1Sh95fAG0)H#b+#v`x&bqQKQL>WhIM)RTe|B>Wl?XmeCCUoR4K@pSLx* zb0-+wy9bs2Bjp*oD9^q-UuCl@$+M7kJ}2|Al}|siS=Bl`tgepI)n(X z+vVNtif$ehtXdUWpb7^pth!mZ=zLZwWtewYMAy67ael(TRrC$vMiQ5T{kcjCc6g}C z_2Z8s@c`?re*7`&hz277dUx2t^hBm5B8|v)n6ZoCc~Rs=*m@deSzZNze=J5TXt%cV ztya6$IjGKx{34k5XL-yHTd&_d`|Z{9KYn@h?vEF5e*5KFt2@6&coqBIRtIr3eTnXqbhNCihH$LvJXs|>Tp*@ShjyJ=U~WL-|XYf%cDl$nG@ zvJtK3&}S^29}W-lhXssjc3Pbs~kH(m*+d31{qXkT3CP*$F=1 zA&`SXu!317l7o4XFKG79Rz<w({vq)-^;9G#d(xMm#PcKvfv`BW@o`NPt(!@j41|8`U&8gxae^(8V-lSBpB@u zhmz}LS(cp}pzs$$av9+)FRLtCFyP3bJsRKd58=O28_Ft{Tw7&G6^3mnw`mnjO)l6@W?5hPe{2NW!!w zjcIXPEtaof`u?(7Oj&_~XmHm_n}oA`f$++|7A#JpKUb`{`U^yVX8`hx&FZ5Om1kl~ zqVRCQ`Q$_$3nv8@5o?Z{LJ6cIlI1CBHaChSyL5naOhNw61e<4XLGQY%L;UW$S`h)} zJAiQw#J%o*HpKm8yQ`Lp$%E^Y?s$`R2NX9{_x=l}dl}^Od4LK^5WzwYqp?g#vSnAM zOu^zS)C@sPkZclbP@I&s5>$|N4zxtoBB@#qKd6p~!;LAlqdY@eM;yZHnL-xbW0SJRD5He~1V@Z5S%e7e24%N&+Bw(I@ z24WiPC#+#TA%%OQPODQ}F9lG7aTwIrSpyzaWS4#j9!8*{$MnHn5_}D75-~q#6GWj; zWkDrI=J@UoPg_Q(440@ENtVFa#ef#27wiMGJq?sr?Bfoo0Fd;o6V-c*aC8Q|5Q4(jR< zpSZJvMHPdc)g;ipkMr3Id(;)o4}XzV=48j!6nK6~JWTSchjSo1RV5IiGawo?MYa3% z19-087Sd6!dUFHl2L)nI}n-NqrB zw1cf6}vnOmqMhV6z}f3lcw5T#OUg-W3(i{wgONp1pb9 z4K7%)h^~T+K@OxBY?($g=uBlHmZvfC+%K>dK;bJW+&^X2^OWJ&pRNF*Bo<;_*89ZR z@{L{BR2l@%PiYi`D8QYG7Fa+|r~%rMz@6k$5riHC_7f<@_R0 z4%<|wZQ!gb^iPb>$O? z#K=#y;R;JlKmo%BejSjJst%W|ZRRvmkX#6!*<2$V^mcP2#bd(j-!jeB}`3Pd5EMMebefG-+qF;UD1z=QjwjPBF& zGAlsqv6?$#Oxi%pe3nFMe^JI+f04|Jyv*kylk&v?&|EFb0n2*79S!cY;r?j4x7*vl zzaRB>X5(>hpY84UW}{)e{a`j`@%9+>62LcORSz_U6o$FzQPZsK@eu=F>QP5}q9eU3 z@8O8r;(P;IMZa8uhN)H)u=3!(=4dB z)NkFuir3rjr6ldddn(FQn5<>`t{zG&dxu-rudM_XfG^yek2Q+>C1OTGFE` zFJME`;adi!+5^PLT;fjxPjQ3NlEMD~90dQ}F@{TH0veK~%ZJOTI)na4W%W9blX=2o zsnomNgZ-yY_$Co2AjtoD4oY8ijw=c(*a&_LzJUy*y8X7pP<~=rL_@XiB@Dg5RbW>K zujve!t0N;DYDfS<;MzCG)u()hDB_=i z#0Y&gI{kChF5k>UnuXrMQUFx@My-yIUqE>M25U7RwpqTss+ABk6sUT`dU7CTC31FEcRGX z3bG$T+2m2%2963%eQ9>Lym4~g?sSRUi>})pmVaL{^Gyn zzv5&$R0)0BDu#pb`1kjNldbUmhNcDyyQ)RtJ(>q+U&e7B3=zk-_Jk+<8TUVbFkjm9L6` z8zQlbuo!MxGo<}+KrMo}c({B76&^-pPdX&AsR$X6@O)&Z3DN;d4+qhs!0ZnVGh%=Y zW3YRG?3;8s*B}hv>c}LQ9w#TH9(c{*iqymq{pG4W3nkn3#bz-ayeF1@e?901A)Qja z1m0qOOzZ}uVF&3pM6!kns$HFqS7Mp)2z3IeJ8^R*KE71V>|Uo?{dKG-s+LOwMP?-J zup6}9CCn-?f&%z`ZK1ITisaBOU{M%H8dqcnPD^ACoTTY$kx??>D}HSORcS2(fq?8& zqgDIiDkZ)WBl$5;vasEzN)HE^=d(6(n!xHY`-H2PrVoy&)Gt9Tc!io}@aQnusjVz# zmmW@w!J{LB_70%1hakR#0Y{6s(l3{30&?kn*6#F6bVCV89f2&>ZhNg_TufvcBk7Gx zHgDB2EFK+^8p3C-nA4>yp^mqu6*+W-XE!*uCw0FrZ-Q0Y4SeZo5`1pkdIs=FS&988 z3ZY4m_nwqY(anHoFg>FGC)e&l>6ya2)T!=i8ApPJn--s|hR#IAMEJP^Lb8 zG2VRAHzGfu58?A=(9gElj^}vj87#`bV0<{Ic^Ws<4F@|I2D|?bZj72KG8#r-1d?xQ z8sQeK-qnqX(VON~l`nv%9+FP;B4&juG6H(V5gqaQ+Pu~$^d~|lqMYmopZPh{Bxqax zY6sUHSC=AbW0;_9iPoZS&7(z<0uw(ek_e<(8D(V;1Y*WJh~i{bPLOrn5x-GC%c(Ku&GhQ zBDIk@ur`CPJ*Ix#>e>@gBS#YO=zF!2F_=_O|HJf#Si);nbtM@UEi7`@|e?P zWFW7N<}<*iY7zmd!f}H&a%p$nkz#`}rO`ldHD%fSc~g|G4{w^l`z<&riwZS9G-fxO zHb^CQwU}$)RinQmHm;{FTBM%;pyC3H(ia>Cewlo-4wTnaHsOWc+N>-C{c| zyQ!&wT5t}Mu?4q}*_zXy%su6~p=)wb+};faSsp}G{3Z~!y5E{Py(96>c(aKZ|HoL9 zBLLj#Hrp%~d{fC`P1Cf*?MZ>M899ccTbgtlO+(tc@_)#t(!xS5(|iJL{67Q9x=R1g zKr#W1*<&8DtRn9-zm?$|TSMMwhAD*5l2#C3!INo81V@+L*HH%I z!#)n^(+#QtXxK@SXSf6pB2lG>QlhuumC!3udVbCg_g?fMy~EGUj$k4pbr1#E+$`7y z%BVhx>1WA&PA9o>j)EU^t26qRz|JWm=|#&lIsK^`!qJx8BGhRHHcwV5%u2GPf;|`A z2Do!ai7U`3Z1SlM0J5aeKO6!hgEn1&AaT~hmM1Ob-MeAy3AA+1{`(ET(1obVdmSbV z%lkI$B5)BBTgtn`R|&$gv7=2IFjr0HRmFmBQ386-3}aBDyMH zN1qs;3zSe91YBjUZVg2g(}@0XCv?Eh-w?_|6DrBZX;czWJeh`F&##8=M|z*k_b`pB zAmx>b%2}dR;opk%*9hc6s4Bo7O@i$&2|y##asJ;wzcsO@gm6`)-2e-~>JX(VS|sR@ z3%{siKpe))GaNq8d^=D@+&eS1>nZiiF%$cOjd4>-_*X!)eULRpk;LpZ>>}Sma%YV~ z=_?=B+)+7+1>?tTx&n0*s4)rtF0Kx>QF{W~pyJe)Tu-o<4A#NFKYs_yDbbGbHVTxi z5~TT=MKLgJ`^jv^mQ|aRnUp$0=d#DoTqSM?!Jmi2{(~;e_j~;NZrg&J!7c_SnlzrM zfh5la_Lh}Ppd&+yHH@XC5t5fcR#CMoaXB6j$rsc}d>CvGhqX0YK&9G+Xb{b1bsGwn zI7L$MLV^~pS5aB@H}`8-_Kv@PGn$Yb?5kaERBCe6=>C z=Emf#ljRG$tZ5p#eIaJf$nPCNuoHZv5sB~1(CJI$KpYP{JJh?`<_V)cY zP_LUsp;*!^y-MFb5T1C?KyR8=d2wam^>ryrEK3CalhLzHVm(&_7 znRe@bXabt6m0Opl1}#NNiK~rTIAwDdZyWpO8X&zVwUl#xb4h*^x0WcEE=HltGrGu5 znY>eKUj_B5ig*tq!hKK5IHB@+0F+$fEeTda(OJ5RrB@d=0}3nOidrX|r7FNo3I ziUl!^TJ6wDftF*uwdPx;^-$EVHfcMXx;{gnLk+bL6WVie*t&HGqoUa67;B!acV3j& zxx@*FQ}@6xoN&#-gA{prVWL2E)mTmlZ{=_{f#RlD)jF&udM0Fdm1dUQj>y=leB4=sRgW{=D!+QhMD;5cR*51QqQr-tp? z?Kn4fn(L6!T|JBeKge$*`?k$dv~(>TE!=j@@l-4bF-xqWklSf>31^OZpfKuiaVcc6 zAvKL%`)xMBlhF?B=I?Lj*Nm>sbjuHF;`gI7awx?j;$9n`m?0Fr@h$hZ0&p1s6@@4x zdmfJ)f?)qA#7nrzo87n{sxGJsO1H^vyw)0K9o!+4O-<%=c*Y3H>zw9#MZIjYatzFo zY;_E4iMA05pUJre0_Bsl%QPBAGMl+Z-HzytjgiHI=FM9`p@+ULEF=7EuS?N?X+}1x z@iUS_+QyBmwmt~bN1YIpKcwj5ztM=T!BblO{;o|nvi}^x6kDS0#$aLVj;~6ULV!T1 zRQ2sG-Ow$rkhHH?X_YKNd8q?AkX8f~9-w*Pr4@>PfeZBeL3r8gJjND&7#tW@A((j; zX!UsY5uKH6M|cxkqaZ94u$(&Q7fqBct+V#tfYok-M zG|zxU(~s8u226~F%1CT2BDbKDgSIN8yz2b)BVMk4bCLbZHKD5zOV_t21p65Ca4~{v z{Cj<4Wnj)L5#}HZ>1G{l7t)m9oCQ=-m0E%#U*!wkw<$0l9pZOs&3#gwTAc(X@(R+B zz)y-Ix-xZn^n~LCj*3$fOF-kXSQ!LT-m5euUpY|KKp)mhP)NefS{a)ASEDJs^p;+Q zq9!@2H0hTxhTU5$U)N>T>SQ*L>s!-LB1%(o%qzfyqG|01Xe|&qD!N z2KEV(t*shAt7}-ti81Et+83Q<32$X%cGlR48qQ!5&t~k668VCgmE1CGIHmiVG&~N0 z_;FBc#?Wm!irVo}Tu5KnjInJ|)V5T1ePHx`|K1M+aR}p>a6gu3Nrq8t@+A)Q1b2q6 z30FiQ0vePn3~7_oT@WJz5h8EfXnAM?j8qnC_1oz|gC~oeTQma*G(YgCP&n&cQ0P== zT><=v^C1x9crw-E?tQME*!NiR)H?y?)6J3Vh!!wlkQ{NGVjEmjs}o zVTXY((U&_gdx9?c#Sf#LvKUz9#Qw}KDiWO|eNbaDR}^=abH@}jF;!q(R?x8HyY!{^ zi*&2ZJ^;#dI-P0EXK93IRKFEzIjN0=nQNY>8{GiiAGAbqN5)KdyK~^Jjra*V*BX~u zcx8SqU~BDbxKk%DqpA5pGh2KI5Z{?F?l!X|MWitS%gcI)`i>pywDtwR1G^5j!DlR8 z&MWI+O`Q3?HWhoxE#?>$_`lqgAjE_Kq&#(MAf#=@%DC1)&1-Uoxr1(Kf}{vAKoEv{ zBcs4se!)YxOxam<4%*Sh8Owx#GB0R~m5CqaOW&nNsUSI7%pHRxG-sKsFegAwbm`EI zO)G5Us>=Ezj?PjY1$u{}7Cu3)Jr;HKvVsup4Ux|Ca?UNdlOrZB>(X9J#Q^GhuXJ{U z=Ekq>pAO&YdN**N4N`rxy+KUbr;O(&^1RX7_*$lObFl3NVeMcyj-+XVw6Wh{88U2P zjq7?D)>riUqUqZ&5bN_uT1}eBaZ*WW%qS1=WCUA zTVZD^UYBP6^?u}ZK2+A?3Yeb_?u${UOg*pGS}paud2V+N!%Lc){KDOqnY9FYefdRQfxs0+^)1L)gN7dV~RROCA&ft*^yIpX9?< znq;2j7Agc{4pmw%b{x92$xpy6CNFv$1v}n=2dYw&!Nq%z#1yXNdn>`LiFjievxxAa zxu_^M`6p)yP{8Cs!8%#BOVl#TWSWveBT4}`;{+9b0t?pT%F`Wj9$Y& z@A^Vj-MmO#-!w;pnfya$>OTDE=V7Rj9MmHApD(5^lxV_GDc|bc8zgWO09)!(gQSuHK>l!XjT~6@|KnDT9+z z`0Ia+&LiUoP9UcKrM{6_ulvVA?4R@5Gjzjy2L)DI9roL;yKWzx) zF0xQTwdDtmx)JGXQJ(swqj}10Uc9lnr)d)>M-xg@19jo%-rTh%Ik^*kHHyiaZSGfM zh?C$OV2EID!Vt@R35ty03H)jtIs4s!B)|Nz5tdq@tCs}uU+H*Y?3^54ZnPU2i!msC zuY^bqo$7k)a&5#=d+Nt!+>Z+qP2Rzv0mS=0cJfK@f1PaopkcWn%4D%jeNoz-F8=<$|Na6fHaIoVYWLa_ zm}nE(pVS{R-7(Ij2g&ztE!gU)sxZvcRI_bz5Nzo89FPD@;*VJFts!c$r zOdX&LP-1Qy*qNZzkv78O@$BInf#db@?G9M*ID#CAQJGI*EoIiG{EmfMQ90dp+Z2IRJdCr$9UEjabQ&qQ_U+jQ3a7Y^cZk5m=9$ ziMG#H*{7G;a&;pNDhWh@qJ17i7?_RrHn4x1u3(!K0hgAFXUi2U`If1Tel0fBVI$I= zn;a>70Xe^rR}?ZDzxKlM=0MEbA)3`3AO^njv8W+2kQj zj33qA8LJslN3u#Er3o2BvGGiC&;_jj0Y0+`e9zP5qi((rzYP)Ni*j`9hYz3Fq6?q8 zWv~#w#WMdqDU%BQtEUV%vfLsjT7j852OTV%83Q3(K?cdt81aLM)RTJLp*r0=GVyff|i7I00N20KcIyL)*cO z9#WW5xn!E8Np%&3FQ4y|qd;#}Bpp-!z19-cfVDuui55UEcu{SH5#iy4&RCgPBJ{T` zF$AatvBFgKL=aM7712$d0)2_3IN@(HzK)i%M|OwuRR!WBhyq>?@LCE&5Q9l)d8lmE zyI{nF!gmR#IWJ71%;gLKzDPt+&-SWF(cjtPb88`rxoQn0U_sR%gbG(%e_ZmacpZlBkX+Hoghdz3p@{$Q9w63c!JF>2*s(GhI#b zoNBcU?y6#R&xju$5&&z?JwLZJH9e)~MYLcWPrdr2kTZ{F5eJ6t@Gqdi%UDAE@}<=! zdGF9k6_u`C^bL3RB>Ppfb@K_hnAuRWqEE zh6#-B4t@_GPo%-&ulIw_AmI<@33sP;O=YNhq{+XS3^FeHmph*tHx0zVmh6;ffbc>S zL5Ev|RtGlU_~s!Cm3OEpD;QXKSxP2AJ)8xhgeU!b?$VWc>#6}SLGCxAtQbpG0z@(F z=v2wNI~6R4t$u4#Qx&GLx_>(G750^;GhOPnKvo<*;lVv7ADemjMhagT0ajxmN2)=L zud%=79-4!&DWWQF(qs8dZ>{WR$T<+LSPFtg2@nNAK}M0T0#zR8K&DvS)5ePxQchPn zp8h|+qc+HGgdq|V$=A(%KdW{ zVd`)=pBr@`brBU9gA4NRLr%P-^8SSzBi@Wr1$4<%p1eEXjb|!3DgP8$&DqXOL7Ao? zGI+!IF_K~H!Qv=gCwa;$%-fH~Q#Mw4p!jE)9PN&yaio%A zLBG1lb7~`I)BSx#l35h9N;b4Rf50Mz9vbDUg256h=`u9((9juiBFE#s2P3Ak@*+xk zXYS8;hemQXhwURPWNUjn4|Z8>=9fwOiPxO(YpQ}qu_$xuRy-T+Z0n4xD60==92K8T z%I#0h99?IBYUiBhY0R>M6A4JPH?*^h=!z)&0ROXdSaS{&t?lh-;$haOv*=SoEydIO zdsa&eP;s(~7Abh;7@)%n#(LIa^G}?J!<&>YUH0MlBo=O%H)4d1ypOwLU8F_rF zS$)JF7&CYd(ryYG2VpTC<40wsID54Cn$M%T8V-!qTULtVU_?p9rA!)6H*MbF4+opZToD`%F@!;A~??zvX5EvlCspeYU%^$Me*1!C5AZO#{Zlw zwkC`B^TCk8Jh1ZgxJ~zFBP&Y_9w5L_3m%?nNS^UPvq%w$28jA)kDm4m#YFz6gbG+_lNPmookNP z_H4R+f8^wwE5-fk-acbafhF3a45=}PrPeNDEeJdN@kp<4yZ~Pkq%gQY+TB;PagoHC zIj=?!Mi1_5>Lpo)X2XS0_~x3O7D-uM6?v(2KBjw?&tU73WHM)}TFavI=woik_!ytI z)tOgHb5SV3?8Ng;Djv^wH7k%hAm!_DXeGx*G^LTA?z6EPFH=E?c8w~OF32;V?^s!K z=;H_mS2ezjQf4g(jIn*qQp+BXG%d?rYjomIF5#~8k}W*5$i>L zI%LMA)H7h;8ai0&8E}Hm-rL*W)&fNl+?=n#QCCWpN3}{TRz-dlDcQ3#+Iyfmu7u?v zWvbr(bZ2+8tuvK0jrNE4$2vWWbzAeDXlGBMVF_8bKi$1=jD^>_G*dYvEYsi>S(l+OoZ)sB4Qd;Idf3 z(t0gSwXr7q#Tkn#E}vk3x2==4B55r7lw2nl1LZ6og6Ux7Qf z4^0efP8&o=FzV{xGfWuvhi2MBq*;l$TwvmO*YNRdFE3SUFbE#(nOT*Yb$@JT&Frk; zUNGXmlEMWhUKMmaZ=qf~s4q&1rdbu13VdV7s8_%e1~mua_#WC(`@g<4E|tUP>XdS~ z_l8F5sjLKBG$R>JOqk3YG&pRdcZVs;i#IlQEfTS(m|;p47vwE-t%`nVL~QvO7;ib^ z&DWP08|=+IY(JJx;%I367(BAw+KuQVsyct>ZP*PyTGv6En;6(lJhYo=uJ``E9U0eK zU0C~CEzi{y56X0n^I!wYR>jp5a#nc7%JRANBr`|IV-_ET+(GT+-VdF>!sGXk4^H~` zIzJ2y(|GWh8>J`e@m+c{p}h%CGDPSRk7(RlPt7t_>%9J(h8 zf4zU-86+J}I#p?tww*}W|E?g|vKow`Q4G*qkDUrHZ_HVl#sgm?;NNt>!oeVjvHX-( z7qGAe)kUs7e7LJX5Gj`&%F=%MD-rjzDI6#UM$}?Ww7j;4#7@^ry1^p4q#%njK1G5t z#Y9OfE#^I!(-rA2QS76k2fxvIjERcMxpCqH9sr$$JA4f-AhE_noR@SJc|4gy^q_Z| z;h6?dy1i~w~p0|&79jBA^<^@f9qgv-_ zK)2|`X$z{Uu!y;HRn z{U?tE?VMl-NtSO9;nng!EarGn67>5)nd86mVH1!~c`=3cJj=75Z1_s+qjEp{gEsso&Dj@sk@S zu?+e9i?ATb@)&u^nsLT3V#9v29!pS8+*hY^eHBYeU6lezSmpZ^iqzAd{}~wUc%6FE z)2`k$ziA1BTjJFZRaGmNpdXlA+@lNq5?^0@Oc)R|3bAuEHr<4p^& zyLHEpxFX4W>0p4twea=}-gV1zZI0;&zosmrM+3YIqRhk?^J0bLX=iq22^h3&?C_9&>gI9tSPch}8-vI-zxP`}c0#8D|*& z)VkwNAfp_ABCdHx*%9_@Gs+pk+Q@T1MmsKlb7Lyjj=2{3eT-{-(y$I24H*F^_zF7N z9^q=d(d&>n@K5oO!dZ-~f-!!2Ad==M3r7SvDMawRKl?PX2T@asrg8vtMKx8s?1!F{Vfe~SLgz;Gb zhkHSYVI-nbn_+5!zP4+t>dZjCIGv(eJP5|SyPDHy2F?v75DlbKi2a_G&bBbBUCpNo zAs~Jap-b!mm0nGyCYtfgEiBxF$`}o70G;>k3ky>0v4wjYN!ynf_n^cgVS$0`^#crg z%rTgpsrhj9#Wj;FSX=hi0|y`fOQZE@U_EOuA}!;P z@euY|_ItsPoBH0DeU?pF)h3PAcvopi@x5Qg6Ot17yduY;wSAyS(-^A-#59iS)aEOo z5A50cyDoRJptg@hD2NP}AMfI^30ZZ^KZ^>I>u)Ddf-oHIA?2w9Fx~I*G1=kYyqu?o zuE%HMm_`mOFy!EvM$@JPsO9m^bdZo6Xf4dJHh$yh#;^XEH8oQjO ztCEgSZ^OZ3PCJW>rD+T85*OPut;};5{s?+R4=3H+juZ?i5ylp}89Nn+y*ER_;W9ff zP#-C62Ny&oQ0Xz>hS4z3f|>@*xm!NB6c1hLm>$T|zxm#R2kmVD4OM)RWW6uZXb>H} zoEvNKWaoa@yUI?+wAOF*b`+B98Ei%6d1r0Ck7cG@^EcBB{=ZdT(W5Z6Vt-POEcXOB z>}rv(N?*}PW`420!K)EwY77pn2W_Io5_m@KDa?tsNU{(_n>t?_b}?{Aht?zg@@bhy ze5f1{cB6e=u74)jqhHD|l41Ih4V+&;4>OZ#GZhdzpX;IX%o(!UzDRS}J7j%yGwCN~ z*#27^rEAv5i=hnWjW)?{A}^=rJ%Z1P z+G(JN+KY&h)#%y`qm&v@=_ba`092yWZZK_Hel){Dy-1es2BZGaUMw)%0~Zu7cZG+N zsN{+QComP3Mx4!=j`1PsJnN!n*Ez64_2F|AqSI0R$s$ALJ0%?KRk%z|RAK($yI?ny zfaaVi?I8hXd*C`G&@+9-!kW-*t*|3hP0m1%8Bs!y65NRJiFj%g3f>F$ zp!Uch;$nmr*#*X=TZ~XSp+X0NebG)$P|O{>AjWHpZ$t6%x)#In0AuH!bsAfCJ_e`* z|Cs<;y~X$g+`k3edqY$S;E$#af2ai|vM5=Cunkf-6-6-dla(5E%p(|NT+GVjK;* zV2wl44d%v{Li&2l(;Nf^5Ni-%bAJo=jQNHBCMv5JBo4@PvY?#Xq&=5=^Rm;BF-In8 z%H${t`7VUNKVyTZ)u{Fa>j!%d=3Us{H4pS7E1r=4@S~N_mlf z9bmL;z)Ic?Py?{qpeN3g6K6* zmKAKIBFns5*p#KKOT+uRC|03xs|hS8`{G1_eZ;9tNdtv`QiPsU4AUf z*QKXT5sma_Cd*x^i6y>Pp4x;D_e^yH~CWx*%5tZ-w5ab8Lc z1;%Ed$j(d+=#>$>9)Zyq? zeOtg4_%gLA7_(c^a8rbP|2Bkax$sDsFUL0BguJPRZMrdeqvF#yMs@?zej&2+C}zpG zL^j%lvXO+_Bf482DAD$W*zEo-Cm-uVwN^e`pWP1^O_HUHQn)iu56=Qg`r# zgrAD4Bxf^tF`|8JcmY5o^e*X*&^UU5Hk=C_dfd{6XdR&voesAhfL>5T4NVQW4ZIjR zZ3yd`ae_OdG>Sw!6y) zy~s4;VfmV(eMLsXO%zXOld4yJIlpc8LYu4I8anb6QR$PnxW;w)x{Pu0@F|ZxjT{8xH)>u;xTdDjMd9Z2 ze#;ZvJoDFQ;gcPFFUsQzP&=`o>>4G-x%=e)aIM$CSH2l#x@#IPc$>Nd;ODouuY3hp zMQWD%LRSE)DqaCL@s?lSQH`t2SY?beLclykH*_RjL zfm5w#%GB4|t%$br>1-=!eGgZKEg5#YWxNrMmkw~^|H6?6r0^Q^FQT`$mg44`v@r9~ zwa@@-OC>WWIIL+lmIf-zIsox7-u%sFq^*8Se1wm(M9o*U?o@79aR#h!zMK#|Zlpr3 zUag(U`ttC-xZ;<}?XDFO#YH`;_#Gq(gmW7PPWZm(k#^3feH@&89C-+dc;PV@=j2Y$JaS(Bz>s;<}&Bu=p zg23N7=i#%hY0=o1RVl9e1oFjW>vmwwDnOX7getBFbnvd_Dezim<7jffHBa$l%o>wq z`g)Nf7xw+T@4iEjx)R>7OE7xdpgcd_x?H5*OM;&6nAwfNgL$}fx}h0BnRpz17N9z~eAC*wil|oT;3ntycl+xR_FNFN&p_Pf?K-89TL_GcSOdJ^`#JK2= z?{vKoSzk71-0Q=#p}u@{qPF8SZ{r+&N|s9&tM?BA278y7UaFlkdW3|(_kmnL2Tdt< zUyr?c0-`Q$&5kAm({wc#)UohCxWngzravq;cTFBMukB%PVFGO=7ry(>7$n}hZsc*$ z)Igb%wE>BWPjLZ(CwPxcGhxu~w&7oFcuUD&n*T5*@llFd zlp)>EU_+gvLazoX1#KT6U_jI2_PBe0Z{K(dtslIc%ezwOZp>KBVh$8{<|xm4J^5Hh zFi)dXAV?aTTQ<2E4 zOOFn%k|Y;}bTj$6uduORzlM_EZOW{$b3@{)B@Q1MmJEz`^;Z5M15aCYyKyC!?%b(}oj_{G03cMS(cX4F}FH-~ul|EEJ%nH;l)S$mcx_s12 zJ!WX;*+^m;JLSMMzVNPF(aZip?{PKQZMtM7()yg2Q)=9FPiBKU(7T zEiTrnV8iuJyEPR~vXPg*=0S@;NT!Hk)phUC&@j6aXfSy9 z=Ghy12-$13l)#QNahZQkGs}<&hW%_(H|ALS>6__CP|jP-tjc@cTW4siVhUbMb+79P{?6Db8w*nVe$K!4zaX$j11~0-fGuw9^+a4h^i_ zsXW=-?q)HtzaHJ$FIwVZT=fP#2WQ0kD#ct<5Tx){kxT5btxf5@sknvgDWEK9ov^+s zGRonrZJz4`%elp(a>K;$VyIs-E$(S(U-I!> z^Jm0Mw~8p1DZGN2!s}3qrSk-TV8_CF)}-V_U9~uds&{wo% zqlkwuxCc)cSFuDT*L;%60`n`Wc-TQ7EGL0E26A=pZFM@F6#SyOeT&p$0+Ucy#`+th zR#ARwl*YikFNzl%Agfy|Y+e_&+bqy#5|~jVU`Xed0LRTFpC;lS-<;p$YpFxT7HI!? z0dQ{G$_42Jqp0O+wJWgOu&ym9H*m>L3$p%-SO_o4St9?4DyaYdRZ8 zVZNQ<_&488m0|{ixm;S~n3S*4!OPSd=_Sm=;7L(LS7wZ0w6T-A84A^rqz8Yk4pTg_ zis<>d;bfy(oM#LTwDgRyoYAEUYvfF2ab@SD+BK*zzh(4THClkgZFiNzWf1;*R7F)X zM=h! z)zD!QO4TCm+?A1$ZkE)%O32wJDd}%0fJ))#QEy!~!^k#bpMsUUH}RnXeVr9uL|XEi zE^N-xTe`kGR3y(RM4)0E9)nkkIK1v`-(e7t2t$M4I&vAoxEZ=Ny|Ca%tVuR{Hz371 zyM~pKHMs$x-M*-F$dS40YwOTz3xkQ;MTtL;hbOXwO+DaP0)85{jSDBZ7Zs7^^tx#r zC%TSq0mH@fS$EuOoj4Q}%{Z-!1{Eb9n*b*A2NrOq)khmu&opWrOA`}a$iHy}p}St@ zCYgLhI^_?omrBn1r;*tupcf6T6fIUko5}G%p&mT)SOMgO zH5Xi=6!7Zywfx9X)uKKk?6xiiZ0iP2G*H`nk1H!!926O< zu!t@xoN0^BLGp|0#d%du|`8~woIupI*+|_!CZCe2}HiIHgIvT+6r&%nk zGmN*`Fw|k9u~<}jmy^J-BWrM=%j5>s?8zaYFR}ZVn>M+~9}~ic6A2#vTQHULEb5D$ zkBMD=VL-m@23IvZANP2@+n%(o^fSmxKrb@b~WJAkwaIt5?AKYt`28#H@s{J zhXPC9-SBEN4e2)f*-~w2MIaJOIQtLWoRI|jhL>^xt^|K{gG=8~uwsS}>z!IhExu?k zb~`#EiF*n0&h>_#g`01`HV*Oo?+FU@pV4`AG%J#2gO+0#7e$o==m7Cw=2ttXwPYMS_@6bBQe78 z^19N(VGu{;^Dhc9q!tYH^UGx@T9cENnt|b=zha6_f_A%Op<|7dGYaC&U0_6PkD{vG z?g}ir5?emDu}v75$aSIwgL}Aob@@O2e*fOUCB;VO11{e%_`B^1eiI#ifh^Z;Z}Bs@ z_pv;K-ExrT`4T%c!NokdH}JRYjL_h3$7LLy3=+e)waP!S%%^hG5jzdlVL*k%O9_K= zkl=MMYr_h|DSvaN$>UBY&t*(l$4`3y>*R+)hkSc#zB@ug6uS>cm-jj?HTV2)IBB#% z|5p69@w#9L)XCoPw*KYgjUv$A`l#x5hCTdj7RC-g{{wv2*E)Ka=cheoZh}XYz8_@u+6T84^Pxw* zoC)H)$(15W@kbkvmfE%PXgd;K(@DJn)_(Z-a*+n&&0HWvA1L(rQ9IbOI@o>)s0UCo zD-T=s=#zly z6Ki?UK}TDQx3+@z-z8;}_^_qcaaHWMEU5td6*O|R1P$;__8TyEU_!E(4bNDhs9gk&?b%dgPRDyh-A=wziRmE3(&jYTdlc zZ(TOr(!CoZ5gh|_@s=M_G}Sh*l*24Ysw-ZN=kwyU5y$U?NA0!pgOD7on~R>Qi&Knd zokv_lO?1dlVVV|c_`QVMX$6Bv4^hHcGt!V_o~@$Ht;g4(8vL?{bz`gBBCO;SU3Mj( z!+)!7*5HpCcD2U$Z+HFwnv2Vu-wGIS9RGatTLJ(7iIjfxM)b{+@j#Hia=Fa>TJM&m zj9eEboNSIWwC!}p3v6;LL2O!*Qk=?L?YJj2hNsz@W8O^^BKf=*I(n!lzDhRBvsind zfTqLo>Nn^!0%vh#qK}IB*@WD1Kap4XqVF&jKj7IAg6@|Ch0|z5C?bG~ z142ll4Pgk9xjT(S+S;~*l0_VTh_1F`W@mI22No|%+vaf|9~QLB%6 z6Y-a)@st~mcau42gOKy>4ixD<;G}>(lsVmKZq;38w*t3uExti@>jyta=PbC&SE%ow z!k&xK0|fx|jFn0Gm^3>O3Ep`s1*2~tK=>HVO6Kxi66f+vi>nP)d$XR`=5Ab~_FkUm z_00!_Ycj|_9mPX>!_UNK5qw3khsmu?j$HMrTIM;v6|Vprr|H6lkh=?73})VY65^ho z=Nn)Mx*pyMk3}t22jlwj3%vMF4>=o3C&!3x*z+We7skz@BeSaLg%PLxmqfJ$nXey}f3fuC6X6r+x4zw|m-JQ6C=LQ3NgGd{~iWC9jJM`*lIS0`|G zQy3V)pauSP$VIoL12;I+x=XjB`_I@CSR6f69tXc=D_o#}Ey^S&Rt09F`@~|~0NF4T z`!@VPSB#8R_6wRgzNH8Oc?Nn-)u^p!hw%tc3Z% z5@|RyxrC9MN(z(1ROv9`GoP9}i%{U`+>Xj2Y1%sPxJFwLOKzG+^vGqEy!waS0(|4{>+|aiV@*j_T`9bD%U$^P~O-#I0Fc( zVNFw!A5&SGSmM%(8E2n^tA%>vvZW3H=N!Zfb);TF=G4o}A@SFdxsAQvI1t;?3@FtY z`EGrHDQg$HE*zUZnZnP;R{E*ZRA3(i!kfzW7NQF%YH$ZlGvM0UTk<_XqeF>brnsmr zb>utAoc@YZN_bkM_fJH`uBV;=m6*pU*B8@R>bHibq$?;r$>tRN82XJ-UWdoBDu6)w zH7fDm9j=e7WlYYgk`0kw^cU8CwcPUMrqrtmDv(MGH2~9w6Gkp9SJS`B)v_ZFnt^|u zqHfLSm(gMg(q-ai^e|XeBSvk$XBlMCIsU(oOKzLc(;b3Rm^^UYXi#}ZDVph`$~-#D zf%v?Z(Lno_xWR^RkzB&M{BJ-DVB6>zLarXQ(&lQI|0tnCm))F6mCQpEs3{J8h9j%2 zMBQ$fE~+>SpOUt+3TXH(*tc30G2>Y>w-KsKC^J_HV)ybQ@0u;8`bmjJpNKtI=<5qv zy3IOKdJ$cfucJ>C!mCu3y{Eyqp^U2kqaJ-Ya!z@!a-f9fSTOn4DBq^ zywE2}?jO*O1B3%W{ci^R%aua1G1LQ5df zZscnPY2LYRZGc?UYLihG2aDT&LQem#OA^dI!{b*^>w0GOVtc&^Fv^(S~6azyz~^fy5*TjbFCK*Pw>^z11;5 z!3sqO8HVydX@U`nvOQA?H@)APg%`8%La}3Dx@M>hfagh>zzi)dYRE*BB3z(N*4VP^ zKKeFPmD;xBH0gShfhX&%>iBUO3`pUm*hcq~GJ&4U9=E+Z82BIyPBlS`q(<0No)5rl z6QH3rH4C5__1$w|(Bu4BL&bz;O(THk+KvsFd^M8%)l3ZT?PiSzPqHIzHP2=P7WKmd zMJZnZiFSoN4yMs36c9Z!YuFP#%1R85{jNUaMNZG1`>QHRZO)|>Yciy(Q@jA}%w`-e z%F(2CUn8(_7H<(qA#X}~?9V#kjv@`dQ%KC4MaX2d;}$gK)nv459*kjBF#>Ee3Zzn~ zGfiq(R0tU>AgvhK$@aGTK{SSxv3FUbM2l{aN+)%K+a}x8Zhfjj&I2chPw>`chY+(z z8B#|)6~FINRT|sYWS@#l!3V#0V6oiZIHV{+vDXF;So(4)riDU{tE(=B%ABJ!8akE? zc1Zj}<@r?_ijrt7n#N{B8!}K4cVLMsT6LCEL+riW;EH7K%($3s*fz*&&coViPN7$j zG`JytmCqusR!C1s0_$9WLG_)CEVDj-tv%Tmh)nppT4YW((B&1cFG7oAU=2_Em?xX} zG{aAk4tW7GCRbtmebzQNT%_a5_XPMCygqnzl~vKD;a00oUBuWl9K}hm20{-58#55&6P0HL_~0ja+|Ef<6yFbYZdq|dA>-e;xHbF&McC6>!J>*a zy-bFa;e~ZR(ZQoM%6p+tUZ4b@sVapRQB&S3in`nj^yRTOEB>+;mZ6i+huluJ?ed?RNr>r@2?sJu^-#l{rHB!KhIHaKq205g} z$^)h!{1e@upyUEQ#n2NM-v^1HNSsiKUHj~06>(bonyPKe8URJ;Ivz45@(7d(i=+7!?dTDzWAsg(vHOL~B zT@5daigTY(7wZO}_1H~n!>FW;VreB&C$`kAhhDj^(ay_~0vB}D^RN++3QzotEJ_uF zhW6+P09t$>iv?CvQut|E_;N2A@0$x&iCQ#jI(!iOV7en@)iHfS8pcKzC1q`HpCy=t z6Lue7ieh4<4N@Wno9c{cN zD~ju9#lMN;v?yp!GpD>`h}+cDdW{LvSnRngq!o8MBSUY#&ND7o%Z>c@*I%?(w3(7` z>6MB>be0X(9>kt$e-}~1mfE__&&{!4?)tEmeJxo!uetCU981TYHGVPTX^Qhm)QfPZ z>Qi`$p4^Cq%?U${K~DQ%kQ@1$&PCT84r~QgV&oD zL*u$Z-37_?=&t83o!LPHWu{pMLvJm-9LTGb&Wc!eynNPo8?}BrO=%ZtkAH(!cWb*R z*;bSDyN^7^;%p{wcr@%-QzazRrrIKw^~5=$&4F|%G0c5BF4^(#?+5SSpWORl&_ypC z&+gamNV7Wt_grlDStDSU^X1KcmnIUzo6_q&vAZv4)*+{}A$SBi|4ClARR5+GV$M;1M}0oBOv| z+hliFsfgsu@Hrz8_P26EXgci?IzwxsR0`BsHhP`{uce?xUOXm%2NU#|!0c?5eJcCS z3%^>n=TVZH>pQTLGWK)zy9;UO3|}T2cKP+tSL(N-P#TrhnIeQvou;I1{Hn1pN61wn(ZM=!b5#N<~=ll+U!6*5h+eF^?XPmgzJ6|Ck<2 znVn&n7p^-?ieM8|DFp3tRy+3Lgz>Z(^b~fsM@$%Eorl5hXw1X92)GzzIITyWtUDFk zl;C=_IEEpMp=`G6MQbYy|?uq%cwN+p3+==5Kt9re94>W?KbqLm_GE%zNGp6~& zVA!Njsz+v%G*sa&a*luSA^gztGUkmwq&M_v_rbaz)q#_muRDaxho0*Gb)&iQ(RjP5 zb!gmU&)#6DzriSv#=C3Ks`rqOa{6@x{P}AJm_~&ofTHnRjn9MeI_7xqMWa!e;mItb z;}vNK8VwJM7Ufo%2%8&xc>jJgqETl+2k<05@FYIiTi0!9k>3XRP{UKKg(TJMboQ>K zo3iVg6{Kka`l@xs!hANq{UT$2h%W%hBOooYz?!i(%O67LaHTK^3*F+e6>qNkV2oAu zz}5NHs^p{Xp~1L~wej<{9BO|29m9`*>TGH<@J?4j*_%ei>7N{r4|u7IKRMIKi;YhO zchCaA6||`HUcUFu(4G71=G_44$i%%>e#ldKyJRf4q{*xw*qeI3IrEc_=wC4fNABEj z;v?+epv&*hrP-XZ*jwz@Qegb;q`>Wnv4+1%{X|HpaBg$;Q&MO&l~1= ziV?hV<&c#&p08?J-j>G{dSAS5c=f?qn$zD8_XZma&-F-dxM+ZBT9$cj^;)hxUq^2?tR8h3Lc4tXkXP@0@W!A0h#EHp z9he?Y8$Y8Yc*Q;|6p1$+5}NiwVK(F+m^!c6(UGt`@|cB+5+7wLQBnpIp*FRBB|2wE z!W$J0eLOxHgqy1#UpRWpxQ^%2kO7gb|M#jTe&~Yky-kjoVf>mCt z{c8?GG));fN4(~avR%AdKIc)I;C~A61p_b`+@-7XsFfn0MpJxMHd>Y1w8RIitNV|? z`6Gx#FI`Z+d%KoUA{FrM^1JWUOCul^702_#-~++en>|j3m%?vd9lILIeH;egklQWe zsg_YGIj9dKw^HJ|$7@Y=_mYWSyBmC*1RvEwpfInSMGBxgJ|b)&w)Bjb^;C(Npt>25 zIBEn@QL{7gj9F##u-rBH+<3c&VQLagL2M-0O+3iGT58EY^DuvIgdDZaambgZvyFZo zn2O4as0he0J-)x=d^Oa&BWlP|BbS?I1m?&xaFYbILN zY59IEH=NrLdM1PeAAq&2Z@RKrMaq9Fd$V=&!h@W9JgRDh-;#xqafcoE{zuGwy71EK zg$$?5O9Qh%{rSn;r*ED;|KsS_Cr_W#otRqI)3^TgcTaxuXS{l051zL3?+WcU$6@YcA2}$A^4&l242{!o% zd^eCU-l{wd4w6uiEh>TWiW3an9w3RMS;Y$OVI|Jnx@N^(R}y^`MJ*W}gdfE351qbI z-C}apfi=OI?QH`Ny~#Zt?zENHTw4sbuy4m`K9-;IQ?k@t9J)aJ4oq&)9{e#WaL&Hs~p^dlEqcHNLCAsO>@N~w({ep9-r@uS;`=62W`3zg_ovGC_Gjj1zCya z6-7~usy-nH8@m!jg^CrKh;WIhZM91i$Y~KR78EiaCQw;{7Gk22WF^KBLiYwQr#a&* zo~N+fvZPlQ(M0%Uael0MWXTtDvE*jTI2F}z7$4G;4RYv$Nez^gF;co5E!ixI(&S$} zs4>j*A4nS1<%O+9IJ4q^?5ctv6lV+H$w7URx?|bwD`^+Ac=R- zz{SO5&AEoIjSJbJwuY&$D#Q6_+G*GJu1Sg4T|{pt#N5~QCh^1LSzT7YunTeR81a^| zH(T%VuI47_n_ZBw)*RkTTIpuhID5Ba2u-yGvVW8mPWlgZV@^Vq zZv&%e?7i^uGEv&@l7xQIpn^@eK!Ejfe zjoAhpR_s{Vk@@f5JbNQT7@##t(6B@sfjU^lMI=g7ddLE6V~UqvPuK5_Zc7K>xq*pP zgQ554W}3mDvPvFX+z7iF3ew`2y!vIeU_~-(f<=q7*Pz<4vJVC?%RoQKL_1Nz2=jM`Iugqa_Ca&(Msuh(57W3cNp8$qWxK zLliHIs{p4P#(w6vE)amu2yvdnU5+~e;H zMD#+^k`;4&#*^QC>|x$4LIH;t_fJ8zTJ5hg{svF5!s|q^ltm=tRi!v7@xhQ4NMxyr zSoSDp{*S^|TY z8CpHXW3!xj)o6$t7{Z2qQRI+D7q{>vl&EY%5^uglQ~s<7Z!wZ*u(Sk_nhD_WEcP@v zD@!Y9KA$HjAYt5em;_o>fP4s^`{U!IAz5&qL>N<;@q;M8Dv_7+JXoyo z2^Sbqe31u(C?sXMVg^Z+gA6fpZ38Utq=JUTZ?!m)Qv~du)Nwk-)BPb}%oi z@xs=XHO|GY$u6pD8Z^D9=XAaeNpWlzFid1 z!(RNLQz&^rl}nVSCB9IJV+`KE;!L)>TzLeEcB1hw8_!BG4jTgwTqKD6b%Jb7kGq-YZX2##>DO^gRf*OXQU#4!$1_ zhx}bRJQ~FaIIF0lr5iv}d;|rlMyXF(egPFDc^OtwY$l&cCpNO#D=wl79*G=1sqz)- zEb_1w!!hwDP|xCf_KeLFdZWw(Xu-J+=t|1IguzeCoP&m(f@B12X-Tk%_w7h`XQg!bC}oFK zkTY{X*?h%(?gT+lAxg{;RJQ+{y_kfZ+CAXQB}T}Iic<=k=XrG%?K!w3&nc*s5V@r? z2k_%k9k_(1=v#LB+;D^t&+l;4Zzuv;nqk+(6%`5$0;mX!#&J$11F3DEwDHYS$maz` z&oTInbx2AO?Bim;S=b51qm&BujTU!|%tx+t!s4Rw6BZYIU6_**re+&&+&~e$UDGB9 z%67{!`WaS)kZ$3$TWf8@p3fw}OH8s&5|S->{rP&0`9+L&$HxPNkK}`O{sMFgO=M^w zC}iD8&99}H-C5lg*+!Q*^QQ1%HyA-TI|Hx-a#+v5)C=?HuHB%)^>XUvF6fJG`E+(L zTsEk*2D*S4c!q&V5xcN9#htJxwQd~LOs6)jQWXks;t9GeG!dVrE9~$f%y_wU7*3DHl)MrGPb+Pb~hHp7XiT4|!6ll_- zG79b}A;U(SKTfrXichPhr=AMyL@}#B$e$nh!;iSG^*yzYr4b`apG8%4f{F&W3&28! z5!ZyX6?8!0QsNk+`X5n#_=#P01Mv(r$OWY>iI;rSD<8F%Jhs2~?c^pj^}LCVmG=!c z3QA(WrrHfo(|j7G{{Yxs44DopGye`-k9Yi36`w7)K#aFu|>XYAadJnd!Me6-3SX^9I+snTN@!`R^(XJj(7}$;7WBPF4HK(aJ}9T zU5f1C#&B>|_GREY)j|qt{5*aNB5wdSATH z2CzPeu{V`}@_4=PzCiptUyA zK@a7DPm0@d^=thm1GI}U-8$3C@3Kfh*j&LbIWm->dkoc_CW{1ha?wbw?X&zsy}ylW+XYzxRbRx)p3g{Ok8AP=+NCEokPNiT zM}cucU9L(D(@JnEp}z20UqeEi_LwE(BnAq01W|jJkv`btM;H?KK-C27%0(h#0;vG&kLe#FA%QpI2RHcL+9a^s28$Q^jBJ7iw|r>R9$ z0+rWzceLcMo;S>>#;HWpEo3U-JnV`T-5W2gOFV9~!Zb03H`x>V(ZfA8l$vAO*49Q9 zEb`{pZhh~-3dPEKc@|x#$cNGI(tM$g!uq_%KlsnkAR974JzyJt`o)UB0N=ffM;@|PhKj6aAW{}_fo%1@O19y;obbfw* zawl$V#6s-}(i<764opLRfj%@AvPV&vy~9p9+rQlE$fT zOeB{Db59mDv&G_#U~1k}4PMWB`YNAcoZF;L6VmRoj8_U+Ss_VVI619uB9|x~vK1OW zLskVQZZzt2Dq5jg6wQQM`BocYiAf#}|5tu{BZ?<2obJ|0^&+OdrWag;7_2YUU0TxG zYbC>9q~0iLJ-HEm7#PIjjjH;wCvo`QjI3qaUxVowEpdA!=2Wcm$ZN!UV|{!+mpf_J zMF&CJqynwr9)>txWvPQobAD-*cKEds+C|YmCGuhQLzj+lbtXEv?NSFy`;7z+g=e+X zS7M;onHV2lcOEd-AqB6jrV-A%wva37` zx;;v%OzE-xG$_7+095NtN^xg6i7NcVZVthkcX57p^S8x%H(4$OBX8Tg1~m_~7AP?Q zhn_8$xj62{euVp4ion7f!OdAG$&mY~5I0INQJ80(zA|S~RPV0y)pC~IiuqjMmOPHbqi5N{4n$t=34|>mw0&YVD1e6{qt8!E$Am&u!iR_7M zu0wnYN^Qm4LZ|q`A6=#SfOsvis{@RsKolUIJ0UxCpN9!EX4nQr!Krd_qA&@o9H-nnLZn9^OjZph;8J0F3BKmT7i^~xRNyd)%>cSO z(cmk`oKVg%(7sNxb=BbEsdI3t0vs`_k8#fnX{9LS7E1nw1F?RJJ&JGQf+#kJm*HN` zXZG7E2Idz;@}ZMek05m^HAvEO{MFO_Ux%mV>3p=ek3jpMkHnWsbb_Y>r4Y9J3*^dJ zKqr^eWxJk^P@6M@HHhH-W^~g%zLh>7#av4fS2=h+6y=q%VixRVaWN;R0Oq-Ln>SiF zWvyjoiwxz4q_9J8PPAiLB?WYMvE~02b}&*8bM|v|X;vfUWpN&*SSHa7shCy7w3Ius zb&dNZ_nBj_>ALycKENE$6b? zL10Sv{a}0`$Y|{^bzg3lByVFpTR^84qEWkHd+@ZbirJgn3!RN z-|kd7l8TNR1cTJL`R_RF4pbXH7Mub6`^g9>7yR|9c%w4^!SBOSr<>FxCOiRR)b*z( zh97t>(gRxpkp2W%-~o`8gDntZJcH{vk~Mokys~A$7d24-4T+phQQ=K+UH|a@*WqtZ zd;gX7{@xp@zYcm|_C~u^s}~IWqaN*7h%`lr!59l!O2|-EteRd}`MM+C{~imZ=LSyg zEmmc9F-{+U_E{Iwl8AqOt}j-cw_SlZhei#UQ2bl}xP@)_#K?DB?av1J~RzjBQuNOan|Jt*x zjE@nyR#^+Kj&SuVuaB^Vo)&>+v<<3cs1(aI3^9*ox932EuK^>KxTAMNGGtXgxF1W3p?LJ^3*iodKC{?S_bcaWJRq%u#F zZE+n0B!rmVYQ(%ZaN)PcIyqp47Qh1O&d~%1v`0Tm+ENK#ExRX)(&7k)q*+m7wVRdQ z%nP{5`Bq2YcfLM|5Lij$K5h+bU(0v`%g=k{Pt^aQo&D&&89;xM1%DGLSl;IX6xj?@RE^ zI0x@DP<~?^esrK8=j3I$h8;xSSc3k6fA~1RgrL=MK^bZpY!;^AuxZH`CD~Xi1E`7d z_F6MO+&IsP9zuOb+=>GtE02o z@%G%u(~Vg^DLa@X8zZ0Y`1_kAfyPW&bvVJ$a}OpXVUh^7@ zAgrP;y*tTC<;?iAJz&IYzL?)$EjDFG61s-0YGXx%zM3aWt5reC*^~2P{^kt&+v31g zmKjhNlHDxdZcFpD8K(B@UaYj^Nn-9q0%?hXz~yiwEe{V>>#Pw?QKh%j3OqysVABQ^ zOrNwd)>u>~fAZvnr1F|e4i|qlGNugd52j=kcyw*!5iF)M0R|6Fx>QQu-6eVdqMtl@ zC(8S+t45v)N?3ajtJYxxg@3Pwz{bNXar#awNIIu?_g;L|cC23Opmbe%TbaH3W*pb&0 zB9_wSNGh8nLrE6&7ztpevlB!|5P?4QI;!7OOR*EGrH9XEcJE)2Yl1nr&Q}mkLsXxr zdKi_yfY?|IFfxJ2f^hpOuWTLBGe&*M@gw9VXcPF4&==ORkKuu$dQrI>tCXIOuR z@7CP*pQXcJ&qlkQv#RBL?d7lFkGp(kPCKF|-s7uVd-3yOm-g11dK(ka(`Z&(9n4us zKI$ibEm>eF&>#h`Ys2QED8NtAx7sV_d+ zx&%!(fj0_b^qn+{_wT1#T?}{S)sXS6_J2J^Tfg9jjMD(Cg`*Ig5w{CAnMmIx--l<4(%Zv4>EYy*{!J3JA-$vPmV3goZSpIDzW;6xwyTE$O^8FPU_~z5})1}}A(Ll1I@OZOc zF9Jep+#>D_@%#*Y5SP+DW|iy9KnX0_8i$&ILl?C`Q?li|$w?t1&4Xo_>jEQVPEj5d zE1b?l;d=UR^)gc7d?rASUs-}vBC~?@fRNJldd!XiBdH3 zUT*i1Z<0SgYS$dT@B|F=NO>m~6#`=79Tre>&3b}Y8mXPsv_HslNY98bY(=XC5Aoqg z{SjDD17rC9^c4PN+Rnr7=Xc4;`{A$VT?a1q8l2menz(!0A;Gw<6ONX>lTL8S4WiVE zaSGN7#zFjw^9}$o#Kyo z3mYpK8JZ1t+1K=-S}};#80o0KE^pX3a#nS{HaAvOkE?|sFD^1&G!!dnzR2j~)|%-C zR7+WZHnx(q3?z#Z$5280wf&f52P9s_i8xIcM#z0feNxN{6x*l8L}tqhL8u;MFUhPl z%UAhT0jl{qdk6Lg8U2ohnhVzoSB5rAdTI&nwjyK?OMhR4^8fc&eq0>BIdDnmU$z8Q& zj(QXx_7&pQl9?EMQieHdVg9k55I!{l2%8SnZ46iZoKjC3Z2!dBJ_ECL;?gXC=q!E5 zwlDyUap&r))-Vb6!y+8lH`11&lX)#|f1S6|!>JPEtB;lsVvimDq=-zV8b^TwakMd} z;nSP!R@zxraue_bD^<@&?2EdTv!X@&h4A)H59k9BIl+=EGmToR0>dRZA@-^IVG=th zhfOvr4M11N3^!Hf<8#)Cp6c%Ijiu0n7%==3H-4*O#=@-Upq}+qwb`MqCj9H_{I6~c z4)f=x?~P=dyLR23|7g+X1)DoX+W)YDw-Im}FKLD_4IfFC&|l|Z`? zr6~}{JZ7}Wbc_&8Y%$HxGYH( z5riSVhE#rFW*Lm4M}a>m&qkLLD3WC~E>Dv#Va;TgK_U^5ZA&os`FwIqt_MxFFcK?C zV+=D9V3R8Nq(+FpQ)^t{)@Vlf_#;t!qAi0k_%B+K%dw*V2a!%`*&3sG6C%Z*h9XGp z(Tth)!rHd3ZsJ4j;rbHns8)A#V&3}|5dwAFCVb_Ni;e$>wN;b!&t`2YGA5k)B>(+R ztgeR(O=g$5;z|@$s8Io0qom1JUzF)}8zDO116xz-uOC3bj= zwF9gAYSAGNF}FZUc+`%s-L$TztZ8YNO_iQh+YS8#xq}-{U|SMj)oKNg5YRkUUuPOa zBXy~XH<*|p8xp+aL96BXeWtpfOwuPSamZ}S0XXP%lP74&9KvQ3jC^eKr= z;2DMjJ|i))5gcawZRZjuA*I^_T>P$*lQG4})UbKgBoI!XI%iT}V;v~;QM=MVGZ2(! z`0KmT?rDu&@Owt3p%kBCTl{-mJCoUBl}RvmSQ%534o579Hd~e2NU>jK!U%IYN}%jHxz3C zLQ6G-=Sen5-cj&Yv0aX;W+Z|`~0 zuau1D&Jl@trKSwidCJ^F|Ddb+Z}oOiUbeKMqtyRH-iS6(h();Rx}KU(&%@mt>=2re z`~Z_DL4eze5SJn9-yT#oXW$ zF>>Qb;Y8wxx#dGEN{T0VHEF*#9y?y%i`q4NN*MuU24sPR{p6>`Iwuc9C-A%uV2{jo z`>yRRBMWV!qOOyTE5^6LZ%Y;iRvx^tGK5dLGLUr=s?;7K74 z3TZ`T2XbKR;U7sk*FCVu} zh@ot~UKN7O=V=7^({%W2+IceC180tKk>RNrU3zl-q!R})Ob;*;NpQ-E#6_u1NYD+H zyPxeXY6h+qaww~CxKnoT_!^5fmXi8sa32wLsfG{Uj&r^@PrI#j^-p1Rg9wsyf7FQG zx#v2(HP>uNU@56zZY<8%3o#JE@^r~xNDteAfO_UFhC1g2-QH=~oh*&!610XPU`^k?=9Sq9aOUEEYn#!=a z*9B@qcg>Lcugl%anKwn7oF}fIfTjA2(5wkry6#7#A2+33=%pi0$;*6d5HQTL?NhLf z)BVa|8D3*e1L4(^oeb)8lmrn*M4EWc!7&$A@&5}?zvzGh?Wv=xq1bJ+LSe_$CWBYqHV~#{mdmd}s)~wGvm(g` zmy7G#m=Id_@x&ZRil#0jztgTiur}FPG+cS2lz~|+O32|EJ5?$iDW#Vr3u-_-Og5X5 zzj#T9d)MfE<9W~|7#MfL^7rNr#vQVgw$D6aVh z7f||#N{_~xWsZe zcl^f@|Iy_?sxz%u=I8U@gasuwPwpw_2cEDAj^04^vXtts3T3XqbX=heJGL~kbY&Q8 zP!Xzff-V#gVDM({qmpy(XoW_TG;6_p2*Y+=ke8}Eim=C`ii8d!J)$9MC@_6YNfM>6 zvYHB+0h%P1vFUVow0ru#bK<|PqGZmn$oi+dlV0tAk4S%O;( z_3CD?^wg)xa}us^R*>8mY$fo*ZtZ0gR>nwEu$el0cUP^5Md%ud&5(_Lz7AtVV86X< zcPJPz)l(Zvf*RMlRpd35%M^vAS_On7m5wAeFOC2J&7DWR;Wfq$7`nPU|(vB0W)UpcoSZCUZ!bCvu_=r9;=OQ7uDZ$LaOLW8AHtO zVtOkijir;)K2USz&Q*LT==eZFnviA+T`}k54Vn`LaHNs_mgH*TR;WMSTrDC0=1&-8 zHtIO4`xHxdk*~j1KW(YI8If$@@2(F;E@xJ$=yxhzUbo_aRFit{;Vjobh&e1dbEv-| zcUZ=`!+U$kBREEs!H6~*pl0^&l7~XWArfGb?Ut-E^mlv24q?ljKjAkJkmaHNh zO*~Olb<{U!tp8KSbg#9GFw+KMFjP70YKQtq&!y&SRg9#r$*kr#6!l9PX_0hAkpze! zK3PA<2qiJ+hkK9^cqBl5PEHs(3stGq6Uz3sRMR!q30uExzI?T@L#wV=wm~L{F3nUP4O6AdAeXY>vV&g~r$H#TCu^JsM(g@d2K4X%a z|4fO)f-JSl0~yr>>0v@Aw@dJ6r!K`1S`_*|mXn4&Y@0Z~TRC++zuph6! zzKte8y0ysc}ndAsasRBQ^)rN#;T8}&?TS+c~hNr zQ)Vx|9Mu|Oi_kQY+pD~zetoicy5DZ?o~1|c?s}u$PB27qt;>_ANHm$~lnc}cP;oq+ zCr=3dlBu9nm?f;H3OuS#YgUX~M>Q3`#V9UdY9yu2_I4*HCWohkoN^ocCd_zIvVkqgryiJehv1=gb0 zT1^mgnXNAcrN}dZH2D_EJfN;v_;7|b>i^`l+>1u(7Imu}GRZj>q+ckRoN!|Og1)5? zQ6G&bfRlN5SHazl7Y~$-xfa^P~ zQ}rP&wIC{wdzoJqJ6D5KPSE?x?KbIfkAKFdk zf-zLFA;3e}hop)9b(DDJ+-AWzdxjlL<0P$;uHX=~5mS{+ct7WsrMX~_YjXL3n~C!g zU>dl_U`^mX8tHb}^tk>s)-8$PKM)1z@|^zbsOe2Sca&s1%|re@6wQEb7 zD+DZg=V64Ei3> z-uq*&WCa7}=&e3I7KA!?zJTE|jD}I_| z41fN0{${?op})UTmXqNyq172hb||lEt*N%TlNz>3kZO;ZIuX}9c63)>dr5?e2%Qf! z!3aPxG`*;rj^IklD8zAljy@pa({*|X-ik@P*Vb3_h(s^WQ}M2wJnmGn zH?gi;Pg=kCiBzGzZzRa{&)=o^bQ>U_LduNPMhhQtbP({Pi4$)XL$ z#!EJW0>KqC(xB8;F`dq8a0Cky5Y+_&N<$vS!aOvx}O&FI;pn#Jx-M>)k@uqt!DfbD z^8QRa>#EaT{L@Mb4bK+0Xh!d5;dZkT)n>^10HZRU+;>zGZR&;;5Fm%YzB^LRZ|!!c zzg`trRYR>EsTWe8nWj{wcWCU4sz^?hul9u33gg{KAJhgos_$qDN4d1f@F^Tb@B`TG zyGlGQ>p4bYQnGS0i$+%^A|od!wqAk~#VeDGt?7%_y=qBPUpa$2t}#Y%@w|!XixvfB zBMfvb>!}nJQ+-8kHg{$Iaw!{2#{8<7-42p(vhq#7x-Mp5Q}=JVSR~K~iIElObrwv| z!M}uz@iGbJDhEK&XB_fm-BJ#$>>TrDfFtD~5ISiNmPqF+0Q}iewLj%`Q){%m8%PM@ zm8@64HY0`ARM5@$^84vuV>-yN3Ud2Yb?!!OlsKf)&QRNVHt{^Ki3hY34G9p6f{F*h zPO_^Z2)lJxz+P^~O;9mI&Htl+;qRMVsBV8#nQ1feDS47r;cQkNm+xOf^}-}QSkyWV z`K`<_8%68%$*!iB5tQp0DRJkw9;DabDZWHrl6kda;n45miy1K{b}&bp5)_lHNh$}l zuI&OIfv3E-%LEUoS0L9+eF(1(YyFTfVrodbCuPWOkq zr~9M&{BQTqHrqJm13Z2l2ihq6(O99o!7vDX*gF{HA-taqjgK~w1(vtEzs&8LstY!X{EB;XYm*qD3KE!%5XnzEQZ`!I?W`;s+Z3Jav{ z_oI>jXBW%oL+oM`lC2@fIF9%$R7bJXXrv3pHggnlwm7?Y0*80^wA@XF*em|&oIrLX zn5|G&n+BOB@4cJGji$jG%J_E!hDYgRQ8HDmhqS#|wb`n|e6jVv52o5}-4|0IX8IJn zD9e9HpT%VDw3{*zf~SLTkf{Vv6h|; zzCM2c)$#k|uig*8I{tbTv@TYySD#Dc4?G^;bM3B~M35dxJi~H@7!QrqP6}re^U^3L zs?$8(tHapX+Q)4ioc<>L`o$MO%66yOpd+q4btdxgMAaQaR1g&TBn-Cr*v5V5l1@;K zP8yJrI%TFjLm>|mI4DZ}Am-$eS(28Jo)U6su;bQK8Je^hkOg&x2{Awg83>l(03o}7 zptU?MS_8@?PsHBv$!S_4&1#Aj=1Lo>qtSsufm&|H&Sst#R}=)fGEEc9(**NcmHVkd z6PW5LGD{NgV>GcTFS+0w@F!>!uM9$#bAdTiY~8jxd8Tep@&Y4RXvH@;L0{&OmQ{@3 zps=4g2BK)NqyMAGaaC)ENN%|?q`wFP ze=p^_&OLTt&AOVbTD5w0lJW?t4Ii8h?|eTH;D9R{jbKXQN(p0pCGy}-TKla;?{LvE zggM6?b^DJGmTx;UBc;5FCvpoRXtrkUPxptX`@0SFa)=O7omqUWs&lO0#973i#?aj> zHT8i*e$<$HhlXSl>pjS$K{d1OO@;DWYO=wjwv_4V?n&=t_*>Td`_tZkVLV*SVLOO< zzEwrFQlk__n)$w2m06spErta2O35Ygw>Zq-+&7-2?i2%0q^pV)Z>yy61fe*gy4=j) z1g3u#BNAu}4wWjUbr?16l32DAc-W#)VQe@YRRf+z)(bR2gg!wrrh&!*Ns?|zr32gR zycd5yIekaJPVYLMYU1=EqJop9Ee}BX@y7`V?R4+A_osWE6S+0EvyKQBg=_M4GRrW@ zx=JZ@NddTK`8t=OSLTbGesZq6^r{knCivd|8}V#s(rxtt=KM$`FwxeS?Nw$(!V>ge{YJ zvA0(RS}BdWhi?Luh{G=mfI(5IY`YJbMg2+T8RH9sr4Xx{RndXWQqfVemz2`x`*Anv z9d_chL_IjC0`z-Ek6=`xj!whVmBk{kVv0@*rPqJC@_goAc18peJZ9z%3 zdkY2%P5|ZPp26kUw7vij1KSw}ko5&3cKq0Yah*6em9pZ^!DSqUbEYDu+E)0ilqd@o#1O))v3_WQ%*=^rdOqhD9c;F}c#c!;Z>_VA?$5yp)_s znhd#OB~I(3tHo5Dmte^PmY8A?G|}SAUH4t9-`@uh_a3TFT7ypxy6_6{t~L1VOZ>4} z7qhZ8_#=I~F3JL8sEQY#iWmE|-aX7#ChC87H|l=!#bBtHZAAg!x&%g7g3)>RXn%M2 zk&sP(o^39~di|KqvkS;av%CKYW}IHjw;T;-EKQ7#mn;gvKS$=R0#lm)==aM-xfV-5 z5v2oPi+Q<*?9Nl_-un(4NW!GPi7A#Nc{+uVyt5gld6NyuWNsLK5(+(8LIUpO-BWmR zr;6dQts#S_`Fa8IK0*F4;OKdfHPuw0_Q8H7_eH8$kb|Q_5Jp)@)5gN5jY{gFURATh zViZ6)J$yDes?cmq{*bK2br*#A5?PR-p&zPbs&Rr8Ssj0c5{VlW*h>D8ryeE-ROWk> zK_j1?!_hd+DV=l<4Pm~YVx5$i7)xulnfKZFWs`Li@Qdu3(>Qu%O@YE>8oDYG7#5&5 zu=<4CazGsC=*?YX?Ezk3js}vVz^YiRAVpR$x!4pSM9l?%a3~;^wt71DC)_X}9vmEq zPu9D~^p1@G*q2(Q;GkK!!9R30g#19jbM7yT=W{`i)=y=GWY_@C2VxT3mtTeGgV`l^ zX?xFL6j8tO(5W=)>v{e9*c*X*941xmvj_p}mrFb$oUXdbK{t746&)mzDIDm(?l@L4 zytrbtxnk|UH^h;zoUCo(G^eA4*Q%5Y0i9)~BA5i#s<_V9c_lo8q5jz=^AnLjgO2ooJ_TYe)33?hJ?3u-uR3qDLXnYNcyqzyME zvUrH`(y&<39+4gUi(t6AG8*EK_J+Zz_POYn@2Vt~>0xz%vWX0?>=7m$g^bTtNk<@Li9o4ZKP4P_F>%RBBqKUu0{2^9beDW(2&8qA8g;lDe`){%`hd8LQ zhSc|pCSHnZt!hGjkBx=U0$?qjCcN(zQ2bjyhpRi_y~AMW0yXRT9D@y3ttgf7NQt!r zCa5QI)+0*($d*7A4ph{?V|4_sR8rXpN4(6!i-SEyQ4Wg2zq z5@dK3%@;GeM?eUcR?OqmCB*d>+?!H)HlS%v%@8xJR?wMRZ@Qbzr@_$8RUwN%9@VM6uL)faAP(e zU{MkVG#OL{0yQ0`n9o->ZZ)4ujn$31vCo)$4bN_3i@sgz(|n9pO?we#dADcH{|RRA z(}M>xd$qis=9ubPyWi-L8IGJo;Wx$T7^bhUUb#gX=fg^~x3LNiR~D%3l(6Y#lvN6z zI=^|vSbyHP{wiP2!1-YR^mPBCo7k2xcg}zoE*jh1hm9&eO`ts%;@xTntT?Nh0jpx6 zPSm%i0}jHW*s~fqRIv~o>RUA&3W7+(>Yg|DnRI_}JBQc6`@swF7|?rIBYHC$72bp6 zZv~G&j!leZ^$?1EbN80dtJ+F3&I52duZvq|4bOX&o) zugBMM>U$p8#OJJB-Pa&PwGkw;i;69Gi67F>^?2T#EGvS-sNUuZN|;sL6qmHkzQ z!9PlUw!yQ%U*J)I{+08KB)?j&Z)Fz0(pvSMpmmk&8h&SsT6kgRL<_)i{NR5ed=Hj> z7Wz~;XsL}l0?JlY@zD$_d4V6VLshr0=H88xvA-{dibh3X`mjIF=5xr7j@i#;3ZM02 zsq-opjsd>eHjxuJ06~a`f(g|0^`=~7H@L9A8WK(WdhRgmJM>k4m^Txf`wBO!HXA$$ zxfI#J(aHs&<14{_NfVE)XDPPvYC6+f_aN+H#?aKQDg?oG+B)^(HCec-RR$o|%+ zAa!kYK@d-uw9iHwDL~`tc z%~WF+)Vr9FvB!J?*++SK714m-7CQnEVh|J)yAr8@v7%UJwhGvs#U9h|@uSl8K{J2F z+-DwQSAkwZ$KcX%!2&r?q;*2DeetSStDI z8TFS|P!F77g%bCp9k${|NOyC%DUgV*t?L5##WqpE(Zy9{SKNKbaf(U*^Q#v>^@(#S z&Tm~=!c5V60VUIpYfGD9+2u84eO% zk1)Po6!Wy*b_lPlq9odAX($hy+Tlp#0v1mh*R=Zk>TOFJyI*U=NmfYPCCfrm}^`fm1I@&fX>H+dH5GhdjW+*SG!A`N5$O z|L@L3BjVr~=aa=%?l+*TLFC7@{RCTUcTE9Sgi@3b`8W2}xV5=Ok_d2isgd=Y|LSn4 znFW-dC#mirYgi1+zk~K`f>FSKSxM&tPA{qSBzTkGmaKGNNEOUbDQN!0JPD{4I-U3e zib^<*X3g^n7^1O|i?OpeT8()T*2T*WE)jmL&#oM7M~FcT`V?CmZX~QmAuujAU{+7E4|nDQL<}Ex;xF8lfNgR1+8PD)q)g2JEJ)_7 ze3k?ECfi9JmmOXlZUg7j1_l2D{H7}RP8nDal5ZA^S)R>PbMZl6g#4h}0yjvBa$Nhq zaC{yQtp zy$pWQ2KN@;#^m8h{}p|6TvF!T2WY@u1wbVbR+F`3!KR|@ApIBrab$gW(qfj-b}_Jc zUTx^8?O0n*AER(=i+}p?B9%K?9fJ-G*EOAAJH6^Y?5*D>y6a0nhy+&9W{ zh5|S)?v%Ny}IWj|Fv4#;yCH;kNU?VzT`?5$2 z-?v1kZh>qv$(Qz(Z_qbIK_PJ+|4q%OP6#$!SF349Sk~+`wt>Z&p(Tt9TXf6lW;#ks z%Q)B|ASBX+Kyht?=@%%c(pH9@FP7P)Sl=GEI*gVwh^TE({^uXP&LmE{+nRN5O)W!U z4qvC$iFp3u_%&i9#tlCI0uc9;4~4iY_JWJNaB|BF85z3ydwo%(l(90xd%pgmc$3Gl zT?O%w?qQ^tXX(i)jG}B&d{Te1uMPm9g0kPRvJ4_oPV$n8_15+a=$sITk_>n$LO(S* z@qOx-Fnd*fYlX{syUKB;z)j_Y_=U55)B9Igj>UlrOF2tMoEyuv+&c7~WKerB3wU-6&e}Omq)_{f3gS@!4LB&f^Nc{IGendSo4aPS>porN4`eQ3n^1~imp&ssc zcDXtg+>5&TR83(wi63c?3_Io>Yau}IkE*bidrA9PDSG}{2U`&H^-u*q1#thf4~6^d z^{NGmvJU6e5%)!OQFH~lBR zh3euh{L_FzZNP$x$p=WIbiw|pNdmlXd0*=fMvaFs0*|`O(OCy3DN9WqMz?7d{sW>U zz~Fd`5RO#*l`WUKV0Ne4m_QU8J|6YubU?I;Ri2d#0R0w6E}=^(M2G?q;-kv3)95f> zA59iGN3It*NQh)1wU_WJW01}S6FW%GO2{!S+D}PQ-#P0mIP@H=2p0JyFJxRP$*RI6 z&`;_EhvA@A-T8vi%n5Zgo;X_ajEVM{eG~{Wo~b~|Uy|HZHC=!WVH1l~@6m2z-Bnge zI9!G|?F;$gmuyx{Qw%LFX7130<@B9YwQDJB06mb|=1>o&Tch$j$CP(0=*BEvK7Bt~ zZYZqWQGKh9)#63~4l6ZCB!vKL%a@z^y12?)Ve^!$yezW|QKN-1f%pd2t9I5>eorc& zAG`@Rr=K+M%cdcO(IA1-#=IIp_^>cQxNZY$4b=_zAh?>^YDPJ3m>IK=Jiwl3I%o_( z1{xrYN1q?Slc-rtTlFF$*Mx@RQ{Wzps6%xD(1%v?>NxRW1_`!Rfu>z#;|i#5!makK zi4WRMQ~>j6|k%0WS<>A{$n?J{Ml#SEYaKRr}6V45{N`ns^Cwcrmu*KO}w^V`FEPd>*gam$4Q5?;hXnU$|GSlZe+K&ewAx zSx>sj;pc%nLQfQRdL{c)$PKz}hho1(J7wIWRPf8Y=}g{9QvfE2Es_a}ct~m!#Gg1D zXn!?)AiM|FzTvrM+0`<=27T*WM*#d0{0Xj#c}jm|Z=u*hhl&a)SS#zrpK|fpX`uZP z3J+DY1@ZC;1ngwB*vzM*1fnLJEafgR5k%+kb2usv+H^X=%nGUIm2^E&Gkn)!hADU6 zboFPOEBh+N3ap|y6S3$Jxo;mgiU#I_e?Ig+kNM}v^0P9F0d?^z`AQJy{=p|-KK>&J zy(>}V@Nxgk$6`b{3(Lh#nxsJqG5i?QY3VG?hZW(yeGn7hyUBF%(_;Nh z-HbDAP`Bl1l!}Exd7;wC>aSoiVztqw14GbsdBGyd>zRzveFkK_%-34%z~adb#G2Eh zf~q8=vkEcde6_d|gaDX>sjNaKa5AR%JkO`9mN*0iB#<0}dI0JzWd)i&tC{s;(YK{O z32DqQR(`hh29O2zTt}oW7gr#iWb+ck_fJrnnJ0_65Q1*9TLMtU$uHLW_$q}^nI&gp z2W4md_BvbOtkBpT*$0v2WL2eXJR{_K`0!!YMA1yzvrt(Z;1{t)R3m+ zFiq!@s#$UemSDP6s_~U=hONBRVIES=UDE;BOu#I^p z_6}XGB`@ZaTy18kwAie)$gLDHVzOm=7MI(U+KI_32X#h9k`>Mgu+;$MrPzho3N=dF z1czo5_nAkI1juX1uMYA2MvhIno1?mc???Kvo1}+=Ij4crZWN2aejX`-ied;)NTLD` zfVsorCa{OQ#X z|44qwe72Y6$QarQE>nEcyr(!wFS^MX*iQ@)tGQG4!L0TrhVcg-R0@skK@DJ69*a{R zFaO_)g%|G_EyB*ke!eoHX5j%Z>M}7dAFhCaZf9W6-v3Mx!>Q;aeGF}@9zes6Zw(xb zf|cSR0woP&y*23o72j%r00{Q2C&nk5nF93{JfE1;ljL*oCeoQ&{n{6@_E^+jsoIZ^ z68nkO9?RM*2=}ULe_B)fj!oRYkl+G{{VutLmUoj+K0gr4G{BV_B!V_&1Az+^^?QH+ z=`>qvZs&5nUJmy6uU;3gv&oxsF$b<||M9`WANLO)?+di*trxw^a@G@PaZmre?jf1% z2}wVn^^DNk%Vrl4+4S=pCg>+Cu!CxT+FgS+CF|DWxOYuW&;MQ2O6JHm3+sM`yG z>)1N2dz0-IZ4NgF?u~!g*4TD4d>Hh<9wgTm`ulkJv=NOTTF0Bfr;+0AH1!XY|BykB zs|`rsq9)|ykM$tmD$IwK6)ODlxwV;o3i`VqExy{%#9vWX_^tifeZnyT04?l zaZR9&L}DZJ0pL&5Q)FhYveg>{WsuqN#-izUWUeEIzUXCQb2rLGN;;rK2!u2-B82?dt>7#JEKpeWdn^L2~Pk zC*p*1b)(dQ$(IM(3iiz#!6cfC0CIIp?izxumm0t=0DMA_ZNy8p{ zhZ-tCG~m0w!XRSm*RlQct79jkoz+@$;I(#aRsZ_<0gd~he(g3MuFfY;HGw`HesRw; zuA{9tyBt4lL#8fAM$fR@Be8Ptog_OFy$0F_C`_#+?uNLT&l>yQPZ_h~9$13kSikLJ zSeI8hB!ywS(rklc#om$tMMunZbA`SP6dZ;w&)nn3-zl-`;oTz>372gj@AU@N!|P|I zr0=O1RKOQ9rW$Bp<FI%ZKB-%kyE{GU9yQW+ zboh_Y9_$sXjIsj3L3nf!$wz&gud~TzK9ww?ZFxoS#1dd&0E@F&>GJX~#z*Kl0`v!t z-RURF6h+Hv*2pQ*s;UF0$M?mmTx*UvUbZ1iWdEL(GykdCsbZB$9PXZxZ?0bJX9Chbz4YC6oByHy$Jl35t z7?qsskj_v02mA5TR@=;r^)qApmjnzUp$NNb(Q$YFD&E@-LrL{j*+N>;eZWx77*sw@ z$O=w{vw`Z$l=54h=RTk)fr3Fj2pZ>oKU;`Z@C1Ynft%vLf;Yi`S@e{@VxuSYULDA= z^6-Ibog_o}cf^&`(gRz=8z&Ba2}2gtw^q1Z!|g4H7}(o5W3*uc%{O!&gO;LgtQWrZ zYry$Ts=3XoaZgD8_b3kTcA6vgjT?A@an)oE3tM)KMg=Abl{xc^%`97`j+rai*uxOM z17rEL^`l^lz$5|@2HiNO8dfpP)ru^%)ORs8%E$?qNx|MvzR9NeYLK+{3>@10v18u@ zc)n;sOC-X6qZJYZ{zX=j&8q$3DBO22(xsRZ`uP=@_Q7*#-hG|))Jr}=U>AZOCgWTg zq8;YF&y##T>4)G@zH8qXZ}VyT_<-?H2Ydgz-vwsYzX6FG>p8IeSH4(19kbVW24toq>PJ9EOUd&&SPW^)a&2X|zF8Q8UMdqJDTu4+(&xzP z=wj^>*9i-ki{$KZ3C0$WW!SRYA{Ur;_Q~??SwBc4wlgr=-+f(Pf|u8PfpF_}IM47%DA>2uZ_<&vGktv2Oa#!qHyTZd_2b&~!9>O$1 z9RrvHBlQSkymQ&Q(;@+doU2Pm0 zH2v&?I$RUY9V)@OdEKgLZ!}WCM%CzlG71RlKXCB*}XkYd* zG>w8~D7`aiNZmMBp1oJDNA5}l9A*C+fYp*_cwJW zUpL{+y@Ah0x1p}$#0bUr@|1fPDetqh;D@7eE+#KIN8c8wp0EE?WgTNYPw_T5{G_Y( zXoF9`;5xys(!UM9_#E_u4~`8+1kk9~SplgkHG230lpPRN!Vk70hmTd_fdM_s9^)*Z zcmY@fR!`_@ym1m77`3j_^dAMj^)raF{rpO;1~V2kT|OYXi!RHrUD@3UX%FQDR%j2s z5=?t2zqP{U>a~Zl!%>c+=u zqniw|*2tEe!jK)c>ky^M9oDw{!J90LOgZsx>Sn~ETA{kS5GGd*kS*&hk~6^3z@p3c zO4J7kHRL*q);eI3dn7=F9W83fflFZhOFSKtXrhC+$diOJb|;bEF{YCvj5O~RYWI-? zu)5R{IpY1wld-&i->L<#|9GbjtSr&~w95~{xZR~fN)E1%nd|^{j#lIYS*#i=R1y4L z?*Ncm?7;+sC54No9*b-L6(t51;i;m-a{erHDDmRiTw4<8%x%)ZQfUU)+4zV2I!EtC z@7;S4-1i^`2cyzK?clWU9jD5nl@QPd7eUWzZLpxbV8?g7V|R?b9-~_9 zUc|%~_z8mj*u#eT6%D+~*RR&-aeX=ma}|n0<3d}GPq7WBB=J6E;5kU>*@uAtK+Gk6tfc3Jo#dlWp&Q<)-^o5koOH=YoD^%vblGIUT;RBW$*0R~FrWyu^4a#ZMy07%)4{eJ8!m_dp zZ#)O41D+LbxGpeolU8ZJH7FR2?dQ+Mhl*F!NZ1NOP#cn18A6!&MNX=+kobaE>?%o- zsoJ;RI}#12NJvQ?JBv~^S72n9l7iE&7 zHF8O@gdp&DuzoH?Yf zZR68r+%2g?CoB8M7713Cz3mA3v~N{(%g!M7ED{_%k|px7EI9hu8+`glSH(yt=iu`% z;eh@?F`ye9(DKx^PiG|4`e@cU%zTT%I-g181p_CUa|zG7kbppB-VFFrKz$*Qt|>IN zo@`Sieh>wUn6pTKY(+{wBo6`$>&!0qg55OpkOGYS#U|Rt99MUJnU{qY8zr64hIjP) z`TWJwRGcn0Lhe_n!JKp`Wjkxta*CJx)GCmA`WANb==7z5AYICg3UR>X$YZtbkX>G2 zUX^Vsrop-E_#BlFo0rMiE(XGcJEP7Am|7P$dx8z2G&AK-gxz*Xr4=SqyuP~@wQDI3 zjTh(j%W0;-!6}>-Eie`(gj0DjhYNfP@297s8Ue6K%HD?z9@yvjW@^q}#3KK4^azLk zrA4||>|fq^g`C+6#{P|s8HwrBo9tE+b5BF&(<%ncc`*~DRqr$tl$1^VPI~P~PtcDJ z9U7KL4Xph9!-Hk;>6ev<--81X>w^n2LGtOKH>qNIRGL~TS6Xvb8djvVxDe^8D4mSy z53cx&2v;Ol{8mhHZUBt_T%e73vA4&HQ5+NT7IR|SHPw}>bnm0Ct$ht{Z!Jh(V7t9x zGk6*IO)d~W_o$Lx=;`@7UwLI5cebFHY@nln6R6*lQ;2mX@t)5Y?$}4_W&HHFKeLk` zKC}WQ8lLzJGXhek`l^n6r;lxfK|)rm)u2zTLSj$&aXUu?oCoy2ZGWKc7cBhwD=lL1 zzO~?Cg*_3)CEx5Oi!GSZy{xKAh7()r4r27&ZHDc2ROjWoc~t{!UpJ6nRAro)EiQ@) zNNDotVTm`&VoGH+!cYno*4Ft(%y*vr<;AxzAfVXdI#0$6!IxmGCB-GTS^!n7*fA3C zoRdbHue+mC%ue7F@EWf0B!ldDw(pIq+F^t4_)MSMv#ftAyU5_o+qzJNj21!--zBQ_ z!0zX66g!##PlKM`501q|IEt>b_Gk2w)ec^mZJzsgt!C=mzi$?6yfb2-|Az0HS&mQ{ zo#VrQZ$9Vde*&00!7T{fRlg-iD z;3h*iGt{pG+Je&S`bY{3(l=v13L2?e2hdn8mAmjpcn1Mq=C#qfND;4#5At;v$ z4?CwItOX^kNg(?#){v956l^X9gv9=hgCBa?f>z_05YOlpbI+Jk<7WIc76fd5?nWuj6CsFf*Z(&w9YQXRwx%#6vGt*ZNijMYO9x!A_}(V z8lxRgG20SABV9)5&Q}iQ`8+v;4rm`;WujyW$0qER=VojrgbOp-s=APnX(I^Gbw0ZV zcvPw^v2`{}Zx|(-KB)4*)4t!x3C_8~2qg4ewbd+vdn$?8-x5}GLhqRZn#leiu~R?Yhw57-u4feA%=6;v58{f{WY z6ad7b1QZ2kYW(ZTXlsHOs&C3_&=OTPGs=wX4Gj{Hk%?2_WaJ`;M0MSx!R;DQ*>UH? z7pfnfIBWuzHWQ^4*i0SAN327*c_YTK7K>G2xB;E=?=xy9KoS_(T2N{=Yze0zP1A-2 z2k)VBgK>v+t*CPsw1}5&98XZzvz(|xQ|hXnRYjLZxO|2?@#=xF4^v7HFa|vk^?A-2 zS4`F@4m@!rT2(z3#i(>)N?*!46^w~O3@r!h>D$wlY;Z%aD^?2%hB>6Cm=%A|k+CvG zf}4Y8K87E)_bfUNia9myQ&g?GCd&@?*o3ouQ!L$OmIepq{knBgh zW%Hx5JeZoUi(Z^}rtCgqq$I;*!eb>)n)4f@EbGuuD&?T$puU%{@46H@7yrvmxES%* zb52oWP^3*_DwYnO!RNokt#^6(Q;vr4T;PX%1O9rV$8GLczn8bCZ24?UDDuEgYFBZZJP%1DE zc?5s=pUT83O5@TN;K3_k!mxlFyQeLEj&uR;@WTpC)oWAGi_pc3%a1)dNL@>3zOl>e zz!D4&6D7!kLj{pg1)W$$ZSs}UpG`!0Rze0<*M)vD7VWH*vQXE>fyz{@Cuo z##amAFQ>dnG|L%KcD5O1V2CEU6OLu#l`in->^gge=}qiXChdvoRIJ3s+y^ex?->@E zsKnMVnGGl2d}`j9oh9BQ6lz(;Z-hY~0OG|Ttqb|^!72Ve z3>>0-fyFz7P*Fhf`%~#k>!6_c@)>usWydl6i91yM_#^$GLqYroTY=9T2M+&p3E>6( zYn#_)5BQrNzrG0_e%4wyzN%?-4TIou!o%)J(Sp32h`Gv^pwn!ixtC={JMu54ZO{49 zLX9`j>o+qDH$(80pl0$xbO{yI>QM8s6)EXRa+M*)H46_aVbfabOhz{eiEw1lPi@)B zg##)a+cjNQ@+FW!n*lEY)+XUt+HQe|jvUusB7Sxgm0FOmdMNLL>E6jVO;AKSHnN?} zHYjsiLiWl^leA!Mu7&i;zFC<#Tkla?Yv&F=KeQG6CeZ2t){ny^X-VP&2hH%uDFvnYMa=cX#AP1?-!1=({-#dg|P~@rdMJ zS>N>cU2-LW&Mxvn()zy^8_XZO!K-33%&wJ}HisaPB{tV@*$xSguEABvsn2#L+#mx^ z_UAj`75sWSH?FV7<+kkl`k~ z2t@UT_zLa!Wnpv_#4LqpEw|s6c=ZohS#sf!Dt4x4q@coJ)^hDC;B{8hH*f{0Kf9_u z{lQCl=IKl8Bj`9AbNEK5LmO#{i$BOE4GeI@H=~%F&wBCaSA)Q1i2HEGPQaN+dPF$4 zRy5PruZYUg##DV|v(1LC>1+}{BwDr!FXu7{{s4pIYdkgkeApVn?rybP6qxV##!)u$ zEImN*Xh1?@od%2XYkqrYANS&;(zXe5ZGLh?{g9u`5N5`dwhi;aURag9)))bKvJJZc z^E;~Xwt@C7e2Q@jdLn{;uC93S;IR4fZ1)o*8V8t=^9!t}tP?%&z3-X_mS0+-GWWOw zXFgMZXcNG+RiHt!PhQ>5*V)@vmu;Qrb5W_7CVxOX3DK?$DBcnSt54*m!T!ri8~Mvu zX&VS#n+^Ya3<&EKLWAJ2ir{~#jEuhd-sg=&w>L4NbCpF}6qVn7O(T=`Wto6dkc-5P zr9|0dNHJ*Z6to2EtC20`ghFhkQ1T+dn@f%cBIg4HM|~!j%%+nh8i)p|Ej@K8FxRYw z7%2gB>R7YT6^9I}G2~Yux-02d-Wj49dcsMq@jsYAY zsx5hEr~^iT1_!fmZqbO=^IX)EX^L95{(b|t38h~>@x7dFo|Og>GZu&krV=u?pFw8Dwm6F+5Hgh4nob%iXA zhyjLs;_))tAZL8sZa~Z|A0o{ds2Zjos#=tI49x+KBMzyo&4zr)If7Eb z<6_H5W67~YbKUr3`a?LB7mX?wqim}m7*UMb2 z;RXRUuRx11qak*{t=+$Z>^O>T=jRjtGtI%p zCe+eV^!v}oT+!D&gjRv5W8Fd&Dr%D+fwZUe3AS_r!{cJqF^l%y+x04w$$qeO4^u}b z`g*n$(~nsi1vp5O&$?$x`r>7$A4KG(IUPJaRsuYf0UXuGI2`m7_@s24K)m$}c<4Kbp{&Eb?2D#Nv;N0H{fMm+5GTo|xu zxkUYLfd-Uzmn|_@t&T+{UHzF8NP{_P+;!N7`W~ETGBmTmdo#KaQcgiKxs-AW>OXQi zP$Ub)hT$kI_sG?$9HryUSg@Im+_F)$GVd5lK3EZVfR>xcuRPQ*VKp{=?I-qym#u~Km@ zQnY~ys1QF;boXY8zaPOo#~8)gg+1FHSxH7-fSWw4LVsTYUhc~>M$HFpNrNnQc`QAp zk@c^LAx}0*nIWFa5nBz>;-MYiZ7i!r3sE?Q&fp3H{?*Y?PVgsCTlDDBH9tgrcnv?a zqy8r9rRF87r4N)a>OA$W6)v}h!cK>caJ4FpqfHnppc^#;o!cs3kC@_)iGz$O4-B)3 zYXu^+Kr#GR{_``sCll&v8X}ICE4K&A73t9lKVHo9?;$}WRW@Aa zM4XnzR4_lPJ^i9<7{{09ROqT5^-|i?h@W^V@m&GFsL!%8Kkgl}_*wb+PZUSv0L#it zjzd#X{CW(1ZRVgbToo6f?|G@5OXiEGYG%L3=sPNUg_=Jh{Z9l@_%}$Uk-8J+iXThT z43ta33ff$V;Cbl$ITz>8WATrF<~Y+aJRf;#F^A$1SDT(Yx4yviEUCAp=uJb*Vo&&e ziL#+%FfjuXE$XI*OD6@1LUmobkBFm6SV8&53 zfOiX6Lrtc%xx#RUJg}trYc+o`k_o1*w}&Ga-bmdYA7H;OJVu@86pjd7YU>U3zH`SH zV)W(ibu|ul31|CTau*&`$1WLFK0W%4BYs#(>Sago5;7dfc;W!~88Eic1_Fwi_oxV0 zmH|N&9V%uJ*egT~QKfWo*Ge+Pcw9#@TcQ0SY!2AcfY4j`L4>4w%^g6eW3((@!Zkzg zHHEUigEYLL*Z^meT&0~e9*)OoeS{!yxGF)PK`(RzQ8un~OsLu_H)Bx1=Vc26p7hU%3L+fIbt)|KD`bMz4yGcqa2@OwjOt7D!@N2)v!|trpb^C&n<4rM} znqw@P70@@dJ%Mb<7`y}{n?R^n2%D16Wk3f3;G6m4hI9lA!4!i|8c~7grjT8!;0hUC zP>4yI6ljO@$ffmyfDxixDPnIBFI zx8294c8-tz6QF8Q48KXDyZ#;E3nCK(kK%g6tLicoQT}X|%S=lSqqjlnXLx|>rGt^j zzFAwE4XI{ZW5YvJ9yTjZ<4A=yjKECX0#ueK@+d_1+2}OK9y#q}S^Wal{}P;HnbKZ@ z1Z76aUZP)MpMr7u+RqEF9^0;}{ZiB{uJU#~e!4ceYCpXi7Z)2a0fI&=l{i0wB*YvD?(Zk(+s{rxIx&fOCu(1TZhQvZmJY zv0?);2d)3fAWW1Z*_HtAqfR>;JbW9c*c2_aW^r-=ej|5FeY)H~p zi%dwUeU&~6xjQ_JBLvWD+5_v@9YDMh|I|_s-KQ|Ev>?p#7P=B7IR=6ZEsx$3~3!R0;~aq!#V)uUl1g*z$OtJD(kU=H}zg|dBC*@N`Z zF;BYd-J~8}aqn0vHDD?Str)tR7Ozd7kotyMVJ|gZj0@x~v`$V=Dq+&siWg4cBHOKD zfMIgQ2s^FFMV4A$lYZF0q8S{1S?Q_Gyc_t%72H)dPUF?=HmZq1dlSQXCn$w-8Q9QKx6-1r_rJ{+ zi#MAk&sb08X+fr@N%3Pd$y0s{g!dm_1gxDU%`R}>@=tIdT}lrUW>H8|DMken{P+e_z!lmqMK~tg?DURX#P>raB{$Q~!E)ga2 zutXhZt-UKijcKv_KPupd2HnQs-$dOC-Ew$%9n9LMDzbw!I-ftQK?QsXkivd9zgBEK zl%GCzuSm6L=6F$-mRBZ_8bp*N6i^HP%e1$mF!dt-%MIWpczk`deT3O1-Q+c12Ph&^ zl)%eO<#nfM@;MO{=;8-y8G}g?ptc&P1XGdAJ~+;$W)g-t7HwUkKFCd>jfTho=fb)| zmRBIiPblb*tgjje&Bj6W2UoL+t^w=?$5}ugGkGWDJ?Ao>-C8d@Ul!!%+&RrXw zk|pA6S7l89hhkT|iPFvfi~g%92vH4q<6FvFI3Kw6bI`MZJ6$u4TxnqTud@0XDgZ`| zD6qXOH%SrRBowYxl~Bx12s0!VPHd+s_28Ia6KDvHGSxHGsA8|nwn^uYgL*v*?xeaU zLQv|qsbk+MJ9lG2G?j+PV22URKs;GB)8bQn3TDV{&g!TUGv?$A=cEPnn|2CQH|nH{ zY;l^(6-6MMT;{<51rOZQH><_`Lb^m_9tv#-u-*1f)&7>}CG2i!L2FWoZO51#;k~{+ zCc%0Jro`LMw6bwcleKUC?Wnf8yTJF~bdmEgw(shVT@(cBrpgW_j1w6Z3ARb(#5Cp_ zExMcq=u`a?cdhQE__~pTPY7#;pc!9{VwkQ={Nj|?W#Cb{F zuicy?wMGoHP(g=Wh~vRiV()5DKx(y(SQ@rL7v%Jyn}}aLc)v}5T`ril`jxF2>$r2~ zJn!t$J4TqS-LHe%oGsh+I35r9)Yj|uFdER7ozS$+Fox}q=z~?vSub72)O5Jnq2pcy zD-aSncGyH{iHPSqt`P~;m>q`F4QK@>t6q!I(iNtx0rf&y9&_>CyGbw`z+5G0J^0}8 zps^cFByg*Hv+#lPkB7pIThV442V9k^eio#dDf&f^mhxV?a?UYKl$cLdE$Zdr7tq>V z^{Evsb-&;xy*5`v6LLi(k_6#z6kkM9XP%k)olAU?7tjlpws!?nGqj_b_6|E;2I{EO ziO05Je6NC7{my+*)Som4!!2z9>m-B_7A&vLiRcF>-StAgI^5qEtDLm*Wm(L`1_jS_v5_HnAL&j?%KLZN zKakI7iP*AmZi#~ow5BEd_UV^je%TjK2gAiKF}UXJHbMCFsrbP0HD$0K)8!2Fr~e6i zPs!0<%>U!OclbG+=-(G_^Qo!ZVWTh%D^(c!-1ImuaYtSJb+)v z>KA_dTKxhe|J`hUyDQTl5?sIW5zA;GYCO>6Ab(7xXBwtU&gzWAchBeI; zs9=z;@j|9$ZI!oILQGf{6X_#dw&49FPms>_Aa&F z{|)ilS(T2TBYv6*Mp)oGYWjC<&;6>dP4^aqa6pkFu?Im6a)FW0YIc~ODFHUlRPRvt zFklmy99XZ#Hlx>v_QVER4;@$(IEfFG4cblmqq9+L%l&e8ngxAb!r3Ff%%`BaD_?>5 zKDACrjGD7pN&~SY{(Q9_D4M&up4wTRgwf@!$muqNV$;J>;v5Td6gjE)jqym}@p1%2#l#4{Old2UWtY zPlffIX$jEE-V+rEfo3;O-c}RwS*2pyM$LeAqBPO@s_7xVZ~5Qvr&>t2Q7yQYJ5siD zLD}N63#)D`@nfY>MCUIW=l7{Tg15>3(=gqKPX1$M>*=Z#nfJ}vlj=W>*s>-!cR!tv z!a&(4Fw^Ze`;O^Q63q0|pIm0Er|Z-*fP7fOADV%hWIt{pjrLLi2$a|^#Q6@NzzBUZ zlhHU_aCMOL`*qIG1#i?aL@WKXtD0gPjcqTy1xfeQvvm0D*=VnG)_HHICg}v%suBCc zv&HE6c&6_oUC^X_c}aN_q#e1H6GiOTfS~dUvmd3H=_HV-NmOFq!E*jg$A$Q?S}tZ8 z1&oOH?V1r`5|BiNntN~-mRKU&^g5LO`y{#6!2z$GtOwE>ONT93<4Jg(%dx5G?5q3& zXJ%!F{QZ35j!@0#RJn6FWKoQb8HXMT}T-Yl6Bu1qlWJznAx%x$Tlt%+C59OCv&Hp~_yF!K+(6fRlYsJ272Lh(n?AX%;1vd#oZ4$rm3i z6Ipdi3P0N}%NVH`7wMkkI?Bko))pOIigaBO6%I3mceTAi1OFMd)1=~+(Z-*Uxi%VF z69ZJnKJ6R{wDqd7tgeFh34c~*F()UC@d-tQ6Wx==t$w3C>IODjMIpeCX@WisJH^_7 zS;a>14>2rujcjZYh(Xmkr|f)eG?Vm&>B4ZOB_oJAfY@)r7*dLuCvC~4KhhY2F@Hr- zX5PZiQ%b0%`~@*y+gvWa)GZp3UPc%_PTpB}V1jiPtz9bzz4GWz9fXcqvTqjv-M|gK zeK%hz@mP9Dc_iLFdIWe972fQRnu&$iE${37@4}>wx7H5&*e z6{Mi4L`d_4e(Sc|dag0t^mN3&YA4s@YA4tu1`=q2taII+60<$Uyrg`OVCV)pQM0VX zTpj#AN=;q|wnM80{+dUvW|Md4t!Wc}IhLfNoA6m7a*NiizYxu38`|37ObLT|L#Y|q z=`A{`TYPoIsV>eExJqg-1=%VvZ8KG&kg2m<3JtyHRo0hy;-8E8%f(*%@56&X;I13z z^T{RnwTnG0rf^_wIG{Xif6K7Emf}v47YG5zD6%}E?6UBjB(k(-jU!aYwx{8V7RVGy zjA@=o>Y~J%#8gQW~jDQg%s1}j89cV@MvbU=BQ#sQ=M8nkp#{-DU~N1 zmDv7tGuRh6=YIbrK>i_SnPR)vFRti{*kn$ux)r{zL#dY88j(HETKlkA6}xD7i6IE3 zOsC|e!RL>Can3{t|Kh{t+%2`bFb}lGSTn9TDThMdzrEm~oE?@>E4| zjo-3lZQM)&UiS*|-o;t_Zp5Uykq$RR!eoL)3ypc04gEJ0fVT}+Vf94UA?7#VAa$D~ zzA;*%GCHlJ=JG1aSg9ZVa$ALgSYKKPM?AuVC}`=fnNgIz5?NhVi7lg2 z)A6WYUT<3`ne->H*@Z_@@~jy4D7pq2tu$iKKv`zO8y8*3S^r|5|18dLAzZQTEe~pI z8ccs6GEsA~YyC-0izRIESTxMLnFj;KT-T|?tlLR{t#5{bFV-NJFup})A1Yyt4SMaCoh6}ki$|@vyc(4 zjJ_UQMnB>~$h|Zel@*J)%Io@mST0ZBe^7am+0KMAm4@Tz=(!d8blE4FjbFJ-gN6qW+Iy0wnuT&jFf7qd3 zZ{9qod0N7-4_->K%8GUZN(xSsoMuf{S_!ftZdN`~er71(zmuv1DV3HQAPcMBzYpUF z1fEnMf;FhRp>fzz-8NLjd6F;}2TSm&$MNFK3BtLcjCR-rWvLci*}(xLl^DVi=Ykj!#1n{8yG zz!H>N&@lYavSi`A|H>w^*(%Sbw@`eQ_hEU;0+K0^jD}IFF&z$kjb#a4(=Yw zO@=z^7PZhaK%B1@S27YIjk@A?4IgFT2SQ zA`qFpZOEGj8-Pu_cWj>;kSow;THGQ%r+}sh!I&qEr4M2=m+XHhd?w)kxmca8fqkvQ zok%dS|4p#OIpZ_|g{u@w2Z?x8K|`a_qE=G-q0z(9n6FSr)9iTJ=xEL)(4CmSS!Qp1 z`A;95bh(lf4^as&^T`_+Gf7ujGAT=$G6r*^5_ho5uNK$&)INux7iUud+X&kN#$R$F z(tZ<3ovA_OKuHMB7c;sslYVC(181_z?MpiyFI)Enmv=?^=S{grd)~DUjvDrnw>C#w z^m-Jw%_|7e_?&E-*zd|(mWoJSQd&`XgY|~5BcZ@42*0Z0(IH?a<;Plb6d2{+9_4qH zO++(C*$|P_2f%q|DEszl$U7uI33-aY`RPB%m^3rG?H3=(?2eA%+cmGW4=71(} zy|bACqGW;^9f=9p^HOQv*w29KO+Bl?DHb}zSZg7EtJpgZbm*Q_(b#M&i(GUe;Ue!a zrjUV0hBm1>_=4CHyDy7fmw`gX)fqC?j2(MD%KxnFeq-cC;k#XW>u`6fnL5trt`k%Z zMfO=dIFB=RI~a*akX06mM@1wMEeo1913QA-#RjD~d1z`aA!b3#=n##8u|=#X*!W;d z^vc#kvNO*9sd0G3hyib)LdzHnegth;P4Ku?y7o@Eh!e*Oo`$ik;PJvaH2~L*UE?o; z*?7S#XS%vkTvBrEW&r-}nt4RH-|QQoVE5MnhYHiXF@rJvc-IdW2s@VM_1#@E;CtK) zgMOKnm)*qM?6}cg{=yb>a2w#|OjtL4IV9N@8RIJQr|i9@-U--UGoXUJC~-Rj->}9T zMMYanN{dJ~JhF-Q)NQ?7Xc-_Xv;NzR&|Z6uXJGEwgvIy&GzFoM&Yoc4N}B zt40;3B8EUz?P7-$BZ9%zji825ToWX(3h{Z9xsI6VnJ^b!DP0B`yh%Wj$b?p3`bCjM zUjn;Gpn;`pt(7e^gxFtQBQlLFq@^{J*mNcPYfd;b#|Rp~b?6*vZo|I09nv(6j$*tP zWQq-14B*}BIhy~ijSmaFBlCcB;2z9P69-;r6Yo;M>>nu$xt_o``7JXsFs@j7q)?!k z+h>gvC`i8_iozp}YG&{PXVVVk_4!U5foXWg`OKoB8jQx{mYb>#-875@La`}*%TZY05<#tHTWjd}&N;&?uM=#etGnJ?~AmfluE_Yg~6rJ;6T>H}w*H zA~+^FemyrFRM3u0MB?&sSe}1fp1!QEs)f9NbMN4GP141O?gC%C2Da6rz}jeGQ=;PQ z&3YxSnx&TuIJuBvPcn!{#R2Ev8WqJz7$ukzZ>sfu+SJ?Ys-->Nog=O^(?Y8-Lh%>` zun?q6y+9X(4sLmQ3$B3&H($DocC(m+q7_{f>@{#{*E(nnwPGFVhucevzRi~$#F+^k13!!fS0?Dl~Ko&l%7K|r;B*KICI5<0c3 z`XKHm5TjL2GBJwF@s++{!d&LC*6-frwnb1Po#)g}gZ+Ibe4WL_Ht{ILZ63Z5RxB^h5bl5?Akv~t z3R`Oevh%!cc8myYICFNghU;}IZr#gdN z9ANQM@Uf;0lv{t%FkxY3BGD6M5#BfLHR%2@JSW{c1MLCbvGc$SPYmF)@XU;7jpoUo z?g(?cpcJa^twiqaHxnA3IPS&>9A%inGl7stJF|xIO4`BD?X8l2NZ^<+G+nnGrDj(r zXk;51O{k~o9FIEQadgU}?$F7rfHC6@HgI+f?XFwgT@f9H%tW_4a*#2DZS$>h|3s;^ z4#+?I=LR$Cjy;-vD@BIGB0gF|@yHuT2KzNsT)EPk@+HQ2pujp!me^-I9E{Khk0UP! z;!fBNN~Er3YWOE^dXKj@fGG_#ieDbCQMYYk&TqG_~ogmXuf`N_^0wDI0Taos`! z4D0cNB9g8AH^aNui$!s|sTXtLS2xQkyhMizbO2cs%M1bLE7;V2fMo}K@92{D?9B*U z4|=w}oZb{Z;}yM?gbC(zd~)(n*zypnq-|{Kt(84v{Bpe87yuec9sm|uggR1z;b1;b z%)_EZqODRbhBY}3Zg%zJl?%!%w36{5ZkB>(sp#Qh;8xRuAZ`UUN@^>;!$dk4K_pM_ z;PFuiY=u|N+t!;S#-~SsLJ3Warvdi#7!+c2ZjgDiO7>egaVKx{t)J{`=+3W0M3gmD z+gH+CJ53bomdobGE{t^*Hh}-!NTuf&7}Eu8N7%&%U7X6bup-`c)m-bwilgW?Lb*I> zCxVhIP$bL63lFI$TK)mi2O>y&d0ICmU=s`lP{)9R^^+hMgLZaFD9bq2Kt>ZrJrt*_ za&Bjq>x!gm5VjX>r$+MwN!sVeCWkPi=^i4i}69kcN? z;A0eN@=iB+3Q=%wxm)?+^jtWCUbLAD0-o72_Q9?5p0>_=g?D+Mw;PAYv8GF$N zc*Dc{o4165Sa;fKst=Xx<24cR;$Br_>+N*@Z19xOZXe%zU-Lk1*!wWr= zwrJjyVaH4GIw1#-FJN-nHX=rUphun6cWiObNWojp6q>EwkOUW2?7^n}-0I7S52R}z zRJ9S8!aPVmObroLpbg15T@zxF@f;J1Kr-d$3fWHXMqLlz9XslGZGVy9vg;x#qAyX-{VfL?4E~V3*s^4f9oX{%&9Gb2KV2$2}WdFE>b}Q!9hdQ z7#%v1beZIhZIYuSPB$?m+ z1cmre+u;;x|EtyCF6uRqki!;Isg411+jE z16ByHORmAw5=p)h$ET;ewld@DCCez_ww0HHwpY!33YAR8*h*EXDDIho8l^tz;Y5Uj zI;ym_^I>+T(i5?AvrR6P_*TZe7nYmxjZ&&g@g+#TUIfO}w!hs%PDD|%=M<+|_;!KD zG&Q1NCTY2dM9(06=f)^VWnm~mjO6(N}C#;Hz-bQS_ zRw6!P91ztT3q{O;2Hp9Yu7!?Lx#*YK6!Kd9$HRlKCt;Mw!`~k$>E>k=O}K=%iRSHk za%TBI{_7{o&!%2f`psZwRW`8{WV#QE(3S=aKm8dV%lm4^d(! zd{5nP`F$ug1enqU!7SxaizmUzy`jUyndWgyV-6fri!jQZ>B#X#xmcKK0T&F@ej2Hz z?hwM#Q<-@5em!!rAYEN)5a3&OtCY4aS2NqXudlYB2fRcDC1a_t*t-}Zwb4%kiTt|% zae@Tn=*>f)eJ=WPsG-r3J8;Bd$9R*FD>*=CDJI8^aSMxWBRtEkOXCn@NYPyzxU7H% z_fCsQEQfu=Hb>6s-&Q)xtd;e*%H(0f99;m&pM%RrZrHXlB2pFH0l;8-R ztu5=|9NJoHiHiIZ-(Na3refBN5B~TDt18amHojqeWW{GcRL>eViK|g@r5TM9vreai zQaBF#Wa6XP98owJ!%#R6QFNIxvH~ub*;MZGQD4;nx>{5SM-1HXcO%FhJs3m)j27YB zzEZ${C6x>|tJs*6%kc|Hixj5LvOX`PU7I}cc=Gx0e*WU;DWo`~L}wqyKmR=4-Th+! zTzdUzR5@6|$0y`&kzPl8Ia)@c5la-KkN}Gh9qCWOUn=cj*4ImmNu({CjYtt~dKq;g zTp<}*DO<{?G-0D2S#q2dO;!|Zng1N294yR9Top)c69YNr55mLC8vaEgCu~a-Z3RQh zRs;uaMEx1vl;y?rByw{IzEAk%#u-nXYhZ?1!)D!ILBnHuFB``fS`QL~2tI*Su+`z5 zTedrUByw+_raSXw3}B^N`tQ1x9mKFvu)U?RXR&j~1gj$a#w^TsvA_TJ)w5T{%n(~6 z=Y3mrOSn|!l!aZ}d@E0z#BnM<-L%7}auM~zX~&Ko{9$`r+8i@5Xy>Xi_%5)DiWut` zo!X{O)Z&yS-sH$qmr$JO>GhS(TwQW4PKxO3Y|%D)5GE1G4C;)-RdHaOB+!mO2@u+Cb3f;L!=OK_4c!Gqqac-Jivc(Y z>OKg;zF8RDqicv2Ttb%Sgocy{=z`sFo)2K_FN#aZG3(Aq`T}DUAr=apf`jQGF7jC3&`J(NSVC$o;9aeu)QI5dh8g?*Y-Y+yEmkb?Z` zqq&m^@x_RHP@R`0mgGF=Tn~>7((aFJR%B7t9mhc+B3DsEvcUw%@`$QCo6OjId8L_w z(@yHpy#vsa>T8|&w$0DKESJ^lyRxe|DY35_e$;z?X_E_NH}SudbN!fm#+Wu%)LZ`g zp}PF=-#*mMhuP(a%gYbT*@xx&L-p(aZl*tHF_G&ozbhU)#7$8_#Q00Pd}Fuv0C$me z`V9$Uckk11{jxKNGzhyW*bf(2s6?ORX}P8nuUh<4 zJc-*E6N)als0rmvsrjB*7yb?p{$&!0qJR8U;`-~Cv4Gxpc?(f(=Q;WPF1M}no|O~A zid?YFFJfq>NcSqV-woyY<5z%Kx%M3vRL^Lz6PmHhv9wT`@Wiz@{2q=r;T-dAxFwU^_s|pf? zUsXx_P7xlVkW+`psx>z*+Y*Ktu&s$Z0E8`tuQCIcYF1A29v61Ws5>xAd(9&ryUM%H zFI#r~5WfFo)2>zPQ!!2ZbGoXQi_*yU`^P_zf8O00{oI}GpHDo)XG1z#=3w;m&!b29 z@+e7#5)v;lPv7$+|5|0VWF-rNrd?f@i~4_800{ws&~gYC-C#0?7zbEX4FsGG{V8pW zrrc8zr96QkAtOsu|Lf=O3!sgM`)Z6TN_e}dFKc3be0?M;ug=Ch-|mnMxOV_SHonCm z8=vo_#2=dCp`m`uHu|WD2A)=>sKZImzcW2Q#GZ3!lmxhMz+#1IVB&`KsDSpAGpo;M z!nbdP|LpL$I`*Xc>h()HF1D~ASXo+`o`0`js=C&%KG6a9SBC2ybkKG!A10A&D7!eC zR%61?5w*^Jqgt#43l`V_8_E|fWIHUJJ-ni??)bv@qxAb7jC_=Ne=CO0kO$B9lBa-J2sB0O$wf&o2_8j;7@-r{pnA9CI+$= zSKs*)1fU9X#$#>ko-s`Jqpb3h;Sga{-0dahOGv5hZ=6VZ2ec|XsrQjjrTn@wBj_ON zn~RI@bA+Po2x@P{lvJ`bgN84MI+JNXrxg(ZhZ2i!Q(b|`2N5{TiunC&it*I=pk zu2Fglef4;oQz&VY#(!R|U$!&6MLhJ<8I!=eF=y%*8KX^BTZmi_Y;H6O(8F6`%K{~R;=fhnZ4f{ps;l}-CO#Q$pmI^=(SbMivp zEI+LI!M2=-nMKHXO!wiHHQe|sampcY!t67$C;1x`Z2mb~qsS&iq0R21-nuuCp|G%_mH;ZsFan;1@BcOe$w{FS>|>EU{+Ccc7KQP~ z)INSZ#S?Xefm5*E_%0v)EiC}H{~8k?gy}tg#PH56!GuZ$_mW2Utg4n(6m3_wj+q;t zIkrJ|bQym7bbYeBP&_FPFPZ5h3bUES8TD|?D0yroL9&yafcKzte0wfUI3c-9VmAs8 zWR`+J;)nEgJS}&RIE1btRI>|=`g3DF6TKHECwfW3@XL%c!PF?`KKvtMk8(=dH1j$< zk+j8Cv!?M$Z*X@ja)tpFm_D~gs>#8sgU*LLkGv7x@`zpugs+Ady1taB{?kdA|D3&AGv0p_%w08bSa7uCNF|Mtdl)(Kn1 zpWS3onddNrfXcm}?vIL9Td2dXGqXGM-q8}rlo@h8o8cqaBf3ucofFc1r>k!LoGHdzGquRq zA7`dG%&P~l_Rd~oq4O^sj8#DDuY*MI zw<%u$ZYlvc055vZXZJniePk>E74ir&t+E0!98?4^S2YoD^)=4$V+mMfzt3!Zec7=K zy59qopv-*$lWRZ$jvHhIprDCQ4J2f+;i&p))y|BV&!s<(+lMyQ_J-K@glk8?Bf2v-wx__!B?LXy%-Ngfz_88SE#4Wc*pfFzTOmfn7MQ5qJ!IUh%bCvk1* zuAh^NqAIBnG9ckF#>Hck2*=D7dm{Ni-j*xFJ{w_q4MrrUD5iD~@6jbkHsiKIKQyn; z(0gP}(f{armKq0}k?E8Ji|}byT92v%!%tmTHklMfzMZwp8`Chz0A?(h7}gYBmfc$B z5n_94$6J|JD7X~nz<>cPZYVPrw@+cK=5uP$j=;q|>OkMMMj)hNc5LXY%c^WT`U#lI zZ9wEx3Z&H%kBj*X(Y#pUWtB$P7p)n0Wk$%Et!?NO3*+l{_1^4j8*;36O9#+DTL1&y z%rT4@L~+H^X07E2l!!RCe;d*Zdc17S0#v^)Vd1VSvv4>c&L9a*HUi`@?^(I&DhE%r z+BXtP8LZ1i2{2hz<@^THj{xPU%*fB=NK7$E-&dHaRHf<53k_y&#kz(Il@iA~hcQ6P zU2#f3P-w~vz6`)6eJ)>-!>@D7>)y6tDnO#8aPPL?J-GyMO#&X?3#_sqY=(ZyR7=6m z0xewl0?hjYc{T_a%r0<{aSWv@iNExQk(ar$Kza(l+4znc2LZ*v&lCoz34#2T zXF*e&ri5Y1&@}^wkg3-#2954)=(-KYiD7&MjNP1a@F?7Nb}JUA_4#=P(%#x)plLp! zgkV&JnYOtx01`4j#XmNNfK`6Wfy5xNlVk_^;u}elofsiX7=a?>Dxt{)$Eo4;^*1TS zcbz1qv8y481Y0^515|_)*>YHshH#v89UF-(~^mVZ{SX6P#5Tp80qU-jA8?gfev z^h-VO+nKgJqhw>WK&v5ywwXg! z@UBP&>qxN>fCpq2FWwzLK2hM!^v!|V@@FvOA5aNyiB=>XssbOkCT{Ol@tSBjvRW1@ z7|aZo%Tja?jHw=KvQp-lWT<+giMoS^nCG$74US{P;bSdC{Uyan>WcvEItf>% zcoIfK>6@kvWXRKM8;)XaD3FfbBsAh8Mr!1-cEy1O zuYFK&m_XeVAyx7cE@;=$4nSg7K4GX?4nM_CGsUcD617ABxXj?)&P9vy8Aj~tvLr&wSF3TH3%MErlz%iZ@@u=ouIT85;<#S~I zz_v2xXRPb0jwj(@mA2>%$hMK<*o+t=5KI&eH5$-(3mGf$CrHBRW7fKWX>wRxSI!b2 zv)$Q1W^r>kdL$t8Xk-Z+7~hC#J{s+gZhNmG_{L4rPtQPfR>G@(tx0^N>q?ur1=tQF zyw${!`iuxDlEy9AR5*Qg*FMgR*QU) z0^Q4mCCbL>cB~v%T1_eFVqCF#!9E#5QtKi0g3xB`+Jz!jFE|KOgZ|HN(kpe>swD#pc%Ss`cqu-lWv+oEG2 zYYg4;hr)?|&ng-WLzOv3re8zhl>p9|mt=pB0fE})lPUu;ecV;B*P52dBc-j67SnTq z-tX*_3r~X28ji2Mb&r1`1TG z(sYvTA7K>EDA&QU+HmGfBQ*!!Px$zke1<{#2+}n(%MJ>u(&Gz%0BNC|Mm1dD z;%|J#4%f7wL)uD+;T3AxI+s?AF3d$n&|LpWy+f9^Zq$v9Sx(A=QYA4i*PPncU7LWo zUMx*XgSDW0^J-VR%id%Mf?70AM*~_w5LSH(C04-HsMnYadr;=@F5GAvECv?kHOfB+jXA=xCIxL801;11y8bn z$puJVo}myYP<0L(hVBBA46Pw|lg-F$HS6xgp)`U} zO(gB@tQCzp6O;_U@L;;WU@F@KaB2saP(ruDuw}yKP26{eN96m7!fV8jMRqy`pCU*M ze(CH7dO8ns8E}Z|Y|}wMx3$}gi77C9u@Rn(s=WuVkZN25nZ0bUz_}R{oK6&c!`qXp zM!bR3yg>R-sK|CiD<`^s0zB$j?VW|B0h;O^-I3YIG$#pGWi!90|uD==7iccK0BRVg8@{z)GDfz!> z@$ZbsccZta*KUbE5cQ-u=;^KA+sjep{x_B022E(1Tah<{tHpjzPuHeT!-XdCijt~RBmX{(JB62K zN@2nG)s0fpyj5c&(d3kL!MDkH9)|t6+#3(Wo|2F!`8l~Jwrrt)#ObI-`96m(c%tPk zl!5BQJX9j(A2i(r-HW8J^VQ2Ze3AAH2BSrP7#K)jL zh`!Fp9>w3@!DMCN6!o3Tq|Wf?`kb`lxt)U7>ev=$Il9XLOmQQBkuUpr`;pjseXL0T z{!N!ae-p&OOXafsRIhCA-Q1jfc)7ceK6em`njsxZPRR7yF;wm!iknnj&Ce=kn2%~U zxW5m^Ql-ru>ssM@q~~DWn{^iuZF*C+Kyl3%{gRz`s>&#MKw2`^ZAQ9dHVlnCMRACv z0Sn$c%fE0VquGz96emSNq~yM~?C?==-^f50N?7stH;%2d#K3<{se(Tb7=G-|Q-B=o zKIT7tIOltX2lyzreNL_WRGPAB-uQuM^4-kb#2Ums1%LNDKLKKRopB;gF`d=!@ zfVPCWxB>saEn_ym!6#YD|92q~l8Ab0JOiHy0mH5x{{HKUh_H6}6-My;a+_#wZf-9y zlH?mx4vfZEc z1}URF&*${97|NOyHj&s((f1eY>e7XZaEAalcj$hFA`nD#KU6{#LJG@resf6r0)Ji{ zB>*Mt^h03OwCaX9Bt|&iX-TozF*LOR4IVZWN79Dd?n0+J(FTt-@vVu#HeIi7UT+%f z$3TI7`(ltn$^{5ava2x&^ZP8%VRvwCn;Cr_)o?;ZUF`{#fWwN^H zTm&)?7f)t8OQv=6zgEC;V!yB!K5U3eqqz+91NLXZSKbdjef}sM~Z^IlEY=T?3 z&wL(Xjgkdf=n{&UoGD2Ox8?NXBH9u@w&%ZW8{1Pv%9Qav?d$Dgd{UVg39S`n38nTr z`_;uQr&>xRAgTeTV04S_G^KY51p13@1)^N=Px+aehHmkP_+%r%Q~NF~79@2EG8$2< zHj>6;@daE)LHYFzJ+jP{e!wh$zsZweMZvk-h6=T-xWF%+fG3P3KDl+gnVv$-Y=lNY zJ@XNgfDD0Vg`)Jp(M78|5b%_Usoda^uRB667XP=1kLsmW?--Z1LFrbX6ne@QzJ&PR zTl9p-Tm<3xn43KKECK9cbjExpZ#%vh<{qDY_L-yJhDccYL3lRyg9myenNeCN339@) z0nWZ|AQmv?U+@*!sUD(Dz~`e-?tdr>&dhRs_~4sK?2QGnQ1^t~G?QQpamaQT-Z2uk z{qgw|x@i|anmScPYM(B>*m$bbs-Iik{WYTT*;t4I84@OjrpUPc!Z+`>+N6+6iqK|#JAUws|a9ztam@#2~izVhcT#y$G zgcDzb8C&d~A8lmKRi3Qp(CY=PYdhMboUhtO2tYsMCf9U7vBi7zXc53p@nQ5bB{gck zu(*~*1sh^PRi6gw7JlH8DmYTtWpp(H$367r^MM|~#0;FOSC^1@08@KoxCEGn0Y}rW z6LMyndWtQ*w6Z+LBYP4fDJ>SJV0M|FgT_)DhhU3MWu)g`1BbL0rr~`e(KKtTpx2Ej zqZtF;%fRu$$gjTGBp$m9!m_eI^sW!}uyBWG&h4 zFIw93YK=+ZASH~74$0Wl1YwyyFwv$miaDOf zogNj1si&mF9q~E!GcdpzkBYlwqQ>^=hNrbx7E=YR&jw| zoD>~G6v(fIDY(7_gGgnPm~GU_thN@>Kve4Fr_{Z#mpZY|aY<=qRcjUxD?fKlX4}GI zDj%6fHw+%`^w^H^q&M)*fX&mE7l2yO0|8o2YT@%vC}k{yeeXAroq=)}|Ii~fun3uR z8|+tO49cTW7JU^^CQaaxvzUM91RN>Aq=1by1o?6an;NvxF9Ey7BIZ;fcR^zct#K_3 zO~6lm8;l9S9UUnFUPUFtvqf(%D~o$A8{Rj_m#Wroqg{rxqES9=pUctdffVo zyLTRHMzTO9=`T5*?)mWG@kCP{AAa?vasm3U+p4^|o=;%LBRCw?Z6^hH+~~Oc4wru} z{ZoVTWHTI>|8rY6)-pt^1-{aI)=ng@{1&{HwOZ?T&q$cQxPFOX;o%a)g+ny(JrK*_ z-~J1{RR?B1{vJMt{hPOcP}c4D+pgPSo-rt-08--$lPqD!C&AtIVB!I#pL=8ryGtzn z|5~xZK9WF(+UQ_4k8^oUA|rJh4d++}*gATk5;f}%2vv4tai|!IALhdwgt2!-ud+Ba z>OS>_tddr`5LgMK{Rc6OtcQU`G-uL#UaenruQ1=SA<=4RA$6cZhYZL# zi=S`GELf4yNpAAWALKTE4@FU7i$m_e%T_3=JCULz;}8F=%$3lFJY54jmN47&oo=NS z(Gg%GyBfNp1wnSJ8``Z8nR}lyHf|lFh?Yj!4@0}(wOMeu1!X)#=TgtuAQ&zb5jn3r z%FMFHERCRI-I*JN57MesH^qB%Zh`msI!LiVF<~%D1;nLYRHcm)4ke3=3PKRHbVC3a z2OCN-!hvPr)}UN0AfU{3E%H{lNig#)Oz8qR5LcN7V9U%usQX=e3ASLe@{C>$tgI+y zMEEzL-&v0XG)|NZ+FQlHk(yTJ37X7aR3dlCgHIjQN4`S{@_$yGs;92 z{lZr21yrpDCb6-G+Q$R_{PW^rSQf|#e@y~YbOWhd&RQ4jiJTcR?Foo@>%z7tH*MT*X_2TH8+!XEN^^p{@DeYdMa0c= zwuXe9zEwL7O4Jm$e2PXZT|GB2GMm@z*K<=FuIeD`${OQHnazLda@J6wD^O@AJP4hx z)Nk%?E`%z=2i7pB?4!f{GWH(i{XHJ-e}QS!!&WH{b+~J%>`FzMs3(wy`q8NP!u&PL z#Gc@8{TLGya`&ZIU9Fu(-1b(XvSTbwOG&sV3iLjtCf3kw8s#28Xw@%3bo{^|5Wm3N9E5P8N_y ze-bGGz=8B1n7CNpnQpxAD%-or4a+6NiP|CJtmc<@$t_1fEqG@4{a8U#$9Is6BWFuStie zl>f3t)QbM}$>z*AFkhOz%Q*=!ra5n@pd|WG8T5OdPseUQQ%ZJU_*?&5P0bDuhB1g} zv}o_B$n6x_Q$nNRvHK2|5dPJVG64`IH-?l_T15`7cG+HmZImIcm%!3dPN>rg18bRM zs$S^f_$(+%iKYsorbI68wFld9a4Z3=T!<_et9%PSqt3g~GMGr>LaUUTepmIwXqbbGw2o|dd zR_f9C5x~&6y1?7&AQK^mPf<$nV zjasFY<>4qtR9`?z3mUE+H>w|pc7j-O+evQOBgi7!dsQ2e8K2JfIV?e|NNibab9l-w z4J)@sVb%7MjTFy%8)jrM`llNN@`pJs<=A7}`^3Y;eOtHBe_gI1SG74yP@2}&0dz!xw$o;owY7G+TGVG&>bKEU za*_0J)3`*rp<{@`yNntu+;_ltA1ZE3gG6>|wGD%1Jkz35KHhd%G~glZgXtR~vBLa6 zEQ!z%7m6*)ZvDm=&6K23Z2=&h0_|wS0gWCdR}ivb)b{|}DjzvH7GoviMh)jgS$Oh# zjO`$kZzG-^nXG7=UwQZO6GXDe`Y^XQWV3l%(r*|bZ^gF?h4RObHV@#d|6iQ!0B2qy z)HFtMeF4()>AMJpmUa>t$%kp_ zV$V$`5pe5cCi&{RVfFA0R7nIJY?dg6sexxnxai$=ji&4z=^M+do_wV_;6@fKqr;q< zsy=VvmhTj^z1!j)-=@IDV?%(szNk&NeD9Cf_hsP>EOL!QEY=nJ{{dWeZ8P4G!z_fo z1_Ve8U*S^q(HO0~4f#fkpHIS}z0J7Y5m;M1urolV-oRxjL`58-!$f^7O0NlDD)FBh z!yOPBcuFs0(wAex)zH=^{6D3DiaYoF#tM}#gBkK)P-}u~y@*9`c)%8U8od3rFOJeqT;col7Qr|!3RmDNGTP$C*dl=h~mYe22F(#)`ts!x6()2%mLcRROoh{$P~+Uq7E%#3tgkX_R_(v6!;Cv^BK78OFK}Sp9%jJ9-(#5Q4JNx@8lGaT zv50cvl~<#}&e51eI1;^dS>iHtH)vKq3Dte(g#NK@_Exs*pkFyAbR^V>PT!&u>6@v&PNs!Einu?eT(IppT?h_KfP2U5A~1yE33huD z5R>mU)M4#|1}QUs;V!S=Ik~=j0_9RF;RQs?XsGZ6+TKEU&aiJSwXx}KsV#xraAZN>79{WB-rRmPf9ku|!+T_f*H6797S8`^8+RdyVn>|i}}-qY7MJl?ZD$)wtqL)fY>K_{XkK4Q>sLH; z{bGP7H||Bj5Lp`s%a>&Mo8zEGdx}1Z6nE)Yyef)Q)f*5t+Lk_R;vS^d?^a$=*!fNQ z$JoJXViu>gY0x^W^HM^SyV2O4ql^j(ot&mNY}YlQfy=-)-npr|ok_9Nw6Q(htpY_P zkY)g4z5xy~y1<5zW5}TQc!w=gcP7&D;!0cWuHCF=fSQ$=0RB!7-LWlXwjS?7!=H+m z=rsrX%``GE*Cm-3GHu!eor!8`2wkq*CFtkM^OC$>_2VqSwI1a+%;>D~cq=`+<0r+p zbalijF+p6qCnn`q8J?7KjYH5GEc#+6iyB*w!XW3{`m!=doB80QD??!9U4Vl-N!Ilm zuTFOO9NIZ@pZJXv`tAFwx#IK4zA0DdSC-uQk%3OxjOo^QhDtCJ(OuQ~+~RTa4Z_Z( zFVD`BcVw-RZHGQTT`X*gE-6x7)@%3DL!hQuYfr?!l3|<3A{=P$bBJx?7SdI$JJjcP znz>5I~<@%L#;k*5ZH)X}%D;i;HbaVTHg333Z~?4Bw^ zEbQn-qYM(+AOnYP&v&DP<3V`Dpn;IHZw$jQtF$+eHHo~JvzTI&!1 zjLAjNqa{ZoF>v_ZlZ%+q=Z$WQXYv zX4ro%WrL&Np)6B2Zl7Oc2znzf5c){;EF3msvoTiTw-~8xzdkpG+O6m`Y}S6@=0YQ` zNwGkAfAPhG;)~*K`5rI1ZHDp1 zO=0%vX?0Pe4+poi@=FVT3YSo+Lo)D1FfaHhMhDIyEjaeFJ3FwFQ&R`3{b1Sv{--$K zl&i8?SKtG23L4U~yJ=>If;2Z!cHgg7xU#*+G9LJC<8T-lZ%^Kh6yo`{C;>0}dYYQM z;ojuN#6}eT%Om1eihrxB?AqpDjobOyHpIE$cK5IHWKY_STNQ0mhQ(XJ15l^IVLm$i z`oM6VUq8MF*SWv{7Pv!jYec1HSyOm~;`y6DQ1;sn?JdCm1Y`Xhys&)Y{?kXr)1O`t z>uL`%!M#GDuT?dD*O_DCKHM!}dhrHyF|*=(XZc~!%HtIhG|T!5bkMlLLedHeeuV_Y zJgsnRjyXricnfWvcTf|^7snGy;6e=oQiTYF4xvX7r9}`96hRO}5r_~<=+a|Af`u*! z0t%svDAK#sP>v#k0s^53Ncml;BB4a#;{1NUIdA56XLo0I=d<(n&G-GYv-5VW-!B2U z$|sk$h)B(FH?bTi>Vq|>27RcmfUU>%8W8vV4xx&+xghHd(3- zfAlr+CR2l2`r(eUvXdt=1>4PoKirwx-E#VV@IA|Bh_YI>eiC_nly0-Gg1dW6y5f7% z_pG6UzAAR}rD%t~4(iH->#8v!ZK1hfM)Vs>B@^3uR?~=#%s~Jkm1l7}I{uuDw-QIwH~x1ZTWTzbM+!&sIO3s67)717O#n zreDzx4>OfS)#Qy`CZ(kINbx4NX~SMnrfB)ttTGlmlWzihMU4Rb3gp!llZPsDPq;T> z61+DE;$GR=grew!po>i?^BX4J%s>7V$}`U2H@5=bqEeZjV5b$Qv=z++r`r()6+~Xy zF0e-QN*mNht2xn)b(@K4js>%kX_wwO2SLTNxNwdQjWRYLrZ{A%#b$?yjY^QIef#R? znb=a+^cE@}-oHF(yl7G~D%`s&9m0QdwOo1nod1RXmyvH{%vu6@{I#K0ilpk#+%g=` zWrES?O#A8*IoprIdEl8WWO(L>Tw+kkij<7^$p_2I+?r~X?d&wGl7lT#s4dMkpzi+s zYqw__tQwT+2(G6sd8+CXT71sCQ9VkVp9=2Lge&hlT2yTyXWwdhlNo##@*cjN<8y74 z1D!UowzRiiem+!?BHMA1$lIKwrJ@B;&y+`@#tq7ENGuwnmTBw2K zwirlyVxD9?**YnLE7PfzrtJ#9^AQmajLft97BZq~&JNy*6;U|P+wnTKM*tL~H5s71 z8#&XkegD)#zth6LlD#kr(7QlgR1OKSqK!y@cmbLMru zj`zUnQD5|w%m`P*_i&?Q*JnGs*Efnm& zF#qzn=K{af-SY8>KgJp_&3yz~lZ;A3wh+C@`M|IAzr2!sQtr%3crWR6Dkb~pIU%jd z41EJk{TOI7GNM(>w?dfNQmPwt&7)BeHe%BGT;uWhLarTVFp8TcHRa~6KHO(wl7+DM zI4$RrKsT&<7m}pG8&hAiuyp21dv10JC9d#%{Zl`K)(Yy#WTWRBPe#Y#s+Q9EC5YRz zqx>9)%o;Ff&3K82cv|t)7x}=m!=JfnI?0P$J%w_h(%<+{bJcE3yMV*A(u976nQ)y>2UEeO%GYI=KJ3o}nMvtf{l>pGBm@OsKnm^-b z62w(s0%r%d!f8SP%;yjsP8T~3GJGz0o;a~_{4|-1lPY%NOoV~Gz(#k%tJ>@lVP3tn z)pgh4{4H6HL%faEF|xPdf?>MQ5m9WiQ+2U2V@-UYY--b^hWIc9rTl2XYL`3`&#B?j z0Y*45?09T*Z4wM%G}sxg<1NL&M*z{I9O+UJZuhpX?b?c$B`sg-T7b|!zgS?EBsYlX zq>KF>jisSQGSp>S=7si;*aw~jNA&c@{C)QmFk-Jfpr_DIs=H6&4VkZs{4UW!!}#^V z*3mjlyzP;=Dzf;_YXoy1I?heKW*XVrxD_J%9v2iKJ?V^fDvuEAcWA54&?(q-d95vEWy?{>T*}HK{`!Ti!2v$8DA^P zlY~nu+4)Ik`up`0GGPPIymDRQW4&h+a)E$TehLfX0J& zpA#JWG=(cpQ~JpD*RMsvr?+YiE8HgvQThw4OUK?VzBsP;f$K4BcY6^E1{a}hZpGq^ z#ZgJCW~xRT79XeyXn*Pl7XdrV_>P4Q-gJrB@ zZOk%5&IO3Ogv}ESQak!cEH)yOh95lua)T38{KFhN+wcb4ETI6Ghj->E|o&4XMl<~O3M2posrn?$0fnp2BHaiXEo z`;i=KubLYSY%&ACbe*bIt%{NYT}dGjSCz7^>q5b}8F`dva*2Y!VsDSV{plHz@2-t0 zLTpK-y7pO`lD%AySV$0yK!eeg1oLXu{U4ibSIvM7ynz2|T#2sn>v@-Ra8dxkSGtuy z4g6;@G|{&(Mq2$e_g8R;ezL-lH~|tA2tac)16ck+mC(2QU#R>F{aZx+%_SKF{}26) iuV2A`^W)#(=w;xqUcG9@4EnjqM6aLeqn{~|-v0$#-22!7 literal 0 HcmV?d00001 diff --git a/less.js/less.js_2.2.0/CHANGES.htm b/less.js/less.js_2.2.0/CHANGES.htm new file mode 100644 index 00000000..e823d8b9 --- /dev/null +++ b/less.js/less.js_2.2.0/CHANGES.htm @@ -0,0 +1,570 @@ +
+

+2.2.0

+ +

2015-01-04

+ +
    +
  • do not apply relative paths to svg-gradient and data-uri functions data-uri output
  • +
  • using import filename interpolation and import inline together now works
  • +
  • deprecate the compression option (still works, but outputs a warning unless silent)
  • +
  • The node version of less now has image-size, image-width, image-height which return the image dimensions of a file
  • +
  • Fixed an issue that could cause the parse to occur more than once and the callback be called multiple times
  • +
  • if you are outputting to the console, lessc defaults to silent so warnings do not end up in output
  • +
  • isunit function supports '' to test if a dimension has no unit
  • +
  • data-uri function now counts characters after base64 encoding instead of bytes before encoding to determine ie8 support
  • +
  • fix bug effecting guards on pseudo class selectors
  • +
  • do not cache on the browser when used with modifyVars
  • +
  • detection if less does not parse last character in file
  • +
  • detection of whether a file is css now requires /css, .css, ?css, &css instead of just css. You can still tell less the type of file using import options.
  • +
  • remove extra new line added to sourcemap entry inline file
  • +
  • support safari extension
  • +
  • less.parse now exposes a way to get the AST. We do not recommend you use this unless you need to.
  • +
+ +

+2.1.2

+ +

2014-12-20

+ +
    +
  • Fix for use with requirejs
  • +
  • Fixes for data-uri function
  • +
+ +

+2.1.1

+ +

2014-11-27

+ +
    +
  • Improved keyword and anonymous usage with the replace function
  • +
  • Added getCSSAppendage to sourcemap builder to avoid duplication in plugins
  • +
  • Fix problem with plugins when used with the promises version of render
  • +
  • If the render callback throws an exception it now propogates instead of calling the callback again with an error
  • +
+ +

+2.1.0

+ +

2014-11-23

+ +
    +
  • Fixed isSync option, it was using sync file operations but promises are guaranteed to call back async. We now support promises as a feature rather than the 1st class way of doing things.
  • +
  • Browser code is now synchronous again, like in v1, meaning it blocks the site until less is compiled
  • +
  • Some fixes for variable imports which affected filemanagers when synchronous
  • +
  • Fixed lessc makefile dependencies option
  • +
  • output now reports back a imports field with an array of imported files
  • +
  • relative path test for drive names (so windows only) is now case insensitive
  • +
  • Fix for IE7 - use getChar instead of indexing array
  • +
  • variables using !important now output !important, which bubbles up to affect the rule
  • +
  • livereload cache buster is now treated specially
  • +
  • upgrade dependencies
  • +
+ +

+2.0.0

+ +

2014-11-09

+ +
    +
  • Fixed multiplication in non strict units mode to take the left operand unit, in the case that the unit cannot be resolved
  • +
  • Some fixes for browser cross-compatibility
  • +
  • browser tests now pass in IE 8-11 and FF
  • +
  • added index.js and browser.js in root as shortcuts
  • +
  • fixed some local variable spellings
  • +
  • support for @counter-style directive
  • +
+ +

+2.0.0-b3

+ +

2014-11-01

+ +
    +
  • some refactoring of browser structure to allow use of api vs normal browser bundle
  • +
  • browser bundle no longer leaks require
  • +
  • browser can now be scoped with just window
  • +
  • browser useFileCache defaults to true, but file cache is now cleared when refreshing or in watch mode
  • +
+ +

+2.0.0-b2

+ +

2014-10-26

+ +
    +
  • Imports are now sequenced and so are consistent (previously some complex projects might end up with occasional different orderings)
  • +
  • Imports with variables are better supported - variables can be specified in sub imports
  • +
  • Support for rebeccapurple
  • +
  • Browser can now accept options as attributes on the script tag and the link tags e.g. <script data-verbose="false" src="less.js"... +
  • +
  • adding a .less file extension is done in the abstract file manager so it the behaviour can be overridden by certain file managers
  • +
  • Fixed a bug where unquoted urls beginning // e.g. url(//file/file.less) would be incorrectly interpreted (bug introduced in b-1)
  • +
  • lessc plugins can be a function, used as a constructor as well as an object - this to allow the plugin more flexibility to be used programattically
  • +
+ +

+2.0.0-b1

+ +

2014-10-19

+ +
    +
  • Public Beta / Release Candidate - Feedback welcome +For a guide to breaking changes see the v2 upgrade guide +
  • +
  • no longer including old versions of less in the repo or npm
  • +
  • not including test less and gradle files in npm
  • +
  • colours now output in the format they are added, so yellow will output yellow, not its hex counterpart
  • +
  • better parsing - better comment support and comments in brackets can now contain comments including quotes.
  • +
  • Removal of dependency on clean-css - install less-plugin-clean-css and use --clean-css to reference plugin
  • +
  • Environment Support - less is now separate from its node and browser environment implementations and adding support for another javascript environment should be straight forward.
  • +
  • Plugin Support - it is now straight forward to add AST manipulations (see less-plugin-inline-images), file managers (see less-plugin-npm-import) and post processors (see less-plugin-clean-css and less-plugin-autoprefix).
  • +
  • We now recommend using less.render and using the parser directly is not in the same way as in v2. It is possible but it would require changes and we do not guarantee it will not be broken in minor version releases.
  • +
  • In the browser, less.pageLoadFinished will be a promise, resolved when less has finished its initial processing. less.refresh and less.modifyVars also return promises.
  • +
  • In the browser, as before less is used as options, however this is now copied to less.options if you need to access after less has run
  • +
  • In the browser, the cache can be overwritten by setting less.cache before less loads. After load less.cache will be the default implementation.
  • +
  • less.js now uses browserify to generate its browser side component
  • +
  • default values for the sourcemap options have been re-done and improved to hopefully mean creating sourcemaps is easier
  • +
  • Many smaller bugfixes and API changes. Please let us know if something you relied on has disappeared or an area should be better documented.
  • +
+ +

+1.7.5

+ +

2014-09-03

+ +
    +
  • Allow comments in keyframe (complete comment support coming in 2.0)
  • +
  • pass options to parser from less.render
  • +
  • Support /deep/ combinator
  • +
  • handle fragments in data-uri's
  • +
  • float @charsets to the top correctly
  • +
  • updates to some dependencies
  • +
  • Fix interpolated import in media query
  • +
  • A few other various small corrections
  • +
+ +

+1.7.4

+ +

2014-07-27

+ +
    +
  • Handle uppercase paths in browser
  • +
  • Show error if an empty selector is used in extend
  • +
  • Fix property merging in directives
  • +
  • Fix ordering of charset and import directives
  • +
  • Fix race condition that caused a rules is undefined error sometimes if you had a complex import strategy
  • +
  • Better error message for imports missing semi-colons or malformed
  • +
  • Do not use util.print to avoid deprecate warnings in node 0.11
  • +
+ +

+1.7.3

+ +

2014-06-22

+ +
    +
  • Include dist files, missing from 1.7.2
  • +
  • Do not round the results of color functions, like lightness, hue, luma etc.
  • +
  • +

    Support cover and contain keywords in background definitions

    + +

    +1.7.2

    +
  • +
+ +

2014-06-19

+ +
    +
  • Allow paths option to be a string (in 1.7.1 less started throwing an exception instead of incorrectly processing the string as an array of chars)
  • +
  • Do not round numbers when used with javascript (introduced 1.7.0)
  • +
+ +

+1.7.1

+ +

2014-06-08

+ +
    +
  • Fix detection of recursive mixins
  • +
  • Fix the paths option for later versions of node (0.10+)
  • +
  • Fix paths joining bug
  • +
  • Fix a number precision issue on some versions of node
  • +
  • Fix an IE8 issue with importing css files
  • +
  • Fix IE11 detection for xhr requests
  • +
  • Modify var works if the last line of a less file is a comment.
  • +
  • Better detection of valid hex colour codes
  • +
  • Some stability fixes to support a low number of available file handles
  • +
  • Support comparing values with different quote types e.g. "test" now === 'test'
  • +
  • Give better error messages if accessing a url that returns a non 200 status code
  • +
  • Fix the e() function when passed empty string
  • +
  • Several minor bug fixes
  • +
+ +

+1.7.0

+ +

2014-02-27

+ +
    +
  • Add support for rulesets in variables and passed to mixins to allow wrapping
  • +
  • Change luma to follow the w3c spec, luma is available as luminance. Contrast still uses luma so you may see differences if your threshold % is close to the existing calculated luma.
  • +
  • Upgraded clean css which means the --selectors-merge-mode is now renamed --compatibility
  • +
  • Add support for using variables with @keyframes, @namespace, @charset
  • +
  • Support property merging with +_ when spaces are needed and keep + for comma separated
  • +
  • Imports now always import once consistently - a race condition meant previously certain configurations would lead to a different ordering of files
  • +
  • Fix support for .mixin(@args...) when called with no args (e.g. .mixin();)
  • +
  • Do unit conversions with min and max functions. Don't pass through if not understood, throw an error
  • +
  • Allow % to be passed on its own to the unit function e.g. unit(10, %) +
  • +
  • Fix a bug when comparing a unit value to a non-unit value if the unit-value was the multiple of another unit (e.g. cm, mm, deg etc.)
  • +
  • Fix mixins with media queries in import reference files not being put into the output (they now output, they used to incorrectly not)
  • +
  • Fix lint mode - now reports all errors
  • +
  • Fixed a small scope issue with & {} selector rulesets incorrectly making mixins visible - regression from 1.6.2
  • +
  • Browser - added log level "debug" at 3 to get less logging, The default has changed so unless you set the value to the default you won't see a difference
  • +
  • Browser - logLevel takes effect regardless of the environment (production/dev)
  • +
  • Browser - added postProcessor option, a function called to post-process the css before adding to the page
  • +
  • Browser - use the right request for file access in IE
  • +
+ +

+1.6.3

+ +

2014-02-08

+ +
    +
  • Fix issue with calling toCSS twice not working in some situations (like with bootstrap 2)
  • +
+ +

+1.6.2

+ +

2014-02-02

+ +
    +
  • The Rhino release is fixed!
  • +
  • ability to use uppercase colours
  • +
  • Fix a nasty bug causing syntax errors when selector interpolation is preceded by a long comment (and some other cases)
  • +
  • Fix a major bug with the variable scope in guards on selectors (e.g. not mixins)
  • +
  • Fold in & when () { to the current selector rather than duplicating it
  • +
  • fix another issue with array prototypes
  • +
  • add a url-args option which adds a value to all urls (for cache busting)
  • +
  • Round numbers to 8 decimal places - thereby stopping javascript precision errors
  • +
  • some improvements to the default() function in more complex scenarios
  • +
  • improved missing '{' and '(' detection
  • +
+ +

+1.6.1

+ +

2014-01-12

+ +
    +
  • support ^ and ^^ shadow dom selectors
  • +
  • fix sourcemap selector (used to report end of the element or selector) and directive position (previously not supported)
  • +
  • fix parsing empty less files
  • +
  • error on (currently) ambiguous guards on multiple css selectors
  • +
  • older environments - protect against typeof regex returning function
  • +
  • Do not use default keyword
  • +
  • use innerHTML in tests, not innerText
  • +
  • protect for-in in case Array and Object prototypes have custom fields
  • +
+ +

+1.6.0

+ +

2014-01-01

+ +
    +
  • Properties can be interpolated, e.g. @{prefix}-property: value;
  • +
  • a default function has been added only valid in mixin definitions to determine if no other mixins have been matched
  • +
  • Added a plugins option that allows specifying an array of visitors run on the less AST
  • +
  • Performance improvements that may result in approx 20-40% speed up
  • +
  • Javascript evaluations returning numbers can now be used in calculations/functions
  • +
  • fixed issue when adding colours, taking the alpha over 1 and breaking when used in colour functions
  • +
  • when adding together 2 colours with non zero alpha, the alpha will now be combined rather than added
  • +
  • the advanced colour functions no longer ignore transparency, they blend that too
  • +
  • Added --clean-option and cleancssOptions to allow passing in clean css options
  • +
  • rgba declarations are now always clamped e.g. rgba(-1,258,258, -1) becomes rgba(0, 255, 255, 0)
  • +
  • Fix possible issue with import reference not bringing in styles (may not be a bugfix, just a code tidy)
  • +
  • Fix some issues with urls() being prefixed twice and unquoted urls in mixins being processed each time they are called
  • +
  • Fixed error messages for undefined variables in javascript evaluation
  • +
  • Fixed line/column numbers from math errors
  • +
+ +

+1.5.1

+ +

2013-11-17

+ +
    +
  • Added source-map-URL option
  • +
  • Fixed a bug which meant the minimised 1.5.0 browser version was not wrapped, meaning it interfered with require js
  • +
  • Fixed a bug where the browser version assume port was specified
  • +
  • Added the ability to specify variables on the command line
  • +
  • Upgraded clean-css and fixed it from trying to import
  • +
  • correct a bug meaning imports weren't synchronous (syncImport option available for full synchronous behaviour)
  • +
  • better mixin matching behaviour with calling multiple classes e.g. .a.b.c;
  • +
+ +

+1.5.0

+ +

2013-10-21

+ +
    +
  • sourcemap support
  • +
  • support for import inline option to include css that you do NOT want less to parse e.g. @import (inline) "file.css"; +
  • +
  • better support for modifyVars (refresh styles with new variables, using a file cache), is now more resiliant
  • +
  • support for import reference option to reference external css, but not output it. Any mixin calls or extend's will be output.
  • +
  • support for guards on selectors (currently only if you have a single selector)
  • +
  • allow property merging through the +: syntax
  • +
  • Added min/max functions
  • +
  • Added length function and improved extract to work with comma separated values
  • +
  • when using import multiple, sub imports are imported multiple times into final output
  • +
  • fix bad spaces between namespace operators
  • +
  • do not compress comment if it begins with an exclamation mark
  • +
  • Fix the saturate function to pass through when using the CSS syntax
  • +
  • Added svg-gradient function
  • +
  • Added no-js option to lessc (in browser, use javascriptEnabled: false) which disallows JavaScript in less files
  • +
  • switched from the little supported and buggy cssmin (previously ycssmin) to clean-css
  • +
  • support transparent as a color, but not convert between rgba(0, 0, 0, 0) and transparent
  • +
  • remove sys.puts calls to stop deprecation warnings in future node.js releases
  • +
  • Browser: added logLevel option to control logging (2 = everything, 1 = errors only, 0 = no logging)
  • +
  • Browser: added errorReporting option which can be "html" (default) or "console" or a function
  • +
  • Now uses grunt for building and testing
  • +
  • A few bug fixes for media queries, extends, scoping, compression and import once.
  • +
+ +

+1.4.2

+ +

2013-07-20

+ +
    +
  • if you don't pass a strict maths option, font size/line height options are output correctly again
  • +
  • npmignore now include .gitattributes
  • +
  • property names may include capital letters
  • +
  • various windows path fixes (capital letters, multiple // in a path)
  • +
+ +

+1.4.1

+ +

2013-07-05

+ +
    +
  • fix syncImports and yui-compress option, as they were being ignored
  • +
  • fixed several global variable leaks
  • +
  • handle getting null or undefined passed as the options object
  • +
+ +

+1.4.0

+ +

2013-06-05

+ +
    +
  • fix passing of strict maths option
  • +
+ +

+1.4.0 Beta 4

+ +

2013-05-04

+ +
    +
  • change strictMaths to strictMath. Enable this with --strict-math=on in lessc and strictMath:true in JavaScript.
  • +
  • change lessc option for strict units to --strict-units=off
  • +
+ +

+1.4.0 Beta 3

+ +

2013-04-30

+ +
    +
  • strictUnits now defaults to false and the true case now gives more useful but less correct results, e.g. 2px/1px = 2px
  • +
  • Process ./ when having relative paths
  • +
  • add isunit function for mixin guards and non basic units
  • +
  • extends recognise attributes
  • +
  • exception errors extend the JavaScript Error
  • +
  • remove es-5-shim as standard from the browser
  • +
  • Fix path issues with windows/linux local paths
  • +
+ +

+1.4.0 Beta 1 & 2

+ +

2013-03-07

+ +
    +
  • support for :extend() in selectors (e.g. input:extend(.button) {}) and &:extend(); in ruleset (e.g. input { &:extend(.button all); })
  • +
  • maths is now only done inside brackets. This means font: statements, media queries and the calc function can use a simpler format without being escaped. Disable this with --strict-maths-off in lessc and strictMaths:false in JavaScript.
  • +
  • units are calculated, e.g. 200cm+1m = 3m, 3px/1px = 3. If you use units inconsistently you will get an error. Suppress this error with --strict-units-off in lessc or strictUnits:false in JavaScript
  • +
  • +(~"@var") selector interpolation is removed. Use @{var} in selectors to have variable selectors
  • +
  • default behaviour of import is to import each file once. @import-once has been removed.
  • +
  • You can specify options on imports to force it to behave as css or less @import (less) "file.css" will process the file as less
  • +
  • variables in mixins no longer 'leak' into their calling scope
  • +
  • added data-uri function which will inline an image into the output css. If ieCompat option is true and file is too large, it will fallback to a url()
  • +
  • significant bug fixes to our debug options
  • +
  • other parameters can be used as defaults in mixins e.g. .a(@a, @b:@a)
  • +
  • an error is shown if properties are used outside of a ruleset
  • +
  • added extract function which picks a value out of a list, e.g. extract(12 13 14, 3) => 14
  • +
  • added luma, hsvhue, hsvsaturation, hsvvalue functions
  • +
  • added pow, pi, mod, tan, sin, cos, atan, asin, acos and sqrt math functions
  • +
  • added convert function, e.g. convert(1rad, deg) => value in degrees
  • +
  • lessc makes output directories if they don't exist
  • +
  • lessc @import supports https and 301's
  • +
  • lessc "-depends" option for lessc writes out the list of import files used in makefile format
  • +
  • lessc "-lint" option just reports errors
  • +
  • support for namespaces in attributes and selector interpolation in attributes
  • +
  • other bug fixes
  • +
+ +

+1.3.3

+ +

2012-12-30

+ +
    +
  • Fix critical bug with mixin call if using multiple brackets
  • +
  • when using the filter contrast function, the function is passed through if the first argument is not a color
  • +
+ +

+1.3.2

+ +

2012-12-28

+ +
    +
  • browser and server url re-writing is now aligned to not re-write (previous lessc behaviour)
  • +
  • url-rewriting can be made to re-write to be relative to the entry file using the relative-urls option (less.relativeUrls option)
  • +
  • rootpath option can be used to add a base path to every url
  • +
  • Support mixin argument separator of ';' so you can pass comma separated values. e.g. .mixin(23px, 12px;); +
  • +
  • Fix lots of problems with named arguments in corner cases, not behaving as expected
  • +
  • hsv, hsva, unit functions
  • +
  • fixed lots more bad error messages
  • +
  • fix @import-once to use the full path, not the relative one for determining if an import has been imported already
  • +
  • support :not(:nth-child(3)) +
  • +
  • mixin guards take units into account
  • +
  • support unicode descriptors (U+00A1-00A9)
  • +
  • support calling mixins with a stack when using & (broken in 1.3.1)
  • +
  • support @namespace and namespace combinators
  • +
  • when using % with colour functions, take into account a colour is out of 256
  • +
  • when doing maths with a % do not divide by 100 and keep the unit
  • +
  • allow url to contain % (e.g. %20 for a space)
  • +
  • if a mixin guard stops execution a default mixin is not required
  • +
  • units are output in strings (use the unit function if you need to get the value without unit)
  • +
  • do not infinite recurse when mixins call mixins of the same name
  • +
  • fix issue on important on mixin calls
  • +
  • fix issue with multiple comments being confused
  • +
  • tolerate multiple semi-colons on rules
  • +
  • ignore subsequant @charset +
  • +
  • syncImport option for node.js to read files syncronously
  • +
  • write the output directory if it is missing
  • +
  • change dependency on cssmin to ycssmin
  • +
  • lessc can load files over http
  • +
  • allow calling less.watch() in non dev mode
  • +
  • don't cache in dev mode
  • +
  • less files cope with query parameters better
  • +
  • sass debug statements are now chrome compatible
  • +
  • modifyVars function added to re-render with different root variables
  • +
+ +

+1.3.1

+ +

2012-10-18

+ +
    +
  • Support for comment and @media debugging statements
  • +
  • bug fix for async access in chrome extensions
  • +
  • new functions tint, shade, multiply, screen, overlay, hardlight, difference, exclusion, average, negation, softlight, red, green, blue, contrast
  • +
  • allow escaped characters in attributes
  • +
  • in selectors support @{a} directly, e.g. .a.@{a} { color: black; }
  • +
  • add fraction parameter to round function
  • +
  • much better support for & selector
  • +
  • preserve order of link statements client side
  • +
  • lessc has better help
  • +
  • rhino version fixed
  • +
  • fix bugs in clientside error handling
  • +
  • support dpi, vmin, vm, dppx, dpcm units
  • +
  • Fix ratios in media statements
  • +
  • in mixin guards allow comparing colors and strings
  • +
  • support for -*-keyframes (for -khtml but now supports any)
  • +
  • in mix function, default weight to 50%
  • +
  • support @import-once
  • +
  • remove duplicate rules in output
  • +
  • implement named parameters when calling mixins
  • +
  • many numerous bug fixes
  • +
+ +

+1.3.0

+ +

2012-03-10

+ +
    +
  • @media bubbling
  • +
  • Support arbitrary entities as selectors
  • +
  • Variadic argument support
  • +
  • Behaviour of zero-arity mixins has changed +
  • +
  • Allow @import directives in any selector
  • +
  • Media-query features can now be a variable
  • +
  • Automatic merging of media-query conditions
  • +
  • Fix global variable leaks
  • +
  • Fix error message on wrong-arity call
  • +
  • Fix an @arguments behaviour bug
  • +
  • Fix :: selector output
  • +
  • Fix a bug when using @media with mixins
  • +
+ +

+1.2.1

+ +

2012-01-15

+ +
    +
  • Fix imports in browser
  • +
  • Improve error reporting in browser
  • +
  • Fix Runtime error reports from imported files
  • +
  • Fix File not found import error reporting
  • +
+ +

+1.2.0

+ +

2012-01-07

+ +
    +
  • Mixin guards
  • +
  • New function percentage +
  • +
  • New color function to parse hex color strings
  • +
  • New type-checking stylesheet functions
  • +
  • Fix Rhino support
  • +
  • Fix bug in string arguments to mixin call
  • +
  • Fix error reporting when index is 0
  • +
  • Fix browser support in WebKit and IE
  • +
  • Fix string interpolation bug when var is empty
  • +
  • Support !important after mixin calls
  • +
  • Support vanilla @keyframes directive
  • +
  • Support variables in certain css selectors, like nth-child +
  • +
  • Support @media and @import features properly
  • +
  • Improve @import support with media features
  • +
  • Improve error reports from imported files
  • +
  • Improve function call error reporting
  • +
  • Improve error-reporting
  • +
+
\ No newline at end of file diff --git a/less.js/less.js_2.2.0/LICENSE.htm b/less.js/less.js_2.2.0/LICENSE.htm new file mode 100644 index 00000000..89d1497f --- /dev/null +++ b/less.js/less.js_2.2.0/LICENSE.htm @@ -0,0 +1 @@ +

less.js is licened under the Apache 2.0 License.

diff --git a/less.js/less.js_2.2.0/less.js b/less.js/less.js_2.2.0/less.js new file mode 100644 index 00000000..718869f2 --- /dev/null +++ b/less.js/less.js_2.2.0/less.js @@ -0,0 +1,9525 @@ +/*! + * Less - Leaner CSS v2.2.0 + * http://lesscss.org + * + * Copyright (c) 2009-2015, Alexis Sellier + * Licensed under the Apache v2 License. + * + */ + + /** * @license Apache v2 + */ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.less=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) || + options.isFileProtocol ? 'development' + : 'production'); + + var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash); + if (dumpLineNumbers) { + options.dumpLineNumbers = dumpLineNumbers[1]; + } + + if (options.useFileCache === undefined) { + options.useFileCache = true; + } + + if (options.onReady === undefined) { + options.onReady = true; + } + +}; + +},{"./browser":3,"./utils":9}],2:[function(require,module,exports){ +/** + * Kicks off less and compiles any stylesheets + * used in the browser distributed version of less + * to kick-start less using the browser api + */ +/*global window */ + +// shim Promise if required +require('promise/polyfill.js'); + +var options = window.less || {}; +require("./add-default-options")(window, options); + +var less = module.exports = require("./index")(window, options); + +if (options.onReady) { + if (/!watch/.test(window.location.hash)) { + less.watch(); + } + + less.pageLoadFinished = less.registerStylesheets().then( + function () { + return less.refresh(less.env === 'development'); + } + ); +} +},{"./add-default-options":1,"./index":7,"promise/polyfill.js":undefined}],3:[function(require,module,exports){ +var utils = require("./utils"); +module.exports = { + createCSS: function (document, styles, sheet) { + // Strip the query-string + var href = sheet.href || ''; + + // If there is no title set, use the filename, minus the extension + var id = 'less:' + (sheet.title || utils.extractId(href)); + + // If this has already been inserted into the DOM, we may need to replace it + var oldStyleNode = document.getElementById(id); + var keepOldStyleNode = false; + + // Create a new stylesheet node for insertion or (if necessary) replacement + var styleNode = document.createElement('style'); + styleNode.setAttribute('type', 'text/css'); + if (sheet.media) { + styleNode.setAttribute('media', sheet.media); + } + styleNode.id = id; + + if (!styleNode.styleSheet) { + styleNode.appendChild(document.createTextNode(styles)); + + // If new contents match contents of oldStyleNode, don't replace oldStyleNode + keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 && + oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue); + } + + var head = document.getElementsByTagName('head')[0]; + + // If there is no oldStyleNode, just append; otherwise, only append if we need + // to replace oldStyleNode with an updated stylesheet + if (oldStyleNode === null || keepOldStyleNode === false) { + var nextEl = sheet && sheet.nextSibling || null; + if (nextEl) { + nextEl.parentNode.insertBefore(styleNode, nextEl); + } else { + head.appendChild(styleNode); + } + } + if (oldStyleNode && keepOldStyleNode === false) { + oldStyleNode.parentNode.removeChild(oldStyleNode); + } + + // For IE. + // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash. + // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head + if (styleNode.styleSheet) { + try { + styleNode.styleSheet.cssText = styles; + } catch (e) { + throw new Error("Couldn't reassign styleSheet.cssText."); + } + } + }, + currentScript: function(window) { + var document = window.document; + return document.currentScript || (function() { + var scripts = document.getElementsByTagName("script"); + return scripts[scripts.length - 1]; + })(); + } +}; + +},{"./utils":9}],4:[function(require,module,exports){ +// Cache system is a bit outdated and could do with work + +module.exports = function(window, options, logger) { + var cache = null; + if (options.env !== 'development') { + try { + cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage; + } catch (_) {} + } + return { + setCSS: function(path, lastModified, styles) { + if (cache) { + logger.info('saving ' + path+ ' to cache.'); + try { + cache.setItem(path, styles); + cache.setItem(path + ':timestamp', lastModified); + } catch(e) { + //TODO - could do with adding more robust error handling + logger.error('failed to save "' + path + '" to local storage for caching.'); + } + } + }, + getCSS: function(path, webInfo) { + var css = cache && cache.getItem(path), + timestamp = cache && cache.getItem(path + ':timestamp'); + + if (timestamp && webInfo.lastModified && + (new Date(webInfo.lastModified).valueOf() === + new Date(timestamp).valueOf())) { + // Use local copy + return css; + } + } + }; +}; + +},{}],5:[function(require,module,exports){ +var utils = require("./utils"), + browser = require("./browser"); + +module.exports = function(window, less, options) { + + function errorHTML(e, rootHref) { + var id = 'less-error-message:' + utils.extractId(rootHref || ""); + var template = '
  • {content}
  • '; + var elem = window.document.createElement('div'), timer, content, errors = []; + var filename = e.filename || rootHref; + var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; + + elem.id = id; + elem.className = "less-error-message"; + + content = '

    ' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + + '

    ' + '

    in ' + filenameNoPath + " "; + + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + + if (e.extract) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':

    ' + + '
      ' + errors.join('') + '
    '; + } + if (e.stack && (e.extract || options.logLevel >= 4)) { + content += '
    Stack Trace
    ' + e.stack.split('\n').slice(1).join('
    '); + } + elem.innerHTML = content; + + // CSS for error messages + browser.createCSS(window.document, [ + '.less-error-message ul, .less-error-message li {', + 'list-style-type: none;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'margin: 0;', + '}', + '.less-error-message label {', + 'font-size: 12px;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'color: #cc7777;', + '}', + '.less-error-message pre {', + 'color: #dd6666;', + 'padding: 4px 0;', + 'margin: 0;', + 'display: inline-block;', + '}', + '.less-error-message pre.line {', + 'color: #ff0000;', + '}', + '.less-error-message h3 {', + 'font-size: 20px;', + 'font-weight: bold;', + 'padding: 15px 0 5px 0;', + 'margin: 0;', + '}', + '.less-error-message a {', + 'color: #10a', + '}', + '.less-error-message .error {', + 'color: red;', + 'font-weight: bold;', + 'padding-bottom: 2px;', + 'border-bottom: 1px dashed red;', + '}' + ].join('\n'), { title: 'error-message' }); + + elem.style.cssText = [ + "font-family: Arial, sans-serif", + "border: 1px solid #e00", + "background-color: #eee", + "border-radius: 5px", + "-webkit-border-radius: 5px", + "-moz-border-radius: 5px", + "color: #e00", + "padding: 15px", + "margin-bottom: 15px" + ].join(';'); + + if (options.env === 'development') { + timer = setInterval(function () { + var document = window.document, + body = document.body; + if (body) { + if (document.getElementById(id)) { + body.replaceChild(elem, document.getElementById(id)); + } else { + body.insertBefore(elem, body.firstChild); + } + clearInterval(timer); + } + }, 10); + } + } + + function error(e, rootHref) { + if (!options.errorReporting || options.errorReporting === "html") { + errorHTML(e, rootHref); + } else if (options.errorReporting === "console") { + errorConsole(e, rootHref); + } else if (typeof options.errorReporting === 'function') { + options.errorReporting("add", e, rootHref); + } + } + + function removeErrorHTML(path) { + var node = window.document.getElementById('less-error-message:' + utils.extractId(path)); + if (node) { + node.parentNode.removeChild(node); + } + } + + function removeErrorConsole(path) { + //no action + } + + function removeError(path) { + if (!options.errorReporting || options.errorReporting === "html") { + removeErrorHTML(path); + } else if (options.errorReporting === "console") { + removeErrorConsole(path); + } else if (typeof options.errorReporting === 'function') { + options.errorReporting("remove", path); + } + } + + function errorConsole(e, rootHref) { + var template = '{line} {content}'; + var filename = e.filename || rootHref; + var errors = []; + var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') + + " in " + filename + " "; + + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + + if (e.extract) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' + + errors.join('\n'); + } + if (e.stack && (e.extract || options.logLevel >= 4)) { + content += '\nStack Trace\n' + e.stack; + } + less.logger.error(content); + } + + return { + add: error, + remove: removeError + }; +}; + +},{"./browser":3,"./utils":9}],6:[function(require,module,exports){ +/*global window, XMLHttpRequest */ + +module.exports = function(options, logger) { + +var AbstractFileManager = require("../less/environment/abstract-file-manager.js"); + +var fileCache = {}; + +//TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load + +function getXMLHttpRequest() { + if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) { + return new XMLHttpRequest(); + } else { + try { + /*global ActiveXObject */ + return new ActiveXObject("Microsoft.XMLHTTP"); + } catch (e) { + logger.error("browser doesn't support AJAX."); + return null; + } + } +} + +var FileManager = function() { +}; + +FileManager.prototype = new AbstractFileManager(); + +FileManager.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() { + return true; +}; +FileManager.prototype.join = function join(basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return this.extractUrlParts(laterPath, basePath).path; +}; +FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) { + + var xhr = getXMLHttpRequest(); + var async = options.isFileProtocol ? options.fileAsync : options.async; + + if (typeof(xhr.overrideMimeType) === 'function') { + xhr.overrideMimeType('text/css'); + } + logger.debug("XHR: Getting '" + url + "'"); + xhr.open('GET', url, async); + xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); + xhr.send(null); + + function handleResponse(xhr, callback, errback) { + if (xhr.status >= 200 && xhr.status < 300) { + callback(xhr.responseText, + xhr.getResponseHeader("Last-Modified")); + } else if (typeof(errback) === 'function') { + errback(xhr.status, url); + } + } + + if (options.isFileProtocol && !options.fileAsync) { + if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { + callback(xhr.responseText); + } else { + errback(xhr.status, url); + } + } else if (async) { + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + handleResponse(xhr, callback, errback); + } + }; + } else { + handleResponse(xhr, callback, errback); + } +}; +FileManager.prototype.supports = function(filename, currentDirectory, options, environment) { + return true; +}; + +FileManager.prototype.clearFileCache = function() { + fileCache = {}; +}; + +FileManager.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment, callback) { + if (currentDirectory && !this.isPathAbsolute(filename)) { + filename = currentDirectory + filename; + } + + options = options || {}; + + // sheet may be set to the stylesheet for the initial load or a collection of properties including + // some context variables for imports + var hrefParts = this.extractUrlParts(filename, window.location.href); + var href = hrefParts.url; + + if (options.useFileCache && fileCache[href]) { + try { + var lessText = fileCache[href]; + callback(null, { contents: lessText, filename: href, webInfo: { lastModified: new Date() }}); + } catch (e) { + callback({filename: href, message: "Error loading file " + href + " error was " + e.message}); + } + return; + } + + this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) { + // per file cache + fileCache[href] = data; + + // Use remote copy (re-parse) + callback(null, { contents: data, filename: href, webInfo: { lastModified: lastModified }}); + }, function doXHRError(status, url) { + callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href }); + }); +}; + +return FileManager; +}; + +},{"../less/environment/abstract-file-manager.js":14}],7:[function(require,module,exports){ +// +// index.js +// Should expose the additional browser functions on to the less object +// +var addDataAttr = require("./utils").addDataAttr, + browser = require("./browser"); + +module.exports = function(window, options) { +var document = window.document; +var less = require('../less')(); +module.exports = less; +less.options = options; +var environment = less.environment, + FileManager = require("./file-manager")(options, less.logger), + fileManager = new FileManager(); +environment.addFileManager(fileManager); +less.FileManager = FileManager; + +require("./log-listener")(less, options); +var errors = require("./error-reporting")(window, less, options); +var cache = less.cache = options.cache || require("./cache")(window, options, less.logger); + +//Setup user functions +if (options.functions) { + less.functions.functionRegistry.addMultiple(options.functions); +} + +var typePattern = /^text\/(x-)?less$/; + +function postProcessCSS(styles) { + if (options.postProcessor && typeof options.postProcessor === 'function') { + styles = options.postProcessor.call(styles, styles) || styles; + } + return styles; +} + +function clone(obj) { + var cloned = {}; + for(var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } + } + return cloned; +} + +// only really needed for phantom +function bind(func, thisArg) { + var curryArgs = Array.prototype.slice.call(arguments, 2); + return function() { + var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0)); + return func.apply(thisArg, args); + }; +} + +function loadStyles(modifyVars) { + var styles = document.getElementsByTagName('style'), + style; + + for (var i = 0; i < styles.length; i++) { + style = styles[i]; + if (style.type.match(typePattern)) { + var instanceOptions = clone(options); + instanceOptions.modifyVars = modifyVars; + var lessText = style.innerHTML || ''; + instanceOptions.filename = document.location.href.replace(/#.*$/, ''); + + /*jshint loopfunc:true */ + // use closure to store current style + less.render(lessText, instanceOptions, + bind(function(style, e, result) { + if (e) { + errors.add(e, "inline"); + } else { + style.type = 'text/css'; + if (style.styleSheet) { + style.styleSheet.cssText = result.css; + } else { + style.innerHTML = result.css; + } + } + }, null, style)); + } + } +} + +function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { + + var instanceOptions = clone(options); + addDataAttr(instanceOptions, sheet); + instanceOptions.mime = sheet.type; + + if (modifyVars) { + instanceOptions.modifyVars = modifyVars; + } + + function loadInitialFileCallback(loadedFile) { + + var data = loadedFile.contents, + path = loadedFile.filename, + webInfo = loadedFile.webInfo; + + var newFileInfo = { + currentDirectory: fileManager.getPath(path), + filename: path, + rootFilename: path, + relativeUrls: instanceOptions.relativeUrls}; + + newFileInfo.entryPath = newFileInfo.currentDirectory; + newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory; + + if (webInfo) { + webInfo.remaining = remaining; + + if (!instanceOptions.modifyVars) { + var css = cache.getCSS(path, webInfo); + if (!reload && css) { + webInfo.local = true; + callback(null, null, data, sheet, webInfo, path); + return; + } + } + } + + //TODO add tests around how this behaves when reloading + errors.remove(path); + + instanceOptions.rootFileInfo = newFileInfo; + less.render(data, instanceOptions, function(e, result) { + if (e) { + e.href = path; + callback(e); + } else { + result.css = postProcessCSS(result.css); + if (!instanceOptions.modifyVars) { + cache.setCSS(sheet.href, webInfo.lastModified, result.css); + } + callback(null, result.css, data, sheet, webInfo, path); + } + }); + } + + fileManager.loadFile(sheet.href, null, instanceOptions, environment, function(e, loadedFile) { + if (e) { + callback(e); + return; + } + loadInitialFileCallback(loadedFile); + }); +} + +function loadStyleSheets(callback, reload, modifyVars) { + for (var i = 0; i < less.sheets.length; i++) { + loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); + } +} + +function initRunningMode(){ + if (less.env === 'development') { + less.watchTimer = setInterval(function () { + if (less.watchMode) { + fileManager.clearFileCache(); + loadStyleSheets(function (e, css, _, sheet, webInfo) { + if (e) { + errors.add(e, e.href || sheet.href); + } else if (css) { + browser.createCSS(window.document, css, sheet); + } + }); + } + }, options.poll); + } +} + +// +// Watch mode +// +less.watch = function () { + if (!less.watchMode ){ + less.env = 'development'; + initRunningMode(); + } + this.watchMode = true; + return true; +}; + +less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; }; + +// +// Get all tags with the 'rel' attribute set to "stylesheet/less" +// +less.registerStylesheets = function() { + return new Promise(function(resolve, reject) { + var links = document.getElementsByTagName('link'); + less.sheets = []; + + for (var i = 0; i < links.length; i++) { + if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) && + (links[i].type.match(typePattern)))) { + less.sheets.push(links[i]); + } + } + + resolve(); + }); +}; + +// +// With this function, it's possible to alter variables and re-render +// CSS without reloading less-files +// +less.modifyVars = function(record) { + return less.refresh(true, record, false); +}; + +less.refresh = function (reload, modifyVars, clearFileCache) { + if ((reload || clearFileCache) && clearFileCache !== false) { + fileManager.clearFileCache(); + } + return new Promise(function (resolve, reject) { + var startTime, endTime, totalMilliseconds; + startTime = endTime = new Date(); + + loadStyleSheets(function (e, css, _, sheet, webInfo) { + if (e) { + errors.add(e, e.href || sheet.href); + reject(e); + return; + } + if (webInfo.local) { + less.logger.info("loading " + sheet.href + " from cache."); + } else { + less.logger.info("rendered " + sheet.href + " successfully."); + } + browser.createCSS(window.document, css, sheet); + less.logger.info("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms'); + if (webInfo.remaining === 0) { + totalMilliseconds = new Date() - startTime; + less.logger.info("less has finished. css generated in " + totalMilliseconds + 'ms'); + resolve({ + startTime: startTime, + endTime: endTime, + totalMilliseconds: totalMilliseconds, + sheets: less.sheets.length + }); + } + endTime = new Date(); + }, reload, modifyVars); + + loadStyles(modifyVars); + }); +}; + +less.refreshStyles = loadStyles; + return less; +}; + +},{"../less":29,"./browser":3,"./cache":4,"./error-reporting":5,"./file-manager":6,"./log-listener":8,"./utils":9}],8:[function(require,module,exports){ +module.exports = function(less, options) { + + var logLevel_debug = 4, + logLevel_info = 3, + logLevel_warn = 2, + logLevel_error = 1; + + // The amount of logging in the javascript console. + // 3 - Debug, information and errors + // 2 - Information and errors + // 1 - Errors + // 0 - None + // Defaults to 2 + options.logLevel = typeof(options.logLevel) !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error); + + if (!options.loggers) { + options.loggers = [{ + debug: function(msg) { + if (options.logLevel >= logLevel_debug) { + console.log(msg); + } + }, + info: function(msg) { + if (options.logLevel >= logLevel_info) { + console.log(msg); + } + }, + warn: function(msg) { + if (options.logLevel >= logLevel_warn) { + console.warn(msg); + } + }, + error: function(msg) { + if (options.logLevel >= logLevel_error) { + console.error(msg); + } + } + }]; + } + for(var i = 0; i < options.loggers.length; i++) { + less.logger.addListener(options.loggers[i]); + } +}; + +},{}],9:[function(require,module,exports){ +module.exports = { + extractId: function(href) { + return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain + .replace(/[\?\&]livereload=\w+/,'' ) // Remove LiveReload cachebuster + .replace(/^\//, '' ) // Remove root / + .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension + .replace(/[^\.\w-]+/g, '-') // Replace illegal characters + .replace(/\./g, ':'); // Replace dots with colons(for valid id) + }, + addDataAttr: function(options, tag) { + for (var opt in tag.dataset) { + if (tag.dataset.hasOwnProperty(opt)) { + if (opt === "env" || opt === "dumpLineNumbers" || opt === "rootpath" || opt === "errorReporting") { + options[opt] = tag.dataset[opt]; + } else { + try { + options[opt] = JSON.parse(tag.dataset[opt]); + } + catch(_) {} + } + } + } + } +}; + +},{}],10:[function(require,module,exports){ +var contexts = {}; +module.exports = contexts; + +var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) { + if (!original) { return; } + + for(var i = 0; i < propertiesToCopy.length; i++) { + if (original.hasOwnProperty(propertiesToCopy[i])) { + destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; + } + } +}; + +/* + parse is used whilst parsing + */ +var parseCopyProperties = [ + // options + 'paths', // option - unmodified - paths to search for imports on + 'relativeUrls', // option - whether to adjust URL's to be relative + 'rootpath', // option - rootpath to append to URL's + 'strictImports', // option - + 'insecure', // option - whether to allow imports from insecure ssl hosts + 'dumpLineNumbers', // option - whether to dump line numbers + 'compress', // option - whether to compress + 'syncImport', // option - whether to import synchronously + 'chunkInput', // option - whether to chunk input. more performant but causes parse issues. + 'mime', // browser only - mime type for sheet import + 'useFileCache', // browser only - whether to use the per file session cache + // context + 'processImports', // option & context - whether to process imports. if false then imports will not be imported. + // Used by the import manager to stop multiple import visitors being created. + 'reference', // Used to indicate that the contents are imported by reference + 'pluginManager' // Used as the plugin manager for the session +]; + +contexts.Parse = function(options) { + copyFromOriginal(options, this, parseCopyProperties); + + if (typeof this.paths === "string") { this.paths = [this.paths]; } +}; + +var evalCopyProperties = [ + 'compress', // whether to compress + 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri) + 'strictMath', // whether math has to be within parenthesis + 'strictUnits', // whether units need to evaluate correctly + 'sourceMap', // whether to output a source map + 'importMultiple', // whether we are currently importing multiple copies + 'urlArgs', // whether to add args into url tokens + 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true + 'pluginManager', // Used as the plugin manager for the session + 'importantScope' // used to bubble up !important statements + ]; + +contexts.Eval = function(options, frames) { + copyFromOriginal(options, this, evalCopyProperties); + + this.frames = frames || []; + this.importantScope = this.importantScope || []; +}; + +contexts.Eval.prototype.inParenthesis = function () { + if (!this.parensStack) { + this.parensStack = []; + } + this.parensStack.push(true); +}; + +contexts.Eval.prototype.outOfParenthesis = function () { + this.parensStack.pop(); +}; + +contexts.Eval.prototype.isMathOn = function () { + return this.strictMath ? (this.parensStack && this.parensStack.length) : true; +}; + +contexts.Eval.prototype.isPathRelative = function (path) { + return !/^(?:[a-z-]+:|\/)/i.test(path); +}; + +contexts.Eval.prototype.normalizePath = function( path ) { + var + segments = path.split("/").reverse(), + segment; + + path = []; + while (segments.length !== 0 ) { + segment = segments.pop(); + switch( segment ) { + case ".": + break; + case "..": + if ((path.length === 0) || (path[path.length - 1] === "..")) { + path.push( segment ); + } else { + path.pop(); + } + break; + default: + path.push( segment ); + break; + } + } + + return path.join("/"); +}; + +//todo - do the same for the toCSS ? + + +},{}],11:[function(require,module,exports){ +module.exports = { + 'aliceblue':'#f0f8ff', + 'antiquewhite':'#faebd7', + 'aqua':'#00ffff', + 'aquamarine':'#7fffd4', + 'azure':'#f0ffff', + 'beige':'#f5f5dc', + 'bisque':'#ffe4c4', + 'black':'#000000', + 'blanchedalmond':'#ffebcd', + 'blue':'#0000ff', + 'blueviolet':'#8a2be2', + 'brown':'#a52a2a', + 'burlywood':'#deb887', + 'cadetblue':'#5f9ea0', + 'chartreuse':'#7fff00', + 'chocolate':'#d2691e', + 'coral':'#ff7f50', + 'cornflowerblue':'#6495ed', + 'cornsilk':'#fff8dc', + 'crimson':'#dc143c', + 'cyan':'#00ffff', + 'darkblue':'#00008b', + 'darkcyan':'#008b8b', + 'darkgoldenrod':'#b8860b', + 'darkgray':'#a9a9a9', + 'darkgrey':'#a9a9a9', + 'darkgreen':'#006400', + 'darkkhaki':'#bdb76b', + 'darkmagenta':'#8b008b', + 'darkolivegreen':'#556b2f', + 'darkorange':'#ff8c00', + 'darkorchid':'#9932cc', + 'darkred':'#8b0000', + 'darksalmon':'#e9967a', + 'darkseagreen':'#8fbc8f', + 'darkslateblue':'#483d8b', + 'darkslategray':'#2f4f4f', + 'darkslategrey':'#2f4f4f', + 'darkturquoise':'#00ced1', + 'darkviolet':'#9400d3', + 'deeppink':'#ff1493', + 'deepskyblue':'#00bfff', + 'dimgray':'#696969', + 'dimgrey':'#696969', + 'dodgerblue':'#1e90ff', + 'firebrick':'#b22222', + 'floralwhite':'#fffaf0', + 'forestgreen':'#228b22', + 'fuchsia':'#ff00ff', + 'gainsboro':'#dcdcdc', + 'ghostwhite':'#f8f8ff', + 'gold':'#ffd700', + 'goldenrod':'#daa520', + 'gray':'#808080', + 'grey':'#808080', + 'green':'#008000', + 'greenyellow':'#adff2f', + 'honeydew':'#f0fff0', + 'hotpink':'#ff69b4', + 'indianred':'#cd5c5c', + 'indigo':'#4b0082', + 'ivory':'#fffff0', + 'khaki':'#f0e68c', + 'lavender':'#e6e6fa', + 'lavenderblush':'#fff0f5', + 'lawngreen':'#7cfc00', + 'lemonchiffon':'#fffacd', + 'lightblue':'#add8e6', + 'lightcoral':'#f08080', + 'lightcyan':'#e0ffff', + 'lightgoldenrodyellow':'#fafad2', + 'lightgray':'#d3d3d3', + 'lightgrey':'#d3d3d3', + 'lightgreen':'#90ee90', + 'lightpink':'#ffb6c1', + 'lightsalmon':'#ffa07a', + 'lightseagreen':'#20b2aa', + 'lightskyblue':'#87cefa', + 'lightslategray':'#778899', + 'lightslategrey':'#778899', + 'lightsteelblue':'#b0c4de', + 'lightyellow':'#ffffe0', + 'lime':'#00ff00', + 'limegreen':'#32cd32', + 'linen':'#faf0e6', + 'magenta':'#ff00ff', + 'maroon':'#800000', + 'mediumaquamarine':'#66cdaa', + 'mediumblue':'#0000cd', + 'mediumorchid':'#ba55d3', + 'mediumpurple':'#9370d8', + 'mediumseagreen':'#3cb371', + 'mediumslateblue':'#7b68ee', + 'mediumspringgreen':'#00fa9a', + 'mediumturquoise':'#48d1cc', + 'mediumvioletred':'#c71585', + 'midnightblue':'#191970', + 'mintcream':'#f5fffa', + 'mistyrose':'#ffe4e1', + 'moccasin':'#ffe4b5', + 'navajowhite':'#ffdead', + 'navy':'#000080', + 'oldlace':'#fdf5e6', + 'olive':'#808000', + 'olivedrab':'#6b8e23', + 'orange':'#ffa500', + 'orangered':'#ff4500', + 'orchid':'#da70d6', + 'palegoldenrod':'#eee8aa', + 'palegreen':'#98fb98', + 'paleturquoise':'#afeeee', + 'palevioletred':'#d87093', + 'papayawhip':'#ffefd5', + 'peachpuff':'#ffdab9', + 'peru':'#cd853f', + 'pink':'#ffc0cb', + 'plum':'#dda0dd', + 'powderblue':'#b0e0e6', + 'purple':'#800080', + 'rebeccapurple':'#663399', + 'red':'#ff0000', + 'rosybrown':'#bc8f8f', + 'royalblue':'#4169e1', + 'saddlebrown':'#8b4513', + 'salmon':'#fa8072', + 'sandybrown':'#f4a460', + 'seagreen':'#2e8b57', + 'seashell':'#fff5ee', + 'sienna':'#a0522d', + 'silver':'#c0c0c0', + 'skyblue':'#87ceeb', + 'slateblue':'#6a5acd', + 'slategray':'#708090', + 'slategrey':'#708090', + 'snow':'#fffafa', + 'springgreen':'#00ff7f', + 'steelblue':'#4682b4', + 'tan':'#d2b48c', + 'teal':'#008080', + 'thistle':'#d8bfd8', + 'tomato':'#ff6347', + 'turquoise':'#40e0d0', + 'violet':'#ee82ee', + 'wheat':'#f5deb3', + 'white':'#ffffff', + 'whitesmoke':'#f5f5f5', + 'yellow':'#ffff00', + 'yellowgreen':'#9acd32' +}; +},{}],12:[function(require,module,exports){ +module.exports = { + colors: require("./colors"), + unitConversions: require("./unit-conversions") +}; + +},{"./colors":11,"./unit-conversions":13}],13:[function(require,module,exports){ +module.exports = { + length: { + 'm': 1, + 'cm': 0.01, + 'mm': 0.001, + 'in': 0.0254, + 'px': 0.0254 / 96, + 'pt': 0.0254 / 72, + 'pc': 0.0254 / 72 * 12 + }, + duration: { + 's': 1, + 'ms': 0.001 + }, + angle: { + 'rad': 1/(2*Math.PI), + 'deg': 1/360, + 'grad': 1/400, + 'turn': 1 + } +}; +},{}],14:[function(require,module,exports){ +var abstractFileManager = function() { +}; + +abstractFileManager.prototype.getPath = function (filename) { + var j = filename.lastIndexOf('?'); + if (j > 0) { + filename = filename.slice(0, j); + } + j = filename.lastIndexOf('/'); + if (j < 0) { + j = filename.lastIndexOf('\\'); + } + if (j < 0) { + return ""; + } + return filename.slice(0, j + 1); +}; + +abstractFileManager.prototype.tryAppendLessExtension = function(path) { + return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + '.less'; +}; + +abstractFileManager.prototype.supportsSync = function() { + return false; +}; + +abstractFileManager.prototype.alwaysMakePathsAbsolute = function() { + return false; +}; + +abstractFileManager.prototype.isPathAbsolute = function(filename) { + return (/^(?:[a-z-]+:|\/|\\)/i).test(filename); +}; + +abstractFileManager.prototype.join = function(basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return basePath + laterPath; +}; +abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) { + // diff between two paths to create a relative path + + var urlParts = this.extractUrlParts(url), + baseUrlParts = this.extractUrlParts(baseUrl), + i, max, urlDirectories, baseUrlDirectories, diff = ""; + if (urlParts.hostPart !== baseUrlParts.hostPart) { + return ""; + } + max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); + for(i = 0; i < max; i++) { + if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; } + } + baseUrlDirectories = baseUrlParts.directories.slice(i); + urlDirectories = urlParts.directories.slice(i); + for(i = 0; i < baseUrlDirectories.length-1; i++) { + diff += "../"; + } + for(i = 0; i < urlDirectories.length-1; i++) { + diff += urlDirectories[i] + "/"; + } + return diff; +}; +// helper function, not part of API +abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, baseUrl) { + // urlParts[1] = protocol&hostname || / + // urlParts[2] = / if path relative to host base + // urlParts[3] = directories + // urlParts[4] = filename + // urlParts[5] = parameters + + var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i, + urlParts = url.match(urlPartsRegex), + returner = {}, directories = [], i, baseUrlParts; + + if (!urlParts) { + throw new Error("Could not parse sheet href - '" + url + "'"); + } + + // Stylesheets in IE don't always return the full path + if (baseUrl && (!urlParts[1] || urlParts[2])) { + baseUrlParts = baseUrl.match(urlPartsRegex); + if (!baseUrlParts) { + throw new Error("Could not parse page url - '"+baseUrl+"'"); + } + urlParts[1] = urlParts[1] || baseUrlParts[1] || ""; + if (!urlParts[2]) { + urlParts[3] = baseUrlParts[3] + urlParts[3]; + } + } + + if (urlParts[3]) { + directories = urlParts[3].replace(/\\/g, "/").split("/"); + + // extract out . before .. so .. doesn't absorb a non-directory + for(i = 0; i < directories.length; i++) { + if (directories[i] === ".") { + directories.splice(i, 1); + i -= 1; + } + } + + for(i = 0; i < directories.length; i++) { + if (directories[i] === ".." && i > 0) { + directories.splice(i-1, 2); + i -= 2; + } + } + } + + returner.hostPart = urlParts[1]; + returner.directories = directories; + returner.path = (urlParts[1] || "") + directories.join("/"); + returner.fileUrl = returner.path + (urlParts[4] || ""); + returner.url = returner.fileUrl + (urlParts[5] || ""); + return returner; +}; + +module.exports = abstractFileManager; + +},{}],15:[function(require,module,exports){ +var logger = require("../logger"); +var environment = function(externalEnvironment, fileManagers) { + this.fileManagers = fileManagers || []; + externalEnvironment = externalEnvironment || {}; + + var optionalFunctions = ["encodeBase64", "mimeLookup", "charsetLookup", "getSourceMapGenerator"], + requiredFunctions = [], + functions = requiredFunctions.concat(optionalFunctions); + + for(var i = 0; i < functions.length; i++) { + var propName = functions[i], + environmentFunc = externalEnvironment[propName]; + if (environmentFunc) { + this[propName] = environmentFunc.bind(externalEnvironment); + } else if (i < requiredFunctions.length) { + this.warn("missing required function in environment - " + propName); + } + } +}; + +environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) { + + if (!filename) { + logger.warn("getFileManager called with no filename.. Please report this issue. continuing."); + } + if (currentDirectory == null) { + logger.warn("getFileManager called with null directory.. Please report this issue. continuing."); + } + + var fileManagers = this.fileManagers; + if (options.pluginManager) { + fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); + } + for(var i = fileManagers.length - 1; i >= 0 ; i--) { + var fileManager = fileManagers[i]; + if (fileManager[isSync ? "supportsSync" : "supports"](filename, currentDirectory, options, environment)) { + return fileManager; + } + } + return null; +}; + +environment.prototype.addFileManager = function (fileManager) { + this.fileManagers.push(fileManager); +}; + +environment.prototype.clearFileManagers = function () { + this.fileManagers = []; +}; + +module.exports = environment; + +},{"../logger":31}],16:[function(require,module,exports){ +var Color = require("../tree/color"), + functionRegistry = require("./function-registry"); + +// Color Blending +// ref: http://www.w3.org/TR/compositing-1 + +function colorBlend(mode, color1, color2) { + var ab = color1.alpha, cb, // backdrop + as = color2.alpha, cs, // source + ar, cr, r = []; // result + + ar = as + ab * (1 - as); + for (var i = 0; i < 3; i++) { + cb = color1.rgb[i] / 255; + cs = color2.rgb[i] / 255; + cr = mode(cb, cs); + if (ar) { + cr = (as * cs + ab * (cb - + as * (cb + cs - cr))) / ar; + } + r[i] = cr * 255; + } + + return new Color(r, ar); +} + +var colorBlendModeFunctions = { + multiply: function(cb, cs) { + return cb * cs; + }, + screen: function(cb, cs) { + return cb + cs - cb * cs; + }, + overlay: function(cb, cs) { + cb *= 2; + return (cb <= 1) + ? colorBlendModeFunctions.multiply(cb, cs) + : colorBlendModeFunctions.screen(cb - 1, cs); + }, + softlight: function(cb, cs) { + var d = 1, e = cb; + if (cs > 0.5) { + e = 1; + d = (cb > 0.25) ? Math.sqrt(cb) + : ((16 * cb - 12) * cb + 4) * cb; + } + return cb - (1 - 2 * cs) * e * (d - cb); + }, + hardlight: function(cb, cs) { + return colorBlendModeFunctions.overlay(cs, cb); + }, + difference: function(cb, cs) { + return Math.abs(cb - cs); + }, + exclusion: function(cb, cs) { + return cb + cs - 2 * cb * cs; + }, + + // non-w3c functions: + average: function(cb, cs) { + return (cb + cs) / 2; + }, + negation: function(cb, cs) { + return 1 - Math.abs(cb + cs - 1); + } +}; + +for (var f in colorBlendModeFunctions) { + if (colorBlendModeFunctions.hasOwnProperty(f)) { + colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); + } +} + +functionRegistry.addMultiple(colorBlend); + +},{"../tree/color":47,"./function-registry":21}],17:[function(require,module,exports){ +var Dimension = require("../tree/dimension"), + Color = require("../tree/color"), + Quoted = require("../tree/quoted"), + Anonymous = require("../tree/anonymous"), + functionRegistry = require("./function-registry"), + colorFunctions; + +function clamp(val) { + return Math.min(1, Math.max(0, val)); +} +function hsla(color) { + return colorFunctions.hsla(color.h, color.s, color.l, color.a); +} +function number(n) { + if (n instanceof Dimension) { + return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); + } else if (typeof(n) === 'number') { + return n; + } else { + throw { + type: "Argument", + message: "color functions take numbers as parameters" + }; + } +} +function scaled(n, size) { + if (n instanceof Dimension && n.unit.is('%')) { + return parseFloat(n.value * size / 100); + } else { + return number(n); + } +} +colorFunctions = { + rgb: function (r, g, b) { + return colorFunctions.rgba(r, g, b, 1.0); + }, + rgba: function (r, g, b, a) { + var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); + a = number(a); + return new Color(rgb, a); + }, + hsl: function (h, s, l) { + return colorFunctions.hsla(h, s, l, 1.0); + }, + hsla: function (h, s, l, a) { + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { return m1 + (m2 - m1) * h * 6; } + else if (h * 2 < 1) { return m2; } + else if (h * 3 < 2) { return m1 + (m2 - m1) * (2/3 - h) * 6; } + else { return m1; } + } + + h = (number(h) % 360) / 360; + s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a)); + + var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + var m1 = l * 2 - m2; + + return colorFunctions.rgba(hue(h + 1/3) * 255, + hue(h) * 255, + hue(h - 1/3) * 255, + a); + }, + + hsv: function(h, s, v) { + return colorFunctions.hsva(h, s, v, 1.0); + }, + + hsva: function(h, s, v, a) { + h = ((number(h) % 360) / 360) * 360; + s = number(s); v = number(v); a = number(a); + + var i, f; + i = Math.floor((h / 60) % 6); + f = (h / 60) - i; + + var vs = [v, + v * (1 - s), + v * (1 - f * s), + v * (1 - (1 - f) * s)]; + var perm = [[0, 3, 1], + [2, 0, 1], + [1, 0, 3], + [1, 2, 0], + [3, 1, 0], + [0, 1, 2]]; + + return colorFunctions.rgba(vs[perm[i][0]] * 255, + vs[perm[i][1]] * 255, + vs[perm[i][2]] * 255, + a); + }, + + hue: function (color) { + return new Dimension(color.toHSL().h); + }, + saturation: function (color) { + return new Dimension(color.toHSL().s * 100, '%'); + }, + lightness: function (color) { + return new Dimension(color.toHSL().l * 100, '%'); + }, + hsvhue: function(color) { + return new Dimension(color.toHSV().h); + }, + hsvsaturation: function (color) { + return new Dimension(color.toHSV().s * 100, '%'); + }, + hsvvalue: function (color) { + return new Dimension(color.toHSV().v * 100, '%'); + }, + red: function (color) { + return new Dimension(color.rgb[0]); + }, + green: function (color) { + return new Dimension(color.rgb[1]); + }, + blue: function (color) { + return new Dimension(color.rgb[2]); + }, + alpha: function (color) { + return new Dimension(color.toHSL().a); + }, + luma: function (color) { + return new Dimension(color.luma() * color.alpha * 100, '%'); + }, + luminance: function (color) { + var luminance = + (0.2126 * color.rgb[0] / 255) + + (0.7152 * color.rgb[1] / 255) + + (0.0722 * color.rgb[2] / 255); + + return new Dimension(luminance * color.alpha * 100, '%'); + }, + saturate: function (color, amount) { + // filter: saturate(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + var hsl = color.toHSL(); + + hsl.s += amount.value / 100; + hsl.s = clamp(hsl.s); + return hsla(hsl); + }, + desaturate: function (color, amount) { + var hsl = color.toHSL(); + + hsl.s -= amount.value / 100; + hsl.s = clamp(hsl.s); + return hsla(hsl); + }, + lighten: function (color, amount) { + var hsl = color.toHSL(); + + hsl.l += amount.value / 100; + hsl.l = clamp(hsl.l); + return hsla(hsl); + }, + darken: function (color, amount) { + var hsl = color.toHSL(); + + hsl.l -= amount.value / 100; + hsl.l = clamp(hsl.l); + return hsla(hsl); + }, + fadein: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a += amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + fadeout: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a -= amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + fade: function (color, amount) { + var hsl = color.toHSL(); + + hsl.a = amount.value / 100; + hsl.a = clamp(hsl.a); + return hsla(hsl); + }, + spin: function (color, amount) { + var hsl = color.toHSL(); + var hue = (hsl.h + amount.value) % 360; + + hsl.h = hue < 0 ? 360 + hue : hue; + + return hsla(hsl); + }, + // + // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein + // http://sass-lang.com + // + mix: function (color1, color2, weight) { + if (!weight) { + weight = new Dimension(50); + } + var p = weight.value / 100.0; + var w = p * 2 - 1; + var a = color1.toHSL().a - color2.toHSL().a; + + var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, + color1.rgb[1] * w1 + color2.rgb[1] * w2, + color1.rgb[2] * w1 + color2.rgb[2] * w2]; + + var alpha = color1.alpha * p + color2.alpha * (1 - p); + + return new Color(rgb, alpha); + }, + greyscale: function (color) { + return colorFunctions.desaturate(color, new Dimension(100)); + }, + contrast: function (color, dark, light, threshold) { + // filter: contrast(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + if (typeof light === 'undefined') { + light = colorFunctions.rgba(255, 255, 255, 1.0); + } + if (typeof dark === 'undefined') { + dark = colorFunctions.rgba(0, 0, 0, 1.0); + } + //Figure out which is actually light and dark! + if (dark.luma() > light.luma()) { + var t = light; + light = dark; + dark = t; + } + if (typeof threshold === 'undefined') { + threshold = 0.43; + } else { + threshold = number(threshold); + } + if (color.luma() < threshold) { + return light; + } else { + return dark; + } + }, + argb: function (color) { + return new Anonymous(color.toARGB()); + }, + color: function(c) { + if ((c instanceof Quoted) && + (/^#([a-f0-9]{6}|[a-f0-9]{3})$/i.test(c.value))) { + return new Color(c.value.slice(1)); + } + if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) { + c.keyword = undefined; + return c; + } + throw { + type: "Argument", + message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF" + }; + }, + tint: function(color, amount) { + return colorFunctions.mix(colorFunctions.rgb(255,255,255), color, amount); + }, + shade: function(color, amount) { + return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); + } +}; +functionRegistry.addMultiple(colorFunctions); + +},{"../tree/anonymous":43,"../tree/color":47,"../tree/dimension":53,"../tree/quoted":70,"./function-registry":21}],18:[function(require,module,exports){ +module.exports = function(environment) { + var Quoted = require("../tree/quoted"), + URL = require("../tree/url"), + functionRegistry = require("./function-registry"), + fallback = function(functionThis, node) { + return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); + }, + logger = require('../logger'); + + functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) { + + if (!filePathNode) { + filePathNode = mimetypeNode; + mimetypeNode = null; + } + + var mimetype = mimetypeNode && mimetypeNode.value; + var filePath = filePathNode.value; + var currentDirectory = filePathNode.currentFileInfo.relativeUrls ? + filePathNode.currentFileInfo.currentDirectory : filePathNode.currentFileInfo.entryPath; + + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart!==-1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + + var fileManager = environment.getFileManager(filePath, currentDirectory, this.context, environment, true); + + if (!fileManager) { + return fallback(this, filePathNode); + } + + var useBase64 = false; + + // detect the mimetype if not given + if (!mimetypeNode) { + + mimetype = environment.mimeLookup(filePath); + + if (mimetype === "image/svg+xml") { + useBase64 = false; + } else { + // use base 64 unless it's an ASCII or UTF-8 format + var charset = environment.charsetLookup(mimetype); + useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; + } + if (useBase64) { mimetype += ';base64'; } + } + else { + useBase64 = /;base64$/.test(mimetype); + } + + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment); + if (!fileSync.contents) { + logger.warn("Skipped data-uri embedding because file not found"); + return fallback(this, filePathNode || mimetypeNode); + } + var buf = fileSync.contents; + if (useBase64 && !environment.encodeBase64) { + return fallback(this, filePathNode); + } + + buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); + + var uri = "data:" + mimetype + ',' + buf + fragment; + + // IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded + // and the --ieCompat flag is enabled, return a normal url() instead. + var DATA_URI_MAX = 32768; + if (uri.length >= DATA_URI_MAX) { + + if (this.context.ieCompat !== false) { + logger.warn("Skipped data-uri embedding of " + filePath + " because its size (" + uri.length + " characters) exceeds IE8-safe " + DATA_URI_MAX + " characters!"); + + return fallback(this, filePathNode || mimetypeNode); + } + } + + return new URL(new Quoted('"' + uri + '"', uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + }); +}; + +},{"../logger":31,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],19:[function(require,module,exports){ +var Keyword = require("../tree/keyword"), + functionRegistry = require("./function-registry"); + +var defaultFunc = { + eval: function () { + var v = this.value_, e = this.error_; + if (e) { + throw e; + } + if (v != null) { + return v ? Keyword.True : Keyword.False; + } + }, + value: function (v) { + this.value_ = v; + }, + error: function (e) { + this.error_ = e; + }, + reset: function () { + this.value_ = this.error_ = null; + } +}; + +functionRegistry.add("default", defaultFunc.eval.bind(defaultFunc)); + +module.exports = defaultFunc; + +},{"../tree/keyword":62,"./function-registry":21}],20:[function(require,module,exports){ +var functionRegistry = require("./function-registry"); + +var functionCaller = function(name, context, index, currentFileInfo) { + this.name = name.toLowerCase(); + this.func = functionRegistry.get(this.name); + this.index = index; + this.context = context; + this.currentFileInfo = currentFileInfo; +}; +functionCaller.prototype.isValid = function() { + return Boolean(this.func); +}; +functionCaller.prototype.call = function(args) { + return this.func.apply(this, args); +}; + +module.exports = functionCaller; + +},{"./function-registry":21}],21:[function(require,module,exports){ +module.exports = { + _data: {}, + add: function(name, func) { + if (this._data.hasOwnProperty(name)) { + //TODO warn + } + this._data[name] = func; + }, + addMultiple: function(functions) { + Object.keys(functions).forEach( + function(name) { + this.add(name, functions[name]); + }.bind(this)); + }, + get: function(name) { + return this._data[name]; + } +}; + +},{}],22:[function(require,module,exports){ +module.exports = function(environment) { + var functions = { + functionRegistry: require("./function-registry"), + functionCaller: require("./function-caller") + }; + + //register functions + require("./default"); + require("./color"); + require("./color-blending"); + require("./data-uri")(environment); + require("./math"); + require("./number"); + require("./string"); + require("./svg")(environment); + require("./types"); + + return functions; +}; + +},{"./color":17,"./color-blending":16,"./data-uri":18,"./default":19,"./function-caller":20,"./function-registry":21,"./math":23,"./number":24,"./string":25,"./svg":26,"./types":27}],23:[function(require,module,exports){ +var Dimension = require("../tree/dimension"), + functionRegistry = require("./function-registry"); + +var mathFunctions = { + // name, unit + ceil: null, + floor: null, + sqrt: null, + abs: null, + tan: "", + sin: "", + cos: "", + atan: "rad", + asin: "rad", + acos: "rad" +}; + +function _math(fn, unit, n) { + if (!(n instanceof Dimension)) { + throw { type: "Argument", message: "argument must be a number" }; + } + if (unit == null) { + unit = n.unit; + } else { + n = n.unify(); + } + return new Dimension(fn(parseFloat(n.value)), unit); +} + +for (var f in mathFunctions) { + if (mathFunctions.hasOwnProperty(f)) { + mathFunctions[f] = _math.bind(null, Math[f], mathFunctions[f]); + } +} + +mathFunctions.round = function (n, f) { + var fraction = typeof(f) === "undefined" ? 0 : f.value; + return _math(function(num) { return num.toFixed(fraction); }, null, n); +}; + +functionRegistry.addMultiple(mathFunctions); + +},{"../tree/dimension":53,"./function-registry":21}],24:[function(require,module,exports){ +var Dimension = require("../tree/dimension"), + Anonymous = require("../tree/anonymous"), + functionRegistry = require("./function-registry"); + +var minMax = function (isMin, args) { + args = Array.prototype.slice.call(args); + switch(args.length) { + case 0: throw { type: "Argument", message: "one or more arguments required" }; + } + var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone, + order = [], // elems only contains original argument values. + values = {}; // key is the unit.toString() for unified Dimension values, + // value is the index into the order array. + for (i = 0; i < args.length; i++) { + current = args[i]; + if (!(current instanceof Dimension)) { + if(Array.isArray(args[i].value)) { + Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); + } + continue; + } + currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); + unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); + unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic; + unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone; + j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit]; + if (j === undefined) { + if(unitStatic !== undefined && unit !== unitStatic) { + throw{ type: "Argument", message: "incompatible types" }; + } + values[unit] = order.length; + order.push(current); + continue; + } + referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); + if ( isMin && currentUnified.value < referenceUnified.value || + !isMin && currentUnified.value > referenceUnified.value) { + order[j] = current; + } + } + if (order.length == 1) { + return order[0]; + } + args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? "," : ", "); + return new Anonymous((isMin ? "min" : "max") + "(" + args + ")"); +}; +functionRegistry.addMultiple({ + min: function () { + return minMax(true, arguments); + }, + max: function () { + return minMax(false, arguments); + }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, + pi: function () { + return new Dimension(Math.PI); + }, + mod: function(a, b) { + return new Dimension(a.value % b.value, a.unit); + }, + pow: function(x, y) { + if (typeof x === "number" && typeof y === "number") { + x = new Dimension(x); + y = new Dimension(y); + } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { + throw { type: "Argument", message: "arguments must be numbers" }; + } + + return new Dimension(Math.pow(x.value, y.value), x.unit); + }, + percentage: function (n) { + return new Dimension(n.value * 100, '%'); + } +}); + +},{"../tree/anonymous":43,"../tree/dimension":53,"./function-registry":21}],25:[function(require,module,exports){ +var Quoted = require("../tree/quoted"), + Anonymous = require("../tree/anonymous"), + JavaScript = require("../tree/javascript"), + functionRegistry = require("./function-registry"); + +functionRegistry.addMultiple({ + e: function (str) { + return new Anonymous(str instanceof JavaScript ? str.evaluated : str.value); + }, + escape: function (str) { + return new Anonymous(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29")); + }, + replace: function (string, pattern, replacement, flags) { + var result = string.value; + + result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement.value); + return new Quoted(string.quote || '', result, string.escaped); + }, + '%': function (string /* arg, arg, ...*/) { + var args = Array.prototype.slice.call(arguments, 1), + result = string.value; + + for (var i = 0; i < args.length; i++) { + /*jshint loopfunc:true */ + result = result.replace(/%[sda]/i, function(token) { + var value = token.match(/s/i) ? args[i].value : args[i].toCSS(); + return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; + }); + } + result = result.replace(/%%/g, '%'); + return new Quoted(string.quote || '', result, string.escaped); + } +}); + +},{"../tree/anonymous":43,"../tree/javascript":60,"../tree/quoted":70,"./function-registry":21}],26:[function(require,module,exports){ +module.exports = function(environment) { + var Dimension = require("../tree/dimension"), + Color = require("../tree/color"), + Quoted = require("../tree/quoted"), + URL = require("../tree/url"), + functionRegistry = require("./function-registry"); + + functionRegistry.add("svg-gradient", function(direction) { + + function throwArgumentDescriptor() { + throw { type: "Argument", message: "svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]" }; + } + + if (arguments.length < 3) { + throwArgumentDescriptor(); + } + var stops = Array.prototype.slice.call(arguments, 1), + gradientDirectionSvg, + gradientType = "linear", + rectangleDimension = 'x="0" y="0" width="1" height="1"', + renderEnv = {compress: false}, + returner, + directionValue = direction.toCSS(renderEnv), + i, color, position, positionValue, alpha; + + switch (directionValue) { + case "to bottom": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; + break; + case "to right": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; + break; + case "to bottom right": + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; + break; + case "to top right": + gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; + break; + case "ellipse": + case "ellipse at center": + gradientType = "radial"; + gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; + rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; + break; + default: + throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'" }; + } + returner = '' + + '' + + '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>'; + + for (i = 0; i < stops.length; i+= 1) { + if (stops[i].value) { + color = stops[i].value[0]; + position = stops[i].value[1]; + } else { + color = stops[i]; + position = undefined; + } + + if (!(color instanceof Color) || (!((i === 0 || i+1 === stops.length) && position === undefined) && !(position instanceof Dimension))) { + throwArgumentDescriptor(); + } + positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%"; + alpha = color.alpha; + returner += ''; + } + returner += '' + + ''; + + returner = encodeURIComponent(returner); + + returner = "data:image/svg+xml," + returner; + return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + }); +}; + +},{"../tree/color":47,"../tree/dimension":53,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],27:[function(require,module,exports){ +var Keyword = require("../tree/keyword"), + Dimension = require("../tree/dimension"), + Color = require("../tree/color"), + Quoted = require("../tree/quoted"), + Anonymous = require("../tree/anonymous"), + URL = require("../tree/url"), + Operation = require("../tree/operation"), + functionRegistry = require("./function-registry"); + +var isa = function (n, Type) { + return (n instanceof Type) ? Keyword.True : Keyword.False; + }, + isunit = function (n, unit) { + if (unit === undefined) { + throw { type: "Argument", message: "missing the required second argument to isunit." }; + } + unit = typeof unit.value === "string" ? unit.value : unit; + if (typeof unit !== "string") { + throw { type: "Argument", message: "Second argument to isunit should be a unit or a string." }; + } + return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False; + }; +functionRegistry.addMultiple({ + iscolor: function (n) { + return isa(n, Color); + }, + isnumber: function (n) { + return isa(n, Dimension); + }, + isstring: function (n) { + return isa(n, Quoted); + }, + iskeyword: function (n) { + return isa(n, Keyword); + }, + isurl: function (n) { + return isa(n, URL); + }, + ispixel: function (n) { + return isunit(n, 'px'); + }, + ispercentage: function (n) { + return isunit(n, '%'); + }, + isem: function (n) { + return isunit(n, 'em'); + }, + isunit: isunit, + unit: function (val, unit) { + if(!(val instanceof Dimension)) { + throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof Operation ? ". Have you forgotten parenthesis?" : "") }; + } + if (unit) { + if (unit instanceof Keyword) { + unit = unit.value; + } else { + unit = unit.toCSS(); + } + } else { + unit = ""; + } + return new Dimension(val.value, unit); + }, + "get-unit": function (n) { + return new Anonymous(n.unit); + }, + extract: function(values, index) { + index = index.value - 1; // (1-based index) + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + return Array.isArray(values.value) ? + values.value[index] : Array(values)[index]; + }, + length: function(values) { + var n = Array.isArray(values.value) ? values.value.length : 1; + return new Dimension(n); + } +}); + +},{"../tree/anonymous":43,"../tree/color":47,"../tree/dimension":53,"../tree/keyword":62,"../tree/operation":68,"../tree/quoted":70,"../tree/url":77,"./function-registry":21}],28:[function(require,module,exports){ +var contexts = require("./contexts"), + Parser = require('./parser/parser'); + +module.exports = function(environment) { + + // FileInfo = { + // 'relativeUrls' - option - whether to adjust URL's to be relative + // 'filename' - full resolved filename of current file + // 'rootpath' - path to append to normal URLs for this node + // 'currentDirectory' - path to the current file, absolute + // 'rootFilename' - filename of the base file + // 'entryPath' - absolute path to the entry file + // 'reference' - whether the file should not be output and only output parts that are referenced + + var ImportManager = function(context, rootFileInfo) { + this.rootFilename = rootFileInfo.filename; + this.paths = context.paths || []; // Search paths, when importing + this.contents = {}; // map - filename to contents of all the files + this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore + this.mime = context.mime; + this.error = null; + this.context = context; + // Deprecated? Unused outside of here, could be useful. + this.queue = []; // Files which haven't been imported yet + this.files = {}; // Holds the imported parse trees. + }; + /** + * Add an import to be imported + * @param path - the raw path + * @param tryAppendLessExtension - whether to try appending the less extension (if the path has no extension) + * @param currentFileInfo - the current file info (used for instance to work out relative paths) + * @param importOptions - import options + * @param callback - callback for when it is imported + */ + ImportManager.prototype.push = function (path, tryAppendLessExtension, currentFileInfo, importOptions, callback) { + var importManager = this; + this.queue.push(path); + + var fileParsedFunc = function (e, root, fullPath) { + importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue + + var importedEqualsRoot = fullPath === importManager.rootFilename; + + importManager.files[fullPath] = root; + + if (e && !importManager.error) { importManager.error = e; } + + callback(e, root, importedEqualsRoot, fullPath); + }; + + var newFileInfo = { + relativeUrls: this.context.relativeUrls, + entryPath: currentFileInfo.entryPath, + rootpath: currentFileInfo.rootpath, + rootFilename: currentFileInfo.rootFilename + }; + + var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + + if (!fileManager) { + fileParsedFunc({ message: "Could not find a file-manager for " + path }); + return; + } + + if (tryAppendLessExtension) { + path = fileManager.tryAppendLessExtension(path); + } + + var loadFileCallback = function(loadedFile) { + var resolvedFilename = loadedFile.filename, + contents = loadedFile.contents; + + // Pass on an updated rootpath if path of imported file is relative and file + // is in a (sub|sup) directory + // + // Examples: + // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', + // then rootpath should become 'less/module/nav/' + // - If path of imported file is '../mixins.less' and rootpath is 'less/', + // then rootpath should become 'less/../' + newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); + if(newFileInfo.relativeUrls) { + newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ""), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); + if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { + newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + } + } + newFileInfo.filename = resolvedFilename; + + var newEnv = new contexts.Parse(importManager.context); + + newEnv.processImports = false; + importManager.contents[resolvedFilename] = contents; + + if (currentFileInfo.reference || importOptions.reference) { + newFileInfo.reference = true; + } + + if (importOptions.inline) { + fileParsedFunc(null, contents, resolvedFilename); + } else { + new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { + fileParsedFunc(e, root, resolvedFilename); + }); + } + }; + + var promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, this.context, environment, + function(err, loadedFile) { + if (err) { + fileParsedFunc(err); + } else { + loadFileCallback(loadedFile); + } + }); + if (promise) { + promise.then(loadFileCallback, fileParsedFunc); + } + }; + return ImportManager; +}; + +},{"./contexts":10,"./parser/parser":36}],29:[function(require,module,exports){ +module.exports = function(environment, fileManagers) { + var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment; + + var less = { + version: [2, 2, 0], + data: require('./data'), + tree: require('./tree'), + Environment: (Environment = require("./environment/environment")), + AbstractFileManager: require("./environment/abstract-file-manager"), + environment: (environment = new Environment(environment, fileManagers)), + visitors: require('./visitors'), + Parser: require('./parser/parser'), + functions: require('./functions')(environment), + contexts: require("./contexts"), + SourceMapOutput: (SourceMapOutput = require('./source-map-output')(environment)), + SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder')(SourceMapOutput, environment)), + ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)), + ImportManager: (ImportManager = require('./import-manager')(environment)), + render: require("./render")(environment, ParseTree, ImportManager), + parse: require("./parse")(environment, ParseTree, ImportManager), + LessError: require('./less-error'), + transformTree: require('./transform-tree'), + utils: require('./utils'), + PluginManager: require('./plugin-manager'), + logger: require('./logger') + }; + + return less; +}; + +},{"./contexts":10,"./data":12,"./environment/abstract-file-manager":14,"./environment/environment":15,"./functions":22,"./import-manager":28,"./less-error":30,"./logger":31,"./parse":33,"./parse-tree":32,"./parser/parser":36,"./plugin-manager":37,"./render":38,"./source-map-builder":39,"./source-map-output":40,"./transform-tree":41,"./tree":59,"./utils":80,"./visitors":84}],30:[function(require,module,exports){ +var utils = require("./utils"); + +var LessError = module.exports = function LessError(e, importManager, currentFilename) { + + Error.call(this); + + var filename = e.filename || currentFilename; + + if (importManager && filename) { + var input = importManager.contents[filename], + loc = utils.getLocation(e.index, input), + line = loc.line, + col = loc.column, + callLine = e.call && utils.getLocation(e.call, input).line, + lines = input.split('\n'); + + this.type = e.type || 'Syntax'; + this.filename = filename; + this.index = e.index; + this.line = typeof(line) === 'number' ? line + 1 : null; + this.callLine = callLine + 1; + this.callExtract = lines[callLine]; + this.column = col; + this.extract = [ + lines[line - 1], + lines[line], + lines[line + 1] + ]; + } + this.message = e.message; + this.stack = e.stack; +}; + +if (typeof Object.create === 'undefined') { + var F = function () {}; + F.prototype = Error.prototype; + LessError.prototype = new F(); +} else { + LessError.prototype = Object.create(Error.prototype); +} + +LessError.prototype.constructor = LessError; + +},{"./utils":80}],31:[function(require,module,exports){ +module.exports = { + error: function(msg) { + this._fireEvent("error", msg); + }, + warn: function(msg) { + this._fireEvent("warn", msg); + }, + info: function(msg) { + this._fireEvent("info", msg); + }, + debug: function(msg) { + this._fireEvent("debug", msg); + }, + addListener: function(listener) { + this._listeners.push(listener); + }, + removeListener: function(listener) { + for(var i = 0; i < this._listeners.length; i++) { + if (this._listeners[i] === listener) { + this._listeners.splice(i, 1); + return; + } + } + }, + _fireEvent: function(type, msg) { + for(var i = 0; i < this._listeners.length; i++) { + var logFunction = this._listeners[i][type]; + if (logFunction) { + logFunction(msg); + } + } + }, + _listeners: [] +}; + +},{}],32:[function(require,module,exports){ +var LessError = require('./less-error'), + transformTree = require("./transform-tree"), + logger = require("./logger"); + +module.exports = function(SourceMapBuilder) { +var ParseTree = function(root, imports) { + this.root = root; + this.imports = imports; +}; + +ParseTree.prototype.toCSS = function(options) { + var evaldRoot, result = {}, sourceMapBuilder; + try { + evaldRoot = transformTree(this.root, options); + } catch (e) { + throw new LessError(e, this.imports); + } + + try { + var compress = Boolean(options.compress); + if (compress) { + logger.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css."); + } + + var toCSSOptions = { + compress: compress, + dumpLineNumbers: options.dumpLineNumbers, + strictUnits: Boolean(options.strictUnits), + numPrecision: 8}; + + if (options.sourceMap) { + sourceMapBuilder = new SourceMapBuilder(options.sourceMap); + result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); + } else { + result.css = evaldRoot.toCSS(toCSSOptions); + } + } catch (e) { + throw new LessError(e, this.imports); + } + + if (options.pluginManager) { + var postProcessors = options.pluginManager.getPostProcessors(); + for(var i = 0; i < postProcessors.length; i++) { + result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports }); + } + } + if (options.sourceMap) { + result.map = sourceMapBuilder.getExternalSourceMap(); + } + + result.imports = []; + for(var file in this.imports.files) { + if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) { + result.imports.push(file); + } + } + return result; +}; +return ParseTree; +}; + +},{"./less-error":30,"./logger":31,"./transform-tree":41}],33:[function(require,module,exports){ +var PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise, + contexts = require("./contexts"), + Parser = require('./parser/parser'), + PluginManager = require('./plugin-manager'); + +module.exports = function(environment, ParseTree, ImportManager) { + var parse = function (input, options, callback) { + options = options || {}; + + if (typeof(options) === 'function') { + callback = options; + options = {}; + } + + if (!callback) { + var self = this; + return new PromiseConstructor(function (resolve, reject) { + parse.call(self, input, options, function(err, output) { + if (err) { + reject(err); + } else { + resolve(output); + } + }); + }); + } else { + var context, + rootFileInfo, + pluginManager = new PluginManager(this); + + pluginManager.addPlugins(options.plugins); + options.pluginManager = pluginManager; + + context = new contexts.Parse(options); + + if (options.rootFileInfo) { + rootFileInfo = options.rootFileInfo; + } else { + var filename = options.filename || "input"; + var entryPath = filename.replace(/[^\/\\]*$/, ""); + rootFileInfo = { + filename: filename, + relativeUrls: context.relativeUrls, + rootpath: context.rootpath || "", + currentDirectory: entryPath, + entryPath: entryPath, + rootFilename: filename + }; + } + + var imports = new ImportManager(context, rootFileInfo); + + new Parser(context, imports, rootFileInfo) + .parse(input, function (e, root) { + if (e) { return callback(e); } + callback(null, root, imports, options); + }, options); + } + }; + return parse; +}; + +},{"./contexts":10,"./parser/parser":36,"./plugin-manager":37,"promise":undefined}],34:[function(require,module,exports){ +// Split the input into chunks. +module.exports = function (input, fail) { + var len = input.length, level = 0, parenLevel = 0, + lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace, + chunks = [], emitFrom = 0, + chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched; + + function emitChunk(force) { + var len = chunkerCurrentIndex - emitFrom; + if (((len < 512) && !force) || !len) { + return; + } + chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); + emitFrom = chunkerCurrentIndex + 1; + } + + for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc = input.charCodeAt(chunkerCurrentIndex); + if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { + // a-z or whitespace + continue; + } + + switch (cc) { + case 40: // ( + parenLevel++; + lastOpeningParen = chunkerCurrentIndex; + continue; + case 41: // ) + if (--parenLevel < 0) { + return fail("missing opening `(`", chunkerCurrentIndex); + } + continue; + case 59: // ; + if (!parenLevel) { emitChunk(); } + continue; + case 123: // { + level++; + lastOpening = chunkerCurrentIndex; + continue; + case 125: // } + if (--level < 0) { + return fail("missing opening `{`", chunkerCurrentIndex); + } + if (!level && !parenLevel) { emitChunk(); } + continue; + case 92: // \ + if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; } + return fail("unescaped `\\`", chunkerCurrentIndex); + case 34: + case 39: + case 96: // ", ' and ` + matched = 0; + currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 > 96) { continue; } + if (cc2 == cc) { matched = 1; break; } + if (cc2 == 92) { // \ + if (chunkerCurrentIndex == len - 1) { + return fail("unescaped `\\`", chunkerCurrentIndex); + } + chunkerCurrentIndex++; + } + } + if (matched) { continue; } + return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); + case 47: // /, check for comment + if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; } + cc2 = input.charCodeAt(chunkerCurrentIndex + 1); + if (cc2 == 47) { + // //, find lnfeed + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; } + } + } else if (cc2 == 42) { + // /*, find */ + lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; } + if (cc2 != 42) { continue; } + if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; } + } + if (chunkerCurrentIndex == len - 1) { + return fail("missing closing `*/`", currentChunkStartIndex); + } + chunkerCurrentIndex++; + } + continue; + case 42: // *, check for unmatched */ + if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) { + return fail("unmatched `/*`", chunkerCurrentIndex); + } + continue; + } + } + + if (level !== 0) { + if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { + return fail("missing closing `}` or `*/`", lastOpening); + } else { + return fail("missing closing `}`", lastOpening); + } + } else if (parenLevel !== 0) { + return fail("missing closing `)`", lastOpeningParen); + } + + emitChunk(true); + return chunks; +}; + +},{}],35:[function(require,module,exports){ +var chunker = require('./chunker'); + +module.exports = function() { + var input, // LeSS input string + j, // current chunk + saveStack = [], // holds state for backtracking + furthest, // furthest index the parser has gone to + furthestPossibleErrorMessage,// if this is furthest we got to, this is the probably cause + chunks, // chunkified input + current, // current chunk + currentPos, // index of current chunk, in `input` + parserInput = {}; + + parserInput.save = function() { + currentPos = parserInput.i; + saveStack.push( { current: current, i: parserInput.i, j: j }); + }; + parserInput.restore = function(possibleErrorMessage) { + + if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) { + furthest = parserInput.i; + furthestPossibleErrorMessage = possibleErrorMessage; + } + var state = saveStack.pop(); + current = state.current; + currentPos = parserInput.i = state.i; + j = state.j; + }; + parserInput.forget = function() { + saveStack.pop(); + }; + function sync() { + if (parserInput.i > currentPos) { + current = current.slice(parserInput.i - currentPos); + currentPos = parserInput.i; + } + } + parserInput.isWhitespace = function (offset) { + var pos = parserInput.i + (offset || 0), + code = input.charCodeAt(pos); + return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF); + }; + // + // Parse from a token, regexp or string, and move forward if match + // + parserInput.$ = function(tok) { + var tokType = typeof tok, + match, length; + + // Either match a single character in the input, + // or match a regexp in the current chunk (`current`). + // + if (tokType === "string") { + if (input.charAt(parserInput.i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + } + + // regexp + sync(); + if (! (match = tok.exec(current))) { + return null; + } + + length = match[0].length; + + // The match is confirmed, add the match length to `i`, + // and consume any extra white-space characters (' ' || '\n') + // which come after that. The reason for this is that LeSS's + // grammar is mostly white-space insensitive. + // + skipWhitespace(length); + + if(typeof(match) === 'string') { + return match; + } else { + return match.length === 1 ? match[0] : match; + } + }; + + // Specialization of $(tok) + parserInput.$re = function(tok) { + if (parserInput.i > currentPos) { + current = current.slice(parserInput.i - currentPos); + currentPos = parserInput.i; + } + var m = tok.exec(current); + if (!m) { + return null; + } + + skipWhitespace(m[0].length); + if(typeof m === "string") { + return m; + } + + return m.length === 1 ? m[0] : m; + }; + + // Specialization of $(tok) + parserInput.$char = function(tok) { + if (input.charAt(parserInput.i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + }; + + var CHARCODE_SPACE = 32, + CHARCODE_TAB = 9, + CHARCODE_LF = 10, + CHARCODE_CR = 13, + CHARCODE_PLUS = 43, + CHARCODE_COMMA = 44, + CHARCODE_FORWARD_SLASH = 47, + CHARCODE_9 = 57; + + parserInput.autoCommentAbsorb = true; + parserInput.commentStore = []; + parserInput.finished = false; + + var skipWhitespace = function(length) { + var oldi = parserInput.i, oldj = j, + curr = parserInput.i - currentPos, + endIndex = parserInput.i + current.length - curr, + mem = (parserInput.i += length), + inp = input, + c, nextChar, comment; + + for (; parserInput.i < endIndex; parserInput.i++) { + c = inp.charCodeAt(parserInput.i); + + if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { + nextChar = inp.charAt(parserInput.i + 1); + if (nextChar === '/') { + comment = {index: parserInput.i, isLineComment: true}; + var nextNewLine = inp.indexOf("\n", parserInput.i + 1); + if (nextNewLine < 0) { + nextNewLine = endIndex; + } + parserInput.i = nextNewLine; + comment.text = inp.substr(comment.i, parserInput.i - comment.i); + parserInput.commentStore.push(comment); + continue; + } else if (nextChar === '*') { + var haystack = inp.substr(parserInput.i); + var comment_search_result = haystack.match(/^\/\*(?:[^*]|\*+[^\/*])*\*+\//); + if (comment_search_result) { + comment = { + index: parserInput.i, + text: comment_search_result[0], + isLineComment: false + }; + parserInput.i += comment.text.length - 1; + parserInput.commentStore.push(comment); + continue; + } + } + break; + } + + if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) { + break; + } + } + + current = current.slice(length + parserInput.i - mem + curr); + currentPos = parserInput.i; + + if (!current.length) { + if (j < chunks.length - 1) + { + current = chunks[++j]; + skipWhitespace(0); // skip space at the beginning of a chunk + return true; // things changed + } + parserInput.finished = true; + } + + return oldi !== parserInput.i || oldj !== j; + }; + + // Same as $(), but don't change the state of the parser, + // just return the match. + parserInput.peek = function(tok) { + if (typeof(tok) === 'string') { + return input.charAt(parserInput.i) === tok; + } else { + return tok.test(current); + } + }; + + // Specialization of peek() + // TODO remove or change some currentChar calls to peekChar + parserInput.peekChar = function(tok) { + return input.charAt(parserInput.i) === tok; + }; + + parserInput.currentChar = function() { + return input.charAt(parserInput.i); + }; + + parserInput.getInput = function() { + return input; + }; + + parserInput.peekNotNumeric = function() { + var c = input.charCodeAt(parserInput.i); + //Is the first char of the dimension 0-9, '.', '+' or '-' + return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; + }; + + parserInput.start = function(str, chunkInput, failFunction) { + input = str; + parserInput.i = j = currentPos = furthest = 0; + + // chunking apparantly makes things quicker (but my tests indicate + // it might actually make things slower in node at least) + // and it is a non-perfect parse - it can't recognise + // unquoted urls, meaning it can't distinguish comments + // meaning comments with quotes or {}() in them get 'counted' + // and then lead to parse errors. + // In addition if the chunking chunks in the wrong place we might + // not be able to parse a parser statement in one go + // this is officially deprecated but can be switched on via an option + // in the case it causes too much performance issues. + if (chunkInput) { + chunks = chunker(str, failFunction); + } else { + chunks = [str]; + } + + current = chunks[0]; + + skipWhitespace(0); + }; + + parserInput.end = function() { + var message, + isFinished = parserInput.i >= input.length; + + if (parserInput.i < furthest) { + message = furthestPossibleErrorMessage; + parserInput.i = furthest; + } + return { + isFinished: isFinished, + furthest: parserInput.i, + furthestPossibleErrorMessage: message, + furthestReachedEnd: parserInput.i >= input.length - 1, + furthestChar: input[parserInput.i] + }; + }; + + return parserInput; +}; + +},{"./chunker":34}],36:[function(require,module,exports){ +var LessError = require('../less-error'), + tree = require("../tree"), + visitors = require("../visitors"), + getParserInput = require("./parser-input"), + utils = require("../utils"); + +// +// less.js - parser +// +// A relatively straight-forward predictive parser. +// There is no tokenization/lexing stage, the input is parsed +// in one sweep. +// +// To make the parser fast enough to run in the browser, several +// optimization had to be made: +// +// - Matching and slicing on a huge input is often cause of slowdowns. +// The solution is to chunkify the input into smaller strings. +// The chunks are stored in the `chunks` var, +// `j` holds the current chunk index, and `currentPos` holds +// the index of the current chunk in relation to `input`. +// This gives us an almost 4x speed-up. +// +// - In many cases, we don't need to match individual tokens; +// for example, if a value doesn't hold any variables, operations +// or dynamic references, the parser can effectively 'skip' it, +// treating it as a literal. +// An example would be '1px solid #000' - which evaluates to itself, +// we don't need to know what the individual components are. +// The drawback, of course is that you don't get the benefits of +// syntax-checking on the CSS. This gives us a 50% speed-up in the parser, +// and a smaller speed-up in the code-gen. +// +// +// Token matching is done with the `$` function, which either takes +// a terminal string or regexp, or a non-terminal function to call. +// It also takes care of moving all the indices forwards. +// +// +var Parser = function Parser(context, imports, fileInfo) { + var parsers, + parserInput = getParserInput(); + + function expect(arg, msg, index) { + // some older browsers return typeof 'function' for RegExp + var result = (Object.prototype.toString.call(arg) === '[object Function]') ? arg.call(parsers) : parserInput.$(arg); + if (result) { + return result; + } + error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'" + : "unexpected token")); + } + + // Specialization of expect() + function expectChar(arg, msg) { + if (parserInput.$char(arg)) { + return arg; + } + error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'"); + } + + function error(msg, type) { + throw new LessError( + { + index: parserInput.i, + filename: fileInfo.filename, + type: type || 'Syntax', + message: msg + }, + imports + ); + } + + function getDebugInfo(index) { + var filename = fileInfo.filename; + + return { + lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1, + fileName: filename + }; + } + + // + // The Parser + // + return { + + // + // Parse an input string into an abstract syntax tree, + // @param str A string containing 'less' markup + // @param callback call `callback` when done. + // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply + // + parse: function (str, callback, additionalData) { + var root, error = null, globalVars, modifyVars, preText = ""; + + globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + '\n' : ''; + modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + Parser.serializeVars(additionalData.modifyVars) : ''; + + if (globalVars || (additionalData && additionalData.banner)) { + preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars; + imports.contentsIgnoredChars[fileInfo.filename] = preText.length; + } + + str = str.replace(/\r\n/g, '\n'); + // Remove potential UTF Byte Order Mark + str = preText + str.replace(/^\uFEFF/, '') + modifyVars; + imports.contents[fileInfo.filename] = str; + + // Start with the primary rule. + // The whole syntax tree is held under a Ruleset node, + // with the `root` property set to true, so no `{}` are + // output. The callback is called when the input is parsed. + try { + parserInput.start(str, context.chunkInput, function fail(msg, index) { + throw LessError({ + index: index, + type: 'Parse', + message: msg, + filename: fileInfo.filename + }, imports); + }); + + root = new(tree.Ruleset)(null, this.parsers.primary()); + root.root = true; + root.firstRoot = true; + } catch (e) { + return callback(new LessError(e, imports, fileInfo.filename)); + } + + // If `i` is smaller than the `input.length - 1`, + // it means the parser wasn't able to parse the whole + // string, so we've got a parsing error. + // + // We try to extract a \n delimited string, + // showing the line where the parse error occurred. + // We split it up into two parts (the part which parsed, + // and the part which didn't), so we can color them differently. + var endInfo = parserInput.end(); + if (!endInfo.isFinished) { + + var message = endInfo.furthestPossibleErrorMessage; + + if (!message) { + message = "Unrecognised input"; + if (endInfo.furthestChar === '}') { + message += ". Possibly missing opening '{'"; + } else if (endInfo.furthestChar === ')') { + message += ". Possibly missing opening '('"; + } else if (endInfo.furthestReachedEnd) { + message += ". Possibly missing something"; + } + } + + error = new LessError({ + type: "Parse", + message: message, + index: endInfo.furthest, + filename: fileInfo.filename + }, imports); + } + + var finish = function (e) { + e = error || e || imports.error; + + if (e) { + if (!(e instanceof LessError)) { + e = new LessError(e, imports, fileInfo.filename); + } + + return callback(e); + } + else { + return callback(null, root); + } + }; + + if (context.processImports !== false) { + new visitors.ImportVisitor(imports, finish) + .run(root); + } else { + return finish(); + } + }, + + // + // Here in, the parsing rules/functions + // + // The basic structure of the syntax tree generated is as follows: + // + // Ruleset -> Rule -> Value -> Expression -> Entity + // + // Here's some Less code: + // + // .class { + // color: #fff; + // border: 1px solid #000; + // width: @w + 4px; + // > .child {...} + // } + // + // And here's what the parse tree might look like: + // + // Ruleset (Selector '.class', [ + // Rule ("color", Value ([Expression [Color #fff]])) + // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) + // Rule ("width", Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]])) + // Ruleset (Selector [Element '>', '.child'], [...]) + // ]) + // + // In general, most rules will try to parse a token with the `$()` function, and if the return + // value is truly, will return a new node, of the relevant type. Sometimes, we need to check + // first, before parsing, that's when we use `peek()`. + // + parsers: parsers = { + // + // The `primary` rule is the *entry* and *exit* point of the parser. + // The rules here can appear at any level of the parse tree. + // + // The recursive nature of the grammar is an interplay between the `block` + // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, + // as represented by this simplified grammar: + // + // primary → (ruleset | rule)+ + // ruleset → selector+ block + // block → '{' primary '}' + // + // Only at one point is the primary rule not called from the + // block rule: at the root level. + // + primary: function () { + var mixin = this.mixin, root = [], node; + + while (!parserInput.finished) + { + while(true) { + node = this.comment(); + if (!node) { break; } + root.push(node); + } + if (parserInput.peek('}')) { + break; + } + + node = this.extendRule(); + if (node) { + root = root.concat(node); + continue; + } + + node = mixin.definition() || this.rule() || this.ruleset() || + mixin.call() || this.rulesetCall() || this.directive(); + if (node) { + root.push(node); + } else { + if (!(parserInput.$re(/^[\s\n]+/) || parserInput.$re(/^;+/))) { + break; + } + } + } + + return root; + }, + + // comments are collected by the main parsing mechanism and then assigned to nodes + // where the current structure allows it + comment: function () { + if (parserInput.commentStore.length) { + var comment = parserInput.commentStore.shift(); + return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo); + } + }, + + // + // Entities are tokens which can be found inside an Expression + // + entities: { + // + // A string, which supports escaping " and ' + // + // "milky way" 'he\'s the one!' + // + quoted: function () { + var str, index = parserInput.i; + + str = parserInput.$re(/^(~)?("((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)')/); + if (str) { + return new(tree.Quoted)(str[2], str[3] || str[4], Boolean(str[1]), index, fileInfo); + } + }, + + // + // A catch-all word, such as: + // + // black border-collapse + // + keyword: function () { + var k = parserInput.$re(/^%|^[_A-Za-z-][_A-Za-z0-9-]*/); + if (k) { + return tree.Color.fromKeyword(k) || new(tree.Keyword)(k); + } + }, + + // + // A function call + // + // rgb(255, 0, 255) + // + // We also try to catch IE's `alpha()`, but let the `alpha` parser + // deal with the details. + // + // The arguments are parsed with the `entities.arguments` parser. + // + call: function () { + var name, nameLC, args, alpha, index = parserInput.i; + + if (parserInput.peek(/^url\(/i)) { + return; + } + + parserInput.save(); + + name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); + if (!name) { parserInput.forget(); return; } + + name = name[1]; + nameLC = name.toLowerCase(); + + if (nameLC === 'alpha') { + alpha = parsers.alpha(); + if(alpha) { + return alpha; + } + } + + args = this.arguments(); + + if (! parserInput.$char(')')) { + parserInput.restore("Could not parse call arguments or missing ')'"); + return; + } + + parserInput.forget(); + return new(tree.Call)(name, args, index, fileInfo); + }, + arguments: function () { + var args = [], arg; + + while (true) { + arg = this.assignment() || parsers.expression(); + if (!arg) { + break; + } + args.push(arg); + if (! parserInput.$char(',')) { + break; + } + } + return args; + }, + literal: function () { + return this.dimension() || + this.color() || + this.quoted() || + this.unicodeDescriptor(); + }, + + // Assignments are argument entities for calls. + // They are present in ie filter properties as shown below. + // + // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) + // + + assignment: function () { + var key, value; + key = parserInput.$re(/^\w+(?=\s?=)/i); + if (!key) { + return; + } + if (!parserInput.$char('=')) { + return; + } + value = parsers.entity(); + if (value) { + return new(tree.Assignment)(key, value); + } + }, + + // + // Parse url() tokens + // + // We use a specific rule for urls, because they don't really behave like + // standard function calls. The difference is that the argument doesn't have + // to be enclosed within a string, so it can't be parsed as an Expression. + // + url: function () { + var value, index = parserInput.i; + + parserInput.autoCommentAbsorb = false; + + if (parserInput.currentChar() !== 'u' || !parserInput.$re(/^url\(/)) { + parserInput.autoCommentAbsorb = true; + return; + } + + value = this.quoted() || this.variable() || + parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ""; + + parserInput.autoCommentAbsorb = true; + + expectChar(')'); + + return new(tree.URL)((value.value != null || value instanceof tree.Variable) ? + value : new(tree.Anonymous)(value), index, fileInfo); + }, + + // + // A Variable entity, such as `@fink`, in + // + // width: @fink + 2px + // + // We use a different parser for variable definitions, + // see `parsers.variable`. + // + variable: function () { + var name, index = parserInput.i; + + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { + return new(tree.Variable)(name, index, fileInfo); + } + }, + + // A variable entity useing the protective {} e.g. @{var} + variableCurly: function () { + var curly, index = parserInput.i; + + if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { + return new(tree.Variable)("@" + curly[1], index, fileInfo); + } + }, + + // + // A Hexadecimal color + // + // #4F3C2F + // + // `rgb` and `hsl` colors are parsed through the `entities.call` parser. + // + color: function () { + var rgb; + + if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) { + var colorCandidateString = rgb.input.match(/^#([\w]+).*/); // strip colons, brackets, whitespaces and other characters that should not definitely be part of color string + colorCandidateString = colorCandidateString[1]; + if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters + error("Invalid HEX color code"); + } + return new(tree.Color)(rgb[1]); + } + }, + + // + // A Dimension, that is, a number and a unit + // + // 0.5em 95% + // + dimension: function () { + if (parserInput.peekNotNumeric()) { + return; + } + + var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/i); + if (value) { + return new(tree.Dimension)(value[1], value[2]); + } + }, + + // + // A unicode descriptor, as is used in unicode-range + // + // U+0?? or U+00A1-00A9 + // + unicodeDescriptor: function () { + var ud; + + ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + if (ud) { + return new(tree.UnicodeDescriptor)(ud[0]); + } + }, + + // + // JavaScript code to be evaluated + // + // `window.location.href` + // + javascript: function () { + var js, index = parserInput.i; + + js = parserInput.$re(/^(~)?`([^`]*)`/); + if (js) { + return new(tree.JavaScript)(js[2], Boolean(js[1]), index, fileInfo); + } + } + }, + + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink: + // + variable: function () { + var name; + + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { return name[1]; } + }, + + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink(); + // + rulesetCall: function () { + var name; + + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*\(\s*\)\s*;/))) { + return new tree.RulesetCall(name[1]); + } + }, + + // + // extend syntax - used to extend selectors + // + extend: function(isRule) { + var elements, e, index = parserInput.i, option, extendList, extend; + + if (!(isRule ? parserInput.$re(/^&:extend\(/) : parserInput.$re(/^:extend\(/))) { return; } + + do { + option = null; + elements = null; + while (! (option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { + e = this.element(); + if (!e) { break; } + if (elements) { elements.push(e); } else { elements = [ e ]; } + } + + option = option && option[1]; + if (!elements) + error("Missing target selector for :extend()."); + extend = new(tree.Extend)(new(tree.Selector)(elements), option, index); + if (extendList) { extendList.push(extend); } else { extendList = [ extend ]; } + + } while(parserInput.$char(",")); + + expect(/^\)/); + + if (isRule) { + expect(/^;/); + } + + return extendList; + }, + + // + // extendRule - used in a rule to extend all the parent selectors + // + extendRule: function() { + return this.extend(true); + }, + + // + // Mixins + // + mixin: { + // + // A Mixin call, with an optional argument list + // + // #mixins > .square(#fff); + // .rounded(4px, black); + // .button; + // + // The `while` loop is there because mixins can be + // namespaced, but we only support the child and descendant + // selector for now. + // + call: function () { + var s = parserInput.currentChar(), important = false, index = parserInput.i, elemIndex, + elements, elem, e, c, args; + + if (s !== '.' && s !== '#') { return; } + + parserInput.save(); // stop us absorbing part of an invalid selector + + while (true) { + elemIndex = parserInput.i; + e = parserInput.$re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/); + if (!e) { + break; + } + elem = new(tree.Element)(c, e, elemIndex, fileInfo); + if (elements) { elements.push(elem); } else { elements = [ elem ]; } + c = parserInput.$char('>'); + } + + if (elements) { + if (parserInput.$char('(')) { + args = this.args(true).args; + expectChar(')'); + } + + if (parsers.important()) { + important = true; + } + + if (parsers.end()) { + parserInput.forget(); + return new(tree.mixin.Call)(elements, args, index, fileInfo, important); + } + } + + parserInput.restore(); + }, + args: function (isCall) { + var entities = parsers.entities, + returner = { args:null, variadic: false }, + expressions = [], argsSemiColon = [], argsComma = [], + isSemiColonSeparated, expressionContainsNamed, name, nameLoop, value, arg; + + parserInput.save(); + + while (true) { + if (isCall) { + arg = parsers.detachedRuleset() || parsers.expression(); + } else { + parserInput.commentStore.length = 0; + if (parserInput.currentChar() === '.' && parserInput.$re(/^\.{3}/)) { + returner.variadic = true; + if (parserInput.$char(";") && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ variadic: true }); + break; + } + arg = entities.variable() || entities.literal() || entities.keyword(); + } + + if (!arg) { + break; + } + + nameLoop = null; + if (arg.throwAwayComments) { + arg.throwAwayComments(); + } + value = arg; + var val = null; + + if (isCall) { + // Variable + if (arg.value && arg.value.length == 1) { + val = arg.value[0]; + } + } else { + val = arg; + } + + if (val && val instanceof tree.Variable) { + if (parserInput.$char(':')) { + if (expressions.length > 0) { + if (isSemiColonSeparated) { + error("Cannot mix ; and , as delimiter types"); + } + expressionContainsNamed = true; + } + + // we do not support setting a ruleset as a default variable - it doesn't make sense + // However if we do want to add it, there is nothing blocking it, just don't error + // and remove isCall dependency below + value = (isCall && parsers.detachedRuleset()) || parsers.expression(); + + if (!value) { + if (isCall) { + error("could not understand value for named argument"); + } else { + parserInput.restore(); + returner.args = []; + return returner; + } + } + nameLoop = (name = val.name); + } else if (!isCall && parserInput.$re(/^\.{3}/)) { + returner.variadic = true; + if (parserInput.$char(";") && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ name: arg.name, variadic: true }); + break; + } else if (!isCall) { + name = nameLoop = val.name; + value = null; + } + } + + if (value) { + expressions.push(value); + } + + argsComma.push({ name:nameLoop, value:value }); + + if (parserInput.$char(',')) { + continue; + } + + if (parserInput.$char(';') || isSemiColonSeparated) { + + if (expressionContainsNamed) { + error("Cannot mix ; and , as delimiter types"); + } + + isSemiColonSeparated = true; + + if (expressions.length > 1) { + value = new(tree.Value)(expressions); + } + argsSemiColon.push({ name:name, value:value }); + + name = null; + expressions = []; + expressionContainsNamed = false; + } + } + + parserInput.forget(); + returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; + return returner; + }, + // + // A Mixin definition, with a list of parameters + // + // .rounded (@radius: 2px, @color) { + // ... + // } + // + // Until we have a finer grained state-machine, we have to + // do a look-ahead, to make sure we don't have a mixin call. + // See the `rule` function for more information. + // + // We start by matching `.rounded (`, and then proceed on to + // the argument list, which has optional default values. + // We store the parameters in `params`, with a `value` key, + // if there is a value, such as in the case of `@radius`. + // + // Once we've got our params list, and a closing `)`, we parse + // the `{...}` block. + // + definition: function () { + var name, params = [], match, ruleset, cond, variadic = false; + if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') || + parserInput.peek(/^[^{]*\}/)) { + return; + } + + parserInput.save(); + + match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); + if (match) { + name = match[1]; + + var argInfo = this.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + + // .mixincall("@{a}"); + // looks a bit like a mixin definition.. + // also + // .mixincall(@a: {rule: set;}); + // so we have to be nice and restore + if (!parserInput.$char(')')) { + parserInput.restore("Missing closing ')'"); + return; + } + + parserInput.commentStore.length = 0; + + if (parserInput.$re(/^when/)) { // Guard + cond = expect(parsers.conditions, 'expected condition'); + } + + ruleset = parsers.block(); + + if (ruleset) { + parserInput.forget(); + return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic); + } else { + parserInput.restore(); + } + } else { + parserInput.forget(); + } + } + }, + + // + // Entities are the smallest recognized token, + // and can be found inside a rule's value. + // + entity: function () { + var entities = this.entities; + + return this.comment() || entities.literal() || entities.variable() || entities.url() || + entities.call() || entities.keyword() || entities.javascript(); + }, + + // + // A Rule terminator. Note that we use `peek()` to check for '}', + // because the `block` rule will be expecting it, but we still need to make sure + // it's there, if ';' was ommitted. + // + end: function () { + return parserInput.$char(';') || parserInput.peek('}'); + }, + + // + // IE's alpha function + // + // alpha(opacity=88) + // + alpha: function () { + var value; + + if (! parserInput.$re(/^opacity=/i)) { return; } + value = parserInput.$re(/^\d+/); + if (!value) { + value = expect(this.entities.variable, "Could not parse alpha"); + } + expectChar(')'); + return new(tree.Alpha)(value); + }, + + // + // A Selector Element + // + // div + // + h1 + // #socks + // input[type="text"] + // + // Elements are the building blocks for Selectors, + // they are made out of a `Combinator` (see combinator rule), + // and an element name, such as a tag a class, or `*`. + // + element: function () { + var e, c, v, index = parserInput.i; + + c = this.combinator(); + + e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || + parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^()@]+\)/) || parserInput.$re(/^[\.#](?=@)/) || + this.entities.variableCurly(); + + if (! e) { + parserInput.save(); + if (parserInput.$char('(')) { + if ((v = this.selector()) && parserInput.$char(')')) { + e = new(tree.Paren)(v); + parserInput.forget(); + } else { + parserInput.restore("Missing closing ')'"); + } + } else { + parserInput.forget(); + } + } + + if (e) { return new(tree.Element)(c, e, index, fileInfo); } + }, + + // + // Combinators combine elements together, in a Selector. + // + // Because our parser isn't white-space sensitive, special care + // has to be taken, when parsing the descendant combinator, ` `, + // as it's an empty space. We have to check the previous character + // in the input, to see if it's a ` ` character. More info on how + // we deal with this in *combinator.js*. + // + combinator: function () { + var c = parserInput.currentChar(); + + if (c === '/') { + parserInput.save(); + var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); + if (slashedCombinator) { + parserInput.forget(); + return new(tree.Combinator)(slashedCombinator); + } + parserInput.restore(); + } + + if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { + parserInput.i++; + if (c === '^' && parserInput.currentChar() === '^') { + c = '^^'; + parserInput.i++; + } + while (parserInput.isWhitespace()) { parserInput.i++; } + return new(tree.Combinator)(c); + } else if (parserInput.isWhitespace(-1)) { + return new(tree.Combinator)(" "); + } else { + return new(tree.Combinator)(null); + } + }, + // + // A CSS selector (see selector below) + // with less extensions e.g. the ability to extend and guard + // + lessSelector: function () { + return this.selector(true); + }, + // + // A CSS Selector + // + // .class > div + h1 + // li a:hover + // + // Selectors are made out of one or more Elements, see above. + // + selector: function (isLess) { + var index = parserInput.i, elements, extendList, c, e, allExtends, when, condition; + + while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$re(/^when/))) || (e = this.element())) { + if (when) { + condition = expect(this.conditions, 'expected condition'); + } else if (condition) { + error("CSS guard can only be used at the end of selector"); + } else if (extendList) { + if (allExtends) { allExtends = allExtends.concat(extendList); } else { allExtends = extendList; } + } else { + if (allExtends) { error("Extend can only be used at the end of selector"); } + c = parserInput.currentChar(); + if (elements) { elements.push(e); } else { elements = [ e ]; } + e = null; + } + if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { + break; + } + } + + if (elements) { return new(tree.Selector)(elements, allExtends, condition, index, fileInfo); } + if (allExtends) { error("Extend must be used to extend a selector, it cannot be used on its own"); } + }, + attribute: function () { + if (! parserInput.$char('[')) { return; } + + var entities = this.entities, + key, val, op; + + if (!(key = entities.variableCurly())) { + key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + } + + op = parserInput.$re(/^[|~*$^]?=/); + if (op) { + val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); + } + + expectChar(']'); + + return new(tree.Attribute)(key, op, val); + }, + + // + // The `block` rule is used by `ruleset` and `mixin.definition`. + // It's a wrapper around the `primary` rule, with added `{}`. + // + block: function () { + var content; + if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { + return content; + } + }, + + blockRuleset: function() { + var block = this.block(); + + if (block) { + block = new tree.Ruleset(null, block); + } + return block; + }, + + detachedRuleset: function() { + var blockRuleset = this.blockRuleset(); + if (blockRuleset) { + return new tree.DetachedRuleset(blockRuleset); + } + }, + + // + // div, .class, body > p {...} + // + ruleset: function () { + var selectors, s, rules, debugInfo; + + parserInput.save(); + + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(parserInput.i); + } + + while (true) { + s = this.lessSelector(); + if (!s) { + break; + } + if (selectors) { selectors.push(s); } else { selectors = [ s ]; } + parserInput.commentStore.length = 0; + if (s.condition && selectors.length > 1) { + error("Guards are only currently allowed on a single selector."); + } + if (! parserInput.$char(',')) { break; } + if (s.condition) { + error("Guards are only currently allowed on a single selector."); + } + parserInput.commentStore.length = 0; + } + + if (selectors && (rules = this.block())) { + parserInput.forget(); + var ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports); + if (context.dumpLineNumbers) { + ruleset.debugInfo = debugInfo; + } + return ruleset; + } else { + parserInput.restore(); + } + }, + rule: function (tryAnonymous) { + var name, value, startOfRule = parserInput.i, c = parserInput.currentChar(), important, merge, isVariable; + + if (c === '.' || c === '#' || c === '&') { return; } + + parserInput.save(); + + name = this.variable() || this.ruleProperty(); + if (name) { + isVariable = typeof name === "string"; + + if (isVariable) { + value = this.detachedRuleset(); + } + + parserInput.commentStore.length = 0; + if (!value) { + // a name returned by this.ruleProperty() is always an array of the form: + // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] + // where each item is a tree.Keyword or tree.Variable + merge = !isVariable && name.pop().value; + + // prefer to try to parse first if its a variable or we are compressing + // but always fallback on the other one + var tryValueFirst = !tryAnonymous && (context.compress || isVariable); + + if (tryValueFirst) { + value = this.value(); + } + if (!value) { + value = this.anonymousValue(); + if (value) { + parserInput.forget(); + // anonymous values absorb the end ';' which is reequired for them to work + return new (tree.Rule)(name, value, false, merge, startOfRule, fileInfo); + } + } + if (!tryValueFirst && !value) { + value = this.value(); + } + + important = this.important(); + } + + if (value && this.end()) { + parserInput.forget(); + return new (tree.Rule)(name, value, important, merge, startOfRule, fileInfo); + } else { + parserInput.restore(); + if (value && !tryAnonymous) { + return this.rule(true); + } + } + } else { + parserInput.forget(); + } + }, + anonymousValue: function () { + var match = parserInput.$re(/^([^@+\/'"*`(;{}-]*);/); + if (match) { + return new(tree.Anonymous)(match[1]); + } + }, + + // + // An @import directive + // + // @import "lib"; + // + // Depending on our environment, importing is done differently: + // In the browser, it's an XHR request, in Node, it would be a + // file-system operation. The function used for importing is + // stored in `import`, which we pass to the Import constructor. + // + "import": function () { + var path, features, index = parserInput.i; + + var dir = parserInput.$re(/^@import?\s+/); + + if (dir) { + var options = (dir ? this.importOptions() : null) || {}; + + if ((path = this.entities.quoted() || this.entities.url())) { + features = this.mediaFeatures(); + + if (!parserInput.$(';')) { + parserInput.i = index; + error("missing semi-colon or unrecognised media features on import"); + } + features = features && new(tree.Value)(features); + return new(tree.Import)(path, features, options, index, fileInfo); + } + else + { + parserInput.i = index; + error("malformed import statement"); + } + } + }, + + importOptions: function() { + var o, options = {}, optionName, value; + + // list of options, surrounded by parens + if (! parserInput.$char('(')) { return null; } + do { + o = this.importOption(); + if (o) { + optionName = o; + value = true; + switch(optionName) { + case "css": + optionName = "less"; + value = false; + break; + case "once": + optionName = "multiple"; + value = false; + break; + } + options[optionName] = value; + if (! parserInput.$char(',')) { break; } + } + } while (o); + expectChar(')'); + return options; + }, + + importOption: function() { + var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference)/); + if (opt) { + return opt[1]; + } + }, + + mediaFeature: function () { + var entities = this.entities, nodes = [], e, p; + parserInput.save(); + do { + e = entities.keyword() || entities.variable(); + if (e) { + nodes.push(e); + } else if (parserInput.$char('(')) { + p = this.property(); + e = this.value(); + if (parserInput.$char(')')) { + if (p && e) { + nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, parserInput.i, fileInfo, true))); + } else if (e) { + nodes.push(new(tree.Paren)(e)); + } else { + parserInput.restore("badly formed media feature definition"); + return null; + } + } else { + parserInput.restore("Missing closing ')'"); + return null; + } + } + } while (e); + + parserInput.forget(); + if (nodes.length > 0) { + return new(tree.Expression)(nodes); + } + }, + + mediaFeatures: function () { + var entities = this.entities, features = [], e; + do { + e = this.mediaFeature(); + if (e) { + features.push(e); + if (! parserInput.$char(',')) { break; } + } else { + e = entities.variable(); + if (e) { + features.push(e); + if (! parserInput.$char(',')) { break; } + } + } + } while (e); + + return features.length > 0 ? features : null; + }, + + media: function () { + var features, rules, media, debugInfo; + + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(parserInput.i); + } + + if (parserInput.$re(/^@media/)) { + features = this.mediaFeatures(); + + rules = this.block(); + if (rules) { + media = new(tree.Media)(rules, features, parserInput.i, fileInfo); + if (context.dumpLineNumbers) { + media.debugInfo = debugInfo; + } + return media; + } + } + }, + + // + // A CSS Directive + // + // @charset "utf-8"; + // + directive: function () { + var index = parserInput.i, name, value, rules, nonVendorSpecificName, + hasIdentifier, hasExpression, hasUnknown, hasBlock = true; + + if (parserInput.currentChar() !== '@') { return; } + + value = this['import']() || this.media(); + if (value) { + return value; + } + + parserInput.save(); + + name = parserInput.$re(/^@[a-z-]+/); + + if (!name) { return; } + + nonVendorSpecificName = name; + if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { + nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); + } + + switch(nonVendorSpecificName) { + /* + case "@font-face": + case "@viewport": + case "@top-left": + case "@top-left-corner": + case "@top-center": + case "@top-right": + case "@top-right-corner": + case "@bottom-left": + case "@bottom-left-corner": + case "@bottom-center": + case "@bottom-right": + case "@bottom-right-corner": + case "@left-top": + case "@left-middle": + case "@left-bottom": + case "@right-top": + case "@right-middle": + case "@right-bottom": + hasBlock = true; + break; + */ + case "@counter-style": + hasIdentifier = true; + hasBlock = true; + break; + case "@charset": + hasIdentifier = true; + hasBlock = false; + break; + case "@namespace": + hasExpression = true; + hasBlock = false; + break; + case "@keyframes": + hasIdentifier = true; + break; + case "@host": + case "@page": + case "@document": + case "@supports": + hasUnknown = true; + break; + } + + parserInput.commentStore.length = 0; + + if (hasIdentifier) { + value = this.entity(); + if (!value) { + error("expected " + name + " identifier"); + } + } else if (hasExpression) { + value = this.expression(); + if (!value) { + error("expected " + name + " expression"); + } + } else if (hasUnknown) { + value = (parserInput.$re(/^[^{;]+/) || '').trim(); + if (value) { + value = new(tree.Anonymous)(value); + } + } + + if (hasBlock) { + rules = this.blockRuleset(); + } + + if (rules || (!hasBlock && value && parserInput.$char(';'))) { + parserInput.forget(); + return new(tree.Directive)(name, value, rules, index, fileInfo, + context.dumpLineNumbers ? getDebugInfo(index) : null); + } + + parserInput.restore("directive options not recognised"); + }, + + // + // A Value is a comma-delimited list of Expressions + // + // font-family: Baskerville, Georgia, serif; + // + // In a Rule, a Value represents everything after the `:`, + // and before the `;`. + // + value: function () { + var e, expressions = []; + + do { + e = this.expression(); + if (e) { + expressions.push(e); + if (! parserInput.$char(',')) { break; } + } + } while(e); + + if (expressions.length > 0) { + return new(tree.Value)(expressions); + } + }, + important: function () { + if (parserInput.currentChar() === '!') { + return parserInput.$re(/^! *important/); + } + }, + sub: function () { + var a, e; + + parserInput.save(); + if (parserInput.$char('(')) { + a = this.addition(); + if (a && parserInput.$char(')')) { + parserInput.forget(); + e = new(tree.Expression)([a]); + e.parens = true; + return e; + } + parserInput.restore("Expected ')'"); + return; + } + parserInput.restore(); + }, + multiplication: function () { + var m, a, op, operation, isSpaced; + m = this.operand(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + if (parserInput.peek(/^\/[*\/]/)) { + break; + } + + parserInput.save(); + + op = parserInput.$char('/') || parserInput.$char('*'); + + if (!op) { parserInput.forget(); break; } + + a = this.operand(); + + if (!a) { parserInput.restore(); break; } + parserInput.forget(); + + m.parensInOp = true; + a.parensInOp = true; + operation = new(tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + addition: function () { + var m, a, op, operation, isSpaced; + m = this.multiplication(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-'))); + if (!op) { + break; + } + a = this.multiplication(); + if (!a) { + break; + } + + m.parensInOp = true; + a.parensInOp = true; + operation = new(tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + conditions: function () { + var a, b, index = parserInput.i, condition; + + a = this.condition(); + if (a) { + while (true) { + if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { + break; + } + b = this.condition(); + if (!b) { + break; + } + condition = new(tree.Condition)('or', condition || a, b, index); + } + return condition || a; + } + }, + condition: function () { + var entities = this.entities, index = parserInput.i, negate = false, + a, b, c, op; + + if (parserInput.$re(/^not/)) { negate = true; } + expectChar('('); + a = this.addition() || entities.keyword() || entities.quoted(); + if (a) { + op = parserInput.$re(/^(?:>=|<=|=<|[<=>])/); + if (op) { + b = this.addition() || entities.keyword() || entities.quoted(); + if (b) { + c = new(tree.Condition)(op, a, b, index, negate); + } else { + error('expected expression'); + } + } else { + c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate); + } + expectChar(')'); + return parserInput.$re(/^and/) ? new(tree.Condition)('and', c, this.condition()) : c; + } + }, + + // + // An operand is anything that can be part of an operation, + // such as a Color, or a Variable + // + operand: function () { + var entities = this.entities, negate; + + if (parserInput.peek(/^-[@\(]/)) { + negate = parserInput.$char('-'); + } + + var o = this.sub() || entities.dimension() || + entities.color() || entities.variable() || + entities.call(); + + if (negate) { + o.parensInOp = true; + o = new(tree.Negative)(o); + } + + return o; + }, + + // + // Expressions either represent mathematical operations, + // or white-space delimited Entities. + // + // 1px solid black + // @var * 2 + // + expression: function () { + var entities = [], e, delim; + + do { + e = this.comment(); + if (e) { + entities.push(e); + continue; + } + e = this.addition() || this.entity(); + if (e) { + entities.push(e); + // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here + if (!parserInput.peek(/^\/[\/*]/)) { + delim = parserInput.$char('/'); + if (delim) { + entities.push(new(tree.Anonymous)(delim)); + } + } + } + } while (e); + if (entities.length > 0) { + return new(tree.Expression)(entities); + } + }, + property: function () { + var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); + if (name) { + return name[1]; + } + }, + ruleProperty: function () { + var name = [], index = [], s, k; + + parserInput.save(); + + function match(re) { + var i = parserInput.i, + chunk = parserInput.$re(re); + if (chunk) { + index.push(i); + return name.push(chunk[1]); + } + } + + match(/^(\*?)/); + while (true) { + if (!match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)) { + break; + } + } + + if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) { + parserInput.forget(); + + // at last, we have the complete match now. move forward, + // convert name particles to tree objects and return: + if (name[0] === '') { + name.shift(); + index.shift(); + } + for (k = 0; k < name.length; k++) { + s = name[k]; + name[k] = (s.charAt(0) !== '@') ? + new(tree.Keyword)(s) : + new(tree.Variable)('@' + s.slice(2, -1), + index[k], fileInfo); + } + return name; + } + parserInput.restore(); + } + } + }; +}; +Parser.serializeVars = function(vars) { + var s = ''; + + for (var name in vars) { + if (Object.hasOwnProperty.call(vars, name)) { + var value = vars[name]; + s += ((name[0] === '@') ? '' : '@') + name +': '+ value + + ((('' + value).slice(-1) === ';') ? '' : ';'); + } + } + + return s; +}; + +module.exports = Parser; + +},{"../less-error":30,"../tree":59,"../utils":80,"../visitors":84,"./parser-input":35}],37:[function(require,module,exports){ +/** + * Plugin Manager + */ +var PluginManager = function(less) { + this.less = less; + this.visitors = []; + this.postProcessors = []; + this.installedPlugins = []; + this.fileManagers = []; +}; +/** + * Adds all the plugins in the array + * @param {Array} plugins + */ +PluginManager.prototype.addPlugins = function(plugins) { + if (plugins) { + for(var i = 0;i < plugins.length; i++) { + this.addPlugin(plugins[i]); + } + } +}; +/** + * + * @param plugin + */ +PluginManager.prototype.addPlugin = function(plugin) { + this.installedPlugins.push(plugin); + plugin.install(this.less, this); +}; +/** + * Adds a visitor. The visitor object has options on itself to determine + * when it should run. + * @param visitor + */ +PluginManager.prototype.addVisitor = function(visitor) { + this.visitors.push(visitor); +}; +/** + * Adds a post processor object + * @param {object} postProcessor + * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression + */ +PluginManager.prototype.addPostProcessor = function(postProcessor, priority) { + var indexToInsertAt; + for(indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { + if (this.postProcessors[indexToInsertAt].priority >= priority) { + break; + } + } + this.postProcessors.splice(indexToInsertAt, 0, {postProcessor: postProcessor, priority: priority}); +}; +/** + * + * @param manager + */ +PluginManager.prototype.addFileManager = function(manager) { + this.fileManagers.push(manager); +}; +/** + * + * @returns {Array} + * @private + */ +PluginManager.prototype.getPostProcessors = function() { + var postProcessors = []; + for(var i = 0; i < this.postProcessors.length; i++) { + postProcessors.push(this.postProcessors[i].postProcessor); + } + return postProcessors; +}; +/** + * + * @returns {Array} + * @private + */ +PluginManager.prototype.getVisitors = function() { + return this.visitors; +}; +/** + * + * @returns {Array} + * @private + */ +PluginManager.prototype.getFileManagers = function() { + return this.fileManagers; +}; +module.exports = PluginManager; + +},{}],38:[function(require,module,exports){ +var PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise; + +module.exports = function(environment, ParseTree, ImportManager) { + var render = function (input, options, callback) { + if (typeof(options) === 'function') { + callback = options; + options = {}; + } + + if (!callback) { + var self = this; + return new PromiseConstructor(function (resolve, reject) { + render.call(self, input, options, function(err, output) { + if (err) { + reject(err); + } else { + resolve(output); + } + }); + }); + } else { + this.parse(input, options, function(err, root, imports, options) { + if (err) { return callback(err); } + + var result; + try { + var parseTree = new ParseTree(root, imports); + result = parseTree.toCSS(options); + } + catch (err) { return callback(err); } + + callback(null, result); + }); + } + }; + + return render; +}; + +},{"promise":undefined}],39:[function(require,module,exports){ +module.exports = function (SourceMapOutput, environment) { + + var SourceMapBuilder = function (options) { + this.options = options; + }; + + SourceMapBuilder.prototype.toCSS = function(rootNode, options, imports) { + var sourceMapOutput = new SourceMapOutput( + { + contentsIgnoredCharsMap: imports.contentsIgnoredChars, + rootNode: rootNode, + contentsMap: imports.contents, + sourceMapFilename: this.options.sourceMapFilename, + sourceMapURL: this.options.sourceMapURL, + outputFilename: this.options.sourceMapOutputFilename, + sourceMapBasepath: this.options.sourceMapBasepath, + sourceMapRootpath: this.options.sourceMapRootpath, + outputSourceFiles: this.options.outputSourceFiles, + sourceMapGenerator: this.options.sourceMapGenerator, + sourceMapFileInline: this.options.sourceMapFileInline + }); + + var css = sourceMapOutput.toCSS(options); + this.sourceMap = sourceMapOutput.sourceMap; + this.sourceMapURL = sourceMapOutput.sourceMapURL; + if (this.options.sourceMapInputFilename) { + this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + } + return css + this.getCSSAppendage(); + }; + + SourceMapBuilder.prototype.getCSSAppendage = function() { + var sourceMapURL = this.sourceMapURL; + if (this.options.sourceMapFileInline) { + sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap); + } + + if (sourceMapURL) { + return "/*# sourceMappingURL=" + sourceMapURL + " */"; + } + return ""; + }; + + SourceMapBuilder.prototype.getExternalSourceMap = function() { + return this.sourceMap; + }; + SourceMapBuilder.prototype.setExternalSourceMap = function(sourceMap) { + this.sourceMap = sourceMap; + }; + + SourceMapBuilder.prototype.isInline = function() { + return this.options.sourceMapFileInline; + }; + SourceMapBuilder.prototype.getSourceMapURL = function() { + return this.sourceMapURL; + }; + SourceMapBuilder.prototype.getOutputFilename = function() { + return this.options.sourceMapOutputFilename; + }; + SourceMapBuilder.prototype.getInputFilename = function() { + return this.sourceMapInputFilename; + }; + + return SourceMapBuilder; +}; + +},{}],40:[function(require,module,exports){ +module.exports = function (environment) { + + var SourceMapOutput = function (options) { + this._css = []; + this._rootNode = options.rootNode; + this._contentsMap = options.contentsMap; + this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; + if (options.sourceMapFilename) { + this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); + } + this._outputFilename = options.outputFilename; + this.sourceMapURL = options.sourceMapURL; + if (options.sourceMapBasepath) { + this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); + } + if (options.sourceMapRootpath) { + this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); + if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1) !== '/') { + this._sourceMapRootpath += '/'; + } + } else { + this._sourceMapRootpath = ""; + } + this._outputSourceFiles = options.outputSourceFiles; + this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); + + this._lineNumber = 0; + this._column = 0; + }; + + SourceMapOutput.prototype.normalizeFilename = function(filename) { + filename = filename.replace(/\\/g, '/'); + + if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) { + filename = filename.substring(this._sourceMapBasepath.length); + if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') { + filename = filename.substring(1); + } + } + return (this._sourceMapRootpath || "") + filename; + }; + + SourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) { + + //ignore adding empty strings + if (!chunk) { + return; + } + + var lines, + sourceLines, + columns, + sourceColumns, + i; + + if (fileInfo) { + var inputSource = this._contentsMap[fileInfo.filename]; + + // remove vars/banner added to the top of the file + if (this._contentsIgnoredCharsMap[fileInfo.filename]) { + // adjust the index + index -= this._contentsIgnoredCharsMap[fileInfo.filename]; + if (index < 0) { index = 0; } + // adjust the source + inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); + } + inputSource = inputSource.substring(0, index); + sourceLines = inputSource.split("\n"); + sourceColumns = sourceLines[sourceLines.length-1]; + } + + lines = chunk.split("\n"); + columns = lines[lines.length-1]; + + if (fileInfo) { + if (!mapLines) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column}, + original: { line: sourceLines.length, column: sourceColumns.length}, + source: this.normalizeFilename(fileInfo.filename)}); + } else { + for(i = 0; i < lines.length; i++) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0}, + original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0}, + source: this.normalizeFilename(fileInfo.filename)}); + } + } + } + + if (lines.length === 1) { + this._column += columns.length; + } else { + this._lineNumber += lines.length - 1; + this._column = columns.length; + } + + this._css.push(chunk); + }; + + SourceMapOutput.prototype.isEmpty = function() { + return this._css.length === 0; + }; + + SourceMapOutput.prototype.toCSS = function(context) { + this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); + + if (this._outputSourceFiles) { + for(var filename in this._contentsMap) { + if (this._contentsMap.hasOwnProperty(filename)) + { + var source = this._contentsMap[filename]; + if (this._contentsIgnoredCharsMap[filename]) { + source = source.slice(this._contentsIgnoredCharsMap[filename]); + } + this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + } + } + } + + this._rootNode.genCSS(context, this); + + if (this._css.length > 0) { + var sourceMapURL, + sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); + + if (this.sourceMapURL) { + sourceMapURL = this.sourceMapURL; + } else if (this._sourceMapFilename) { + sourceMapURL = this._sourceMapFilename; + } + this.sourceMapURL = sourceMapURL; + + this.sourceMap = sourceMapContent; + } + + return this._css.join(''); + }; + + return SourceMapOutput; +}; + +},{}],41:[function(require,module,exports){ +var contexts = require("./contexts"), + visitor = require("./visitors"), + tree = require("./tree"); + +module.exports = function(root, options) { + options = options || {}; + var evaldRoot, + variables = options.variables, + evalEnv = new contexts.Eval(options); + + // + // Allows setting variables with a hash, so: + // + // `{ color: new tree.Color('#f01') }` will become: + // + // new tree.Rule('@color', + // new tree.Value([ + // new tree.Expression([ + // new tree.Color('#f01') + // ]) + // ]) + // ) + // + if (typeof(variables) === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables).map(function (k) { + var value = variables[k]; + + if (! (value instanceof tree.Value)) { + if (! (value instanceof tree.Expression)) { + value = new tree.Expression([value]); + } + value = new tree.Value([value]); + } + return new tree.Rule('@' + k, value, false, null, 0); + }); + evalEnv.frames = [new tree.Ruleset(null, variables)]; + } + + var preEvalVisitors = [], + visitors = [ + new visitor.JoinSelectorVisitor(), + new visitor.ExtendVisitor(), + new visitor.ToCSSVisitor({compress: Boolean(options.compress)}) + ], i; + + if (options.pluginManager) { + var pluginVisitors = options.pluginManager.getVisitors(); + for(i =0; i < pluginVisitors.length; i++) { + var pluginVisitor = pluginVisitors[i]; + if (pluginVisitor.isPreEvalVisitor) { + preEvalVisitors.push(pluginVisitor); + } else { + if (pluginVisitor.isPreVisitor) { + visitors.splice(0, 0, pluginVisitor); + } else { + visitors.push(pluginVisitor); + } + } + } + } + + for(i = 0; i < preEvalVisitors.length; i++) { + preEvalVisitors[i].run(root); + } + + evaldRoot = root.eval(evalEnv); + + for(i = 0; i < visitors.length; i++) { + visitors[i].run(evaldRoot); + } + + return evaldRoot; +}; + +},{"./contexts":10,"./tree":59,"./visitors":84}],42:[function(require,module,exports){ +var Node = require("./node"); + +var Alpha = function (val) { + this.value = val; +}; +Alpha.prototype = new Node(); +Alpha.prototype.type = "Alpha"; + +Alpha.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); +}; +Alpha.prototype.eval = function (context) { + if (this.value.eval) { return new Alpha(this.value.eval(context)); } + return this; +}; +Alpha.prototype.genCSS = function (context, output) { + output.add("alpha(opacity="); + + if (this.value.genCSS) { + this.value.genCSS(context, output); + } else { + output.add(this.value); + } + + output.add(")"); +}; + +module.exports = Alpha; + +},{"./node":67}],43:[function(require,module,exports){ +var Node = require("./node"); + +var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike) { + this.value = value; + this.index = index; + this.mapLines = mapLines; + this.currentFileInfo = currentFileInfo; + this.rulesetLike = (typeof rulesetLike === 'undefined')? false : rulesetLike; +}; +Anonymous.prototype = new Node(); +Anonymous.prototype.type = "Anonymous"; +Anonymous.prototype.eval = function () { + return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike); +}; +Anonymous.prototype.compare = function (other) { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; +}; +Anonymous.prototype.isRulesetLike = function() { + return this.rulesetLike; +}; +Anonymous.prototype.genCSS = function (context, output) { + output.add(this.value, this.currentFileInfo, this.index, this.mapLines); +}; +module.exports = Anonymous; + +},{"./node":67}],44:[function(require,module,exports){ +var Node = require("./node"); + +var Assignment = function (key, val) { + this.key = key; + this.value = val; +}; + +Assignment.prototype = new Node(); +Assignment.prototype.type = "Assignment"; +Assignment.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); +}; +Assignment.prototype.eval = function (context) { + if (this.value.eval) { + return new Assignment(this.key, this.value.eval(context)); + } + return this; +}; +Assignment.prototype.genCSS = function (context, output) { + output.add(this.key + '='); + if (this.value.genCSS) { + this.value.genCSS(context, output); + } else { + output.add(this.value); + } +}; +module.exports = Assignment; + + +},{"./node":67}],45:[function(require,module,exports){ +var Node = require("./node"); + +var Attribute = function (key, op, value) { + this.key = key; + this.op = op; + this.value = value; +}; +Attribute.prototype = new Node(); +Attribute.prototype.type = "Attribute"; +Attribute.prototype.eval = function (context) { + return new Attribute(this.key.eval ? this.key.eval(context) : this.key, + this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value); +}; +Attribute.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); +}; +Attribute.prototype.toCSS = function (context) { + var value = this.key.toCSS ? this.key.toCSS(context) : this.key; + + if (this.op) { + value += this.op; + value += (this.value.toCSS ? this.value.toCSS(context) : this.value); + } + + return '[' + value + ']'; +}; +module.exports = Attribute; + +},{"./node":67}],46:[function(require,module,exports){ +var Node = require("./node"), + FunctionCaller = require("../functions/function-caller"); +// +// A function call node. +// +var Call = function (name, args, index, currentFileInfo) { + this.name = name; + this.args = args; + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +Call.prototype = new Node(); +Call.prototype.type = "Call"; +Call.prototype.accept = function (visitor) { + if (this.args) { + this.args = visitor.visitArray(this.args); + } +}; +// +// When evaluating a function call, +// we either find the function in the functionRegistry, +// in which case we call it, passing the evaluated arguments, +// if this returns null or we cannot find the function, we +// simply print it out as it appeared originally [2]. +// +// The reason why we evaluate the arguments, is in the case where +// we try to pass a variable to a function, like: `saturate(@color)`. +// The function should receive the value, not the variable. +// +Call.prototype.eval = function (context) { + var args = this.args.map(function (a) { return a.eval(context); }), + result, funcCaller = new FunctionCaller(this.name, context, this.index, this.currentFileInfo); + + if (funcCaller.isValid()) { // 1. + try { + result = funcCaller.call(args); + if (result != null) { + return result; + } + } catch (e) { + throw { type: e.type || "Runtime", + message: "error evaluating function `" + this.name + "`" + + (e.message ? ': ' + e.message : ''), + index: this.index, filename: this.currentFileInfo.filename }; + } + } + + return new Call(this.name, args, this.index, this.currentFileInfo); +}; +Call.prototype.genCSS = function (context, output) { + output.add(this.name + "(", this.currentFileInfo, this.index); + + for(var i = 0; i < this.args.length; i++) { + this.args[i].genCSS(context, output); + if (i + 1 < this.args.length) { + output.add(", "); + } + } + + output.add(")"); +}; +module.exports = Call; + +},{"../functions/function-caller":20,"./node":67}],47:[function(require,module,exports){ +var Node = require("./node"), + colors = require("../data/colors"); + +// +// RGB Colors - #ff0014, #eee +// +var Color = function (rgb, a) { + // + // The end goal here, is to parse the arguments + // into an integer triplet, such as `128, 255, 0` + // + // This facilitates operations and conversions. + // + if (Array.isArray(rgb)) { + this.rgb = rgb; + } else if (rgb.length == 6) { + this.rgb = rgb.match(/.{2}/g).map(function (c) { + return parseInt(c, 16); + }); + } else { + this.rgb = rgb.split('').map(function (c) { + return parseInt(c + c, 16); + }); + } + this.alpha = typeof(a) === 'number' ? a : 1; +}; + +Color.prototype = new Node(); +Color.prototype.type = "Color"; + +function clamp(v, max) { + return Math.min(Math.max(v, 0), max); +} + +function toHex(v) { + return '#' + v.map(function (c) { + c = clamp(Math.round(c), 255); + return (c < 16 ? '0' : '') + c.toString(16); + }).join(''); +} + +Color.prototype.luma = function () { + var r = this.rgb[0] / 255, + g = this.rgb[1] / 255, + b = this.rgb[2] / 255; + + r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); + g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); + b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); + + return 0.2126 * r + 0.7152 * g + 0.0722 * b; +}; +Color.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); +}; +Color.prototype.toCSS = function (context, doNotCompress) { + var compress = context && context.compress && !doNotCompress, color, alpha; + + // `keyword` is set if this color was originally + // converted from a named color string so we need + // to respect this and try to output named color too. + if (this.keyword) { + return this.keyword; + } + + // If we have some transparency, the only way to represent it + // is via `rgba`. Otherwise, we use the hex representation, + // which has better compatibility with older browsers. + // Values are capped between `0` and `255`, rounded and zero-padded. + alpha = this.fround(context, this.alpha); + if (alpha < 1) { + return "rgba(" + this.rgb.map(function (c) { + return clamp(Math.round(c), 255); + }).concat(clamp(alpha, 1)) + .join(',' + (compress ? '' : ' ')) + ")"; + } + + color = this.toRGB(); + + if (compress) { + var splitcolor = color.split(''); + + // Convert color to short format + if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { + color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5]; + } + } + + return color; +}; + +// +// Operations have to be done per-channel, if not, +// channels will spill onto each other. Once we have +// our result, in the form of an integer triplet, +// we create a new Color node to hold the result. +// +Color.prototype.operate = function (context, op, other) { + var rgb = []; + var alpha = this.alpha * (1 - other.alpha) + other.alpha; + for (var c = 0; c < 3; c++) { + rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); + } + return new Color(rgb, alpha); +}; +Color.prototype.toRGB = function () { + return toHex(this.rgb); +}; +Color.prototype.toHSL = function () { + var r = this.rgb[0] / 255, + g = this.rgb[1] / 255, + b = this.rgb[2] / 255, + a = this.alpha; + + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2, d = max - min; + + if (max === min) { + h = s = 0; + } else { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h * 360, s: s, l: l, a: a }; +}; +//Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript +Color.prototype.toHSV = function () { + var r = this.rgb[0] / 255, + g = this.rgb[1] / 255, + b = this.rgb[2] / 255, + a = this.alpha; + + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, v = max; + + var d = max - min; + if (max === 0) { + s = 0; + } else { + s = d / max; + } + + if (max === min) { + h = 0; + } else { + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + return { h: h * 360, s: s, v: v, a: a }; +}; +Color.prototype.toARGB = function () { + return toHex([this.alpha * 255].concat(this.rgb)); +}; +Color.prototype.compare = function (x) { + return (x.rgb && + x.rgb[0] === this.rgb[0] && + x.rgb[1] === this.rgb[1] && + x.rgb[2] === this.rgb[2] && + x.alpha === this.alpha) ? 0 : undefined; +}; + +Color.fromKeyword = function(keyword) { + var c, key = keyword.toLowerCase(); + if (colors.hasOwnProperty(key)) { + c = new Color(colors[key].slice(1)); + } + else if (key === "transparent") { + c = new Color([0, 0, 0], 0); + } + + if (c) { + c.keyword = keyword; + return c; + } +}; +module.exports = Color; + +},{"../data/colors":11,"./node":67}],48:[function(require,module,exports){ +var Node = require("./node"); + +var Combinator = function (value) { + if (value === ' ') { + this.value = ' '; + this.emptyOrWhitespace = true; + } else { + this.value = value ? value.trim() : ""; + this.emptyOrWhitespace = this.value === ""; + } +}; +Combinator.prototype = new Node(); +Combinator.prototype.type = "Combinator"; +var _noSpaceCombinators = { + '': true, + ' ': true, + '|': true +}; +Combinator.prototype.genCSS = function (context, output) { + var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' '; + output.add(spaceOrEmpty + this.value + spaceOrEmpty); +}; +module.exports = Combinator; + +},{"./node":67}],49:[function(require,module,exports){ +var Node = require("./node"), + getDebugInfo = require("./debug-info"); + +var Comment = function (value, isLineComment, index, currentFileInfo) { + this.value = value; + this.isLineComment = isLineComment; + this.currentFileInfo = currentFileInfo; +}; +Comment.prototype = new Node(); +Comment.prototype.type = "Comment"; +Comment.prototype.genCSS = function (context, output) { + if (this.debugInfo) { + output.add(getDebugInfo(context, this), this.currentFileInfo, this.index); + } + output.add(this.value); +}; +Comment.prototype.isSilent = function(context) { + var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced), + isCompressed = context.compress && this.value[2] !== "!"; + return this.isLineComment || isReference || isCompressed; +}; +Comment.prototype.markReferenced = function () { + this.isReferenced = true; +}; +Comment.prototype.isRulesetLike = function(root) { + return Boolean(root); +}; +module.exports = Comment; + +},{"./debug-info":51,"./node":67}],50:[function(require,module,exports){ +var Node = require("./node"); + +var Condition = function (op, l, r, i, negate) { + this.op = op.trim(); + this.lvalue = l; + this.rvalue = r; + this.index = i; + this.negate = negate; +}; +Condition.prototype = new Node(); +Condition.prototype.type = "Condition"; +Condition.prototype.accept = function (visitor) { + this.lvalue = visitor.visit(this.lvalue); + this.rvalue = visitor.visit(this.rvalue); +}; +Condition.prototype.eval = function (context) { + var result = (function (op, a, b) { + switch (op) { + case 'and': return a && b; + case 'or': return a || b; + default: + switch (Node.compare(a, b)) { + case -1: return op === '<' || op === '=<' || op === '<='; + case 0: return op === '=' || op === '>=' || op === '=<' || op === '<='; + case 1: return op === '>' || op === '>='; + default: return false; + } + } + }) (this.op, this.lvalue.eval(context), this.rvalue.eval(context)); + + return this.negate ? !result : result; +}; +module.exports = Condition; + +},{"./node":67}],51:[function(require,module,exports){ +var debugInfo = function(context, ctx, lineSeparator) { + var result=""; + if (context.dumpLineNumbers && !context.compress) { + switch(context.dumpLineNumbers) { + case 'comments': + result = debugInfo.asComment(ctx); + break; + case 'mediaquery': + result = debugInfo.asMediaQuery(ctx); + break; + case 'all': + result = debugInfo.asComment(ctx) + (lineSeparator || "") + debugInfo.asMediaQuery(ctx); + break; + } + } + return result; +}; + +debugInfo.asComment = function(ctx) { + return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n'; +}; + +debugInfo.asMediaQuery = function(ctx) { + return '@media -sass-debug-info{filename{font-family:' + + ('file://' + ctx.debugInfo.fileName).replace(/([.:\/\\])/g, function (a) { + if (a == '\\') { + a = '\/'; + } + return '\\' + a; + }) + + '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n'; +}; + +module.exports = debugInfo; + +},{}],52:[function(require,module,exports){ +var Node = require("./node"), + contexts = require("../contexts"); + +var DetachedRuleset = function (ruleset, frames) { + this.ruleset = ruleset; + this.frames = frames; +}; +DetachedRuleset.prototype = new Node(); +DetachedRuleset.prototype.type = "DetachedRuleset"; +DetachedRuleset.prototype.evalFirst = true; +DetachedRuleset.prototype.accept = function (visitor) { + this.ruleset = visitor.visit(this.ruleset); +}; +DetachedRuleset.prototype.eval = function (context) { + var frames = this.frames || context.frames.slice(0); + return new DetachedRuleset(this.ruleset, frames); +}; +DetachedRuleset.prototype.callEval = function (context) { + return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); +}; +module.exports = DetachedRuleset; + +},{"../contexts":10,"./node":67}],53:[function(require,module,exports){ +var Node = require("./node"), + unitConversions = require("../data/unit-conversions"), + Unit = require("./unit"), + Color = require("./color"); + +// +// A number with a unit +// +var Dimension = function (value, unit) { + this.value = parseFloat(value); + this.unit = (unit && unit instanceof Unit) ? unit : + new Unit(unit ? [unit] : undefined); +}; + +Dimension.prototype = new Node(); +Dimension.prototype.type = "Dimension"; +Dimension.prototype.accept = function (visitor) { + this.unit = visitor.visit(this.unit); +}; +Dimension.prototype.eval = function (context) { + return this; +}; +Dimension.prototype.toColor = function () { + return new Color([this.value, this.value, this.value]); +}; +Dimension.prototype.genCSS = function (context, output) { + if ((context && context.strictUnits) && !this.unit.isSingular()) { + throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString()); + } + + var value = this.fround(context, this.value), + strValue = String(value); + + if (value !== 0 && value < 0.000001 && value > -0.000001) { + // would be output 1e-6 etc. + strValue = value.toFixed(20).replace(/0+$/, ""); + } + + if (context && context.compress) { + // Zero values doesn't need a unit + if (value === 0 && this.unit.isLength()) { + output.add(strValue); + return; + } + + // Float values doesn't need a leading zero + if (value > 0 && value < 1) { + strValue = (strValue).substr(1); + } + } + + output.add(strValue); + this.unit.genCSS(context, output); +}; + +// In an operation between two Dimensions, +// we default to the first Dimension's unit, +// so `1px + 2` will yield `3px`. +Dimension.prototype.operate = function (context, op, other) { + /*jshint noempty:false */ + var value = this._operate(context, op, this.value, other.value), + unit = this.unit.clone(); + + if (op === '+' || op === '-') { + if (unit.numerator.length === 0 && unit.denominator.length === 0) { + unit.numerator = other.unit.numerator.slice(0); + unit.denominator = other.unit.denominator.slice(0); + } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) { + // do nothing + } else { + other = other.convertTo(this.unit.usedUnits()); + + if(context.strictUnits && other.unit.toString() !== unit.toString()) { + throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() + + "' and '" + other.unit.toString() + "'."); + } + + value = this._operate(context, op, this.value, other.value); + } + } else if (op === '*') { + unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); + unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); + unit.cancel(); + } else if (op === '/') { + unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); + unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); + unit.cancel(); + } + return new Dimension(value, unit); +}; +Dimension.prototype.compare = function (other) { + var a, b; + + if (!(other instanceof Dimension)) { + return undefined; + } + + if (this.unit.isEmpty() || other.unit.isEmpty()) { + a = this; + b = other; + } else { + a = this.unify(); + b = other.unify(); + if (a.unit.compare(b.unit) !== 0) { + return undefined; + } + } + + return Node.numericCompare(a.value, b.value); +}; +Dimension.prototype.unify = function () { + return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); +}; +Dimension.prototype.convertTo = function (conversions) { + var value = this.value, unit = this.unit.clone(), + i, groupName, group, targetUnit, derivedConversions = {}, applyUnit; + + if (typeof conversions === 'string') { + for(i in unitConversions) { + if (unitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; + } + applyUnit = function (atomicUnit, denominator) { + /*jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit)) { + if (denominator) { + value = value / (group[atomicUnit] / group[targetUnit]); + } else { + value = value * (group[atomicUnit] / group[targetUnit]); + } + + return targetUnit; + } + + return atomicUnit; + }; + + for (groupName in conversions) { + if (conversions.hasOwnProperty(groupName)) { + targetUnit = conversions[groupName]; + group = unitConversions[groupName]; + + unit.map(applyUnit); + } + } + + unit.cancel(); + + return new Dimension(value, unit); +}; +module.exports = Dimension; + +},{"../data/unit-conversions":13,"./color":47,"./node":67,"./unit":76}],54:[function(require,module,exports){ +var Node = require("./node"), + Ruleset = require("./ruleset"); + +var Directive = function (name, value, rules, index, currentFileInfo, debugInfo) { + this.name = name; + this.value = value; + if (rules) { + this.rules = rules; + this.rules.allowImports = true; + } + this.index = index; + this.currentFileInfo = currentFileInfo; + this.debugInfo = debugInfo; +}; + +Directive.prototype = new Node(); +Directive.prototype.type = "Directive"; +Directive.prototype.accept = function (visitor) { + var value = this.value, rules = this.rules; + if (rules) { + this.rules = visitor.visit(rules); + } + if (value) { + this.value = visitor.visit(value); + } +}; +Directive.prototype.isRulesetLike = function() { + return this.rules || !this.isCharset(); +}; +Directive.prototype.isCharset = function() { + return "@charset" === this.name; +}; +Directive.prototype.genCSS = function (context, output) { + var value = this.value, rules = this.rules; + output.add(this.name, this.currentFileInfo, this.index); + if (value) { + output.add(' '); + value.genCSS(context, output); + } + if (rules) { + this.outputRuleset(context, output, [rules]); + } else { + output.add(';'); + } +}; +Directive.prototype.eval = function (context) { + var value = this.value, rules = this.rules; + if (value) { + value = value.eval(context); + } + if (rules) { + rules = rules.eval(context); + rules.root = true; + } + return new Directive(this.name, value, rules, + this.index, this.currentFileInfo, this.debugInfo); +}; +Directive.prototype.variable = function (name) { if (this.rules) return Ruleset.prototype.variable.call(this.rules, name); }; +Directive.prototype.find = function () { if (this.rules) return Ruleset.prototype.find.apply(this.rules, arguments); }; +Directive.prototype.rulesets = function () { if (this.rules) return Ruleset.prototype.rulesets.apply(this.rules); }; +Directive.prototype.markReferenced = function () { + var i, rules; + this.isReferenced = true; + if (this.rules) { + rules = this.rules.rules; + for (i = 0; i < rules.length; i++) { + if (rules[i].markReferenced) { + rules[i].markReferenced(); + } + } + } +}; +Directive.prototype.outputRuleset = function (context, output, rules) { + var ruleCnt = rules.length, i; + context.tabLevel = (context.tabLevel | 0) + 1; + + // Compressed + if (context.compress) { + output.add('{'); + for (i = 0; i < ruleCnt; i++) { + rules[i].genCSS(context, output); + } + output.add('}'); + context.tabLevel--; + return; + } + + // Non-compressed + var tabSetStr = '\n' + Array(context.tabLevel).join(" "), tabRuleStr = tabSetStr + " "; + if (!ruleCnt) { + output.add(" {" + tabSetStr + '}'); + } else { + output.add(" {" + tabRuleStr); + rules[0].genCSS(context, output); + for (i = 1; i < ruleCnt; i++) { + output.add(tabRuleStr); + rules[i].genCSS(context, output); + } + output.add(tabSetStr + '}'); + } + + context.tabLevel--; +}; +module.exports = Directive; + +},{"./node":67,"./ruleset":73}],55:[function(require,module,exports){ +var Node = require("./node"), + Paren = require("./paren"), + Combinator = require("./combinator"); + +var Element = function (combinator, value, index, currentFileInfo) { + this.combinator = combinator instanceof Combinator ? + combinator : new Combinator(combinator); + + if (typeof(value) === 'string') { + this.value = value.trim(); + } else if (value) { + this.value = value; + } else { + this.value = ""; + } + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +Element.prototype = new Node(); +Element.prototype.type = "Element"; +Element.prototype.accept = function (visitor) { + var value = this.value; + this.combinator = visitor.visit(this.combinator); + if (typeof value === "object") { + this.value = visitor.visit(value); + } +}; +Element.prototype.eval = function (context) { + return new Element(this.combinator, + this.value.eval ? this.value.eval(context) : this.value, + this.index, + this.currentFileInfo); +}; +Element.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context), this.currentFileInfo, this.index); +}; +Element.prototype.toCSS = function (context) { + context = context || {}; + var value = this.value, firstSelector = context.firstSelector; + if (value instanceof Paren) { + // selector in parens should not be affected by outer selector + // flags (breaks only interpolated selectors - see #1973) + context.firstSelector = true; + } + value = value.toCSS ? value.toCSS(context) : value; + context.firstSelector = firstSelector; + if (value === '' && this.combinator.value.charAt(0) === '&') { + return ''; + } else { + return this.combinator.toCSS(context) + value; + } +}; +module.exports = Element; + +},{"./combinator":48,"./node":67,"./paren":69}],56:[function(require,module,exports){ +var Node = require("./node"), + Paren = require("./paren"), + Comment = require("./comment"); + +var Expression = function (value) { + this.value = value; + if (!value) { + throw new Error("Expression requires a array parameter"); + } +}; +Expression.prototype = new Node(); +Expression.prototype.type = "Expression"; +Expression.prototype.accept = function (visitor) { + this.value = visitor.visitArray(this.value); +}; +Expression.prototype.eval = function (context) { + var returnValue, + inParenthesis = this.parens && !this.parensInOp, + doubleParen = false; + if (inParenthesis) { + context.inParenthesis(); + } + if (this.value.length > 1) { + returnValue = new Expression(this.value.map(function (e) { + return e.eval(context); + })); + } else if (this.value.length === 1) { + if (this.value[0].parens && !this.value[0].parensInOp) { + doubleParen = true; + } + returnValue = this.value[0].eval(context); + } else { + returnValue = this; + } + if (inParenthesis) { + context.outOfParenthesis(); + } + if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) { + returnValue = new Paren(returnValue); + } + return returnValue; +}; +Expression.prototype.genCSS = function (context, output) { + for(var i = 0; i < this.value.length; i++) { + this.value[i].genCSS(context, output); + if (i + 1 < this.value.length) { + output.add(" "); + } + } +}; +Expression.prototype.throwAwayComments = function () { + this.value = this.value.filter(function(v) { + return !(v instanceof Comment); + }); +}; +module.exports = Expression; + +},{"./comment":49,"./node":67,"./paren":69}],57:[function(require,module,exports){ +var Node = require("./node"); + +var Extend = function Extend(selector, option, index) { + this.selector = selector; + this.option = option; + this.index = index; + this.object_id = Extend.next_id++; + this.parent_ids = [this.object_id]; + + switch(option) { + case "all": + this.allowBefore = true; + this.allowAfter = true; + break; + default: + this.allowBefore = false; + this.allowAfter = false; + break; + } +}; +Extend.next_id = 0; + +Extend.prototype = new Node(); +Extend.prototype.type = "Extend"; +Extend.prototype.accept = function (visitor) { + this.selector = visitor.visit(this.selector); +}; +Extend.prototype.eval = function (context) { + return new Extend(this.selector.eval(context), this.option, this.index); +}; +Extend.prototype.clone = function (context) { + return new Extend(this.selector, this.option, this.index); +}; +Extend.prototype.findSelfSelectors = function (selectors) { + var selfElements = [], + i, + selectorElements; + + for(i = 0; i < selectors.length; i++) { + selectorElements = selectors[i].elements; + // duplicate the logic in genCSS function inside the selector node. + // future TODO - move both logics into the selector joiner visitor + if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") { + selectorElements[0].combinator.value = ' '; + } + selfElements = selfElements.concat(selectors[i].elements); + } + + this.selfSelectors = [{ elements: selfElements }]; +}; +module.exports = Extend; + +},{"./node":67}],58:[function(require,module,exports){ +var Node = require("./node"), + Media = require("./media"), + URL = require("./url"), + Quoted = require("./quoted"), + Ruleset = require("./ruleset"), + Anonymous = require("./anonymous"); + +// +// CSS @import node +// +// The general strategy here is that we don't want to wait +// for the parsing to be completed, before we start importing +// the file. That's because in the context of a browser, +// most of the time will be spent waiting for the server to respond. +// +// On creation, we push the import path to our import queue, though +// `import,push`, we also pass it a callback, which it'll call once +// the file has been fetched, and parsed. +// +var Import = function (path, features, options, index, currentFileInfo) { + this.options = options; + this.index = index; + this.path = path; + this.features = features; + this.currentFileInfo = currentFileInfo; + + if (this.options.less !== undefined || this.options.inline) { + this.css = !this.options.less || this.options.inline; + } else { + var pathValue = this.getPath(); + if (pathValue && /[#\.\&\?\/]css([\?;].*)?$/.test(pathValue)) { + this.css = true; + } + } +}; + +// +// The actual import node doesn't return anything, when converted to CSS. +// The reason is that it's used at the evaluation stage, so that the rules +// it imports can be treated like any other rules. +// +// In `eval`, we make sure all Import nodes get evaluated, recursively, so +// we end up with a flat structure, which can easily be imported in the parent +// ruleset. +// +Import.prototype = new Node(); +Import.prototype.type = "Import"; +Import.prototype.accept = function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); + } + this.path = visitor.visit(this.path); + if (!this.options.inline && this.root) { + this.root = visitor.visit(this.root); + } +}; +Import.prototype.genCSS = function (context, output) { + if (this.css) { + output.add("@import ", this.currentFileInfo, this.index); + this.path.genCSS(context, output); + if (this.features) { + output.add(" "); + this.features.genCSS(context, output); + } + output.add(';'); + } +}; +Import.prototype.getPath = function () { + if (this.path instanceof Quoted) { + return this.path.value; + } else if (this.path instanceof URL) { + return this.path.value.value; + } + return null; +}; +Import.prototype.isVariableImport = function () { + var path = this.path; + if (path instanceof URL) { + path = path.value; + } + if (path instanceof Quoted) { + return path.containsVariables(); + } + + return true; +}; +Import.prototype.evalForImport = function (context) { + var path = this.path; + if (path instanceof URL) { + path = path.value; + } + return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo); +}; +Import.prototype.evalPath = function (context) { + var path = this.path.eval(context); + var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; + + if (!(path instanceof URL)) { + if (rootpath) { + var pathValue = path.value; + // Add the base path if the import is relative + if (pathValue && context.isPathRelative(pathValue)) { + path.value = rootpath +pathValue; + } + } + path.value = context.normalizePath(path.value); + } + + return path; +}; +Import.prototype.eval = function (context) { + var ruleset, features = this.features && this.features.eval(context); + + if (this.skip) { + if (typeof this.skip === "function") { + this.skip = this.skip(); + } + if (this.skip) { + return []; + } + } + + if (this.options.inline) { + var contents = new Anonymous(this.root, 0, {filename: this.importedFilename}, true, true); + return this.features ? new Media([contents], this.features.value) : [contents]; + } else if (this.css) { + var newImport = new Import(this.evalPath(context), features, this.options, this.index); + if (!newImport.css && this.error) { + throw this.error; + } + return newImport; + } else { + ruleset = new Ruleset(null, this.root.rules.slice(0)); + + ruleset.evalImports(context); + + return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; + } +}; +module.exports = Import; + +},{"./anonymous":43,"./media":63,"./node":67,"./quoted":70,"./ruleset":73,"./url":77}],59:[function(require,module,exports){ +var tree = {}; + +tree.Alpha = require('./alpha'); +tree.Color = require('./color'); +tree.Directive = require('./directive'); +tree.DetachedRuleset = require('./detached-ruleset'); +tree.Operation = require('./operation'); +tree.Dimension = require('./dimension'); +tree.Unit = require('./unit'); +tree.Keyword = require('./keyword'); +tree.Variable = require('./variable'); +tree.Ruleset = require('./ruleset'); +tree.Element = require('./element'); +tree.Attribute = require('./attribute'); +tree.Combinator = require('./combinator'); +tree.Selector = require('./selector'); +tree.Quoted = require('./quoted'); +tree.Expression = require('./expression'); +tree.Rule = require('./rule'); +tree.Call = require('./call'); +tree.URL = require('./url'); +tree.Import = require('./import'); +tree.mixin = { + Call: require('./mixin-call'), + Definition: require('./mixin-definition') +}; +tree.Comment = require('./comment'); +tree.Anonymous = require('./anonymous'); +tree.Value = require('./value'); +tree.JavaScript = require('./javascript'); +tree.Assignment = require('./assignment'); +tree.Condition = require('./condition'); +tree.Paren = require('./paren'); +tree.Media = require('./media'); +tree.UnicodeDescriptor = require('./unicode-descriptor'); +tree.Negative = require('./negative'); +tree.Extend = require('./extend'); +tree.RulesetCall = require('./ruleset-call'); + +module.exports = tree; + +},{"./alpha":42,"./anonymous":43,"./assignment":44,"./attribute":45,"./call":46,"./color":47,"./combinator":48,"./comment":49,"./condition":50,"./detached-ruleset":52,"./dimension":53,"./directive":54,"./element":55,"./expression":56,"./extend":57,"./import":58,"./javascript":60,"./keyword":62,"./media":63,"./mixin-call":64,"./mixin-definition":65,"./negative":66,"./operation":68,"./paren":69,"./quoted":70,"./rule":71,"./ruleset":73,"./ruleset-call":72,"./selector":74,"./unicode-descriptor":75,"./unit":76,"./url":77,"./value":78,"./variable":79}],60:[function(require,module,exports){ +var JsEvalNode = require("./js-eval-node"), + Dimension = require("./dimension"), + Quoted = require("./quoted"), + Anonymous = require("./anonymous"); + +var JavaScript = function (string, escaped, index, currentFileInfo) { + this.escaped = escaped; + this.expression = string; + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +JavaScript.prototype = new JsEvalNode(); +JavaScript.prototype.type = "JavaScript"; +JavaScript.prototype.eval = function(context) { + var result = this.evaluateJavaScript(this.expression, context); + + if (typeof(result) === 'number') { + return new Dimension(result); + } else if (typeof(result) === 'string') { + return new Quoted('"' + result + '"', result, this.escaped, this.index); + } else if (Array.isArray(result)) { + return new Anonymous(result.join(', ')); + } else { + return new Anonymous(result); + } +}; + +module.exports = JavaScript; + +},{"./anonymous":43,"./dimension":53,"./js-eval-node":61,"./quoted":70}],61:[function(require,module,exports){ +var Node = require("./node"), + Variable = require("./variable"); + +var JsEvalNode = function() { +}; +JsEvalNode.prototype = new Node(); + +JsEvalNode.prototype.evaluateJavaScript = function (expression, context) { + var result, + that = this, + evalContext = {}; + + if (context.javascriptEnabled !== undefined && !context.javascriptEnabled) { + throw { message: "You are using JavaScript, which has been disabled.", + filename: this.currentFileInfo.filename, + index: this.index }; + } + + expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { + return that.jsify(new Variable('@' + name, that.index, that.currentFileInfo).eval(context)); + }); + + try { + expression = new Function('return (' + expression + ')'); + } catch (e) { + throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" , + filename: this.currentFileInfo.filename, + index: this.index }; + } + + var variables = context.frames[0].variables(); + for (var k in variables) { + if (variables.hasOwnProperty(k)) { + /*jshint loopfunc:true */ + evalContext[k.slice(1)] = { + value: variables[k].value, + toJS: function () { + return this.value.eval(context).toCSS(); + } + }; + } + } + + try { + result = expression.call(evalContext); + } catch (e) { + throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" , + filename: this.currentFileInfo.filename, + index: this.index }; + } + return result; +}; +JsEvalNode.prototype.jsify = function (obj) { + if (Array.isArray(obj.value) && (obj.value.length > 1)) { + return '[' + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + ']'; + } else { + return obj.toCSS(); + } +}; + +module.exports = JsEvalNode; + +},{"./node":67,"./variable":79}],62:[function(require,module,exports){ +var Node = require("./node"); + +var Keyword = function (value) { this.value = value; }; +Keyword.prototype = new Node(); +Keyword.prototype.type = "Keyword"; +Keyword.prototype.genCSS = function (context, output) { + if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; } + output.add(this.value); +}; + +Keyword.True = new Keyword('true'); +Keyword.False = new Keyword('false'); + +module.exports = Keyword; + +},{"./node":67}],63:[function(require,module,exports){ +var Ruleset = require("./ruleset"), + Value = require("./value"), + Element = require("./element"), + Selector = require("./selector"), + Anonymous = require("./anonymous"), + Expression = require("./expression"), + Directive = require("./directive"); + +var Media = function (value, features, index, currentFileInfo) { + this.index = index; + this.currentFileInfo = currentFileInfo; + + var selectors = this.emptySelectors(); + + this.features = new Value(features); + this.rules = [new Ruleset(selectors, value)]; + this.rules[0].allowImports = true; +}; +Media.prototype = new Directive(); +Media.prototype.type = "Media"; +Media.prototype.isRulesetLike = true; +Media.prototype.accept = function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); + } + if (this.rules) { + this.rules = visitor.visitArray(this.rules); + } +}; +Media.prototype.genCSS = function (context, output) { + output.add('@media ', this.currentFileInfo, this.index); + this.features.genCSS(context, output); + this.outputRuleset(context, output, this.rules); +}; +Media.prototype.eval = function (context) { + if (!context.mediaBlocks) { + context.mediaBlocks = []; + context.mediaPath = []; + } + + var media = new Media(null, [], this.index, this.currentFileInfo); + if(this.debugInfo) { + this.rules[0].debugInfo = this.debugInfo; + media.debugInfo = this.debugInfo; + } + var strictMathBypass = false; + if (!context.strictMath) { + strictMathBypass = true; + context.strictMath = true; + } + try { + media.features = this.features.eval(context); + } + finally { + if (strictMathBypass) { + context.strictMath = false; + } + } + + context.mediaPath.push(media); + context.mediaBlocks.push(media); + + context.frames.unshift(this.rules[0]); + media.rules = [this.rules[0].eval(context)]; + context.frames.shift(); + + context.mediaPath.pop(); + + return context.mediaPath.length === 0 ? media.evalTop(context) : + media.evalNested(context); +}; +//TODO merge with directive +Media.prototype.variable = function (name) { return Ruleset.prototype.variable.call(this.rules[0], name); }; +Media.prototype.find = function () { return Ruleset.prototype.find.apply(this.rules[0], arguments); }; +Media.prototype.rulesets = function () { return Ruleset.prototype.rulesets.apply(this.rules[0]); }; +Media.prototype.emptySelectors = function() { + var el = new Element('', '&', this.index, this.currentFileInfo), + sels = [new Selector([el], null, null, this.index, this.currentFileInfo)]; + sels[0].mediaEmpty = true; + return sels; +}; +Media.prototype.markReferenced = function () { + var i, rules = this.rules[0].rules; + this.rules[0].markReferenced(); + this.isReferenced = true; + for (i = 0; i < rules.length; i++) { + if (rules[i].markReferenced) { + rules[i].markReferenced(); + } + } +}; +Media.prototype.evalTop = function (context) { + var result = this; + + // Render all dependent Media blocks. + if (context.mediaBlocks.length > 1) { + var selectors = this.emptySelectors(); + result = new Ruleset(selectors, context.mediaBlocks); + result.multiMedia = true; + } + + delete context.mediaBlocks; + delete context.mediaPath; + + return result; +}; +Media.prototype.evalNested = function (context) { + var i, value, + path = context.mediaPath.concat([this]); + + // Extract the media-query conditions separated with `,` (OR). + for (i = 0; i < path.length; i++) { + value = path[i].features instanceof Value ? + path[i].features.value : path[i].features; + path[i] = Array.isArray(value) ? value : [value]; + } + + // Trace all permutations to generate the resulting media-query. + // + // (a, b and c) with nested (d, e) -> + // a and d + // a and e + // b and c and d + // b and c and e + this.features = new Value(this.permute(path).map(function (path) { + path = path.map(function (fragment) { + return fragment.toCSS ? fragment : new Anonymous(fragment); + }); + + for(i = path.length - 1; i > 0; i--) { + path.splice(i, 0, new Anonymous("and")); + } + + return new Expression(path); + })); + + // Fake a tree-node that doesn't output anything. + return new Ruleset([], []); +}; +Media.prototype.permute = function (arr) { + if (arr.length === 0) { + return []; + } else if (arr.length === 1) { + return arr[0]; + } else { + var result = []; + var rest = this.permute(arr.slice(1)); + for (var i = 0; i < rest.length; i++) { + for (var j = 0; j < arr[0].length; j++) { + result.push([arr[0][j]].concat(rest[i])); + } + } + return result; + } +}; +Media.prototype.bubbleSelectors = function (selectors) { + if (!selectors) + return; + this.rules = [new Ruleset(selectors.slice(0), [this.rules[0]])]; +}; +module.exports = Media; + +},{"./anonymous":43,"./directive":54,"./element":55,"./expression":56,"./ruleset":73,"./selector":74,"./value":78}],64:[function(require,module,exports){ +var Node = require("./node"), + Selector = require("./selector"), + MixinDefinition = require("./mixin-definition"), + defaultFunc = require("../functions/default"); + +var MixinCall = function (elements, args, index, currentFileInfo, important) { + this.selector = new Selector(elements); + this.arguments = (args && args.length) ? args : null; + this.index = index; + this.currentFileInfo = currentFileInfo; + this.important = important; +}; +MixinCall.prototype = new Node(); +MixinCall.prototype.type = "MixinCall"; +MixinCall.prototype.accept = function (visitor) { + if (this.selector) { + this.selector = visitor.visit(this.selector); + } + if (this.arguments) { + this.arguments = visitor.visitArray(this.arguments); + } +}; +MixinCall.prototype.eval = function (context) { + var mixins, mixin, mixinPath, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule, + candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase=-1, + defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter; + + function calcDefGroup(mixin, mixinPath) { + var p, namespace; + + for (f = 0; f < 2; f++) { + conditionResult[f] = true; + defaultFunc.value(f); + for(p = 0; p < mixinPath.length && conditionResult[f]; p++) { + namespace = mixinPath[p]; + if (namespace.matchCondition) { + conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + } + } + if (mixin.matchCondition) { + conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); + } + } + if (conditionResult[0] || conditionResult[1]) { + if (conditionResult[0] != conditionResult[1]) { + return conditionResult[1] ? + defTrue : defFalse; + } + + return defNone; + } + return defFalseEitherCase; + } + + args = this.arguments && this.arguments.map(function (a) { + return { name: a.name, value: a.value.eval(context) }; + }); + + noArgumentsFilter = function(rule) {return rule.matchArgs(null, context);}; + + for (i = 0; i < context.frames.length; i++) { + if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { + isOneFound = true; + + // To make `default()` function independent of definition order we have two "subpasses" here. + // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), + // and build candidate list with corresponding flags. Then, when we know all possible matches, + // we make a final decision. + + for (m = 0; m < mixins.length; m++) { + mixin = mixins[m].rule; + mixinPath = mixins[m].path; + isRecursive = false; + for(f = 0; f < context.frames.length; f++) { + if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { + isRecursive = true; + break; + } + } + if (isRecursive) { + continue; + } + + if (mixin.matchArgs(args, context)) { + candidate = {mixin: mixin, group: calcDefGroup(mixin, mixinPath)}; + + if (candidate.group!==defFalseEitherCase) { + candidates.push(candidate); + } + + match = true; + } + } + + defaultFunc.reset(); + + count = [0, 0, 0]; + for (m = 0; m < candidates.length; m++) { + count[candidates[m].group]++; + } + + if (count[defNone] > 0) { + defaultResult = defFalse; + } else { + defaultResult = defTrue; + if ((count[defTrue] + count[defFalse]) > 1) { + throw { type: 'Runtime', + message: 'Ambiguous use of `default()` found when matching for `' + + this.format(args) + '`', + index: this.index, filename: this.currentFileInfo.filename }; + } + } + + for (m = 0; m < candidates.length; m++) { + candidate = candidates[m].group; + if ((candidate === defNone) || (candidate === defaultResult)) { + try { + mixin = candidates[m].mixin; + if (!(mixin instanceof MixinDefinition)) { + originalRuleset = mixin.originalRuleset || mixin; + mixin = new MixinDefinition("", [], mixin.rules, null, false); + mixin.originalRuleset = originalRuleset; + } + Array.prototype.push.apply( + rules, mixin.evalCall(context, args, this.important).rules); + } catch (e) { + throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack }; + } + } + } + + if (match) { + if (!this.currentFileInfo || !this.currentFileInfo.reference) { + for (i = 0; i < rules.length; i++) { + rule = rules[i]; + if (rule.markReferenced) { + rule.markReferenced(); + } + } + } + return rules; + } + } + } + if (isOneFound) { + throw { type: 'Runtime', + message: 'No matching definition was found for `' + this.format(args) + '`', + index: this.index, filename: this.currentFileInfo.filename }; + } else { + throw { type: 'Name', + message: this.selector.toCSS().trim() + " is undefined", + index: this.index, filename: this.currentFileInfo.filename }; + } +}; +MixinCall.prototype.format = function (args) { + return this.selector.toCSS().trim() + '(' + + (args ? args.map(function (a) { + var argValue = ""; + if (a.name) { + argValue += a.name + ":"; + } + if (a.value.toCSS) { + argValue += a.value.toCSS(); + } else { + argValue += "???"; + } + return argValue; + }).join(', ') : "") + ")"; +}; +module.exports = MixinCall; + +},{"../functions/default":19,"./mixin-definition":65,"./node":67,"./selector":74}],65:[function(require,module,exports){ +var Selector = require("./selector"), + Element = require("./element"), + Ruleset = require("./ruleset"), + Rule = require("./rule"), + Expression = require("./expression"), + contexts = require("../contexts"); + +var Definition = function (name, params, rules, condition, variadic, frames) { + this.name = name; + this.selectors = [new Selector([new Element(null, name, this.index, this.currentFileInfo)])]; + this.params = params; + this.condition = condition; + this.variadic = variadic; + this.arity = params.length; + this.rules = rules; + this._lookups = {}; + this.required = params.reduce(function (count, p) { + if (!p.name || (p.name && !p.value)) { return count + 1; } + else { return count; } + }, 0); + this.frames = frames; +}; +Definition.prototype = new Ruleset(); +Definition.prototype.type = "MixinDefinition"; +Definition.prototype.evalFirst = true; +Definition.prototype.accept = function (visitor) { + if (this.params && this.params.length) { + this.params = visitor.visitArray(this.params); + } + this.rules = visitor.visitArray(this.rules); + if (this.condition) { + this.condition = visitor.visit(this.condition); + } +}; +Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) { + /*jshint boss:true */ + var frame = new Ruleset(null, null), + varargs, arg, + params = this.params.slice(0), + i, j, val, name, isNamedFound, argIndex, argsLength = 0; + + mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); + + if (args) { + args = args.slice(0); + argsLength = args.length; + + for(i = 0; i < argsLength; i++) { + arg = args[i]; + if (name = (arg && arg.name)) { + isNamedFound = false; + for(j = 0; j < params.length; j++) { + if (!evaldArguments[j] && name === params[j].name) { + evaldArguments[j] = arg.value.eval(context); + frame.prependRule(new Rule(name, arg.value.eval(context))); + isNamedFound = true; + break; + } + } + if (isNamedFound) { + args.splice(i, 1); + i--; + continue; + } else { + throw { type: 'Runtime', message: "Named argument for " + this.name + + ' ' + args[i].name + ' not found' }; + } + } + } + } + argIndex = 0; + for (i = 0; i < params.length; i++) { + if (evaldArguments[i]) { continue; } + + arg = args && args[argIndex]; + + if (name = params[i].name) { + if (params[i].variadic) { + varargs = []; + for (j = argIndex; j < argsLength; j++) { + varargs.push(args[j].value.eval(context)); + } + frame.prependRule(new Rule(name, new Expression(varargs).eval(context))); + } else { + val = arg && arg.value; + if (val) { + val = val.eval(context); + } else if (params[i].value) { + val = params[i].value.eval(mixinEnv); + frame.resetCache(); + } else { + throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + + ' (' + argsLength + ' for ' + this.arity + ')' }; + } + + frame.prependRule(new Rule(name, val)); + evaldArguments[i] = val; + } + } + + if (params[i].variadic && args) { + for (j = argIndex; j < argsLength; j++) { + evaldArguments[j] = args[j].value.eval(context); + } + } + argIndex++; + } + + return frame; +}; +Definition.prototype.eval = function (context) { + return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || context.frames.slice(0)); +}; +Definition.prototype.evalCall = function (context, args, important) { + var _arguments = [], + mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames, + frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments), + rules, ruleset; + + frame.prependRule(new Rule('@arguments', new Expression(_arguments).eval(context))); + + rules = this.rules.slice(0); + + ruleset = new Ruleset(null, rules); + ruleset.originalRuleset = this; + ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); + if (important) { + ruleset = this.makeImportant.apply(ruleset); + } + return ruleset; +}; +Definition.prototype.matchCondition = function (args, context) { + if (this.condition && !this.condition.eval( + new contexts.Eval(context, + [this.evalParams(context, new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])] // the parameter variables + .concat(this.frames) // the parent namespace/mixin frames + .concat(context.frames)))) { // the current environment frames + return false; + } + return true; +}; +Definition.prototype.matchArgs = function (args, context) { + var argsLength = (args && args.length) || 0, len; + + if (! this.variadic) { + if (argsLength < this.required) { return false; } + if (argsLength > this.params.length) { return false; } + } else { + if (argsLength < (this.required - 1)) { return false; } + } + + len = Math.min(argsLength, this.arity); + + for (var i = 0; i < len; i++) { + if (!this.params[i].name && !this.params[i].variadic) { + if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) { + return false; + } + } + } + return true; +}; +module.exports = Definition; + +},{"../contexts":10,"./element":55,"./expression":56,"./rule":71,"./ruleset":73,"./selector":74}],66:[function(require,module,exports){ +var Node = require("./node"), + Operation = require("./operation"), + Dimension = require("./dimension"); + +var Negative = function (node) { + this.value = node; +}; +Negative.prototype = new Node(); +Negative.prototype.type = "Negative"; +Negative.prototype.genCSS = function (context, output) { + output.add('-'); + this.value.genCSS(context, output); +}; +Negative.prototype.eval = function (context) { + if (context.isMathOn()) { + return (new Operation('*', [new Dimension(-1), this.value])).eval(context); + } + return new Negative(this.value.eval(context)); +}; +module.exports = Negative; + +},{"./dimension":53,"./node":67,"./operation":68}],67:[function(require,module,exports){ +var Node = function() { +}; +Node.prototype.toCSS = function (context) { + var strs = []; + this.genCSS(context, { + add: function(chunk, fileInfo, index) { + strs.push(chunk); + }, + isEmpty: function () { + return strs.length === 0; + } + }); + return strs.join(''); +}; +Node.prototype.genCSS = function (context, output) { + output.add(this.value); +}; +Node.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); +}; +Node.prototype.eval = function () { return this; }; +Node.prototype._operate = function (context, op, a, b) { + switch (op) { + case '+': return a + b; + case '-': return a - b; + case '*': return a * b; + case '/': return a / b; + } +}; +Node.prototype.fround = function(context, value) { + var precision = context && context.numPrecision; + //add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded... + return (precision == null) ? value : Number((value + 2e-16).toFixed(precision)); +}; +Node.compare = function (a, b) { + /* returns: + -1: a < b + 0: a = b + 1: a > b + and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ + + if ((a.compare) && + // for "symmetric results" force toCSS-based comparison + // of Quoted or Anonymous if either value is one of those + !(b.type === "Quoted" || b.type === "Anonymous")) { + return a.compare(b); + } else if (b.compare) { + return -b.compare(a); + } else if (a.type !== b.type) { + return undefined; + } + + a = a.value; + b = b.value; + if (!Array.isArray(a)) { + return a === b ? 0 : undefined; + } + if (a.length !== b.length) { + return undefined; + } + for (var i = 0; i < a.length; i++) { + if (Node.compare(a[i], b[i]) !== 0) { + return undefined; + } + } + return 0; +}; + +Node.numericCompare = function (a, b) { + return a < b ? -1 + : a === b ? 0 + : a > b ? 1 : undefined; +}; +module.exports = Node; + +},{}],68:[function(require,module,exports){ +var Node = require("./node"), + Color = require("./color"), + Dimension = require("./dimension"); + +var Operation = function (op, operands, isSpaced) { + this.op = op.trim(); + this.operands = operands; + this.isSpaced = isSpaced; +}; +Operation.prototype = new Node(); +Operation.prototype.type = "Operation"; +Operation.prototype.accept = function (visitor) { + this.operands = visitor.visit(this.operands); +}; +Operation.prototype.eval = function (context) { + var a = this.operands[0].eval(context), + b = this.operands[1].eval(context); + + if (context.isMathOn()) { + if (a instanceof Dimension && b instanceof Color) { + a = a.toColor(); + } + if (b instanceof Dimension && a instanceof Color) { + b = b.toColor(); + } + if (!a.operate) { + throw { type: "Operation", + message: "Operation on an invalid type" }; + } + + return a.operate(context, this.op, b); + } else { + return new Operation(this.op, [a, b], this.isSpaced); + } +}; +Operation.prototype.genCSS = function (context, output) { + this.operands[0].genCSS(context, output); + if (this.isSpaced) { + output.add(" "); + } + output.add(this.op); + if (this.isSpaced) { + output.add(" "); + } + this.operands[1].genCSS(context, output); +}; + +module.exports = Operation; + +},{"./color":47,"./dimension":53,"./node":67}],69:[function(require,module,exports){ +var Node = require("./node"); + +var Paren = function (node) { + this.value = node; +}; +Paren.prototype = new Node(); +Paren.prototype.type = "Paren"; +Paren.prototype.genCSS = function (context, output) { + output.add('('); + this.value.genCSS(context, output); + output.add(')'); +}; +Paren.prototype.eval = function (context) { + return new Paren(this.value.eval(context)); +}; +module.exports = Paren; + +},{"./node":67}],70:[function(require,module,exports){ +var Node = require("./node"), + JsEvalNode = require("./js-eval-node"), + Variable = require("./variable"); + +var Quoted = function (str, content, escaped, index, currentFileInfo) { + this.escaped = (escaped == null) ? true : escaped; + this.value = content || ''; + this.quote = str.charAt(0); + this.index = index; + this.currentFileInfo = currentFileInfo; +}; +Quoted.prototype = new JsEvalNode(); +Quoted.prototype.type = "Quoted"; +Quoted.prototype.genCSS = function (context, output) { + if (!this.escaped) { + output.add(this.quote, this.currentFileInfo, this.index); + } + output.add(this.value); + if (!this.escaped) { + output.add(this.quote); + } +}; +Quoted.prototype.containsVariables = function() { + return this.value.match(/(`([^`]+)`)|@\{([\w-]+)\}/); +}; +Quoted.prototype.eval = function (context) { + var that = this, value = this.value; + var javascriptReplacement = function (_, exp) { + return String(that.evaluateJavaScript(exp, context)); + }; + var interpolationReplacement = function (_, name) { + var v = new Variable('@' + name, that.index, that.currentFileInfo).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + function iterativeReplace(value, regexp, replacementFnc) { + var evaluatedValue = value; + do { + value = evaluatedValue; + evaluatedValue = value.replace(regexp, replacementFnc); + } while (value!==evaluatedValue); + return evaluatedValue; + } + value = iterativeReplace(value, /`([^`]+)`/g, javascriptReplacement); + value = iterativeReplace(value, /@\{([\w-]+)\}/g, interpolationReplacement); + return new Quoted(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo); +}; +Quoted.prototype.compare = function (other) { + // when comparing quoted strings allow the quote to differ + if (other.type === "Quoted" && !this.escaped && !other.escaped) { + return Node.numericCompare(this.value, other.value); + } else { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + } +}; +module.exports = Quoted; + +},{"./js-eval-node":61,"./node":67,"./variable":79}],71:[function(require,module,exports){ +var Node = require("./node"), + Value = require("./value"), + Keyword = require("./keyword"); + +var Rule = function (name, value, important, merge, index, currentFileInfo, inline, variable) { + this.name = name; + this.value = (value instanceof Node) ? value : new Value([value]); //value instanceof tree.Value || value instanceof tree.Ruleset ?? + this.important = important ? ' ' + important.trim() : ''; + this.merge = merge; + this.index = index; + this.currentFileInfo = currentFileInfo; + this.inline = inline || false; + this.variable = (variable !== undefined) ? variable + : (name.charAt && (name.charAt(0) === '@')); +}; + +function evalName(context, name) { + var value = "", i, n = name.length, + output = {add: function (s) {value += s;}}; + for (i = 0; i < n; i++) { + name[i].eval(context).genCSS(context, output); + } + return value; +} + +Rule.prototype = new Node(); +Rule.prototype.type = "Rule"; +Rule.prototype.genCSS = function (context, output) { + output.add(this.name + (context.compress ? ':' : ': '), this.currentFileInfo, this.index); + try { + this.value.genCSS(context, output); + } + catch(e) { + e.index = this.index; + e.filename = this.currentFileInfo.filename; + throw e; + } + output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? "" : ";"), this.currentFileInfo, this.index); +}; +Rule.prototype.eval = function (context) { + var strictMathBypass = false, name = this.name, evaldValue, variable = this.variable; + if (typeof name !== "string") { + // expand 'primitive' name directly to get + // things faster (~10% for benchmark.less): + name = (name.length === 1) + && (name[0] instanceof Keyword) + ? name[0].value : evalName(context, name); + variable = false; // never treat expanded interpolation as new variable name + } + if (name === "font" && !context.strictMath) { + strictMathBypass = true; + context.strictMath = true; + } + try { + context.importantScope.push({}); + evaldValue = this.value.eval(context); + + if (!this.variable && evaldValue.type === "DetachedRuleset") { + throw { message: "Rulesets cannot be evaluated on a property.", + index: this.index, filename: this.currentFileInfo.filename }; + } + var important = this.important, + importantResult = context.importantScope.pop(); + if (!important && importantResult.important) { + important = importantResult.important; + } + + return new Rule(name, + evaldValue, + important, + this.merge, + this.index, this.currentFileInfo, this.inline, + variable); + } + catch(e) { + if (typeof e.index !== 'number') { + e.index = this.index; + e.filename = this.currentFileInfo.filename; + } + throw e; + } + finally { + if (strictMathBypass) { + context.strictMath = false; + } + } +}; +Rule.prototype.makeImportant = function () { + return new Rule(this.name, + this.value, + "!important", + this.merge, + this.index, this.currentFileInfo, this.inline); +}; + +module.exports = Rule; + +},{"./keyword":62,"./node":67,"./value":78}],72:[function(require,module,exports){ +var Node = require("./node"), + Variable = require("./variable"); + +var RulesetCall = function (variable) { + this.variable = variable; +}; +RulesetCall.prototype = new Node(); +RulesetCall.prototype.type = "RulesetCall"; +RulesetCall.prototype.eval = function (context) { + var detachedRuleset = new Variable(this.variable).eval(context); + return detachedRuleset.callEval(context); +}; +module.exports = RulesetCall; + +},{"./node":67,"./variable":79}],73:[function(require,module,exports){ +var Node = require("./node"), + Rule = require("./rule"), + Selector = require("./selector"), + Element = require("./element"), + contexts = require("../contexts"), + defaultFunc = require("../functions/default"), + getDebugInfo = require("./debug-info"); + +var Ruleset = function (selectors, rules, strictImports) { + this.selectors = selectors; + this.rules = rules; + this._lookups = {}; + this.strictImports = strictImports; +}; +Ruleset.prototype = new Node(); +Ruleset.prototype.type = "Ruleset"; +Ruleset.prototype.isRuleset = true; +Ruleset.prototype.isRulesetLike = true; +Ruleset.prototype.accept = function (visitor) { + if (this.paths) { + visitor.visitArray(this.paths, true); + } else if (this.selectors) { + this.selectors = visitor.visitArray(this.selectors); + } + if (this.rules && this.rules.length) { + this.rules = visitor.visitArray(this.rules); + } +}; +Ruleset.prototype.eval = function (context) { + var thisSelectors = this.selectors, selectors, + selCnt, selector, i, hasOnePassingSelector = false; + + if (thisSelectors && (selCnt = thisSelectors.length)) { + selectors = []; + defaultFunc.error({ + type: "Syntax", + message: "it is currently only allowed in parametric mixin guards," + }); + for (i = 0; i < selCnt; i++) { + selector = thisSelectors[i].eval(context); + selectors.push(selector); + if (selector.evaldCondition) { + hasOnePassingSelector = true; + } + } + defaultFunc.reset(); + } else { + hasOnePassingSelector = true; + } + + var rules = this.rules ? this.rules.slice(0) : null, + ruleset = new Ruleset(selectors, rules, this.strictImports), + rule, subRule; + + ruleset.originalRuleset = this; + ruleset.root = this.root; + ruleset.firstRoot = this.firstRoot; + ruleset.allowImports = this.allowImports; + + if(this.debugInfo) { + ruleset.debugInfo = this.debugInfo; + } + + if (!hasOnePassingSelector) { + rules.length = 0; + } + + // push the current ruleset to the frames stack + var ctxFrames = context.frames; + ctxFrames.unshift(ruleset); + + // currrent selectors + var ctxSelectors = context.selectors; + if (!ctxSelectors) { + context.selectors = ctxSelectors = []; + } + ctxSelectors.unshift(this.selectors); + + // Evaluate imports + if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { + ruleset.evalImports(context); + } + + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0; + for (i = 0; i < rsRuleCnt; i++) { + if (rsRules[i].evalFirst) { + rsRules[i] = rsRules[i].eval(context); + } + } + + var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0; + + // Evaluate mixin calls. + for (i = 0; i < rsRuleCnt; i++) { + if (rsRules[i].type === "MixinCall") { + /*jshint loopfunc:true */ + rules = rsRules[i].eval(context).filter(function(r) { + if ((r instanceof Rule) && r.variable) { + // do not pollute the scope if the variable is + // already there. consider returning false here + // but we need a way to "return" variable from mixins + return !(ruleset.variable(r.name)); + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + rsRuleCnt += rules.length - 1; + i += rules.length-1; + ruleset.resetCache(); + } else if (rsRules[i].type === "RulesetCall") { + /*jshint loopfunc:true */ + rules = rsRules[i].eval(context).rules.filter(function(r) { + if ((r instanceof Rule) && r.variable) { + // do not pollute the scope at all + return false; + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + rsRuleCnt += rules.length - 1; + i += rules.length-1; + ruleset.resetCache(); + } + } + + // Evaluate everything else + for (i = 0; i < rsRules.length; i++) { + rule = rsRules[i]; + if (!rule.evalFirst) { + rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + } + } + + // Evaluate everything else + for (i = 0; i < rsRules.length; i++) { + rule = rsRules[i]; + // for rulesets, check if it is a css guard and can be removed + if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { + // check if it can be folded in (e.g. & where) + if (rule.selectors[0].isJustParentSelector()) { + rsRules.splice(i--, 1); + + for(var j = 0; j < rule.rules.length; j++) { + subRule = rule.rules[j]; + if (!(subRule instanceof Rule) || !subRule.variable) { + rsRules.splice(++i, 0, subRule); + } + } + } + } + } + + // Pop the stack + ctxFrames.shift(); + ctxSelectors.shift(); + + if (context.mediaBlocks) { + for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { + context.mediaBlocks[i].bubbleSelectors(selectors); + } + } + + return ruleset; +}; +Ruleset.prototype.evalImports = function(context) { + var rules = this.rules, i, importRules; + if (!rules) { return; } + + for (i = 0; i < rules.length; i++) { + if (rules[i].type === "Import") { + importRules = rules[i].eval(context); + if (importRules && importRules.length) { + rules.splice.apply(rules, [i, 1].concat(importRules)); + i+= importRules.length-1; + } else { + rules.splice(i, 1, importRules); + } + this.resetCache(); + } + } +}; +Ruleset.prototype.makeImportant = function() { + return new Ruleset(this.selectors, this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(); + } else { + return r; + } + }), this.strictImports); +}; +Ruleset.prototype.matchArgs = function (args) { + return !args || args.length === 0; +}; +// lets you call a css selector with a guard +Ruleset.prototype.matchCondition = function (args, context) { + var lastSelector = this.selectors[this.selectors.length-1]; + if (!lastSelector.evaldCondition) { + return false; + } + if (lastSelector.condition && + !lastSelector.condition.eval( + new contexts.Eval(context, + context.frames))) { + return false; + } + return true; +}; +Ruleset.prototype.resetCache = function () { + this._rulesets = null; + this._variables = null; + this._lookups = {}; +}; +Ruleset.prototype.variables = function () { + if (!this._variables) { + this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Rule && r.variable === true) { + hash[r.name] = r; + } + // when evaluating variables in an import statement, imports have not been eval'd + // so we need to go inside import statements. + // guard against root being a string (in the case of inlined less) + if (r.type === "Import" && r.root && r.root.variables) { + var vars = r.root.variables(); + for(var name in vars) { + if (vars.hasOwnProperty(name)) { + hash[name] = vars[name]; + } + } + } + return hash; + }, {}); + } + return this._variables; +}; +Ruleset.prototype.variable = function (name) { + return this.variables()[name]; +}; +Ruleset.prototype.rulesets = function () { + if (!this.rules) { return null; } + + var filtRules = [], rules = this.rules, cnt = rules.length, + i, rule; + + for (i = 0; i < cnt; i++) { + rule = rules[i]; + if (rule.isRuleset) { + filtRules.push(rule); + } + } + + return filtRules; +}; +Ruleset.prototype.prependRule = function (rule) { + var rules = this.rules; + if (rules) { rules.unshift(rule); } else { this.rules = [ rule ]; } +}; +Ruleset.prototype.find = function (selector, self, filter) { + self = self || this; + var rules = [], match, foundMixins, + key = selector.toCSS(); + + if (key in this._lookups) { return this._lookups[key]; } + + this.rulesets().forEach(function (rule) { + if (rule !== self) { + for (var j = 0; j < rule.selectors.length; j++) { + match = selector.match(rule.selectors[j]); + if (match) { + if (selector.elements.length > match) { + if (!filter || filter(rule)) { + foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); + for (var i = 0; i < foundMixins.length; ++i) { + foundMixins[i].path.push(rule); + } + Array.prototype.push.apply(rules, foundMixins); + } + } else { + rules.push({ rule: rule, path: []}); + } + break; + } + } + } + }); + this._lookups[key] = rules; + return rules; +}; +Ruleset.prototype.genCSS = function (context, output) { + var i, j, + charsetRuleNodes = [], + ruleNodes = [], + rulesetNodes = [], + rulesetNodeCnt, + debugInfo, // Line number debugging + rule, + path; + + context.tabLevel = (context.tabLevel || 0); + + if (!this.root) { + context.tabLevel++; + } + + var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(" "), + tabSetStr = context.compress ? '' : Array(context.tabLevel).join(" "), + sep; + + function isRulesetLikeNode(rule, root) { + // if it has nested rules, then it should be treated like a ruleset + // medias and comments do not have nested rules, but should be treated like rulesets anyway + // some directives and anonymous nodes are ruleset like, others are not + if (typeof rule.isRulesetLike === "boolean") + { + return rule.isRulesetLike; + } else if (typeof rule.isRulesetLike === "function") + { + return rule.isRulesetLike(root); + } + + //anything else is assumed to be a rule + return false; + } + + for (i = 0; i < this.rules.length; i++) { + rule = this.rules[i]; + if (isRulesetLikeNode(rule, this.root)) { + rulesetNodes.push(rule); + } else { + //charsets should float on top of everything + if (rule.isCharset && rule.isCharset()) { + charsetRuleNodes.push(rule); + } else { + ruleNodes.push(rule); + } + } + } + ruleNodes = charsetRuleNodes.concat(ruleNodes); + + // If this is the root node, we don't render + // a selector, or {}. + if (!this.root) { + debugInfo = getDebugInfo(context, this, tabSetStr); + + if (debugInfo) { + output.add(debugInfo); + output.add(tabSetStr); + } + + var paths = this.paths, pathCnt = paths.length, + pathSubCnt; + + sep = context.compress ? ',' : (',\n' + tabSetStr); + + for (i = 0; i < pathCnt; i++) { + path = paths[i]; + if (!(pathSubCnt = path.length)) { continue; } + if (i > 0) { output.add(sep); } + + context.firstSelector = true; + path[0].genCSS(context, output); + + context.firstSelector = false; + for (j = 1; j < pathSubCnt; j++) { + path[j].genCSS(context, output); + } + } + + output.add((context.compress ? '{' : ' {\n') + tabRuleStr); + } + + // Compile rules and rulesets + for (i = 0; i < ruleNodes.length; i++) { + rule = ruleNodes[i]; + + // @page{ directive ends up with root elements inside it, a mix of rules and rulesets + // In this instance we do not know whether it is the last property + if (i + 1 === ruleNodes.length && (!this.root || rulesetNodes.length === 0 || this.firstRoot)) { + context.lastRule = true; + } + + if (rule.genCSS) { + rule.genCSS(context, output); + } else if (rule.value) { + output.add(rule.value.toString()); + } + + if (!context.lastRule) { + output.add(context.compress ? '' : ('\n' + tabRuleStr)); + } else { + context.lastRule = false; + } + } + + if (!this.root) { + output.add((context.compress ? '}' : '\n' + tabSetStr + '}')); + context.tabLevel--; + } + + sep = (context.compress ? "" : "\n") + (this.root ? tabRuleStr : tabSetStr); + rulesetNodeCnt = rulesetNodes.length; + if (rulesetNodeCnt) { + if (ruleNodes.length && sep) { output.add(sep); } + rulesetNodes[0].genCSS(context, output); + for (i = 1; i < rulesetNodeCnt; i++) { + if (sep) { output.add(sep); } + rulesetNodes[i].genCSS(context, output); + } + } + + if (!output.isEmpty() && !context.compress && this.firstRoot) { + output.add('\n'); + } +}; +Ruleset.prototype.markReferenced = function () { + if (!this.selectors) { + return; + } + for (var s = 0; s < this.selectors.length; s++) { + this.selectors[s].markReferenced(); + } +}; +Ruleset.prototype.joinSelectors = function (paths, context, selectors) { + for (var s = 0; s < selectors.length; s++) { + this.joinSelector(paths, context, selectors[s]); + } +}; +Ruleset.prototype.joinSelector = function (paths, context, selector) { + + var i, j, k, + hasParentSelector, newSelectors, el, sel, parentSel, + newSelectorPath, afterParentJoin, newJoinedSelector, + newJoinedSelectorEmpty, lastSelector, currentElements, + selectorsMultiplied; + + for (i = 0; i < selector.elements.length; i++) { + el = selector.elements[i]; + if (el.value === '&') { + hasParentSelector = true; + } + } + + if (!hasParentSelector) { + if (context.length > 0) { + for (i = 0; i < context.length; i++) { + paths.push(context[i].concat(selector)); + } + } + else { + paths.push([selector]); + } + return; + } + + // The paths are [[Selector]] + // The first list is a list of comma separated selectors + // The inner list is a list of inheritance separated selectors + // e.g. + // .a, .b { + // .c { + // } + // } + // == [[.a] [.c]] [[.b] [.c]] + // + + // the elements from the current selector so far + currentElements = []; + // the current list of new selectors to add to the path. + // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors + // by the parents + newSelectors = [[]]; + + for (i = 0; i < selector.elements.length; i++) { + el = selector.elements[i]; + // non parent reference elements just get added + if (el.value !== "&") { + currentElements.push(el); + } else { + // the new list of selectors to add + selectorsMultiplied = []; + + // merge the current list of non parent selector elements + // on to the current list of selectors to add + if (currentElements.length > 0) { + this.mergeElementsOnToSelectors(currentElements, newSelectors); + } + + // loop through our current selectors + for (j = 0; j < newSelectors.length; j++) { + sel = newSelectors[j]; + // if we don't have any parent paths, the & might be in a mixin so that it can be used + // whether there are parents or not + if (context.length === 0) { + // the combinator used on el should now be applied to the next element instead so that + // it is not lost + if (sel.length > 0) { + sel[0].elements = sel[0].elements.slice(0); + sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo)); + } + selectorsMultiplied.push(sel); + } + else { + // and the parent selectors + for (k = 0; k < context.length; k++) { + parentSel = context[k]; + // We need to put the current selectors + // then join the last selector's elements on to the parents selectors + + // our new selector path + newSelectorPath = []; + // selectors from the parent after the join + afterParentJoin = []; + newJoinedSelectorEmpty = true; + + //construct the joined selector - if & is the first thing this will be empty, + // if not newJoinedSelector will be the last set of elements in the selector + if (sel.length > 0) { + newSelectorPath = sel.slice(0); + lastSelector = newSelectorPath.pop(); + newJoinedSelector = selector.createDerived(lastSelector.elements.slice(0)); + newJoinedSelectorEmpty = false; + } + else { + newJoinedSelector = selector.createDerived([]); + } + + //put together the parent selectors after the join + if (parentSel.length > 1) { + afterParentJoin = afterParentJoin.concat(parentSel.slice(1)); + } + + if (parentSel.length > 0) { + newJoinedSelectorEmpty = false; + + // /deep/ is a combinator that is valid without anything in front of it + // so if the & does not have a combinator that is "" or " " then + // and there is a combinator on the parent, then grab that. + // this also allows + a { & .b { .a & { ... though not sure why you would want to do that + var combinator = el.combinator, + parentEl = parentSel[0].elements[0]; + if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { + combinator = parentEl.combinator; + } + // join the elements so far with the first part of the parent + newJoinedSelector.elements.push(new Element(combinator, parentEl.value, el.index, el.currentFileInfo)); + newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1)); + } + + if (!newJoinedSelectorEmpty) { + // now add the joined selector + newSelectorPath.push(newJoinedSelector); + } + + // and the rest of the parent + newSelectorPath = newSelectorPath.concat(afterParentJoin); + + // add that to our new set of selectors + selectorsMultiplied.push(newSelectorPath); + } + } + } + + // our new selectors has been multiplied, so reset the state + newSelectors = selectorsMultiplied; + currentElements = []; + } + } + + // if we have any elements left over (e.g. .a& .b == .b) + // add them on to all the current selectors + if (currentElements.length > 0) { + this.mergeElementsOnToSelectors(currentElements, newSelectors); + } + + for (i = 0; i < newSelectors.length; i++) { + if (newSelectors[i].length > 0) { + paths.push(newSelectors[i]); + } + } +}; +Ruleset.prototype.mergeElementsOnToSelectors = function(elements, selectors) { + var i, sel; + + if (selectors.length === 0) { + selectors.push([ new Selector(elements) ]); + return; + } + + for (i = 0; i < selectors.length; i++) { + sel = selectors[i]; + + // if the previous thing in sel is a parent this needs to join on to it + if (sel.length > 0) { + sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); + } + else { + sel.push(new Selector(elements)); + } + } +}; +module.exports = Ruleset; + +},{"../contexts":10,"../functions/default":19,"./debug-info":51,"./element":55,"./node":67,"./rule":71,"./selector":74}],74:[function(require,module,exports){ +var Node = require("./node"); + +var Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) { + this.elements = elements; + this.extendList = extendList; + this.condition = condition; + this.currentFileInfo = currentFileInfo || {}; + this.isReferenced = isReferenced; + if (!condition) { + this.evaldCondition = true; + } +}; +Selector.prototype = new Node(); +Selector.prototype.type = "Selector"; +Selector.prototype.accept = function (visitor) { + if (this.elements) { + this.elements = visitor.visitArray(this.elements); + } + if (this.extendList) { + this.extendList = visitor.visitArray(this.extendList); + } + if (this.condition) { + this.condition = visitor.visit(this.condition); + } +}; +Selector.prototype.createDerived = function(elements, extendList, evaldCondition) { + evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; + var newSelector = new Selector(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced); + newSelector.evaldCondition = evaldCondition; + newSelector.mediaEmpty = this.mediaEmpty; + return newSelector; +}; +Selector.prototype.match = function (other) { + var elements = this.elements, + len = elements.length, + olen, i; + + other.CacheElements(); + + olen = other._elements.length; + if (olen === 0 || len < olen) { + return 0; + } else { + for (i = 0; i < olen; i++) { + if (elements[i].value !== other._elements[i]) { + return 0; + } + } + } + + return olen; // return number of matched elements +}; +Selector.prototype.CacheElements = function() { + if (this._elements) + return; + + var elements = this.elements.map( function(v) { + return v.combinator.value + (v.value.value || v.value); + }).join("").match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); + + if (elements) { + if (elements[0] === "&") { + elements.shift(); + } + } else { + elements = []; + } + + this._elements = elements; +}; +Selector.prototype.isJustParentSelector = function() { + return !this.mediaEmpty && + this.elements.length === 1 && + this.elements[0].value === '&' && + (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); +}; +Selector.prototype.eval = function (context) { + var evaldCondition = this.condition && this.condition.eval(context), + elements = this.elements, extendList = this.extendList; + + elements = elements && elements.map(function (e) { return e.eval(context); }); + extendList = extendList && extendList.map(function(extend) { return extend.eval(context); }); + + return this.createDerived(elements, extendList, evaldCondition); +}; +Selector.prototype.genCSS = function (context, output) { + var i, element; + if ((!context || !context.firstSelector) && this.elements[0].combinator.value === "") { + output.add(' ', this.currentFileInfo, this.index); + } + if (!this._css) { + //TODO caching? speed comparison? + for(i = 0; i < this.elements.length; i++) { + element = this.elements[i]; + element.genCSS(context, output); + } + } +}; +Selector.prototype.markReferenced = function () { + this.isReferenced = true; +}; +Selector.prototype.getIsReferenced = function() { + return !this.currentFileInfo.reference || this.isReferenced; +}; +Selector.prototype.getIsOutput = function() { + return this.evaldCondition; +}; +module.exports = Selector; + +},{"./node":67}],75:[function(require,module,exports){ +var Node = require("./node"); + +var UnicodeDescriptor = function (value) { + this.value = value; +}; +UnicodeDescriptor.prototype = new Node(); +UnicodeDescriptor.prototype.type = "UnicodeDescriptor"; + +module.exports = UnicodeDescriptor; + +},{"./node":67}],76:[function(require,module,exports){ +var Node = require("./node"), + unitConversions = require("../data/unit-conversions"); + +var Unit = function (numerator, denominator, backupUnit) { + this.numerator = numerator ? numerator.slice(0).sort() : []; + this.denominator = denominator ? denominator.slice(0).sort() : []; + if (backupUnit) { + this.backupUnit = backupUnit; + } else if (numerator && numerator.length) { + this.backupUnit = numerator[0]; + } +}; + +Unit.prototype = new Node(); +Unit.prototype.type = "Unit"; +Unit.prototype.clone = function () { + return new Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit); +}; +Unit.prototype.genCSS = function (context, output) { + // Dimension checks the unit is singular and throws an error if in strict math mode. + var strictUnits = context && context.strictUnits; + if (this.numerator.length === 1) { + output.add(this.numerator[0]); // the ideal situation + } else if (!strictUnits && this.backupUnit) { + output.add(this.backupUnit); + } +}; +Unit.prototype.toString = function () { + var i, returnStr = this.numerator.join("*"); + for (i = 0; i < this.denominator.length; i++) { + returnStr += "/" + this.denominator[i]; + } + return returnStr; +}; +Unit.prototype.compare = function (other) { + return this.is(other.toString()) ? 0 : undefined; +}; +Unit.prototype.is = function (unitString) { + return this.toString().toUpperCase() === unitString.toUpperCase(); +}; +Unit.prototype.isLength = function () { + return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/)); +}; +Unit.prototype.isEmpty = function () { + return this.numerator.length === 0 && this.denominator.length === 0; +}; +Unit.prototype.isSingular = function() { + return this.numerator.length <= 1 && this.denominator.length === 0; +}; +Unit.prototype.map = function(callback) { + var i; + + for (i = 0; i < this.numerator.length; i++) { + this.numerator[i] = callback(this.numerator[i], false); + } + + for (i = 0; i < this.denominator.length; i++) { + this.denominator[i] = callback(this.denominator[i], true); + } +}; +Unit.prototype.usedUnits = function() { + var group, result = {}, mapUnit; + + mapUnit = function (atomicUnit) { + /*jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { + result[groupName] = atomicUnit; + } + + return atomicUnit; + }; + + for (var groupName in unitConversions) { + if (unitConversions.hasOwnProperty(groupName)) { + group = unitConversions[groupName]; + + this.map(mapUnit); + } + } + + return result; +}; +Unit.prototype.cancel = function () { + var counter = {}, atomicUnit, i; + + for (i = 0; i < this.numerator.length; i++) { + atomicUnit = this.numerator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; + } + + for (i = 0; i < this.denominator.length; i++) { + atomicUnit = this.denominator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; + } + + this.numerator = []; + this.denominator = []; + + for (atomicUnit in counter) { + if (counter.hasOwnProperty(atomicUnit)) { + var count = counter[atomicUnit]; + + if (count > 0) { + for (i = 0; i < count; i++) { + this.numerator.push(atomicUnit); + } + } else if (count < 0) { + for (i = 0; i < -count; i++) { + this.denominator.push(atomicUnit); + } + } + } + } + + this.numerator.sort(); + this.denominator.sort(); +}; +module.exports = Unit; + +},{"../data/unit-conversions":13,"./node":67}],77:[function(require,module,exports){ +var Node = require("./node"); + +var URL = function (val, index, currentFileInfo, isEvald) { + this.value = val; + this.currentFileInfo = currentFileInfo; + this.index = index; + this.isEvald = isEvald; +}; +URL.prototype = new Node(); +URL.prototype.type = "Url"; +URL.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); +}; +URL.prototype.genCSS = function (context, output) { + output.add("url("); + this.value.genCSS(context, output); + output.add(")"); +}; +URL.prototype.eval = function (context) { + var val = this.value.eval(context), + rootpath; + + if (!this.isEvald) { + // Add the base path if the URL is relative + rootpath = this.currentFileInfo && this.currentFileInfo.rootpath; + if (rootpath && + typeof val.value === "string" && + context.isPathRelative(val.value)) { + + if (!val.quote) { + rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; }); + } + val.value = rootpath + val.value; + } + + val.value = context.normalizePath(val.value); + + // Add url args if enabled + if (context.urlArgs) { + if (!val.value.match(/^\s*data:/)) { + var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; + var urlArgs = delimiter + context.urlArgs; + if (val.value.indexOf('#') !== -1) { + val.value = val.value.replace('#', urlArgs + '#'); + } else { + val.value += urlArgs; + } + } + } + } + + return new URL(val, this.index, this.currentFileInfo, true); +}; +module.exports = URL; + +},{"./node":67}],78:[function(require,module,exports){ +var Node = require("./node"); + +var Value = function (value) { + this.value = value; + if (!value) { + throw new Error("Value requires an array argument"); + } +}; +Value.prototype = new Node(); +Value.prototype.type = "Value"; +Value.prototype.accept = function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } +}; +Value.prototype.eval = function (context) { + if (this.value.length === 1) { + return this.value[0].eval(context); + } else { + return new Value(this.value.map(function (v) { + return v.eval(context); + })); + } +}; +Value.prototype.genCSS = function (context, output) { + var i; + for(i = 0; i < this.value.length; i++) { + this.value[i].genCSS(context, output); + if (i+1 < this.value.length) { + output.add((context && context.compress) ? ',' : ', '); + } + } +}; +module.exports = Value; + +},{"./node":67}],79:[function(require,module,exports){ +var Node = require("./node"); + +var Variable = function (name, index, currentFileInfo) { + this.name = name; + this.index = index; + this.currentFileInfo = currentFileInfo || {}; +}; +Variable.prototype = new Node(); +Variable.prototype.type = "Variable"; +Variable.prototype.eval = function (context) { + var variable, name = this.name; + + if (name.indexOf('@@') === 0) { + name = '@' + new Variable(name.slice(1), this.index, this.currentFileInfo).eval(context).value; + } + + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive variable definition for " + name, + filename: this.currentFileInfo.filename, + index: this.index }; + } + + this.evaluating = true; + + variable = this.find(context.frames, function (frame) { + var v = frame.variable(name); + if (v) { + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length-1]; + importantScope.important = v.important; + } + return v.value.eval(context); + } + }); + if (variable) { + this.evaluating = false; + return variable; + } else { + throw { type: 'Name', + message: "variable " + name + " is undefined", + filename: this.currentFileInfo.filename, + index: this.index }; + } +}; +Variable.prototype.find = function (obj, fun) { + for (var i = 0, r; i < obj.length; i++) { + r = fun.call(obj, obj[i]); + if (r) { return r; } + } + return null; +}; +module.exports = Variable; + +},{"./node":67}],80:[function(require,module,exports){ +module.exports = { + getLocation: function(index, inputStream) { + var n = index + 1, + line = null, + column = -1; + + while (--n >= 0 && inputStream.charAt(n) !== '\n') { + column++; + } + + if (typeof index === 'number') { + line = (inputStream.slice(0, index).match(/\n/g) || "").length; + } + + return { + line: line, + column: column + }; + } +}; + +},{}],81:[function(require,module,exports){ +var tree = require("../tree"), + Visitor = require("./visitor"); + +/*jshint loopfunc:true */ + +var ExtendFinderVisitor = function() { + this._visitor = new Visitor(this); + this.contexts = []; + this.allExtendsStack = [[]]; +}; + +ExtendFinderVisitor.prototype = { + run: function (root) { + root = this._visitor.visit(root); + root.allExtends = this.allExtendsStack[0]; + return root; + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitRuleset: function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; + } + + var i, j, extend, allSelectorsExtendList = [], extendList; + + // get &:extend(.a); rules which apply to all selectors in this ruleset + var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0; + for(i = 0; i < ruleCnt; i++) { + if (rulesetNode.rules[i] instanceof tree.Extend) { + allSelectorsExtendList.push(rules[i]); + rulesetNode.extendOnEveryPath = true; + } + } + + // now find every selector and apply the extends that apply to all extends + // and the ones which apply to an individual extend + var paths = rulesetNode.paths; + for(i = 0; i < paths.length; i++) { + var selectorPath = paths[i], + selector = selectorPath[selectorPath.length - 1], + selExtendList = selector.extendList; + + extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList) + : allSelectorsExtendList; + + if (extendList) { + extendList = extendList.map(function(allSelectorsExtend) { + return allSelectorsExtend.clone(); + }); + } + + for(j = 0; j < extendList.length; j++) { + this.foundExtends = true; + extend = extendList[j]; + extend.findSelfSelectors(selectorPath); + extend.ruleset = rulesetNode; + if (j === 0) { extend.firstExtendOnThisSelectorPath = true; } + this.allExtendsStack[this.allExtendsStack.length-1].push(extend); + } + } + + this.contexts.push(rulesetNode.selectors); + }, + visitRulesetOut: function (rulesetNode) { + if (!rulesetNode.root) { + this.contexts.length = this.contexts.length - 1; + } + }, + visitMedia: function (mediaNode, visitArgs) { + mediaNode.allExtends = []; + this.allExtendsStack.push(mediaNode.allExtends); + }, + visitMediaOut: function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }, + visitDirective: function (directiveNode, visitArgs) { + directiveNode.allExtends = []; + this.allExtendsStack.push(directiveNode.allExtends); + }, + visitDirectiveOut: function (directiveNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + } +}; + +var ProcessExtendsVisitor = function() { + this._visitor = new Visitor(this); +}; + +ProcessExtendsVisitor.prototype = { + run: function(root) { + var extendFinder = new ExtendFinderVisitor(); + extendFinder.run(root); + if (!extendFinder.foundExtends) { return root; } + root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); + this.allExtendsStack = [root.allExtends]; + return this._visitor.visit(root); + }, + doExtendChaining: function (extendsList, extendsListTarget, iterationCount) { + // + // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting + // the selector we would do normally, but we are also adding an extend with the same target selector + // this means this new extend can then go and alter other extends + // + // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors + // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if + // we look at each selector at a time, as is done in visitRuleset + + var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath, extend, targetExtend, newExtend; + + iterationCount = iterationCount || 0; + + //loop through comparing every extend with every target extend. + // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place + // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one + // and the second is the target. + // the seperation into two lists allows us to process a subset of chains with a bigger set, as is the + // case when processing media queries + for(extendIndex = 0; extendIndex < extendsList.length; extendIndex++){ + for(targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++){ + + extend = extendsList[extendIndex]; + targetExtend = extendsListTarget[targetExtendIndex]; + + // look for circular references + if( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ){ continue; } + + // find a match in the target extends self selector (the bit before :extend) + selectorPath = [targetExtend.selfSelectors[0]]; + matches = extendVisitor.findMatch(extend, selectorPath); + + if (matches.length) { + + // we found a match, so for each self selector.. + extend.selfSelectors.forEach(function(selfSelector) { + + // process the extend as usual + newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector); + + // but now we create a new extend from it + newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0); + newExtend.selfSelectors = newSelector; + + // add the extend onto the list of extends for that selector + newSelector[newSelector.length-1].extendList = [newExtend]; + + // record that we need to add it. + extendsToAdd.push(newExtend); + newExtend.ruleset = targetExtend.ruleset; + + //remember its parents for circular references + newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); + + // only process the selector once.. if we have :extend(.a,.b) then multiple + // extends will look at the same selector path, so when extending + // we know that any others will be duplicates in terms of what is added to the css + if (targetExtend.firstExtendOnThisSelectorPath) { + newExtend.firstExtendOnThisSelectorPath = true; + targetExtend.ruleset.paths.push(newSelector); + } + }); + } + } + } + + if (extendsToAdd.length) { + // try to detect circular references to stop a stack overflow. + // may no longer be needed. + this.extendChainCount++; + if (iterationCount > 100) { + var selectorOne = "{unable to calculate}"; + var selectorTwo = "{unable to calculate}"; + try + { + selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); + selectorTwo = extendsToAdd[0].selector.toCSS(); + } + catch(e) {} + throw {message: "extend circular reference detected. One of the circular extends is currently:"+selectorOne+":extend(" + selectorTwo+")"}; + } + + // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e... + return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount+1)); + } else { + return extendsToAdd; + } + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitSelector: function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitRuleset: function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; + } + var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length-1], selectorsToAdd = [], extendVisitor = this, selectorPath; + + // look at each selector path in the ruleset, find any extend matches and then copy, find and replace + + for(extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { + for(pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { + selectorPath = rulesetNode.paths[pathIndex]; + + // extending extends happens initially, before the main pass + if (rulesetNode.extendOnEveryPath) { continue; } + var extendList = selectorPath[selectorPath.length-1].extendList; + if (extendList && extendList.length) { continue; } + + matches = this.findMatch(allExtends[extendIndex], selectorPath); + + if (matches.length) { + + allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) { + selectorsToAdd.push(extendVisitor.extendSelector(matches, selectorPath, selfSelector)); + }); + } + } + } + rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); + }, + findMatch: function (extend, haystackSelectorPath) { + // + // look through the haystack selector path to try and find the needle - extend.selector + // returns an array of selector matches that can then be replaced + // + var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement, + targetCombinator, i, + extendVisitor = this, + needleElements = extend.selector.elements, + potentialMatches = [], potentialMatch, matches = []; + + // loop through the haystack elements + for(haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { + hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; + + for(hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { + + haystackElement = hackstackSelector.elements[hackstackElementIndex]; + + // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. + if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { + potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, initialCombinator: haystackElement.combinator}); + } + + for(i = 0; i < potentialMatches.length; i++) { + potentialMatch = potentialMatches[i]; + + // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't + // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out + // what the resulting combinator will be + targetCombinator = haystackElement.combinator.value; + if (targetCombinator === '' && hackstackElementIndex === 0) { + targetCombinator = ' '; + } + + // if we don't match, null our match to indicate failure + if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || + (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { + potentialMatch = null; + } else { + potentialMatch.matched++; + } + + // if we are still valid and have finished, test whether we have elements after and whether these are allowed + if (potentialMatch) { + potentialMatch.finished = potentialMatch.matched === needleElements.length; + if (potentialMatch.finished && + (!extend.allowAfter && (hackstackElementIndex+1 < hackstackSelector.elements.length || haystackSelectorIndex+1 < haystackSelectorPath.length))) { + potentialMatch = null; + } + } + // if null we remove, if not, we are still valid, so either push as a valid match or continue + if (potentialMatch) { + if (potentialMatch.finished) { + potentialMatch.length = needleElements.length; + potentialMatch.endPathIndex = haystackSelectorIndex; + potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match + potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again + matches.push(potentialMatch); + } + } else { + potentialMatches.splice(i, 1); + i--; + } + } + } + } + return matches; + }, + isElementValuesEqual: function(elementValue1, elementValue2) { + if (typeof elementValue1 === "string" || typeof elementValue2 === "string") { + return elementValue1 === elementValue2; + } + if (elementValue1 instanceof tree.Attribute) { + if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { + return false; + } + if (!elementValue1.value || !elementValue2.value) { + if (elementValue1.value || elementValue2.value) { + return false; + } + return true; + } + elementValue1 = elementValue1.value.value || elementValue1.value; + elementValue2 = elementValue2.value.value || elementValue2.value; + return elementValue1 === elementValue2; + } + elementValue1 = elementValue1.value; + elementValue2 = elementValue2.value; + if (elementValue1 instanceof tree.Selector) { + if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { + return false; + } + for(var i = 0; i currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + + newElements = selector.elements + .slice(currentSelectorPathElementIndex, match.index) + .concat([firstElement]) + .concat(replacementSelector.elements.slice(1)); + + if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { + path[path.length - 1].elements = + path[path.length - 1].elements.concat(newElements); + } else { + path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); + + path.push(new tree.Selector( + newElements + )); + } + currentSelectorPathIndex = match.endPathIndex; + currentSelectorPathElementIndex = match.endPathElementIndex; + if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + } + + if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathIndex++; + } + + path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); + + return path; + }, + visitRulesetOut: function (rulesetNode) { + }, + visitMedia: function (mediaNode, visitArgs) { + var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }, + visitMediaOut: function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }, + visitDirective: function (directiveNode, visitArgs) { + var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }, + visitDirectiveOut: function (directiveNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + } +}; + +module.exports = ProcessExtendsVisitor; + +},{"../tree":59,"./visitor":87}],82:[function(require,module,exports){ +function ImportSequencer(onSequencerEmpty) { + this.imports = []; + this.variableImports = []; + this._onSequencerEmpty = onSequencerEmpty; + this._currentDepth = 0; +} + +ImportSequencer.prototype.addImport = function(callback) { + var importSequencer = this, + importItem = { + callback: callback, + args: null, + isReady: false + }; + this.imports.push(importItem); + return function() { + importItem.args = Array.prototype.slice.call(arguments, 0); + importItem.isReady = true; + importSequencer.tryRun(); + }; +}; + +ImportSequencer.prototype.addVariableImport = function(callback) { + this.variableImports.push(callback); +}; + +ImportSequencer.prototype.tryRun = function() { + this._currentDepth++; + try { + while(true) { + while(this.imports.length > 0) { + var importItem = this.imports[0]; + if (!importItem.isReady) { + return; + } + this.imports = this.imports.slice(1); + importItem.callback.apply(null, importItem.args); + } + if (this.variableImports.length === 0) { + break; + } + var variableImport = this.variableImports[0]; + this.variableImports = this.variableImports.slice(1); + variableImport(); + } + } finally { + this._currentDepth--; + } + if (this._currentDepth === 0 && this._onSequencerEmpty) { + this._onSequencerEmpty(); + } +}; + +module.exports = ImportSequencer; + +},{}],83:[function(require,module,exports){ +var contexts = require("../contexts"), + Visitor = require("./visitor"), + ImportSequencer = require("./import-sequencer"); + +var ImportVisitor = function(importer, finish) { + + this._visitor = new Visitor(this); + this._importer = importer; + this._finish = finish; + this.context = new contexts.Eval(); + this.importCount = 0; + this.onceFileDetectionMap = {}; + this.recursionDetector = {}; + this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); +}; + +ImportVisitor.prototype = { + isReplacing: false, + run: function (root) { + try { + // process the contents + this._visitor.visit(root); + } + catch(e) { + this.error = e; + } + + this.isFinished = true; + this._sequencer.tryRun(); + }, + _onSequencerEmpty: function() { + if (!this.isFinished) { + return; + } + this._finish(this.error); + }, + visitImport: function (importNode, visitArgs) { + var inlineCSS = importNode.options.inline; + + if (!importNode.css || inlineCSS) { + + var context = new contexts.Eval(this.context, this.context.frames.slice(0)); + var importParent = context.frames[0]; + + this.importCount++; + if (importNode.isVariableImport()) { + this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); + } else { + this.processImportNode(importNode, context, importParent); + } + } + visitArgs.visitDeeper = false; + }, + processImportNode: function(importNode, context, importParent) { + var evaldImportNode, + inlineCSS = importNode.options.inline; + + try { + evaldImportNode = importNode.evalForImport(context); + } catch(e){ + if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } + // attempt to eval properly and treat as css + importNode.css = true; + // if that fails, this error will be thrown + importNode.error = e; + } + + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { + + if (evaldImportNode.options.multiple) { + context.importMultiple = true; + } + + // try appending if we haven't determined if it is css or not + var tryAppendLessExtension = evaldImportNode.css === undefined; + + for(var i = 0; i < importParent.rules.length; i++) { + if (importParent.rules[i] === importNode) { + importParent.rules[i] = evaldImportNode; + break; + } + } + + var onImported = this.onImported.bind(this, evaldImportNode, context), + sequencedOnImported = this._sequencer.addImport(onImported); + + this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.currentFileInfo, evaldImportNode.options, sequencedOnImported); + } else { + this.importCount--; + if (this.isFinished) { + this._sequencer.tryRun(); + } + } + }, + onImported: function (importNode, context, e, root, importedAtRoot, fullPath) { + if (e) { + if (!e.filename) { + e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; + } + this.error = e; + } + + var importVisitor = this, + inlineCSS = importNode.options.inline, + duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; + + if (!context.importMultiple) { + if (duplicateImport) { + importNode.skip = true; + } else { + importNode.skip = function() { + if (fullPath in importVisitor.onceFileDetectionMap) { + return true; + } + importVisitor.onceFileDetectionMap[fullPath] = true; + return false; + }; + } + } + + if (root) { + importNode.root = root; + importNode.importedFilename = fullPath; + + if (!inlineCSS && (context.importMultiple || !duplicateImport)) { + importVisitor.recursionDetector[fullPath] = true; + + var oldContext = this.context; + this.context = context; + try { + this._visitor.visit(root); + } catch (e) { + this.error = e; + } + this.context = oldContext; + } + } + + importVisitor.importCount--; + + if (importVisitor.isFinished) { + importVisitor._sequencer.tryRun(); + } + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitDirective: function (directiveNode, visitArgs) { + this.context.frames.unshift(directiveNode); + }, + visitDirectiveOut: function (directiveNode) { + this.context.frames.shift(); + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + this.context.frames.unshift(mixinDefinitionNode); + }, + visitMixinDefinitionOut: function (mixinDefinitionNode) { + this.context.frames.shift(); + }, + visitRuleset: function (rulesetNode, visitArgs) { + this.context.frames.unshift(rulesetNode); + }, + visitRulesetOut: function (rulesetNode) { + this.context.frames.shift(); + }, + visitMedia: function (mediaNode, visitArgs) { + this.context.frames.unshift(mediaNode.rules[0]); + }, + visitMediaOut: function (mediaNode) { + this.context.frames.shift(); + } +}; +module.exports = ImportVisitor; + +},{"../contexts":10,"./import-sequencer":82,"./visitor":87}],84:[function(require,module,exports){ +var visitors = { + Visitor: require("./visitor"), + ImportVisitor: require('./import-visitor'), + ExtendVisitor: require('./extend-visitor'), + JoinSelectorVisitor: require('./join-selector-visitor'), + ToCSSVisitor: require('./to-css-visitor') +}; + +module.exports = visitors; + +},{"./extend-visitor":81,"./import-visitor":83,"./join-selector-visitor":85,"./to-css-visitor":86,"./visitor":87}],85:[function(require,module,exports){ +var Visitor = require("./visitor"); + +var JoinSelectorVisitor = function() { + this.contexts = [[]]; + this._visitor = new Visitor(this); +}; + +JoinSelectorVisitor.prototype = { + run: function (root) { + return this._visitor.visit(root); + }, + visitRule: function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }, + + visitRuleset: function (rulesetNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1], + paths = [], selectors; + + this.contexts.push(paths); + + if (! rulesetNode.root) { + selectors = rulesetNode.selectors; + if (selectors) { + selectors = selectors.filter(function(selector) { return selector.getIsOutput(); }); + rulesetNode.selectors = selectors.length ? selectors : (selectors = null); + if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); } + } + if (!selectors) { rulesetNode.rules = null; } + rulesetNode.paths = paths; + } + }, + visitRulesetOut: function (rulesetNode) { + this.contexts.length = this.contexts.length - 1; + }, + visitMedia: function (mediaNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); + } +}; + +module.exports = JoinSelectorVisitor; + +},{"./visitor":87}],86:[function(require,module,exports){ +var tree = require("../tree"), + Visitor = require("./visitor"); + +var ToCSSVisitor = function(context) { + this._visitor = new Visitor(this); + this._context = context; +}; + +ToCSSVisitor.prototype = { + isReplacing: true, + run: function (root) { + return this._visitor.visit(root); + }, + + visitRule: function (ruleNode, visitArgs) { + if (ruleNode.variable) { + return; + } + return ruleNode; + }, + + visitMixinDefinition: function (mixinNode, visitArgs) { + // mixin definitions do not get eval'd - this means they keep state + // so we have to clear that state here so it isn't used if toCSS is called twice + mixinNode.frames = []; + }, + + visitExtend: function (extendNode, visitArgs) { + }, + + visitComment: function (commentNode, visitArgs) { + if (commentNode.isSilent(this._context)) { + return; + } + return commentNode; + }, + + visitMedia: function(mediaNode, visitArgs) { + mediaNode.accept(this._visitor); + visitArgs.visitDeeper = false; + + if (!mediaNode.rules.length) { + return; + } + return mediaNode; + }, + + visitDirective: function(directiveNode, visitArgs) { + if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) { + return; + } + if (directiveNode.name === "@charset") { + // Only output the debug info together with subsequent @charset definitions + // a comment (or @media statement) before the actual @charset directive would + // be considered illegal css as it has to be on the first line + if (this.charset) { + if (directiveNode.debugInfo) { + var comment = new tree.Comment("/* " + directiveNode.toCSS(this._context).replace(/\n/g, "")+" */\n"); + comment.debugInfo = directiveNode.debugInfo; + return this._visitor.visit(comment); + } + return; + } + this.charset = true; + } + if (directiveNode.rules && directiveNode.rules.rules) { + this._mergeRules(directiveNode.rules.rules); + } + return directiveNode; + }, + + checkPropertiesInRoot: function(rules) { + var ruleNode; + for(var i = 0; i < rules.length; i++) { + ruleNode = rules[i]; + if (ruleNode instanceof tree.Rule && !ruleNode.variable) { + throw { message: "properties must be inside selector blocks, they cannot be in the root.", + index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + } + } + }, + + visitRuleset: function (rulesetNode, visitArgs) { + var rule, rulesets = []; + if (rulesetNode.firstRoot) { + this.checkPropertiesInRoot(rulesetNode.rules); + } + if (! rulesetNode.root) { + if (rulesetNode.paths) { + rulesetNode.paths = rulesetNode.paths + .filter(function(p) { + var i; + if (p[0].elements[0].combinator.value === ' ') { + p[0].elements[0].combinator = new(tree.Combinator)(''); + } + for(i = 0; i < p.length; i++) { + if (p[i].getIsReferenced() && p[i].getIsOutput()) { + return true; + } + } + return false; + }); + } + + // Compile rules and rulesets + var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0; + for (var i = 0; i < nodeRuleCnt; ) { + rule = nodeRules[i]; + if (rule && rule.rules) { + // visit because we are moving them out from being a child + rulesets.push(this._visitor.visit(rule)); + nodeRules.splice(i, 1); + nodeRuleCnt--; + continue; + } + i++; + } + // accept the visitor to remove rules and refactor itself + // then we can decide now whether we want it or not + if (nodeRuleCnt > 0) { + rulesetNode.accept(this._visitor); + } else { + rulesetNode.rules = null; + } + visitArgs.visitDeeper = false; + + nodeRules = rulesetNode.rules; + if (nodeRules) { + this._mergeRules(nodeRules); + nodeRules = rulesetNode.rules; + } + if (nodeRules) { + this._removeDuplicateRules(nodeRules); + nodeRules = rulesetNode.rules; + } + + // now decide whether we keep the ruleset + if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) { + rulesets.splice(0, 0, rulesetNode); + } + } else { + rulesetNode.accept(this._visitor); + visitArgs.visitDeeper = false; + if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) { + rulesets.splice(0, 0, rulesetNode); + } + } + if (rulesets.length === 1) { + return rulesets[0]; + } + return rulesets; + }, + + _removeDuplicateRules: function(rules) { + if (!rules) { return; } + + // remove duplicates + var ruleCache = {}, + ruleList, rule, i; + + for(i = rules.length - 1; i >= 0 ; i--) { + rule = rules[i]; + if (rule instanceof tree.Rule) { + if (!ruleCache[rule.name]) { + ruleCache[rule.name] = rule; + } else { + ruleList = ruleCache[rule.name]; + if (ruleList instanceof tree.Rule) { + ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; + } + var ruleCSS = rule.toCSS(this._context); + if (ruleList.indexOf(ruleCSS) !== -1) { + rules.splice(i, 1); + } else { + ruleList.push(ruleCSS); + } + } + } + } + }, + + _mergeRules: function (rules) { + if (!rules) { return; } + + var groups = {}, + parts, + rule, + key; + + for (var i = 0; i < rules.length; i++) { + rule = rules[i]; + + if ((rule instanceof tree.Rule) && rule.merge) { + key = [rule.name, + rule.important ? "!" : ""].join(","); + + if (!groups[key]) { + groups[key] = []; + } else { + rules.splice(i--, 1); + } + + groups[key].push(rule); + } + } + + Object.keys(groups).map(function (k) { + + function toExpression(values) { + return new (tree.Expression)(values.map(function (p) { + return p.value; + })); + } + + function toValue(values) { + return new (tree.Value)(values.map(function (p) { + return p; + })); + } + + parts = groups[k]; + + if (parts.length > 1) { + rule = parts[0]; + var spacedGroups = []; + var lastSpacedGroup = []; + parts.map(function (p) { + if (p.merge==="+") { + if (lastSpacedGroup.length > 0) { + spacedGroups.push(toExpression(lastSpacedGroup)); + } + lastSpacedGroup = []; + } + lastSpacedGroup.push(p); + }); + spacedGroups.push(toExpression(lastSpacedGroup)); + rule.value = toValue(spacedGroups); + } + }); + } +}; + +module.exports = ToCSSVisitor; + +},{"../tree":59,"./visitor":87}],87:[function(require,module,exports){ +var tree = require("../tree"); + +var _visitArgs = { visitDeeper: true }, + _hasIndexed = false; + +function _noop(node) { + return node; +} + +function indexNodeTypes(parent, ticker) { + // add .typeIndex to tree node types for lookup table + var key, child; + for (key in parent) { + if (parent.hasOwnProperty(key)) { + child = parent[key]; + switch (typeof child) { + case "function": + // ignore bound functions directly on tree which do not have a prototype + // or aren't nodes + if (child.prototype && child.prototype.type) { + child.prototype.typeIndex = ticker++; + } + break; + case "object": + ticker = indexNodeTypes(child, ticker); + break; + } + } + } + return ticker; +} + +var Visitor = function(implementation) { + this._implementation = implementation; + this._visitFnCache = []; + + if (!_hasIndexed) { + indexNodeTypes(tree, 1); + _hasIndexed = true; + } +}; + +Visitor.prototype = { + visit: function(node) { + if (!node) { + return node; + } + + var nodeTypeIndex = node.typeIndex; + if (!nodeTypeIndex) { + return node; + } + + var visitFnCache = this._visitFnCache, + impl = this._implementation, + aryIndx = nodeTypeIndex << 1, + outAryIndex = aryIndx | 1, + func = visitFnCache[aryIndx], + funcOut = visitFnCache[outAryIndex], + visitArgs = _visitArgs, + fnName; + + visitArgs.visitDeeper = true; + + if (!func) { + fnName = "visit" + node.type; + func = impl[fnName] || _noop; + funcOut = impl[fnName + "Out"] || _noop; + visitFnCache[aryIndx] = func; + visitFnCache[outAryIndex] = funcOut; + } + + if (func !== _noop) { + var newNode = func.call(impl, node, visitArgs); + if (impl.isReplacing) { + node = newNode; + } + } + + if (visitArgs.visitDeeper && node && node.accept) { + node.accept(this); + } + + if (funcOut != _noop) { + funcOut.call(impl, node); + } + + return node; + }, + visitArray: function(nodes, nonReplacing) { + if (!nodes) { + return nodes; + } + + var cnt = nodes.length, i; + + // Non-replacing + if (nonReplacing || !this._implementation.isReplacing) { + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); + } + return nodes; + } + + // Replacing + var out = []; + for (i = 0; i < cnt; i++) { + var evald = this.visit(nodes[i]); + if (evald === undefined) { continue; } + if (!evald.splice) { + out.push(evald); + } else if (evald.length) { + this.flatten(evald, out); + } + } + return out; + }, + flatten: function(arr, out) { + if (!out) { + out = []; + } + + var cnt, i, item, + nestedCnt, j, nestedItem; + + for (i = 0, cnt = arr.length; i < cnt; i++) { + item = arr[i]; + if (item === undefined) { + continue; + } + if (!item.splice) { + out.push(item); + continue; + } + + for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { + nestedItem = item[j]; + if (nestedItem === undefined) { + continue; + } + if (!nestedItem.splice) { + out.push(nestedItem); + } else if (nestedItem.length) { + this.flatten(nestedItem, out); + } + } + } + + return out; + } +}; +module.exports = Visitor; + +},{"../tree":59}],88:[function(require,module,exports){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canMutationObserver = typeof window !== 'undefined' + && window.MutationObserver; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + var queue = []; + + if (canMutationObserver) { + var hiddenDiv = document.createElement("div"); + var observer = new MutationObserver(function () { + var queueList = queue.slice(); + queue.length = 0; + queueList.forEach(function (fn) { + fn(); + }); + }); + + observer.observe(hiddenDiv, { attributes: true }); + + return function nextTick(fn) { + if (!queue.length) { + hiddenDiv.setAttribute('yes', 'no'); + } + queue.push(fn); + }; + } + + if (canPost) { + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +},{}],89:[function(require,module,exports){ +'use strict'; + +var asap = require('asap') + +module.exports = Promise; +function Promise(fn) { + if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new') + if (typeof fn !== 'function') throw new TypeError('not a function') + var state = null + var value = null + var deferreds = [] + var self = this + + this.then = function(onFulfilled, onRejected) { + return new self.constructor(function(resolve, reject) { + handle(new Handler(onFulfilled, onRejected, resolve, reject)) + }) + } + + function handle(deferred) { + if (state === null) { + deferreds.push(deferred) + return + } + asap(function() { + var cb = state ? deferred.onFulfilled : deferred.onRejected + if (cb === null) { + (state ? deferred.resolve : deferred.reject)(value) + return + } + var ret + try { + ret = cb(value) + } + catch (e) { + deferred.reject(e) + return + } + deferred.resolve(ret) + }) + } + + function resolve(newValue) { + try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.') + if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { + var then = newValue.then + if (typeof then === 'function') { + doResolve(then.bind(newValue), resolve, reject) + return + } + } + state = true + value = newValue + finale() + } catch (e) { reject(e) } + } + + function reject(newValue) { + state = false + value = newValue + finale() + } + + function finale() { + for (var i = 0, len = deferreds.length; i < len; i++) + handle(deferreds[i]) + deferreds = null + } + + doResolve(fn, resolve, reject) +} + + +function Handler(onFulfilled, onRejected, resolve, reject){ + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null + this.onRejected = typeof onRejected === 'function' ? onRejected : null + this.resolve = resolve + this.reject = reject +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, onFulfilled, onRejected) { + var done = false; + try { + fn(function (value) { + if (done) return + done = true + onFulfilled(value) + }, function (reason) { + if (done) return + done = true + onRejected(reason) + }) + } catch (ex) { + if (done) return + done = true + onRejected(ex) + } +} + +},{"asap":91}],90:[function(require,module,exports){ +'use strict'; + +//This file contains the ES6 extensions to the core Promises/A+ API + +var Promise = require('./core.js') +var asap = require('asap') + +module.exports = Promise + +/* Static Functions */ + +function ValuePromise(value) { + this.then = function (onFulfilled) { + if (typeof onFulfilled !== 'function') return this + return new Promise(function (resolve, reject) { + asap(function () { + try { + resolve(onFulfilled(value)) + } catch (ex) { + reject(ex); + } + }) + }) + } +} +ValuePromise.prototype = Promise.prototype + +var TRUE = new ValuePromise(true) +var FALSE = new ValuePromise(false) +var NULL = new ValuePromise(null) +var UNDEFINED = new ValuePromise(undefined) +var ZERO = new ValuePromise(0) +var EMPTYSTRING = new ValuePromise('') + +Promise.resolve = function (value) { + if (value instanceof Promise) return value + + if (value === null) return NULL + if (value === undefined) return UNDEFINED + if (value === true) return TRUE + if (value === false) return FALSE + if (value === 0) return ZERO + if (value === '') return EMPTYSTRING + + if (typeof value === 'object' || typeof value === 'function') { + try { + var then = value.then + if (typeof then === 'function') { + return new Promise(then.bind(value)) + } + } catch (ex) { + return new Promise(function (resolve, reject) { + reject(ex) + }) + } + } + + return new ValuePromise(value) +} + +Promise.all = function (arr) { + var args = Array.prototype.slice.call(arr) + + return new Promise(function (resolve, reject) { + if (args.length === 0) return resolve([]) + var remaining = args.length + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then + if (typeof then === 'function') { + then.call(val, function (val) { res(i, val) }, reject) + return + } + } + args[i] = val + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex) + } + } + for (var i = 0; i < args.length; i++) { + res(i, args[i]) + } + }) +} + +Promise.reject = function (value) { + return new Promise(function (resolve, reject) { + reject(value); + }); +} + +Promise.race = function (values) { + return new Promise(function (resolve, reject) { + values.forEach(function(value){ + Promise.resolve(value).then(resolve, reject); + }) + }); +} + +/* Prototype Methods */ + +Promise.prototype['catch'] = function (onRejected) { + return this.then(null, onRejected); +} + +},{"./core.js":89,"asap":91}],91:[function(require,module,exports){ +(function (process){ + +// Use the fastest possible means to execute a task in a future turn +// of the event loop. + +// linked list of tasks (single, with head node) +var head = {task: void 0, next: null}; +var tail = head; +var flushing = false; +var requestFlush = void 0; +var isNodeJS = false; + +function flush() { + /* jshint loopfunc: true */ + + while (head.next) { + head = head.next; + var task = head.task; + head.task = void 0; + var domain = head.domain; + + if (domain) { + head.domain = void 0; + domain.enter(); + } + + try { + task(); + + } catch (e) { + if (isNodeJS) { + // In node, uncaught exceptions are considered fatal errors. + // Re-throw them synchronously to interrupt flushing! + + // Ensure continuation if the uncaught exception is suppressed + // listening "uncaughtException" events (as domains does). + // Continue in next event to avoid tick recursion. + if (domain) { + domain.exit(); + } + setTimeout(flush, 0); + if (domain) { + domain.enter(); + } + + throw e; + + } else { + // In browsers, uncaught exceptions are not fatal. + // Re-throw them asynchronously to avoid slow-downs. + setTimeout(function() { + throw e; + }, 0); + } + } + + if (domain) { + domain.exit(); + } + } + + flushing = false; +} + +if (typeof process !== "undefined" && process.nextTick) { + // Node.js before 0.9. Note that some fake-Node environments, like the + // Mocha test runner, introduce a `process` global without a `nextTick`. + isNodeJS = true; + + requestFlush = function () { + process.nextTick(flush); + }; + +} else if (typeof setImmediate === "function") { + // In IE10, Node.js 0.9+, or https://github.com/NobleJS/setImmediate + if (typeof window !== "undefined") { + requestFlush = setImmediate.bind(window, flush); + } else { + requestFlush = function () { + setImmediate(flush); + }; + } + +} else if (typeof MessageChannel !== "undefined") { + // modern browsers + // http://www.nonblocking.io/2011/06/windownexttick.html + var channel = new MessageChannel(); + channel.port1.onmessage = flush; + requestFlush = function () { + channel.port2.postMessage(0); + }; + +} else { + // old browsers + requestFlush = function () { + setTimeout(flush, 0); + }; +} + +function asap(task) { + tail = tail.next = { + task: task, + domain: isNodeJS && process.domain, + next: null + }; + + if (!flushing) { + flushing = true; + requestFlush(); + } +}; + +module.exports = asap; + + +}).call(this,require('_process')) +},{"_process":88}],92:[function(require,module,exports){ +// should work in any browser without browserify + +if (typeof Promise.prototype.done !== 'function') { + Promise.prototype.done = function (onFulfilled, onRejected) { + var self = arguments.length ? this.then.apply(this, arguments) : this + self.then(null, function (err) { + setTimeout(function () { + throw err + }, 0) + }) + } +} +},{}],"promise/polyfill.js":[function(require,module,exports){ +// not "use strict" so we can declare global "Promise" + +var asap = require('asap'); + +if (typeof Promise === 'undefined') { + Promise = require('./lib/core.js') + require('./lib/es6-extensions.js') +} + +require('./polyfill-done.js'); + +},{"./lib/core.js":89,"./lib/es6-extensions.js":90,"./polyfill-done.js":92,"asap":91}]},{},[2])(2) +}); \ No newline at end of file diff --git a/less.js/less.js_2.2.0/less.js.dnn b/less.js/less.js_2.2.0/less.js.dnn new file mode 100644 index 00000000..fa0468fa --- /dev/null +++ b/less.js/less.js_2.2.0/less.js.dnn @@ -0,0 +1,41 @@ + + + + less.js + The dynamic stylesheet language + + Engage Software + Engage Software + http://www.engagesoftware.com + support@engagesoftware.com + + + + true + + + + + + + less.js + less.js + BodyBottom + https://cdnjs.cloudflare.com/ajax/libs/less.js/2.2.0/less.min.js + less + + + + + less.js + + less.js + + + + + + +